From f1fc490a80234b9c9379fa09bf5939d69b227ffe Mon Sep 17 00:00:00 2001 From: Chris Nizzardini Date: Sun, 26 Jan 2025 12:14:36 -0500 Subject: [PATCH 1/6] Adds beforeSerialize and afterSerialize events --- plugins/collection-view/README.md | 14 +++++++++++ plugins/collection-view/src/Serializer.php | 24 ++++++++++++++++++- .../tests/TestCase/SerializerTest.php | 11 ++++++++- plugins/hal-view/README.md | 12 ++++++++++ plugins/hal-view/src/JsonSerializer.php | 9 +++++++ .../tests/TestCase/JsonSerializerTest.php | 6 +++++ plugins/json-ld-view/README.md | 13 ++++++++++ plugins/json-ld-view/src/JsonSerializer.php | 8 +++++++ .../tests/TestCase/JsonSerializerTest.php | 6 +++++ 9 files changed, 101 insertions(+), 2 deletions(-) diff --git a/plugins/collection-view/README.md b/plugins/collection-view/README.md index 0c5b047..12fe870 100644 --- a/plugins/collection-view/README.md +++ b/plugins/collection-view/README.md @@ -157,3 +157,17 @@ return [ ] ]; ``` + +## Events + +CollectionView dispatches two events: + +### MixerApi.CollectionView.beforeSerialize + +The event contains the Serializer as the subject and the `type` of data (i.e. "xml" or "json"). + +### MixerApi.CollectionView.afterSerialize + +The event contains the Serializer as the subject, the `type` of data (i.e. "xml" or "json") and the serialized data +as `data`. + diff --git a/plugins/collection-view/src/Serializer.php b/plugins/collection-view/src/Serializer.php index 769f450..e4f86ea 100644 --- a/plugins/collection-view/src/Serializer.php +++ b/plugins/collection-view/src/Serializer.php @@ -7,6 +7,8 @@ use Cake\Core\Configure; use Cake\Datasource\Paging\PaginatedResultSet; use Cake\Datasource\ResultSetInterface; +use Cake\Event\Event; +use Cake\Event\EventManager; use Cake\Http\ServerRequest; use Cake\Utility\Xml; use Cake\View\Helper\PaginatorHelper; @@ -66,12 +68,21 @@ public function __construct(mixed $serialize, ?ServerRequest $request = null, ?P */ public function asJson(int $jsonOptions = 0): string { + EventManager::instance()->dispatch(new Event('MixerApi.CollectionView.beforeSerialize', $this, [ + 'type' => 'json', + ])); + $json = json_encode($this->data, $jsonOptions); if ($json === false) { throw new RuntimeException(json_last_error_msg(), json_last_error()); } + EventManager::instance()->dispatch(new Event('MixerApi.CollectionView.afterSerialize', $this, [ + 'type' => 'json', + 'data' => $json, + ])); + return $json; } @@ -85,7 +96,18 @@ public function asJson(int $jsonOptions = 0): string */ public function asXml(array $options, string $rootNode = 'response'): string { - return Xml::fromArray([$rootNode => $this->data], $options)->saveXML(); + EventManager::instance()->dispatch(new Event('MixerApi.CollectionView.beforeSerialize', $this, [ + 'type' => 'xml', + ])); + + $xml = Xml::fromArray([$rootNode => $this->data], $options)->saveXML(); + + EventManager::instance()->dispatch(new Event('MixerApi.CollectionView.afterSerialize', $this, [ + 'type' => 'xml', + 'data' => $xml, + ])); + + return $xml; } /** diff --git a/plugins/collection-view/tests/TestCase/SerializerTest.php b/plugins/collection-view/tests/TestCase/SerializerTest.php index bcae1cc..9d65339 100644 --- a/plugins/collection-view/tests/TestCase/SerializerTest.php +++ b/plugins/collection-view/tests/TestCase/SerializerTest.php @@ -5,6 +5,8 @@ use Cake\Controller\ComponentRegistry; use Cake\Datasource\FactoryLocator; use Cake\Datasource\Paging\PaginatedResultSet; +use Cake\Event\EventList; +use Cake\Event\EventManager; use Cake\Http\Response; use Cake\Http\ServerRequest; use Cake\Routing\RouteBuilder; @@ -20,7 +22,7 @@ class SerializerTest extends TestCase { /** - * @var string[] + * @inheritdoc */ public array $fixtures = [ 'plugin.MixerApi/CollectionView.Actors', @@ -34,6 +36,8 @@ public function setUp(): void public function test_as_json(): void { + EventManager::instance()->trackEvents(true)->setEventList(new EventList()); + $actor = FactoryLocator::get('Table')->get('Actors'); $result = new PaginatedResultSet($actor->find()->limit(1)->all(), [ @@ -85,6 +89,8 @@ public function test_as_json(): void $obj = json_decode($json); $this->assertIsObject($obj); + $this->assertEventFired('MixerApi.CollectionView.beforeSerialize'); + $this->assertEventFired('MixerApi.CollectionView.afterSerialize'); $this->assertEquals(20, $obj->collection->count); $this->assertEquals(60, $obj->collection->total); $this->assertEquals('/', $obj->collection->url); @@ -93,6 +99,7 @@ public function test_as_json(): void public function test_as_xml(): void { + EventManager::instance()->trackEvents(true)->setEventList(new EventList()); $actor = FactoryLocator::get('Table')->get('Actors'); $result = new PaginatedResultSet($actor->find()->limit(1)->all(), [ @@ -142,6 +149,8 @@ public function test_as_xml(): void $this->assertIsString($xml); $simpleXml = simplexml_load_string($xml); + $this->assertEventFired('MixerApi.CollectionView.beforeSerialize'); + $this->assertEventFired('MixerApi.CollectionView.afterSerialize'); $this->assertInstanceOf(SimpleXMLElement::class, $simpleXml); $this->assertEquals('/', $simpleXml->collection->url); $this->assertInstanceOf(SimpleXMLElement::class, $simpleXml->data); diff --git a/plugins/hal-view/README.md b/plugins/hal-view/README.md index 762e158..fd3d2aa 100644 --- a/plugins/hal-view/README.md +++ b/plugins/hal-view/README.md @@ -245,3 +245,15 @@ use Cake\Http\ServerRequest; use Cake\View\Helper\PaginatorHelper; $json = (new JsonSerializer($data, new ServerRequest(), new PaginatorHelper()))->asJson(); ``` + +## Events + +HalView dispatches two events: + +### MixerApi.HalView.beforeSerialize + +The event contains the Serializer as the subject. + +### MixerApi.HalView.afterSerialize + +The event contains the Serializer as the subject and the serialized data as `data`. diff --git a/plugins/hal-view/src/JsonSerializer.php b/plugins/hal-view/src/JsonSerializer.php index 75d00a5..0ef80c5 100644 --- a/plugins/hal-view/src/JsonSerializer.php +++ b/plugins/hal-view/src/JsonSerializer.php @@ -6,10 +6,13 @@ use Cake\Datasource\EntityInterface; use Cake\Datasource\Paging\PaginatedResultSet; use Cake\Datasource\ResultSetInterface; +use Cake\Event\Event; +use Cake\Event\EventManager; use Cake\Http\ServerRequest; use Cake\ORM\Entity; use Cake\Utility\Inflector; use Cake\View\Helper\PaginatorHelper; +use Cake\View\View; use MixerApi\Core\View\SerializableAssociation; use ReflectionClass; use ReflectionException; @@ -63,12 +66,18 @@ public function __construct(mixed $serialize, ?ServerRequest $request = null, ?P */ public function asJson(int $jsonOptions = 0): string { + EventManager::instance()->dispatch(new Event('MixerApi.HalView.beforeSerialize', $this)); + $json = json_encode($this->data, $jsonOptions); if ($json === false) { throw new RuntimeException(json_last_error_msg(), json_last_error()); } + EventManager::instance()->dispatch(new Event('MixerApi.HalView.afterSerialize', $this, [ + 'data' => $json, + ])); + return $json; } diff --git a/plugins/hal-view/tests/TestCase/JsonSerializerTest.php b/plugins/hal-view/tests/TestCase/JsonSerializerTest.php index 02f776c..69f6b79 100644 --- a/plugins/hal-view/tests/TestCase/JsonSerializerTest.php +++ b/plugins/hal-view/tests/TestCase/JsonSerializerTest.php @@ -4,6 +4,8 @@ use Cake\Datasource\FactoryLocator; use Cake\Datasource\Paging\PaginatedResultSet; +use Cake\Event\EventList; +use Cake\Event\EventManager; use Cake\Http\Response; use Cake\Http\ServerRequest; use Cake\ORM\Table; @@ -71,6 +73,8 @@ public function setUp(): void public function test_collection(): void { + EventManager::instance()->trackEvents(true)->setEventList(new EventList()); + $actor = FactoryLocator::get('Table')->get('Actors'); $result = new PaginatedResultSet($actor->find()->applyOptions(['contain' => 'Films'])->limit(1)->all(), [ 'sort' => null, @@ -101,6 +105,8 @@ public function test_collection(): void $this->assertIsString($json); $this->assertIsObject(json_decode($json)); + $this->assertEventFired('MixerApi.HalView.beforeSerialize'); + $this->assertEventFired('MixerApi.HalView.afterSerialize'); } public function test_item(): void diff --git a/plugins/json-ld-view/README.md b/plugins/json-ld-view/README.md index c7f520e..f0e6c42 100644 --- a/plugins/json-ld-view/README.md +++ b/plugins/json-ld-view/README.md @@ -345,3 +345,16 @@ use Cake\Http\ServerRequest; use Cake\View\Helper\PaginatorHelper; $json = (new JsonSerializer($data, new ServerRequest(), new PaginatorHelper()))->asJson(); ``` + +## Events + +JsonLdView dispatches two events: + +### MixerApi.JsonLdView.beforeSerialize + +The event contains the Serializer as the subject. + +### MixerApi.JsonLdView.afterSerialize + +The event contains the Serializer as the subject and the serialized data as `data`. + diff --git a/plugins/json-ld-view/src/JsonSerializer.php b/plugins/json-ld-view/src/JsonSerializer.php index 8524f43..d23c1b1 100644 --- a/plugins/json-ld-view/src/JsonSerializer.php +++ b/plugins/json-ld-view/src/JsonSerializer.php @@ -7,6 +7,8 @@ use Cake\Datasource\EntityInterface; use Cake\Datasource\Paging\PaginatedResultSet; use Cake\Datasource\ResultSetInterface; +use Cake\Event\Event; +use Cake\Event\EventManager; use Cake\Http\ServerRequest; use Cake\ORM\Entity; use Cake\View\Helper\PaginatorHelper; @@ -82,12 +84,18 @@ public function __construct(mixed $serialize, ?ServerRequest $request = null, ?P */ public function asJson(int $jsonOptions = 0): string { + EventManager::instance()->dispatch(new Event('MixerApi.JsonLdView.beforeSerialize', $this)); + $json = json_encode($this->data, $jsonOptions); if ($json === false) { throw new RuntimeException(json_last_error_msg(), json_last_error()); } + EventManager::instance()->dispatch(new Event('MixerApi.JsonLdView.afterSerialize', $this, [ + 'data' => $json, + ])); + return $json; } diff --git a/plugins/json-ld-view/tests/TestCase/JsonSerializerTest.php b/plugins/json-ld-view/tests/TestCase/JsonSerializerTest.php index 9a40d73..1eaf336 100644 --- a/plugins/json-ld-view/tests/TestCase/JsonSerializerTest.php +++ b/plugins/json-ld-view/tests/TestCase/JsonSerializerTest.php @@ -4,6 +4,8 @@ use Cake\Datasource\FactoryLocator; use Cake\Datasource\Paging\PaginatedResultSet; +use Cake\Event\EventList; +use Cake\Event\EventManager; use Cake\Http\Response; use Cake\Http\ServerRequest; use Cake\ORM\Table; @@ -66,6 +68,8 @@ public function setUp(): void */ public function test_collection(string $resultType): void { + EventManager::instance()->trackEvents(true)->setEventList(new EventList()); + /** @var Table $actor */ $actor = FactoryLocator::get('Table')->get('Actors'); $result = $actor->find()->contain('Films')->limit(1)->all(); @@ -96,6 +100,8 @@ public function test_collection(string $resultType): void $this->assertIsString($json); $this->assertIsObject(json_decode($json)); + $this->assertEventFired('MixerApi.JsonLdView.beforeSerialize'); + $this->assertEventFired('MixerApi.JsonLdView.afterSerialize'); } public static function dataProviderForCollectionTypes(): array From 49751d88f007c77a5a629e627644a7c20130a3e1 Mon Sep 17 00:00:00 2001 From: Chris Nizzardini Date: Mon, 27 Jan 2025 08:52:24 -0500 Subject: [PATCH 2/6] phpcs fix --- plugins/hal-view/src/JsonSerializer.php | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/hal-view/src/JsonSerializer.php b/plugins/hal-view/src/JsonSerializer.php index 0ef80c5..20d1a92 100644 --- a/plugins/hal-view/src/JsonSerializer.php +++ b/plugins/hal-view/src/JsonSerializer.php @@ -12,7 +12,6 @@ use Cake\ORM\Entity; use Cake\Utility\Inflector; use Cake\View\Helper\PaginatorHelper; -use Cake\View\View; use MixerApi\Core\View\SerializableAssociation; use ReflectionClass; use ReflectionException; From 9f35307d088f30d2f04c02dae2c79ce97c126d35 Mon Sep 17 00:00:00 2001 From: Chris Nizzardini Date: Mon, 27 Jan 2025 20:57:47 -0500 Subject: [PATCH 3/6] Adds some getters and constants. Also some cleanup --- plugins/collection-view/README.md | 26 ++++++++-- plugins/collection-view/src/Serializer.php | 46 ++++++++++++------ .../tests/TestCase/SerializerTest.php | 6 +-- plugins/hal-view/README.md | 27 +++++++++-- plugins/hal-view/src/JsonSerializer.php | 47 +++++++++++++------ .../tests/TestCase/JsonSerializerTest.php | 4 +- plugins/json-ld-view/README.md | 26 ++++++++-- plugins/json-ld-view/src/JsonSerializer.php | 40 ++++++++++++---- .../tests/TestCase/JsonSerializerTest.php | 5 +- 9 files changed, 170 insertions(+), 57 deletions(-) diff --git a/plugins/collection-view/README.md b/plugins/collection-view/README.md index 12fe870..ea389f9 100644 --- a/plugins/collection-view/README.md +++ b/plugins/collection-view/README.md @@ -160,14 +160,34 @@ return [ ## Events -CollectionView dispatches two events: +CollectionView dispatches two events. Read the CakePHP docs for how to +[register listeners](https://book.cakephp.org/5/en/core-libraries/events.html#registering-listeners). ### MixerApi.CollectionView.beforeSerialize -The event contains the Serializer as the subject and the `type` of data (i.e. "xml" or "json"). +The event contains the Serializer as the subject and the `type` of data (i.e. "xml" or "json") and is dispatched just +before serialization. + +```php +use \Cake\Event\Event; +use \Cake\Event\EventManager; +use \MixerApi\CollectionView\Serializer + +EventManager::instance()->on(Serializer::BEFORE_SERIALIZE_EVENT, function (Event $event, string $type) { + /** @var Serializer $serializer */ + $serializer = $event->getSubject(); + $data = $serializer->getData(); // modify if you want or other stuff + $serializer->setData($data); +}) +``` ### MixerApi.CollectionView.afterSerialize The event contains the Serializer as the subject, the `type` of data (i.e. "xml" or "json") and the serialized data -as `data`. +as `data`. This is dispatched just after serialization. +```php +EventManager::instance()->on(Serializer::BEFORE_SERIALIZE_EVENT, function (Event $event, string $type, string $data) { + // whatever you want to do here +}) +``` diff --git a/plugins/collection-view/src/Serializer.php b/plugins/collection-view/src/Serializer.php index e4f86ea..8914902 100644 --- a/plugins/collection-view/src/Serializer.php +++ b/plugins/collection-view/src/Serializer.php @@ -16,16 +16,11 @@ /** * Serializes the CollectionView into either JSON or XML. - * - * @uses \Adbar\Dot - * @uses \Cake\Core\Configure - * @uses \Cake\Utility\Xml */ class Serializer { - private ?ServerRequest $request; - - private ?PaginatorHelper $paginator; + public const BEFORE_SERIALIZE_EVENT = 'MixerApi.CollectionView.beforeSerialize'; + public const AFTER_SERIALIZE_EVENT = 'MixerApi.CollectionView.afterSerialize'; /** * serialized data @@ -46,10 +41,12 @@ class Serializer * @param \Cake\Http\ServerRequest|null $request optional ServerRequest * @param \Cake\View\Helper\PaginatorHelper|null $paginator optional PaginatorHelper */ - public function __construct(mixed $serialize, ?ServerRequest $request = null, ?PaginatorHelper $paginator = null) + public function __construct( + mixed $serialize, + private ?ServerRequest $request = null, + private ?PaginatorHelper $paginator = null + ) { - $this->request = $request; - $this->paginator = $paginator; $this->config = Configure::read('CollectionView'); if ($serialize instanceof ResultSetInterface || $serialize instanceof PaginatedResultSet) { @@ -68,7 +65,7 @@ public function __construct(mixed $serialize, ?ServerRequest $request = null, ?P */ public function asJson(int $jsonOptions = 0): string { - EventManager::instance()->dispatch(new Event('MixerApi.CollectionView.beforeSerialize', $this, [ + EventManager::instance()->dispatch(new Event(self::BEFORE_SERIALIZE_EVENT, $this, [ 'type' => 'json', ])); @@ -78,7 +75,7 @@ public function asJson(int $jsonOptions = 0): string throw new RuntimeException(json_last_error_msg(), json_last_error()); } - EventManager::instance()->dispatch(new Event('MixerApi.CollectionView.afterSerialize', $this, [ + EventManager::instance()->dispatch(new Event(self::AFTER_SERIALIZE_EVENT, $this, [ 'type' => 'json', 'data' => $json, ])); @@ -96,13 +93,13 @@ public function asJson(int $jsonOptions = 0): string */ public function asXml(array $options, string $rootNode = 'response'): string { - EventManager::instance()->dispatch(new Event('MixerApi.CollectionView.beforeSerialize', $this, [ + EventManager::instance()->dispatch(new Event(self::BEFORE_SERIALIZE_EVENT, $this, [ 'type' => 'xml', ])); $xml = Xml::fromArray([$rootNode => $this->data], $options)->saveXML(); - EventManager::instance()->dispatch(new Event('MixerApi.CollectionView.afterSerialize', $this, [ + EventManager::instance()->dispatch(new Event(self::AFTER_SERIALIZE_EVENT, $this, [ 'type' => 'xml', 'data' => $xml, ])); @@ -118,6 +115,27 @@ public function getData(): mixed return $this->data; } + public function setData(mixed $data): void + { + $this->data = $data; + } + + /** + * @return \Cake\Http\ServerRequest|null + */ + public function getRequest(): ?ServerRequest + { + return $this->request; + } + + /** + * @return \Cake\View\Helper\PaginatorHelper|null + */ + public function getPaginatorHelper(): ?PaginatorHelper + { + return $this->paginator; + } + /** * @param \Cake\Datasource\ResultSetInterface|\Cake\Datasource\Paging\PaginatedResultSet $resultSet the data to be converted into a HAL array * @return array diff --git a/plugins/collection-view/tests/TestCase/SerializerTest.php b/plugins/collection-view/tests/TestCase/SerializerTest.php index 9d65339..dce0897 100644 --- a/plugins/collection-view/tests/TestCase/SerializerTest.php +++ b/plugins/collection-view/tests/TestCase/SerializerTest.php @@ -2,7 +2,6 @@ namespace MixerApi\CollectionView\Test\TestCase; -use Cake\Controller\ComponentRegistry; use Cake\Datasource\FactoryLocator; use Cake\Datasource\Paging\PaginatedResultSet; use Cake\Event\EventList; @@ -13,7 +12,6 @@ use Cake\Routing\Router; use Cake\TestSuite\TestCase; use Cake\View\Helper\PaginatorHelper; -use Cake\View\View; use MixerApi\CollectionView\Configuration; use MixerApi\CollectionView\View\JsonCollectionView; use MixerApi\CollectionView\Serializer; @@ -149,8 +147,8 @@ public function test_as_xml(): void $this->assertIsString($xml); $simpleXml = simplexml_load_string($xml); - $this->assertEventFired('MixerApi.CollectionView.beforeSerialize'); - $this->assertEventFired('MixerApi.CollectionView.afterSerialize'); + $this->assertEventFired(Serializer::BEFORE_SERIALIZE_EVENT); + $this->assertEventFired(Serializer::AFTER_SERIALIZE_EVENT); $this->assertInstanceOf(SimpleXMLElement::class, $simpleXml); $this->assertEquals('/', $simpleXml->collection->url); $this->assertInstanceOf(SimpleXMLElement::class, $simpleXml->data); diff --git a/plugins/hal-view/README.md b/plugins/hal-view/README.md index fd3d2aa..c049e68 100644 --- a/plugins/hal-view/README.md +++ b/plugins/hal-view/README.md @@ -248,12 +248,33 @@ $json = (new JsonSerializer($data, new ServerRequest(), new PaginatorHelper()))- ## Events -HalView dispatches two events: +HalView dispatches two events. Read the CakePHP docs for how to +[register listeners](https://book.cakephp.org/5/en/core-libraries/events.html#registering-listeners). ### MixerApi.HalView.beforeSerialize -The event contains the Serializer as the subject. +The event contains the Serializer as the subject and is dispatched just before serialization. + +```php +use \Cake\Event\Event; +use \Cake\Event\EventManager; +use \MixerApi\HalView\JsonSerializer; + +EventManager::instance()->on(JsonSerializer::BEFORE_SERIALIZE_EVENT, function (Event $event) { + /** @var Serializer $serializer */ + $serializer = $event->getSubject(); + $data = $serializer->getData(); // modify if you want or other stuff + $serializer->setData($data); +}) +``` ### MixerApi.HalView.afterSerialize -The event contains the Serializer as the subject and the serialized data as `data`. +The event contains the Serializer as the subject and the serialized data as `data`. This is dispatched just after +serialization. + +```php +EventManager::instance()->on(JsonSerializer::AFTER_SERIALIZE_EVENT, function (Event $event, string $data) { + // whatever you want to do here +}) +``` diff --git a/plugins/hal-view/src/JsonSerializer.php b/plugins/hal-view/src/JsonSerializer.php index 20d1a92..6f945f3 100644 --- a/plugins/hal-view/src/JsonSerializer.php +++ b/plugins/hal-view/src/JsonSerializer.php @@ -21,16 +21,11 @@ * Creates a HAL+JSON resource * * @link https://tools.ietf.org/html/draft-kelly-json-hal-06 - * @uses \Cake\Utility\Inflector - * @uses \MixerApi\Core\View\SerializableAssociation - * @uses ReflectionClass */ class JsonSerializer { - private ?ServerRequest $request; - - private ?PaginatorHelper $paginator; - + public const BEFORE_SERIALIZE_EVENT = 'MixerApi.HalView.beforeSerialize'; + public const AFTER_SERIALIZE_EVENT = 'MixerApi.HalView.afterSerialize'; private mixed $data; /** @@ -40,11 +35,12 @@ class JsonSerializer * @param \Cake\Http\ServerRequest|null $request optional ServerRequest * @param \Cake\View\Helper\PaginatorHelper|null $paginator optional PaginatorHelper */ - public function __construct(mixed $serialize, ?ServerRequest $request = null, ?PaginatorHelper $paginator = null) + public function __construct( + mixed $serialize, + private ?ServerRequest $request = null, + private ?PaginatorHelper $paginator = null + ) { - $this->request = $request; - $this->paginator = $paginator; - $hal = $this->recursion($serialize); if ($hal instanceof ResultSetInterface || $hal instanceof PaginatedResultSet) { @@ -65,7 +61,7 @@ public function __construct(mixed $serialize, ?ServerRequest $request = null, ?P */ public function asJson(int $jsonOptions = 0): string { - EventManager::instance()->dispatch(new Event('MixerApi.HalView.beforeSerialize', $this)); + EventManager::instance()->dispatch(new Event(self::BEFORE_SERIALIZE_EVENT, $this)); $json = json_encode($this->data, $jsonOptions); @@ -73,7 +69,7 @@ public function asJson(int $jsonOptions = 0): string throw new RuntimeException(json_last_error_msg(), json_last_error()); } - EventManager::instance()->dispatch(new Event('MixerApi.HalView.afterSerialize', $this, [ + EventManager::instance()->dispatch(new Event(self::AFTER_SERIALIZE_EVENT, $this, [ 'data' => $json, ])); @@ -83,13 +79,34 @@ public function asJson(int $jsonOptions = 0): string /** * Get HAL data as an array * - * @return array|null + * @return mixed */ - public function getData(): ?array + public function getData(): mixed { return $this->data; } + public function setData(mixed $data): void + { + $this->data = $data; + } + + /** + * @return \Cake\Http\ServerRequest|null + */ + public function getRequest(): ?ServerRequest + { + return $this->request; + } + + /** + * @return \Cake\View\Helper\PaginatorHelper|null + */ + public function getPaginatorHelper(): ?PaginatorHelper + { + return $this->paginator; + } + /** * Recursive method for converting mixed data into HAL. This method converts instances of Cake\ORM\Entity into * HAL resources, but does not serialize the data. diff --git a/plugins/hal-view/tests/TestCase/JsonSerializerTest.php b/plugins/hal-view/tests/TestCase/JsonSerializerTest.php index 69f6b79..6cac6bb 100644 --- a/plugins/hal-view/tests/TestCase/JsonSerializerTest.php +++ b/plugins/hal-view/tests/TestCase/JsonSerializerTest.php @@ -105,8 +105,8 @@ public function test_collection(): void $this->assertIsString($json); $this->assertIsObject(json_decode($json)); - $this->assertEventFired('MixerApi.HalView.beforeSerialize'); - $this->assertEventFired('MixerApi.HalView.afterSerialize'); + $this->assertEventFired(JsonSerializer::BEFORE_SERIALIZE_EVENT); + $this->assertEventFired(JsonSerializer::AFTER_SERIALIZE_EVENT); } public function test_item(): void diff --git a/plugins/json-ld-view/README.md b/plugins/json-ld-view/README.md index f0e6c42..3d86a96 100644 --- a/plugins/json-ld-view/README.md +++ b/plugins/json-ld-view/README.md @@ -348,13 +348,33 @@ $json = (new JsonSerializer($data, new ServerRequest(), new PaginatorHelper()))- ## Events -JsonLdView dispatches two events: +JsonLdView dispatches two events. Read the CakePHP docs for how to +[register listeners](https://book.cakephp.org/5/en/core-libraries/events.html#registering-listeners). ### MixerApi.JsonLdView.beforeSerialize -The event contains the Serializer as the subject. +The event contains the Serializer as the subject and is dispatched just before serialization. + +```php +use \Cake\Event\Event; +use \Cake\Event\EventManager; +use \MixerApi\JsonLdView\JsonSerializer; + +EventManager::instance()->on(JsonSerializer::BEFORE_SERIALIZE_EVENT, function (Event $event) { + /** @var Serializer $serializer */ + $serializer = $event->getSubject(); + $data = $serializer->getData(); // modify if you want or other stuff + $serializer->setData($data); +}) +``` ### MixerApi.JsonLdView.afterSerialize -The event contains the Serializer as the subject and the serialized data as `data`. +The event contains the Serializer as the subject and the serialized data as `data`. This is dispatched just after +serialization. +```php +EventManager::instance()->on(JsonSerializer::AFTER_SERIALIZE_EVENT, function (Event $event, string $data) { + // whatever you want to do here +}) +``` diff --git a/plugins/json-ld-view/src/JsonSerializer.php b/plugins/json-ld-view/src/JsonSerializer.php index d23c1b1..ff6d33d 100644 --- a/plugins/json-ld-view/src/JsonSerializer.php +++ b/plugins/json-ld-view/src/JsonSerializer.php @@ -19,15 +19,13 @@ /** * Creates a JSON-LD resource * - * @uses \MixerApi\Core\View\SerializableAssociation * @link https://json-ld.org/ * @link https://lists.w3.org/Archives/Public/public-hydra/2015Oct/0163.html */ class JsonSerializer { - private ?ServerRequest $request; - - private ?PaginatorHelper $paginator; + public const BEFORE_SERIALIZE_EVENT = 'MixerApi.JsonLdView.beforeSerialize'; + public const AFTER_SERIALIZE_EVENT = 'MixerApi.JsonLdView.afterSerialize'; /** * JSON-LD data array @@ -55,11 +53,12 @@ class JsonSerializer * @param \Cake\Http\ServerRequest|null $request optional ServerRequest * @param \Cake\View\Helper\PaginatorHelper|null $paginator optional PaginatorHelper */ - public function __construct(mixed $serialize, ?ServerRequest $request = null, ?PaginatorHelper $paginator = null) + public function __construct( + mixed $serialize, + private ?ServerRequest $request = null, + private ?PaginatorHelper $paginator = null + ) { - $this->request = $request; - $this->paginator = $paginator; - $jsonLd = $this->recursion($serialize); $this->config = Configure::read('JsonLdView'); if (isset($this->config['isHydra']) && $this->config['isHydra']) { @@ -84,7 +83,7 @@ public function __construct(mixed $serialize, ?ServerRequest $request = null, ?P */ public function asJson(int $jsonOptions = 0): string { - EventManager::instance()->dispatch(new Event('MixerApi.JsonLdView.beforeSerialize', $this)); + EventManager::instance()->dispatch(new Event(self::BEFORE_SERIALIZE_EVENT, $this)); $json = json_encode($this->data, $jsonOptions); @@ -92,7 +91,7 @@ public function asJson(int $jsonOptions = 0): string throw new RuntimeException(json_last_error_msg(), json_last_error()); } - EventManager::instance()->dispatch(new Event('MixerApi.JsonLdView.afterSerialize', $this, [ + EventManager::instance()->dispatch(new Event(self::AFTER_SERIALIZE_EVENT, $this, [ 'data' => $json, ])); @@ -109,6 +108,27 @@ public function getData(): ?array return $this->data; } + public function setData(mixed $data): void + { + $this->data = $data; + } + + /** + * @return \Cake\Http\ServerRequest|null + */ + public function getRequest(): ?ServerRequest + { + return $this->request; + } + + /** + * @return \Cake\View\Helper\PaginatorHelper|null + */ + public function getPaginatorHelper(): ?PaginatorHelper + { + return $this->paginator; + } + /** * Recursive method for converting mixed data into JSON-LD. This method converts instances of Cake\ORM\Entity into * JSON-LD resources, but does not serialize the data. diff --git a/plugins/json-ld-view/tests/TestCase/JsonSerializerTest.php b/plugins/json-ld-view/tests/TestCase/JsonSerializerTest.php index 1eaf336..abb0bf7 100644 --- a/plugins/json-ld-view/tests/TestCase/JsonSerializerTest.php +++ b/plugins/json-ld-view/tests/TestCase/JsonSerializerTest.php @@ -15,7 +15,6 @@ use Cake\View\Helper\PaginatorHelper; use Cake\View\View; use MixerApi\JsonLdView\JsonSerializer; -use MixerApi\JsonLdView\View\JsonLdView; class JsonSerializerTest extends TestCase { @@ -100,8 +99,8 @@ public function test_collection(string $resultType): void $this->assertIsString($json); $this->assertIsObject(json_decode($json)); - $this->assertEventFired('MixerApi.JsonLdView.beforeSerialize'); - $this->assertEventFired('MixerApi.JsonLdView.afterSerialize'); + $this->assertEventFired(JsonSerializer::BEFORE_SERIALIZE_EVENT); + $this->assertEventFired(JsonSerializer::AFTER_SERIALIZE_EVENT); } public static function dataProviderForCollectionTypes(): array From 360beb6b9317cc1610b9df8540ff6dc194c07028 Mon Sep 17 00:00:00 2001 From: Chris Nizzardini Date: Mon, 27 Jan 2025 21:01:47 -0500 Subject: [PATCH 4/6] static analysis fixes --- plugins/collection-view/src/Serializer.php | 7 +++++-- plugins/hal-view/src/JsonSerializer.php | 7 +++++-- plugins/json-ld-view/src/JsonSerializer.php | 7 +++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/plugins/collection-view/src/Serializer.php b/plugins/collection-view/src/Serializer.php index 8914902..deae5aa 100644 --- a/plugins/collection-view/src/Serializer.php +++ b/plugins/collection-view/src/Serializer.php @@ -45,8 +45,7 @@ public function __construct( mixed $serialize, private ?ServerRequest $request = null, private ?PaginatorHelper $paginator = null - ) - { + ) { $this->config = Configure::read('CollectionView'); if ($serialize instanceof ResultSetInterface || $serialize instanceof PaginatedResultSet) { @@ -115,6 +114,10 @@ public function getData(): mixed return $this->data; } + /** + * @param mixed $data The data to be serialized + * @return void + */ public function setData(mixed $data): void { $this->data = $data; diff --git a/plugins/hal-view/src/JsonSerializer.php b/plugins/hal-view/src/JsonSerializer.php index 6f945f3..f0f4a13 100644 --- a/plugins/hal-view/src/JsonSerializer.php +++ b/plugins/hal-view/src/JsonSerializer.php @@ -39,8 +39,7 @@ public function __construct( mixed $serialize, private ?ServerRequest $request = null, private ?PaginatorHelper $paginator = null - ) - { + ) { $hal = $this->recursion($serialize); if ($hal instanceof ResultSetInterface || $hal instanceof PaginatedResultSet) { @@ -86,6 +85,10 @@ public function getData(): mixed return $this->data; } + /** + * @param mixed $data The data to be serialized + * @return void + */ public function setData(mixed $data): void { $this->data = $data; diff --git a/plugins/json-ld-view/src/JsonSerializer.php b/plugins/json-ld-view/src/JsonSerializer.php index ff6d33d..b434933 100644 --- a/plugins/json-ld-view/src/JsonSerializer.php +++ b/plugins/json-ld-view/src/JsonSerializer.php @@ -57,8 +57,7 @@ public function __construct( mixed $serialize, private ?ServerRequest $request = null, private ?PaginatorHelper $paginator = null - ) - { + ) { $jsonLd = $this->recursion($serialize); $this->config = Configure::read('JsonLdView'); if (isset($this->config['isHydra']) && $this->config['isHydra']) { @@ -108,6 +107,10 @@ public function getData(): ?array return $this->data; } + /** + * @param mixed $data The data to be serialized + * @return void + */ public function setData(mixed $data): void { $this->data = $data; From a7296aed370632c880b8310151cb0c62ecaf470f Mon Sep 17 00:00:00 2001 From: Chris Nizzardini Date: Mon, 27 Jan 2025 21:04:30 -0500 Subject: [PATCH 5/6] readme updates --- plugins/collection-view/README.md | 6 +++--- plugins/hal-view/README.md | 2 +- plugins/json-ld-view/README.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/collection-view/README.md b/plugins/collection-view/README.md index ea389f9..58982df 100644 --- a/plugins/collection-view/README.md +++ b/plugins/collection-view/README.md @@ -165,7 +165,7 @@ CollectionView dispatches two events. Read the CakePHP docs for how to ### MixerApi.CollectionView.beforeSerialize -The event contains the Serializer as the subject and the `type` of data (i.e. "xml" or "json") and is dispatched just +The event contains the Serializer as the subject and the `$type` of data (i.e. "xml" or "json") and is dispatched just before serialization. ```php @@ -183,8 +183,8 @@ EventManager::instance()->on(Serializer::BEFORE_SERIALIZE_EVENT, function (Event ### MixerApi.CollectionView.afterSerialize -The event contains the Serializer as the subject, the `type` of data (i.e. "xml" or "json") and the serialized data -as `data`. This is dispatched just after serialization. +The event contains the Serializer as the subject, the `$type` of data (i.e. "xml" or "json") and the serialized data +as `$data`. This is dispatched just after serialization. ```php EventManager::instance()->on(Serializer::BEFORE_SERIALIZE_EVENT, function (Event $event, string $type, string $data) { diff --git a/plugins/hal-view/README.md b/plugins/hal-view/README.md index c049e68..bdbbb15 100644 --- a/plugins/hal-view/README.md +++ b/plugins/hal-view/README.md @@ -270,7 +270,7 @@ EventManager::instance()->on(JsonSerializer::BEFORE_SERIALIZE_EVENT, function (E ### MixerApi.HalView.afterSerialize -The event contains the Serializer as the subject and the serialized data as `data`. This is dispatched just after +The event contains the Serializer as the subject and the serialized data as `$data`. This is dispatched just after serialization. ```php diff --git a/plugins/json-ld-view/README.md b/plugins/json-ld-view/README.md index 3d86a96..9c7309c 100644 --- a/plugins/json-ld-view/README.md +++ b/plugins/json-ld-view/README.md @@ -370,7 +370,7 @@ EventManager::instance()->on(JsonSerializer::BEFORE_SERIALIZE_EVENT, function (E ### MixerApi.JsonLdView.afterSerialize -The event contains the Serializer as the subject and the serialized data as `data`. This is dispatched just after +The event contains the Serializer as the subject and the serialized data as `$data`. This is dispatched just after serialization. ```php From 01d450ee5ab167469c889875e49f11908d8ad25b Mon Sep 17 00:00:00 2001 From: Chris Nizzardini Date: Mon, 27 Jan 2025 21:06:57 -0500 Subject: [PATCH 6/6] test cleanup --- plugins/collection-view/tests/TestCase/SerializerTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/collection-view/tests/TestCase/SerializerTest.php b/plugins/collection-view/tests/TestCase/SerializerTest.php index dce0897..c8f96ac 100644 --- a/plugins/collection-view/tests/TestCase/SerializerTest.php +++ b/plugins/collection-view/tests/TestCase/SerializerTest.php @@ -87,8 +87,8 @@ public function test_as_json(): void $obj = json_decode($json); $this->assertIsObject($obj); - $this->assertEventFired('MixerApi.CollectionView.beforeSerialize'); - $this->assertEventFired('MixerApi.CollectionView.afterSerialize'); + $this->assertEventFired(Serializer::BEFORE_SERIALIZE_EVENT); + $this->assertEventFired(Serializer::AFTER_SERIALIZE_EVENT); $this->assertEquals(20, $obj->collection->count); $this->assertEquals(60, $obj->collection->total); $this->assertEquals('/', $obj->collection->url);