vendor/api-platform/core/src/Core/Api/IdentifiersExtractor.php line 49
<?php/** This file is part of the API Platform project.** (c) Kévin Dunglas <dunglas@gmail.com>** For the full copyright and license information, please view the LICENSE* file that was distributed with this source code.*/declare(strict_types=1);namespace ApiPlatform\Core\Api;use ApiPlatform\Api\IdentifiersExtractor as NewIdentifiersExtractor;use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;use ApiPlatform\Exception\RuntimeException;use ApiPlatform\Util\ResourceClassInfoTrait;use Symfony\Component\PropertyAccess\PropertyAccess;use Symfony\Component\PropertyAccess\PropertyAccessorInterface;/*** {@inheritdoc}** @author Antoine Bluchet <soyuka@gmail.com>*/final class IdentifiersExtractor implements IdentifiersExtractorInterface{use ResourceClassInfoTrait;private $propertyNameCollectionFactory;private $propertyMetadataFactory;private $propertyAccessor;public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, PropertyAccessorInterface $propertyAccessor = null, ResourceClassResolverInterface $resourceClassResolver = null, bool $metadataBackwardCompatibilityLayer = null){$this->propertyNameCollectionFactory = $propertyNameCollectionFactory;$this->propertyMetadataFactory = $propertyMetadataFactory;$this->propertyAccessor = $propertyAccessor ?? PropertyAccess::createPropertyAccessor();$this->resourceClassResolver = $resourceClassResolver;if (null === $this->resourceClassResolver) {@trigger_error(sprintf('Not injecting %s in the IdentifiersExtractor might introduce cache issues with object identifiers.', ResourceClassResolverInterface::class), \E_USER_DEPRECATED);}if ($metadataBackwardCompatibilityLayer) {trigger_deprecation('api-platform/core', '2.7', sprintf('The service "%s" is deprecated, use %s instead.', self::class, NewIdentifiersExtractor::class));}}/*** {@inheritdoc}*/public function getIdentifiersFromResourceClass(string $resourceClass): array{$identifiers = [];foreach ($properties = $this->propertyNameCollectionFactory->create($resourceClass) as $property) {if ($this->propertyMetadataFactory->create($resourceClass, $property)->isIdentifier() ?? false) {$identifiers[] = $property;}}if (!$identifiers) {if (\in_array('id', iterator_to_array($properties), true)) {return ['id'];}throw new RuntimeException(sprintf('No identifier defined in "%s". You should add #[\ApiPlatform\Core\Annotation\ApiProperty(identifier: true)]" on the property identifying the resource."', $resourceClass));}return $identifiers;}/*** {@inheritdoc}*/public function getIdentifiersFromItem($item): array{$identifiers = [];$resourceClass = $this->getResourceClass($item, true);$identifierProperties = $this->getIdentifiersFromResourceClass($resourceClass);foreach ($this->propertyNameCollectionFactory->create($resourceClass) as $propertyName) {if (!\in_array($propertyName, $identifierProperties, true)) {continue;}$propertyMetadata = $this->propertyMetadataFactory->create($resourceClass, $propertyName);$identifier = $identifiers[$propertyName] = $this->propertyAccessor->getValue($item, $propertyName);if (!\is_object($identifier)) {continue;}if (null === $relatedResourceClass = $this->getResourceClass($identifier)) {continue;}$relatedItem = $identifier;unset($identifiers[$propertyName]);foreach ($this->propertyNameCollectionFactory->create($relatedResourceClass) as $relatedPropertyName) {$propertyMetadata = $this->propertyMetadataFactory->create($relatedResourceClass, $relatedPropertyName);if ($propertyMetadata->isIdentifier()) {if (isset($identifiers[$propertyName])) {throw new RuntimeException(sprintf('Composite identifiers not supported in "%s" through relation "%s" of "%s" used as identifier', $relatedResourceClass, $propertyName, $resourceClass));}$identifiers[$propertyName] = $this->propertyAccessor->getValue($relatedItem, $relatedPropertyName);}}if (!isset($identifiers[$propertyName])) {throw new RuntimeException(sprintf('No identifier found in "%s" through relation "%s" of "%s" used as identifier', $relatedResourceClass, $propertyName, $resourceClass));}}return $identifiers;}}