Skip to content

Commit 113eb39

Browse files
committed
Refactor the filter system
1 parent a45108c commit 113eb39

File tree

9 files changed

+171
-85
lines changed

9 files changed

+171
-85
lines changed

src/Bridge/Doctrine/Orm/Filter/BooleanFilter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function getDescription(string $resourceClass) : array
5757

5858
$description[$property] = [
5959
'property' => $property,
60-
'type' => 'boolean',
60+
'type' => 'bool',
6161
'required' => false,
6262
];
6363
}

src/Bridge/Doctrine/Orm/Filter/DateFilter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ protected function getFilterDescription(string $property, string $period) : arra
194194
return [
195195
sprintf('%s[%s]', $property, $period) => [
196196
'property' => $property,
197-
'type' => '\DateTime',
197+
'type' => \DateTimeInterface::class,
198198
'required' => false,
199199
],
200200
];

src/Bridge/Doctrine/Orm/Filter/NumericFilter.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,34 @@ public function getDescription(string $resourceClass) : array
7171

7272
$description[$property] = [
7373
'property' => $property,
74-
'type' => $metadata->getTypeOfField($propertyParts['field']),
74+
'type' => $this->getType($metadata->getTypeOfField($propertyParts['field'])),
7575
'required' => false,
7676
];
7777
}
7878

7979
return $description;
8080
}
8181

82+
/**
83+
* Gets the PHP type corresponding to this Doctrine type.
84+
*
85+
* @param string $doctrineType
86+
*
87+
* @return string
88+
*/
89+
private function getType(string $doctrineType) : string
90+
{
91+
if (DBALType::DECIMAL === $doctrineType) {
92+
return 'string';
93+
}
94+
95+
if (DBALType::FLOAT === $doctrineType) {
96+
return 'float';
97+
}
98+
99+
return 'int';
100+
}
101+
82102
/**
83103
* {@inheritdoc}
84104
*/

src/Bridge/Doctrine/Orm/Filter/SearchFilter.php

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
1616
use ApiPlatform\Core\Exception\InvalidArgumentException;
1717
use Doctrine\Common\Persistence\ManagerRegistry;
18+
use Doctrine\DBAL\Types\Type;
1819
use Doctrine\ORM\QueryBuilder;
1920
use Psr\Log\LoggerInterface;
2021
use Symfony\Component\HttpFoundation\RequestStack;
@@ -91,14 +92,14 @@ public function getDescription(string $resourceClass) : array
9192
}
9293

9394
if ($metadata->hasField($field)) {
94-
$typeOfField = $metadata->getTypeOfField($field);
95+
$typeOfField = $this->getType($metadata->getTypeOfField($field));
9596
$strategy = $this->properties[$property] ?? self::STRATEGY_EXACT;
96-
$filterParameterNames = [
97-
$property,
98-
];
97+
$filterParameterNames = [$property];
98+
9999
if (self::STRATEGY_EXACT === $strategy) {
100100
$filterParameterNames[] = $property.'[]';
101101
}
102+
102103
foreach ($filterParameterNames as $filterParameterName) {
103104
$description[$filterParameterName] = [
104105
'property' => $property,
@@ -116,7 +117,7 @@ public function getDescription(string $resourceClass) : array
116117
foreach ($filterParameterNames as $filterParameterName) {
117118
$description[$filterParameterName] = [
118119
'property' => $property,
119-
'type' => 'iri',
120+
'type' => 'string',
120121
'required' => false,
121122
'strategy' => self::STRATEGY_EXACT,
122123
];
@@ -127,6 +128,40 @@ public function getDescription(string $resourceClass) : array
127128
return $description;
128129
}
129130

131+
/**
132+
* Converts a Doctrine type in PHP type.
133+
*
134+
* @param string $doctrineType
135+
*
136+
* @return string
137+
*/
138+
private function getType(string $doctrineType) : string
139+
{
140+
switch ($doctrineType) {
141+
case Type::TARRAY:
142+
return 'array';
143+
144+
case Type::BIGINT:
145+
case Type::INTEGER:
146+
case Type::SMALLINT:
147+
return 'int';
148+
149+
case Type::BOOLEAN:
150+
return 'bool';
151+
152+
case Type::DATE:
153+
case Type::TIME:
154+
case Type::DATETIME:
155+
case Type::DATETIMETZ:
156+
return \DateTimeInterface::class;
157+
158+
case Type::FLOAT:
159+
return 'float';
160+
}
161+
162+
return 'string';
163+
}
164+
130165
/**
131166
* {@inheritdoc}
132167
*/

src/Swagger/Serializer/DocumentationNormalizer.php

Lines changed: 81 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -399,63 +399,76 @@ private function getPropertySchema(PropertyMetadata $propertyMetadata) : \ArrayO
399399
$propertySchema['description'] = $description;
400400
}
401401

402-
if (null == $type = $propertyMetadata->getType()) {
402+
if (null === $type = $propertyMetadata->getType()) {
403403
return $propertySchema;
404404
}
405405

406-
$valueSchema = new \ArrayObject();
407-
$valueType = $type->isCollection() ? $type->getCollectionValueType() : $type;
408-
409-
switch ($valueType ? $valueType->getBuiltinType() : null) {
410-
case Type::BUILTIN_TYPE_STRING:
411-
$valueSchema['type'] = 'string';
412-
break;
413-
414-
case Type::BUILTIN_TYPE_INT:
415-
$valueSchema['type'] = 'integer';
416-
break;
417-
418-
case Type::BUILTIN_TYPE_FLOAT:
419-
$valueSchema['type'] = 'number';
420-
break;
421-
422-
case Type::BUILTIN_TYPE_BOOL:
423-
$valueSchema['type'] = 'boolean';
424-
break;
425-
426-
case Type::BUILTIN_TYPE_OBJECT:
427-
if (null === $className = $valueType->getClassName()) {
428-
break;
429-
}
430-
431-
if (is_subclass_of($className, \DateTimeInterface::class)) {
432-
$valueSchema['type'] = 'string';
433-
$valueSchema['format'] = 'date-time';
434-
break;
435-
}
436-
437-
if (!$this->resourceClassResolver->isResourceClass($className)) {
438-
break;
439-
}
440-
441-
if (true === $propertyMetadata->isReadableLink()) {
442-
$valueSchema['$ref'] = sprintf('#/definitions/%s', $this->resourceMetadataFactory->create($className)->getShortName());
443-
break;
444-
}
445-
446-
$valueSchema['type'] = 'string';
447-
$valueSchema['format'] = 'uri';
448-
break;
406+
$isCollection = $type->isCollection();
407+
if (null === $valueType = $isCollection ? $type->getCollectionValueType() : $type) {
408+
$builtinType = 'string';
409+
$className = null;
410+
} else {
411+
$builtinType = $valueType->getBuiltinType();
412+
$className = $valueType->getClassName();
449413
}
450414

451-
if ($type->isCollection()) {
452-
$propertySchema['type'] = 'array';
453-
$propertySchema['items'] = $valueSchema;
454-
} else {
455-
$propertySchema = new \ArrayObject((array) $propertySchema + (array) $valueSchema);
415+
$valueSchema = $this->getType($builtinType, $isCollection, $className, $propertyMetadata->isReadableLink());
416+
417+
return new \ArrayObject((array) $propertySchema + $valueSchema);
418+
}
419+
420+
/**
421+
* Gets the Swagger's type corresponding to the given PHP's type.
422+
*
423+
* @param string $type
424+
*
425+
* @param bool $isCollection
426+
* @param string $className
427+
* @param bool $readableLink
428+
*
429+
* @return array
430+
*/
431+
private function getType(string $type, bool $isCollection, string $className = null, bool $readableLink = null) : array
432+
{
433+
if ($isCollection) {
434+
return ['type' => 'array', 'items' => $this->getType($type, false, $className, $readableLink)];
435+
}
436+
437+
if (Type::BUILTIN_TYPE_STRING === $type) {
438+
return ['type' => 'string'];
439+
}
440+
441+
if (Type::BUILTIN_TYPE_INT === $type) {
442+
return ['type' => 'integer'];
443+
}
444+
445+
if (Type::BUILTIN_TYPE_FLOAT === $type) {
446+
return ['type' => 'number'];
447+
}
448+
449+
if (Type::BUILTIN_TYPE_BOOL === $type) {
450+
return ['type' => 'boolean'];
456451
}
457452

458-
return $propertySchema;
453+
if (Type::BUILTIN_TYPE_OBJECT === $type) {
454+
if (null === $className) {
455+
return ['type' => 'string'];
456+
}
457+
458+
if (is_subclass_of($className, \DateTimeInterface::class)) {
459+
return ['type' => 'string', 'format' => 'date-time'];
460+
}
461+
462+
if (!$this->resourceClassResolver->isResourceClass($className)) {
463+
return ['type' => 'string'];
464+
}
465+
466+
if (true === $readableLink) {
467+
return ['$ref' => sprintf('#/definitions/%s', $this->resourceMetadataFactory->create($className)->getShortName())];
468+
}
469+
}
470+
471+
return ['type' => 'string'];
459472
}
460473

461474
/**
@@ -490,6 +503,24 @@ private function computeDoc(Documentation $documentation, \ArrayObject $definiti
490503
return $doc;
491504
}
492505

506+
private function getFiltersParameters(string $resourceClass, string $operationName, ResourceMetadata $resourceMetadata) : array
507+
{
508+
$parameters = new \ArrayObject();
509+
foreach($resourceMetadata->getCollectionOperationAttribute($operationName, 'filters', [], true) as $filter) {
510+
foreach ($filter->getDescription($resourceClass) as $variable => $data) {
511+
$parameter = [
512+
'name' => $variable,
513+
'in' => 'query',
514+
'required' => $data['required'],
515+
'type' => $this->getType($data['type'])
516+
];
517+
518+
$data['swagger'] ?? $parameter = $data['swagger'] + $parameter;
519+
$parameters[] = $parameter;
520+
}
521+
}
522+
}
523+
493524
/**
494525
* {@inheritdoc}
495526
*/

tests/Bridge/Doctrine/Orm/Filter/BooleanFilterTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public function testGetDescription()
9595
$this->assertEquals([
9696
'dummyBoolean' => [
9797
'property' => 'dummyBoolean',
98-
'type' => 'boolean',
98+
'type' => 'bool',
9999
'required' => false,
100100
],
101101
], $filter->getDescription($this->resourceClass));
@@ -111,7 +111,7 @@ public function testGetDescriptionDefaultFields()
111111
$this->assertEquals([
112112
'dummyBoolean' => [
113113
'property' => 'dummyBoolean',
114-
'type' => 'boolean',
114+
'type' => 'bool',
115115
'required' => false,
116116
],
117117
], $filter->getDescription($this->resourceClass));

tests/Bridge/Doctrine/Orm/Filter/DateFilterTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,12 @@ public function testGetDescription()
8989
$this->assertEquals([
9090
'dummyDate[before]' => [
9191
'property' => 'dummyDate',
92-
'type' => '\DateTime',
92+
'type' => 'DateTimeInterface',
9393
'required' => false,
9494
],
9595
'dummyDate[after]' => [
9696
'property' => 'dummyDate',
97-
'type' => '\DateTime',
97+
'type' => 'DateTimeInterface',
9898
'required' => false,
9999
],
100100
], $filter->getDescription($this->resourceClass));

tests/Bridge/Doctrine/Orm/Filter/NumericFilterTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public function testGetDescription()
9595
$this->assertEquals([
9696
'id' => [
9797
'property' => 'id',
98-
'type' => 'integer',
98+
'type' => 'int',
9999
'required' => false,
100100
],
101101
], $filter->getDescription($this->resourceClass));
@@ -111,12 +111,12 @@ public function testGetDescriptionDefaultFields()
111111
$this->assertEquals([
112112
'id' => [
113113
'property' => 'id',
114-
'type' => 'integer',
114+
'type' => 'int',
115115
'required' => false,
116116
],
117117
'dummyPrice' => [
118118
'property' => 'dummyPrice',
119-
'type' => 'decimal',
119+
'type' => 'string',
120120
'required' => false,
121121
],
122122
], $filter->getDescription($this->resourceClass));

0 commit comments

Comments
 (0)