Skip to content

Commit

Permalink
Be more explicit abotut he return type of DataObjectEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
maxime-rainville committed Nov 11, 2024
1 parent 54afefd commit 1db248b
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 26 deletions.
10 changes: 7 additions & 3 deletions src/Event/DataObjectEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
* Example usage:
* ```php
* $event = DataObjectEvent::create(
* $dataObject->ID,
* get_class($dataObject),
* $dataObject->ID,
* Operation::UPDATE,
* $dataObject->Version,
* Security::getCurrentUser()?->ID
* );
* ```
*
* @template T of DataObject
*/
class DataObjectEvent
{
Expand All @@ -42,15 +44,15 @@ class DataObjectEvent
private readonly int $timestamp;

/**
* @param class-string<T> $objectClass The class name of the affected DataObject
* @param int $objectID The ID of the affected DataObject
* @param string $objectClass The class name of the affected DataObject
* @param Operation $operation The type of operation performed
* @param int|null $version The version number (for versioned objects)
* @param int|null $memberID The ID of the member who performed the operation
*/
public function __construct(
private readonly int $objectID,
private readonly string $objectClass,
private readonly int $objectID,
private readonly Operation $operation,
private readonly ?int $version = null,
private readonly ?int $memberID = null
Expand Down Expand Up @@ -109,6 +111,8 @@ public function getTimestamp(): int
/**
* Get the DataObject associated with this event
*
* @phpstan-return T|null
*
* @param bool $useVersion If true and the object is versioned, retrieves the specific version that was affected
* Note: This may return null if the object has been deleted since the event was created
*/
Expand Down
12 changes: 6 additions & 6 deletions src/Extension/EventDispatchExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public function onAfterWrite(): void
{
$owner = $this->getOwner();
$event = DataObjectEvent::create(
$owner->ID,
get_class($owner),
$owner->ID,
// By this point isInDB() will return true even for new records since the ID is already set
// Instead check if the ID field was changed which indicates this is a new record
$owner->isChanged('ID') ? Operation::CREATE : Operation::UPDATE,
Expand All @@ -46,8 +46,8 @@ public function onBeforeDelete(): void
{
$owner = $this->getOwner();
$event = DataObjectEvent::create(
$owner->ID,
get_class($owner),
$owner->ID,
Operation::DELETE,
$owner->hasExtension(Versioned::class) ? $owner->Version : null,
Security::getCurrentUser()?->ID
Expand All @@ -67,8 +67,8 @@ public function onAfterPublish(): void
}

$event = DataObjectEvent::create(
$owner->ID,
get_class($owner),
$owner->ID,
Operation::PUBLISH,
$owner->Version,
Security::getCurrentUser()?->ID
Expand All @@ -88,8 +88,8 @@ public function onAfterUnpublish(): void
}

$event = DataObjectEvent::create(
$owner->ID,
get_class($owner),
$owner->ID,
Operation::UNPUBLISH,
$owner->Version,
Security::getCurrentUser()?->ID
Expand All @@ -109,8 +109,8 @@ public function onAfterArchive(): void
}

$event = DataObjectEvent::create(
$owner->ID,
get_class($owner),
$owner->ID,
Operation::ARCHIVE,
$owner->Version,
Security::getCurrentUser()?->ID
Expand All @@ -130,8 +130,8 @@ public function onAfterRestore(): void
}

$event = DataObjectEvent::create(
$owner->ID,
get_class($owner),
$owner->ID,
Operation::RESTORE,
$owner->Version,
Security::getCurrentUser()?->ID
Expand Down
9 changes: 6 additions & 3 deletions src/Listener/DataObjectEventListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* This listener can be configured to only handle specific operations (create, update, delete etc)
* and specific DataObject classes. When an event matches the configured criteria, the callback
* is executed with the event.
*
* @template T of DataObject
*/
class DataObjectEventListener
{
Expand All @@ -25,8 +27,9 @@ class DataObjectEventListener
/**
* Creates a new DataObject event listener.
*
* @param Closure(DataObjectEvent): void $callback Callback to execute when an event matches
* @param class-string<DataObject>[] $classes Array of DataObject class names to listen for
* @template T of DataObject
* @param Closure(DataObjectEvent<T>): void $callback Callback to execute when an event matches
* @param class-string<T>[] $classes Array of DataObject class names to listen for
* @param Operation[]|null $operations Array of operations to listen for. If null, listens for all operations.
*/
public function __construct(
Expand Down Expand Up @@ -56,7 +59,7 @@ public function selfRegister(ListenerProvider|EventService $provider = null): vo
* Checks if the event matches the configured operations and classes,
* and executes the callback if it does.
*
* @param DataObjectEvent $event The event to handle
* @param DataObjectEvent<T> $event The event to handle
*/
public function __invoke(DataObjectEvent $event): void
{
Expand Down
12 changes: 6 additions & 6 deletions tests/php/Event/DataObjectEventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class DataObjectEventTest extends SapphireTest

public function testEventCreation(): void
{
$event = DataObjectEvent::create(1, SimpleDataObject::class, Operation::CREATE, null, 1);
$event = DataObjectEvent::create(SimpleDataObject::class, 1, Operation::CREATE, null, 1);

$this->assertEquals(1, $event->getObjectID());
$this->assertEquals(SimpleDataObject::class, $event->getObjectClass());
Expand All @@ -35,7 +35,7 @@ public function testGetObject(): void
/** @var SimpleDataObject $object */
$object = $this->objFromFixture(SimpleDataObject::class, 'object1');

$event = DataObjectEvent::create($object->ID, SimpleDataObject::class, Operation::UPDATE);
$event = DataObjectEvent::create(SimpleDataObject::class, $object->ID, Operation::UPDATE);

$this->assertNotNull($event->getObject());
$this->assertEquals($object->ID, $event->getObject()->ID);
Expand All @@ -50,7 +50,7 @@ public function testGetVersionedObject(): void
$object->Title = 'Updated Title';
$object->write();

$event = DataObjectEvent::create($object->ID, VersionedDataObject::class, Operation::UPDATE, $object->Version);
$event = DataObjectEvent::create(VersionedDataObject::class, $object->ID, Operation::UPDATE, $object->Version);

// Get current version
$currentObject = $event->getObject(false);
Expand All @@ -61,7 +61,7 @@ public function testGetVersionedObject(): void
$this->assertEquals('Updated Title', $versionedObject->Title);

// Get previous version
$previousEvent = DataObjectEvent::create($object->ID, VersionedDataObject::class, Operation::UPDATE, $object->Version - 1);
$previousEvent = DataObjectEvent::create(VersionedDataObject::class, $object->ID, Operation::UPDATE, $object->Version - 1);
$previousVersion = $previousEvent->getObject(true);
$this->assertEquals('Original Title', $previousVersion->Title);
}
Expand All @@ -71,15 +71,15 @@ public function testGetMember(): void
/** @var Member $member */
$member = $this->objFromFixture(Member::class, 'member1');

$event = DataObjectEvent::create(1, SimpleDataObject::class, Operation::CREATE, null, $member->ID);
$event = DataObjectEvent::create(SimpleDataObject::class, 1, Operation::CREATE, null, $member->ID);

$this->assertNotNull($event->getMember());
$this->assertEquals($member->ID, $event->getMember()->ID);
}

public function testSerialization(): void
{
$event = DataObjectEvent::create(1, SimpleDataObject::class, Operation::CREATE, 2, 3);
$event = DataObjectEvent::create(SimpleDataObject::class, 1, Operation::CREATE, 2, 3);

$serialized = serialize($event);
/** @var DataObjectEvent $unserialized */
Expand Down
16 changes: 8 additions & 8 deletions tests/php/Listener/DataObjectEventListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ function (DataObjectEvent $event) {
);

// Should handle SimpleDataObject event
$simpleEvent = DataObjectEvent::create(1, SimpleDataObject::class, Operation::CREATE);
$simpleEvent = DataObjectEvent::create(SimpleDataObject::class, 1, Operation::CREATE);
$listener($simpleEvent);
$this->assertCount(1, $this->receivedEvents, 'Listener should handle SimpleDataObject events');

// Should not handle VersionedDataObject event
$versionedEvent = DataObjectEvent::create(1, VersionedDataObject::class, Operation::CREATE);
$versionedEvent = DataObjectEvent::create(VersionedDataObject::class, 1, Operation::CREATE);
$listener($versionedEvent);
$this->assertCount(1, $this->receivedEvents, 'Listener should not handle VersionedDataObject events');
}
Expand All @@ -65,8 +65,8 @@ function (DataObjectEvent $event) {
);

// Should handle both SimpleDataObject and VersionedDataObject events
$simpleEvent = DataObjectEvent::create(1, SimpleDataObject::class, Operation::CREATE);
$versionedEvent = DataObjectEvent::create(1, VersionedDataObject::class, Operation::CREATE);
$simpleEvent = DataObjectEvent::create(SimpleDataObject::class, 1, Operation::CREATE);
$versionedEvent = DataObjectEvent::create(VersionedDataObject::class, 1, Operation::CREATE);

$listener($simpleEvent);
$listener($versionedEvent);
Expand All @@ -86,17 +86,17 @@ function (DataObjectEvent $event) {
);

// Should handle CREATE event
$createEvent = DataObjectEvent::create(1, SimpleDataObject::class, Operation::CREATE);
$createEvent = DataObjectEvent::create(SimpleDataObject::class, 1, Operation::CREATE);
$listener($createEvent);
$this->assertCount(1, $this->receivedEvents, 'Listener should handle CREATE events');

// Should handle UPDATE event
$updateEvent = DataObjectEvent::create(1, SimpleDataObject::class, Operation::UPDATE);
$updateEvent = DataObjectEvent::create(SimpleDataObject::class, 1, Operation::UPDATE);
$listener($updateEvent);
$this->assertCount(2, $this->receivedEvents, 'Listener should handle UPDATE events');

// Should not handle DELETE event
$deleteEvent = DataObjectEvent::create(1, SimpleDataObject::class, Operation::DELETE);
$deleteEvent = DataObjectEvent::create(SimpleDataObject::class, 1, Operation::DELETE);
$listener($deleteEvent);
$this->assertCount(2, $this->receivedEvents, 'Listener should not handle DELETE events');
}
Expand All @@ -113,7 +113,7 @@ function (DataObjectEvent $event) {

// Should handle all operations
foreach (Operation::cases() as $operation) {
$event = DataObjectEvent::create(1, SimpleDataObject::class, $operation);
$event = DataObjectEvent::create(SimpleDataObject::class, 1, $operation);
$listener($event);
}

Expand Down

0 comments on commit 1db248b

Please sign in to comment.