Skip to content

Commit 74986cb

Browse files
authored
feat: inflector as service (#6447)
1 parent 90e71f0 commit 74986cb

File tree

18 files changed

+92
-33
lines changed

18 files changed

+92
-33
lines changed

src/Elasticsearch/Metadata/Document/Factory/CatDocumentMetadataFactory.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use ApiPlatform\Elasticsearch\Exception\IndexNotFoundException;
1717
use ApiPlatform\Elasticsearch\Metadata\Document\DocumentMetadata;
18+
use ApiPlatform\Metadata\InflectorInterface;
1819
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
1920
use ApiPlatform\Metadata\Util\Inflector;
2021
use Elastic\Elasticsearch\Exception\ClientResponseException;
@@ -32,7 +33,7 @@
3233
final class CatDocumentMetadataFactory implements DocumentMetadataFactoryInterface
3334
{
3435
// @phpstan-ignore-next-line
35-
public function __construct(private readonly Client $client, private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory, private readonly ?DocumentMetadataFactoryInterface $decorated = null)
36+
public function __construct(private readonly Client $client, private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory, private readonly ?DocumentMetadataFactoryInterface $decorated = null, private readonly ?InflectorInterface $inflector = new Inflector())
3637
{
3738
}
3839

@@ -61,7 +62,7 @@ public function create(string $resourceClass): DocumentMetadata
6162
return $this->handleNotFound($documentMetadata, $resourceClass);
6263
}
6364

64-
$index = Inflector::tableize($resourceShortName);
65+
$index = $this->inflector->tableize($resourceShortName);
6566

6667
try {
6768
// @phpstan-ignore-next-line

src/Elasticsearch/Metadata/Resource/Factory/ElasticsearchProviderResourceMetadataCollectionFactory.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ApiPlatform\Elasticsearch\State\ItemProvider;
1818
use ApiPlatform\Elasticsearch\State\Options;
1919
use ApiPlatform\Metadata\CollectionOperationInterface;
20+
use ApiPlatform\Metadata\InflectorInterface;
2021
use ApiPlatform\Metadata\Operation;
2122
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
2223
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
@@ -27,7 +28,7 @@
2728

2829
final class ElasticsearchProviderResourceMetadataCollectionFactory implements ResourceMetadataCollectionFactoryInterface
2930
{
30-
public function __construct(private readonly ?Client $client, private readonly ResourceMetadataCollectionFactoryInterface $decorated, private readonly bool $triggerDeprecation = true) // @phpstan-ignore-line
31+
public function __construct(private readonly ?Client $client, private readonly ResourceMetadataCollectionFactoryInterface $decorated, private readonly bool $triggerDeprecation = true, private readonly ?InflectorInterface $inflector = new Inflector()) // @phpstan-ignore-line
3132
{
3233
}
3334

@@ -106,7 +107,7 @@ public function create(string $resourceClass): ResourceMetadataCollection
106107
private function hasIndices(Operation $operation): bool
107108
{
108109
$shortName = $operation->getShortName();
109-
$index = Inflector::tableize($shortName);
110+
$index = $this->inflector->tableize($shortName);
110111

111112
try {
112113
$this->client->cat()->indices(['index' => $index]); // @phpstan-ignore-line

src/Elasticsearch/State/CollectionProvider.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ApiPlatform\Elasticsearch\Metadata\Document\DocumentMetadata;
1818
use ApiPlatform\Elasticsearch\Metadata\Document\Factory\DocumentMetadataFactoryInterface;
1919
use ApiPlatform\Elasticsearch\Paginator;
20+
use ApiPlatform\Metadata\InflectorInterface;
2021
use ApiPlatform\Metadata\Operation;
2122
use ApiPlatform\Metadata\Util\Inflector;
2223
use ApiPlatform\State\ApiResource\Error;
@@ -39,7 +40,7 @@ final class CollectionProvider implements ProviderInterface
3940
/**
4041
* @param RequestBodySearchCollectionExtensionInterface[] $collectionExtensions
4142
*/
42-
public function __construct(private readonly LegacyClient|Client $client, private readonly ?DocumentMetadataFactoryInterface $documentMetadataFactory = null, private readonly ?DenormalizerInterface $denormalizer = null, private readonly ?Pagination $pagination = null, private readonly iterable $collectionExtensions = []) // @phpstan-ignore-line
43+
public function __construct(private readonly LegacyClient|Client $client, private readonly ?DocumentMetadataFactoryInterface $documentMetadataFactory = null, private readonly ?DenormalizerInterface $denormalizer = null, private readonly ?Pagination $pagination = null, private readonly iterable $collectionExtensions = [], private readonly ?InflectorInterface $inflector = new Inflector()) // @phpstan-ignore-line
4344
{
4445
}
4546

@@ -102,6 +103,6 @@ private function convertDocumentMetadata(DocumentMetadata $documentMetadata): Op
102103

103104
private function getIndex(Operation $operation): string
104105
{
105-
return Inflector::tableize($operation->getShortName());
106+
return $this->inflector->tableize($operation->getShortName());
106107
}
107108
}

src/Elasticsearch/State/ItemProvider.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ApiPlatform\Elasticsearch\Metadata\Document\Factory\DocumentMetadataFactoryInterface;
1818
use ApiPlatform\Elasticsearch\Serializer\DocumentNormalizer;
1919
use ApiPlatform\Metadata\Exception\RuntimeException;
20+
use ApiPlatform\Metadata\InflectorInterface;
2021
use ApiPlatform\Metadata\Operation;
2122
use ApiPlatform\Metadata\Util\Inflector;
2223
use ApiPlatform\State\ApiResource\Error;
@@ -37,7 +38,7 @@
3738
*/
3839
final class ItemProvider implements ProviderInterface
3940
{
40-
public function __construct(private readonly LegacyClient|Client $client, private readonly ?DocumentMetadataFactoryInterface $documentMetadataFactory = null, private readonly ?DenormalizerInterface $denormalizer = null) // @phpstan-ignore-line
41+
public function __construct(private readonly LegacyClient|Client $client, private readonly ?DocumentMetadataFactoryInterface $documentMetadataFactory = null, private readonly ?DenormalizerInterface $denormalizer = null, private readonly ?InflectorInterface $inflector = new Inflector()) // @phpstan-ignore-line
4142
{
4243
}
4344

@@ -96,6 +97,6 @@ private function convertDocumentMetadata(DocumentMetadata $documentMetadata): Op
9697

9798
private function getIndex(Operation $operation): string
9899
{
99-
return Inflector::tableize($operation->getShortName());
100+
return $this->inflector->tableize($operation->getShortName());
100101
}
101102
}

src/GraphQl/Type/FieldsBuilder.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use ApiPlatform\Metadata\GraphQl\Operation;
2323
use ApiPlatform\Metadata\GraphQl\Query;
2424
use ApiPlatform\Metadata\GraphQl\Subscription;
25+
use ApiPlatform\Metadata\InflectorInterface;
2526
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
2627
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
2728
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
@@ -50,7 +51,7 @@ final class FieldsBuilder implements FieldsBuilderInterface, FieldsBuilderEnumIn
5051
{
5152
private readonly ContextAwareTypeBuilderInterface|TypeBuilderEnumInterface|TypeBuilderInterface $typeBuilder;
5253

53-
public function __construct(private readonly PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, private readonly PropertyMetadataFactoryInterface $propertyMetadataFactory, private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, private readonly ResourceClassResolverInterface $resourceClassResolver, private readonly TypesContainerInterface $typesContainer, ContextAwareTypeBuilderInterface|TypeBuilderEnumInterface|TypeBuilderInterface $typeBuilder, private readonly TypeConverterInterface $typeConverter, private readonly ResolverFactoryInterface $itemResolverFactory, private readonly ?ResolverFactoryInterface $collectionResolverFactory, private readonly ?ResolverFactoryInterface $itemMutationResolverFactory, private readonly ?ResolverFactoryInterface $itemSubscriptionResolverFactory, private readonly ContainerInterface $filterLocator, private readonly Pagination $pagination, private readonly ?NameConverterInterface $nameConverter, private readonly string $nestingSeparator)
54+
public function __construct(private readonly PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, private readonly PropertyMetadataFactoryInterface $propertyMetadataFactory, private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, private readonly ResourceClassResolverInterface $resourceClassResolver, private readonly TypesContainerInterface $typesContainer, ContextAwareTypeBuilderInterface|TypeBuilderEnumInterface|TypeBuilderInterface $typeBuilder, private readonly TypeConverterInterface $typeConverter, private readonly ResolverFactoryInterface $itemResolverFactory, private readonly ?ResolverFactoryInterface $collectionResolverFactory, private readonly ?ResolverFactoryInterface $itemMutationResolverFactory, private readonly ?ResolverFactoryInterface $itemSubscriptionResolverFactory, private readonly ContainerInterface $filterLocator, private readonly Pagination $pagination, private readonly ?NameConverterInterface $nameConverter, private readonly string $nestingSeparator, private readonly ?InflectorInterface $inflector = new Inflector())
5455
{
5556
if ($typeBuilder instanceof TypeBuilderInterface) {
5657
@trigger_error(sprintf('$typeBuilder argument of FieldsBuilder implementing "%s" is deprecated since API Platform 3.1. It has to implement "%s" instead.', TypeBuilderInterface::class, TypeBuilderEnumInterface::class), \E_USER_DEPRECATED);
@@ -113,7 +114,7 @@ public function getCollectionQueryFields(string $resourceClass, Operation $opera
113114
$extraArgs = $this->resolveResourceArgs($operation->getExtraArgs() ?? [], $operation);
114115
$configuration['args'] = $args ?: $configuration['args'] ?? $fieldConfiguration['args'] + $extraArgs;
115116

116-
return [Inflector::pluralize($fieldName) => array_merge($fieldConfiguration, $configuration)];
117+
return [$this->inflector->pluralize($fieldName) => array_merge($fieldConfiguration, $configuration)];
117118
}
118119

119120
return [];

src/Metadata/InflectorInterface.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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\Metadata;
15+
16+
interface InflectorInterface
17+
{
18+
/**
19+
* Returns a snake case transformed string.
20+
*/
21+
public function tableize(string $input): string;
22+
23+
/**
24+
* Returns the plural forms of a string.
25+
*/
26+
public function pluralize(string $singular): string;
27+
}

src/Metadata/Operation/DashPathSegmentNameGenerator.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace ApiPlatform\Metadata\Operation;
1515

16+
use ApiPlatform\Metadata\InflectorInterface;
1617
use ApiPlatform\Metadata\Util\Inflector;
1718

1819
/**
@@ -22,12 +23,16 @@
2223
*/
2324
final class DashPathSegmentNameGenerator implements PathSegmentNameGeneratorInterface
2425
{
26+
public function __construct(private readonly ?InflectorInterface $inflector = new Inflector())
27+
{
28+
}
29+
2530
/**
2631
* {@inheritdoc}
2732
*/
2833
public function getSegmentName(string $name, bool $collection = true): string
2934
{
30-
return $collection ? $this->dashize(Inflector::pluralize($name)) : $this->dashize($name);
35+
return $collection ? $this->dashize($this->inflector->pluralize($name)) : $this->dashize($name);
3136
}
3237

3338
private function dashize(string $string): string

src/Metadata/Operation/UnderscorePathSegmentNameGenerator.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace ApiPlatform\Metadata\Operation;
1515

16+
use ApiPlatform\Metadata\InflectorInterface;
1617
use ApiPlatform\Metadata\Util\Inflector;
1718

1819
/**
@@ -22,13 +23,17 @@
2223
*/
2324
final class UnderscorePathSegmentNameGenerator implements PathSegmentNameGeneratorInterface
2425
{
26+
public function __construct(private readonly ?InflectorInterface $inflector = new Inflector())
27+
{
28+
}
29+
2530
/**
2631
* {@inheritdoc}
2732
*/
2833
public function getSegmentName(string $name, bool $collection = true): string
2934
{
30-
$name = Inflector::tableize($name);
35+
$name = $this->inflector->tableize($name);
3136

32-
return $collection ? Inflector::pluralize($name) : $name;
37+
return $collection ? $this->inflector->pluralize($name) : $name;
3338
}
3439
}

src/Metadata/Util/AttributeFilterExtractorTrait.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Metadata\Util;
1515

1616
use ApiPlatform\Metadata\ApiFilter;
17+
use Symfony\Component\String\UnicodeString;
1718

1819
/**
1920
* Generates a service id for a generic filter.
@@ -133,6 +134,6 @@ private function generateFilterId(\ReflectionClass $reflectionClass, string $fil
133134
{
134135
$suffix = null !== $filterId ? '_'.$filterId : $filterId;
135136

136-
return 'annotated_'.Inflector::tableize(str_replace('\\', '', $reflectionClass->getName().(new \ReflectionClass($filterClass))->getName().$suffix));
137+
return 'annotated_'.(new UnicodeString(str_replace('\\', '', $reflectionClass->getName().(new \ReflectionClass($filterClass))->getName().$suffix)))->snake()->toString();
137138
}
138139
}

src/Metadata/Util/Inflector.php

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace ApiPlatform\Metadata\Util;
1515

16+
use ApiPlatform\Metadata\InflectorInterface;
1617
use Doctrine\Inflector\Inflector as LegacyInflector;
1718
use Doctrine\Inflector\InflectorFactory;
1819
use Symfony\Component\String\Inflector\EnglishInflector;
@@ -21,9 +22,12 @@
2122
/**
2223
* @internal
2324
*/
24-
final class Inflector
25+
final class Inflector implements InflectorInterface
2526
{
26-
private static bool $keepLegacyInflector = true;
27+
public function __construct(private bool $keepLegacyInflector = true)
28+
{
29+
}
30+
2731
private static ?LegacyInflector $instance = null;
2832

2933
private static function getInstance(): LegacyInflector
@@ -32,17 +36,12 @@ private static function getInstance(): LegacyInflector
3236
?? static::$instance = InflectorFactory::create()->build();
3337
}
3438

35-
public static function keepLegacyInflector(bool $keepLegacyInflector): void
36-
{
37-
static::$keepLegacyInflector = $keepLegacyInflector;
38-
}
39-
4039
/**
4140
* @see InflectorObject::tableize()
4241
*/
43-
public static function tableize(string $word): string
42+
public function tableize(string $word): string
4443
{
45-
if (!static::$keepLegacyInflector) {
44+
if (!$this->keepLegacyInflector) {
4645
return (new UnicodeString($word))->snake()->toString();
4746
}
4847

@@ -52,9 +51,9 @@ public static function tableize(string $word): string
5251
/**
5352
* @see InflectorObject::pluralize()
5453
*/
55-
public static function pluralize(string $word): string
54+
public function pluralize(string $word): string
5655
{
57-
if (!static::$keepLegacyInflector) {
56+
if (!$this->keepLegacyInflector) {
5857
$pluralize = (new EnglishInflector())->pluralize($word);
5958

6059
return end($pluralize);

0 commit comments

Comments
 (0)