mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-10-03 20:09:42 +00:00
Implement global circular reference handler in line with latest symfony practices and remove now redundant code from current normalizers
This commit is contained in:
4
config/packages/serializer.yaml
Normal file
4
config/packages/serializer.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
framework:
|
||||||
|
serializer:
|
||||||
|
enabled: true
|
||||||
|
enable_attributes: true
|
@@ -18,3 +18,8 @@ services:
|
|||||||
Chill\MainBundle\ArgumentResolver\EntityValueResolver:
|
Chill\MainBundle\ArgumentResolver\EntityValueResolver:
|
||||||
tags:
|
tags:
|
||||||
- { name: controller.argument_value_resolver, priority: 50 }
|
- { name: controller.argument_value_resolver, priority: 50 }
|
||||||
|
|
||||||
|
Chill\MainBundle\Serializer\CircularReferenceHandler:
|
||||||
|
public: false
|
||||||
|
tags:
|
||||||
|
- { name: 'serializer.circular_reference_handler' }
|
||||||
|
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
namespace Chill\MainBundle\Serializer;
|
||||||
|
|
||||||
|
class CircularReferenceHandler
|
||||||
|
{
|
||||||
|
public function handle(object $object, ?string $format = null, array $context = []): mixed
|
||||||
|
{
|
||||||
|
if (method_exists($object, 'getId')) {
|
||||||
|
return [
|
||||||
|
'id' => $object->getId(),
|
||||||
|
'_class' => (new \ReflectionClass($object))->getShortName(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return spl_object_id($object);
|
||||||
|
}
|
||||||
|
}
|
@@ -14,42 +14,43 @@ namespace Chill\PersonBundle\Serializer\Normalizer;
|
|||||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||||
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
|
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
|
||||||
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
use Symfony\Component\Workflow\Registry;
|
use Symfony\Component\Workflow\Registry;
|
||||||
|
|
||||||
class AccompanyingPeriodWorkEvaluationNormalizer implements \Symfony\Component\Serializer\Normalizer\NormalizerInterface, NormalizerAwareInterface
|
class AccompanyingPeriodWorkEvaluationNormalizer implements NormalizerInterface, NormalizerAwareInterface
|
||||||
{
|
{
|
||||||
use NormalizerAwareTrait;
|
use NormalizerAwareTrait;
|
||||||
|
|
||||||
private const IGNORE_EVALUATION = 'evaluation:ignore';
|
public function __construct(
|
||||||
|
private readonly Registry $registry,
|
||||||
public function __construct(private readonly Registry $registry, private readonly EntityWorkflowRepository $entityWorkflowRepository, private readonly MetadataExtractor $metadataExtractor) {}
|
private readonly EntityWorkflowRepository $entityWorkflowRepository,
|
||||||
|
private readonly MetadataExtractor $metadataExtractor,
|
||||||
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param AccompanyingPeriodWorkEvaluation $object
|
* @param AccompanyingPeriodWorkEvaluation $object
|
||||||
*/
|
*/
|
||||||
public function normalize($object, ?string $format = null, array $context = []): array
|
public function normalize($object, ?string $format = null, array $context = []): array
|
||||||
{
|
{
|
||||||
$initial = $this->normalizer->normalize($object, $format, array_merge(
|
$initial = $this->normalizer->normalize($object, $format, $context);
|
||||||
$context,
|
|
||||||
));
|
|
||||||
|
|
||||||
// due to bug: https://api-platform.com/docs/core/serialization/#collection-relation
|
|
||||||
// and also: https://github.com/symfony/symfony/issues/36965
|
|
||||||
// we have to rewrite the documents as a collection
|
|
||||||
$initial['documents'] = $this->normalizer->normalize(
|
$initial['documents'] = $this->normalizer->normalize(
|
||||||
$object->getDocuments()->getValues(),
|
$object->getDocuments()->getValues(),
|
||||||
$format,
|
$format,
|
||||||
$context
|
$context
|
||||||
);
|
);
|
||||||
|
|
||||||
// then, we add normalization for things which are not into the entity
|
$initial['accompanyingPeriodWork'] = $this->normalizer->normalize(
|
||||||
|
$object->getAccompanyingPeriodWork(),
|
||||||
|
$format,
|
||||||
|
$context
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add additional workflows
|
||||||
$initial['workflows_availables'] = $this->metadataExtractor->availableWorkflowFor(
|
$initial['workflows_availables'] = $this->metadataExtractor->availableWorkflowFor(
|
||||||
AccompanyingPeriodWorkEvaluation::class,
|
AccompanyingPeriodWorkEvaluation::class
|
||||||
);
|
);
|
||||||
|
|
||||||
$workflows = $this->entityWorkflowRepository->findBy([
|
$workflows = $this->entityWorkflowRepository->findBy([
|
||||||
@@ -63,12 +64,11 @@ class AccompanyingPeriodWorkEvaluationNormalizer implements \Symfony\Component\S
|
|||||||
public function supportsNormalization($data, ?string $format = null, array $context = []): bool
|
public function supportsNormalization($data, ?string $format = null, array $context = []): bool
|
||||||
{
|
{
|
||||||
return 'json' === $format
|
return 'json' === $format
|
||||||
&& $data instanceof AccompanyingPeriodWorkEvaluation
|
&& ($data instanceof AccompanyingPeriodWorkEvaluation || ($data instanceof \Doctrine\Persistence\Proxy && $data->__isInitialized()));
|
||||||
&& !\array_key_exists(self::IGNORE_EVALUATION, $context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSupportedTypes(?string $format): array
|
public function getSupportedTypes(?string $format): array
|
||||||
{
|
{
|
||||||
return 'json' === $format ? [AccompanyingPeriodWorkEvaluation::class => true] : [];
|
return 'json' === $format ? [AccompanyingPeriodWorkEvaluation::class => null] : [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,6 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluatio
|
|||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||||
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||||
use Symfony\Component\Workflow\Registry;
|
use Symfony\Component\Workflow\Registry;
|
||||||
@@ -32,7 +31,11 @@ class AccompanyingPeriodWorkNormalizer implements \Symfony\Component\Serializer\
|
|||||||
|
|
||||||
private const IGNORE_WORK = 'ignore:work';
|
private const IGNORE_WORK = 'ignore:work';
|
||||||
|
|
||||||
public function __construct(private readonly Registry $registry, private readonly EntityWorkflowRepository $entityWorkflowRepository, private readonly MetadataExtractor $metadataExtractor) {}
|
public function __construct(
|
||||||
|
private readonly Registry $registry,
|
||||||
|
private readonly EntityWorkflowRepository $entityWorkflowRepository,
|
||||||
|
private readonly MetadataExtractor $metadataExtractor,
|
||||||
|
) {}
|
||||||
|
|
||||||
public function normalize($object, ?string $format = null, array $context = []): array|\ArrayObject|bool|float|int|string|null
|
public function normalize($object, ?string $format = null, array $context = []): array|\ArrayObject|bool|float|int|string|null
|
||||||
{
|
{
|
||||||
@@ -42,7 +45,9 @@ class AccompanyingPeriodWorkNormalizer implements \Symfony\Component\Serializer\
|
|||||||
if ('docgen' === $format && !($object instanceof AccompanyingPeriodWork || null === $object)) {
|
if ('docgen' === $format && !($object instanceof AccompanyingPeriodWork || null === $object)) {
|
||||||
throw new UnexpectedValueException(sprintf('Object must be an instanceof AccompanyingPeriodWork or null when format is docgen, %s given', get_debug_type($object)));
|
throw new UnexpectedValueException(sprintf('Object must be an instanceof AccompanyingPeriodWork or null when format is docgen, %s given', get_debug_type($object)));
|
||||||
}
|
}
|
||||||
$cleanContext = array_filter($context, fn (string|int $key) => !in_array($key, ['docgen:expects', self::IGNORE_WORK], true), ARRAY_FILTER_USE_KEY);
|
|
||||||
|
// Only remove docgen:expects, keep IGNORE_WORK in context
|
||||||
|
$cleanContext = array_filter($context, fn (string|int $key) => 'docgen:expects' !== $key, ARRAY_FILTER_USE_KEY);
|
||||||
|
|
||||||
if (null === $object && 'docgen' === $format) {
|
if (null === $object && 'docgen' === $format) {
|
||||||
$dateNull = $this->normalizer->normalize(null, $format, [...$context, 'docgen:expects' => \DateTimeImmutable::class]);
|
$dateNull = $this->normalizer->normalize(null, $format, [...$context, 'docgen:expects' => \DateTimeImmutable::class]);
|
||||||
@@ -72,10 +77,7 @@ class AccompanyingPeriodWorkNormalizer implements \Symfony\Component\Serializer\
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$initial = $this->normalizer->normalize($object, $format, array_merge(
|
$initial = $this->normalizer->normalize($object, $format, $cleanContext);
|
||||||
$cleanContext,
|
|
||||||
[self::IGNORE_WORK => null === $object ? null : spl_object_hash($object)]
|
|
||||||
));
|
|
||||||
|
|
||||||
// due to bug: https://api-platform.com/docs/core/serialization/#collection-relation
|
// due to bug: https://api-platform.com/docs/core/serialization/#collection-relation
|
||||||
// and also: https://github.com/symfony/symfony/issues/36965
|
// and also: https://github.com/symfony/symfony/issues/36965
|
||||||
@@ -83,7 +85,7 @@ class AccompanyingPeriodWorkNormalizer implements \Symfony\Component\Serializer\
|
|||||||
$initial['accompanyingPeriodWorkEvaluations'] = $this->normalizer->normalize(
|
$initial['accompanyingPeriodWorkEvaluations'] = $this->normalizer->normalize(
|
||||||
$object->getAccompanyingPeriodWorkEvaluations()->getValues(),
|
$object->getAccompanyingPeriodWorkEvaluations()->getValues(),
|
||||||
$format,
|
$format,
|
||||||
[...$cleanContext]
|
$cleanContext
|
||||||
);
|
);
|
||||||
|
|
||||||
// add the referrers
|
// add the referrers
|
||||||
@@ -119,7 +121,7 @@ class AccompanyingPeriodWorkNormalizer implements \Symfony\Component\Serializer\
|
|||||||
'relatedEntityClass' => AccompanyingPeriodWork::class,
|
'relatedEntityClass' => AccompanyingPeriodWork::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$initial['workflows'] = $this->normalizer->normalize($workflows, 'json', $context);
|
$initial['workflows'] = $this->normalizer->normalize($workflows, 'json', $contextWithIgnore);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $initial;
|
return $initial;
|
||||||
@@ -128,18 +130,15 @@ class AccompanyingPeriodWorkNormalizer implements \Symfony\Component\Serializer\
|
|||||||
public function supportsNormalization($data, ?string $format = null, array $context = []): bool
|
public function supportsNormalization($data, ?string $format = null, array $context = []): bool
|
||||||
{
|
{
|
||||||
return match ($format) {
|
return match ($format) {
|
||||||
'json' => $data instanceof AccompanyingPeriodWork && ($context[self::IGNORE_WORK] ?? null) !== spl_object_hash($data),
|
'json' => $data instanceof AccompanyingPeriodWork,
|
||||||
'docgen' => ($data instanceof AccompanyingPeriodWork || (null === $data && ($context['docgen:expects'] ?? null) === AccompanyingPeriodWork::class))
|
'docgen' => ($data instanceof AccompanyingPeriodWork
|
||||||
&& !array_key_exists(self::IGNORE_WORK, $context),
|
|| (null === $data && ($context['docgen:expects'] ?? null) === AccompanyingPeriodWork::class)),
|
||||||
default => false,
|
default => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSupportedTypes(?string $format): array
|
public function getSupportedTypes(?string $format): array
|
||||||
{
|
{
|
||||||
return match ($format) {
|
return 'json' === $format ? [AccompanyingPeriodWork::class => null] : [];
|
||||||
'json', 'docgen' => [AccompanyingPeriodWork::class => true],
|
|
||||||
default => [],
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -56,31 +56,19 @@ class SocialIssueNormalizer implements \Symfony\Component\Serializer\Normalizer\
|
|||||||
|
|
||||||
public function supportsNormalization($data, $format = null, array $context = []): bool
|
public function supportsNormalization($data, $format = null, array $context = []): bool
|
||||||
{
|
{
|
||||||
if ($data instanceof SocialIssue && 'json' === $format) {
|
return match ($format) {
|
||||||
return true;
|
'json' => $data instanceof SocialIssue,
|
||||||
}
|
'docgen' => $data instanceof SocialIssue ||
|
||||||
|
(null === $data && ($context['docgen:expects'] ?? null) === SocialIssue::class),
|
||||||
if ('docgen' === $format) {
|
default => false,
|
||||||
if ($data instanceof SocialIssue) {
|
};
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === $data && SocialIssue::class === ($context['docgen:expects'] ?? null)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSupportedTypes(?string $format): array
|
public function getSupportedTypes(?string $format): array
|
||||||
{
|
{
|
||||||
if ('json' === $format || 'docgen' === $format) {
|
return match ($format) {
|
||||||
return [
|
'json', 'docgen' => [SocialIssue::class => true],
|
||||||
SocialIssue::class => true,
|
default => [],
|
||||||
];
|
};
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user