Skip to content

Commit

Permalink
feat(parametervalidator): create api-platform/parameter-validator com…
Browse files Browse the repository at this point in the history
…ponent

Co-authored-by: Antoine Bluchet <[email protected]>
  • Loading branch information
aegypius and soyuka committed Jan 4, 2024
1 parent bbc99cf commit 4f59677
Show file tree
Hide file tree
Showing 47 changed files with 885 additions and 114 deletions.
1 change: 1 addition & 0 deletions .commitlintrc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"jsonapi",
"graphql",
"openapi",
"parametervalidator",
"serializer",
"jsonschema",
"validation",
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
with:
fetch-depth: 0
- name: Run commitlint
run: |
run: |
commit=$(gh api \
/repos/${{ github.repository }}/pulls/${{github.event.number}}/commits \
| jq -r '.[0].commit.message' \
Expand Down Expand Up @@ -197,11 +197,13 @@ jobs:
- JsonSchema
- OpenApi
- Metadata
- ParameterValidator
- Elasticsearch
- HttpCache
- RamseyUuid
- GraphQl
- Serializer
- Symfony
fail-fast: false
steps:
- name: Checkout
Expand Down Expand Up @@ -1139,4 +1141,3 @@ jobs:
name: openapi-docs-php${{ matrix.php }}
path: build/out/openapi
continue-on-error: true

56 changes: 3 additions & 53 deletions src/Api/QueryParameterValidator/QueryParameterValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,63 +13,13 @@

namespace ApiPlatform\Api\QueryParameterValidator;

use ApiPlatform\Api\FilterLocatorTrait;
use ApiPlatform\Api\QueryParameterValidator\Validator\ArrayItems;
use ApiPlatform\Api\QueryParameterValidator\Validator\Bounds;
use ApiPlatform\Api\QueryParameterValidator\Validator\Enum;
use ApiPlatform\Api\QueryParameterValidator\Validator\Length;
use ApiPlatform\Api\QueryParameterValidator\Validator\MultipleOf;
use ApiPlatform\Api\QueryParameterValidator\Validator\Pattern;
use ApiPlatform\Api\QueryParameterValidator\Validator\Required;
use ApiPlatform\Exception\FilterValidationException;
use Psr\Container\ContainerInterface;
use ApiPlatform\ParameterValidator\ParameterValidator as NewQueryParameterValidator;

/**
* Validates query parameters depending on filter description.
*
* @author Julien Deniau <[email protected]>
* @deprecated use ApiPlatform\QueryParameterValidator\QueryParameterValidator instead
*/
class QueryParameterValidator
class QueryParameterValidator extends NewQueryParameterValidator
{
use FilterLocatorTrait;

private array $validators;

public function __construct(ContainerInterface $filterLocator)
{
$this->setFilterLocator($filterLocator);

$this->validators = [
new ArrayItems(),
new Bounds(),
new Enum(),
new Length(),
new MultipleOf(),
new Pattern(),
new Required(),
];
}

public function validateFilters(string $resourceClass, array $resourceFilters, array $queryParameters): void
{
$errorList = [];

foreach ($resourceFilters as $filterId) {
if (!$filter = $this->getFilter($filterId)) {
continue;
}

foreach ($filter->getDescription($resourceClass) as $name => $data) {
foreach ($this->validators as $validator) {
if ($errors = $validator->validate($name, $data, $queryParameters)) {
$errorList[] = $errors;
}
}
}
}

if ($errorList) {
throw new FilterValidationException(array_merge(...$errorList));
}
}
}
6 changes: 6 additions & 0 deletions src/Api/QueryParameterValidator/Validator/ArrayItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace ApiPlatform\Api\QueryParameterValidator\Validator;

use ApiPlatform\ParameterValidator\Validator\CheckFilterDeprecationsTrait;
use ApiPlatform\ParameterValidator\Validator\ValidatorInterface;

/**
* @deprecated use \ApiPlatform\ParameterValidator\Validator\ArrayItems instead
*/
final class ArrayItems implements ValidatorInterface
{
use CheckFilterDeprecationsTrait;
Expand Down
6 changes: 6 additions & 0 deletions src/Api/QueryParameterValidator/Validator/Bounds.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace ApiPlatform\Api\QueryParameterValidator\Validator;

use ApiPlatform\ParameterValidator\Validator\CheckFilterDeprecationsTrait;
use ApiPlatform\ParameterValidator\Validator\ValidatorInterface;

/**
* @deprecated use \ApiPlatform\ParameterValidator\Validator\Bounds instead
*/
final class Bounds implements ValidatorInterface
{
use CheckFilterDeprecationsTrait;
Expand Down
6 changes: 6 additions & 0 deletions src/Api/QueryParameterValidator/Validator/Enum.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace ApiPlatform\Api\QueryParameterValidator\Validator;

use ApiPlatform\ParameterValidator\Validator\CheckFilterDeprecationsTrait;
use ApiPlatform\ParameterValidator\Validator\ValidatorInterface;

/**
* @deprecated use \ApiPlatform\ParameterValidator\Validator\Enum instead
*/
final class Enum implements ValidatorInterface
{
use CheckFilterDeprecationsTrait;
Expand Down
6 changes: 6 additions & 0 deletions src/Api/QueryParameterValidator/Validator/Length.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace ApiPlatform\Api\QueryParameterValidator\Validator;

use ApiPlatform\ParameterValidator\Validator\CheckFilterDeprecationsTrait;
use ApiPlatform\ParameterValidator\Validator\ValidatorInterface;

/**
* @deprecated use \ApiPlatform\ParameterValidator\Validator\Length instead
*/
final class Length implements ValidatorInterface
{
use CheckFilterDeprecationsTrait;
Expand Down
6 changes: 6 additions & 0 deletions src/Api/QueryParameterValidator/Validator/MultipleOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace ApiPlatform\Api\QueryParameterValidator\Validator;

use ApiPlatform\ParameterValidator\Validator\CheckFilterDeprecationsTrait;
use ApiPlatform\ParameterValidator\Validator\ValidatorInterface;

/**
* @deprecated use \ApiPlatform\ParameterValidator\Validator\MultipleOf instead
*/
final class MultipleOf implements ValidatorInterface
{
use CheckFilterDeprecationsTrait;
Expand Down
6 changes: 6 additions & 0 deletions src/Api/QueryParameterValidator/Validator/Pattern.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace ApiPlatform\Api\QueryParameterValidator\Validator;

use ApiPlatform\ParameterValidator\Validator\CheckFilterDeprecationsTrait;
use ApiPlatform\ParameterValidator\Validator\ValidatorInterface;

/**
* @deprecated use \ApiPlatform\ParameterValidator\Validator\Pattern instead
*/
final class Pattern implements ValidatorInterface
{
use CheckFilterDeprecationsTrait;
Expand Down
5 changes: 5 additions & 0 deletions src/Api/QueryParameterValidator/Validator/Required.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@

namespace ApiPlatform\Api\QueryParameterValidator\Validator;

use ApiPlatform\ParameterValidator\Validator\CheckFilterDeprecationsTrait;
use ApiPlatform\ParameterValidator\Validator\ValidatorInterface;
use ApiPlatform\State\Util\RequestParser;

/**
* @deprecated use \ApiPlatform\ParameterValidator\Validator\Required instead
*/
final class Required implements ValidatorInterface
{
use CheckFilterDeprecationsTrait;
Expand Down
11 changes: 4 additions & 7 deletions src/Api/QueryParameterValidator/Validator/ValidatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,9 @@

namespace ApiPlatform\Api\QueryParameterValidator\Validator;

interface ValidatorInterface
use ApiPlatform\ParameterValidator\Validator as ParameterValidatorComponent;

/** @deprecated use \ApiPlatform\ParameterValidator\Validator\ValidatorInterface instead */
interface ValidatorInterface extends ParameterValidatorComponent\ValidatorInterface
{
/**
* @param string $name the parameter name to validate
* @param array<string, mixed> $filterDescription the filter descriptions as returned by `\ApiPlatform\Api\FilterInterface::getDescription()`
* @param array<string, mixed> $queryParameters the list of query parameter
*/
public function validate(string $name, array $filterDescription, array $queryParameters): array;
}
6 changes: 5 additions & 1 deletion src/Exception/FilterValidationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@

namespace ApiPlatform\Exception;

use ApiPlatform\ParameterValidator\Exception\ValidationExceptionInterface;

/**
* Filter validation exception.
*
* @author Julien DENIAU <[email protected]>
*
* @deprecated use \ApiPlatform\Metadata\Exception\ValidationException instead
*/
final class FilterValidationException extends \Exception implements ExceptionInterface, \Stringable
final class FilterValidationException extends \Exception implements ValidationExceptionInterface, ExceptionInterface, \Stringable
{
public function __construct(private readonly array $constraintViolationList, string $message = '', int $code = 0, \Exception $previous = null)
{
Expand Down
3 changes: 3 additions & 0 deletions src/ParameterValidator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/composer.lock
/vendor
/.phpunit.result.cache
32 changes: 32 additions & 0 deletions src/ParameterValidator/Exception/ValidationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\ParameterValidator\Exception;

/**
* Filter validation exception.
*
* @author Julien DENIAU <[email protected]>
*/
final class ValidationException extends \Exception implements ValidationExceptionInterface
{
public function __construct(private readonly array $constraintViolationList, string $message = '', int $code = 0, \Exception $previous = null)
{
parent::__construct($message ?: $this->__toString(), $code, $previous);
}

public function __toString(): string
{
return implode("\n", $this->constraintViolationList);
}
}
23 changes: 23 additions & 0 deletions src/ParameterValidator/Exception/ValidationExceptionInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\ParameterValidator\Exception;

use ApiPlatform\Metadata\Exception\ExceptionInterface;

/**
* This Exception is thrown when any parameter validation fails.
*/
interface ValidationExceptionInterface extends ExceptionInterface, \Stringable
{
}
56 changes: 56 additions & 0 deletions src/ParameterValidator/FilterLocatorTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\ParameterValidator;

use ApiPlatform\Exception\InvalidArgumentException;
use ApiPlatform\Metadata\FilterInterface;
use Psr\Container\ContainerInterface;

/**
* Manipulates filters with a backward compatibility between the new filter locator and the deprecated filter collection.
*
* @author Baptiste Meyer <[email protected]>
*
* @deprecated
*
* @internal
*/
trait FilterLocatorTrait
{
private ?ContainerInterface $filterLocator = null;

/**
* Sets a filter locator with a backward compatibility.
*/
private function setFilterLocator(?ContainerInterface $filterLocator, bool $allowNull = false): void
{
if ($filterLocator instanceof ContainerInterface || (null === $filterLocator && $allowNull)) {
$this->filterLocator = $filterLocator;
} else {
throw new InvalidArgumentException(sprintf('The "$filterLocator" argument is expected to be an implementation of the "%s" interface%s.', ContainerInterface::class, $allowNull ? ' or null' : ''));
}
}

/**
* Gets a filter with a backward compatibility.
*/
private function getFilter(string $filterId): null|FilterInterface
{
if ($this->filterLocator && $this->filterLocator->has($filterId)) {
return $this->filterLocator->get($filterId);
}

return null;
}
}
21 changes: 21 additions & 0 deletions src/ParameterValidator/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT license

Copyright (c) 2015-present Kévin Dunglas

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Loading

0 comments on commit 4f59677

Please sign in to comment.