diff --git a/composer.json b/composer.json index aafeb8a8..7aaa00ad 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "doctrine/dbal": "^4.0.0", "doctrine/migrations": "^3.3.2", - "patchlevel/hydrator": "^1.4.1", + "patchlevel/hydrator": "^1.5.0", "patchlevel/worker": "^1.2.0", "psr/cache": "^2.0.0|^3.0.0", "psr/clock": "^1.0", diff --git a/composer.lock b/composer.lock index 4fbbf42d..bd013035 100644 --- 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": "9352e66b4db0bf595155f52fd4158199", + "content-hash": "a1f064eb241d9bc1206be325eeb69e6e", "packages": [ { "name": "brick/math", @@ -417,16 +417,16 @@ }, { "name": "patchlevel/hydrator", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/patchlevel/hydrator.git", - "reference": "0386ca29388c5c9d3f8b7b328826d16521313d91" + "reference": "b8951b39825e6baef7e6331c7d9a7655e19c7b4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/patchlevel/hydrator/zipball/0386ca29388c5c9d3f8b7b328826d16521313d91", - "reference": "0386ca29388c5c9d3f8b7b328826d16521313d91", + "url": "https://api.github.com/repos/patchlevel/hydrator/zipball/b8951b39825e6baef7e6331c7d9a7655e19c7b4a", + "reference": "b8951b39825e6baef7e6331c7d9a7655e19c7b4a", "shasum": "" }, "require": { @@ -476,9 +476,9 @@ ], "support": { "issues": "https://github.com/patchlevel/hydrator/issues", - "source": "https://github.com/patchlevel/hydrator/tree/1.4.1" + "source": "https://github.com/patchlevel/hydrator/tree/1.5.0" }, - "time": "2024-07-09T08:06:23+00:00" + "time": "2024-09-18T12:04:45+00:00" }, { "name": "patchlevel/worker", @@ -7135,16 +7135,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.10.2", + "version": "3.10.3", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "86e5f5dd9a840c46810ebe5ff1885581c42a3017" + "reference": "62d32998e820bddc40f99f8251958aed187a5c9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/86e5f5dd9a840c46810ebe5ff1885581c42a3017", - "reference": "86e5f5dd9a840c46810ebe5ff1885581c42a3017", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/62d32998e820bddc40f99f8251958aed187a5c9c", + "reference": "62d32998e820bddc40f99f8251958aed187a5c9c", "shasum": "" }, "require": { @@ -7211,7 +7211,7 @@ "type": "open_collective" } ], - "time": "2024-07-21T23:26:44+00:00" + "time": "2024-09-18T10:38:58+00:00" }, { "name": "symfony/clock", diff --git a/src/Aggregate/AggregateRootAttributeBehaviour.php b/src/Aggregate/AggregateRootAttributeBehaviour.php index d070e799..75f0d432 100644 --- a/src/Aggregate/AggregateRootAttributeBehaviour.php +++ b/src/Aggregate/AggregateRootAttributeBehaviour.php @@ -5,6 +5,7 @@ namespace Patchlevel\EventSourcing\Aggregate; use Patchlevel\Hydrator\Attribute\Ignore; +use Patchlevel\Hydrator\Attribute\PostHydrate; use ReflectionProperty; use function array_key_exists; @@ -43,8 +44,6 @@ protected function apply(object $event): void return; } - $this->recorder ??= $this->recordThat(...); - $parts = explode('.', $method); if (count($parts) === 2) { @@ -57,6 +56,15 @@ protected function apply(object $event): void $this->$method($event); } + $this->passRecorderToChildAggregates(); + } + + #[PostHydrate] + private function passRecorderToChildAggregates(): void + { + $metadata = static::metadata(); + $this->recorder ??= $this->recordThat(...); + foreach ($metadata->childAggregates as $property) { if (!isset($this->{$property})) { continue; diff --git a/src/Aggregate/BasicChildAggregate.php b/src/Aggregate/BasicChildAggregate.php index 4d86e501..526db447 100644 --- a/src/Aggregate/BasicChildAggregate.php +++ b/src/Aggregate/BasicChildAggregate.php @@ -4,7 +4,10 @@ namespace Patchlevel\EventSourcing\Aggregate; +use Patchlevel\Hydrator\Normalizer\ObjectNormalizer; + /** @experimental */ +#[ObjectNormalizer] abstract class BasicChildAggregate implements ChildAggregate { use ChildAggregateBehaviour; diff --git a/src/Aggregate/ChildAggregateBehaviour.php b/src/Aggregate/ChildAggregateBehaviour.php index 15847981..898ec509 100644 --- a/src/Aggregate/ChildAggregateBehaviour.php +++ b/src/Aggregate/ChildAggregateBehaviour.php @@ -4,10 +4,13 @@ namespace Patchlevel\EventSourcing\Aggregate; +use Patchlevel\Hydrator\Attribute\Ignore; + /** @experimental */ trait ChildAggregateBehaviour { /** @var callable(object $event): void */ + #[Ignore] private $recorder; protected function recordThat(object $event): void diff --git a/tests/Integration/ChildAggregate/ChildAggregateIntegrationTest.php b/tests/Integration/ChildAggregate/ChildAggregateIntegrationTest.php index 92912aac..a7f4c568 100644 --- a/tests/Integration/ChildAggregate/ChildAggregateIntegrationTest.php +++ b/tests/Integration/ChildAggregate/ChildAggregateIntegrationTest.php @@ -146,11 +146,21 @@ public function testSnapshot(): void self::assertSame('John', $result['name']); $repository = $manager->get(Profile::class); + + // create snapshot + $repository->load($profileId); + + // load from snapshot + $profile = $repository->load($profileId); + + $profile->changeName('Snow'); + $repository->save($profile); + $profile = $repository->load($profileId); self::assertInstanceOf(Profile::class, $profile); self::assertEquals($profileId, $profile->aggregateRootId()); - self::assertSame(1, $profile->playhead()); - self::assertSame('John', $profile->name()); + self::assertSame(2, $profile->playhead()); + self::assertSame('Snow', $profile->name()); } } diff --git a/tests/Integration/ChildAggregate/Profile.php b/tests/Integration/ChildAggregate/Profile.php index 57a4b93f..bd0b438c 100644 --- a/tests/Integration/ChildAggregate/Profile.php +++ b/tests/Integration/ChildAggregate/Profile.php @@ -13,7 +13,7 @@ use Patchlevel\EventSourcing\Tests\Integration\ChildAggregate\Events\ProfileCreated; #[Aggregate('profile')] -#[Snapshot('default', 100)] +#[Snapshot('default', 1)] final class Profile extends BasicAggregateRoot { #[Id]