Skip to content

Commit

Permalink
Add ability to scaffold Dataobject event
Browse files Browse the repository at this point in the history
  • Loading branch information
maxime-rainville committed Nov 7, 2024
1 parent 17e7aaf commit e3063d5
Show file tree
Hide file tree
Showing 21 changed files with 871 additions and 279 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
.vscode/
*.swp
*.swo
.DS_Store
.DS_Store
composer.lock
/public/
19 changes: 16 additions & 3 deletions _config/events.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,20 @@ After:
- '#coreservices'
---
SilverStripe\Core\Injector\Injector:
ArchiPro\Silverstripe\EventDispatcher\Service\EventService:
# Define the listener provider
ArchiPro\EventDispatcher\ListenerProvider:
class: ArchiPro\EventDispatcher\ListenerProvider

# Default event dispatcher
ArchiPro\EventDispatcher\AsyncEventDispatcher:
class: ArchiPro\EventDispatcher\AsyncEventDispatcher
constructor:
dispatcher: '%$Psr\EventDispatcher\EventDispatcherInterface'
listenerProvider: '%$Psr\EventDispatcher\ListenerProviderInterface'
listenerProvider: '%$ArchiPro\EventDispatcher\ListenerProvider'
Psr\EventDispatcher\EventDispatcherInterface:
alias: '%$ArchiPro\EventDispatcher\AsyncEventDispatcher'

# Bootstrap the event service
ArchiPro\Silverstripe\EventDispatcher\Service\EventService:
constructor:
dispatcher: '%$ArchiPro\EventDispatcher\AsyncEventDispatcher'
listenerProvider: '%$ArchiPro\EventDispatcher\ListenerProvider'
27 changes: 20 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
{
"name": "archipro/silverstripe-event-dispatcher",
"description": "PSR-14 Event Dispatcher integration for Silverstripe CMS",
"name": "archipro/silverstripe-revolt-event-dispatcher",
"description": "A Revolt Event Dispatcher integration for Silverstripe CMS",
"type": "silverstripe-vendormodule",
"license": "MIT",
"require": {
"php": "^8.1",
"silverstripe/framework": "^4.13 || ^5.0",
"silverstripe/versioned": "^1.13 || ^2.0",
"psr/event-dispatcher": "^1.0"
"psr/event-dispatcher": "^1.0",
"psr/event-dispatcher-implementation": "^1.0",
"archipro/revolt-event-dispatcher": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3.0",
"friendsofphp/php-cs-fixer": "^3.0",
"phpstan/phpstan": "^1.10",
"symbiote/silverstripe-phpstan": "^1.0"
"phpstan/phpstan": "^1.10"
},
"autoload": {
"psr-4": {
Expand All @@ -36,5 +37,17 @@
"prefer-stable": true,
"extra": {
"expose": []
}
}
},
"config": {
"allow-plugins": {
"composer/installers": true,
"silverstripe/vendor-plugin": true
}
},
"repositories": [
{
"type": "github",
"url": "[email protected]:archiprocode/revolt-event-dispatcher.git"
}
]
}
25 changes: 25 additions & 0 deletions src/Contract/ListenerLoaderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace ArchiPro\Silverstripe\EventDispatcher\Contract;

use ArchiPro\EventDispatcher\ListenerProvider;

/**
* Interface for classes that load event listeners into a ListenerProvider.
*
* This interface allows for modular and configurable loading of event listeners,
* making it easier to organize and maintain event listeners in different parts
* of the application.
*/
interface ListenerLoaderInterface
{
/**
* Loads event listeners into the provided ListenerProvider.
*
* Implementations should use this method to register their event listeners
* with the provider, typically using the provider's addListener method.
*
* @param ListenerProvider $provider The provider to load listeners into
*/
public function loadListeners(ListenerProvider $provider): void;
}
75 changes: 75 additions & 0 deletions src/DataObjectEventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace ArchiPro\Silverstripe\EventDispatcher;

use ArchiPro\Silverstripe\EventDispatcher\Event\DataObjectEvent;
use ArchiPro\Silverstripe\EventDispatcher\Event\Operation;
use Closure;
use SilverStripe\ORM\DataObject;

/**
* Event listener for DataObject events that filters events based on operation type and object class.
*
* 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.
*/
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
* @param Operation[]|null $operations Array of operations to listen for. If null, listens for all operations.
*/
public function __construct(
private Closure $callback,
private array $classes,
private ?array $operations = null
) {
$this->operations = $operations ?? Operation::cases();
}

/**
* Handles a DataObject event.
*
* Checks if the event matches the configured operations and classes,
* and executes the callback if it does.
*
* @param DataObjectEvent $event The event to handle
*/
public function __invoke(DataObjectEvent $event): void
{
// Check if we should handle this class
if (!$this->shouldHandleClass($event->getObjectClass())) {
return;
}

// Check if we should handle this operation
if (!in_array($event->getOperation(), $this->operations)) {
return;
}

// Execute callback
call_user_func($this->callback, $event);
}

/**
* Checks if the given class matches any of the configured target classes.
*
* A match occurs if the class is either the same as or a subclass of any target class.
*
* @param string $class The class name to check
* @return bool True if the class should be handled, false otherwise
*/
private function shouldHandleClass(string $class): bool
{
foreach ($this->classes as $targetClass) {
if (is_a($class, $targetClass, true)) {
return true;
}
}
return false;
}
}
52 changes: 0 additions & 52 deletions src/Event/AbstractDataObjectEvent.php

This file was deleted.

13 changes: 0 additions & 13 deletions src/Event/DataObjectDeleteEvent.php

This file was deleted.

Loading

0 comments on commit e3063d5

Please sign in to comment.