├── src
├── Bundle
│ ├── JdeniauApiPlatformFilterValidatorBundle.php
│ ├── DependencyInjection
│ │ ├── Configuration.php
│ │ └── JdeniauApiPlatformFilterValidatorExtension.php
│ └── Resources
│ │ └── config
│ │ └── services.xml
└── FilterValidator
│ ├── Filter
│ ├── Validator
│ │ ├── ValidatorInterface.php
│ │ ├── Enum.php
│ │ ├── Pattern.php
│ │ ├── MultipleOf.php
│ │ ├── Length.php
│ │ ├── Bounds.php
│ │ ├── ArrayItems.php
│ │ └── Required.php
│ └── QueryParameterValidator.php
│ └── EventListener
│ └── QueryParameterValidateListener.php
├── README.md
├── composer.json
├── Makefile
├── .gitignore
├── LICENSE
└── composer.lock
/src/Bundle/JdeniauApiPlatformFilterValidatorBundle.php:
--------------------------------------------------------------------------------
1 |
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 ApiPlatformFilterValidator\ApiPlatform\Core\Filter\Validator;
15 |
16 | use Symfony\Component\HttpFoundation\Request;
17 |
18 | interface ValidatorInterface
19 | {
20 | public function validate(string $name, array $filterDescription, Request $request): array;
21 | }
22 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jdeniau/api-platform-filter-validator",
3 | "description": "Validate APIPlatform filter values, waiting https://github.com/api-platform/core/pull/1723 to be merged",
4 | "type": "symfony-bundle",
5 | "require": {
6 | "api-platform/core": "^2.3"
7 | },
8 | "license": "MIT",
9 | "authors": [
10 | {
11 | "name": "Julien Deniau",
12 | "email": "julien.deniau@gmail.com"
13 | }
14 | ],
15 | "autoload": {
16 | "psr-4": {
17 | "ApiPlatformFilterValidator\\ApiPlatform\\Core\\": "src/FilterValidator/",
18 | "Jdeniau\\ApiPlatformFilterValidatorBundle\\": "src/Bundle/"
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: clone extract change-namespace
2 |
3 | clean:
4 | rm -rf api-platform-core
5 | rm -rf src/FilterValidator/*
6 |
7 | clone:
8 | git clone git@github.com:jdeniau/api-platform-core.git api-platform-core --branch jd-feat-moreQueryParameterValidation
9 |
10 | extract:
11 | cd api-platform-core; \
12 | git remote add upstream git@github.com:api-platform/core; \
13 | git fetch upstream; \
14 | git diff --name-only --diff-filter=d upstream/master..HEAD src | grep -v '\.xml' | xargs -I '{}' cp --parents '{}' ../src/FilterValidator/
15 | mv src/FilterValidator/src/* src/FilterValidator
16 | rmdir src/FilterValidator/src/
17 |
18 | change-namespace:
19 | find src -type f -name '*.php' -exec sed -i 's/namespace ApiPlatform/namespace ApiPlatformFilterValidator\\ApiPlatform/g' {} \;
20 | find src -type f -name '*.php' -exec sed -i 's/use ApiPlatform/use ApiPlatformFilterValidator\\ApiPlatform/g' {} \;
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Cache and logs (Symfony2)
2 | /app/cache/*
3 | /app/logs/*
4 | !app/cache/.gitkeep
5 | !app/logs/.gitkeep
6 |
7 | # Email spool folder
8 | /app/spool/*
9 |
10 | # Cache, session files and logs (Symfony3)
11 | /var/cache/*
12 | /var/logs/*
13 | /var/sessions/*
14 | !var/cache/.gitkeep
15 | !var/logs/.gitkeep
16 | !var/sessions/.gitkeep
17 |
18 | # Parameters
19 | /app/config/parameters.yml
20 | /app/config/parameters.ini
21 |
22 | # Managed by Composer
23 | /app/bootstrap.php.cache
24 | /var/bootstrap.php.cache
25 | /bin/*
26 | !bin/console
27 | !bin/symfony_requirements
28 | /vendor/
29 |
30 | # Assets and user uploads
31 | /web/bundles/
32 | /web/uploads/
33 |
34 | # PHPUnit
35 | /app/phpunit.xml
36 | /phpunit.xml
37 |
38 | # Build data
39 | /build/
40 |
41 | # Composer PHAR
42 | /composer.phar
43 |
44 | # Backup entities generated with doctrine:generate:entities command
45 | **/Entity/*~
46 |
47 | # Embedded web-server pid file
48 | /.web-server-pid
49 |
50 | /api-platform-core/
51 |
--------------------------------------------------------------------------------
/src/Bundle/DependencyInjection/Configuration.php:
--------------------------------------------------------------------------------
1 | root('jdeniau_api_platform_filter_validator');
22 |
23 | // Here you should define the parameters that are allowed to
24 | // configure your bundle. See the documentation linked above for
25 | // more information on that topic.
26 |
27 | return $treeBuilder;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Bundle/DependencyInjection/JdeniauApiPlatformFilterValidatorExtension.php:
--------------------------------------------------------------------------------
1 | processConfiguration($configuration, $configs);
24 |
25 | $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
26 | $loader->load('services.xml');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Julien Deniau
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/FilterValidator/Filter/Validator/Enum.php:
--------------------------------------------------------------------------------
1 |
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 ApiPlatformFilterValidator\ApiPlatform\Core\Filter\Validator;
15 |
16 | use Symfony\Component\HttpFoundation\Request;
17 |
18 | class Enum implements ValidatorInterface
19 | {
20 | public function validate(string $name, array $filterDescription, Request $request): array
21 | {
22 | $value = $request->query->get($name);
23 | if (empty($value) && '0' !== $value || !\is_string($value)) {
24 | return [];
25 | }
26 |
27 | $enum = $filterDescription['swagger']['enum'] ?? null;
28 |
29 | if (null !== $enum && !\in_array($value, $enum, true)) {
30 | return [
31 | \sprintf('Query parameter "%s" must be one of "%s"', $name, implode(', ', $enum)),
32 | ];
33 | }
34 |
35 | return [];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Bundle/Resources/config/services.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/FilterValidator/Filter/Validator/Pattern.php:
--------------------------------------------------------------------------------
1 |
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 ApiPlatformFilterValidator\ApiPlatform\Core\Filter\Validator;
15 |
16 | use Symfony\Component\HttpFoundation\Request;
17 |
18 | class Pattern implements ValidatorInterface
19 | {
20 | public function validate(string $name, array $filterDescription, Request $request): array
21 | {
22 | $value = $request->query->get($name);
23 | if (empty($value) && '0' !== $value || !\is_string($value)) {
24 | return [];
25 | }
26 |
27 | $pattern = $filterDescription['swagger']['pattern'] ?? null;
28 |
29 | if (null !== $pattern && !preg_match($pattern, $value)) {
30 | return [
31 | \sprintf('Query parameter "%s" must match pattern %s', $name, $pattern),
32 | ];
33 | }
34 |
35 | return [];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/FilterValidator/Filter/Validator/MultipleOf.php:
--------------------------------------------------------------------------------
1 |
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 ApiPlatformFilterValidator\ApiPlatform\Core\Filter\Validator;
15 |
16 | use Symfony\Component\HttpFoundation\Request;
17 |
18 | class MultipleOf implements ValidatorInterface
19 | {
20 | public function validate(string $name, array $filterDescription, Request $request): array
21 | {
22 | $value = $request->query->get($name);
23 | if (empty($value) && '0' !== $value || !\is_string($value)) {
24 | return [];
25 | }
26 |
27 | $multipleOf = $filterDescription['swagger']['multipleOf'] ?? null;
28 |
29 | if (null !== $multipleOf && 0 !== ($value % $multipleOf)) {
30 | return [
31 | \sprintf('Query parameter "%s" must multiple of %s', $name, $multipleOf),
32 | ];
33 | }
34 |
35 | return [];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/FilterValidator/Filter/Validator/Length.php:
--------------------------------------------------------------------------------
1 |
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 ApiPlatformFilterValidator\ApiPlatform\Core\Filter\Validator;
15 |
16 | use Symfony\Component\HttpFoundation\Request;
17 |
18 | class Length implements ValidatorInterface
19 | {
20 | public function validate(string $name, array $filterDescription, Request $request): array
21 | {
22 | $maxLength = $filterDescription['swagger']['maxLength'] ?? null;
23 | $minLength = $filterDescription['swagger']['minLength'] ?? null;
24 |
25 | $value = $request->query->get($name);
26 | if (empty($value) && '0' !== $value || !\is_string($value)) {
27 | return [];
28 | }
29 |
30 | $errorList = [];
31 |
32 | if (null !== $maxLength && mb_strlen($value) > $maxLength) {
33 | $errorList[] = \sprintf('Query parameter "%s" length must be lower than or equal to %s', $name, $maxLength);
34 | }
35 |
36 | if (null !== $minLength && mb_strlen($value) < $minLength) {
37 | $errorList[] = \sprintf('Query parameter "%s" length must be greater than or equal to %s', $name, $minLength);
38 | }
39 |
40 | return $errorList;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/FilterValidator/Filter/Validator/Bounds.php:
--------------------------------------------------------------------------------
1 |
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 ApiPlatformFilterValidator\ApiPlatform\Core\Filter\Validator;
15 |
16 | use Symfony\Component\HttpFoundation\Request;
17 |
18 | class Bounds implements ValidatorInterface
19 | {
20 | public function validate(string $name, array $filterDescription, Request $request): array
21 | {
22 | $value = $request->query->get($name);
23 | if (empty($value) && '0' !== $value) {
24 | return [];
25 | }
26 |
27 | $maximum = $filterDescription['swagger']['maximum'] ?? null;
28 | $minimum = $filterDescription['swagger']['minimum'] ?? null;
29 |
30 | $errorList = [];
31 |
32 | if (null !== $maximum) {
33 | if (($filterDescription['swagger']['exclusiveMaximum'] ?? false) && $value >= $maximum) {
34 | $errorList[] = \sprintf('Query parameter "%s" must be less than %s', $name, $maximum);
35 | } elseif ($value > $maximum) {
36 | $errorList[] = \sprintf('Query parameter "%s" must be less than or equal to %s', $name, $maximum);
37 | }
38 | }
39 |
40 | if (null !== $minimum) {
41 | if (($filterDescription['swagger']['exclusiveMinimum'] ?? false) && $value <= $minimum) {
42 | $errorList[] = \sprintf('Query parameter "%s" must be greater than %s', $name, $minimum);
43 | } elseif ($value < $minimum) {
44 | $errorList[] = \sprintf('Query parameter "%s" must be greater than or equal to %s', $name, $minimum);
45 | }
46 | }
47 |
48 | return $errorList;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/FilterValidator/Filter/QueryParameterValidator.php:
--------------------------------------------------------------------------------
1 |
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 ApiPlatformFilterValidator\ApiPlatform\Core\Filter;
15 |
16 | use ApiPlatform\Core\Api\FilterLocatorTrait;
17 | use ApiPlatform\Core\Exception\FilterValidationException;
18 | use Psr\Container\ContainerInterface;
19 | use Symfony\Component\HttpFoundation\Request;
20 |
21 | /**
22 | * Validates query parameters depending on filter description.
23 | *
24 | * @author Julien Deniau
25 | */
26 | class QueryParameterValidator
27 | {
28 | use FilterLocatorTrait;
29 |
30 | private $validators;
31 |
32 | public function __construct(ContainerInterface $filterLocator)
33 | {
34 | $this->setFilterLocator($filterLocator);
35 |
36 | $this->validators = [
37 | new Validator\ArrayItems(),
38 | new Validator\Bounds(),
39 | new Validator\Enum(),
40 | new Validator\Length(),
41 | new Validator\MultipleOf(),
42 | new Validator\Pattern(),
43 | new Validator\Required(),
44 | ];
45 | }
46 |
47 | public function validateFilters(string $resourceClass, array $resourceFilters, Request $request)
48 | {
49 | $errorList = [];
50 | foreach ($resourceFilters as $filterId) {
51 | if (!$filter = $this->getFilter($filterId)) {
52 | continue;
53 | }
54 |
55 | foreach ($filter->getDescription($resourceClass) as $name => $data) {
56 | foreach ($this->validators as $validator) {
57 | $errorList = \array_merge($errorList, $validator->validate($name, $data, $request));
58 | }
59 | }
60 | }
61 |
62 | if ($errorList) {
63 | throw new FilterValidationException($errorList);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/FilterValidator/EventListener/QueryParameterValidateListener.php:
--------------------------------------------------------------------------------
1 |
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 ApiPlatformFilterValidator\ApiPlatform\Core\EventListener;
15 |
16 | use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
17 | use ApiPlatform\Core\Util\RequestAttributesExtractor;
18 | use ApiPlatformFilterValidator\ApiPlatform\Core\Filter\QueryParameterValidator;
19 | use Symfony\Component\HttpKernel\Event\GetResponseEvent;
20 |
21 | /**
22 | * Validates query parameters depending on filter description.
23 | *
24 | * @author Julien Deniau
25 | */
26 | final class QueryParameterValidateListener
27 | {
28 | private $resourceMetadataFactory;
29 |
30 | private $queryParameterValidator;
31 |
32 | public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, QueryParameterValidator $queryParameterValidator)
33 | {
34 | $this->resourceMetadataFactory = $resourceMetadataFactory;
35 | $this->queryParameterValidator = $queryParameterValidator;
36 | }
37 |
38 | public function onKernelRequest(GetResponseEvent $event)
39 | {
40 | $request = $event->getRequest();
41 | if (
42 | !$request->isMethodSafe(false)
43 | || !($attributes = RequestAttributesExtractor::extractAttributes($request))
44 | || !isset($attributes['collection_operation_name'])
45 | || !($operationName = $attributes['collection_operation_name'])
46 | || $request->getMethod() != 'GET'
47 | ) {
48 | return;
49 | }
50 |
51 | $resourceMetadata = $this->resourceMetadataFactory->create($attributes['resource_class']);
52 | $resourceFilters = $resourceMetadata->getCollectionOperationAttribute($operationName, 'filters', [], true);
53 |
54 | $this->queryParameterValidator->validateFilters($attributes['resource_class'], $resourceFilters, $request);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/FilterValidator/Filter/Validator/ArrayItems.php:
--------------------------------------------------------------------------------
1 |
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 ApiPlatformFilterValidator\ApiPlatform\Core\Filter\Validator;
15 |
16 | use Symfony\Component\HttpFoundation\Request;
17 |
18 | class ArrayItems implements ValidatorInterface
19 | {
20 | public function validate(string $name, array $filterDescription, Request $request): array
21 | {
22 | if (!$request->query->has($name)) {
23 | return [];
24 | }
25 |
26 | $maxItems = $filterDescription['swagger']['maxItems'] ?? null;
27 | $minItems = $filterDescription['swagger']['minItems'] ?? null;
28 | $uniqueItems = $filterDescription['swagger']['uniqueItems'] ?? false;
29 |
30 | $errorList = [];
31 |
32 | $value = $this->getValue($name, $filterDescription, $request);
33 | $nbItems = \count($value);
34 |
35 | if (null !== $maxItems && $nbItems > $maxItems) {
36 | $errorList[] = \sprintf('Query parameter "%s" must contain less than %d values', $name, $maxItems);
37 | }
38 |
39 | if (null !== $minItems && $nbItems < $minItems) {
40 | $errorList[] = \sprintf('Query parameter "%s" must contain more than %d values', $name, $minItems);
41 | }
42 |
43 | if (true === $uniqueItems && $nbItems > \count(array_unique($value))) {
44 | $errorList[] = \sprintf('Query parameter "%s" must contain unique values', $name);
45 | }
46 |
47 | return $errorList;
48 | }
49 |
50 | private function getValue(string $name, array $filterDescription, Request $request): array
51 | {
52 | $value = $request->query->get($name);
53 |
54 | if (empty($value) && '0' !== $value) {
55 | return [];
56 | }
57 |
58 | if (\is_array($value)) {
59 | return $value;
60 | }
61 |
62 | $collectionFormat = $filterDescription['swagger']['collectionFormat'] ?? 'csv';
63 |
64 | return explode(self::getSeparator($collectionFormat), $value) ?: [];
65 | }
66 |
67 | private static function getSeparator(string $collectionFormat): string
68 | {
69 | switch ($collectionFormat) {
70 | case 'csv':
71 | return ',';
72 | case 'ssv':
73 | return ' ';
74 | case 'tsv':
75 | return '\t';
76 | case 'pipes':
77 | return '|';
78 | default:
79 | throw new \InvalidArgumentException(sprintf('Unknown collection format %s', $collectionFormat));
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/FilterValidator/Filter/Validator/Required.php:
--------------------------------------------------------------------------------
1 |
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 ApiPlatformFilterValidator\ApiPlatform\Core\Filter\Validator;
15 |
16 | use Symfony\Component\HttpFoundation\Request;
17 |
18 | class Required implements ValidatorInterface
19 | {
20 | public function validate(string $name, array $filterDescription, Request $request): array
21 | {
22 | // filter is not required, the `checkRequired` method can not break
23 | if (!($filterDescription['required'] ?? false)) {
24 | return [];
25 | }
26 |
27 | // if query param is not given, then break
28 | if (!$this->requestHasQueryParameter($request, $name)) {
29 | return [
30 | \sprintf('Query parameter "%s" is required', $name),
31 | ];
32 | }
33 |
34 | // if query param is empty and the configuration does not allow it
35 | if (!($filterDescription['swagger']['allowEmptyValue'] ?? false) && empty($this->requestGetQueryParameter($request, $name))) {
36 | return [
37 | \sprintf('Query parameter "%s" does not allow empty value', $name),
38 | ];
39 | }
40 |
41 | return [];
42 | }
43 |
44 | /**
45 | * Test if request has required parameter.
46 | */
47 | private function requestHasQueryParameter(Request $request, string $name): bool
48 | {
49 | $matches = [];
50 | parse_str($name, $matches);
51 | if (!$matches) {
52 | return false;
53 | }
54 |
55 | $rootName = \array_keys($matches)[0] ?? '';
56 | if (!$rootName) {
57 | return false;
58 | }
59 |
60 | if (\is_array($matches[$rootName])) {
61 | $keyName = \array_keys($matches[$rootName])[0];
62 |
63 | $queryParameter = $request->query->get((string) $rootName);
64 |
65 | return \is_array($queryParameter) && isset($queryParameter[$keyName]);
66 | }
67 |
68 | return $request->query->has((string) $rootName);
69 | }
70 |
71 | /**
72 | * Test if required filter is valid. It validates array notation too like "required[bar]".
73 | */
74 | private function requestGetQueryParameter(Request $request, string $name)
75 | {
76 | $matches = [];
77 | \parse_str($name, $matches);
78 | if (empty($matches)) {
79 | return null;
80 | }
81 |
82 | $rootName = \array_keys($matches)[0] ?? '';
83 | if (!$rootName) {
84 | return null;
85 | }
86 |
87 | if (\is_array($matches[$rootName])) {
88 | $keyName = \array_keys($matches[$rootName])[0];
89 |
90 | $queryParameter = $request->query->get((string) $rootName);
91 |
92 | if (\is_array($queryParameter) && isset($queryParameter[$keyName])) {
93 | return $queryParameter[$keyName];
94 | }
95 |
96 | return null;
97 | }
98 |
99 | return $request->query->get((string) $rootName);
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "915c8d21de95f2e873a3ce5be8b1a6f9",
8 | "packages": [
9 | {
10 | "name": "api-platform/core",
11 | "version": "v2.3.6",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/api-platform/core.git",
15 | "reference": "f12aa2ae9ee67e7c948cd3161ad980d35210bed7"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/api-platform/core/zipball/f12aa2ae9ee67e7c948cd3161ad980d35210bed7",
20 | "reference": "f12aa2ae9ee67e7c948cd3161ad980d35210bed7",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "doctrine/inflector": "^1.0",
25 | "php": ">=7.1",
26 | "psr/cache": "^1.0",
27 | "psr/container": "^1.0",
28 | "symfony/http-foundation": "^3.4 || ^4.0",
29 | "symfony/http-kernel": "^3.4 || ^4.0",
30 | "symfony/property-access": "^3.4 || ^4.0",
31 | "symfony/property-info": "^3.4 || ^4.0",
32 | "symfony/serializer": "^4.1",
33 | "willdurand/negotiation": "^2.0.3"
34 | },
35 | "conflict": {
36 | "doctrine/common": "<2.7"
37 | },
38 | "require-dev": {
39 | "behat/behat": "^3.1",
40 | "behat/mink": "^1.7",
41 | "behat/mink-browserkit-driver": "^1.3.1",
42 | "behat/mink-extension": "^2.2",
43 | "behat/symfony2-extension": "^2.1.1",
44 | "behatch/contexts": "3.1.0",
45 | "doctrine/annotations": "^1.2",
46 | "doctrine/doctrine-bundle": "^1.8",
47 | "doctrine/orm": "^2.6.3",
48 | "friendsofsymfony/user-bundle": "^2.1",
49 | "guzzlehttp/guzzle": "^6.0",
50 | "justinrainbow/json-schema": "^5.0",
51 | "nelmio/api-doc-bundle": "^2.13.3",
52 | "php-mock/php-mock-phpunit": "^2.0",
53 | "phpdocumentor/reflection-docblock": "^3.0 || ^4.0",
54 | "phpdocumentor/type-resolver": "^0.3 || ^0.4",
55 | "phpunit/phpunit": "^6.1",
56 | "psr/log": "^1.0",
57 | "ramsey/uuid": "^3.7",
58 | "ramsey/uuid-doctrine": "^1.4",
59 | "symfony/asset": "^3.4 || ^4.0",
60 | "symfony/cache": "^3.4 || ^4.0",
61 | "symfony/config": "^3.4 || ^4.0",
62 | "symfony/console": "^3.4 || ^4.0",
63 | "symfony/debug": "^3.4 || ^4.0",
64 | "symfony/dependency-injection": "^3.4 || ^4.0",
65 | "symfony/doctrine-bridge": "^3.4 || ^4.0",
66 | "symfony/event-dispatcher": "^3.4 || ^4.0",
67 | "symfony/expression-language": "^3.4 || ^4.0",
68 | "symfony/finder": "^3.4 || ^4.0",
69 | "symfony/form": "^3.4 || ^4.0",
70 | "symfony/framework-bundle": "^3.4 || ^4.0",
71 | "symfony/phpunit-bridge": "^3.4 || ^4.0",
72 | "symfony/routing": "^3.4 || ^4.0",
73 | "symfony/security": "^3.4 || ^4.0",
74 | "symfony/security-bundle": "^3.4 || ^4.0",
75 | "symfony/twig-bundle": "^3.4 || ^4.0",
76 | "symfony/validator": "^3.4 || ^4.0",
77 | "symfony/web-profiler-bundle": "^3.4 || ^4.0",
78 | "symfony/yaml": "^3.4 || ^4.0",
79 | "webonyx/graphql-php": ">=0.13 <1.0"
80 | },
81 | "suggest": {
82 | "friendsofsymfony/user-bundle": "To use the FOSUserBundle bridge.",
83 | "guzzlehttp/guzzle": "To use the HTTP cache invalidation system.",
84 | "phpdocumentor/reflection-docblock": "To support extracting metadata from PHPDoc.",
85 | "psr/cache-implementation": "To use metadata caching.",
86 | "ramsey/uuid": "To support Ramsey's UUID identifiers.",
87 | "symfony/cache": "To have metadata caching when using Symfony integration.",
88 | "symfony/config": "To load XML configuration files.",
89 | "symfony/expression-language": "To use authorization features.",
90 | "symfony/security": "To use authorization features.",
91 | "symfony/twig-bundle": "To use the Swagger UI integration.",
92 | "symfony/web-profiler-bundle": "To use the data collector.",
93 | "webonyx/graphql-php": "To support GraphQL."
94 | },
95 | "type": "library",
96 | "extra": {
97 | "branch-alias": {
98 | "dev-master": "2.3.x-dev"
99 | }
100 | },
101 | "autoload": {
102 | "psr-4": {
103 | "ApiPlatform\\Core\\": "src/"
104 | }
105 | },
106 | "notification-url": "https://packagist.org/downloads/",
107 | "license": [
108 | "MIT"
109 | ],
110 | "authors": [
111 | {
112 | "name": "Kévin Dunglas",
113 | "email": "dunglas@gmail.com",
114 | "homepage": "https://dunglas.fr"
115 | }
116 | ],
117 | "description": "Build a fully-featured hypermedia or GraphQL API in minutes",
118 | "homepage": "https://api-platform.com",
119 | "keywords": [
120 | "Hydra",
121 | "JSON-LD",
122 | "api",
123 | "graphql",
124 | "hal",
125 | "jsonapi",
126 | "openapi",
127 | "rest",
128 | "swagger"
129 | ],
130 | "time": "2019-01-15T16:10:35+00:00"
131 | },
132 | {
133 | "name": "doctrine/inflector",
134 | "version": "v1.3.0",
135 | "source": {
136 | "type": "git",
137 | "url": "https://github.com/doctrine/inflector.git",
138 | "reference": "5527a48b7313d15261292c149e55e26eae771b0a"
139 | },
140 | "dist": {
141 | "type": "zip",
142 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a",
143 | "reference": "5527a48b7313d15261292c149e55e26eae771b0a",
144 | "shasum": ""
145 | },
146 | "require": {
147 | "php": "^7.1"
148 | },
149 | "require-dev": {
150 | "phpunit/phpunit": "^6.2"
151 | },
152 | "type": "library",
153 | "extra": {
154 | "branch-alias": {
155 | "dev-master": "1.3.x-dev"
156 | }
157 | },
158 | "autoload": {
159 | "psr-4": {
160 | "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector"
161 | }
162 | },
163 | "notification-url": "https://packagist.org/downloads/",
164 | "license": [
165 | "MIT"
166 | ],
167 | "authors": [
168 | {
169 | "name": "Roman Borschel",
170 | "email": "roman@code-factory.org"
171 | },
172 | {
173 | "name": "Benjamin Eberlei",
174 | "email": "kontakt@beberlei.de"
175 | },
176 | {
177 | "name": "Guilherme Blanco",
178 | "email": "guilhermeblanco@gmail.com"
179 | },
180 | {
181 | "name": "Jonathan Wage",
182 | "email": "jonwage@gmail.com"
183 | },
184 | {
185 | "name": "Johannes Schmitt",
186 | "email": "schmittjoh@gmail.com"
187 | }
188 | ],
189 | "description": "Common String Manipulations with regard to casing and singular/plural rules.",
190 | "homepage": "http://www.doctrine-project.org",
191 | "keywords": [
192 | "inflection",
193 | "pluralize",
194 | "singularize",
195 | "string"
196 | ],
197 | "time": "2018-01-09T20:05:19+00:00"
198 | },
199 | {
200 | "name": "psr/cache",
201 | "version": "1.0.1",
202 | "source": {
203 | "type": "git",
204 | "url": "https://github.com/php-fig/cache.git",
205 | "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
206 | },
207 | "dist": {
208 | "type": "zip",
209 | "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
210 | "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
211 | "shasum": ""
212 | },
213 | "require": {
214 | "php": ">=5.3.0"
215 | },
216 | "type": "library",
217 | "extra": {
218 | "branch-alias": {
219 | "dev-master": "1.0.x-dev"
220 | }
221 | },
222 | "autoload": {
223 | "psr-4": {
224 | "Psr\\Cache\\": "src/"
225 | }
226 | },
227 | "notification-url": "https://packagist.org/downloads/",
228 | "license": [
229 | "MIT"
230 | ],
231 | "authors": [
232 | {
233 | "name": "PHP-FIG",
234 | "homepage": "http://www.php-fig.org/"
235 | }
236 | ],
237 | "description": "Common interface for caching libraries",
238 | "keywords": [
239 | "cache",
240 | "psr",
241 | "psr-6"
242 | ],
243 | "time": "2016-08-06T20:24:11+00:00"
244 | },
245 | {
246 | "name": "psr/container",
247 | "version": "1.0.0",
248 | "source": {
249 | "type": "git",
250 | "url": "https://github.com/php-fig/container.git",
251 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
252 | },
253 | "dist": {
254 | "type": "zip",
255 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
256 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
257 | "shasum": ""
258 | },
259 | "require": {
260 | "php": ">=5.3.0"
261 | },
262 | "type": "library",
263 | "extra": {
264 | "branch-alias": {
265 | "dev-master": "1.0.x-dev"
266 | }
267 | },
268 | "autoload": {
269 | "psr-4": {
270 | "Psr\\Container\\": "src/"
271 | }
272 | },
273 | "notification-url": "https://packagist.org/downloads/",
274 | "license": [
275 | "MIT"
276 | ],
277 | "authors": [
278 | {
279 | "name": "PHP-FIG",
280 | "homepage": "http://www.php-fig.org/"
281 | }
282 | ],
283 | "description": "Common Container Interface (PHP FIG PSR-11)",
284 | "homepage": "https://github.com/php-fig/container",
285 | "keywords": [
286 | "PSR-11",
287 | "container",
288 | "container-interface",
289 | "container-interop",
290 | "psr"
291 | ],
292 | "time": "2017-02-14T16:28:37+00:00"
293 | },
294 | {
295 | "name": "psr/log",
296 | "version": "1.1.0",
297 | "source": {
298 | "type": "git",
299 | "url": "https://github.com/php-fig/log.git",
300 | "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
301 | },
302 | "dist": {
303 | "type": "zip",
304 | "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
305 | "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
306 | "shasum": ""
307 | },
308 | "require": {
309 | "php": ">=5.3.0"
310 | },
311 | "type": "library",
312 | "extra": {
313 | "branch-alias": {
314 | "dev-master": "1.0.x-dev"
315 | }
316 | },
317 | "autoload": {
318 | "psr-4": {
319 | "Psr\\Log\\": "Psr/Log/"
320 | }
321 | },
322 | "notification-url": "https://packagist.org/downloads/",
323 | "license": [
324 | "MIT"
325 | ],
326 | "authors": [
327 | {
328 | "name": "PHP-FIG",
329 | "homepage": "http://www.php-fig.org/"
330 | }
331 | ],
332 | "description": "Common interface for logging libraries",
333 | "homepage": "https://github.com/php-fig/log",
334 | "keywords": [
335 | "log",
336 | "psr",
337 | "psr-3"
338 | ],
339 | "time": "2018-11-20T15:27:04+00:00"
340 | },
341 | {
342 | "name": "symfony/contracts",
343 | "version": "v1.0.2",
344 | "source": {
345 | "type": "git",
346 | "url": "https://github.com/symfony/contracts.git",
347 | "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf"
348 | },
349 | "dist": {
350 | "type": "zip",
351 | "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf",
352 | "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf",
353 | "shasum": ""
354 | },
355 | "require": {
356 | "php": "^7.1.3"
357 | },
358 | "require-dev": {
359 | "psr/cache": "^1.0",
360 | "psr/container": "^1.0"
361 | },
362 | "suggest": {
363 | "psr/cache": "When using the Cache contracts",
364 | "psr/container": "When using the Service contracts",
365 | "symfony/cache-contracts-implementation": "",
366 | "symfony/service-contracts-implementation": "",
367 | "symfony/translation-contracts-implementation": ""
368 | },
369 | "type": "library",
370 | "extra": {
371 | "branch-alias": {
372 | "dev-master": "1.0-dev"
373 | }
374 | },
375 | "autoload": {
376 | "psr-4": {
377 | "Symfony\\Contracts\\": ""
378 | },
379 | "exclude-from-classmap": [
380 | "**/Tests/"
381 | ]
382 | },
383 | "notification-url": "https://packagist.org/downloads/",
384 | "license": [
385 | "MIT"
386 | ],
387 | "authors": [
388 | {
389 | "name": "Nicolas Grekas",
390 | "email": "p@tchwork.com"
391 | },
392 | {
393 | "name": "Symfony Community",
394 | "homepage": "https://symfony.com/contributors"
395 | }
396 | ],
397 | "description": "A set of abstractions extracted out of the Symfony components",
398 | "homepage": "https://symfony.com",
399 | "keywords": [
400 | "abstractions",
401 | "contracts",
402 | "decoupling",
403 | "interfaces",
404 | "interoperability",
405 | "standards"
406 | ],
407 | "time": "2018-12-05T08:06:11+00:00"
408 | },
409 | {
410 | "name": "symfony/debug",
411 | "version": "v4.2.2",
412 | "source": {
413 | "type": "git",
414 | "url": "https://github.com/symfony/debug.git",
415 | "reference": "64cb33c81e37d19b7715d4a6a4d49c1c382066dd"
416 | },
417 | "dist": {
418 | "type": "zip",
419 | "url": "https://api.github.com/repos/symfony/debug/zipball/64cb33c81e37d19b7715d4a6a4d49c1c382066dd",
420 | "reference": "64cb33c81e37d19b7715d4a6a4d49c1c382066dd",
421 | "shasum": ""
422 | },
423 | "require": {
424 | "php": "^7.1.3",
425 | "psr/log": "~1.0"
426 | },
427 | "conflict": {
428 | "symfony/http-kernel": "<3.4"
429 | },
430 | "require-dev": {
431 | "symfony/http-kernel": "~3.4|~4.0"
432 | },
433 | "type": "library",
434 | "extra": {
435 | "branch-alias": {
436 | "dev-master": "4.2-dev"
437 | }
438 | },
439 | "autoload": {
440 | "psr-4": {
441 | "Symfony\\Component\\Debug\\": ""
442 | },
443 | "exclude-from-classmap": [
444 | "/Tests/"
445 | ]
446 | },
447 | "notification-url": "https://packagist.org/downloads/",
448 | "license": [
449 | "MIT"
450 | ],
451 | "authors": [
452 | {
453 | "name": "Fabien Potencier",
454 | "email": "fabien@symfony.com"
455 | },
456 | {
457 | "name": "Symfony Community",
458 | "homepage": "https://symfony.com/contributors"
459 | }
460 | ],
461 | "description": "Symfony Debug Component",
462 | "homepage": "https://symfony.com",
463 | "time": "2019-01-03T09:07:35+00:00"
464 | },
465 | {
466 | "name": "symfony/event-dispatcher",
467 | "version": "v4.2.2",
468 | "source": {
469 | "type": "git",
470 | "url": "https://github.com/symfony/event-dispatcher.git",
471 | "reference": "887de6d34c86cf0cb6cbf910afb170cdb743cb5e"
472 | },
473 | "dist": {
474 | "type": "zip",
475 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/887de6d34c86cf0cb6cbf910afb170cdb743cb5e",
476 | "reference": "887de6d34c86cf0cb6cbf910afb170cdb743cb5e",
477 | "shasum": ""
478 | },
479 | "require": {
480 | "php": "^7.1.3",
481 | "symfony/contracts": "^1.0"
482 | },
483 | "conflict": {
484 | "symfony/dependency-injection": "<3.4"
485 | },
486 | "require-dev": {
487 | "psr/log": "~1.0",
488 | "symfony/config": "~3.4|~4.0",
489 | "symfony/dependency-injection": "~3.4|~4.0",
490 | "symfony/expression-language": "~3.4|~4.0",
491 | "symfony/stopwatch": "~3.4|~4.0"
492 | },
493 | "suggest": {
494 | "symfony/dependency-injection": "",
495 | "symfony/http-kernel": ""
496 | },
497 | "type": "library",
498 | "extra": {
499 | "branch-alias": {
500 | "dev-master": "4.2-dev"
501 | }
502 | },
503 | "autoload": {
504 | "psr-4": {
505 | "Symfony\\Component\\EventDispatcher\\": ""
506 | },
507 | "exclude-from-classmap": [
508 | "/Tests/"
509 | ]
510 | },
511 | "notification-url": "https://packagist.org/downloads/",
512 | "license": [
513 | "MIT"
514 | ],
515 | "authors": [
516 | {
517 | "name": "Fabien Potencier",
518 | "email": "fabien@symfony.com"
519 | },
520 | {
521 | "name": "Symfony Community",
522 | "homepage": "https://symfony.com/contributors"
523 | }
524 | ],
525 | "description": "Symfony EventDispatcher Component",
526 | "homepage": "https://symfony.com",
527 | "time": "2019-01-05T16:37:49+00:00"
528 | },
529 | {
530 | "name": "symfony/http-foundation",
531 | "version": "v4.2.2",
532 | "source": {
533 | "type": "git",
534 | "url": "https://github.com/symfony/http-foundation.git",
535 | "reference": "a633d422a09242064ba24e44a6e1494c5126de86"
536 | },
537 | "dist": {
538 | "type": "zip",
539 | "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a633d422a09242064ba24e44a6e1494c5126de86",
540 | "reference": "a633d422a09242064ba24e44a6e1494c5126de86",
541 | "shasum": ""
542 | },
543 | "require": {
544 | "php": "^7.1.3",
545 | "symfony/polyfill-mbstring": "~1.1"
546 | },
547 | "require-dev": {
548 | "predis/predis": "~1.0",
549 | "symfony/expression-language": "~3.4|~4.0"
550 | },
551 | "type": "library",
552 | "extra": {
553 | "branch-alias": {
554 | "dev-master": "4.2-dev"
555 | }
556 | },
557 | "autoload": {
558 | "psr-4": {
559 | "Symfony\\Component\\HttpFoundation\\": ""
560 | },
561 | "exclude-from-classmap": [
562 | "/Tests/"
563 | ]
564 | },
565 | "notification-url": "https://packagist.org/downloads/",
566 | "license": [
567 | "MIT"
568 | ],
569 | "authors": [
570 | {
571 | "name": "Fabien Potencier",
572 | "email": "fabien@symfony.com"
573 | },
574 | {
575 | "name": "Symfony Community",
576 | "homepage": "https://symfony.com/contributors"
577 | }
578 | ],
579 | "description": "Symfony HttpFoundation Component",
580 | "homepage": "https://symfony.com",
581 | "time": "2019-01-05T16:37:49+00:00"
582 | },
583 | {
584 | "name": "symfony/http-kernel",
585 | "version": "v4.2.2",
586 | "source": {
587 | "type": "git",
588 | "url": "https://github.com/symfony/http-kernel.git",
589 | "reference": "83de6543328917c18d5498eeb6bb6d36f7aab31b"
590 | },
591 | "dist": {
592 | "type": "zip",
593 | "url": "https://api.github.com/repos/symfony/http-kernel/zipball/83de6543328917c18d5498eeb6bb6d36f7aab31b",
594 | "reference": "83de6543328917c18d5498eeb6bb6d36f7aab31b",
595 | "shasum": ""
596 | },
597 | "require": {
598 | "php": "^7.1.3",
599 | "psr/log": "~1.0",
600 | "symfony/contracts": "^1.0.2",
601 | "symfony/debug": "~3.4|~4.0",
602 | "symfony/event-dispatcher": "~4.1",
603 | "symfony/http-foundation": "^4.1.1",
604 | "symfony/polyfill-ctype": "~1.8"
605 | },
606 | "conflict": {
607 | "symfony/config": "<3.4",
608 | "symfony/dependency-injection": "<4.2",
609 | "symfony/translation": "<4.2",
610 | "symfony/var-dumper": "<4.1.1",
611 | "twig/twig": "<1.34|<2.4,>=2"
612 | },
613 | "provide": {
614 | "psr/log-implementation": "1.0"
615 | },
616 | "require-dev": {
617 | "psr/cache": "~1.0",
618 | "symfony/browser-kit": "~3.4|~4.0",
619 | "symfony/config": "~3.4|~4.0",
620 | "symfony/console": "~3.4|~4.0",
621 | "symfony/css-selector": "~3.4|~4.0",
622 | "symfony/dependency-injection": "^4.2",
623 | "symfony/dom-crawler": "~3.4|~4.0",
624 | "symfony/expression-language": "~3.4|~4.0",
625 | "symfony/finder": "~3.4|~4.0",
626 | "symfony/process": "~3.4|~4.0",
627 | "symfony/routing": "~3.4|~4.0",
628 | "symfony/stopwatch": "~3.4|~4.0",
629 | "symfony/templating": "~3.4|~4.0",
630 | "symfony/translation": "~4.2",
631 | "symfony/var-dumper": "^4.1.1"
632 | },
633 | "suggest": {
634 | "symfony/browser-kit": "",
635 | "symfony/config": "",
636 | "symfony/console": "",
637 | "symfony/dependency-injection": "",
638 | "symfony/var-dumper": ""
639 | },
640 | "type": "library",
641 | "extra": {
642 | "branch-alias": {
643 | "dev-master": "4.2-dev"
644 | }
645 | },
646 | "autoload": {
647 | "psr-4": {
648 | "Symfony\\Component\\HttpKernel\\": ""
649 | },
650 | "exclude-from-classmap": [
651 | "/Tests/"
652 | ]
653 | },
654 | "notification-url": "https://packagist.org/downloads/",
655 | "license": [
656 | "MIT"
657 | ],
658 | "authors": [
659 | {
660 | "name": "Fabien Potencier",
661 | "email": "fabien@symfony.com"
662 | },
663 | {
664 | "name": "Symfony Community",
665 | "homepage": "https://symfony.com/contributors"
666 | }
667 | ],
668 | "description": "Symfony HttpKernel Component",
669 | "homepage": "https://symfony.com",
670 | "time": "2019-01-06T16:19:23+00:00"
671 | },
672 | {
673 | "name": "symfony/inflector",
674 | "version": "v4.2.2",
675 | "source": {
676 | "type": "git",
677 | "url": "https://github.com/symfony/inflector.git",
678 | "reference": "9f64271222922ef1a10e43f77d88baf72bf22b0e"
679 | },
680 | "dist": {
681 | "type": "zip",
682 | "url": "https://api.github.com/repos/symfony/inflector/zipball/9f64271222922ef1a10e43f77d88baf72bf22b0e",
683 | "reference": "9f64271222922ef1a10e43f77d88baf72bf22b0e",
684 | "shasum": ""
685 | },
686 | "require": {
687 | "php": "^7.1.3",
688 | "symfony/polyfill-ctype": "~1.8"
689 | },
690 | "type": "library",
691 | "extra": {
692 | "branch-alias": {
693 | "dev-master": "4.2-dev"
694 | }
695 | },
696 | "autoload": {
697 | "psr-4": {
698 | "Symfony\\Component\\Inflector\\": ""
699 | },
700 | "exclude-from-classmap": [
701 | "/Tests/"
702 | ]
703 | },
704 | "notification-url": "https://packagist.org/downloads/",
705 | "license": [
706 | "MIT"
707 | ],
708 | "authors": [
709 | {
710 | "name": "Bernhard Schussek",
711 | "email": "bschussek@gmail.com"
712 | },
713 | {
714 | "name": "Symfony Community",
715 | "homepage": "https://symfony.com/contributors"
716 | }
717 | ],
718 | "description": "Symfony Inflector Component",
719 | "homepage": "https://symfony.com",
720 | "keywords": [
721 | "inflection",
722 | "pluralize",
723 | "singularize",
724 | "string",
725 | "symfony",
726 | "words"
727 | ],
728 | "time": "2019-01-03T09:07:35+00:00"
729 | },
730 | {
731 | "name": "symfony/polyfill-ctype",
732 | "version": "v1.10.0",
733 | "source": {
734 | "type": "git",
735 | "url": "https://github.com/symfony/polyfill-ctype.git",
736 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
737 | },
738 | "dist": {
739 | "type": "zip",
740 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
741 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
742 | "shasum": ""
743 | },
744 | "require": {
745 | "php": ">=5.3.3"
746 | },
747 | "suggest": {
748 | "ext-ctype": "For best performance"
749 | },
750 | "type": "library",
751 | "extra": {
752 | "branch-alias": {
753 | "dev-master": "1.9-dev"
754 | }
755 | },
756 | "autoload": {
757 | "psr-4": {
758 | "Symfony\\Polyfill\\Ctype\\": ""
759 | },
760 | "files": [
761 | "bootstrap.php"
762 | ]
763 | },
764 | "notification-url": "https://packagist.org/downloads/",
765 | "license": [
766 | "MIT"
767 | ],
768 | "authors": [
769 | {
770 | "name": "Symfony Community",
771 | "homepage": "https://symfony.com/contributors"
772 | },
773 | {
774 | "name": "Gert de Pagter",
775 | "email": "backendtea@gmail.com"
776 | }
777 | ],
778 | "description": "Symfony polyfill for ctype functions",
779 | "homepage": "https://symfony.com",
780 | "keywords": [
781 | "compatibility",
782 | "ctype",
783 | "polyfill",
784 | "portable"
785 | ],
786 | "time": "2018-08-06T14:22:27+00:00"
787 | },
788 | {
789 | "name": "symfony/polyfill-mbstring",
790 | "version": "v1.10.0",
791 | "source": {
792 | "type": "git",
793 | "url": "https://github.com/symfony/polyfill-mbstring.git",
794 | "reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
795 | },
796 | "dist": {
797 | "type": "zip",
798 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
799 | "reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
800 | "shasum": ""
801 | },
802 | "require": {
803 | "php": ">=5.3.3"
804 | },
805 | "suggest": {
806 | "ext-mbstring": "For best performance"
807 | },
808 | "type": "library",
809 | "extra": {
810 | "branch-alias": {
811 | "dev-master": "1.9-dev"
812 | }
813 | },
814 | "autoload": {
815 | "psr-4": {
816 | "Symfony\\Polyfill\\Mbstring\\": ""
817 | },
818 | "files": [
819 | "bootstrap.php"
820 | ]
821 | },
822 | "notification-url": "https://packagist.org/downloads/",
823 | "license": [
824 | "MIT"
825 | ],
826 | "authors": [
827 | {
828 | "name": "Nicolas Grekas",
829 | "email": "p@tchwork.com"
830 | },
831 | {
832 | "name": "Symfony Community",
833 | "homepage": "https://symfony.com/contributors"
834 | }
835 | ],
836 | "description": "Symfony polyfill for the Mbstring extension",
837 | "homepage": "https://symfony.com",
838 | "keywords": [
839 | "compatibility",
840 | "mbstring",
841 | "polyfill",
842 | "portable",
843 | "shim"
844 | ],
845 | "time": "2018-09-21T13:07:52+00:00"
846 | },
847 | {
848 | "name": "symfony/property-access",
849 | "version": "v4.2.2",
850 | "source": {
851 | "type": "git",
852 | "url": "https://github.com/symfony/property-access.git",
853 | "reference": "a21d40670000f61a1a4b90a607d54696aad914cd"
854 | },
855 | "dist": {
856 | "type": "zip",
857 | "url": "https://api.github.com/repos/symfony/property-access/zipball/a21d40670000f61a1a4b90a607d54696aad914cd",
858 | "reference": "a21d40670000f61a1a4b90a607d54696aad914cd",
859 | "shasum": ""
860 | },
861 | "require": {
862 | "php": "^7.1.3",
863 | "symfony/inflector": "~3.4|~4.0"
864 | },
865 | "require-dev": {
866 | "symfony/cache": "~3.4|~4.0"
867 | },
868 | "suggest": {
869 | "psr/cache-implementation": "To cache access methods."
870 | },
871 | "type": "library",
872 | "extra": {
873 | "branch-alias": {
874 | "dev-master": "4.2-dev"
875 | }
876 | },
877 | "autoload": {
878 | "psr-4": {
879 | "Symfony\\Component\\PropertyAccess\\": ""
880 | },
881 | "exclude-from-classmap": [
882 | "/Tests/"
883 | ]
884 | },
885 | "notification-url": "https://packagist.org/downloads/",
886 | "license": [
887 | "MIT"
888 | ],
889 | "authors": [
890 | {
891 | "name": "Fabien Potencier",
892 | "email": "fabien@symfony.com"
893 | },
894 | {
895 | "name": "Symfony Community",
896 | "homepage": "https://symfony.com/contributors"
897 | }
898 | ],
899 | "description": "Symfony PropertyAccess Component",
900 | "homepage": "https://symfony.com",
901 | "keywords": [
902 | "access",
903 | "array",
904 | "extraction",
905 | "index",
906 | "injection",
907 | "object",
908 | "property",
909 | "property path",
910 | "reflection"
911 | ],
912 | "time": "2019-01-05T16:37:49+00:00"
913 | },
914 | {
915 | "name": "symfony/property-info",
916 | "version": "v4.2.2",
917 | "source": {
918 | "type": "git",
919 | "url": "https://github.com/symfony/property-info.git",
920 | "reference": "cfb42283015c194d14917f4dc108df7efc63fa4a"
921 | },
922 | "dist": {
923 | "type": "zip",
924 | "url": "https://api.github.com/repos/symfony/property-info/zipball/cfb42283015c194d14917f4dc108df7efc63fa4a",
925 | "reference": "cfb42283015c194d14917f4dc108df7efc63fa4a",
926 | "shasum": ""
927 | },
928 | "require": {
929 | "php": "^7.1.3",
930 | "symfony/inflector": "~3.4|~4.0"
931 | },
932 | "conflict": {
933 | "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2",
934 | "phpdocumentor/type-resolver": "<0.3.0",
935 | "symfony/dependency-injection": "<3.4"
936 | },
937 | "require-dev": {
938 | "doctrine/annotations": "~1.0",
939 | "phpdocumentor/reflection-docblock": "^3.0|^4.0",
940 | "symfony/cache": "~3.4|~4.0",
941 | "symfony/dependency-injection": "~3.4|~4.0",
942 | "symfony/serializer": "~3.4|~4.0"
943 | },
944 | "suggest": {
945 | "phpdocumentor/reflection-docblock": "To use the PHPDoc",
946 | "psr/cache-implementation": "To cache results",
947 | "symfony/doctrine-bridge": "To use Doctrine metadata",
948 | "symfony/serializer": "To use Serializer metadata"
949 | },
950 | "type": "library",
951 | "extra": {
952 | "branch-alias": {
953 | "dev-master": "4.2-dev"
954 | }
955 | },
956 | "autoload": {
957 | "psr-4": {
958 | "Symfony\\Component\\PropertyInfo\\": ""
959 | },
960 | "exclude-from-classmap": [
961 | "/Tests/"
962 | ]
963 | },
964 | "notification-url": "https://packagist.org/downloads/",
965 | "license": [
966 | "MIT"
967 | ],
968 | "authors": [
969 | {
970 | "name": "Kévin Dunglas",
971 | "email": "dunglas@gmail.com"
972 | },
973 | {
974 | "name": "Symfony Community",
975 | "homepage": "https://symfony.com/contributors"
976 | }
977 | ],
978 | "description": "Symfony Property Info Component",
979 | "homepage": "https://symfony.com",
980 | "keywords": [
981 | "doctrine",
982 | "phpdoc",
983 | "property",
984 | "symfony",
985 | "type",
986 | "validator"
987 | ],
988 | "time": "2019-01-03T09:07:35+00:00"
989 | },
990 | {
991 | "name": "symfony/serializer",
992 | "version": "v4.2.2",
993 | "source": {
994 | "type": "git",
995 | "url": "https://github.com/symfony/serializer.git",
996 | "reference": "0e696a2a8ce2648a8b1074fc9aedd9fdd328ba77"
997 | },
998 | "dist": {
999 | "type": "zip",
1000 | "url": "https://api.github.com/repos/symfony/serializer/zipball/0e696a2a8ce2648a8b1074fc9aedd9fdd328ba77",
1001 | "reference": "0e696a2a8ce2648a8b1074fc9aedd9fdd328ba77",
1002 | "shasum": ""
1003 | },
1004 | "require": {
1005 | "php": "^7.1.3",
1006 | "symfony/polyfill-ctype": "~1.8"
1007 | },
1008 | "conflict": {
1009 | "phpdocumentor/type-resolver": "<0.2.1",
1010 | "symfony/dependency-injection": "<3.4",
1011 | "symfony/property-access": "<3.4",
1012 | "symfony/property-info": "<3.4",
1013 | "symfony/yaml": "<3.4"
1014 | },
1015 | "require-dev": {
1016 | "doctrine/annotations": "~1.0",
1017 | "doctrine/cache": "~1.0",
1018 | "phpdocumentor/reflection-docblock": "^3.0|^4.0",
1019 | "symfony/cache": "~3.4|~4.0",
1020 | "symfony/config": "~3.4|~4.0",
1021 | "symfony/dependency-injection": "~3.4|~4.0",
1022 | "symfony/http-foundation": "~3.4|~4.0",
1023 | "symfony/property-access": "~3.4|~4.0",
1024 | "symfony/property-info": "~3.4|~4.0",
1025 | "symfony/validator": "~3.4|~4.0",
1026 | "symfony/yaml": "~3.4|~4.0"
1027 | },
1028 | "suggest": {
1029 | "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
1030 | "doctrine/cache": "For using the default cached annotation reader and metadata cache.",
1031 | "psr/cache-implementation": "For using the metadata cache.",
1032 | "symfony/config": "For using the XML mapping loader.",
1033 | "symfony/http-foundation": "To use the DataUriNormalizer.",
1034 | "symfony/property-access": "For using the ObjectNormalizer.",
1035 | "symfony/property-info": "To deserialize relations.",
1036 | "symfony/yaml": "For using the default YAML mapping loader."
1037 | },
1038 | "type": "library",
1039 | "extra": {
1040 | "branch-alias": {
1041 | "dev-master": "4.2-dev"
1042 | }
1043 | },
1044 | "autoload": {
1045 | "psr-4": {
1046 | "Symfony\\Component\\Serializer\\": ""
1047 | },
1048 | "exclude-from-classmap": [
1049 | "/Tests/"
1050 | ]
1051 | },
1052 | "notification-url": "https://packagist.org/downloads/",
1053 | "license": [
1054 | "MIT"
1055 | ],
1056 | "authors": [
1057 | {
1058 | "name": "Fabien Potencier",
1059 | "email": "fabien@symfony.com"
1060 | },
1061 | {
1062 | "name": "Symfony Community",
1063 | "homepage": "https://symfony.com/contributors"
1064 | }
1065 | ],
1066 | "description": "Symfony Serializer Component",
1067 | "homepage": "https://symfony.com",
1068 | "time": "2019-01-03T09:07:35+00:00"
1069 | },
1070 | {
1071 | "name": "willdurand/negotiation",
1072 | "version": "v2.3.1",
1073 | "source": {
1074 | "type": "git",
1075 | "url": "https://github.com/willdurand/Negotiation.git",
1076 | "reference": "03436ededa67c6e83b9b12defac15384cb399dc9"
1077 | },
1078 | "dist": {
1079 | "type": "zip",
1080 | "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/03436ededa67c6e83b9b12defac15384cb399dc9",
1081 | "reference": "03436ededa67c6e83b9b12defac15384cb399dc9",
1082 | "shasum": ""
1083 | },
1084 | "require": {
1085 | "php": ">=5.4.0"
1086 | },
1087 | "require-dev": {
1088 | "phpunit/phpunit": "~4.5"
1089 | },
1090 | "type": "library",
1091 | "extra": {
1092 | "branch-alias": {
1093 | "dev-master": "2.3-dev"
1094 | }
1095 | },
1096 | "autoload": {
1097 | "psr-4": {
1098 | "Negotiation\\": "src/Negotiation"
1099 | }
1100 | },
1101 | "notification-url": "https://packagist.org/downloads/",
1102 | "license": [
1103 | "MIT"
1104 | ],
1105 | "authors": [
1106 | {
1107 | "name": "William Durand",
1108 | "email": "will+git@drnd.me"
1109 | }
1110 | ],
1111 | "description": "Content Negotiation tools for PHP provided as a standalone library.",
1112 | "homepage": "http://williamdurand.fr/Negotiation/",
1113 | "keywords": [
1114 | "accept",
1115 | "content",
1116 | "format",
1117 | "header",
1118 | "negotiation"
1119 | ],
1120 | "time": "2017-05-14T17:21:12+00:00"
1121 | }
1122 | ],
1123 | "packages-dev": [],
1124 | "aliases": [],
1125 | "minimum-stability": "stable",
1126 | "stability-flags": [],
1127 | "prefer-stable": false,
1128 | "prefer-lowest": false,
1129 | "platform": [],
1130 | "platform-dev": []
1131 | }
1132 |
--------------------------------------------------------------------------------