From 824afd2fb3d74a0c97620f13b4711a08e1c9073b Mon Sep 17 00:00:00 2001 From: Georgi Georgiev Date: Thu, 5 Sep 2024 13:29:53 +0300 Subject: [PATCH] feat: Adding support for Symfony attributed: SerializedName & Groups (#42) --- composer.json | 15 +- composer.lock | 281 ++++++++++++------ src/Metadata/MetadataExtractor.php | 66 +++- .../Symfony/SymfonyAnnotatedObject.php | 39 +++ tests/Unit/SymfonyTest.php | 50 ++++ 5 files changed, 339 insertions(+), 112 deletions(-) create mode 100644 tests/Datasets/Symfony/SymfonyAnnotatedObject.php create mode 100644 tests/Unit/SymfonyTest.php diff --git a/composer.json b/composer.json index 40953bd..dbb671a 100755 --- a/composer.json +++ b/composer.json @@ -5,17 +5,18 @@ "license": "MIT", "require": { "php": "^8.3", - "symfony/property-info": "^7.1", - "phpdocumentor/reflection-docblock": "^5.4", - "phpstan/phpdoc-parser": "^1.29", + "symfony/property-info": "^7.1.3", + "phpdocumentor/reflection-docblock": "^5.4.1", + "phpstan/phpdoc-parser": "^1.30", "psr/cache": "^3.0" }, "require-dev": { - "pestphp/pest": "^2.34", - "vimeo/psalm": "^5.24", + "pestphp/pest": "^2.35.1", + "vimeo/psalm": "^5.25", "pestphp/pest-plugin-faker": "^2.0", - "friendsofphp/php-cs-fixer": "^3.58", - "mockery/mockery": "^1.6" + "friendsofphp/php-cs-fixer": "^3.64", + "mockery/mockery": "^1.6.12", + "symfony/serializer": "^7.1.4" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 89f421a..c5ad058 100755 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2bdc1e8b8a28a2cbf59762cd26eb3576", + "content-hash": "1c78c285cc455faada6c1d388631b1ac", "packages": [ { "name": "doctrine/deprecations", @@ -230,16 +230,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.1", + "version": "1.30.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/5ceb0e384997db59f38774bf79c2a6134252c08f", + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f", "shasum": "" }, "require": { @@ -271,9 +271,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.0" }, - "time": "2024-05-31T08:52:43+00:00" + "time": "2024-08-29T09:54:52+00:00" }, { "name": "psr/cache", @@ -781,16 +781,16 @@ }, { "name": "symfony/string", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ea272a882be7f20cad58d5d78c215001617b7f07" + "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07", - "reference": "ea272a882be7f20cad58d5d78c215001617b7f07", + "url": "https://api.github.com/repos/symfony/string/zipball/6cd670a6d968eaeb1c77c2e76091c45c56bc367b", + "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b", "shasum": "" }, "require": { @@ -848,7 +848,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.3" + "source": "https://github.com/symfony/string/tree/v7.1.4" }, "funding": [ { @@ -864,7 +864,7 @@ "type": "tidelift" } ], - "time": "2024-07-22T10:25:37+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "symfony/type-info", @@ -1328,26 +1328,26 @@ }, { "name": "composer/pcre", - "version": "3.2.0", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90" + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/ea4ab6f9580a4fd221e0418f2c357cdd39102a90", - "reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90", + "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, "conflict": { - "phpstan/phpstan": "<1.11.8" + "phpstan/phpstan": "<1.11.10" }, "require-dev": { - "phpstan/phpstan": "^1.11.8", + "phpstan/phpstan": "^1.11.10", "phpstan/phpstan-strict-rules": "^1.1", "phpunit/phpunit": "^8 || ^9" }, @@ -1387,7 +1387,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.2.0" + "source": "https://github.com/composer/pcre/tree/3.3.1" }, "funding": [ { @@ -1403,7 +1403,7 @@ "type": "tidelift" } ], - "time": "2024-07-25T09:36:02+00:00" + "time": "2024-08-27T18:44:43+00:00" }, { "name": "composer/semver", @@ -1802,16 +1802,16 @@ }, { "name": "fidry/cpu-core-counter", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + "reference": "8520451a140d3f46ac33042715115e290cf5785f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", "shasum": "" }, "require": { @@ -1851,7 +1851,7 @@ ], "support": { "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" }, "funding": [ { @@ -1859,7 +1859,7 @@ "type": "github" } ], - "time": "2024-02-07T09:43:46+00:00" + "time": "2024-08-06T10:04:20+00:00" }, { "name": "filp/whoops", @@ -1934,16 +1934,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.61.1", + "version": "v3.64.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "94a87189f55814e6cabca2d9a33b06de384a2ab8" + "reference": "58dd9c931c785a79739310aef5178928305ffa67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/94a87189f55814e6cabca2d9a33b06de384a2ab8", - "reference": "94a87189f55814e6cabca2d9a33b06de384a2ab8", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/58dd9c931c785a79739310aef5178928305ffa67", + "reference": "58dd9c931c785a79739310aef5178928305ffa67", "shasum": "" }, "require": { @@ -2025,7 +2025,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.61.1" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.64.0" }, "funding": [ { @@ -2033,7 +2033,7 @@ "type": "github" } ], - "time": "2024-07-31T14:33:15+00:00" + "time": "2024-08-30T23:09:38+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -2397,23 +2397,23 @@ }, { "name": "nunomaduro/collision", - "version": "v8.3.0", + "version": "v8.4.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "b49f5b2891ce52726adfd162841c69d4e4c84229" + "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/b49f5b2891ce52726adfd162841c69d4e4c84229", - "reference": "b49f5b2891ce52726adfd162841c69d4e4c84229", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/e7d1aa8ed753f63fa816932bbc89678238843b4a", + "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a", "shasum": "" }, "require": { "filp/whoops": "^2.15.4", "nunomaduro/termwind": "^2.0.1", "php": "^8.2.0", - "symfony/console": "^7.1.2" + "symfony/console": "^7.1.3" }, "conflict": { "laravel/framework": "<11.0.0 || >=12.0.0", @@ -2421,13 +2421,13 @@ }, "require-dev": { "larastan/larastan": "^2.9.8", - "laravel/framework": "^11.16.0", - "laravel/pint": "^1.16.2", - "laravel/sail": "^1.30.2", + "laravel/framework": "^11.19.0", + "laravel/pint": "^1.17.1", + "laravel/sail": "^1.31.0", "laravel/sanctum": "^4.0.2", "laravel/tinker": "^2.9.0", - "orchestra/testbench-core": "^9.2.1", - "pestphp/pest": "^2.34.9 || ^3.0.0", + "orchestra/testbench-core": "^9.2.3", + "pestphp/pest": "^2.35.0 || ^3.0.0", "sebastian/environment": "^6.1.0 || ^7.0.0" }, "type": "library", @@ -2490,7 +2490,7 @@ "type": "patreon" } ], - "time": "2024-07-16T22:41:01+00:00" + "time": "2024-08-03T15:32:23+00:00" }, { "name": "nunomaduro/termwind", @@ -2582,21 +2582,21 @@ }, { "name": "pestphp/pest", - "version": "v2.35.0", + "version": "v2.35.1", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "d0ff2c8ec294b7aa7fcb0f3ddc4fdec864234646" + "reference": "b13acb630df52c06123588d321823c31fc685545" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/d0ff2c8ec294b7aa7fcb0f3ddc4fdec864234646", - "reference": "d0ff2c8ec294b7aa7fcb0f3ddc4fdec864234646", + "url": "https://api.github.com/repos/pestphp/pest/zipball/b13acb630df52c06123588d321823c31fc685545", + "reference": "b13acb630df52c06123588d321823c31fc685545", "shasum": "" }, "require": { "brianium/paratest": "^7.3.1", - "nunomaduro/collision": "^7.10.0|^8.3.0", + "nunomaduro/collision": "^7.10.0|^8.4.0", "nunomaduro/termwind": "^1.15.1|^2.0.1", "pestphp/pest-plugin": "^2.1.1", "pestphp/pest-plugin-arch": "^2.7.0", @@ -2674,7 +2674,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v2.35.0" + "source": "https://github.com/pestphp/pest/tree/v2.35.1" }, "funding": [ { @@ -2686,7 +2686,7 @@ "type": "github" } ], - "time": "2024-08-02T10:57:29+00:00" + "time": "2024-08-20T21:41:50+00:00" }, { "name": "pestphp/pest-plugin", @@ -3014,32 +3014,32 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.15", + "version": "10.1.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae" + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", - "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", + "nikic/php-parser": "^4.19.1 || ^5.1.0", "php": ">=8.1", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-text-template": "^3.0", - "sebastian/code-unit-reverse-lookup": "^3.0", - "sebastian/complexity": "^3.0", - "sebastian/environment": "^6.0", - "sebastian/lines-of-code": "^2.0", - "sebastian/version": "^4.0", - "theseer/tokenizer": "^1.2.0" + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { "phpunit/phpunit": "^10.1" @@ -3051,7 +3051,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1-dev" + "dev-main": "10.1.x-dev" } }, "autoload": { @@ -3080,7 +3080,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, "funding": [ { @@ -3088,7 +3088,7 @@ "type": "github" } ], - "time": "2024-06-29T08:25:15+00:00" + "time": "2024-08-22T04:31:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -3486,16 +3486,16 @@ }, { "name": "psr/log", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "79dff0b268932c640297f5208d6298f71855c03e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e", + "reference": "79dff0b268932c640297f5208d6298f71855c03e", "shasum": "" }, "require": { @@ -3530,9 +3530,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.1" }, - "time": "2021-07-14T16:46:02+00:00" + "time": "2024-08-21T13:31:24+00:00" }, { "name": "react/cache", @@ -4234,16 +4234,16 @@ }, { "name": "sebastian/comparator", - "version": "5.0.1", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372" + "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53", + "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53", "shasum": "" }, "require": { @@ -4254,7 +4254,7 @@ "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^10.3" + "phpunit/phpunit": "^10.4" }, "type": "library", "extra": { @@ -4299,7 +4299,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.2" }, "funding": [ { @@ -4307,7 +4307,7 @@ "type": "github" } ], - "time": "2023-08-14T13:18:12+00:00" + "time": "2024-08-12T06:03:08+00:00" }, { "name": "sebastian/complexity", @@ -5050,16 +5050,16 @@ }, { "name": "symfony/console", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9" + "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", - "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", + "url": "https://api.github.com/repos/symfony/console/zipball/1eed7af6961d763e7832e874d7f9b21c3ea9c111", + "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111", "shasum": "" }, "require": { @@ -5123,7 +5123,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.3" + "source": "https://github.com/symfony/console/tree/v7.1.4" }, "funding": [ { @@ -5139,7 +5139,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-08-15T22:48:53+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5432,16 +5432,16 @@ }, { "name": "symfony/finder", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "717c6329886f32dc65e27461f80f2a465412fdca" + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca", - "reference": "717c6329886f32dc65e27461f80f2a465412fdca", + "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", "shasum": "" }, "require": { @@ -5476,7 +5476,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.3" + "source": "https://github.com/symfony/finder/tree/v7.1.4" }, "funding": [ { @@ -5492,7 +5492,7 @@ "type": "tidelift" } ], - "time": "2024-07-24T07:08:44+00:00" + "time": "2024-08-13T14:28:19+00:00" }, { "name": "symfony/options-resolver", @@ -5778,6 +5778,103 @@ ], "time": "2024-07-26T12:44:47+00:00" }, + { + "name": "symfony/serializer", + "version": "v7.1.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/serializer.git", + "reference": "0158b0e91b7cf7e744a6fb9acaeb613d1ca40dbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/serializer/zipball/0158b0e91b7cf7e744a6fb9acaeb613d1ca40dbb", + "reference": "0158b0e91b7cf7e744a6fb9acaeb613d1ca40dbb", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/dependency-injection": "<6.4", + "symfony/property-access": "<6.4", + "symfony/property-info": "<6.4", + "symfony/uid": "<6.4", + "symfony/validator": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", + "seld/jsonlint": "^1.10", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/type-info": "^7.1", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Serializer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/serializer/tree/v7.1.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-08-22T09:39:57+00:00" + }, { "name": "symfony/service-contracts", "version": "v3.5.0", diff --git a/src/Metadata/MetadataExtractor.php b/src/Metadata/MetadataExtractor.php index 6ce2df6..0d19566 100644 --- a/src/Metadata/MetadataExtractor.php +++ b/src/Metadata/MetadataExtractor.php @@ -85,19 +85,7 @@ private function extractPropertyMetadata( \ReflectionProperty $reflectionProperty, string $propertyName ): PropertyMetadata { - $serializerContexts = $reflectionProperty->getAttributes(SerializerContext::class); - - if (count($serializerContexts) > 1) { - throw new InvalidAttributeUsageException( - sprintf( - 'Property "%s" of class "%s" has more than one SerializerContext attribute', - $reflectionProperty->getName(), - $reflectionProperty->getDeclaringClass()->getName(), - ), - ); - } - - $serializerContext = isset($serializerContexts[0]) ? $serializerContexts[0]->newInstance() : new SerializerContext(); + $serializerContext = $this->getSerializerContext($reflectionProperty); return new PropertyMetadata( name: $propertyName, @@ -316,4 +304,56 @@ private function extractConstructorMetadata(\ReflectionClass $reflectionClass): return new ConstructorMetadata(isPublic: $isPublic, arguments: $arguments); } + + /** + * @throws InvalidAttributeUsageException + */ + public function getSerializerContext(\ReflectionProperty $reflectionProperty): SerializerContext + { + $symfonySerializedName = null; + $symfonySerializerGroups = []; + $serializerContexts = $reflectionProperty->getAttributes(SerializerContext::class); + + if (count($serializerContexts) > 1) { + throw new InvalidAttributeUsageException( + sprintf( + 'Property "%s" of class "%s" has more than one SerializerContext attribute', + $reflectionProperty->getName(), + $reflectionProperty->getDeclaringClass()->getName(), + ), + ); + } + + if (class_exists('\Symfony\Component\Serializer\Attribute\SerializedName')) { + $symfonySerializedNameAttribute = $reflectionProperty->getAttributes( + \Symfony\Component\Serializer\Attribute\SerializedName::class + ); + + if (isset($symfonySerializedNameAttribute[0])) { + $symfonySerializedName = $symfonySerializedNameAttribute[0]->newInstance()->getSerializedName(); + } + } + + if (class_exists('\Symfony\Component\Serializer\Attribute\Groups')) { + $symfonySerializerGroupsAttribute = $reflectionProperty->getAttributes( + \Symfony\Component\Serializer\Attribute\Groups::class + ); + + foreach ($symfonySerializerGroupsAttribute as $attribute) { + $symfonySerializerGroups = $attribute->newInstance()->getGroups(); + } + } + + $serializerContext = isset($serializerContexts[0]) ? $serializerContexts[0]->newInstance() : new SerializerContext(); + + if (null === $serializerContext->name && null !== $symfonySerializedName) { + $serializerContext->name = $symfonySerializedName; + } + + if ([] === $serializerContext->groups && [] !== $symfonySerializerGroups) { + $serializerContext->groups = $symfonySerializerGroups; + } + + return $serializerContext; + } } diff --git a/tests/Datasets/Symfony/SymfonyAnnotatedObject.php b/tests/Datasets/Symfony/SymfonyAnnotatedObject.php new file mode 100644 index 0000000..ed3e048 --- /dev/null +++ b/tests/Datasets/Symfony/SymfonyAnnotatedObject.php @@ -0,0 +1,39 @@ +serialize($object); + + expect($json)->toBe('{"some_property":5,"another_property":7,"some_field":"foo","another_field":"bar","this_has_priority":"really?","and_another_field":"blah"}'); + + $json = $serializer->serialize($object, ['groups' => ['group1']]); + + expect($json)->toBe('{"another_property":7,"some_field":"foo","this_has_priority":"really?","and_another_field":"blah"}'); + + $json = $serializer->serialize($object, ['groups' => ['group2']]); + + expect($json)->toBe('{"another_field":"bar"}'); +}); + +test('Can deserialized with Symfony serializer attributes', function () { + $json = '{"some_property":51,"another_property":71,"some_field":"foobar","another_field":"barfoo","this_has_priority":"nope","and_another_field":"111"}'; + $serializer = new \Vuryss\Serializer\Serializer(); + $person = $serializer->deserialize($json, \Vuryss\Serializer\Tests\Datasets\Symfony\SymfonyAnnotatedObject::class); + + expect($person->someProperty)->toBe(51) + ->and($person->anotherProperty)->toBe(71) + ->and($person->someField)->toBe('foobar') + ->and($person->anotherField)->toBe('barfoo') + ->and($person->yetAnotherField)->toBe('nope') + ->and($person->andAnotherField)->toBe('111'); + + $person = $serializer->deserialize($json, \Vuryss\Serializer\Tests\Datasets\Symfony\SymfonyAnnotatedObject::class, ['groups' => ['group1']]); + + expect($person->someProperty)->toBe(5) + ->and($person->anotherProperty)->toBe(71) + ->and($person->someField)->toBe('foobar') + ->and($person->anotherField)->toBe('bar') + ->and($person->yetAnotherField)->toBe('nope') + ->and($person->andAnotherField)->toBe('111'); + + $person = $serializer->deserialize($json, \Vuryss\Serializer\Tests\Datasets\Symfony\SymfonyAnnotatedObject::class, ['groups' => ['group2']]); + + expect($person->someProperty)->toBe(5) + ->and($person->anotherProperty)->toBe(7) + ->and($person->someField)->toBe('foo') + ->and($person->anotherField)->toBe('barfoo') + ->and($person->yetAnotherField)->toBe('really?') + ->and($person->andAnotherField)->toBe('blah'); +});