Skip to content

Commit e2020a4

Browse files
author
abluchet
committed
temp
1 parent df776e8 commit e2020a4

19 files changed

+536
-74
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ public function getConfigTreeBuilder()
4343
->scalarNode('title')->defaultValue('')->info('The title of the API.')->end()
4444
->scalarNode('description')->defaultValue('')->info('The description of the API.')->end()
4545
->scalarNode('version')->defaultValue('0.0.0')->info('The version of the API.')->end()
46-
->scalarNode('default_operation_path_resolver')->defaultValue('api_platform.operation_path_resolver.underscore')->info('Specify the default operation path resolver to use for generating resources operations path.')->end()
46+
->scalarNode('default_operation_path_resolver')->defaultValue('api_platform.operation_path_resolver.generator')->info('[Deprecated] Specify the default operation path resolver to use for generating resources operations path.')->end()
4747
->scalarNode('name_converter')->defaultNull()->info('Specify a name converter to use.')->end()
48+
->scalarNode('path_name_generator')->defaultValue('api_platform.path_name_generator.underscore')->info('Specify a path name generator to use.')->end()
4849
->scalarNode('api_resources_directory')->defaultValue('Entity')->info('The name of the directory within the bundles that contains the api resources.')->end()
4950
->arrayNode('eager_loading')
5051
->canBeDisabled()

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

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,34 @@
8585

8686
<!-- Resources Operations path resolver -->
8787

88+
<service id="api_platform.path_name_generator" alias="api_platform.path_name_generator.underscore" public="false" />
89+
90+
<service id="api_platform.path_name_generator.underscore" class="ApiPlatform\Core\Operation\UnderscorePathNameGenerator" public="false" />
91+
<service id="api_platform.path_name_generator.dash" class="ApiPlatform\Core\Operation\DashPathNameGenerator" public="false" />
92+
8893
<service id="api_platform.operation_path_resolver" alias="api_platform.operation_path_resolver.router" public="false" />
8994

9095
<service id="api_platform.operation_path_resolver.router" class="ApiPlatform\Core\Bridge\Symfony\Routing\RouterOperationPathResolver" public="false">
9196
<argument type="service" id="api_platform.router" />
9297
<argument type="service" id="api_platform.operation_path_resolver.custom" />
98+
<argument type="service" id="api_platform.subresource_operation_factory" />
9399
</service>
94100

95101
<service id="api_platform.operation_path_resolver.custom" class="ApiPlatform\Core\PathResolver\CustomOperationPathResolver" public="false">
96102
<argument type="service" id="api_platform.operation_path_resolver.default" />
97103
</service>
98104

99-
<service id="api_platform.operation_path_resolver.underscore" class="ApiPlatform\Core\PathResolver\UnderscoreOperationPathResolver" public="false" />
100-
<service id="api_platform.operation_path_resolver.dash" class="ApiPlatform\Core\PathResolver\DashOperationPathResolver" public="false" />
105+
<service id="api_platform.operation_path_resolver.generator" class="ApiPlatform\Core\PathResolver\OperationPathResolver" public="false">
106+
<argument type="service" id="api_platform.path_name_generator" />
107+
</service>
108+
109+
<service id="api_platform.operation_path_resolver.underscore" class="ApiPlatform\Core\PathResolver\UnderscoreOperationPathResolver" public="false">
110+
<deprecated>The "%service_id%" service is deprecated since ApiPlatform 2.1 and will be removed in 3.0. Use PathNameGenerator instead.</deprecated>
111+
</service>
112+
113+
<service id="api_platform.operation_path_resolver.dash" class="ApiPlatform\Core\PathResolver\DashOperationPathResolver" public="false">
114+
<deprecated>The "%service_id%" service is deprecated since ApiPlatform 2.1 and will be removed in 3.0. Use PathNameGenerator instead.</deprecated>
115+
</service>
101116

102117
<!-- Event listeners -->
103118

@@ -193,6 +208,20 @@
193208
<argument type="service" id="api_platform.property_accessor" />
194209
</service>
195210

211+
<!-- Subresources -->
212+
213+
<service id="api_platform.subresource_operation_factory" class="ApiPlatform\Core\Operation\Factory\SubresourceOperationFactory" public="false">
214+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
215+
<argument type="service" id="api_platform.metadata.property.name_collection_factory" />
216+
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
217+
<argument type="service" id="api_platform.path_name_generator" />
218+
</service>
219+
220+
<service id="api_platform.subresource_operation_factory.cached" class="ApiPlatform\Core\Operation\Factory\CachedSubresourceOperationFactory" decorates="api_platform.subresource_operation_factory" decoration-priority="-10" public="false">
221+
<argument type="service" id="api_platform.cache.subresource_operation_factory" />
222+
<argument type="service" id="api_platform.subresource_operation_factory.cached.inner" />
223+
</service>
224+
196225
<!-- Cache -->
197226

198227
<service id="api_platform.cache.route_name_resolver" parent="cache.system" public="false">
@@ -203,12 +232,8 @@
203232
<tag name="cache.pool" />
204233
</service>
205234

206-
<service id="api_platform.subresource_operation_factory" class="ApiPlatform\Core\Bridge\Symfony\Routing\SubresourceOperationFactory" public="false">
207-
<argument type="service" id="api_platform.metadata.resource.name_collection_factory" />
208-
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
209-
<argument type="service" id="api_platform.metadata.property.name_collection_factory" />
210-
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
211-
<argument type="service" id="api_platform.operation_path_resolver.custom" />
235+
<service id="api_platform.cache.subresource_operation_factory" parent="cache.system" public="false">
236+
<tag name="cache.pool" />
212237
</service>
213238
</services>
214239

src/Bridge/Symfony/Routing/ApiLoader.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616
use ApiPlatform\Core\Api\OperationType;
1717
use ApiPlatform\Core\Exception\InvalidResourceException;
1818
use ApiPlatform\Core\Exception\RuntimeException;
19-
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
20-
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
2119
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
2220
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
21+
use ApiPlatform\Core\Operation\Factory\SubresourceOperationFactoryInterface;
2322
use ApiPlatform\Core\PathResolver\OperationPathResolverInterface;
2423
use Symfony\Component\Config\FileLocator;
2524
use Symfony\Component\Config\Loader\Loader;
@@ -53,7 +52,7 @@ final class ApiLoader extends Loader
5352
private $formats;
5453
private $resourceClassDirectories;
5554

56-
public function __construct(KernelInterface $kernel, ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory, ResourceMetadataFactoryInterface $resourceMetadataFactory, OperationPathResolverInterface $operationPathResolver, ContainerInterface $container, array $formats, array $resourceClassDirectories = [], SubresourceOperationFactory $subresourceOperationFactory = null)
55+
public function __construct(KernelInterface $kernel, ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory, ResourceMetadataFactoryInterface $resourceMetadataFactory, OperationPathResolverInterface $operationPathResolver, ContainerInterface $container, array $formats, array $resourceClassDirectories = [], SubresourceOperationFactoryInterface $subresourceOperationFactory = null)
5756
{
5857
$this->fileLoader = new XmlFileLoader(new FileLocator($kernel->locateResource('@ApiPlatformBundle/Resources/config/routing')));
5958
$this->resourceNameCollectionFactory = $resourceNameCollectionFactory;

src/Bridge/Symfony/Routing/RouteNameGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ private function __construct()
4545
*
4646
* @return string
4747
*/
48-
public static function generate(string $operationName, string $resourceShortName, $operationType, array $subresourceContext = []): string
48+
public static function generate(string $operationName, string $resourceShortName, $operationType): string
4949
{
5050
if (OperationType::SUBRESOURCE === $operationType = OperationTypeDeprecationHelper::getOperationType($operationType)) {
5151
throw new InvalidArgumentException('Subresource operations are not supported by the RouteNameGenerator.');

src/Bridge/Symfony/Routing/RouterOperationPathResolver.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
namespace ApiPlatform\Core\Bridge\Symfony\Routing;
1515

16+
use ApiPlatform\Core\Api\OperationType;
1617
use ApiPlatform\Core\Api\OperationTypeDeprecationHelper;
17-
use ApiPlatform\Core\Bridge\Symfony\Routing\SubresourceOperationFactory;
1818
use ApiPlatform\Core\Exception\InvalidArgumentException;
1919
use ApiPlatform\Core\PathResolver\OperationPathResolverInterface;
2020
use Symfony\Component\Routing\RouterInterface;
@@ -52,10 +52,14 @@ public function resolveOperationPath(string $resourceShortName, array $operation
5252

5353
if (isset($operation['route_name'])) {
5454
$routeName = $operation['route_name'];
55-
} elseif (null !== $operationName) {
56-
$routeName = RouteNameGenerator::generate($operationName, $resourceShortName, $operationType, $operation);
55+
} elseif (OperationType::SUBRESOURCE === $operationType) {
56+
throw new InvalidArgumentException('Subresource operations are not supported by the OperationPathResolver.');
5757
} else {
58-
return $this->deferred->resolveOperationPath($resourceShortName, $operation, OperationTypeDeprecationHelper::getOperationType($operationType), $operationName);
58+
if (null !== $operationName) {
59+
$routeName = RouteNameGenerator::generate($operationName, $resourceShortName, $operationType, $operation);
60+
} else {
61+
return $this->deferred->resolveOperationPath($resourceShortName, $operation, OperationTypeDeprecationHelper::getOperationType($operationType), $operationName);
62+
}
5963
}
6064

6165
if (!$route = $this->router->getRouteCollection()->get($routeName)) {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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\Operation;
15+
16+
use Doctrine\Common\Util\Inflector;
17+
18+
/**
19+
* Generate a path name with an underscore separator according to a string and whether it needs pluralization.
20+
*
21+
* @author Antoine Bluchet <[email protected]>
22+
*/
23+
class DashPathNameGenerator implements PathNameGeneratorInterface
24+
{
25+
/**
26+
* {@inheritdoc}
27+
*/
28+
public function getPathName(string $name, bool $pluralize = true): string
29+
{
30+
$name = $this->dashize($name);
31+
32+
return $pluralize ? Inflector::pluralize($name) : $name;
33+
}
34+
35+
private function dashize(string $string): string
36+
{
37+
return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '-$1', $string));
38+
}
39+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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\Operation\Factory;
15+
16+
use Psr\Cache\CacheException;
17+
use Psr\Cache\CacheItemPoolInterface;
18+
19+
/**
20+
* @internal
21+
*/
22+
final class CachedSubresourceOperationFactory implements SubresourceOperationFactoryInterface
23+
{
24+
const CACHE_KEY_PREFIX = 'subresource_operations_';
25+
26+
private $cacheItemPool;
27+
private $decorated;
28+
29+
public function __construct(CacheItemPoolInterface $cacheItemPool, SubresourceOperationFactoryInterface $decorated)
30+
{
31+
$this->cacheItemPool = $cacheItemPool;
32+
$this->decorated = $decorated;
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public function create(string $resourceClass): array
39+
{
40+
$cacheKey = self::CACHE_KEY_PREFIX.md5(serialize([$resourceClass]));
41+
42+
try {
43+
$cacheItem = $this->cacheItemPool->getItem($cacheKey);
44+
45+
if ($cacheItem->isHit()) {
46+
return $cacheItem->get();
47+
}
48+
} catch (CacheException $e) {
49+
// do nothing
50+
}
51+
52+
$subresourceOperations = $this->decorated->create($resourceClass);
53+
54+
if (!isset($cacheItem)) {
55+
return $subresourceOperations;
56+
}
57+
58+
$cacheItem->set($subresourceOperations);
59+
$this->cacheItemPool->save($cacheItem);
60+
61+
return $subresourceOperations;
62+
}
63+
}

0 commit comments

Comments
 (0)