Skip to content

Commit 510801f

Browse files
committed
Refactor YAML loaders
1 parent f62ab14 commit 510801f

26 files changed

+273
-364
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ high performance API-first projects. Extend or override everything you want.
1414
[![Build Status](https://travis-ci.org/api-platform/core.svg?branch=master)](https://travis-ci.org/api-platform/core)
1515
[![Build status](https://ci.appveyor.com/api/projects/status/grwuyprts3wdqx5l?svg=true)](https://ci.appveyor.com/project/dunglas/dunglasapibundle)
1616
[![Coverage Status](https://coveralls.io/repos/github/api-platform/core/badge.svg)](https://coveralls.io/github/api-platform/core)
17-
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/a93f5a40-483f-4c46-ba09-3e1033b62552/mini.png)](https://insight.sensiolabs.com/projects/a93f5a40-483f-4c46-ba09-3e1033b62552)
17+
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/92d78899-946c-4282-89a3-ac92344f9a93/mini.png)](https://insight.sensiolabs.com/projects/92d78899-946c-4282-89a3-ac92344f9a93)
1818
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/api-platform/core/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/api-platform/core/?branch=master)
1919
[![Dependency Status](https://www.versioneye.com/user/projects/5552e93306c318a32a0000fa/badge.svg?style=flat)](https://www.versioneye.com/user/projects/5552e93306c318a32a0000fa)
2020

features/configurable.feature

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ Feature: Configurable resource CRUD
1919
{
2020
"@id": "/fileconfigdummies/1",
2121
"@type": "fileconfigdummy",
22-
"foo": "Foo",
2322
"id": 1,
24-
"name": "ConfigDummy"
23+
"name": "ConfigDummy",
24+
"foo": "Foo"
2525
}
2626
],
2727
"hydra:totalItems": 1
@@ -53,11 +53,11 @@ Feature: Configurable resource CRUD
5353
And the JSON should be equal to:
5454
"""
5555
{
56-
"@context": "\/contexts\/fileconfigdummy",
57-
"@id": "\/fileconfigdummies\/1",
58-
"@type": "fileconfigdummy",
59-
"foo": "Foo",
60-
"id": 1,
61-
"name": "ConfigDummy"
62-
}
56+
"@context": "/contexts/fileconfigdummy",
57+
"@id": "/fileconfigdummies/1",
58+
"@type": "fileconfigdummy",
59+
"id": 1,
60+
"name": "ConfigDummy",
61+
"foo": "Foo"
62+
}
6363
"""

src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,7 @@ private function registerLoaders(ContainerBuilder $container, array $bundles)
256256

257257
$container->getDefinition('api_platform.metadata.resource.name_collection_factory.annotation')->addArgument($annotationPaths);
258258

259-
$container->getDefinition('api_platform.metadata.resource.name_collection_factory.yaml')->replaceArgument(0, $yamlResources);
260-
$container->getDefinition('api_platform.metadata.resource.metadata_factory.yaml')->replaceArgument(0, $yamlResources);
261-
262-
$container->getDefinition('api_platform.metadata.property.name_collection_factory.yaml')->replaceArgument(0, $yamlResources);
263-
$container->getDefinition('api_platform.metadata.property.metadata_factory.yaml')->replaceArgument(0, $yamlResources);
259+
$container->getDefinition('api_platform.metadata.extractor.yaml')->replaceArgument(0, $yamlResources);
264260

265261
$container->getDefinition('api_platform.metadata.resource.name_collection_factory.xml')->replaceArgument(0, $xmlResources);
266262
$container->getDefinition('api_platform.metadata.resource.metadata_factory.xml')->replaceArgument(0, $xmlResources);

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
66

77
<services>
8+
<!-- Extractor -->
9+
<service id="api_platform.metadata.extractor.yaml" class="ApiPlatform\Core\Metadata\YamlExtractor" public="false">
10+
<argument type="collection" />
11+
</service>
12+
813
<!-- Resource name collection -->
914

1015
<service id="api_platform.metadata.resource.name_collection_factory" alias="api_platform.metadata.resource.name_collection_factory.annotation" />
@@ -19,13 +24,13 @@
1924
</service>
2025

2126
<service id="api_platform.metadata.resource.name_collection_factory.yaml" decorates="api_platform.metadata.resource.name_collection_factory" class="ApiPlatform\Core\Metadata\Resource\Factory\YamlResourceNameCollectionFactory" public="false">
22-
<argument type="collection" />
23-
<argument type="service" id="api_platform.metadata.resource.name_collection_factory.yaml.inner" />
27+
<argument type="service" id="api_platform.metadata.extractor.yaml" />
28+
<argument type="service" id="api_platform.metadata.resource.name_collection_factory.yaml.inner" />
2429
</service>
2530

2631
<service id="api_platform.metadata.resource.name_collection_factory.xml" decorates="api_platform.metadata.resource.name_collection_factory" class="ApiPlatform\Core\Metadata\Resource\Factory\XmlResourceNameCollectionFactory" public="false">
27-
<argument type="collection" />
28-
<argument type="service" id="api_platform.metadata.resource.name_collection_factory.xml.inner" />
32+
<argument type="collection" />
33+
<argument type="service" id="api_platform.metadata.resource.name_collection_factory.xml.inner" />
2934
</service>
3035

3136
<!-- Resource metadata -->
@@ -41,7 +46,7 @@
4146
</service>
4247

4348
<service id="api_platform.metadata.resource.metadata_factory.yaml" decorates="api_platform.metadata.resource.metadata_factory" class="ApiPlatform\Core\Metadata\Resource\Factory\YamlResourceMetadataFactory" decoration-priority="40" public="false">
44-
<argument type="collection" />
49+
<argument type="service" id="api_platform.metadata.extractor.yaml" />
4550
<argument type="service" id="api_platform.metadata.resource.metadata_factory.yaml.inner" />
4651
</service>
4752

@@ -90,7 +95,7 @@
9095
</service>
9196

9297
<service id="api_platform.metadata.property.name_collection_factory.yaml" class="ApiPlatform\Core\Metadata\Property\Factory\YamlPropertyNameCollectionFactory" decorates="api_platform.metadata.property.name_collection_factory" public="false">
93-
<argument type="collection" />
98+
<argument type="service" id="api_platform.metadata.extractor.yaml" />
9499
<argument type="service" id="api_platform.metadata.property.name_collection_factory.yaml.inner" />
95100
</service>
96101

@@ -119,7 +124,7 @@
119124
</service>
120125

121126
<service id="api_platform.metadata.property.metadata_factory.yaml" class="ApiPlatform\Core\Metadata\Property\Factory\YamlPropertyMetadataFactory" decorates="api_platform.metadata.property.metadata_factory" decoration-priority="40" public="false">
122-
<argument type="collection" />
127+
<argument type="service" id="api_platform.metadata.extractor.yaml" />
123128
<argument type="service" id="api_platform.metadata.property.metadata_factory.yaml.inner" />
124129
</service>
125130

src/Metadata/Property/Factory/AbstractFilePropertyMetadataFactory.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,10 @@
2424
*/
2525
abstract class AbstractFilePropertyMetadataFactory implements PropertyMetadataFactoryInterface
2626
{
27-
protected $paths;
2827
protected $decorated;
2928

30-
/**
31-
* @param string[] $paths
32-
* @param PropertyMetadataFactoryInterface|null $decorated
33-
*/
34-
public function __construct(array $paths, PropertyMetadataFactoryInterface $decorated = null)
29+
public function __construct(PropertyMetadataFactoryInterface $decorated = null)
3530
{
36-
$this->paths = $paths;
3731
$this->decorated = $decorated;
3832
}
3933

@@ -78,7 +72,7 @@ public function create(string $resourceClass, string $property, array $options =
7872
}
7973

8074
/**
81-
* Extracts metadata from the XML tree.
75+
* Extracts metadata.
8276
*
8377
* @param string $resourceClass
8478
* @param string $propertyName

src/Metadata/Property/Factory/XmlPropertyMetadataFactory.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ final class XmlPropertyMetadataFactory extends AbstractFilePropertyMetadataFacto
2323
{
2424
const RESOURCE_SCHEMA = __DIR__.'/../../schema/metadata.xsd';
2525

26+
private $paths;
27+
28+
/**
29+
* @param string[] $paths
30+
* @param PropertyMetadataFactoryInterface|null $decorated
31+
*/
32+
public function __construct(array $paths, PropertyMetadataFactoryInterface $decorated = null)
33+
{
34+
parent::__construct($decorated);
35+
36+
$this->paths = $paths;
37+
}
38+
2639
/**
2740
* {@inheritdoc}
2841
*/

src/Metadata/Property/Factory/YamlPropertyMetadataFactory.php

Lines changed: 11 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111

1212
namespace ApiPlatform\Core\Metadata\Property\Factory;
1313

14-
use ApiPlatform\Core\Exception\InvalidArgumentException;
15-
use Symfony\Component\Yaml\Exception\ParseException;
16-
use Symfony\Component\Yaml\Yaml;
14+
use ApiPlatform\Core\Metadata\YamlExtractor;
1715

1816
/**
1917
* Creates a property metadata from YAML {@see Property} configuration files.
@@ -22,79 +20,20 @@
2220
*/
2321
final class YamlPropertyMetadataFactory extends AbstractFilePropertyMetadataFactory
2422
{
23+
private $extractor;
24+
25+
public function __construct(YamlExtractor $extractor, PropertyMetadataFactoryInterface $decorated = null)
26+
{
27+
parent::__construct($decorated);
28+
29+
$this->extractor = $extractor;
30+
}
31+
2532
/**
2633
* {@inheritdoc}
27-
*
28-
* @throws ParseException
2934
*/
3035
protected function getMetadata(string $resourceClass, string $property): array
3136
{
32-
foreach ($this->paths as $path) {
33-
try {
34-
$resources = Yaml::parse(file_get_contents($path));
35-
} catch (ParseException $parseException) {
36-
$parseException->setParsedFile($path);
37-
38-
throw $parseException;
39-
}
40-
41-
if (null === $resources = $resources['resources'] ?? $resources) {
42-
continue;
43-
}
44-
45-
if (!is_array($resources)) {
46-
throw new InvalidArgumentException(sprintf('"resources" setting is expected to be null or an array, %s given in "%s".', gettype($resources), $path));
47-
}
48-
49-
foreach ($resources as $resourceName => $resource) {
50-
if (null === $resource) {
51-
continue;
52-
}
53-
54-
if (!is_array($resource)) {
55-
throw new InvalidArgumentException(sprintf('"%s" setting is expected to be null or an array, %s given in "%s".', $resourceName, gettype($resource), $path));
56-
}
57-
58-
if (!isset($resource['class'])) {
59-
throw new InvalidArgumentException(sprintf('"class" setting is expected to be a string, none given in "%s".', $path));
60-
}
61-
62-
if ($resourceClass !== $resource['class'] || !isset($resource['properties'])) {
63-
continue;
64-
}
65-
66-
if (!is_array($resource['properties'])) {
67-
throw new InvalidArgumentException(sprintf('"properties" setting is expected to be null or an array, %s given in "%s".', gettype($resource['properties']), $path));
68-
}
69-
70-
foreach ($resource['properties'] as $propertyName => $propertyValues) {
71-
if (null === $propertyValues) {
72-
continue;
73-
}
74-
75-
if (!is_array($propertyValues)) {
76-
throw new InvalidArgumentException(sprintf('"%s" setting is expected to be null or an array, %s given in "%s".', $propertyName, gettype($propertyValues), $path));
77-
}
78-
79-
if ($property !== $propertyName) {
80-
continue;
81-
}
82-
83-
return [
84-
'description' => isset($propertyValues['description']) && is_scalar($propertyValues['description']) ? $propertyValues['description'] : null,
85-
'readable' => isset($propertyValues['readable']) && is_bool($propertyValues['readable']) ? $propertyValues['readable'] : null,
86-
'writable' => isset($propertyValues['writable']) && is_bool($propertyValues['writable']) ? $propertyValues['writable'] : null,
87-
'readableLink' => isset($propertyValues['readableLink']) && is_bool($propertyValues['readableLink']) ? $propertyValues['readableLink'] : null,
88-
'writableLink' => isset($propertyValues['writableLink']) && is_bool($propertyValues['writableLink']) ? $propertyValues['writableLink'] : null,
89-
'required' => isset($propertyValues['required']) && is_bool($propertyValues['required']) ? $propertyValues['required'] : null,
90-
'identifier' => isset($propertyValues['identifier']) && is_bool($propertyValues['identifier']) ? $propertyValues['identifier'] : null,
91-
'iri' => isset($propertyValues['iri']) && is_scalar($propertyValues['iri']) ? $propertyValues['iri'] : null,
92-
'attributes' => $propertyValues['attributes'] ?? null,
93-
];
94-
}
95-
}
96-
}
97-
98-
return [];
37+
return $this->extractor->getResources()[$resourceClass]['properties'][$property] ?? [];
9938
}
10039
}

src/Metadata/Property/Factory/YamlPropertyNameCollectionFactory.php

Lines changed: 12 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
use ApiPlatform\Core\Exception\InvalidArgumentException;
1515
use ApiPlatform\Core\Exception\ResourceClassNotFoundException;
1616
use ApiPlatform\Core\Metadata\Property\PropertyNameCollection;
17-
use Symfony\Component\Yaml\Exception\ParseException;
18-
use Symfony\Component\Yaml\Yaml;
17+
use ApiPlatform\Core\Metadata\YamlExtractor;
1918

2019
/**
2120
* Creates a property name collection from YAML {@see Property} configuration files.
@@ -24,30 +23,29 @@
2423
*/
2524
final class YamlPropertyNameCollectionFactory implements PropertyNameCollectionFactoryInterface
2625
{
27-
private $paths;
26+
private $extractor;
2827
private $decorated;
2928

30-
/**
31-
* @param array $paths
32-
* @param PropertyNameCollectionFactoryInterface|null $decorated
33-
*/
34-
public function __construct(array $paths, PropertyNameCollectionFactoryInterface $decorated = null)
29+
public function __construct(YamlExtractor $extractor, PropertyNameCollectionFactoryInterface $decorated = null)
3530
{
36-
$this->paths = $paths;
31+
$this->extractor = $extractor;
3732
$this->decorated = $decorated;
3833
}
3934

4035
/**
4136
* {@inheritdoc}
4237
*
43-
* @throws ParseException
4438
* @throws InvalidArgumentException
4539
*/
4640
public function create(string $resourceClass, array $options = []): PropertyNameCollection
4741
{
42+
$propertyNames = [];
43+
4844
if ($this->decorated) {
4945
try {
50-
$propertyNameCollection = $this->decorated->create($resourceClass, $options);
46+
foreach ($propertyNameCollection = $this->decorated->create($resourceClass, $options) as $propertyName) {
47+
$propertyNames[$propertyName] = true;
48+
}
5149
} catch (ResourceClassNotFoundException $resourceClassNotFoundException) {
5250
// Ignore not found exceptions from parent
5351
}
@@ -61,62 +59,9 @@ public function create(string $resourceClass, array $options = []): PropertyName
6159
throw new ResourceClassNotFoundException(sprintf('The resource class "%s" does not exist.', $resourceClass));
6260
}
6361

64-
$propertyNames = [];
65-
66-
foreach ($this->paths as $path) {
67-
try {
68-
$resources = Yaml::parse(file_get_contents($path));
69-
} catch (ParseException $parseException) {
70-
$parseException->setParsedFile($path);
71-
72-
throw $parseException;
73-
}
74-
75-
if (null === $resources = $resources['resources'] ?? $resources) {
76-
continue;
77-
}
78-
79-
if (!is_array($resources)) {
80-
throw new InvalidArgumentException(sprintf('"resources" setting is expected to be null or an array, %s given in "%s".', gettype($resources), $path));
81-
}
82-
83-
foreach ($resources as $resourceName => $resource) {
84-
if (null === $resource) {
85-
continue;
86-
}
87-
88-
if (!is_array($resource)) {
89-
throw new InvalidArgumentException(sprintf('"%s" setting is expected to be null or an array, %s given in "%s".', $resourceName, gettype($resource), $path));
90-
}
91-
92-
if (!isset($resource['class'])) {
93-
throw new InvalidArgumentException(sprintf('"class" setting is expected to be a string, none given in "%s".', $path));
94-
}
95-
96-
if ($resourceClass !== $resource['class'] || !isset($resource['properties'])) {
97-
continue;
98-
}
99-
100-
if (!is_array($resource['properties'])) {
101-
throw new InvalidArgumentException(sprintf('"properties" setting is expected to be null or an array, %s given in "%s".', gettype($resource['properties']), $path));
102-
}
103-
104-
foreach ($resource['properties'] as $propertyName => $propertyValues) {
105-
if (null === $propertyValues) {
106-
continue;
107-
}
108-
109-
if (!is_array($propertyValues)) {
110-
throw new InvalidArgumentException(sprintf('"%s" setting is expected to be null or an array, %s given in "%s".', $propertyName, gettype($propertyValues), $path));
111-
}
112-
113-
$propertyNames[$propertyName] = true;
114-
}
115-
}
116-
}
117-
118-
if (isset($propertyNameCollection)) {
119-
foreach ($propertyNameCollection as $propertyName) {
62+
$resources = $this->extractor->getResources();
63+
if (isset($resources[$resourceClass]['properties'])) {
64+
foreach ($resources[$resourceClass]['properties'] as $propertyName => $property) {
12065
$propertyNames[$propertyName] = true;
12166
}
12267
}

0 commit comments

Comments
 (0)