vendor/api-platform/core/src/Core/Identifier/IdentifierConverter.php line 63

  1. <?php
  2. /*
  3.  * This file is part of the API Platform project.
  4.  *
  5.  * (c) Kévin Dunglas <dunglas@gmail.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. declare(strict_types=1);
  11. namespace ApiPlatform\Core\Identifier;
  12. use ApiPlatform\Core\Api\IdentifiersExtractorInterface;
  13. use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
  14. use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
  15. use ApiPlatform\Exception\InvalidIdentifierException;
  16. use Symfony\Component\PropertyInfo\Type;
  17. use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
  18. /**
  19.  * Identifier converter that chains identifier denormalizers.
  20.  *
  21.  * @author Antoine Bluchet <soyuka@gmail.com>
  22.  */
  23. final class IdentifierConverter implements ContextAwareIdentifierConverterInterface
  24. {
  25.     private $propertyMetadataFactory;
  26.     private $identifiersExtractor;
  27.     private $identifierDenormalizers;
  28.     private $resourceMetadataFactory;
  29.     /**
  30.      * TODO: rename identifierDenormalizers to identifierTransformers in 3.0 and change their interfaces to a IdentifierTransformerInterface.
  31.      *
  32.      * @param iterable<DenormalizerInterface> $identifierDenormalizers
  33.      */
  34.     public function __construct(IdentifiersExtractorInterface $identifiersExtractorPropertyMetadataFactoryInterface $propertyMetadataFactoryiterable $identifierDenormalizersResourceMetadataFactoryInterface $resourceMetadataFactory null)
  35.     {
  36.         $this->propertyMetadataFactory $propertyMetadataFactory;
  37.         $this->identifiersExtractor $identifiersExtractor;
  38.         $this->identifierDenormalizers $identifierDenormalizers;
  39.         $this->resourceMetadataFactory $resourceMetadataFactory;
  40.     }
  41.     public function convert($datastring $class, array $context = []): array
  42.     {
  43.         if (!\is_array($data)) {
  44.             @trigger_error(sprintf('Not using an array as the first argument of "%s->convert" is deprecated since API Platform 2.6 and will not be possible anymore in API Platform 3'self::class), \E_USER_DEPRECATED);
  45.             $data = ['id' => $data];
  46.         }
  47.         $identifiers $data;
  48.         foreach ($data as $parameter => $value) {
  49.             if (null === $type $this->getIdentifierType($context['identifiers'][$parameter][0] ?? $class$context['identifiers'][$parameter][1] ?? $parameter)) {
  50.                 continue;
  51.             }
  52.             /* @var DenormalizerInterface[] */
  53.             foreach ($this->identifierDenormalizers as $identifierTransformer) {
  54.                 if (!$identifierTransformer->supportsDenormalization($value$type)) {
  55.                     continue;
  56.                 }
  57.                 try {
  58.                     $identifiers[$parameter] = $identifierTransformer->denormalize($value$type);
  59.                     break;
  60.                 } catch (InvalidIdentifierException $e) { // @phpstan-ignore-line wrong choice of interface, was fixed in 3.0
  61.                     throw new InvalidIdentifierException(sprintf('Identifier "%s" could not be denormalized.'$parameter), $e->getCode(), $e);
  62.                 }
  63.             }
  64.         }
  65.         return $identifiers;
  66.     }
  67.     private function getIdentifierType(string $resourceClassstring $property): ?string
  68.     {
  69.         if (!$type $this->propertyMetadataFactory->create($resourceClass$property)->getType()) {
  70.             return null;
  71.         }
  72.         return Type::BUILTIN_TYPE_OBJECT === ($builtinType $type->getBuiltinType()) ? $type->getClassName() : $builtinType;
  73.     }
  74. }