123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- <?php
- /*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Symfony\Component\Serializer\NameConverter;
- use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
- use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
- /**
- * @author Fabien Bourigault <bourigaultfabien@gmail.com>
- */
- final class MetadataAwareNameConverter implements AdvancedNameConverterInterface
- {
- private $metadataFactory;
- /**
- * @var NameConverterInterface|AdvancedNameConverterInterface|null
- */
- private $fallbackNameConverter;
- private static $normalizeCache = [];
- private static $denormalizeCache = [];
- private static $attributesMetadataCache = [];
- public function __construct(ClassMetadataFactoryInterface $metadataFactory, NameConverterInterface $fallbackNameConverter = null)
- {
- $this->metadataFactory = $metadataFactory;
- $this->fallbackNameConverter = $fallbackNameConverter;
- }
- /**
- * {@inheritdoc}
- */
- public function normalize(string $propertyName, string $class = null, string $format = null, array $context = []): string
- {
- if (null === $class) {
- return $this->normalizeFallback($propertyName, $class, $format, $context);
- }
- if (!\array_key_exists($class, self::$normalizeCache) || !\array_key_exists($propertyName, self::$normalizeCache[$class])) {
- self::$normalizeCache[$class][$propertyName] = $this->getCacheValueForNormalization($propertyName, $class);
- }
- return self::$normalizeCache[$class][$propertyName] ?? $this->normalizeFallback($propertyName, $class, $format, $context);
- }
- /**
- * {@inheritdoc}
- */
- public function denormalize(string $propertyName, string $class = null, string $format = null, array $context = []): string
- {
- if (null === $class) {
- return $this->denormalizeFallback($propertyName, $class, $format, $context);
- }
- $cacheKey = $this->getCacheKey($class, $context);
- if (!\array_key_exists($cacheKey, self::$denormalizeCache) || !\array_key_exists($propertyName, self::$denormalizeCache[$cacheKey])) {
- self::$denormalizeCache[$cacheKey][$propertyName] = $this->getCacheValueForDenormalization($propertyName, $class, $context);
- }
- return self::$denormalizeCache[$cacheKey][$propertyName] ?? $this->denormalizeFallback($propertyName, $class, $format, $context);
- }
- private function getCacheValueForNormalization(string $propertyName, string $class): ?string
- {
- if (!$this->metadataFactory->hasMetadataFor($class)) {
- return null;
- }
- $attributesMetadata = $this->metadataFactory->getMetadataFor($class)->getAttributesMetadata();
- if (!\array_key_exists($propertyName, $attributesMetadata)) {
- return null;
- }
- return $attributesMetadata[$propertyName]->getSerializedName() ?? null;
- }
- private function normalizeFallback(string $propertyName, string $class = null, string $format = null, array $context = []): string
- {
- return $this->fallbackNameConverter ? $this->fallbackNameConverter->normalize($propertyName, $class, $format, $context) : $propertyName;
- }
- private function getCacheValueForDenormalization(string $propertyName, string $class, array $context): ?string
- {
- $cacheKey = $this->getCacheKey($class, $context);
- if (!\array_key_exists($cacheKey, self::$attributesMetadataCache)) {
- self::$attributesMetadataCache[$cacheKey] = $this->getCacheValueForAttributesMetadata($class, $context);
- }
- return self::$attributesMetadataCache[$cacheKey][$propertyName] ?? null;
- }
- private function denormalizeFallback(string $propertyName, string $class = null, string $format = null, array $context = []): string
- {
- return $this->fallbackNameConverter ? $this->fallbackNameConverter->denormalize($propertyName, $class, $format, $context) : $propertyName;
- }
- private function getCacheValueForAttributesMetadata(string $class, array $context): array
- {
- if (!$this->metadataFactory->hasMetadataFor($class)) {
- return [];
- }
- $classMetadata = $this->metadataFactory->getMetadataFor($class);
- $cache = [];
- foreach ($classMetadata->getAttributesMetadata() as $name => $metadata) {
- if (null === $metadata->getSerializedName()) {
- continue;
- }
- $groups = $metadata->getGroups();
- if (!$groups && ($context[AbstractNormalizer::GROUPS] ?? [])) {
- continue;
- }
- if ($groups && !array_intersect($groups, (array) ($context[AbstractNormalizer::GROUPS] ?? []))) {
- continue;
- }
- $cache[$metadata->getSerializedName()] = $name;
- }
- return $cache;
- }
- private function getCacheKey(string $class, array $context): string
- {
- if (isset($context['cache_key'])) {
- return $class.'-'.$context['cache_key'];
- }
- return $class.md5(serialize($context[AbstractNormalizer::GROUPS] ?? []));
- }
- }
|