From 4f306718b11ffb5e4ea18d3f89e216a1d9bf6701 Mon Sep 17 00:00:00 2001 From: MateuszKolankowski Date: Tue, 16 Dec 2025 10:27:15 +0100 Subject: [PATCH 1/3] Introduce SerializerFactory and improve serializer config Implemented `SerializerFactory` to streamline serializer creation logic. Updated services configuration to use tagged normalizers and encoders, improving modularity and maintainability. Added `SiteAccessMatcherDenormalizer` with corresponding service definitions. --- .../Resources/config/routing/serializers.yml | 89 ++++++++++++------- .../Core/Serializer/SerializerFactory.php | 50 +++++++++++ 2 files changed, 106 insertions(+), 33 deletions(-) create mode 100644 src/bundle/Core/Serializer/SerializerFactory.php diff --git a/src/bundle/Core/Resources/config/routing/serializers.yml b/src/bundle/Core/Resources/config/routing/serializers.yml index 62329fb916..998eca0e4c 100644 --- a/src/bundle/Core/Resources/config/routing/serializers.yml +++ b/src/bundle/Core/Resources/config/routing/serializers.yml @@ -1,59 +1,82 @@ services: - ibexa.core.mvc.serializer: - class: Symfony\Component\Serializer\Serializer - arguments: - $normalizers: - - '@ibexa.core.mvc.serializer.normalizer.array_denormalizer' - - '@Ibexa\Core\MVC\Symfony\Component\Serializer\SiteAccessNormalizer' - - '@Ibexa\Core\MVC\Symfony\Component\Serializer\MatcherDenormalizer' - - '@Ibexa\Core\MVC\Symfony\Component\Serializer\CompoundMatcherNormalizer' - - '@Ibexa\Core\MVC\Symfony\Component\Serializer\HostElementNormalizer' - - '@Ibexa\Core\MVC\Symfony\Component\Serializer\MapNormalizer' - - '@Ibexa\Core\MVC\Symfony\Component\Serializer\URITextNormalizer' - - '@Ibexa\Core\MVC\Symfony\Component\Serializer\HostTextNormalizer' - - '@Ibexa\Core\MVC\Symfony\Component\Serializer\RegexNormalizer' - - '@Ibexa\Core\MVC\Symfony\Component\Serializer\URIElementNormalizer' - - '@Ibexa\Core\MVC\Symfony\Component\Serializer\SimplifiedRequestNormalizer' - - '@ibexa.core.mvc.serializer.normalizer.json_serializable_normalizer' - - '@ibexa.core.mvc.serializer.normalizer.property_normalizer' - $encoders: - - '@ibexa.core.mvc.serializer.json_encoder' + Ibexa\Bundle\Core\Fragment\SiteAccessSerializerInterface: + alias: Ibexa\Bundle\Core\Fragment\SiteAccessSerializer + Ibexa\Bundle\Core\Fragment\SiteAccessSerializer: arguments: $serializer: '@ibexa.core.mvc.serializer' - Ibexa\Bundle\Core\Fragment\SiteAccessSerializerInterface: - alias: Ibexa\Bundle\Core\Fragment\SiteAccessSerializer + ibexa.core.mvc.serializer.normalizer.array_denormalizer: + class: Symfony\Component\Serializer\Normalizer\ArrayDenormalizer + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 1300 } - ibexa.core.mvc.serializer.json_encoder: - class: Symfony\Component\Serializer\Encoder\JsonEncoder + Ibexa\Core\MVC\Symfony\Component\Serializer\SiteAccessNormalizer: + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 1200 } Ibexa\Core\MVC\Symfony\Component\Serializer\MatcherDenormalizer: arguments: $registry: '@Ibexa\Bundle\Core\SiteAccess\SiteAccessMatcherRegistryInterface' + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 1100 } - Ibexa\Core\MVC\Symfony\Component\Serializer\SiteAccessNormalizer: ~ + Ibexa\Core\MVC\Symfony\Component\Serializer\CompoundMatcherNormalizer: + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 1000 } - Ibexa\Core\MVC\Symfony\Component\Serializer\HostElementNormalizer: ~ + Ibexa\Core\MVC\Symfony\Component\Serializer\HostElementNormalizer: + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 900 } - Ibexa\Core\MVC\Symfony\Component\Serializer\MapNormalizer: ~ + Ibexa\Core\MVC\Symfony\Component\Serializer\MapNormalizer: + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 800 } - Ibexa\Core\MVC\Symfony\Component\Serializer\URITextNormalizer: ~ + Ibexa\Core\MVC\Symfony\Component\Serializer\URITextNormalizer: + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 700 } - Ibexa\Core\MVC\Symfony\Component\Serializer\HostTextNormalizer: ~ + Ibexa\Core\MVC\Symfony\Component\Serializer\HostTextNormalizer: + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 600 } - Ibexa\Core\MVC\Symfony\Component\Serializer\RegexNormalizer: ~ + Ibexa\Core\MVC\Symfony\Component\Serializer\RegexNormalizer: + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 500 } - Ibexa\Core\MVC\Symfony\Component\Serializer\URIElementNormalizer: ~ + Ibexa\Core\MVC\Symfony\Component\Serializer\URIElementNormalizer: + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 400 } - Ibexa\Core\MVC\Symfony\Component\Serializer\SimplifiedRequestNormalizer: ~ + Ibexa\Core\MVC\Symfony\Component\Serializer\SimplifiedRequestNormalizer: + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 300 } ibexa.core.mvc.serializer.normalizer.json_serializable_normalizer: class: Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 200 } ibexa.core.mvc.serializer.normalizer.property_normalizer: class: Symfony\Component\Serializer\Normalizer\PropertyNormalizer + tags: + - { name: 'ibexa.core.serializer.normalizer', priority: 100 } - ibexa.core.mvc.serializer.normalizer.array_denormalizer: - class: Symfony\Component\Serializer\Normalizer\ArrayDenormalizer + ibexa.core.mvc.serializer.json_encoder: + class: Symfony\Component\Serializer\Encoder\JsonEncoder + tags: + - { name: 'ibexa.core.serializer.encoder', priority: 100 } + + Ibexa\Bundle\Core\Serializer\SerializerFactory: + class: Ibexa\Bundle\Core\Serializer\SerializerFactory + arguments: + - !tagged_iterator 'ibexa.core.serializer.normalizer' + - !tagged_iterator 'ibexa.core.serializer.encoder' + + ibexa.core.mvc.serializer: + # Warning: Do NOT enable autoconfigure for Serializer and Normalizer services. + # They will be tagged with "serializer.normalizer" tag and injected to main app serializer service if done so. + class: Symfony\Component\Serializer\Serializer + factory: [ '@Ibexa\Bundle\Core\Serializer\SerializerFactory', 'create' ] diff --git a/src/bundle/Core/Serializer/SerializerFactory.php b/src/bundle/Core/Serializer/SerializerFactory.php new file mode 100644 index 0000000000..b839685820 --- /dev/null +++ b/src/bundle/Core/Serializer/SerializerFactory.php @@ -0,0 +1,50 @@ + + */ + private iterable $normalizers; + + /** + * @var iterable<\Symfony\Component\Serializer\Encoder\EncoderInterface|\Symfony\Component\Serializer\Encoder\DecoderInterface> + */ + private iterable $encoders; + + /** + * @param iterable<\Symfony\Component\Serializer\Normalizer\NormalizerInterface|\Symfony\Component\Serializer\Normalizer\DenormalizerInterface> $normalizers + * @param iterable<\Symfony\Component\Serializer\Encoder\EncoderInterface|\Symfony\Component\Serializer\Encoder\DecoderInterface> $encoders + */ + public function __construct(iterable $normalizers, iterable $encoders) + { + $this->normalizers = $normalizers; + $this->encoders = $encoders; + } + + public function create(): Serializer + { + $normalizers = $this->normalizers; + if ($normalizers instanceof Traversable) { + $normalizers = iterator_to_array($normalizers); + } + + $encoders = $this->encoders; + if ($encoders instanceof Traversable) { + $encoders = iterator_to_array($encoders); + } + + return new Serializer($normalizers, $encoders); + } +} From ea49696da92590d3ad14b7cb87baac4c049032d4 Mon Sep 17 00:00:00 2001 From: MateuszKolankowski Date: Wed, 17 Dec 2025 09:28:01 +0100 Subject: [PATCH 2/3] Refactored SerializerFactory to use property promotion --- .../Core/Serializer/SerializerFactory.php | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/bundle/Core/Serializer/SerializerFactory.php b/src/bundle/Core/Serializer/SerializerFactory.php index b839685820..23f48afb4a 100644 --- a/src/bundle/Core/Serializer/SerializerFactory.php +++ b/src/bundle/Core/Serializer/SerializerFactory.php @@ -11,27 +11,16 @@ use Symfony\Component\Serializer\Serializer; use Traversable; -final class SerializerFactory +final readonly class SerializerFactory { - /** - * @var iterable<\Symfony\Component\Serializer\Normalizer\NormalizerInterface|\Symfony\Component\Serializer\Normalizer\DenormalizerInterface> - */ - private iterable $normalizers; - - /** - * @var iterable<\Symfony\Component\Serializer\Encoder\EncoderInterface|\Symfony\Component\Serializer\Encoder\DecoderInterface> - */ - private iterable $encoders; - /** * @param iterable<\Symfony\Component\Serializer\Normalizer\NormalizerInterface|\Symfony\Component\Serializer\Normalizer\DenormalizerInterface> $normalizers - * @param iterable<\Symfony\Component\Serializer\Encoder\EncoderInterface|\Symfony\Component\Serializer\Encoder\DecoderInterface> $encoders + * @param iterable<\Symfony\Component\Serializer\Encoder\EncoderInterface|\Symfony\Component\Serializer\Encoder\DecoderInterface> $encoders */ - public function __construct(iterable $normalizers, iterable $encoders) - { - $this->normalizers = $normalizers; - $this->encoders = $encoders; - } + public function __construct( + public iterable $normalizers, + public iterable $encoders + ) {} public function create(): Serializer { From 102f43b61dfd4024519f3f56a3d06c9d32dbb1eb Mon Sep 17 00:00:00 2001 From: MateuszKolankowski Date: Wed, 17 Dec 2025 14:09:02 +0100 Subject: [PATCH 3/3] Refactored `SerializerFactory` to simplify `create` method by removing redundant `Traversable` checks and improving property encapsulation. --- .../Core/Serializer/SerializerFactory.php | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/bundle/Core/Serializer/SerializerFactory.php b/src/bundle/Core/Serializer/SerializerFactory.php index 23f48afb4a..7ea1d689fa 100644 --- a/src/bundle/Core/Serializer/SerializerFactory.php +++ b/src/bundle/Core/Serializer/SerializerFactory.php @@ -9,7 +9,6 @@ namespace Ibexa\Bundle\Core\Serializer; use Symfony\Component\Serializer\Serializer; -use Traversable; final readonly class SerializerFactory { @@ -18,21 +17,15 @@ * @param iterable<\Symfony\Component\Serializer\Encoder\EncoderInterface|\Symfony\Component\Serializer\Encoder\DecoderInterface> $encoders */ public function __construct( - public iterable $normalizers, - public iterable $encoders - ) {} + private iterable $normalizers, + private iterable $encoders + ) { + } public function create(): Serializer { - $normalizers = $this->normalizers; - if ($normalizers instanceof Traversable) { - $normalizers = iterator_to_array($normalizers); - } - - $encoders = $this->encoders; - if ($encoders instanceof Traversable) { - $encoders = iterator_to_array($encoders); - } + $normalizers = iterator_to_array($this->normalizers); + $encoders = iterator_to_array($this->encoders); return new Serializer($normalizers, $encoders); }