Skip to content

Instantly share code, notes, and snippets.

@voltel
Last active October 5, 2022 18:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save voltel/ac2820fc7f97892999162774452a97fa to your computer and use it in GitHub Desktop.
Save voltel/ac2820fc7f97892999162774452a97fa to your computer and use it in GitHub Desktop.
A trait that can be used by custom normalizer that was decorated by "api_platform.jsonld.normalizer.item"and/or "api_platform.serializer.normalizer.item"as described here: https://api-platform.com/docs/core/serialization/#decorating-a-serializer-and-adding-extra-data
<?php
namespace App\EntityNormalizer\Common;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
interface DecoratedApiNormalizerAwareInterface extends
DenormalizerInterface,
SerializerAwareInterface
{
// This interface combines interfaces to be implemented by DecoratedApiPlatformNormalizerAwareTrait
}
<?php
namespace App\EntityNormalizer\Common;
use ApiPlatform\Core\JsonLd\Serializer\ItemNormalizer as JsonLdItemNormalizerAlias;
use ApiPlatform\Core\Serializer\ItemNormalizer as JsonItemNormalizerAlias;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
/**
* @see DecoratedApiNormalizerAwareInterface
*/
trait DecoratedApiPlatformNormalizerAwareTrait
{
/** @var NormalizerInterface */
private $decoratedNormalizer;
/**
* @required
*/
public function setDecoratedNormalizer(NormalizerInterface $decoratedNormalizer)
{
if (!$decoratedNormalizer instanceof DenormalizerInterface) {
throw new \InvalidArgumentException(sprintf('voltel: The decorated normalizer must implement the %s.',
DenormalizerInterface::class));
}
$this->decoratedNormalizer = $decoratedNormalizer;
}
/**
* @see DenormalizerInterface
*/
public function supportsDenormalization($data, $type, string $format = null)
{
return $this->decoratedNormalizer->supportsDenormalization($data, $type, $format);
}
/**
* @see DenormalizerInterface
*/
public function denormalize($data, $class, string $format = null, array $context = [])
{
return $this->decoratedNormalizer->denormalize($data, $class, $format, $context);
}
/**
* @see SerializerAwareInterface
*/
public function setSerializer(SerializerInterface $serializer)
{
if($this->decoratedNormalizer instanceof SerializerAwareInterface) {
$this->decoratedNormalizer->setSerializer($serializer);
}
}
}
<?php
namespace App\EntityNormalizer;
use App\Entity\MyCoolEntity;
use App\EntityNormalizer\Common\DecoratedApiNormalizerAwareInterface;
use App\EntityNormalizer\Common\DecoratedApiPlatformNormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
class MyCoolEntityCustomNormalizer implements
ContextAwareNormalizerInterface,
CacheableSupportsMethodInterface,
DecoratedApiNormalizerAwareInterface
{
use DecoratedApiPlatformNormalizerAwareTrait;
/** @var UrlGeneratorInterface */
private $router;
public function __construct(
UrlGeneratorInterface $router,
)
{
$this->router = $router;
}
public function normalize($oMyCoolEntity, string $c_format = null, array $context = [])
{
$a_model = $this->decoratedNormalizer->normalize($oMyCoolEntity, $c_format, $context);
if (!empty($context['groups']) && in_array('flag', $context['groups'])) {
/* do something cool */
$a_model['custom'] = $this->router->generate('show_my_cool_entity_info_page', [
'id' => $oMyCoolEntity->getId(),
], UrlGeneratorInterface::NETWORK_PATH);
}
return $a_model;
}//end of function
/**
* @see ContextAwareNormalizerInterface
*/
public function supportsNormalization($data, string $format = null, array $context = [])
{
return $data instanceof MyCoolEntity;
}
/**
* @see CacheableSupportsMethodInterface
*/
public function hasCacheableSupportsMethod(): bool
{
return true; // with this setup we do not use $context in supportsNormalization method
}
}
# in config/services.yaml
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
App\EntityNormalizer\MyCoolEntityCustomNormalizer:
# By default .inner is passed as argument
# decorates ApiPlatform\Core\JsonLd\Serializer\ItemNormalizer
decorates: 'api_platform.jsonld.normalizer.item'
# Need a different name to avoid duplicate YAML key
app.my_cool_entity.normalizer.json:
class: 'App\EntityNormalizer\MyCoolEntityCustomNormalizer'
# decorates ApiPlatform\Core\Serializer\ItemNormalizer
decorates: 'api_platform.serializer.normalizer.item'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment