dustin10 / VichUploaderBundle

A simple Symfony bundle to ease file uploads with ORM entities and ODM documents.
MIT License
1.84k stars 519 forks source link

File attributes using Vich\UploaderBundle\Entity\File embeddable no longer become persisted with upgrade of doctrine/orm v2.7.2 => v2.7.3 #1139

Closed gschafra closed 4 years ago

gschafra commented 4 years ago

Bug Report

Q A
BC Break no
Bundle version 1.13.2 & 1.14.0
Symfony version 4.4.10
api-platform 2.5.6
PHP version 7.3.19

Summary

Since an upgrade of of Symfony v4.4.7 -> v4.4.10 and API-Platform v2.5.5 -> v2.5.6, file attributes using Vich\UploaderBundle\Entity\File embeddable (fileName, fileOriginalName, fileMimeType) no longer become persisted.

Current behavior

After uploading using api-platform POST endpoint (with custom controller, see https://api-platform.com/docs/core/file-upload/#handling-file-upload), the file info values are NULL:

image

How to reproduce

composer.json:

{
    "name": "server",
    "description": "Test-Server",
    "type": "project",
    "license": "proprietary",
    "require": {
        "php": "^7.3.3",
        "ext-amqp": "*",
        "ext-ctype": "*",
        "ext-curl": "*",
        "ext-gmp": "*",
        "ext-iconv": "*",
        "ext-json": "*",
        "api-platform/api-pack": "^1.1",
        "api-platform/core": "^2.4",
        "beberlei/doctrineextensions": "^1.2",
        "doctrine/doctrine-migrations-bundle": "^2.1.2",
        "dunglas/doctrine-json-odm": "^1.0",
        "eightpoints/guzzle-bundle": "^7.4",
        "enqueue/amqp-ext": "^0.10",
        "enqueue/async-event-dispatcher": "^0.10",
        "enqueue/enqueue-bundle": "^0.10",
        "facebook/graph-sdk": "^5.7",
        "fresh/doctrine-enum-bundle": "~6.2",
        "hackzilla/password-generator": "^1.4",
        "league/flysystem": "^1.0",
        "league/flysystem-bundle": "^1.3",
        "lstrojny/functional-php": "^1.12.0",
        "mdanter/ecc": "^0.5.2",
        "nyholm/psr7": "^1.1",
        "sensio/framework-extra-bundle": "^5.2",
        "spatie/temporary-directory": "^1.1",
        "stof/doctrine-extensions-bundle": "^1.3",
        "symfony/console": "^4.1",
        "symfony/dotenv": "^4.1",
        "symfony/filesystem": "^4.1",
        "symfony/flex": "^1.0",
        "symfony/framework-bundle": "^4.1",
        "symfony/ldap": "^4.1",
        "symfony/mercure-bundle": "^0.2.4",
        "symfony/monolog-bundle": "^3.3",
        "symfony/orm-pack": "^1.0",
        "symfony/swiftmailer-bundle": "^3.2",
        "symfony/translation": "^4.0.0",
        "symfony/yaml": "^4.1",
        "trikoder/oauth2-bundle": "^3.0",
        "twig/extensions": "^1.5",
        "vich/uploader-bundle": "^1.8"
    },
    "require-dev": {
        "davidrjonas/composer-lock-diff": "^1.5.0",
        "doctrine/doctrine-fixtures-bundle": "^3.0",
        "symfony/maker-bundle": "^1.11",
        "symfony/phpunit-bridge": "^4.0.0"
    },
    "config": {
        "preferred-install": {
            "*": "dist"
        },
        "sort-packages": true,
        "github-oauth": {
            "github.com": "fc6f9cfeefd9e248b0995796af5e110f68497347"
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },
    "replace": {
        "symfony/polyfill-ctype": "*",
        "symfony/polyfill-iconv": "*",
        "symfony/polyfill-php71": "*",
        "symfony/polyfill-php70": "*",
        "symfony/polyfill-php56": "*"
    },
    "scripts": {
        "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "assets:install --symlink --relative %PUBLIC_DIR%": "symfony-cmd"
        },
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]
    },
    "conflict": {
        "symfony/symfony": "*"
    },
    "extra": {
        "symfony": {
            "allow-contrib": false,
            "require": "4.4.*"
        }
    }
}

Package update info:

+----------------------------------+---------+---------+-------------------------------------------------------------------------------+
| Production Changes               | From    | To      | Compare                                                                       |
+----------------------------------+---------+---------+-------------------------------------------------------------------------------+
| api-platform/core                | v2.5.5  | v2.5.6  | https://github.com/api-platform/core/compare/v2.5.5...v2.5.6                  |
| doctrine/annotations             | 1.10.2  | 1.10.3  | https://github.com/doctrine/annotations/compare/1.10.2...1.10.3               |
| doctrine/cache                   | 1.10.0  | 1.10.1  | https://github.com/doctrine/cache/compare/1.10.0...1.10.1                     |
| doctrine/collections             | 1.6.4   | 1.6.5   | https://github.com/doctrine/collections/compare/1.6.4...1.6.5                 |
| doctrine/common                  | 2.12.0  | 2.13.3  | https://github.com/doctrine/common/compare/2.12.0...2.13.3                    |
| doctrine/doctrine-bundle         | 1.12.7  | 1.12.10 | https://github.com/doctrine/DoctrineBundle/compare/1.12.7...1.12.10           |
| doctrine/inflector               | 1.3.1   | 1.4.3   | https://github.com/doctrine/inflector/compare/1.3.1...1.4.3                   |
| doctrine/instantiator            | 1.3.0   | 1.3.1   | https://github.com/doctrine/instantiator/compare/1.3.0...1.3.1                |
| doctrine/lexer                   | 1.2.0   | 1.2.1   | https://github.com/doctrine/lexer/compare/1.2.0...1.2.1                       |
| doctrine/orm                     | v2.7.2  | v2.7.3  | https://github.com/doctrine/orm/compare/v2.7.2...v2.7.3                       |
| egulias/email-validator          | 2.1.17  | 2.1.18  | https://github.com/egulias/EmailValidator/compare/2.1.17...2.1.18             |
| fig/link-util                    | 1.1.0   | 1.1.1   | https://github.com/php-fig/link-util/compare/1.1.0...1.1.1                    |
| jms/metadata                     | 2.1.0   | 2.3.0   | https://github.com/schmittjoh/metadata/compare/2.1.0...2.3.0                  |
| lcobucci/jwt                     | 3.3.1   | 3.3.2   | https://github.com/lcobucci/jwt/compare/3.3.1...3.3.2                         |
| league/oauth2-server             | 8.0.0   | 8.1.0   | https://github.com/thephpleague/oauth2-server/compare/8.0.0...8.1.0           |
| monolog/monolog                  | 1.25.3  | 1.25.4  | https://github.com/Seldaek/monolog/compare/1.25.3...1.25.4                    |
| phpdocumentor/reflection-common  | 2.0.0   | 2.2.0   | https://github.com/phpDocumentor/ReflectionCommon/compare/2.0.0...2.2.0       |
| phpdocumentor/type-resolver      | 1.1.0   | 1.3.0   | https://github.com/phpDocumentor/TypeResolver/compare/1.1.0...1.3.0           |
| symfony/asset                    | v4.4.7  | v4.4.10 | https://github.com/symfony/asset/compare/v4.4.7...v4.4.10                     |
| symfony/cache                    | v4.4.7  | v4.4.10 | https://github.com/symfony/cache/compare/v4.4.7...v4.4.10                     |
| symfony/cache-contracts          | v2.0.1  | v2.1.2  | https://github.com/symfony/cache-contracts/compare/v2.0.1...v2.1.2            |
| symfony/config                   | v4.4.7  | v4.4.10 | https://github.com/symfony/config/compare/v4.4.7...v4.4.10                    |
| symfony/console                  | v4.4.7  | v4.4.10 | https://github.com/symfony/console/compare/v4.4.7...v4.4.10                   |
| symfony/debug                    | v4.4.7  | v4.4.10 | https://github.com/symfony/debug/compare/v4.4.7...v4.4.10                     |
| symfony/dependency-injection     | v4.4.7  | v4.4.10 | https://github.com/symfony/dependency-injection/compare/v4.4.7...v4.4.10      |
| symfony/doctrine-bridge          | v4.4.7  | v4.4.10 | https://github.com/symfony/doctrine-bridge/compare/v4.4.7...v4.4.10           |
| symfony/dotenv                   | v4.4.7  | v4.4.10 | https://github.com/symfony/dotenv/compare/v4.4.7...v4.4.10                    |
| symfony/error-handler            | v4.4.7  | v4.4.10 | https://github.com/symfony/error-handler/compare/v4.4.7...v4.4.10             |
| symfony/event-dispatcher         | v4.4.7  | v4.4.10 | https://github.com/symfony/event-dispatcher/compare/v4.4.7...v4.4.10          |
| symfony/expression-language      | v4.4.7  | v4.4.10 | https://github.com/symfony/expression-language/compare/v4.4.7...v4.4.10       |
| symfony/filesystem               | v4.4.7  | v4.4.10 | https://github.com/symfony/filesystem/compare/v4.4.7...v4.4.10                |
| symfony/finder                   | v4.4.7  | v4.4.10 | https://github.com/symfony/finder/compare/v4.4.7...v4.4.10                    |
| symfony/flex                     | v1.6.2  | v1.8.4  | https://github.com/symfony/flex/compare/v1.6.2...v1.8.4                       |
| symfony/form                     | v4.4.7  | v4.4.10 | https://github.com/symfony/form/compare/v4.4.7...v4.4.10                      |
| symfony/framework-bundle         | v4.4.7  | v4.4.10 | https://github.com/symfony/framework-bundle/compare/v4.4.7...v4.4.10          |
| symfony/http-client              | v4.4.9  | v4.4.10 | https://github.com/symfony/http-client/compare/v4.4.9...v4.4.10               |
| symfony/http-foundation          | v4.4.7  | v4.4.10 | https://github.com/symfony/http-foundation/compare/v4.4.7...v4.4.10           |
| symfony/http-kernel              | v4.4.7  | v4.4.10 | https://github.com/symfony/http-kernel/compare/v4.4.7...v4.4.10               |
| symfony/inflector                | v4.4.7  | v4.4.10 | https://github.com/symfony/inflector/compare/v4.4.7...v4.4.10                 |
| symfony/intl                     | v4.4.7  | v4.4.10 | https://github.com/symfony/intl/compare/v4.4.7...v4.4.10                      |
| symfony/ldap                     | v4.4.7  | v4.4.10 | https://github.com/symfony/ldap/compare/v4.4.7...v4.4.10                      |
| symfony/mime                     | v4.4.7  | v4.4.10 | https://github.com/symfony/mime/compare/v4.4.7...v4.4.10                      |
| symfony/monolog-bridge           | v4.4.7  | v4.4.10 | https://github.com/symfony/monolog-bridge/compare/v4.4.7...v4.4.10            |
| symfony/options-resolver         | v4.4.7  | v4.4.10 | https://github.com/symfony/options-resolver/compare/v4.4.7...v4.4.10          |
| symfony/polyfill-intl-grapheme   | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-grapheme/compare/v1.15.0...v1.17.1   |
| symfony/polyfill-intl-icu        | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-icu/compare/v1.15.0...v1.17.1        |
| symfony/polyfill-intl-idn        | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-idn/compare/v1.15.0...v1.17.1        |
| symfony/polyfill-intl-normalizer | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-normalizer/compare/v1.15.0...v1.17.1 |
| symfony/polyfill-mbstring        | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-mbstring/compare/v1.15.0...v1.17.1        |
| symfony/polyfill-php72           | v1.15.0 | v1.17.0 | https://github.com/symfony/polyfill-php72/compare/v1.15.0...v1.17.0           |
| symfony/polyfill-php73           | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-php73/compare/v1.15.0...v1.17.1           |
| symfony/property-access          | v4.4.7  | v4.4.10 | https://github.com/symfony/property-access/compare/v4.4.7...v4.4.10           |
| symfony/property-info            | v4.4.7  | v4.4.10 | https://github.com/symfony/property-info/compare/v4.4.7...v4.4.10             |
| symfony/psr-http-message-bridge  | v2.0.0  | v2.0.1  | https://github.com/symfony/psr-http-message-bridge/compare/v2.0.0...v2.0.1    |
| symfony/routing                  | v4.4.7  | v4.4.10 | https://github.com/symfony/routing/compare/v4.4.7...v4.4.10                   |
| symfony/security-bundle          | v4.4.7  | v4.4.10 | https://github.com/symfony/security-bundle/compare/v4.4.7...v4.4.10           |
| symfony/security-core            | v4.4.7  | v4.4.10 | https://github.com/symfony/security-core/compare/v4.4.7...v4.4.10             |
| symfony/security-csrf            | v4.4.7  | v4.4.10 | https://github.com/symfony/security-csrf/compare/v4.4.7...v4.4.10             |
| symfony/security-guard           | v4.4.7  | v4.4.10 | https://github.com/symfony/security-guard/compare/v4.4.7...v4.4.10            |
| symfony/security-http            | v4.4.7  | v4.4.10 | https://github.com/symfony/security-http/compare/v4.4.7...v4.4.10             |
| symfony/serializer               | v4.4.7  | v4.4.10 | https://github.com/symfony/serializer/compare/v4.4.7...v4.4.10                |
| symfony/service-contracts        | v2.0.1  | v2.1.2  | https://github.com/symfony/service-contracts/compare/v2.0.1...v2.1.2          |
| symfony/stopwatch                | v4.4.7  | v4.4.10 | https://github.com/symfony/stopwatch/compare/v4.4.7...v4.4.10                 |
| symfony/string                   | v5.0.7  | v5.1.2  | https://github.com/symfony/string/compare/v5.0.7...v5.1.2                     |
| symfony/translation              | v4.4.7  | v4.4.10 | https://github.com/symfony/translation/compare/v4.4.7...v4.4.10               |
| symfony/translation-contracts    | v2.0.1  | v2.1.2  | https://github.com/symfony/translation-contracts/compare/v2.0.1...v2.1.2      |
| symfony/twig-bridge              | v4.4.7  | v4.4.10 | https://github.com/symfony/twig-bridge/compare/v4.4.7...v4.4.10               |
| symfony/twig-bundle              | v4.4.7  | v4.4.10 | https://github.com/symfony/twig-bundle/compare/v4.4.7...v4.4.10               |
| symfony/validator                | v4.4.7  | v4.4.10 | https://github.com/symfony/validator/compare/v4.4.7...v4.4.10                 |
| symfony/var-dumper               | v4.4.7  | v4.4.10 | https://github.com/symfony/var-dumper/compare/v4.4.7...v4.4.10                |
| symfony/var-exporter             | v4.4.7  | v4.4.10 | https://github.com/symfony/var-exporter/compare/v4.4.7...v4.4.10              |
| symfony/web-link                 | v4.4.7  | v4.4.10 | https://github.com/symfony/web-link/compare/v4.4.7...v4.4.10                  |
| symfony/yaml                     | v4.4.7  | v4.4.10 | https://github.com/symfony/yaml/compare/v4.4.7...v4.4.10                      |
| trikoder/oauth2-bundle           | v3.0.0  | v3.1.1  | https://github.com/trikoder/oauth2-bundle/compare/v3.0.0...v3.1.1             |
| webmozart/assert                 | 1.8.0   | 1.9.0   | https://github.com/webmozart/assert/compare/1.8.0...1.9.0                     |
| symfony/polyfill-php80           | NEW     | v1.17.1 |                                                                               |
+----------------------------------+---------+---------+-------------------------------------------------------------------------------+

+------------------------+---------+---------+--------------------------------------------------------------------+
| Dev Changes            | From    | To      | Compare                                                            |
+------------------------+---------+---------+--------------------------------------------------------------------+
| nikic/php-parser       | v4.3.0  | v4.5.0  | https://github.com/nikic/PHP-Parser/compare/v4.3.0...v4.5.0        |
| symfony/maker-bundle   | v1.14.6 | v1.19.0 | https://github.com/symfony/maker-bundle/compare/v1.14.6...v1.19.0  |
| symfony/phpunit-bridge | v4.4.7  | v4.4.10 | https://github.com/symfony/phpunit-bridge/compare/v4.4.7...v4.4.10 |
+------------------------+---------+---------+--------------------------------------------------------------------+

Entity:

<?php

    namespace App\Entity;

    use ApiPlatform\Core\Annotation\ApiProperty;
    use ApiPlatform\Core\Annotation\ApiResource;
    use App\Controller\CreateIddFileAction;
    use App\Entity\Enums\ClientType;
    use App\Entity\Enums\IddStatusType;
    use Doctrine\ORM\Mapping as ORM;
    use Fresh\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
    use Symfony\Component\HttpFoundation\File\File;
    use Symfony\Component\HttpFoundation\File\UploadedFile;
    use Symfony\Component\Serializer\Annotation\Groups;
    use Symfony\Component\Serializer\Annotation\MaxDepth;
    use Symfony\Component\Validator\Constraints as Assert;
    use Vich\UploaderBundle\Mapping\Annotation as Vich;

    /**
     * Class IddFile
     *
     * @package App\Entity
     *
     * @ApiResource(
     *     attributes={
     *        "normalization_context"=Idd::API_READ,
     *        "denormalization_context"=Idd::API_WRITE,
     *        "access_control"="is_granted('ROLE_IDD_R')"
     *     },
     *     collectionOperations={
     *         "get"={"access_control"="is_granted('ROLE_IDD_R')"},
     *         "upload"={
     *             "method"="POST",
     *             "path"="/idds",
     *             "controller"=CreateIddFileAction::class,
     *             "defaults"={"_api_receive"=false},
     *             "access_control"="is_granted('ROLE_IDD_RW')",
     *             "swagger_context"={
     *                  "summary"="Create an invoice data delivery (Rechnungsstellung/ADL)",
     *                  "description"="Endpoint to transfer invoices to PVS. ATTENTION: As long as not all information for uniquely identifying the IDD is available via the filename, client and doctor identifier is mandatory.",
     *                  "consumes"={"multipart/form-data"},
     *                  "produces"={"application/json"},
     *                  "parameters"={
     *                      {
     *                          "name"="iddFile",
     *                          "in"="formData",
     *                          "description"="IDD transfer file. ATTENTION: The filename should be unique per transfer and therefore should contain informations relating to the doctor (identifier number) and the client.",
     *                          "type"="file",
     *                          "required"=true
     *                      },
     *                      {
     *                          "name"="doctorIdentifierNumber",
     *                          "in"="formData",
     *                          "description"="Doctors identifier number (Arztnummer)",
     *                          "type"="integer",
     *                          "format"="int32",
     *                          "required"=false
     *                      },
     *                      {
     *                          "name"="client",
     *                          "in"="formData",
     *                          "description"="Client (Mandanten)-ID",
     *                          "type"="string",
     *                          "maxLength"=1,
     *                          "enum"={"P", "M"},
     *                          "required"=false
     *                      }
     *                  },
     *                  "responses"={
     *                      "200"={"description"="Upload successfull", "schema"={"$ref"="#/definitions/Idd-Read"}},
     *                      "400"={"description"="Invalid request", "schema"={"properties"={"message"={"description"="Error message", "type"="string"}}}},
     *                      "401"={"description"="Unauthorized"},
     *                      "422"={"description"="Validation error", "schema"={"type"="array", "items"={"type"="object", "properties"={"field"={"type"="string", "description"="Element/attribute for which the error occured"}, "message"={"type"="string", "description"="Error message"}}, "required"={"field", "message"}}}},
     *                      "500"={"description"="Upload failure"}
     *                  }
     *             }
     *         },
     *     },
     *     itemOperations={
     *        "get"={
     *            "access_control"="is_granted('ROLE_IDD_R')",
     *            "swagger_context"={
     *                "parameters"={
     *                      {
     *                          "name"="queued",
     *                          "in"="query",
     *                          "description"="If set, queries the local db instead of the backend proxied to",
     *                          "type"="boolean",
     *                          "required"=false
     *                      }
     *                 }
     *            }
     *         },
     *        "patch"={
     *            "access_control"="is_granted('ROLE_IDD_RW')", "read"=false, "output"=false
     *        }
     *     }
     * )
     *
     * @ORM\Entity
     * @Vich\Uploadable
     */
    class Idd
    {
        /**
         * Serializer normalization context.
         */
        const API_READ = [
            'groups' => ['idd_read'],
            'enable_max_depth' => true,
            'swagger_definition_name' => 'Read'
        ];

        /**
         * Serializer denormalization context.
         */
        const API_WRITE = [
            'groups' => ['idd_write'],
            'enable_max_depth' => true,
            'swagger_definition_name' => 'Write'
        ];

        //region Fields

        /**
         * @var int
         *
         * @Groups({"idd_read", "idd_write"})
         *
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;

        /**
         * NOTE: This is not a mapped field of entity metadata, just a simple property.
         *
         * @Vich\UploadableField(mapping="idd_file", fileNameProperty="file.name", size="file.size", mimeType="file.mimeType", originalName="file.originalName", dimensions="file.dimensions")
         *
         * @var File|null
         *
         * @Groups({"idd_read", "idd_write"})
         *
         * @Assert\NotNull(groups={"idd_file_create"})
         */
        private $iddFile;

        /**
         * @ORM\Embedded(class="EmbeddedFile")
         *
         * @var EmbeddedFile
         *
         * @Groups({"idd_read", "idd_write"})
         */
        private $file;

        /**
         * @ORM\Column(type="datetime")
         *
         * @var \DateTime|null
         *
         * @Groups({"idd_read", "idd_write"})
         */
        private $updatedAt;

        /**
         * @var \DateTime|null
         *
         * @ApiProperty(
         *     attributes={
         *         "swagger_context"={
         *             "type"="string",
         *             "format"="date-time"
         *         }
         *     }
         * )
         *
         * @Groups({"idd_read"})
         */
        private $createdAt;

        /**
         * @var \DateTime|null
         *
         * @ApiProperty(
         *     attributes={
         *         "swagger_context"={
         *             "type"="string",
         *             "format"="date-time"
         *         }
         *     }
         * )
         *
         * @Groups({"idd_read"})
         */
        private $uploadedAt;

        /**
         * @var \DateTime|null
         *
         * @ApiProperty(
         *     attributes={
         *         "swagger_context"={
         *             "type"="string",
         *             "format"="date-time"
         *         }
         *     }
         * )
         *
         * @Groups({"idd_read"})
         */
        private $authorizedAt;

        /**
         * @ORM\Column(type="integer", nullable=true)
         *
         * @var int|null
         *
         * @Groups({"idd_read", "idd_write"})
         */
        private $doctorIdentifierNumber;

        /**
         * @var string|null
         *
         * @Groups({"idd_read", "idd_write"})
         *
         * @Assert\Choice(choices=ClientType::_VALUES)
         * @Assert\NotBlank
         *
         * @ApiProperty(
         *     attributes={
         *         "swagger_context"={
         *             "type"="string",
         *             "enum"=ClientType::_VALUES
         *         }
         *     }
         * )
         *
         * @ORM\Column(type="ClientType", nullable=true)
         * @DoctrineAssert\Enum(entity="App\Entity\Enums\ClientType")
         */
        private $client = ClientType::P;

        /**
         * Status
         *
         * @var string
         *
         * @Groups({"idd_read", "idd_write"})
         *
         * @Assert\Choice(choices=IddStatusType::_VALUES)
         * @Assert\NotBlank
         *
         * @ApiProperty(
         *     attributes={
         *         "swagger_context"={
         *             "type"="string",
         *             "enum"=IddStatusType::_VALUES
         *         }
         *     }
         * )
         *
         * @ORM\Column(type="IddStatusType", nullable=true)
         * @DoctrineAssert\Enum(entity="App\Entity\Enums\IddStatusType")
         */
        private $status = IddStatusType::NEW;

        /**
         * Indicates if IDD is zipped (from PVS-Client) or not
         *
         * @var bool
         *
         * @Groups({"idd_read", "idd_write"})
         *
         * @ORM\Column(type="boolean", options={"default" : true})
         */
        private $isZipped = true;

        /**
         * @var bool|null
         *
         * @ApiProperty(
         *     attributes={
         *         "swagger_context"={
         *             "type"="boolean"
         *         }
         *     }
         * )
         *
         * @Groups({"idd_read"})
         */
        private $valid;

        /**
         * @var string[]|null
         *
         * @ApiProperty(
         *     attributes={
         *         "swagger_context"={
         *             "type"="array",
         *             "items"={
         *                 "type"="string"
         *             }
         *         }
         *     }
         * )
         *
         * @Groups({"idd_read"})
         */
        private $messages;

        /**
         * @var float|null
         *
         * @ApiProperty(
         *     attributes={
         *         "swagger_context"={
         *             "type"="number",
         *             "format"="float"
         *         }
         *     }
         * )
         *
         * @Groups({"idd_read"})
         */
        private $value;

        /**
         * @var Invoice[]
         *
         * @Groups({"idd_read", "idd_write"})
         */
        private $invoices = array();

        /**
         * ID of corresponding entity in the PVS backend
         *
         * @ORM\Column(type="integer", nullable=true)
         *
         * @var int|null
         *
         * @Groups({"idd_read"})
         */
        private $proxyId;

        /**
         * Upload attempt count for queue throttling
         *
         * @ORM\Column(type="integer", nullable=true, options={"default" : 0})
         *
         * @var int
         *
         * @Groups({"idd_read"})
         */
        private $uploadAttempt = 0;

        /**
         * Organisation user
         *
         * @var OrganisationUser|null
         *
         * @MaxDepth(1)
         *
         * @ORM\ManyToOne(targetEntity="App\Entity\OrganisationUser")
         * @ORM\JoinColumn(name="organisation_user_id", referencedColumnName="id", onDelete="SET NULL")
         */
        private $organisationUser;

        //endregion

        public function __construct()
        {
            $this->file = new EmbeddedFile();
        }

        //region Getters/Setters

        /**
         * @return mixed
         */
        public function getId()
        {
            return $this->id;
        }

        /**
         * @param int $id
         */
        public function setId(int $id): void
        {
            $this->id = $id;
        }

        /**
         * @return \DateTime|null
         */
        public function getUpdatedAt(): ?\DateTime
        {
            return $this->updatedAt;
        }

        /**
         * @param \DateTime $updatedAt
         */
        public function setUpdatedAt(?\DateTime $updatedAt = null): void
        {
            $this->updatedAt = $updatedAt;
        }

        /**
         * @return \DateTime|null
         */
        public function getCreatedAt(): ?\DateTime
        {
            return $this->createdAt;
        }

        /**
         * @param \DateTime|null $createdAt
         */
        public function setCreatedAt(?\DateTime $createdAt): void
        {
            $this->createdAt = $createdAt;
        }

        /**
         * @return \DateTime|null
         */
        public function getUploadedAt(): ?\DateTime
        {
            return $this->uploadedAt;
        }

        /**
         * @param \DateTime|null $uploadedAt
         */
        public function setUploadedAt(?\DateTime $uploadedAt): void
        {
            $this->uploadedAt = $uploadedAt;
        }

        /**
         * @return \DateTime|null
         */
        public function getAuthorizedAt(): ?\DateTime
        {
            return $this->authorizedAt;
        }

        /**
         * @param \DateTime|null $authorizedAt
         */
        public function setAuthorizedAt(?\DateTime $authorizedAt): void
        {
            $this->authorizedAt = $authorizedAt;
        }

        /**
         * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
         * of 'UploadedFile' is injected into this setter to trigger the  update. If this
         * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
         * must be able to accept an instance of 'File' as the bundle will inject one here
         * during Doctrine hydration.
         *
         * @param File|UploadedFile $iddFile
         *
         * @throws \Exception
         */
        public function setIddFile(?File $iddFile = null)
        {
            $this->iddFile = $iddFile;

            if (null !== $iddFile)
            {
                // It is required that at least one field changes if you are using doctrine
                // otherwise the event listeners won't be called and the file is lost
                $this->updatedAt = new \DateTime();
            }
        }

        /**
         * @return File|null
         */
        public function getIddFile(): ?File
        {
            return $this->iddFile;
        }

        /**
         * @return EmbeddedFile
         */
        public function getFile(): EmbeddedFile
        {
            return $this->file;
        }

        /**
         * @param EmbeddedFile $file
         */
        public function setFile(EmbeddedFile $file): void
        {
            $this->file = $file;
        }

        /**
         * @return int|null
         */
        public function getDoctorIdentifierNumber(): ?int
        {
            return $this->doctorIdentifierNumber;
        }

        /**
         * @param int|null $doctorIdentifierNumber
         */
        public function setDoctorIdentifierNumber(?int $doctorIdentifierNumber): void
        {
            $this->doctorIdentifierNumber = $doctorIdentifierNumber;
        }

        /**
         * @return string|null
         */
        public function getClient(): ?string
        {
            return $this->client;
        }

        /**
         * @param string|null $client
         */
        public function setClient(?string $client): void
        {
            $this->client = $client;
        }

        /**
         * @return string
         */
        public function getStatus(): string
        {
            return $this->status;
        }

        /**
         * @param string $status
         */
        public function setStatus(string $status): void
        {
            $this->status = $status;
        }

        /**
         * @return bool
         */
        public function getIsZipped(): bool
        {
            return $this->isZipped;
        }

        /**
         * @param bool $isZipped
         */
        public function setIsZipped(bool $isZipped): void
        {
            $this->isZipped = $isZipped;
        }

        /**
         * @return bool|null
         */
        public function getValid(): ?bool
        {
            return $this->valid;
        }

        /**
         * @param bool|null $valid
         */
        public function setValid(?bool $valid): void
        {
            $this->valid = $valid;
        }

        /**
         * @return string[]|null
         */
        public function getMessages(): ?array
        {
            return $this->messages;
        }

        /**
         * @param string[]|null $messages
         */
        public function setMessages(?array $messages): void
        {
            $this->messages = $messages;
        }

        /**
         * @return float|null
         */
        public function getValue(): ?float
        {
            return $this->value;
        }

        /**
         * @param float|null $value
         */
        public function setValue(?float $value): void
        {
            $this->value = $value;
        }

        /**
         * @return Invoice[]
         */
        public function getInvoices(): array
        {
            return $this->invoices;
        }

        /**
         * @param Invoice[] $invoices
         */
        public function setInvoices(array $invoices): void
        {
            $this->invoices = $invoices;
        }

        /**
         * @return int|null
         */
        public function getProxyId(): ?int
        {
            return $this->proxyId;
        }

        /**
         * @param int|null $proxyId
         */
        public function setProxyId(?int $proxyId): void
        {
            $this->proxyId = $proxyId;
        }

        /**
         * @return int
         */
        public function getUploadAttempt(): int
        {
            return $this->uploadAttempt;
        }

        /**
         * @param int $uploadAttempt
         */
        public function setUploadAttempt(int $uploadAttempt): void
        {
            $this->uploadAttempt = $uploadAttempt;
        }

        /**
         * @return OrganisationUser|null
         */
        public function getOrganisationUser(): ?OrganisationUser
        {
            return $this->organisationUser;
        }

        /**
         * @param OrganisationUser|null $organisationUser
         */
        public function setOrganisationUser(?OrganisationUser $organisationUser): void
        {
            $this->organisationUser = $organisationUser;
        }

        //endregion

        //region Misc. methods

        /**
         * @param int $by
         *
         * @return int
         */
        public function incrementUploadAttempt(int $by = 1): int
        {
            $this->uploadAttempt += $by;

            return $this->uploadAttempt;
        }

        /**
         * @param string $status
         *
         * @return bool
         */
        public function hasStatus(string $status): bool
        {
            return $this->getStatus() === $status;
        }

        //endregion
    }

Controller:

<?php

    namespace App\Controller;

    use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
    use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
    use ApiPlatform\Core\Util\RequestAttributesExtractor;
    use App\Entity\Idd;
    use Doctrine\Common\Persistence\ManagerRegistry;
    use Symfony\Bridge\Doctrine\RegistryInterface;
    use Symfony\Component\HttpFoundation\File\UploadedFile;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
    use Symfony\Component\Validator\Validator\ValidatorInterface;

    /**
     * Class CreateIddFileAction
     *
     * @package App\Controller
     */
    class CreateIddFileAction
    {
        /**
         * @var ValidatorInterface
         */
        private $validator;

        /**
         * @var RegistryInterface
         */
        private $doctrine;

        /**
         * @var ResourceMetadataFactoryInterface
         */
        private $resourceMetadataFactory;

        /**
         * CreateIddFileAction constructor.
         *
         * @param ManagerRegistry                  $doctrine
         * @param ValidatorInterface               $validator
         * @param ResourceMetadataFactoryInterface $resourceMetadataFactory
         */
        public function __construct(ManagerRegistry $doctrine, ValidatorInterface $validator, ResourceMetadataFactoryInterface $resourceMetadataFactory)
        {
            $this->doctrine = $doctrine;
            $this->validator = $validator;
            $this->resourceMetadataFactory = $resourceMetadataFactory;
        }

        /**
         * @param Request $request
         *
         * @return Idd
         * @throws \Exception
         */
        public function __invoke(Request $request) : Idd
        {
            /** @var UploadedFile $uploadedFile */
            $uploadedFile = $request->files->get('iddFile');

            if (!$uploadedFile)
            {
                throw new BadRequestHttpException('"iddFile" is required');
            }

            $idd = new Idd();
            $idd->setIddFile($uploadedFile);
            $idd->setDoctorIdentifierNumber($request->get('doctorIdentifierNumber'));
            $idd->setClient($request->get('client'));
            $isZipped = self::isTrue($request->get('isZipped', true));
            $idd->setIsZipped($isZipped);

            // TODO #34699: Validation
            // $this->validate($idd, $request);

            $em = $this->doctrine->getManager();
            $em->persist($idd);
            $em->flush();

            // needed here to prevent normalization errors
            $idd->setIddFile(null);

            return $idd;
        }

        /**
         * @throws ValidationException
         * @throws \ApiPlatform\Core\Exception\ResourceClassNotFoundException
         */
        private function validate(Idd $idd, Request $request): void
        {
            $attributes = RequestAttributesExtractor::extractAttributes($request);
            $resourceMetadata = $this->resourceMetadataFactory->create(Idd::class);
            $validationGroups = $resourceMetadata->getOperationAttribute($attributes, 'validation_groups', null, true);

            $this->validator->validate($idd, null, ['groups' => $validationGroups]);
        }

        /**
         * Cast to bool, also taking 'true' or 'false' into account
         *
         * @param      $val
         * @param bool $return_null
         *
         * @return bool|mixed|null
         */
        private static function isTrue($val, $return_null = false)
        {
            $boolval = (is_string($val) ? filter_var(
                $val,
                FILTER_VALIDATE_BOOLEAN,
                FILTER_NULL_ON_FAILURE
            ) : (bool)$val);

            return ($boolval === null && !$return_null ? false : $boolval);
        }
    }

Expected behavior

File info fields become filled correctly after/on upload

garak commented 4 years ago

Can you try to update only VichUploaderBundle and see what happens?

gschafra commented 4 years ago

Yup... doing composer update vich/uploader-bundel without updating the dependencies...

+----------------------+--------+--------+------------------------------------------------------------------------+
| Production Changes   | From   | To     | Compare                                                                |
+----------------------+--------+--------+------------------------------------------------------------------------+
| vich/uploader-bundle | 1.13.2 | 1.14.0 | https://github.com/dustin10/VichUploaderBundle/compare/1.13.2...1.14.0 |
+----------------------+--------+--------+------------------------------------------------------------------------+

... works like a charm.

gschafra commented 4 years ago

Hmmm... doing the composer update symfony/* also without updating any other dependencies...

+----------------------------------+---------+---------+-------------------------------------------------------------------------------+
| Production Changes               | From    | To      | Compare                                                                       |
+----------------------------------+---------+---------+-------------------------------------------------------------------------------+
| symfony/asset                    | v4.4.7  | v4.4.10 | https://github.com/symfony/asset/compare/v4.4.7...v4.4.10                     |
| symfony/cache                    | v4.4.7  | v4.4.10 | https://github.com/symfony/cache/compare/v4.4.7...v4.4.10                     |
| symfony/cache-contracts          | v2.0.1  | v2.1.2  | https://github.com/symfony/cache-contracts/compare/v2.0.1...v2.1.2            |
| symfony/config                   | v4.4.7  | v4.4.10 | https://github.com/symfony/config/compare/v4.4.7...v4.4.10                    |
| symfony/console                  | v4.4.7  | v4.4.10 | https://github.com/symfony/console/compare/v4.4.7...v4.4.10                   |
| symfony/debug                    | v4.4.7  | v4.4.10 | https://github.com/symfony/debug/compare/v4.4.7...v4.4.10                     |
| symfony/dependency-injection     | v4.4.7  | v4.4.10 | https://github.com/symfony/dependency-injection/compare/v4.4.7...v4.4.10      |
| symfony/doctrine-bridge          | v4.4.7  | v4.4.10 | https://github.com/symfony/doctrine-bridge/compare/v4.4.7...v4.4.10           |
| symfony/dotenv                   | v4.4.7  | v4.4.10 | https://github.com/symfony/dotenv/compare/v4.4.7...v4.4.10                    |
| symfony/error-handler            | v4.4.7  | v4.4.10 | https://github.com/symfony/error-handler/compare/v4.4.7...v4.4.10             |
| symfony/event-dispatcher         | v4.4.7  | v4.4.10 | https://github.com/symfony/event-dispatcher/compare/v4.4.7...v4.4.10          |
| symfony/expression-language      | v4.4.7  | v4.4.10 | https://github.com/symfony/expression-language/compare/v4.4.7...v4.4.10       |
| symfony/filesystem               | v4.4.7  | v4.4.10 | https://github.com/symfony/filesystem/compare/v4.4.7...v4.4.10                |
| symfony/finder                   | v4.4.7  | v4.4.10 | https://github.com/symfony/finder/compare/v4.4.7...v4.4.10                    |
| symfony/flex                     | v1.6.2  | v1.8.4  | https://github.com/symfony/flex/compare/v1.6.2...v1.8.4                       |
| symfony/form                     | v4.4.7  | v4.4.10 | https://github.com/symfony/form/compare/v4.4.7...v4.4.10                      |
| symfony/framework-bundle         | v4.4.7  | v4.4.10 | https://github.com/symfony/framework-bundle/compare/v4.4.7...v4.4.10          |
| symfony/http-client              | v4.4.9  | v4.4.10 | https://github.com/symfony/http-client/compare/v4.4.9...v4.4.10               |
| symfony/http-foundation          | v4.4.7  | v4.4.10 | https://github.com/symfony/http-foundation/compare/v4.4.7...v4.4.10           |
| symfony/http-kernel              | v4.4.7  | v4.4.10 | https://github.com/symfony/http-kernel/compare/v4.4.7...v4.4.10               |
| symfony/inflector                | v4.4.7  | v4.4.10 | https://github.com/symfony/inflector/compare/v4.4.7...v4.4.10                 |
| symfony/intl                     | v4.4.7  | v4.4.10 | https://github.com/symfony/intl/compare/v4.4.7...v4.4.10                      |
| symfony/ldap                     | v4.4.7  | v4.4.10 | https://github.com/symfony/ldap/compare/v4.4.7...v4.4.10                      |
| symfony/mime                     | v4.4.7  | v4.4.10 | https://github.com/symfony/mime/compare/v4.4.7...v4.4.10                      |
| symfony/monolog-bridge           | v4.4.7  | v4.4.10 | https://github.com/symfony/monolog-bridge/compare/v4.4.7...v4.4.10            |
| symfony/options-resolver         | v4.4.7  | v4.4.10 | https://github.com/symfony/options-resolver/compare/v4.4.7...v4.4.10          |
| symfony/polyfill-intl-grapheme   | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-grapheme/compare/v1.15.0...v1.17.1   |
| symfony/polyfill-intl-icu        | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-icu/compare/v1.15.0...v1.17.1        |
| symfony/polyfill-intl-idn        | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-idn/compare/v1.15.0...v1.17.1        |
| symfony/polyfill-intl-normalizer | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-normalizer/compare/v1.15.0...v1.17.1 |
| symfony/polyfill-mbstring        | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-mbstring/compare/v1.15.0...v1.17.1        |
| symfony/polyfill-php72           | v1.15.0 | v1.17.0 | https://github.com/symfony/polyfill-php72/compare/v1.15.0...v1.17.0           |
| symfony/polyfill-php73           | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-php73/compare/v1.15.0...v1.17.1           |
| symfony/property-access          | v4.4.7  | v4.4.10 | https://github.com/symfony/property-access/compare/v4.4.7...v4.4.10           |
| symfony/property-info            | v4.4.7  | v4.4.10 | https://github.com/symfony/property-info/compare/v4.4.7...v4.4.10             |
| symfony/psr-http-message-bridge  | v2.0.0  | v2.0.1  | https://github.com/symfony/psr-http-message-bridge/compare/v2.0.0...v2.0.1    |
| symfony/routing                  | v4.4.7  | v4.4.10 | https://github.com/symfony/routing/compare/v4.4.7...v4.4.10                   |
| symfony/security-bundle          | v4.4.7  | v4.4.10 | https://github.com/symfony/security-bundle/compare/v4.4.7...v4.4.10           |
| symfony/security-core            | v4.4.7  | v4.4.10 | https://github.com/symfony/security-core/compare/v4.4.7...v4.4.10             |
| symfony/security-csrf            | v4.4.7  | v4.4.10 | https://github.com/symfony/security-csrf/compare/v4.4.7...v4.4.10             |
| symfony/security-guard           | v4.4.7  | v4.4.10 | https://github.com/symfony/security-guard/compare/v4.4.7...v4.4.10            |
| symfony/security-http            | v4.4.7  | v4.4.10 | https://github.com/symfony/security-http/compare/v4.4.7...v4.4.10             |
| symfony/serializer               | v4.4.7  | v4.4.10 | https://github.com/symfony/serializer/compare/v4.4.7...v4.4.10                |
| symfony/service-contracts        | v2.0.1  | v2.1.2  | https://github.com/symfony/service-contracts/compare/v2.0.1...v2.1.2          |
| symfony/stopwatch                | v4.4.7  | v4.4.10 | https://github.com/symfony/stopwatch/compare/v4.4.7...v4.4.10                 |
| symfony/string                   | v5.0.7  | v5.1.2  | https://github.com/symfony/string/compare/v5.0.7...v5.1.2                     |
| symfony/translation              | v4.4.7  | v4.4.10 | https://github.com/symfony/translation/compare/v4.4.7...v4.4.10               |
| symfony/translation-contracts    | v2.0.1  | v2.1.2  | https://github.com/symfony/translation-contracts/compare/v2.0.1...v2.1.2      |
| symfony/twig-bridge              | v4.4.7  | v4.4.10 | https://github.com/symfony/twig-bridge/compare/v4.4.7...v4.4.10               |
| symfony/twig-bundle              | v4.4.7  | v4.4.10 | https://github.com/symfony/twig-bundle/compare/v4.4.7...v4.4.10               |
| symfony/validator                | v4.4.7  | v4.4.10 | https://github.com/symfony/validator/compare/v4.4.7...v4.4.10                 |
| symfony/var-dumper               | v4.4.7  | v4.4.10 | https://github.com/symfony/var-dumper/compare/v4.4.7...v4.4.10                |
| symfony/var-exporter             | v4.4.7  | v4.4.10 | https://github.com/symfony/var-exporter/compare/v4.4.7...v4.4.10              |
| symfony/web-link                 | v4.4.7  | v4.4.10 | https://github.com/symfony/web-link/compare/v4.4.7...v4.4.10                  |
| symfony/yaml                     | v4.4.7  | v4.4.10 | https://github.com/symfony/yaml/compare/v4.4.7...v4.4.10                      |
| vich/uploader-bundle             | 1.13.2  | 1.14.0  | https://github.com/dustin10/VichUploaderBundle/compare/1.13.2...1.14.0        |
| symfony/polyfill-php80           | NEW     | v1.17.1 |                                                                               |
+----------------------------------+---------+---------+-------------------------------------------------------------------------------+

+------------------------+---------+---------+--------------------------------------------------------------------+
| Dev Changes            | From    | To      | Compare                                                            |
+------------------------+---------+---------+--------------------------------------------------------------------+
| symfony/maker-bundle   | v1.14.6 | v1.19.0 | https://github.com/symfony/maker-bundle/compare/v1.14.6...v1.19.0  |
| symfony/phpunit-bridge | v4.4.7  | v4.4.10 | https://github.com/symfony/phpunit-bridge/compare/v4.4.7...v4.4.10 |
+------------------------+---------+---------+--------------------------------------------------------------------+

... also works like a charm.

gschafra commented 4 years ago

Even after updating api-platform with composer update api-platform/* (without dependency update with --with-all-dependencies), upload works.

+----------------------------------+---------+---------+-------------------------------------------------------------------------------+ | Production Changes | From | To | Compare | +----------------------------------+---------+---------+-------------------------------------------------------------------------------+ | api-platform/core | v2.5.5 | v2.5.6 | https://github.com/api-platform/core/compare/v2.5.5...v2.5.6 | | symfony/asset | v4.4.7 | v4.4.10 | https://github.com/symfony/asset/compare/v4.4.7...v4.4.10 | | symfony/cache | v4.4.7 | v4.4.10 | https://github.com/symfony/cache/compare/v4.4.7...v4.4.10 | | symfony/cache-contracts | v2.0.1 | v2.1.2 | https://github.com/symfony/cache-contracts/compare/v2.0.1...v2.1.2 | | symfony/config | v4.4.7 | v4.4.10 | https://github.com/symfony/config/compare/v4.4.7...v4.4.10 | | symfony/console | v4.4.7 | v4.4.10 | https://github.com/symfony/console/compare/v4.4.7...v4.4.10 | | symfony/debug | v4.4.7 | v4.4.10 | https://github.com/symfony/debug/compare/v4.4.7...v4.4.10 | | symfony/dependency-injection | v4.4.7 | v4.4.10 | https://github.com/symfony/dependency-injection/compare/v4.4.7...v4.4.10 | | symfony/doctrine-bridge | v4.4.7 | v4.4.10 | https://github.com/symfony/doctrine-bridge/compare/v4.4.7...v4.4.10 | | symfony/dotenv | v4.4.7 | v4.4.10 | https://github.com/symfony/dotenv/compare/v4.4.7...v4.4.10 | | symfony/error-handler | v4.4.7 | v4.4.10 | https://github.com/symfony/error-handler/compare/v4.4.7...v4.4.10 | | symfony/event-dispatcher | v4.4.7 | v4.4.10 | https://github.com/symfony/event-dispatcher/compare/v4.4.7...v4.4.10 | | symfony/expression-language | v4.4.7 | v4.4.10 | https://github.com/symfony/expression-language/compare/v4.4.7...v4.4.10 | | symfony/filesystem | v4.4.7 | v4.4.10 | https://github.com/symfony/filesystem/compare/v4.4.7...v4.4.10 | | symfony/finder | v4.4.7 | v4.4.10 | https://github.com/symfony/finder/compare/v4.4.7...v4.4.10 | | symfony/flex | v1.6.2 | v1.8.4 | https://github.com/symfony/flex/compare/v1.6.2...v1.8.4 | | symfony/form | v4.4.7 | v4.4.10 | https://github.com/symfony/form/compare/v4.4.7...v4.4.10 | | symfony/framework-bundle | v4.4.7 | v4.4.10 | https://github.com/symfony/framework-bundle/compare/v4.4.7...v4.4.10 | | symfony/http-client | v4.4.9 | v4.4.10 | https://github.com/symfony/http-client/compare/v4.4.9...v4.4.10 | | symfony/http-foundation | v4.4.7 | v4.4.10 | https://github.com/symfony/http-foundation/compare/v4.4.7...v4.4.10 | | symfony/http-kernel | v4.4.7 | v4.4.10 | https://github.com/symfony/http-kernel/compare/v4.4.7...v4.4.10 | | symfony/inflector | v4.4.7 | v4.4.10 | https://github.com/symfony/inflector/compare/v4.4.7...v4.4.10 | | symfony/intl | v4.4.7 | v4.4.10 | https://github.com/symfony/intl/compare/v4.4.7...v4.4.10 | | symfony/ldap | v4.4.7 | v4.4.10 | https://github.com/symfony/ldap/compare/v4.4.7...v4.4.10 | | symfony/mime | v4.4.7 | v4.4.10 | https://github.com/symfony/mime/compare/v4.4.7...v4.4.10 | | symfony/monolog-bridge | v4.4.7 | v4.4.10 | https://github.com/symfony/monolog-bridge/compare/v4.4.7...v4.4.10 | | symfony/options-resolver | v4.4.7 | v4.4.10 | https://github.com/symfony/options-resolver/compare/v4.4.7...v4.4.10 | | symfony/polyfill-intl-grapheme | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-grapheme/compare/v1.15.0...v1.17.1 | | symfony/polyfill-intl-icu | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-icu/compare/v1.15.0...v1.17.1 | | symfony/polyfill-intl-idn | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-idn/compare/v1.15.0...v1.17.1 | | symfony/polyfill-intl-normalizer | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-intl-normalizer/compare/v1.15.0...v1.17.1 | | symfony/polyfill-mbstring | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-mbstring/compare/v1.15.0...v1.17.1 | | symfony/polyfill-php72 | v1.15.0 | v1.17.0 | https://github.com/symfony/polyfill-php72/compare/v1.15.0...v1.17.0 | | symfony/polyfill-php73 | v1.15.0 | v1.17.1 | https://github.com/symfony/polyfill-php73/compare/v1.15.0...v1.17.1 | | symfony/property-access | v4.4.7 | v4.4.10 | https://github.com/symfony/property-access/compare/v4.4.7...v4.4.10 | | symfony/property-info | v4.4.7 | v4.4.10 | https://github.com/symfony/property-info/compare/v4.4.7...v4.4.10 | | symfony/psr-http-message-bridge | v2.0.0 | v2.0.1 | https://github.com/symfony/psr-http-message-bridge/compare/v2.0.0...v2.0.1 | | symfony/routing | v4.4.7 | v4.4.10 | https://github.com/symfony/routing/compare/v4.4.7...v4.4.10 | | symfony/security-bundle | v4.4.7 | v4.4.10 | https://github.com/symfony/security-bundle/compare/v4.4.7...v4.4.10 | | symfony/security-core | v4.4.7 | v4.4.10 | https://github.com/symfony/security-core/compare/v4.4.7...v4.4.10 | | symfony/security-csrf | v4.4.7 | v4.4.10 | https://github.com/symfony/security-csrf/compare/v4.4.7...v4.4.10 | | symfony/security-guard | v4.4.7 | v4.4.10 | https://github.com/symfony/security-guard/compare/v4.4.7...v4.4.10 | | symfony/security-http | v4.4.7 | v4.4.10 | https://github.com/symfony/security-http/compare/v4.4.7...v4.4.10 | | symfony/serializer | v4.4.7 | v4.4.10 | https://github.com/symfony/serializer/compare/v4.4.7...v4.4.10 | | symfony/service-contracts | v2.0.1 | v2.1.2 | https://github.com/symfony/service-contracts/compare/v2.0.1...v2.1.2 | | symfony/stopwatch | v4.4.7 | v4.4.10 | https://github.com/symfony/stopwatch/compare/v4.4.7...v4.4.10 | | symfony/string | v5.0.7 | v5.1.2 | https://github.com/symfony/string/compare/v5.0.7...v5.1.2 | | symfony/translation | v4.4.7 | v4.4.10 | https://github.com/symfony/translation/compare/v4.4.7...v4.4.10 | | symfony/translation-contracts | v2.0.1 | v2.1.2 | https://github.com/symfony/translation-contracts/compare/v2.0.1...v2.1.2 | | symfony/twig-bridge | v4.4.7 | v4.4.10 | https://github.com/symfony/twig-bridge/compare/v4.4.7...v4.4.10 | | symfony/twig-bundle | v4.4.7 | v4.4.10 | https://github.com/symfony/twig-bundle/compare/v4.4.7...v4.4.10 | | symfony/validator | v4.4.7 | v4.4.10 | https://github.com/symfony/validator/compare/v4.4.7...v4.4.10 | | symfony/var-dumper | v4.4.7 | v4.4.10 | https://github.com/symfony/var-dumper/compare/v4.4.7...v4.4.10 | | symfony/var-exporter | v4.4.7 | v4.4.10 | https://github.com/symfony/var-exporter/compare/v4.4.7...v4.4.10 | | symfony/web-link | v4.4.7 | v4.4.10 | https://github.com/symfony/web-link/compare/v4.4.7...v4.4.10 | | symfony/yaml | v4.4.7 | v4.4.10 | https://github.com/symfony/yaml/compare/v4.4.7...v4.4.10 | | vich/uploader-bundle | 1.13.2 | 1.14.0 | https://github.com/dustin10/VichUploaderBundle/compare/1.13.2...1.14.0 | | symfony/polyfill-php80 | NEW | v1.17.1 | | +----------------------------------+---------+---------+-------------------------------------------------------------------------------+

+------------------------+---------+---------+--------------------------------------------------------------------+ | Dev Changes | From | To | Compare | +------------------------+---------+---------+--------------------------------------------------------------------+ | symfony/maker-bundle | v1.14.6 | v1.19.0 | https://github.com/symfony/maker-bundle/compare/v1.14.6...v1.19.0 | | symfony/phpunit-bridge | v4.4.7 | v4.4.10 | https://github.com/symfony/phpunit-bridge/compare/v4.4.7...v4.4.10 | +------------------------+---------+---------+--------------------------------------------------------------------+

Looks like the trouble might be caused by any "subsequent" dependency updated when using --with-all-dependencies. Have to investigate further...

gschafra commented 4 years ago

O.k... when it comes to doctrine/* updates in the course of doing composer update trikoder/oauth2-bundle --with-all-dependencies, then the problems begin...

+----------------------------------+---------+---------+----------------------------------------------------------------------------------+
| Production Changes               | From    | To      | Compare                                                                          |
+----------------------------------+---------+---------+----------------------------------------------------------------------------------+
| api-platform/core                | v2.5.5  | v2.5.6  | https://github.com/api-platform/core/compare/v2.5.5...v2.5.6                     |
| doctrine/annotations             | 1.10.2  | 1.10.3  | https://github.com/doctrine/annotations/compare/1.10.2...1.10.3                  |
| doctrine/cache                   | 1.10.0  | 1.10.1  | https://github.com/doctrine/cache/compare/1.10.0...1.10.1                        |
| doctrine/collections             | 1.6.4   | 1.6.5   | https://github.com/doctrine/collections/compare/1.6.4...1.6.5                    |
| doctrine/common                  | 2.12.0  | 2.13.3  | https://github.com/doctrine/common/compare/2.12.0...2.13.3                       |
| doctrine/doctrine-bundle         | 1.12.7  | 1.12.10 | https://github.com/doctrine/DoctrineBundle/compare/1.12.7...1.12.10              |
| doctrine/inflector               | 1.3.1   | 1.4.3   | https://github.com/doctrine/inflector/compare/1.3.1...1.4.3                      |
| doctrine/instantiator            | 1.3.0   | 1.3.1   | https://github.com/doctrine/instantiator/compare/1.3.0...1.3.1                   |
| doctrine/lexer                   | 1.2.0   | 1.2.1   | https://github.com/doctrine/lexer/compare/1.2.0...1.2.1                          |
| doctrine/orm                     | v2.7.2  | v2.7.3  | https://github.com/doctrine/orm/compare/v2.7.2...v2.7.3                          |
| lcobucci/jwt                     | 3.3.1   | 3.3.2   | https://github.com/lcobucci/jwt/compare/3.3.1...3.3.2                            |
| league/oauth2-server             | 8.0.0   | 8.1.0   | https://github.com/thephpleague/oauth2-server/compare/8.0.0...8.1.0              |
| sensio/framework-extra-bundle    | v5.5.3  | v5.5.6  | https://github.com/sensiolabs/SensioFrameworkExtraBundle/compare/v5.5.3...v5.5.6 |
....
gschafra commented 4 years ago

Suspect found... doctrine/orm v2.7.3... but why? Maybe somthing for the doctrine/orm issue list?

garak commented 4 years ago

Maybe this PR? https://github.com/doctrine/orm/pull/8138

gschafra commented 4 years ago

Hmmmm... worth to try out/check... thanks a lot @garak

gschafra commented 4 years ago

O.k... seems to be my fault... or an inattention. As stated in the embeddable tutorial a basic @Column mapping, i.e. @Column annotations must be given in the embeddale class definition, which in my case were dropped by mistake (using a derivated embeddable class to do some API-Platform specific annotation complements). Weird, that it worked in v2.7.2... but this might be related to the PR referenced above. For the sake of completeness here what I've changed:

Before:

<?php

    namespace App\Entity;

    use App\Entity\Interfaces\EmbeddedFileInterface;
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\Serializer\Annotation\Groups;
    use Vich\UploaderBundle\Entity\File;

    /**
     * Class File
     *
     * @package App\Entity
     *
     * @ORM\Embeddable
     */
    class EmbeddedFile extends File implements EmbeddedFileInterface
    {
        /**
         * The entity id
         *
         * @var int|string|null
         */
        private $id;

        /**
         * @var string
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         */
        protected $name;

        /**
         * @var string
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         */
        protected $originalName;

        /**
         * @var string
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         */
        protected $mimeType;

        /**
         * @var int
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         */
        protected $size;

        /**
         * @var array
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         */
        protected $dimensions;

        /**
         * @var string|null
         *
         * @ORM\Column(name="url", type="string", length=255, nullable=true)
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         */
        protected $url;

        /**
         * @return int|string|null
         */
        public function getId()
        {
            return $this->id;
        }

        /**
         * @param int|string|null $id
         */
        public function setId($id): void
        {
            $this->id = $id;
        }

        /**
         * @return string|null
         */
        public function getUrl(): ?string
        {
            return $this->url;
        }

        /**
         * @param string|null $url
         */
        public function setUrl(?string $url): void
        {
            $this->url = $url;
        }
    }

After:

<?php

    namespace App\Entity;

    use App\Entity\Interfaces\EmbeddedFileInterface;
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\Serializer\Annotation\Groups;
    use Vich\UploaderBundle\Entity\File;

    /**
     * Class File
     *
     * @package App\Entity
     *
     * @ORM\Embeddable
     */
    class EmbeddedFile extends File implements EmbeddedFileInterface
    {
        /**
         * The entity id
         *
         * @var int|string|null
         */
        private $id;

        /**
         * @var string
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         *
         * @ORM\Column(name="name", nullable=true)
         */
        protected $name;

        /**
         * @var string
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         *
         * @ORM\Column(name="original_name", nullable=true)
         */
        protected $originalName;

        /**
         * @var string
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         *
         * @ORM\Column(name="mime_type", nullable=true)
         */
        protected $mimeType;

        /**
         * @var int
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         *
         * @ORM\Column(name="size", type="integer", nullable=true)
         */
        protected $size;

        /**
         * @var array
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         *
         * @ORM\Column(name="dimensions", type="simple_array", nullable=true)
         */
        protected $dimensions;

        /**
         * @var string|null
         *
         * @ORM\Column(name="url", type="string", length=255, nullable=true)
         *
         * @Groups({"idd_read", "idd_write", "document_read", "document_write", "message_document_read", "message_document_write", "message_read"})
         *
         * @ORM\Column(type="string")
         */
        protected $url;

        /**
         * @return int|string|null
         */
        public function getId()
        {
            return $this->id;
        }

        /**
         * @param int|string|null $id
         */
        public function setId($id): void
        {
            $this->id = $id;
        }

        /**
         * @return string|null
         */
        public function getUrl(): ?string
        {
            return $this->url;
        }

        /**
         * @param string|null $url
         */
        public function setUrl(?string $url): void
        {
            $this->url = $url;
        }
    }