From 44293afc52160038c4e08cb932eca23c0fb27f1a Mon Sep 17 00:00:00 2001 From: David Badura Date: Sat, 3 Oct 2026 11:34:01 +0200 Subject: [PATCH] Adapt to hydrator 2 and the latest event-sourcing 4.0 changes event-sourcing 4.0.x now requires hydrator 2, so the bundle could no longer be installed. The normalizers get the new context argument, the renamed DoctrineCipherKeyStore is used and upcasters are now hydrator upcasters collected into an UpcastExtension. Also fixes the namespace of two test fixtures that were never autoloaded. --- composer.json | 2 +- composer.lock | 364 +++++++++--------- docs/usage.md | 23 +- phpstan-baseline.neon | 2 +- .../HydratorCompilerPass.php | 12 + .../PatchlevelEventSourcingExtension.php | 21 +- src/Normalizer/DatePointNormalizer.php | 6 +- src/Normalizer/UidNormalizer.php | 6 +- tests/Fixtures/DummyExtension.php | 2 +- tests/Fixtures/DummyGuesser.php | 2 +- tests/Fixtures/DummyUpcaster.php | 22 ++ .../PatchlevelEventSourcingBundleTest.php | 30 +- 12 files changed, 288 insertions(+), 204 deletions(-) create mode 100644 tests/Fixtures/DummyUpcaster.php diff --git a/composer.json b/composer.json index 5eb3de11..aeb9f160 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "require": { "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", "patchlevel/event-sourcing": "4.0.x-dev", - "patchlevel/hydrator": "^1.21.2", + "patchlevel/hydrator": "^2.0.2", "symfony/cache": "^6.4.0 || ^7.0.0 || ^8.0.0", "symfony/config": "^6.4.0 || ^7.0.0 || ^8.0.0", "symfony/console": "^6.4.1 || ^7.0.1 || ^8.0.0", diff --git a/composer.lock b/composer.lock index 3fda10de..eeaeeaba 100644 --- a/composer.lock +++ b/composer.lock @@ -4,27 +4,28 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "43e01b6335841afbf0b83487ba30b960", + "content-hash": "e8e556d60159c0d8a9127c205fd6e149", "packages": [ { "name": "brick/math", - "version": "0.18.0", + "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "82944324d1c1bdb2c2618e89978d4e2ad78d69ad" + "reference": "2effe05d2177c451b86c6a073196a4034c02f211" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/82944324d1c1bdb2c2618e89978d4e2ad78d69ad", - "reference": "82944324d1c1bdb2c2618e89978d4e2ad78d69ad", + "url": "https://api.github.com/repos/brick/math/zipball/2effe05d2177c451b86c6a073196a4034c02f211", + "reference": "2effe05d2177c451b86c6a073196a4034c02f211", "shasum": "" }, "require": { "php": "^8.2" }, "require-dev": { - "phpstan/phpstan": "2.1.22", + "phpstan/phpstan": "2.2.13", + "phpstan/phpstan-phpunit": "2.0.18", "phpunit/phpunit": "^11.5" }, "type": "library", @@ -55,7 +56,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.18.0" + "source": "https://github.com/brick/math/tree/1.0.0" }, "funding": [ { @@ -63,20 +64,20 @@ "type": "github" } ], - "time": "2026-06-14T18:21:03+00:00" + "time": "2026-09-12T10:28:18+00:00" }, { "name": "doctrine/dbal", - "version": "4.4.4", + "version": "4.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "fb9e0ffe15e1590e24dc61c0c0a23f9a33ee42ce" + "reference": "c435cd7ea33e17d2a89288caf994cf3d4549b879" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/fb9e0ffe15e1590e24dc61c0c0a23f9a33ee42ce", - "reference": "fb9e0ffe15e1590e24dc61c0c0a23f9a33ee42ce", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/c435cd7ea33e17d2a89288caf994cf3d4549b879", + "reference": "c435cd7ea33e17d2a89288caf994cf3d4549b879", "shasum": "" }, "require": { @@ -92,9 +93,9 @@ "phpstan/phpstan": "2.1.30", "phpstan/phpstan-phpunit": "2.0.7", "phpstan/phpstan-strict-rules": "^2", - "phpunit/phpunit": "11.5.50", - "slevomat/coding-standard": "8.27.1", - "squizlabs/php_codesniffer": "4.0.1", + "phpunit/phpunit": "11.5.56", + "slevomat/coding-standard": "8.31.1", + "squizlabs/php_codesniffer": "4.0.4", "symfony/cache": "^6.3.8|^7.0|^8.0", "symfony/console": "^5.4|^6.3|^7.0|^8.0" }, @@ -153,7 +154,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/4.4.4" + "source": "https://github.com/doctrine/dbal/tree/4.5.0" }, "funding": [ { @@ -169,7 +170,7 @@ "type": "tidelift" } ], - "time": "2026-07-21T14:34:40+00:00" + "time": "2026-09-24T16:11:26+00:00" }, { "name": "doctrine/deprecations", @@ -419,18 +420,18 @@ "source": { "type": "git", "url": "https://github.com/patchlevel/event-sourcing.git", - "reference": "84bac18018a0e14c6fef8a364fa6e5a298008a69" + "reference": "ade8292ca34e1f8c398e31e4a43c01973548f757" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/patchlevel/event-sourcing/zipball/84bac18018a0e14c6fef8a364fa6e5a298008a69", - "reference": "84bac18018a0e14c6fef8a364fa6e5a298008a69", + "url": "https://api.github.com/repos/patchlevel/event-sourcing/zipball/ade8292ca34e1f8c398e31e4a43c01973548f757", + "reference": "ade8292ca34e1f8c398e31e4a43c01973548f757", "shasum": "" }, "require": { "doctrine/dbal": "^4.4.0", "doctrine/migrations": "^3.3.2", - "patchlevel/hydrator": "^1.24.0", + "patchlevel/hydrator": "^2.0.2", "patchlevel/worker": "^1.4.0", "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", "psr/cache": "^2.0.0 || ^3.0.0", @@ -456,6 +457,7 @@ "phpstan/phpstan": "^2.1.11", "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^11.5.15", + "symfony/cache": "^6.4.0 || ^7.0.0 || ^8.0.0", "symfony/messenger": "^5.4.31 || ^6.4.0 || ^7.0.1 || ^8.0.0", "symfony/var-dumper": "^5.4.29 || ^6.4.0 || ^7.0.0 || ^8.0.0", "wnx/commonmark-markdown-renderer": "^1.5.0" @@ -505,20 +507,20 @@ "issues": "https://github.com/patchlevel/event-sourcing/issues", "source": "https://github.com/patchlevel/event-sourcing/tree/4.0.x" }, - "time": "2026-08-23T10:07:28+00:00" + "time": "2026-09-24T06:22:35+00:00" }, { "name": "patchlevel/hydrator", - "version": "1.24.0", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/patchlevel/hydrator.git", - "reference": "b33d9f92b25114156e9935c12c563195afdbeb13" + "reference": "73aee5f6d9e35ba074ff2d4ade17cb1429475af7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/patchlevel/hydrator/zipball/b33d9f92b25114156e9935c12c563195afdbeb13", - "reference": "b33d9f92b25114156e9935c12c563195afdbeb13", + "url": "https://api.github.com/repos/patchlevel/hydrator/zipball/73aee5f6d9e35ba074ff2d4ade17cb1429475af7", + "reference": "73aee5f6d9e35ba074ff2d4ade17cb1429475af7", "shasum": "" }, "require": { @@ -526,7 +528,6 @@ "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", "psr/cache": "^2.0.0 || ^3.0.0", "psr/simple-cache": "^2.0.0 || ^3.0.0", - "symfony/event-dispatcher": "^5.4.29 || ^6.4.0 || ^7.0.0 || ^8.0.0", "symfony/type-info": "^7.3.0 || ^8.0.0" }, "require-dev": { @@ -537,6 +538,7 @@ "phpstan/phpstan": "^2.1.39", "phpstan/phpstan-phpunit": "^2.0.15", "phpunit/phpunit": "^11.5.53", + "symfony/cache": "^6.4.0 || ^7.0.0 || ^8.0.0", "symfony/var-dumper": "^5.4.29 || ^6.4.0 || ^7.0.0 || ^8.0.0" }, "type": "library", @@ -559,45 +561,55 @@ "email": "david.badura@patchlevel.de" } ], - "description": "Hydrator", - "homepage": "https://github.com/patchlevel/hydrator", + "description": "A library for seamless hydration of objects to arrays - and back again, optimized for developer experience and performance", + "homepage": "https://patchlevel.dev/docs/hydrator/latest", "keywords": [ + "denormalizer", "hydrator", + "normalizer", + "object mapping", + "patchlevel", "serializer" ], "support": { "issues": "https://github.com/patchlevel/hydrator/issues", - "source": "https://github.com/patchlevel/hydrator/tree/1.24.0" + "source": "https://github.com/patchlevel/hydrator/tree/2.0.2" }, - "time": "2026-06-13T11:46:58+00:00" + "time": "2026-09-23T17:48:35+00:00" }, { "name": "patchlevel/worker", - "version": "1.5.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/patchlevel/worker.git", - "reference": "0288d740de7d9806d8dc9dd4c2545be31a043823" + "reference": "eae43edaeb4a96f275c7e8ed05dfa95fc1a3ee9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/patchlevel/worker/zipball/0288d740de7d9806d8dc9dd4c2545be31a043823", - "reference": "0288d740de7d9806d8dc9dd4c2545be31a043823", + "url": "https://api.github.com/repos/patchlevel/worker/zipball/eae43edaeb4a96f275c7e8ed05dfa95fc1a3ee9c", + "reference": "eae43edaeb4a96f275c7e8ed05dfa95fc1a3ee9c", "shasum": "" }, "require": { "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "psr/clock": "^1.0", + "psr/log": "^1.1 || ^2.0 || ^3.0", "symfony/event-dispatcher": "^5.4.26 || ^6.4.0 || ^7.0.0 || ^8.0.0" }, "require-dev": { - "infection/infection": "^0.31.9", + "infection/infection": "^0.32.0", "patchlevel/coding-standard": "^1.3.0", "phpat/phpat": "^0.12.0", "phpbench/phpbench": "^1.2.15", "phpstan/phpstan": "^2.1.32", "phpstan/phpstan-phpunit": "^2.0.8", "phpunit/phpunit": "^11.5.3", - "symfony/var-dumper": "^5.4.29 || ^6.4.0 || ^7.0.0 || ^8.0.0" + "symfony/var-dumper": "^5.4.29 || ^6.4.0 || ^7.0.0 || ^8.0.0", + "wnx/commonmark-markdown-renderer": "^1.6" + }, + "suggest": { + "ext-pcntl": "Required to stop the worker gracefully on SIGTERM" }, "type": "library", "autoload": { @@ -627,9 +639,9 @@ ], "support": { "issues": "https://github.com/patchlevel/worker/issues", - "source": "https://github.com/patchlevel/worker/tree/1.5.0" + "source": "https://github.com/patchlevel/worker/tree/1.6.0" }, - "time": "2025-11-27T15:33:31+00:00" + "time": "2026-10-02T17:54:07+00:00" }, { "name": "psr/cache", @@ -1010,20 +1022,20 @@ }, { "name": "ramsey/uuid", - "version": "4.9.3", + "version": "4.9.4", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "1df15849d00943a67d677dc9cfd80795f038c9f8" + "reference": "75d73f48d02797c2c285a7e9f348fadc0102ffe2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/1df15849d00943a67d677dc9cfd80795f038c9f8", - "reference": "1df15849d00943a67d677dc9cfd80795f038c9f8", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/75d73f48d02797c2c285a7e9f348fadc0102ffe2", + "reference": "75d73f48d02797c2c285a7e9f348fadc0102ffe2", "shasum": "" }, "require": { - "brick/math": ">=0.8.16 <=0.18", + "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14 || ^0.15 || ^0.16 || ^0.17 || ^0.18 || ^0.19 || ^0.20 || ^1.0", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" }, @@ -1082,9 +1094,9 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.9.3" + "source": "https://github.com/ramsey/uuid/tree/4.9.4" }, - "time": "2026-06-18T03:57:49+00:00" + "time": "2026-09-16T11:39:30+00:00" }, { "name": "symfony/cache", @@ -1422,16 +1434,16 @@ }, { "name": "symfony/console", - "version": "v8.1.5", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d07c06839e33047e2c894a6793248f3fb66c8129" + "reference": "4b81146e3ee248ea969186f85499b54fbc78db08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d07c06839e33047e2c894a6793248f3fb66c8129", - "reference": "d07c06839e33047e2c894a6793248f3fb66c8129", + "url": "https://api.github.com/repos/symfony/console/zipball/4b81146e3ee248ea969186f85499b54fbc78db08", + "reference": "4b81146e3ee248ea969186f85499b54fbc78db08", "shasum": "" }, "require": { @@ -1498,7 +1510,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v8.1.5" + "source": "https://github.com/symfony/console/tree/v8.1.8" }, "funding": [ { @@ -1518,7 +1530,7 @@ "type": "tidelift" } ], - "time": "2026-08-21T14:29:57+00:00" + "time": "2026-09-18T16:00:27+00:00" }, { "name": "symfony/dependency-injection", @@ -1921,16 +1933,16 @@ }, { "name": "symfony/filesystem", - "version": "v8.1.5", + "version": "v8.1.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "6b2f4a0eeb28b5d74f90862592923a654bc629b3" + "reference": "7599ebb855fede59413ddb7f15198d67bfcae7ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/6b2f4a0eeb28b5d74f90862592923a654bc629b3", - "reference": "6b2f4a0eeb28b5d74f90862592923a654bc629b3", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/7599ebb855fede59413ddb7f15198d67bfcae7ba", + "reference": "7599ebb855fede59413ddb7f15198d67bfcae7ba", "shasum": "" }, "require": { @@ -1968,7 +1980,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v8.1.5" + "source": "https://github.com/symfony/filesystem/tree/v8.1.6" }, "funding": [ { @@ -1988,20 +2000,20 @@ "type": "tidelift" } ], - "time": "2026-08-21T12:16:08+00:00" + "time": "2026-08-23T10:06:25+00:00" }, { "name": "symfony/finder", - "version": "v8.1.5", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "8d7acede2b2ae07605783d1c43e49b5767036474" + "reference": "bd4fed193a3132c91c5c93595cbfc78988915822" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/8d7acede2b2ae07605783d1c43e49b5767036474", - "reference": "8d7acede2b2ae07605783d1c43e49b5767036474", + "url": "https://api.github.com/repos/symfony/finder/zipball/bd4fed193a3132c91c5c93595cbfc78988915822", + "reference": "bd4fed193a3132c91c5c93595cbfc78988915822", "shasum": "" }, "require": { @@ -2036,7 +2048,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v8.1.5" + "source": "https://github.com/symfony/finder/tree/v8.1.8" }, "funding": [ { @@ -2056,7 +2068,7 @@ "type": "tidelift" } ], - "time": "2026-08-21T12:16:08+00:00" + "time": "2026-09-26T06:33:49+00:00" }, { "name": "symfony/http-foundation", @@ -2426,16 +2438,16 @@ }, { "name": "symfony/polyfill-deepclone", - "version": "v1.42.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-deepclone.git", - "reference": "70ba0627efc68e97ea392843458a2dd9d6dbd156" + "reference": "8db92c5508a3f7f82d8688d32f0a4868a26e58ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-deepclone/zipball/70ba0627efc68e97ea392843458a2dd9d6dbd156", - "reference": "70ba0627efc68e97ea392843458a2dd9d6dbd156", + "url": "https://api.github.com/repos/symfony/polyfill-deepclone/zipball/8db92c5508a3f7f82d8688d32f0a4868a26e58ad", + "reference": "8db92c5508a3f7f82d8688d32f0a4868a26e58ad", "shasum": "" }, "require": { @@ -2489,7 +2501,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-deepclone/tree/v1.42.0" + "source": "https://github.com/symfony/polyfill-deepclone/tree/v1.43.0" }, "funding": [ { @@ -2509,20 +2521,20 @@ "type": "tidelift" } ], - "time": "2026-08-07T06:33:24+00:00" + "time": "2026-09-30T09:07:27+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.41.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d" + "reference": "5cac8f4db97208823aa353f59a01faad2da52c75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/bb899c1db0aa8127dc3afe8cda4a67eb24915f8d", - "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5cac8f4db97208823aa353f59a01faad2da52c75", + "reference": "5cac8f4db97208823aa353f59a01faad2da52c75", "shasum": "" }, "require": { @@ -2571,7 +2583,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.41.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.43.0" }, "funding": [ { @@ -2591,20 +2603,20 @@ "type": "tidelift" } ], - "time": "2026-07-28T08:25:59+00:00" + "time": "2026-09-25T15:46:47+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.42.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502" + "reference": "ebd57ccc7edb93d632e184efbe7693d2517bab3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/aa20edea75bd9c48cfecc8360922e5a6e5c44502", - "reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/ebd57ccc7edb93d632e184efbe7693d2517bab3b", + "reference": "ebd57ccc7edb93d632e184efbe7693d2517bab3b", "shasum": "" }, "require": { @@ -2656,7 +2668,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.42.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.43.0" }, "funding": [ { @@ -2676,20 +2688,20 @@ "type": "tidelift" } ], - "time": "2026-08-07T06:33:24+00:00" + "time": "2026-09-23T22:02:09+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.38.2", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" + "reference": "4d5d331bf731e0aedbc6b2f5e61135b7b7996a72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", - "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/4d5d331bf731e0aedbc6b2f5e61135b7b7996a72", + "reference": "4d5d331bf731e0aedbc6b2f5e61135b7b7996a72", "shasum": "" }, "require": { @@ -2741,7 +2753,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.43.0" }, "funding": [ { @@ -2761,20 +2773,20 @@ "type": "tidelift" } ], - "time": "2026-05-27T06:59:30+00:00" + "time": "2026-09-24T15:19:04+00:00" }, { "name": "symfony/polyfill-php85", - "version": "v1.41.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "255fab485aaa1006ed411040c42aecd7b5302d7a" + "reference": "86a42cbcc07adc331481a5ab310a4024bfc227f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/255fab485aaa1006ed411040c42aecd7b5302d7a", - "reference": "255fab485aaa1006ed411040c42aecd7b5302d7a", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/86a42cbcc07adc331481a5ab310a4024bfc227f6", + "reference": "86a42cbcc07adc331481a5ab310a4024bfc227f6", "shasum": "" }, "require": { @@ -2821,7 +2833,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.41.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.43.0" }, "funding": [ { @@ -2841,20 +2853,20 @@ "type": "tidelift" } ], - "time": "2026-07-01T12:47:55+00:00" + "time": "2026-09-25T15:46:47+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.7.1", + "version": "v3.7.3", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0" + "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0", - "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/15e6a07ec2a2c75ceb1b21dd98105ee8456d2257", + "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257", "shasum": "" }, "require": { @@ -2908,7 +2920,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.7.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.7.3" }, "funding": [ { @@ -2928,7 +2940,7 @@ "type": "tidelift" } ], - "time": "2026-06-16T09:55:08+00:00" + "time": "2026-07-27T15:39:01+00:00" }, { "name": "symfony/stopwatch", @@ -2998,16 +3010,16 @@ }, { "name": "symfony/string", - "version": "v8.1.2", + "version": "v8.1.7", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "286a76b7255e5cc4bf0101a0bc5388ecf1c38ccc" + "reference": "d950140b5f56f31901e5b7a0c04ffc3a3deb943c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/286a76b7255e5cc4bf0101a0bc5388ecf1c38ccc", - "reference": "286a76b7255e5cc4bf0101a0bc5388ecf1c38ccc", + "url": "https://api.github.com/repos/symfony/string/zipball/d950140b5f56f31901e5b7a0c04ffc3a3deb943c", + "reference": "d950140b5f56f31901e5b7a0c04ffc3a3deb943c", "shasum": "" }, "require": { @@ -3064,7 +3076,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v8.1.2" + "source": "https://github.com/symfony/string/tree/v8.1.7" }, "funding": [ { @@ -3084,20 +3096,20 @@ "type": "tidelift" } ], - "time": "2026-07-28T07:35:25+00:00" + "time": "2026-09-11T14:51:16+00:00" }, { "name": "symfony/type-info", - "version": "v8.1.5", + "version": "v8.1.8", "source": { "type": "git", "url": "https://github.com/symfony/type-info.git", - "reference": "ceb48db5b38d6a48640c414be0c69d53980ae5c5" + "reference": "18e1d891f0b8776141f281f7b6f5e67e4df9d9cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/type-info/zipball/ceb48db5b38d6a48640c414be0c69d53980ae5c5", - "reference": "ceb48db5b38d6a48640c414be0c69d53980ae5c5", + "url": "https://api.github.com/repos/symfony/type-info/zipball/18e1d891f0b8776141f281f7b6f5e67e4df9d9cd", + "reference": "18e1d891f0b8776141f281f7b6f5e67e4df9d9cd", "shasum": "" }, "require": { @@ -3146,7 +3158,7 @@ "type" ], "support": { - "source": "https://github.com/symfony/type-info/tree/v8.1.5" + "source": "https://github.com/symfony/type-info/tree/v8.1.8" }, "funding": [ { @@ -3166,7 +3178,7 @@ "type": "tidelift" } ], - "time": "2026-08-21T17:47:34+00:00" + "time": "2026-09-28T19:13:15+00:00" }, { "name": "symfony/var-dumper", @@ -3257,16 +3269,16 @@ }, { "name": "symfony/var-exporter", - "version": "v8.1.5", + "version": "v8.1.6", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "b8f7dd85493e8372c7c81a1547caaaf86b9c16d1" + "reference": "802362f41128c430fd6685491e1fb72127fae78a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/b8f7dd85493e8372c7c81a1547caaaf86b9c16d1", - "reference": "b8f7dd85493e8372c7c81a1547caaaf86b9c16d1", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/802362f41128c430fd6685491e1fb72127fae78a", + "reference": "802362f41128c430fd6685491e1fb72127fae78a", "shasum": "" }, "require": { @@ -3316,7 +3328,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v8.1.5" + "source": "https://github.com/symfony/var-exporter/tree/v8.1.6" }, "funding": [ { @@ -3336,7 +3348,7 @@ "type": "tidelift" } ], - "time": "2026-08-13T16:11:28+00:00" + "time": "2026-08-29T06:30:03+00:00" } ], "packages-dev": [ @@ -4744,16 +4756,16 @@ }, { "name": "league/commonmark", - "version": "2.10.0", + "version": "2.10.3", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "d2d1aa8b35e072966c89bc0c66cf926e56767dc4" + "reference": "6efbd9c472b91db0a3350fcd601c8332c2382e1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d2d1aa8b35e072966c89bc0c66cf926e56767dc4", - "reference": "d2d1aa8b35e072966c89bc0c66cf926e56767dc4", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/6efbd9c472b91db0a3350fcd601c8332c2382e1f", + "reference": "6efbd9c472b91db0a3350fcd601c8332c2382e1f", "shasum": "" }, "require": { @@ -4847,7 +4859,7 @@ "type": "tidelift" } ], - "time": "2026-08-11T16:06:25+00:00" + "time": "2026-09-21T13:07:34+00:00" }, { "name": "league/config", @@ -6162,12 +6174,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "0de4cd39951f4d88f6083e1e18e0c661ed983a10" + "reference": "69ddaead6caa68f4f6190e2ee732f103326e78ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/0de4cd39951f4d88f6083e1e18e0c661ed983a10", - "reference": "0de4cd39951f4d88f6083e1e18e0c661ed983a10", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/69ddaead6caa68f4f6190e2ee732f103326e78ba", + "reference": "69ddaead6caa68f4f6190e2ee732f103326e78ba", "shasum": "" }, "conflict": { @@ -6206,7 +6218,8 @@ "andreapollastri/cipi": "<=3.1.15", "andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5", "aoe/restler": "<1.7.1", - "apache-solr-for-typo3/solr": "<11.6.6|>=12,<12.1.4|>=13,<13.1.4", + "apache-solr-for-typo3/solr": "<11.2.8|>=11.5,<11.6.6|>=12,<12.1.4|>=13,<13.1.4", + "apache/thrift": "<0.24", "apereo/phpcas": "<1.6", "api-platform/core": "<4.1.30|>=4.2,<4.2.26|>=4.3,<4.3.12", "api-platform/graphql": "<3.4.17|>=4,<4.0.22|>=4.1,<4.1.5", @@ -6273,8 +6286,8 @@ "cachethq/cachet": "<2.5.1", "cadmium-org/cadmium-cms": "<=0.4.9", "cakephp/authentication": "<2.11.1|>=3,<3.3.6|>=4,<4.1.1", - "cakephp/cakephp": "<4.5.11|>=4.6,<4.6.4|>=5,<5.1.7|>=5.2,<5.2.13|>=5.3,<5.3.6", - "cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", + "cakephp/cakephp": "<4.5.12|>=4.6,<4.6.5|>=5,<5.1.10|>=5.2,<5.2.15|>=5.3,<5.3.7", + "cakephp/database": ">=3,<4.5.12|>=4.6,<4.6.5|>=5,<5.1.10|>=5.2,<5.2.15|>=5.3,<5.3.7", "cakephp/debug_kit": "<4.10.3|>=5,<5.2.4", "cakephp/queue": ">=0.1.10,<2.3.1", "cardgate/magento2": "<2.0.33", @@ -6288,6 +6301,7 @@ "centreon/centreon": "<22.10.15", "cesargb/laravel-magiclink": ">=2,<2.25.1", "cesnet/simplesamlphp-module-proxystatistics": "<3.1", + "chamilo/chamilo-lms": "<=2", "chriskacerguis/codeigniter-restserver": "<=2.7.1", "chrome-php/chrome": "<1.14", "ci4-cms-erp/ci4ms": "<=0.31.8", @@ -6296,7 +6310,7 @@ "clickstorm/cs-seo": ">=6,<6.8|>=7,<7.5|>=8,<8.4|>=9,<9.3", "co-stack/fal_sftp": "<0.2.6", "cockpit-hq/cockpit": "<=2.14", - "code16/sharp": "<9.22.3", + "code16/sharp": "<9.22.5", "codeception/codeception": "<3.1.3|>=4,<4.1.22", "codeigniter/framework": "<3.1.10", "codeigniter4/framework": "<4.7.4", @@ -6306,7 +6320,7 @@ "codingms/modules": "<7.10.4|>=8,<8.1.4", "commerceteam/commerce": ">=0.9.6,<0.9.9", "components/jquery": ">=1.0.3,<3.5", - "composer/composer": "<2.2.29|>=2.3,<2.10.2", + "composer/composer": "<2.2.30|>=2.3,<2.10.3", "concrete5/concrete5": "<9.5.2", "concrete5/core": "<8.5.8|>=9,<9.1", "contao-components/colorbox": ">=1,<1.6.4.3-dev", @@ -6454,7 +6468,7 @@ "feehi/feehicms": "<=2.1.1", "fenom/fenom": "<=2.12.1", "filament/actions": ">=3.2,<3.2.123|>=4,<=4.11.3|>=5,<=5.6.3", - "filament/filament": ">=3,<=3.3.51|>=4,<4.11.5|>=5,<5.6.5", + "filament/filament": ">=3,<=3.3.51|>=4,<4.12.6|>=5,<5.7.6", "filament/forms": ">=3,<=3.3.52", "filament/infolists": ">=3,<3.2.115|>=4,<=4.11.4|>=5,<=5.6.4", "filament/tables": ">=3,<=3.3.50|>=4,<=4.11.4|>=5,<=5.6.4", @@ -6476,6 +6490,7 @@ "floriangaerber/magnesium": "<0.3.1", "fluidtypo3/vhs": "<5.1.1", "fof/byobu": ">=0.3.0.0-beta2,<1.1.7", + "fof/oauth": "<1.7.4|>=2.0.0.0-beta1,<2.0.0.0-beta4", "fof/pretty-mail": "<=1.1.2", "fof/upload": "<1.2.3", "foodcoopshop/foodcoopshop": ">=3.2,<3.6.1", @@ -6506,7 +6521,7 @@ "getgrav/grav": "<=2.0.19", "getgrav/grav-plugin-api": "<1.0.0.0-beta15", "getgrav/grav-plugin-form": "<9.1", - "getkirby/cms": "<=4.9.3|>=5,<=5.4.3", + "getkirby/cms": "<4.9.5|>=5,<5.5.2", "getkirby/kirby": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1", "getkirby/panel": "<2.5.14", "getkirby/starterkit": "<=3.7.0.2", @@ -6579,6 +6594,7 @@ "james-heinrich/getid3": "<1.9.21", "james-heinrich/phpthumb": "<=1.7.23", "jasig/phpcas": "<1.3.3", + "jayanta/laravel-threat-detection": "<1.9", "jbartels/wec-map": "<3.0.3", "jcbrand/converse.js": "<3.3.3", "jleehr/canto-saas-api": "<=2", @@ -6629,7 +6645,7 @@ "lara-zeus/artemis": ">=1,<=1.0.6", "lara-zeus/dynamic-dashboard": ">=3,<=3.0.1", "laravel/fortify": "<1.11.1", - "laravel/framework": "<12.61.1|>=13,<13.12", + "laravel/framework": "<12.69|>=13,<13.30", "laravel/laravel": ">=5.4,<5.4.22", "laravel/passport": ">=13,<13.7.1", "laravel/pulse": "<1.3.1", @@ -6639,8 +6655,8 @@ "lavalite/cms": "<=10.1", "lavitto/typo3-form-to-database": "<2.2.5|>=3,<3.2.2|>=4,<4.2.3|>=5,<5.0.2", "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5", - "league/commonmark": "<2.9", - "league/flysystem": "<1.1.4|>=2,<2.1.1", + "league/commonmark": "<=2.10.1", + "league/flysystem": "<=3.35.2", "league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3", "leantime/leantime": "<3.3", "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", @@ -6651,7 +6667,7 @@ "limesurvey/limesurvey": "<=7.0.0.0-beta1", "livehelperchat/livehelperchat": "<=3.91", "livewire-filemanager/filemanager": "<=1.0.4", - "livewire/livewire": "<2.12.7|>=3.0.0.0-beta1,<3.6.4", + "livewire/livewire": "<2.12.7|>=3.0.0.0-beta1,<=3.8.2|>=4.0.0.0-beta1,<=4.3.3", "livewire/volt": "<1.7", "lms/routes": "<2.1.1", "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2", @@ -6659,6 +6675,7 @@ "lomkit/laravel-rest-api": "<2.13", "luracast/restler": "<3.1", "luyadev/yii-helpers": "<1.2.1", + "maatwebsite/excel": ">=3.1.8,<3.1.70", "macropay-solutions/laravel-crud-wizard-free": "<3.4.17", "maestroerror/php-heic-to-jpg": "<1.0.5", "magento/community-edition": "<2.4.6.0-patch13|>=2.4.7.0-beta1,<2.4.7.0-patch8|>=2.4.8.0-beta1,<2.4.8.0-patch3|>=2.4.9.0-alpha1,<2.4.9.0-alpha3|==2.4.9", @@ -6692,7 +6709,7 @@ "mediawiki/data-transfer": ">=1.39,<1.39.11|>=1.41,<1.41.3|>=1.42,<1.42.2", "mediawiki/maps": "<12.1.3", "mediawiki/matomo": "<2.4.3", - "mediawiki/semantic-media-wiki": "<4.0.2", + "mediawiki/semantic-media-wiki": "<=7.2.1", "mehrwert/phpmyadmin": "<3.2", "melisplatform/melis-asset-manager": "<5.0.1", "melisplatform/melis-cms": "<5.3.4", @@ -6715,7 +6732,7 @@ "mobiledetect/mobiledetectlib": "<2.8.32", "modx/revolution": "<=3.1", "mojo42/jirafeau": "<4.4", - "mongodb/mongodb": ">=1,<1.9.2", + "mongodb/mongodb": "<1.21.4|>=2,<2.4.1", "mongodb/mongodb-extension": "<1.21.2", "monolog/monolog": ">=1.8,<1.12", "moodle/moodle": "<4.5.9|>=5.0.0.0-beta,<5.0.5|>=5.1.0.0-beta,<5.1.2", @@ -6763,9 +6780,9 @@ "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1", "october/backend": "<1.1.2", "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1", - "october/october": "<3.7.14|>=4,<4.1.10", + "october/october": "<3.7.14|>=4,<4.1.10|>=4.3,<4.3.4", "october/rain": "<=3.7.13|>=4,<=4.1.9", - "october/system": "<3.7.16|>=4,<4.1.16", + "october/system": "<3.7.17|>=4,<4.2.23", "oliverklee/phpunit": "<3.5.15", "omeka/omeka-s": "<4.0.3", "onelogin/php-saml": "<2.21.1|>=3,<3.8.1|>=4,<4.3.1", @@ -6796,7 +6813,7 @@ "paragonie/random_compat": "<2", "paragonie/sodium_compat": "<1.24.1|>=2,<2.5.1", "passbolt/passbolt_api": "<4.6.2", - "paymenter/paymenter": "<=1.5.4", + "paymenter/paymenter": "<=1.5.6", "paypal/adaptivepayments-sdk-php": "<=3.9.2", "paypal/invoice-sdk-php": "<=3.9", "paypal/merchant-sdk-php": "<3.12", @@ -6824,15 +6841,15 @@ "phpmailer/phpmailer": "<6.5", "phpmussel/phpmussel": ">=1,<1.6", "phpmyadmin/phpmyadmin": "<5.2.2", - "phpmyfaq/phpmyfaq": "<=4.1.4", + "phpmyfaq/phpmyfaq": "<4.2.0.0-alpha", "phpoffice/common": "<0.2.9", "phpoffice/math": "<=0.2", "phpoffice/phpexcel": "<=1.8.2", "phpoffice/phpspreadsheet": "<=1.30.5|>=2,<=2.1.17|>=2.2,<=2.4.6|>=3,<=3.10.6|>=4,<=5.8", "phppgadmin/phppgadmin": "<=7.13", - "phpseclib/phpseclib": "<=2.0.54|>=3,<=3.0.53", + "phpseclib/phpseclib": "<3.0.57|>=4,<4.0.1", "phpservermon/phpservermon": "<3.6", - "phpsysinfo/phpsysinfo": "<3.4.3", + "phpsysinfo/phpsysinfo": "<=3.4.5", "phpunit/phpunit": "<8.5.52|>=9,<9.6.33|>=10,<10.5.62|>=11,<11.5.50|>=12,<12.5.8|>=12.5.21,<12.5.22|>=13.1.5,<13.1.6", "phpwhois/phpwhois": "<=4.2.5", "phpxmlrpc/extras": "<0.6.1", @@ -6846,7 +6863,8 @@ "pimcore/demo": "<10.3", "pimcore/ecommerce-framework-bundle": "<1.0.10", "pimcore/perspective-editor": "<1.5.1", - "pimcore/pimcore": "<12.3.9|>=2026.1,<=2026.1.4", + "pimcore/pimcore": "<=12.3.9|>=2026.1,<=2026.1.5", + "pimcore/studio-backend-bundle": "<2025.4.6|>=2026.1,<2026.1.6", "pimcore/web2print-tools-bundle": "<=5.2.1|>=6.0.0.0-RC1-dev,<=6.1", "piwik/piwik": "<1.11", "pixelfed/pixelfed": "<0.12.5", @@ -6857,6 +6875,7 @@ "pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1", "pontedilana/php-weasyprint": "<=2.5.1", "poweradmin/poweradmin": "<4.2.5|>=4.3,<4.3.4", + "predis/predis": ">=3.0.0.0-RC1-dev,<3.3", "pressbooks/pressbooks": "<5.18", "prestashop/autoupgrade": ">=4,<4.10.1", "prestashop/blockreassurance": "<=5.1.3", @@ -6870,7 +6889,7 @@ "prestashop/ps_emailsubscription": "<2.6.1", "prestashop/ps_facetedsearch": "<4.0.4", "prestashop/ps_linklist": "<3.1", - "privatebin/privatebin": "<1.4|>=1.5,<1.7.4|>=1.7.7,<2.0.3", + "privatebin/privatebin": "<=2.0.4", "processwire/processwire": "<=3.0.255", "propel/propel": ">=2.0.0.0-alpha1,<2.0.0.0-alpha8", "propel/propel1": ">=1,<1.7.2", @@ -6893,9 +6912,9 @@ "ralffreit/mfa-email": "<1.0.7|==2", "rankmath/seo-by-rank-math": "<=1.0.95", "rap2hpoutre/laravel-log-viewer": "<0.13", - "react/http": ">=0.7,<1.9", + "react/http": ">=0.6,<1.11.1", "really-simple-plugins/complianz-gdpr": "<6.4.2", - "redaxo/source": "<5.21.1", + "redaxo/source": "<=5.21.1", "remdex/livehelperchat": "<4.29", "renolit/reint-downloadmanager": "<4.0.2|>=5,<5.0.1", "reportico-web/reportico": "<=8.1", @@ -6923,7 +6942,7 @@ "sheng/yiicms": "<1.2.1", "shlinkio/shlink": "<=5.0.1", "shopper/cart": "<2.8", - "shopper/framework": "<2.8", + "shopper/framework": "<2.9.2", "shopware/core": "<6.6.10.18-dev|>=6.7,<6.7.10.1-dev", "shopware/platform": "<6.6.10.18-dev|>=6.7,<6.7.10.1-dev", "shopware/production": "<=6.3.5.2", @@ -6971,7 +6990,7 @@ "slim/slim": "<2.6|>=4.4,<=4.15.1", "slub/slub-events": "<3.0.3", "smarty/smarty": "<4.5.7|>=5,<5.8.4", - "snipe/snipe-it": "<8.6.3", + "snipe/snipe-it": "<8.7", "socalnick/scn-social-auth": "<1.15.2", "socialiteproviders/steam": "<1.1", "solidinvoice/solidinvoice": "<=2.3.15", @@ -6993,14 +7012,14 @@ "starcitizentools/short-description": ">=4,<4.0.1", "starcitizentools/tabber-neue": ">=1.9.1,<2.7.2|>=3,<3.1.1", "starcitizenwiki/embedvideo": "<=4", - "statamic/cms": "<5.74.3|>=6,<6.24.2", + "statamic/cms": "<5.74.3|>=6,<=6.30", "stormpath/sdk": "<9.9.99", - "studio-42/elfinder": "<=2.1.67", + "studio-42/elfinder": "<2.1.70", "studiomitte/friendlycaptcha": "<0.1.4", "subhh/libconnect": "<7.0.8|>=8,<8.1", "sukohi/surpass": "<1", "sulu/form-bundle": ">=2,<2.5.3", - "sulu/sulu": "<=2.6.22|>=3,<=3.0.5", + "sulu/sulu": "<2.6.25|>=3,<3.0.8", "sumocoders/framework-user-bundle": "<1.4", "superbig/craft-audit": "<3.0.2", "svewap/a21glossary": "<=0.4.10", @@ -7107,7 +7126,7 @@ "twig/twig": "<3.27", "typicms/core": "<12.0.5|>=13,<13.0.9|>=14,<14.0.27|>=15,<15.0.29|>=16,<16.1.7", "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", - "typo3/cms-backend": "<10.4.57|>=11,<11.5.51|>=12,<12.4.46|>=13,<13.4.31|>=14,<14.3.3", + "typo3/cms-backend": "<10.4.60|>=11,<11.5.54|>=12,<12.4.49|>=13,<13.4.35|>=14,<14.3.7", "typo3/cms-belog": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", "typo3/cms-beuser": ">=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", "typo3/cms-core": "<10.4.57|>=11,<11.5.51|>=12,<12.4.46|>=13,<13.4.34|>=14,<14.3.6", @@ -7121,7 +7140,7 @@ "typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5", "typo3/cms-indexed-search": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<13.4.31|>=14,<14.3.3", "typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8|==13.4.2", - "typo3/cms-lowlevel": ">=11,<=11.5.41", + "typo3/cms-lowlevel": ">=11,<=11.5.41|>=14.2,<14.3.7", "typo3/cms-recordlist": ">=11,<11.5.48", "typo3/cms-recycler": "<10.4.57|>=11,<11.5.51|>=12,<12.4.46|>=13,<13.4.31|>=14,<14.3.3", "typo3/cms-redirects": ">=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1", @@ -7147,7 +7166,7 @@ "uvdesk/core-framework": "<=1.1.1", "vanilla/safecurl": "<0.9.2", "verbb/comments": "<1.5.5", - "verbb/formie": "<3.1.28", + "verbb/formie": "<3.1.31", "verbb/image-resizer": "<2.0.9", "verbb/knock-knock": "<1.2.8", "verot/class.upload.php": "<=2.1.6", @@ -7167,7 +7186,7 @@ "web-feet/coastercms": "==5.5", "web-token/jwt-bundle": "<3.4.10|>=4,<4.0.7|>=4.1,<4.1.7", "web-token/jwt-experimental": "<4.1.7", - "web-token/jwt-framework": "<4.1.7", + "web-token/jwt-framework": "<3.4.10|>=4,<4.0.7|>=4.1,<4.1.7", "web-token/jwt-library": "<3.4.10|>=4,<4.0.7|>=4.1,<4.1.7", "web-tp3/wec_map": "<3.0.3", "webbuilders-group/silverstripe-kapost-bridge": "<0.4", @@ -7190,7 +7209,7 @@ "woocommerce/woocommerce": "<6.6|>=8.8,<8.8.5|>=8.9,<8.9.3", "wp-cli/wp-cli": ">=0.12,<2.5", "wp-coding-standards/wpcs": ">=0.14.1,<3.4.1", - "wp-graphql/wp-graphql": "<=2.6", + "wp-graphql/wp-graphql": "<2.22.2", "wp-premium/gravityforms": "<2.4.21", "wpanel/wpanel4-cms": "<=4.3.1", "wpcloud/wp-stateless": "<3.2", @@ -7221,6 +7240,7 @@ "yuan1994/tpadmin": "<=1.3.12", "yungifez/skuul": "<=2.6.5", "z-push/z-push-dev": "<2.7.6", + "zbateson/mail-mime-parser": "<3.0.6|>=4,<4.0.2", "zencart/zencart": "<=1.5.7.0-beta", "zendesk/zendesk_api_client_php": "<2.2.11", "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", @@ -7295,7 +7315,7 @@ "type": "tidelift" } ], - "time": "2026-08-28T09:46:03+00:00" + "time": "2026-09-30T15:40:52+00:00" }, { "name": "sanmai/di-container", @@ -8899,16 +8919,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.37.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" + "reference": "9c6a5d6b01ca51d486c813e9a9c0ed55f208bb74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", - "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/9c6a5d6b01ca51d486c813e9a9c0ed55f208bb74", + "reference": "9c6a5d6b01ca51d486c813e9a9c0ed55f208bb74", "shasum": "" }, "require": { @@ -8959,7 +8979,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.43.0" }, "funding": [ { @@ -8979,7 +8999,7 @@ "type": "tidelift" } ], - "time": "2026-04-10T16:19:22+00:00" + "time": "2026-09-25T15:50:05+00:00" }, { "name": "symfony/polyfill-php84", @@ -9146,16 +9166,16 @@ }, { "name": "symfony/process", - "version": "v8.1.5", + "version": "v8.1.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d863f5e70d7c87abb906ac11b61f83036093000b" + "reference": "10823b09358e690df4ff943e24e8492bb1019fc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d863f5e70d7c87abb906ac11b61f83036093000b", - "reference": "d863f5e70d7c87abb906ac11b61f83036093000b", + "url": "https://api.github.com/repos/symfony/process/zipball/10823b09358e690df4ff943e24e8492bb1019fc3", + "reference": "10823b09358e690df4ff943e24e8492bb1019fc3", "shasum": "" }, "require": { @@ -9187,7 +9207,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v8.1.5" + "source": "https://github.com/symfony/process/tree/v8.1.7" }, "funding": [ { @@ -9207,7 +9227,7 @@ "type": "tidelift" } ], - "time": "2026-08-21T17:47:34+00:00" + "time": "2026-09-02T12:40:29+00:00" }, { "name": "symfony/routing", diff --git a/docs/usage.md b/docs/usage.md index 5659f111..b3837c35 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -199,24 +199,33 @@ final class DTO ## Upcasting ```php -use Patchlevel\EventSourcing\Serializer\Upcast\Upcast; -use Patchlevel\EventSourcing\Serializer\Upcast\Upcaster; +use Patchlevel\Hydrator\Extension\Upcast\Upcaster; +use Patchlevel\Hydrator\Metadata\ClassMetadata; final class ProfileCreatedEmailLowerCastUpcaster implements Upcaster { - public function __invoke(Upcast $upcast): Upcast + /** + * @param array $data + * @param array $context + * + * @return array + */ + public function upcast(ClassMetadata $metadata, array $data, array $context): array { // ignore if other event is processed - if ($upcast->eventName !== 'profile_created') { - return $upcast; + if ($metadata->className !== ProfileCreated::class) { + return $data; } - return $upcast->replacePayloadByKey('email', strtolower($upcast->payload['email'])); + $data['email'] = strtolower($data['email']); + + return $data; } } ``` If you have the symfony default service setting with `autowire`and `autoconfigure` enabled, -the upcaster is automatically recognized and registered at the `Upcaster` interface. +the upcaster is automatically recognized and registered in the `UpcastExtension` of the hydrator. +The upcasters run right before the object is built, so encrypted fields are already decrypted. Otherwise you have to define the upcaster in the symfony service file: ```yaml diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e9cf1917..9eb870ca 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -37,7 +37,7 @@ parameters: path: src/Normalizer/UidNormalizer.php - - message: '#^Method Fixtures\\DummyGuesser\:\:guess\(\) has parameter \$type with generic class Symfony\\Component\\TypeInfo\\Type\\ObjectType but does not specify its types\: T$#' + message: '#^Method Patchlevel\\EventSourcingBundle\\Tests\\Fixtures\\DummyGuesser\:\:guess\(\) has parameter \$type with generic class Symfony\\Component\\TypeInfo\\Type\\ObjectType but does not specify its types\: T$#' identifier: missingType.generics count: 1 path: tests/Fixtures/DummyGuesser.php diff --git a/src/DependencyInjection/HydratorCompilerPass.php b/src/DependencyInjection/HydratorCompilerPass.php index 9fcd52d0..af36f2e2 100644 --- a/src/DependencyInjection/HydratorCompilerPass.php +++ b/src/DependencyInjection/HydratorCompilerPass.php @@ -4,8 +4,10 @@ namespace Patchlevel\EventSourcingBundle\DependencyInjection; +use Patchlevel\Hydrator\Extension\Upcast\UpcastExtension; use Patchlevel\Hydrator\StackHydratorBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -14,12 +16,22 @@ /** @internal */ final class HydratorCompilerPass implements CompilerPassInterface { + use PriorityTaggedServiceTrait; + public function process(ContainerBuilder $container): void { if (!$container->has(StackHydratorBuilder::class)) { return; } + $upcasters = $this->findAndSortTaggedServices('event_sourcing.upcaster', $container); + + if ($upcasters !== []) { + $container->register(UpcastExtension::class, UpcastExtension::class) + ->setArguments([[], $upcasters]) + ->addTag('event_sourcing.hydrator.extension'); + } + $builder = $container->getDefinition(StackHydratorBuilder::class); $extensions = $container->findTaggedServiceIds('event_sourcing.hydrator.extension'); diff --git a/src/DependencyInjection/PatchlevelEventSourcingExtension.php b/src/DependencyInjection/PatchlevelEventSourcingExtension.php index 38de96e7..22e730b7 100644 --- a/src/DependencyInjection/PatchlevelEventSourcingExtension.php +++ b/src/DependencyInjection/PatchlevelEventSourcingExtension.php @@ -44,7 +44,7 @@ use Patchlevel\EventSourcing\Console\Command\SubscriptionTeardownCommand; use Patchlevel\EventSourcing\Console\Command\WatchCommand; use Patchlevel\EventSourcing\Console\DoctrineHelper; -use Patchlevel\EventSourcing\Cryptography\ExtensionDoctrineCipherKeyStore; +use Patchlevel\EventSourcing\Cryptography\DoctrineCipherKeyStore; use Patchlevel\EventSourcing\DecisionModel\DecisionModelBuilder; use Patchlevel\EventSourcing\DecisionModel\EventAppender; use Patchlevel\EventSourcing\DecisionModel\StoreDecisionModelBuilder; @@ -91,8 +91,6 @@ use Patchlevel\EventSourcing\Serializer\Encoder\JsonEncoder; use Patchlevel\EventSourcing\Serializer\EventSerializer; use Patchlevel\EventSourcing\Serializer\EventTagExtractor; -use Patchlevel\EventSourcing\Serializer\Upcast\Upcaster; -use Patchlevel\EventSourcing\Serializer\Upcast\UpcasterChain; use Patchlevel\EventSourcing\Snapshot\Adapter\Psr16SnapshotAdapter; use Patchlevel\EventSourcing\Snapshot\Adapter\Psr6SnapshotAdapter; use Patchlevel\EventSourcing\Snapshot\DefaultSnapshotStore; @@ -145,6 +143,7 @@ use Patchlevel\Hydrator\Extension\Cryptography\CryptographyExtension; use Patchlevel\Hydrator\Extension\Cryptography\Store\CipherKeyStore; use Patchlevel\Hydrator\Extension\Lifecycle\LifecycleExtension; +use Patchlevel\Hydrator\Extension\Upcast\Upcaster; use Patchlevel\Hydrator\Hydrator; use Patchlevel\Hydrator\StackHydrator; use Patchlevel\Hydrator\StackHydratorBuilder; @@ -220,7 +219,6 @@ private function configureSerializer(array $config, ContainerBuilder $container) new Reference(EventRegistry::class), new Reference(Hydrator::class), new Reference(Encoder::class), - new Reference(Upcaster::class), ]); $container->setAlias(EventSerializer::class, DefaultEventSerializer::class); @@ -597,13 +595,13 @@ private function configureHydrator(array $config, ContainerBuilder $container): ->addTag('event_sourcing.hydrator.extension'); if ($config['hydrator']['cryptography']['enabled']) { - $container->register(ExtensionDoctrineCipherKeyStore::class) + $container->register(DoctrineCipherKeyStore::class) ->setArguments([new Reference('event_sourcing.dbal_connection')]) ->addTag('event_sourcing.doctrine_schema_configurator'); $container->setAlias( CipherKeyStore::class, - ExtensionDoctrineCipherKeyStore::class, + DoctrineCipherKeyStore::class, ); $container->register(BaseCryptographer::class) @@ -616,11 +614,7 @@ private function configureHydrator(array $config, ContainerBuilder $container): $container->setAlias(Cryptographer::class, BaseCryptographer::class); $container->register(CryptographyExtension::class) - ->setArguments([ - new Reference(Cryptographer::class), - null, - true, - ]) + ->setArguments([new Reference(Cryptographer::class)]) ->addTag('event_sourcing.hydrator.extension'); } @@ -642,11 +636,6 @@ private function configureUpcaster(ContainerBuilder $container): void { $container->registerForAutoconfiguration(Upcaster::class) ->addTag('event_sourcing.upcaster'); - - $container->register(UpcasterChain::class) - ->setArguments([new TaggedIteratorArgument('event_sourcing.upcaster')]); - - $container->setAlias(Upcaster::class, UpcasterChain::class); } private function configureMessageDecorator(ContainerBuilder $container): void diff --git a/src/Normalizer/DatePointNormalizer.php b/src/Normalizer/DatePointNormalizer.php index a30ab753..c85c9f47 100644 --- a/src/Normalizer/DatePointNormalizer.php +++ b/src/Normalizer/DatePointNormalizer.php @@ -19,7 +19,8 @@ public function __construct( ) { } - public function normalize(mixed $value): string|null + /** @param array $context */ + public function normalize(mixed $value, array $context = []): string|null { if ($value === null) { return null; @@ -32,7 +33,8 @@ public function normalize(mixed $value): string|null return $value->format($this->format); } - public function denormalize(mixed $value): DatePoint|null + /** @param array $context */ + public function denormalize(mixed $value, array $context = []): DatePoint|null { if ($value === null) { return null; diff --git a/src/Normalizer/UidNormalizer.php b/src/Normalizer/UidNormalizer.php index b22ff258..91b9583e 100644 --- a/src/Normalizer/UidNormalizer.php +++ b/src/Normalizer/UidNormalizer.php @@ -28,7 +28,8 @@ public function __construct( ) { } - public function normalize(mixed $value): string|null + /** @param array $context */ + public function normalize(mixed $value, array $context = []): string|null { if ($value === null) { return null; @@ -41,7 +42,8 @@ public function normalize(mixed $value): string|null return (string)$value; } - public function denormalize(mixed $value): Uuid|null + /** @param array $context */ + public function denormalize(mixed $value, array $context = []): Uuid|null { if ($value === null) { return null; diff --git a/tests/Fixtures/DummyExtension.php b/tests/Fixtures/DummyExtension.php index 89bd3420..d935d252 100644 --- a/tests/Fixtures/DummyExtension.php +++ b/tests/Fixtures/DummyExtension.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Fixtures; +namespace Patchlevel\EventSourcingBundle\Tests\Fixtures; use Patchlevel\Hydrator\Extension; use Patchlevel\Hydrator\StackHydratorBuilder; diff --git a/tests/Fixtures/DummyGuesser.php b/tests/Fixtures/DummyGuesser.php index 9760c810..26db1ffe 100644 --- a/tests/Fixtures/DummyGuesser.php +++ b/tests/Fixtures/DummyGuesser.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Fixtures; +namespace Patchlevel\EventSourcingBundle\Tests\Fixtures; use Patchlevel\Hydrator\Guesser\Guesser; use Patchlevel\Hydrator\Normalizer\Normalizer; diff --git a/tests/Fixtures/DummyUpcaster.php b/tests/Fixtures/DummyUpcaster.php new file mode 100644 index 00000000..c20d4823 --- /dev/null +++ b/tests/Fixtures/DummyUpcaster.php @@ -0,0 +1,22 @@ + $data + * @param array $context + * + * @return array + */ + public function upcast(ClassMetadata $metadata, array $data, array $context): array + { + return $data; + } +} diff --git a/tests/Unit/PatchlevelEventSourcingBundleTest.php b/tests/Unit/PatchlevelEventSourcingBundleTest.php index 300b1358..cb4e2736 100644 --- a/tests/Unit/PatchlevelEventSourcingBundleTest.php +++ b/tests/Unit/PatchlevelEventSourcingBundleTest.php @@ -13,7 +13,6 @@ use Doctrine\Migrations\Tools\Console\Command\MigrateCommand; use Doctrine\Migrations\Tools\Console\Command\StatusCommand; use Doctrine\Persistence\ManagerRegistry; -use Fixtures\DummyExtension; use InvalidArgumentException; use Patchlevel\EventSourcing\Attribute\Aggregate; use Patchlevel\EventSourcing\Attribute\Event; @@ -102,6 +101,8 @@ use Patchlevel\EventSourcingBundle\Tests\Fixtures\CreateProfile; use Patchlevel\EventSourcingBundle\Tests\Fixtures\CustomHeader; use Patchlevel\EventSourcingBundle\Tests\Fixtures\DummyArgumentResolver; +use Patchlevel\EventSourcingBundle\Tests\Fixtures\DummyExtension; +use Patchlevel\EventSourcingBundle\Tests\Fixtures\DummyUpcaster; use Patchlevel\EventSourcingBundle\Tests\Fixtures\Listener1; use Patchlevel\EventSourcingBundle\Tests\Fixtures\Listener2; use Patchlevel\EventSourcingBundle\Tests\Fixtures\Profile; @@ -114,6 +115,7 @@ use Patchlevel\Hydrator\CoreExtension; use Patchlevel\Hydrator\Extension\Cryptography\CryptographyExtension; use Patchlevel\Hydrator\Extension\Lifecycle\LifecycleExtension; +use Patchlevel\Hydrator\Extension\Upcast\UpcastExtension; use Patchlevel\Hydrator\Hydrator; use Patchlevel\Hydrator\StackHydrator; use PHPUnit\Framework\Attributes\RequiresMethod; @@ -1390,6 +1392,32 @@ public function testHydrator(): void ); } + public function testUpcaster(): void + { + $container = new ContainerBuilder(); + + $container->setDefinition(DummyUpcaster::class, new Definition(DummyUpcaster::class)) + ->setAutoconfigured(true); + + $this->compileContainer( + $container, + [ + 'patchlevel_event_sourcing' => [ + 'connection' => ['service' => 'doctrine.dbal.eventstore_connection'], + ], + ], + ); + + self::assertEquals( + [[], [new Reference(DummyUpcaster::class)]], + $container->getDefinition(UpcastExtension::class)->getArguments(), + ); + self::assertArrayHasKey( + UpcastExtension::class, + $container->findTaggedServiceIds('event_sourcing.hydrator.extension'), + ); + } + public function testFullBuild(): void { $psrClock = $this->createMock(ClockInterface::class);