|
13 | 13 |
|
14 | 14 | namespace ApiPlatform\Api;
|
15 | 15 |
|
16 |
| -use ApiPlatform\Exception\RuntimeException; |
17 |
| -use ApiPlatform\Metadata\GraphQl\Operation as GraphQlOperation; |
18 |
| -use ApiPlatform\Metadata\HttpOperation; |
19 |
| -use ApiPlatform\Metadata\Operation; |
20 |
| -use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface; |
21 |
| -use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; |
22 |
| -use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; |
23 |
| -use ApiPlatform\Metadata\Util\ResourceClassInfoTrait; |
24 |
| -use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; |
25 |
| -use Symfony\Component\PropertyAccess\PropertyAccess; |
26 |
| -use Symfony\Component\PropertyAccess\PropertyAccessorInterface; |
| 16 | +class_exists(\ApiPlatform\Metadata\IdentifiersExtractor::class); |
27 | 17 |
|
28 |
| -/** |
29 |
| - * {@inheritdoc} |
30 |
| - * |
31 |
| - * @author Antoine Bluchet <[email protected]> |
32 |
| - */ |
33 |
| -final class IdentifiersExtractor implements IdentifiersExtractorInterface |
34 |
| -{ |
35 |
| - use ResourceClassInfoTrait; |
36 |
| - private readonly PropertyAccessorInterface $propertyAccessor; |
37 |
| - |
38 |
| - public function __construct(ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory, ResourceClassResolverInterface $resourceClassResolver, private readonly PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, private readonly PropertyMetadataFactoryInterface $propertyMetadataFactory, PropertyAccessorInterface $propertyAccessor = null) |
| 18 | +if (false) { |
| 19 | + final class IdentifiersExtractor extends \ApiPlatform\Metadata\IdentifiersExtractor |
39 | 20 | {
|
40 |
| - $this->resourceMetadataFactory = $resourceMetadataFactory; |
41 |
| - $this->resourceClassResolver = $resourceClassResolver; |
42 |
| - $this->propertyAccessor = $propertyAccessor ?? PropertyAccess::createPropertyAccessor(); |
43 |
| - } |
44 |
| - |
45 |
| - /** |
46 |
| - * {@inheritdoc} |
47 |
| - * |
48 |
| - * TODO: 3.0 identifiers should be stringable? |
49 |
| - */ |
50 |
| - public function getIdentifiersFromItem(object $item, Operation $operation = null, array $context = []): array |
51 |
| - { |
52 |
| - if (!$this->isResourceClass($this->getObjectClass($item))) { |
53 |
| - return ['id' => $this->propertyAccessor->getValue($item, 'id')]; |
54 |
| - } |
55 |
| - |
56 |
| - if ($operation && $operation->getClass()) { |
57 |
| - return $this->getIdentifiersFromOperation($item, $operation, $context); |
58 |
| - } |
59 |
| - |
60 |
| - $resourceClass = $this->getResourceClass($item, true); |
61 |
| - $operation ??= $this->resourceMetadataFactory->create($resourceClass)->getOperation(null, false, true); |
62 |
| - |
63 |
| - return $this->getIdentifiersFromOperation($item, $operation, $context); |
64 |
| - } |
65 |
| - |
66 |
| - private function getIdentifiersFromOperation(object $item, Operation $operation, array $context = []): array |
67 |
| - { |
68 |
| - if ($operation instanceof HttpOperation) { |
69 |
| - $links = $operation->getUriVariables(); |
70 |
| - } elseif ($operation instanceof GraphQlOperation) { |
71 |
| - $links = $operation->getLinks(); |
72 |
| - } |
73 |
| - |
74 |
| - $identifiers = []; |
75 |
| - foreach ($links ?? [] as $link) { |
76 |
| - if (1 < (is_countable($link->getIdentifiers()) ? \count($link->getIdentifiers()) : 0)) { |
77 |
| - $compositeIdentifiers = []; |
78 |
| - foreach ($link->getIdentifiers() as $identifier) { |
79 |
| - $compositeIdentifiers[$identifier] = $this->getIdentifierValue($item, $link->getFromClass() ?? $operation->getClass(), $identifier, $link->getParameterName()); |
80 |
| - } |
81 |
| - |
82 |
| - $identifiers[$link->getParameterName()] = CompositeIdentifierParser::stringify($compositeIdentifiers); |
83 |
| - continue; |
84 |
| - } |
85 |
| - |
86 |
| - $parameterName = $link->getParameterName(); |
87 |
| - $identifiers[$parameterName] = $this->getIdentifierValue($item, $link->getFromClass() ?? $operation->getClass(), $link->getIdentifiers()[0], $parameterName, $link->getToProperty()); |
88 |
| - } |
89 |
| - |
90 |
| - return $identifiers; |
91 |
| - } |
92 |
| - |
93 |
| - /** |
94 |
| - * Gets the value of the given class property. |
95 |
| - */ |
96 |
| - private function getIdentifierValue(object $item, string $class, string $property, string $parameterName, string $toProperty = null): float|bool|int|string |
97 |
| - { |
98 |
| - if ($item instanceof $class) { |
99 |
| - try { |
100 |
| - return $this->resolveIdentifierValue($this->propertyAccessor->getValue($item, $property), $parameterName); |
101 |
| - } catch (NoSuchPropertyException $e) { |
102 |
| - throw new RuntimeException('Not able to retrieve identifiers.', $e->getCode(), $e); |
103 |
| - } |
104 |
| - } |
105 |
| - |
106 |
| - if ($toProperty) { |
107 |
| - return $this->resolveIdentifierValue($this->propertyAccessor->getValue($item, "$toProperty.$property"), $parameterName); |
108 |
| - } |
109 |
| - |
110 |
| - $resourceClass = $this->getResourceClass($item, true); |
111 |
| - foreach ($this->propertyNameCollectionFactory->create($resourceClass) as $propertyName) { |
112 |
| - $propertyMetadata = $this->propertyMetadataFactory->create($resourceClass, $propertyName); |
113 |
| - |
114 |
| - $types = $propertyMetadata->getBuiltinTypes(); |
115 |
| - if (null === ($type = $types[0] ?? null)) { |
116 |
| - continue; |
117 |
| - } |
118 |
| - |
119 |
| - try { |
120 |
| - if ($type->isCollection()) { |
121 |
| - $collectionValueType = $type->getCollectionValueTypes()[0] ?? null; |
122 |
| - |
123 |
| - if (null !== $collectionValueType && $collectionValueType->getClassName() === $class) { |
124 |
| - return $this->resolveIdentifierValue($this->propertyAccessor->getValue($item, sprintf('%s[0].%s', $propertyName, $property)), $parameterName); |
125 |
| - } |
126 |
| - } |
127 |
| - |
128 |
| - if ($type->getClassName() === $class) { |
129 |
| - return $this->resolveIdentifierValue($this->propertyAccessor->getValue($item, "$propertyName.$property"), $parameterName); |
130 |
| - } |
131 |
| - } catch (NoSuchPropertyException $e) { |
132 |
| - throw new RuntimeException('Not able to retrieve identifiers.', $e->getCode(), $e); |
133 |
| - } |
134 |
| - } |
135 |
| - |
136 |
| - throw new RuntimeException('Not able to retrieve identifiers.'); |
137 |
| - } |
138 |
| - |
139 |
| - /** |
140 |
| - * TODO: in 3.0 this method just uses $identifierValue instanceof \Stringable and we remove the weird behavior. |
141 |
| - * |
142 |
| - * @param mixed|\Stringable $identifierValue |
143 |
| - */ |
144 |
| - private function resolveIdentifierValue(mixed $identifierValue, string $parameterName): float|bool|int|string |
145 |
| - { |
146 |
| - if (null === $identifierValue) { |
147 |
| - throw new RuntimeException('No identifier value found, did you forget to persist the entity?'); |
148 |
| - } |
149 |
| - |
150 |
| - if (\is_scalar($identifierValue)) { |
151 |
| - return $identifierValue; |
152 |
| - } |
153 |
| - |
154 |
| - if ($identifierValue instanceof \Stringable) { |
155 |
| - return (string) $identifierValue; |
156 |
| - } |
157 |
| - |
158 |
| - if ($identifierValue instanceof \BackedEnum) { |
159 |
| - return (string) $identifierValue->value; |
160 |
| - } |
161 |
| - |
162 |
| - throw new RuntimeException(sprintf('We were not able to resolve the identifier matching parameter "%s".', $parameterName)); |
163 | 21 | }
|
164 | 22 | }
|
0 commit comments