Created
May 21, 2020 22:25
-
-
Save Aliance/9bb8ce4b93254bc214cf5564779464e2 to your computer and use it in GitHub Desktop.
Add extra information for the list of objects while serializing via JMS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace AppBundle\DTO; | |
use AppBundle\Entity\Item; | |
use JMS\Serializer\Annotation as JMS; | |
/** | |
* @JMS\ExclusionPolicy("all") | |
*/ | |
class ItemListDTO | |
{ | |
/** | |
* @JMS\Expose | |
* @JMS\Type("array<AppBundle\Entity\Item>") | |
*/ | |
private array $items; | |
public function __construct(array $items) | |
{ | |
$this->items = $items; | |
} | |
/** | |
* @return Item[] | |
*/ | |
public function getItems(): array | |
{ | |
return $this->items; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace AppBundle\Entity; | |
use JMS\Serializer\Annotation as JMS; | |
/** | |
* @JMS\ExclusionPolicy("all") | |
*/ | |
class Item | |
{ | |
/** | |
* @JMS\Expose | |
* @JMS\Type("integer") | |
*/ | |
private ?int $id = null; | |
/** | |
* @JMS\Expose | |
* @JMS\Type("string") | |
*/ | |
private ?string $title = null; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace AppBundle\Listener; | |
use AppBundle\DTO\ItemListDTO; | |
use JMS\Serializer\Context; | |
use JMS\Serializer\GraphNavigator; | |
use JMS\Serializer\Handler\SubscribingHandlerInterface; | |
use JMS\Serializer\JsonSerializationVisitor; | |
class ItemListSubscribingHandler implements SubscribingHandlerInterface | |
{ | |
public static function getSubscribingMethods(): array | |
{ | |
return [ | |
[ | |
'direction' => GraphNavigator::DIRECTION_SERIALIZATION, | |
'format' => 'json', | |
'type' => ItemListDTO::class, | |
/** @see ItemListSubscribingHandler::serializeItemListToJson() */ | |
'method' => 'serializeItemListToJson', | |
], | |
]; | |
} | |
public function serializeItemListToJson( | |
JsonSerializationVisitor $visitor, | |
ItemListDTO $itemList, | |
array $type, | |
Context $context | |
) { | |
return $itemList->getItems(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace AppBundle\Listener; | |
use AppBundle\DTO\ItemListDTO; | |
use AppBundle\Entity\Item; | |
use JMS\Serializer\Context; | |
use JMS\Serializer\EventDispatcher\Events; | |
use JMS\Serializer\EventDispatcher\EventSubscriberInterface; | |
use JMS\Serializer\EventDispatcher\ObjectEvent; | |
use JMS\Serializer\JsonSerializationVisitor; | |
use JMS\Serializer\Metadata\StaticPropertyMetadata; | |
class ItemSerializationSubscriber implements EventSubscriberInterface | |
{ | |
private array $extraDataList; | |
public static function getSubscribedEvents(): array | |
{ | |
return [ | |
[ | |
'event' => Events::PRE_SERIALIZE, | |
/** @see ItemSerializationSubscriber::onItemListPreSerialize() */ | |
'method' => 'onItemListPreSerialize', | |
'class' => ItemListDTO::class, | |
], | |
[ | |
'event' => Events::POST_SERIALIZE, | |
/** @see ItemSerializationSubscriber::onPostSerialize() */ | |
'method' => 'onPostSerialize', | |
'class' => Item::class, | |
], | |
]; | |
} | |
public function onItemListPreSerialize(ObjectEvent $event): void | |
{ | |
$visitor = $event->getVisitor(); | |
if (!$visitor instanceof JsonSerializationVisitor) { | |
return; | |
} | |
$itemList = $event->getObject(); | |
if (!$itemList instanceof ItemListDTO) { | |
return; | |
} | |
$itemIdList = array_map(fn (Item $item) => $item->getId(), $itemList->getItems()); | |
$this->extraDataList = $this->statsService->getItemSize($itemIdList); | |
} | |
public function onPostSerialize(ObjectEvent $event): void | |
{ | |
$visitor = $event->getVisitor(); | |
if (!$visitor instanceof JsonSerializationVisitor) { | |
return; | |
} | |
$item = $event->getObject(); | |
if (!$item instanceof Item) { | |
return; | |
} | |
$itemId = $item->getId(); | |
$extraData = $this->extraDataList[$itemId] ?? null; | |
$context = $event->getContext(); | |
$visitor->visitProperty(new StaticPropertyMetadata('', 'extra', $extraData), $extraData, $context); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment