From 33a513456799786c2a9eca98ed9da15db756a9c9 Mon Sep 17 00:00:00 2001 From: Daniel Badura Date: Tue, 6 Jan 2026 13:19:17 +0100 Subject: [PATCH] Deprecate `SubscriberHelper` and `SubscriberUtil` and update docs to use a CONST instead --- docs/pages/getting_started.md | 23 ++++++++----------- docs/pages/subscription.md | 17 ++++---------- .../Subscriber/SubscriberHelper.php | 1 + .../Subscriber/SubscriberUtil.php | 1 + 4 files changed, 15 insertions(+), 27 deletions(-) diff --git a/docs/pages/getting_started.md b/docs/pages/getting_started.md index dd0ed4db7..1e7fb6c9d 100644 --- a/docs/pages/getting_started.md +++ b/docs/pages/getting_started.md @@ -163,12 +163,12 @@ use Patchlevel\EventSourcing\Attribute\Projector; use Patchlevel\EventSourcing\Attribute\Setup; use Patchlevel\EventSourcing\Attribute\Subscribe; use Patchlevel\EventSourcing\Attribute\Teardown; -use Patchlevel\EventSourcing\Subscription\Subscriber\SubscriberUtil; -#[Projector('hotel')] +#[Projector(self::TABLE)] final class HotelProjector { - use SubscriberUtil; + // use a const for easier access in the projector & to keep projector id and table name in sync + private const TABLE = 'hotel'; public function __construct( private readonly Connection $db, @@ -178,14 +178,14 @@ final class HotelProjector /** @return list */ public function getHotels(): array { - return $this->db->fetchAllAssociative("SELECT id, name, guests FROM {$this->table()};"); + return $this->db->fetchAllAssociative(sprintf('SELECT id, name, guests FROM %s;'), self::TABLE); } #[Subscribe(HotelCreated::class)] public function handleHotelCreated(HotelCreated $event): void { $this->db->insert( - $this->table(), + self::TABLE, [ 'id' => $event->hotelId->toString(), 'name' => $event->hotelName, @@ -198,7 +198,7 @@ final class HotelProjector public function handleGuestIsCheckedIn(GuestIsCheckedIn $event): void { $this->db->executeStatement( - "UPDATE {$this->table()} SET guests = guests + 1 WHERE id = ?;", + sprintf('UPDATE %s SET guests = guests + 1 WHERE id = ?;', self::TABLE), [$event->hotelId->toString()], ); } @@ -207,7 +207,7 @@ final class HotelProjector public function handleGuestIsCheckedOut(GuestIsCheckedOut $event): void { $this->db->executeStatement( - "UPDATE {$this->table()} SET guests = guests - 1 WHERE id = ?;", + sprintf('UPDATE %s SET guests = guests - 1 WHERE id = ?;', self::TABLE), [$event->hotelId->toString()], ); } @@ -215,18 +215,13 @@ final class HotelProjector #[Setup] public function create(): void { - $this->db->executeStatement("CREATE TABLE IF NOT EXISTS {$this->table()} (id VARCHAR PRIMARY KEY, name VARCHAR, guests INTEGER);"); + $this->db->executeStatement(sprintf('CREATE TABLE IF NOT EXISTS %s (id VARCHAR PRIMARY KEY, name VARCHAR, guests INTEGER);', self::TABLE)); } #[Teardown] public function drop(): void { - $this->db->executeStatement("DROP TABLE IF EXISTS {$this->table()};"); - } - - private function table(): string - { - return 'projection_' . $this->subscriberId(); + $this->db->executeStatement(sprintf('DROP TABLE IF EXISTS %s;', self::TABLE)); } } ``` diff --git a/docs/pages/subscription.md b/docs/pages/subscription.md index 94a4457db..19e5a9808 100644 --- a/docs/pages/subscription.md +++ b/docs/pages/subscription.md @@ -231,8 +231,6 @@ use Patchlevel\EventSourcing\Subscription\Lookup; #[Projector('public_profile')] final class PublicProfileProjection { - use SubscriberUtil; - // ... constructor #[Subscribe(Published::class)] @@ -306,12 +304,11 @@ use Doctrine\DBAL\Connection; use Patchlevel\EventSourcing\Attribute\Projector; use Patchlevel\EventSourcing\Attribute\Setup; use Patchlevel\EventSourcing\Attribute\Teardown; -use Patchlevel\EventSourcing\Subscription\Subscriber\SubscriberUtil; -#[Projector('profile_1')] +#[Projector(self::TABLE)] final class ProfileProjector { - use SubscriberUtil; + private const TABLE = 'profile_v1'; private Connection $connection; @@ -319,19 +316,14 @@ final class ProfileProjector public function create(): void { $this->connection->executeStatement( - "CREATE TABLE IF NOT EXISTS {$this->table()} (id VARCHAR PRIMARY KEY, name VARCHAR NOT NULL);", + sprintf('CREATE TABLE IF NOT EXISTS %s (id VARCHAR PRIMARY KEY, name VARCHAR NOT NULL);', self::TABLE), ); } #[Teardown] public function drop(): void { - $this->connection->executeStatement("DROP TABLE IF EXISTS {$this->table()};"); - } - - private function table(): string - { - return 'projection_' . $this->subscriberId(); + $this->connection->executeStatement(sprintf('DROP TABLE IF EXISTS %s;', self::TABLE)); } } ``` @@ -346,7 +338,6 @@ final class ProfileProjector If you change the subscriber id, you must also change the table/collection name. The subscription engine will create a new subscription with the new subscriber id. That means the setup method will be called again and the table/collection will conflict with the old existing projection. - You can use the `SubscriberUtil` to build the table/collection name. !!! note diff --git a/src/Subscription/Subscriber/SubscriberHelper.php b/src/Subscription/Subscriber/SubscriberHelper.php index 3243ac8fb..733a4ffcc 100644 --- a/src/Subscription/Subscriber/SubscriberHelper.php +++ b/src/Subscription/Subscriber/SubscriberHelper.php @@ -8,6 +8,7 @@ use Patchlevel\EventSourcing\Metadata\Subscriber\SubscriberMetadata; use Patchlevel\EventSourcing\Metadata\Subscriber\SubscriberMetadataFactory; +/** @deprecated since 3.15.0 will be removed with 4.0.0 */ final class SubscriberHelper { public function __construct( diff --git a/src/Subscription/Subscriber/SubscriberUtil.php b/src/Subscription/Subscriber/SubscriberUtil.php index b73ad0a88..01592494c 100644 --- a/src/Subscription/Subscriber/SubscriberUtil.php +++ b/src/Subscription/Subscriber/SubscriberUtil.php @@ -7,6 +7,7 @@ use Patchlevel\EventSourcing\Metadata\Subscriber\AttributeSubscriberMetadataFactory; use Patchlevel\EventSourcing\Metadata\Subscriber\SubscriberMetadataFactory; +/** @deprecated since 3.15.0 will be removed with 4.0.0 */ trait SubscriberUtil { private static SubscriberMetadataFactory|null $metadataFactory = null;