Skip to content

Commit e534029

Browse files
committed
odm
1 parent 5463112 commit e534029

File tree

13 files changed

+63
-377
lines changed

13 files changed

+63
-377
lines changed

src/Doctrine/Common/Extension/ParameterExtension.php

Lines changed: 0 additions & 101 deletions
This file was deleted.

src/Doctrine/Common/ParameterExtensionTrait.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ trait ParameterExtensionTrait
3030
protected ?LoggerInterface $logger = null;
3131

3232
/**
33-
* Configures a filter with common properties like ManagerRegistry, Logger, and PropertyAwareFilterInterface properties.
34-
*
3533
* @param object $filter the filter instance to configure
3634
* @param Parameter $parameter the operation parameter associated with the filter
3735
*/
@@ -48,7 +46,7 @@ private function configureFilter(object $filter, Parameter $parameter): void
4846
if ($filter instanceof PropertyAwareFilterInterface) {
4947
$properties = [];
5048
// Check if the filter has getProperties method (e.g., if it's an AbstractFilter)
51-
if (method_exists($filter, 'getProperties')) {
49+
if (method_exists($filter, 'getProperties')) { // @phpstan-ignore-line todo 5.x remove this check @see interface
5250
$properties = $filter->getProperties() ?? [];
5351
}
5452

src/GraphQl/Type/FieldsBuilder.php

Lines changed: 26 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -311,60 +311,6 @@ public function resolveResourceArgs(array $args, Operation $operation): array
311311
return $args;
312312
}
313313

314-
/**
315-
* Transform the result of a parse_str to a GraphQL object type.
316-
* We should consider merging getFilterArgs and this, `getFilterArgs` uses `convertType` whereas we assume that parameters have only scalar types.
317-
* Note that this method has a lower complexity then the `getFilterArgs` one.
318-
* TODO: Is there a use case with an argument being a complex type (eg: a Resource, Enum etc.)?
319-
*
320-
* @param array<array{name: string, required: bool|null, description: string|null, leafs: string|array, type: string}> $flattenFields
321-
*/
322-
private function parameterToObjectType(array $flattenFields, string $name): InputObjectType
323-
{
324-
$fields = [];
325-
foreach ($flattenFields as $field) {
326-
$key = $field['name'];
327-
$type = \in_array($field['type'], TypeIdentifier::values(), true) ? Type::builtin($field['type']) : Type::object($field['type']);
328-
if (!$field['required']) {
329-
$type = Type::nullable($type);
330-
}
331-
332-
$type = $this->getParameterType($type);
333-
if (\is_array($l = $field['leafs'])) {
334-
if (0 === key($l)) {
335-
$key = $key;
336-
$type = GraphQLType::listOf($type);
337-
} else {
338-
$n = [];
339-
foreach ($field['leafs'] as $l => $value) {
340-
$n[] = ['required' => null, 'name' => $l, 'leafs' => $value, 'type' => 'string', 'description' => null];
341-
}
342-
343-
$type = $this->parameterToObjectType($n, $key);
344-
if (isset($fields[$key]) && ($t = $fields[$key]['type']) instanceof InputObjectType) {
345-
$t = $fields[$key]['type'];
346-
$t->config['fields'] = array_merge($t->config['fields'], $type->config['fields']);
347-
$type = $t;
348-
}
349-
}
350-
}
351-
352-
if ($field['required']) {
353-
$type = GraphQLType::nonNull($type);
354-
}
355-
356-
if (isset($fields[$key])) {
357-
if ($type instanceof ListOfType) {
358-
$key .= '_list';
359-
}
360-
}
361-
362-
$fields[$key] = ['type' => $type, 'name' => $key];
363-
}
364-
365-
return new InputObjectType(['name' => $name, 'fields' => $fields]);
366-
}
367-
368314
/**
369315
* A simplified version of convert type that does not support resources.
370316
*/
@@ -504,34 +450,32 @@ private function getParameterArgs(Operation $operation, array $args = []): array
504450
$matchFound = false;
505451

506452
if ($filter = $this->getFilterInstance($parameter->getFilter())) {
507-
if ($filter instanceof FilterInterface) {
508-
foreach ($filter->getDescription($operation->getClass()) as $name => $value) {
509-
// Check if this description entry matches the current parameter's property
510-
if ($property && ($value['property'] ?? null) === $property) {
511-
$matchFound = true;
453+
foreach ($filter->getDescription($operation->getClass()) as $name => $value) {
454+
// Check if this description entry matches the current parameter's property
455+
if ($property && ($value['property'] ?? null) === $property) {
456+
$matchFound = true;
512457

513-
$suffix = '';
514-
if (str_starts_with($name, $property)) {
515-
$suffix = substr($name, \strlen($property));
516-
}
458+
$suffix = '';
459+
if (str_starts_with($name, $property)) {
460+
$suffix = substr($name, \strlen($property));
461+
}
517462

518-
$argName = $key.$suffix;
463+
$argName = $key.$suffix;
519464

520-
$type = \in_array($value['type'] ?? 'string', TypeIdentifier::values(), true) ? Type::builtin($value['type'] ?? 'string') : Type::object($value['type'] ?? 'string');
465+
$type = \in_array($value['type'] ?? 'string', TypeIdentifier::values(), true) ? Type::builtin($value['type'] ?? 'string') : Type::object($value['type'] ?? 'string');
521466

522-
if (!($value['required'] ?? false)) {
523-
$type = Type::nullable($type);
524-
}
467+
if (!($value['required'] ?? false)) {
468+
$type = Type::nullable($type);
469+
}
525470

526-
$graphQlType = $this->getParameterType($type);
471+
$graphQlType = $this->getParameterType($type);
527472

528-
parse_str($argName, $parsed);
529-
array_walk_recursive($parsed, static function (&$v) use ($graphQlType): void {
530-
$v = $graphQlType;
531-
});
473+
parse_str($argName, $parsed);
474+
array_walk_recursive($parsed, static function (&$v) use ($graphQlType): void {
475+
$v = $graphQlType;
476+
});
532477

533-
$args = $this->mergeFilterArgs($args, $parsed, $operation, $key);
534-
}
478+
$args = $this->mergeFilterArgs($args, $parsed, $operation, $key);
535479
}
536480
}
537481

@@ -794,6 +738,12 @@ private function getFilterInstance(object|string|null $filter): ?FilterInterface
794738
return null;
795739
}
796740

797-
return $this->filterLocator->get($filter);
741+
$filter = $this->filterLocator->get($filter);
742+
743+
if (!$filter instanceof FilterInterface) {
744+
return null;
745+
}
746+
747+
return $filter;
798748
}
799749
}

src/Laravel/Eloquent/Filter/OrderFilter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ public function getSchema(Parameter $parameter): array
5555
}
5656

5757
/**
58-
* @return OpenApiParameter[]|null
58+
* @return OpenApiParameter[]
5959
*/
60-
public function getOpenApiParameters(Parameter $parameter): ?array
60+
public function getOpenApiParameters(Parameter $parameter): array
6161
{
6262
return [new OpenApiParameter(name: $parameter->getKey(), in: 'query')];
6363
}

src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ final class ParameterResourceMetadataCollectionFactory implements ResourceMetada
4343
{
4444
use StateOptionsTrait;
4545

46-
private array $localPropertyCache;
46+
private array $localPropertyCache = [];
4747

4848
public function __construct(
4949
private readonly PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory,
@@ -111,7 +111,7 @@ private function getProperties(string $resourceClass, ?Parameter $parameter = nu
111111
}
112112

113113
if (($filter = $this->getFilterInstance($parameter->getFilter())) && $filter instanceof PropertyAwareFilterInterface) {
114-
if (!method_exists($filter, 'getProperties')) {
114+
if (!method_exists($filter, 'getProperties')) { // @phpstan-ignore-line todo 5.x remove this check
115115
trigger_deprecation('api-platform/core', 'In API Platform 5.0 "%s" will implement a method named "getProperties"', PropertyAwareFilterInterface::class);
116116
$refl = new \ReflectionClass($filter);
117117
$filterProperties = $refl->hasProperty('properties') ? $refl->getProperty('properties')->getValue($filter) : [];
@@ -221,10 +221,6 @@ private function addFilterMetadata(Parameter $parameter): Parameter
221221
$parameter = $parameter->withProvider($filter::getParameterProvider());
222222
}
223223

224-
if (!$filter) {
225-
return $parameter;
226-
}
227-
228224
if (null === $parameter->getSchema() && $filter instanceof JsonSchemaFilterInterface && $schema = $filter->getSchema($parameter)) {
229225
$parameter = $parameter->withSchema($schema);
230226
}
@@ -239,7 +235,7 @@ private function addFilterMetadata(Parameter $parameter): Parameter
239235
/**
240236
* @param array<string, ApiProperty> $properties
241237
*/
242-
private function setDefaults(string $key, Parameter $parameter, ?FilterInterface $filter, array $properties, Operation $operation): Parameter
238+
private function setDefaults(string $key, Parameter $parameter, ?object $filter, array $properties, Operation $operation): Parameter
243239
{
244240
if (null === $parameter->getKey()) {
245241
$parameter = $parameter->withKey($key);
@@ -305,7 +301,12 @@ private function getLegacyFilterMetadata(Parameter $parameter, Operation $operat
305301
return $parameter;
306302
}
307303

308-
private function getFilterInstance(object|string|null $filter): ?FilterInterface
304+
/**
305+
* TODO: 5.x use FilterInterface on Laravel eloquent filters.
306+
*
307+
* @return FilterInterface|object
308+
*/
309+
private function getFilterInstance(object|string|null $filter): ?object
309310
{
310311
if (!$filter) {
311312
return null;

src/Metadata/Tests/Resource/Factory/ParameterResourceMetadataCollectionFactoryTest.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ public function testParameterFactory(): void
3535
$nameCollection = $this->createStub(PropertyNameCollectionFactoryInterface::class);
3636
$nameCollection->method('create')->willReturn(new PropertyNameCollection(['id', 'hydra', 'everywhere']));
3737
$propertyMetadata = $this->createStub(PropertyMetadataFactoryInterface::class);
38-
$propertyMetadata->method('create')->willReturnOnConsecutiveCalls(new ApiProperty(identifier: true), new ApiProperty(readable: true), new ApiProperty(readable: true));
38+
$propertyMetadata->method('create')->willReturnOnConsecutiveCalls(
39+
new ApiProperty(identifier: true), new ApiProperty(readable: true), new ApiProperty(readable: true),
40+
new ApiProperty(identifier: true), new ApiProperty(readable: true), new ApiProperty(readable: true)
41+
);
3942
$filterLocator = $this->createStub(ContainerInterface::class);
4043
$filterLocator->method('has')->willReturn(true);
4144
$filterLocator->method('get')->willReturn(new class implements FilterInterface {
@@ -79,7 +82,10 @@ public function testParameterFactoryNoFilter(): void
7982
$nameCollection = $this->createStub(PropertyNameCollectionFactoryInterface::class);
8083
$nameCollection->method('create')->willReturn(new PropertyNameCollection(['id', 'hydra', 'everywhere']));
8184
$propertyMetadata = $this->createStub(PropertyMetadataFactoryInterface::class);
82-
$propertyMetadata->method('create')->willReturnOnConsecutiveCalls(new ApiProperty(identifier: true), new ApiProperty(readable: true), new ApiProperty(readable: true));
85+
$propertyMetadata->method('create')->willReturnOnConsecutiveCalls(
86+
new ApiProperty(identifier: true), new ApiProperty(readable: true), new ApiProperty(readable: true),
87+
new ApiProperty(identifier: true), new ApiProperty(readable: true), new ApiProperty(readable: true)
88+
);
8389
$filterLocator = $this->createStub(ContainerInterface::class);
8490
$filterLocator->method('has')->willReturn(false);
8591
$parameter = new ParameterResourceMetadataCollectionFactory(

tests/Fixtures/TestBundle/Document/SearchFilterParameter.php

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

1414
namespace ApiPlatform\Tests\Fixtures\TestBundle\Document;
1515

16+
use ApiPlatform\Doctrine\Odm\Filter\PartialSearchFilter;
1617
use ApiPlatform\Metadata\ApiFilter;
1718
use ApiPlatform\Metadata\GetCollection;
1819
use ApiPlatform\Metadata\GraphQl\QueryCollection;
@@ -33,6 +34,10 @@
3334
'searchExact[:property]' => new QueryParameter(filter: 'app_odm_search_filter_with_exact'),
3435
'searchOnTextAndDate[:property]' => new QueryParameter(filter: 'app_odm_filter_date_and_search'),
3536
'q' => new QueryParameter(property: 'hydra:freetextQuery'),
37+
'search[:property]' => new QueryParameter(
38+
filter: new PartialSearchFilter(),
39+
properties: ['foo', 'createdAt']
40+
),
3641
]
3742
)]
3843
#[QueryCollection(
@@ -46,8 +51,8 @@
4651
'q' => new QueryParameter(property: 'hydra:freetextQuery'),
4752
]
4853
)]
49-
#[ApiFilter(ODMSearchFilterValueTransformer::class, alias: 'app_odm_search_filter_partial', properties: ['foo' => 'partial'], arguments: ['key' => 'searchPartial'])]
50-
#[ApiFilter(ODMSearchFilterValueTransformer::class, alias: 'app_odm_search_filter_with_exact', properties: ['foo' => 'exact'], arguments: ['key' => 'searchExact'])]
54+
#[ApiFilter(ODMSearchFilterValueTransformer::class, alias: 'app_odm_search_filter_partial', properties: ['foo' => 'partial'])]
55+
#[ApiFilter(ODMSearchFilterValueTransformer::class, alias: 'app_odm_search_filter_with_exact', properties: ['foo' => 'exact'])]
5156
#[ApiFilter(ODMSearchTextAndDateFilter::class, alias: 'app_odm_filter_date_and_search', properties: ['foo', 'createdAt'], arguments: ['dateFilterProperties' => ['createdAt' => 'exclude_null'], 'searchFilterProperties' => ['foo' => 'exact']])]
5257
#[QueryParameter(key: ':property', filter: QueryParameterOdmFilter::class)]
5358
#[ODM\Document]

tests/Fixtures/TestBundle/Entity/SearchFilterParameter.php

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

1414
namespace ApiPlatform\Tests\Fixtures\TestBundle\Entity;
1515

16+
use ApiPlatform\Doctrine\Orm\Filter\PartialSearchFilter;
1617
use ApiPlatform\Metadata\ApiFilter;
1718
use ApiPlatform\Metadata\ApiResource;
1819
use ApiPlatform\Metadata\GetCollection;
@@ -36,7 +37,7 @@
3637
'searchOnTextAndDate[:property]' => new QueryParameter(filter: 'app_filter_date_and_search'),
3738
'q' => new QueryParameter(property: 'hydra:freetextQuery'),
3839
'search[:property]' => new QueryParameter(
39-
filter: new \ApiPlatform\Doctrine\Orm\Filter\PartialSearchFilter(),
40+
filter: new PartialSearchFilter(),
4041
properties: ['foo', 'createdAt']
4142
),
4243
]
@@ -52,8 +53,8 @@
5253
'q' => new QueryParameter(property: 'hydra:freetextQuery'),
5354
]
5455
)]
55-
#[ApiFilter(SearchFilterValueTransformer::class, alias: 'app_search_filter_partial', properties: ['foo' => 'partial'], arguments: ['key' => 'searchPartial'])]
56-
#[ApiFilter(SearchFilterValueTransformer::class, alias: 'app_search_filter_with_exact', properties: ['foo' => 'exact'], arguments: ['key' => 'searchExact'])]
56+
#[ApiFilter(SearchFilterValueTransformer::class, alias: 'app_search_filter_partial', properties: ['foo' => 'partial'])]
57+
#[ApiFilter(SearchFilterValueTransformer::class, alias: 'app_search_filter_with_exact', properties: ['foo' => 'exact'])]
5758
#[ApiFilter(SearchTextAndDateFilter::class, alias: 'app_filter_date_and_search', properties: ['foo', 'createdAt'], arguments: ['dateFilterProperties' => ['createdAt' => 'exclude_null'], 'searchFilterProperties' => ['foo' => 'exact']])]
5859
#[QueryParameter(key: ':property', filter: QueryParameterFilter::class)]
5960
#[ORM\Entity]

0 commit comments

Comments
 (0)