From 2e69d8539a52ab39c68391e544ac3b8bdd006b3c Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Sun, 10 Feb 2019 20:33:14 +0100 Subject: [PATCH] Read event --- composer.json | 2 +- .../ApiPlatformExtension.php | 1 + .../Bundle/EventListener/EventDispatcher.php | 47 +++++++++++++++++ .../Symfony/Bundle/Resources/config/api.xml | 2 +- .../Resources/config/event_dispatcher.xml | 31 +++++++++++ src/Event/Event.php | 51 +++++++++++++++++++ src/Event/EventInterface.php | 28 ++++++++++ src/Event/PostReadEvent.php | 21 ++++++++ src/Event/PreReadEvent.php | 21 ++++++++ src/Event/ReadEvent.php | 21 ++++++++ src/EventListener/ReadListener.php | 7 ++- src/Events.php | 40 +++++++++++++++ 12 files changed, 266 insertions(+), 6 deletions(-) create mode 100644 src/Bridge/Symfony/Bundle/EventListener/EventDispatcher.php create mode 100644 src/Bridge/Symfony/Bundle/Resources/config/event_dispatcher.xml create mode 100644 src/Event/Event.php create mode 100644 src/Event/EventInterface.php create mode 100644 src/Event/PostReadEvent.php create mode 100644 src/Event/PreReadEvent.php create mode 100644 src/Event/ReadEvent.php create mode 100644 src/Events.php diff --git a/composer.json b/composer.json index b8cc1465a56..34b0ae13ff8 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ "doctrine/inflector": "^1.0", "psr/cache": "^1.0", "psr/container": "^1.0", + "symfony/event-dispatcher": "^3.4 || ^4.0", "symfony/http-foundation": "^3.4 || ^4.0", "symfony/http-kernel": "^3.4 || ^4.0", "symfony/property-access": "^3.4 || ^4.0", @@ -58,7 +59,6 @@ "symfony/debug": "^3.4 || ^4.0", "symfony/dependency-injection": "^3.4 || ^4.0", "symfony/doctrine-bridge": "^3.4 || ^4.0", - "symfony/event-dispatcher": "^3.4 || ^4.0", "symfony/expression-language": "^3.4 || ^4.0", "symfony/finder": "^3.4 || ^4.0", "symfony/form": "^3.4 || ^4.0", diff --git a/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php b/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php index 0578fe3ee59..8b4d7a77b28 100644 --- a/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php +++ b/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php @@ -101,6 +101,7 @@ public function load(array $configs, ContainerBuilder $container) $loader->load('api.xml'); $loader->load('data_persister.xml'); $loader->load('data_provider.xml'); + $loader->load('event_dispatcher.xml'); $loader->load('filter.xml'); $container->registerForAutoconfiguration(DataPersisterInterface::class) diff --git a/src/Bridge/Symfony/Bundle/EventListener/EventDispatcher.php b/src/Bridge/Symfony/Bundle/EventListener/EventDispatcher.php new file mode 100644 index 00000000000..256620fd7bb --- /dev/null +++ b/src/Bridge/Symfony/Bundle/EventListener/EventDispatcher.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core\Bridge\Symfony\Bundle\EventListener; + +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; + +/** + * @author Alan Poulain + */ +final class EventDispatcher +{ + private $eventName; + private $eventClass; + private $dispatcher; + + public function __construct(string $eventName, string $eventClass, EventDispatcherInterface $dispatcher) + { + $this->eventName = $eventName; + $this->eventClass = $eventClass; + $this->dispatcher = $dispatcher; + } + + public function dispatch(Event $event): void + { + $internalEvent = null; + + switch ($event) { + case $event instanceof GetResponseEvent: + $internalEvent = new $this->eventClass(null, ['request' => $event->getRequest()]); + } + + $this->dispatcher->dispatch($this->eventName, $internalEvent); + } +} diff --git a/src/Bridge/Symfony/Bundle/Resources/config/api.xml b/src/Bridge/Symfony/Bundle/Resources/config/api.xml index 7a23930994f..42e466fa5eb 100644 --- a/src/Bridge/Symfony/Bundle/Resources/config/api.xml +++ b/src/Bridge/Symfony/Bundle/Resources/config/api.xml @@ -150,7 +150,7 @@ - + diff --git a/src/Bridge/Symfony/Bundle/Resources/config/event_dispatcher.xml b/src/Bridge/Symfony/Bundle/Resources/config/event_dispatcher.xml new file mode 100644 index 00000000000..f3a6b6b0703 --- /dev/null +++ b/src/Bridge/Symfony/Bundle/Resources/config/event_dispatcher.xml @@ -0,0 +1,31 @@ + + + + + + api_platform.pre_read + ApiPlatform\Core\Event\PreReadEvent + + + + + + + api_platform.read + ApiPlatform\Core\Event\ReadEvent + + + + + + + api_platform.post_read + ApiPlatform\Core\Event\PostReadEvent + + + + + + diff --git a/src/Event/Event.php b/src/Event/Event.php new file mode 100644 index 00000000000..2f562983523 --- /dev/null +++ b/src/Event/Event.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core\Event; + +use Symfony\Component\EventDispatcher\Event as BaseEvent; + +/** + * @author Alan Poulain + */ +abstract class Event extends BaseEvent implements EventInterface +{ + private $data; + private $context; + + public function __construct($data, array $context = []) + { + $this->data = $data; + $this->context = $context; + } + + public function getData() + { + return $this->data; + } + + public function setData($data): void + { + $this->data = $data; + } + + public function getContext(): array + { + return $this->context; + } + + public function setContext(array $context): void + { + $this->context = $context; + } +} diff --git a/src/Event/EventInterface.php b/src/Event/EventInterface.php new file mode 100644 index 00000000000..e61e2979e65 --- /dev/null +++ b/src/Event/EventInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core\Event; + +/** + * @author Alan Poulain + */ +interface EventInterface +{ + public function getData(); + + public function setData($data): void; + + public function getContext(): array; + + public function setContext(array $context): void; +} diff --git a/src/Event/PostReadEvent.php b/src/Event/PostReadEvent.php new file mode 100644 index 00000000000..0f57273f6ed --- /dev/null +++ b/src/Event/PostReadEvent.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core\Event; + +/** + * @author Alan Poulain + */ +final class PostReadEvent extends Event +{ +} diff --git a/src/Event/PreReadEvent.php b/src/Event/PreReadEvent.php new file mode 100644 index 00000000000..36ff15c0cbc --- /dev/null +++ b/src/Event/PreReadEvent.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core\Event; + +/** + * @author Alan Poulain + */ +final class PreReadEvent extends Event +{ +} diff --git a/src/Event/ReadEvent.php b/src/Event/ReadEvent.php new file mode 100644 index 00000000000..ab59fb0b801 --- /dev/null +++ b/src/Event/ReadEvent.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core\Event; + +/** + * @author Alan Poulain + */ +final class ReadEvent extends Event +{ +} diff --git a/src/EventListener/ReadListener.php b/src/EventListener/ReadListener.php index 80fb62d439f..6415e23e79f 100644 --- a/src/EventListener/ReadListener.php +++ b/src/EventListener/ReadListener.php @@ -17,14 +17,13 @@ use ApiPlatform\Core\DataProvider\ItemDataProviderInterface; use ApiPlatform\Core\DataProvider\OperationDataProviderTrait; use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface; +use ApiPlatform\Core\Event\EventInterface; use ApiPlatform\Core\Exception\InvalidIdentifierException; use ApiPlatform\Core\Exception\RuntimeException; use ApiPlatform\Core\Identifier\IdentifierConverterInterface; use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface; use ApiPlatform\Core\Util\RequestAttributesExtractor; use ApiPlatform\Core\Util\RequestParser; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** @@ -52,9 +51,9 @@ public function __construct(CollectionDataProviderInterface $collectionDataProvi * * @throws NotFoundHttpException */ - public function onKernelRequest(GetResponseEvent $event) + public function handleEvent(EventInterface $event) { - $request = $event->getRequest(); + $request = $event->getContext()['request']; if ( !($attributes = RequestAttributesExtractor::extractAttributes($request)) || !$attributes['receive'] diff --git a/src/Events.php b/src/Events.php new file mode 100644 index 00000000000..89b4ec390ba --- /dev/null +++ b/src/Events.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Core; + +/** + * @author Alan Poulain + */ +final class Events +{ + public const PRE_READ = 'api_platform.pre_read'; + public const READ = 'api_platform.read'; + public const POST_READ = 'api_platform.post_read'; + + public const PRE_DESERIALIZE = 'api_platform.pre_deserialize'; + public const DESERIALIZE = 'api_platform.deserialize'; + public const POST_DESERIALIZE = 'api_platform.post_deserialize'; + + public const PRE_VALIDATE = 'api_platform.pre_validate'; + public const VALIDATE = 'api_platform.validate'; + public const POST_VALIDATE = 'api_platform.post_validate'; + + public const PRE_WRITE = 'api_platform.pre_write'; + public const WRITE = 'api_platform.write'; + public const POST_WRITE = 'api_platform.post_write'; + + public const PRE_SERIALIZE = 'api_platform.pre_serialize'; + public const SERIALIZE = 'api_platform.serialize'; + public const POST_SERIALIZE = 'api_platform.post_serialize'; +}