Skip to content

Commit bf513d5

Browse files
committed
wip
1 parent e8e3f29 commit bf513d5

File tree

5 files changed

+97
-7
lines changed

5 files changed

+97
-7
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Core\Metadata\Property\Factory;
15+
16+
use ApiPlatform\Core\Metadata\Property\PropertyMetadata;
17+
use ApiPlatform\Exception\PropertyNotFoundException;
18+
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
19+
20+
/**
21+
* PropertyInfo metadata loader decorator.
22+
*
23+
* @author Kévin Dunglas <[email protected]>
24+
*/
25+
final class PropertyInfoPropertyMetadataFactory implements PropertyMetadataFactoryInterface
26+
{
27+
private $propertyInfo;
28+
private $decorated;
29+
30+
public function __construct(PropertyInfoExtractorInterface $propertyInfo, PropertyMetadataFactoryInterface $decorated = null)
31+
{
32+
$this->propertyInfo = $propertyInfo;
33+
$this->decorated = $decorated;
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
public function create(string $resourceClass, string $property, array $options = []): PropertyMetadata
40+
{
41+
if (null === $this->decorated) {
42+
$propertyMetadata = new PropertyMetadata();
43+
} else {
44+
try {
45+
$propertyMetadata = $this->decorated->create($resourceClass, $property, $options);
46+
} catch (PropertyNotFoundException $propertyNotFoundException) {
47+
$propertyMetadata = new PropertyMetadata();
48+
}
49+
}
50+
51+
if ($propertyMetadata instanceof PropertyMetadata) {
52+
if (!$propertyMetadata->getBuiltinTypes()) {
53+
$propertyMetadata = $propertyMetadata->withBuiltinTypes($this->propertyInfo->getTypes($resourceClass, $property, $options) ?? []);
54+
}
55+
} elseif (null === $propertyMetadata->getType()) {
56+
$propertyMetadata = $propertyMetadata->withType($this->propertyInfo->getTypes($resourceClass, $property, $options)[0] ?? null);
57+
}
58+
59+
if (null === $propertyMetadata->getDescription() && null !== $description = $this->propertyInfo->getShortDescription($resourceClass, $property, $options)) {
60+
$propertyMetadata = $propertyMetadata->withDescription($description);
61+
}
62+
63+
if (null === $propertyMetadata->isReadable() && null !== $readable = $this->propertyInfo->isReadable($resourceClass, $property, $options)) {
64+
$propertyMetadata = $propertyMetadata->withReadable($readable);
65+
}
66+
67+
if (null === $propertyMetadata->isWritable() && null !== $writable = $this->propertyInfo->isWritable($resourceClass, $property, $options)) {
68+
$propertyMetadata = $propertyMetadata->withWritable($writable);
69+
}
70+
71+
if (method_exists($this->propertyInfo, 'isInitializable')) {
72+
if (null === $propertyMetadata->isInitializable() && null !== $initializable = $this->propertyInfo->isInitializable($resourceClass, $property, $options)) {
73+
$propertyMetadata = $propertyMetadata->withInitializable($initializable);
74+
}
75+
} else {
76+
// BC layer for Symfony < 4.2
77+
$ref = new \ReflectionClass($resourceClass);
78+
if ($ref->isInstantiable() && $constructor = $ref->getConstructor()) {
79+
foreach ($constructor->getParameters() as $constructorParameter) {
80+
if ($constructorParameter->name === $property && null === $propertyMetadata->isInitializable()) {
81+
$propertyMetadata = $propertyMetadata->withInitializable(true);
82+
}
83+
}
84+
}
85+
}
86+
87+
return $propertyMetadata;
88+
}
89+
}

src/Metadata/Property/Factory/PropertyInfoPropertyMetadataFactory.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111

1212
declare(strict_types=1);
1313

14-
namespace ApiPlatform\Metadata\Property;
14+
namespace ApiPlatform\Metadata\Property\Factory;
1515

16-
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
1716
use ApiPlatform\Core\Metadata\Property\PropertyMetadata;
1817
use ApiPlatform\Exception\PropertyNotFoundException;
1918
use ApiPlatform\Metadata\ApiProperty;

src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,13 +870,15 @@ private function registerLegacyServices(ContainerBuilder $container, array $conf
870870
'api_platform.metadata.property.metadata_factory.xml' => 'ApiPlatform\Core\Metadata\Property\Factory\ExtractorPropertyMetadataFactory',
871871
'api_platform.metadata.property.metadata_factory.yaml' => 'ApiPlatform\Core\Metadata\Property\Factory\ExtractorPropertyMetadataFactory',
872872
'api_platform.metadata.property.metadata_factory.property_info' => 'ApiPlatform\Core\Bridge\Symfony\PropertyInfo\Metadata\Property\PropertyInfoPropertyMetadataFactory',
873-
'api_platform.doctrine.orm.metadata.property.metadata_factory' => 'ApiPlatform\Core\Bridge\Doctrine\Orm\Metadata\Property\DoctrineOrmPropertyMetadataFactory'
873+
'api_platform.doctrine.orm.metadata.property.metadata_factory' => 'ApiPlatform\Core\Bridge\Doctrine\Orm\Metadata\Property\DoctrineOrmPropertyMetadataFactory',
874874
];
875875

876876
foreach ($remapDefinitionClasses as $id => $class) {
877877
$container->getDefinition($id)->setClass($class)->setDecoratedService('api_platform.metadata.property.metadata_factory.legacy');
878878
}
879879

880+
$container->getDefinition('api_platform.metadata.property.metadata_factory.annotation')->setDecoratedService('api_platform.metadata.property.metadata_factory.legacy');
881+
880882
$container->removeAlias('api_platform.property.metadata_factory');
881883
$container->setAlias('api_platform.metadata.property.metadata_factory', 'api_platform.metadata.property.metadata_factory.legacy');
882884
}

src/Symfony/Bundle/Resources/config/metadata/resource_collection.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
<!-- Property metadata used to compute identifiers -->
9595
<service id="api_platform.metadata.property.identifier_metadata_factory" alias="api_platform.metadata.property.identifier_metadata_factory.property_info" />
9696

97-
<service id="api_platform.metadata.property.identifier_metadata_factory.property_info" class="ApiPlatform\Metadata\Property\PropertyInfoPropertyMetadataFactory" public="false">
97+
<service id="api_platform.metadata.property.identifier_metadata_factory.property_info" class="ApiPlatform\Metadata\Property\Factory\PropertyInfoPropertyMetadataFactory" public="false">
9898
<argument type="service" id="api_platform.property_info" />
9999
</service>
100100

src/deprecation.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,9 @@
247247
ApiPlatform\Core\Bridge\Symfony\Messenger\DataTransformer::class => ApiPlatform\Symfony\Messenger\DataTransformer::class,
248248
ApiPlatform\Core\Bridge\Symfony\Messenger\RemoveStamp::class => ApiPlatform\Symfony\Messenger\RemoveStamp::class,
249249

250-
// Bridge\Symfony\PropertyInfo\Metadata\Property => Metadata\Property
251-
ApiPlatform\Core\Bridge\Symfony\PropertyInfo\Metadata\Property\PropertyInfoPropertyMetadataFactory::class => ApiPlatform\Metadata\Property\PropertyInfoPropertyMetadataFactory::class,
252-
ApiPlatform\Core\Bridge\Symfony\PropertyInfo\Metadata\Property\PropertyInfoPropertyNameCollectionFactory::class => ApiPlatform\Metadata\Property\PropertyInfoPropertyNameCollectionFactory::class,
250+
// Bridge\Symfony\PropertyInfo\Metadata\Property => Metadata\Property\Factory
251+
ApiPlatform\Core\Bridge\Symfony\PropertyInfo\Metadata\Property\PropertyInfoPropertyMetadataFactory::class => ApiPlatform\Metadata\Property\Factory\PropertyInfoPropertyMetadataFactory::class,
252+
ApiPlatform\Core\Bridge\Symfony\PropertyInfo\Metadata\Property\PropertyInfoPropertyNameCollectionFactory::class => ApiPlatform\Metadata\Property\Factory\PropertyInfoPropertyNameCollectionFactory::class,
253253

254254
// Bridge\Symfony\Routing
255255
ApiPlatform\Core\Bridge\Symfony\Routing\ApiLoader::class => ApiPlatform\Symfony\Routing\ApiLoader::class,

0 commit comments

Comments
 (0)