Skip to content

Commit 2367a47

Browse files
committed
remove dependency on validator
1 parent 31e937a commit 2367a47

File tree

11 files changed

+72
-69
lines changed

11 files changed

+72
-69
lines changed

features/filter/filter_validation.feature

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ Feature: Validate filters based upon filter description
22

33
@createSchema
44
Scenario: Required filter should not throw an error if set
5-
When I am on "/filter_validators?foo=bar"
5+
When I am on "/filter_validators?required=foo"
66
Then the response status code should be 200
77

8-
When I am on "/filter_validators?foo="
8+
When I am on "/filter_validators?required="
99
Then the response status code should be 200
1010

1111
@dropSchema
1212
Scenario: Required filter should throw an error if not set
1313
When I am on "/filter_validators"
1414
Then the response status code should be 400
15-
And the JSON node "detail" should be equal to "query parameter `foo` is required"
15+
And the JSON node "detail" should be equal to 'Query parameter "required" is required'

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

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

1414
namespace ApiPlatform\Core\Bridge\Symfony\Bundle\DependencyInjection;
1515

16+
use ApiPlatform\Core\Exception\FilterValidationException;
1617
use ApiPlatform\Core\Exception\InvalidArgumentException;
1718
use FOS\UserBundle\FOSUserBundle;
1819
use GraphQL\GraphQL;
@@ -248,6 +249,7 @@ private function addExceptionToStatusSection(ArrayNodeDefinition $rootNode)
248249
->defaultValue([
249250
ExceptionInterface::class => Response::HTTP_BAD_REQUEST,
250251
InvalidArgumentException::class => Response::HTTP_BAD_REQUEST,
252+
FilterValidationException::class => Response::HTTP_BAD_REQUEST,
251253
])
252254
->info('The list of exceptions mapped to their HTTP status code.')
253255
->normalizeKeys(false)

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
<service id="ApiPlatform\Core\Filter\QueryParameterValidateListener">
2727
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
28-
<argument type="service" id="validator" />
2928
<argument type="service" id="api_platform.filter_locator" />
3029

3130
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="16" />
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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\Exception;
15+
16+
/**
17+
* Filter validation exception.
18+
*
19+
* @author Julien DENIAU <[email protected]>
20+
*/
21+
class FilterValidationException extends \Exception implements ExceptionInterface
22+
{
23+
private $constraintViolationList;
24+
25+
public function __construct(array $constraintViolationList, string $message = '', int $code = 0, \Exception $previous = null)
26+
{
27+
$this->constraintViolationList = $constraintViolationList;
28+
29+
parent::__construct($message ?: $this->__toString(), $code, $previous);
30+
}
31+
32+
public function __toString(): string
33+
{
34+
return implode("\n", $this->constraintViolationList);
35+
}
36+
}

src/Filter/QueryParameterValidateListener.php

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,14 @@
1414
namespace ApiPlatform\Core\Filter;
1515

1616
use ApiPlatform\Core\Api\FilterLocatorTrait;
17-
use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
17+
use ApiPlatform\Core\Exception\FilterValidationException;
1818
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
1919
use ApiPlatform\Core\Util\RequestAttributesExtractor;
20+
use Psr\Container\ContainerInterface;
2021
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
21-
use Symfony\Component\Validator\Constraints as Assert;
22-
use Symfony\Component\Validator\Validator\ValidatorInterface as SymfonyValidatorInterface;
2322

2423
/**
25-
* Validate query parameters depending on filter description.
24+
* Validates query parameters depending on filter description.
2625
*
2726
* @author Julien Deniau <[email protected]>
2827
*/
@@ -32,12 +31,9 @@ class QueryParameterValidateListener
3231

3332
private $resourceMetadataFactory;
3433

35-
private $validator;
36-
37-
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, SymfonyValidatorInterface $validator, $filterLocator)
34+
public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, ContainerInterface $filterLocator)
3835
{
3936
$this->resourceMetadataFactory = $resourceMetadataFactory;
40-
$this->validator = $validator;
4137
$this->setFilterLocator($filterLocator);
4238
}
4339

@@ -62,14 +58,14 @@ public function onKernelRequest(GetResponseEvent $event)
6258
}
6359

6460
foreach ($filter->getDescription($attributes['resource_class']) as $name => $data) {
65-
if ($data['required'] ?? false) {
66-
$requiredConstraint = new Assert\NotNull();
67-
$requiredConstraint->message = sprintf('query parameter `%s` is required', $name);
68-
$errorList = $this->validator->validate($request->query->get($name), $requiredConstraint);
61+
$errorList = [];
62+
63+
if (($data['required'] ?? false) && null === $request->query->get($name)) {
64+
$errorList[] = sprintf('Query parameter "%s" is required', $name);
65+
}
6966

70-
if (count($errorList) > 0) {
71-
throw new ValidationException($errorList);
72-
}
67+
if ($errorList) {
68+
throw new FilterValidationException($errorList);
7369
}
7470
}
7571
}

tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
2929
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
3030
use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface;
31+
use ApiPlatform\Core\Exception\FilterValidationException;
3132
use ApiPlatform\Core\Exception\InvalidArgumentException;
3233
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
3334
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
@@ -451,7 +452,11 @@ private function getPartialContainerBuilderProphecy($test = false)
451452
'api_platform.description' => 'description',
452453
'api_platform.error_formats' => ['jsonproblem' => ['application/problem+json'], 'jsonld' => ['application/ld+json']],
453454
'api_platform.formats' => ['jsonld' => ['application/ld+json'], 'jsonhal' => ['application/hal+json']],
454-
'api_platform.exception_to_status' => [ExceptionInterface::class => Response::HTTP_BAD_REQUEST, InvalidArgumentException::class => Response::HTTP_BAD_REQUEST],
455+
'api_platform.exception_to_status' => [
456+
ExceptionInterface::class => Response::HTTP_BAD_REQUEST,
457+
InvalidArgumentException::class => Response::HTTP_BAD_REQUEST,
458+
FilterValidationException::class => Response::HTTP_BAD_REQUEST,
459+
],
455460
'api_platform.title' => 'title',
456461
'api_platform.version' => 'version',
457462
'api_platform.allow_plain_identifiers' => false,

tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Core\Tests\Bridge\Symfony\Bundle\DependencyInjection;
1515

1616
use ApiPlatform\Core\Bridge\Symfony\Bundle\DependencyInjection\Configuration;
17+
use ApiPlatform\Core\Exception\FilterValidationException;
1718
use ApiPlatform\Core\Exception\InvalidArgumentException;
1819
use PHPUnit\Framework\TestCase;
1920
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
@@ -67,6 +68,7 @@ public function testDefaultConfig()
6768
'exception_to_status' => [
6869
ExceptionInterface::class => Response::HTTP_BAD_REQUEST,
6970
InvalidArgumentException::class => Response::HTTP_BAD_REQUEST,
71+
FilterValidationException::class => Response::HTTP_BAD_REQUEST,
7072
],
7173
'default_operation_path_resolver' => 'api_platform.operation_path_resolver.underscore',
7274
'path_segment_name_generator' => 'api_platform.path_segment_name_generator.underscore',

tests/Fixtures/TestBundle/Entity/FilterValidator.php

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

1616
use ApiPlatform\Core\Annotation\ApiProperty;
1717
use ApiPlatform\Core\Annotation\ApiResource;
18-
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Filter\NotRequiredBarFilter;
19-
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Filter\RequiredFooFilter;
18+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Filter\RequiredFilter;
2019
use Doctrine\ORM\Mapping as ORM;
2120

2221
/**
@@ -26,8 +25,7 @@
2625
*
2726
* @ApiResource(attributes={
2827
* "filters"={
29-
* NotRequiredBarFilter::class,
30-
* RequiredFooFilter::class
28+
* RequiredFilter::class
3129
* }
3230
* })
3331
* @ORM\Entity

tests/Fixtures/TestBundle/Filter/NotRequiredBarFilter.php renamed to tests/Fixtures/TestBundle/Filter/RequiredFilter.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
1818
use Doctrine\ORM\QueryBuilder;
1919

20-
class NotRequiredBarFilter extends AbstractFilter
20+
class RequiredFilter extends AbstractFilter
2121
{
2222
protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
2323
{
@@ -27,8 +27,13 @@ protected function filterProperty(string $property, $value, QueryBuilder $queryB
2727
public function getDescription(string $resourceClass): array
2828
{
2929
return [
30-
'bar' => [
31-
'property' => 'bar',
30+
'required' => [
31+
'property' => 'required',
32+
'type' => 'string',
33+
'required' => true,
34+
],
35+
'not-required' => [
36+
'property' => 'not-required',
3237
'type' => 'string',
3338
'required' => false,
3439
],

tests/Fixtures/TestBundle/Filter/RequiredFooFilter.php

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

0 commit comments

Comments
 (0)