Skip to content

Commit d976f4b

Browse files
committed
Merge branch '2.1' into 2.2
2 parents 6878324 + 1931348 commit d976f4b

23 files changed

+405
-45
lines changed

.php_cs.dist

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ $finder = PhpCsFixer\Finder::create()
1717
return PhpCsFixer\Config::create()
1818
->setRiskyAllowed(true)
1919
->setRules([
20+
'@DoctrineAnnotation' => true,
21+
'doctrine_annotation_array_assignment' => [
22+
'operator' => '=',
23+
],
24+
'doctrine_annotation_spaces' => [
25+
'after_array_assignments_equals' => false,
26+
'before_array_assignments_equals' => false,
27+
],
2028
'@Symfony' => true,
2129
'@Symfony:risky' => true,
2230
'array_syntax' => [

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
<tag name="serializer.normalizer" priority="16" />
3232
</service>
3333

34+
<service id="api_platform.swagger.normalizer.api_gateway" class="ApiPlatform\Core\Swagger\Serializer\ApiGatewayNormalizer" public="false" decorates="api_platform.swagger.normalizer.documentation">
35+
<argument type="service" id="api_platform.swagger.normalizer.api_gateway.inner" />
36+
<tag name="serializer.normalizer" priority="17" />
37+
</service>
38+
3439
<service id="api_platform.swagger.command.swagger_command" class="ApiPlatform\Core\Bridge\Symfony\Bundle\Command\SwaggerCommand">
3540
<argument type="service" id="api_platform.swagger.normalizer.documentation" />
3641
<argument type="service" id="api_platform.metadata.resource.name_collection_factory" />

src/Documentation/Action/DocumentationAction.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ public function __construct(ResourceNameCollectionFactoryInterface $resourceName
4242
public function __invoke(Request $request = null): Documentation
4343
{
4444
if (null !== $request) {
45-
$request->attributes->set('_api_normalization_context', $request->attributes->get('_api_normalization_context', []) + ['base_url' => $request->getBaseUrl()]);
45+
$context = ['base_url' => $request->getBaseUrl()];
46+
if ($request->query->getBoolean('api_gateway', false)) {
47+
$context['api_gateway'] = true;
48+
}
49+
$request->attributes->set('_api_normalization_context', $request->attributes->get('_api_normalization_context', []) + $context);
4650
}
4751

4852
return new Documentation($this->resourceNameCollectionFactory->create(), $this->title, $this->description, $this->version, $this->formats);
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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\Swagger\Serializer;
15+
16+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
17+
18+
/**
19+
* Removes features unsupported by Amazon API Gateway.
20+
*
21+
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html
22+
*
23+
* @internal
24+
*
25+
* @author Vincent Chalamon <[email protected]>
26+
*/
27+
final class ApiGatewayNormalizer implements NormalizerInterface
28+
{
29+
private $documentationNormalizer;
30+
31+
public function __construct(NormalizerInterface $documentationNormalizer)
32+
{
33+
$this->documentationNormalizer = $documentationNormalizer;
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
public function normalize($object, $format = null, array $context = [])
40+
{
41+
$data = $this->documentationNormalizer->normalize($object, $format, $context);
42+
if (empty($data['basePath'])) {
43+
$data['basePath'] = '/';
44+
}
45+
46+
if (!($context['api_gateway'] ?? false)) {
47+
return $data;
48+
}
49+
50+
foreach ($data['paths'] as $path => $operations) {
51+
foreach ($operations as $operation => $options) {
52+
if (isset($options['parameters'])) {
53+
foreach ($options['parameters'] as $key => $parameter) {
54+
if (!preg_match('/^[a-zA-Z0-9._$-]+$/', $parameter['name'])) {
55+
unset($data['paths'][$path][$operation]['parameters'][$key]);
56+
}
57+
if (isset($parameter['schema']['$ref']) && !preg_match('/^#\/definitions\/[A-z]+$/', $parameter['schema']['$ref'])) {
58+
$data['paths'][$path][$operation]['parameters'][$key]['schema']['$ref'] = str_replace(['-', '_'], '', $parameter['schema']['$ref']);
59+
}
60+
}
61+
$data['paths'][$path][$operation]['parameters'] = array_values($data['paths'][$path][$operation]['parameters']);
62+
}
63+
if (isset($options['responses'])) {
64+
foreach ($options['responses'] as $statusCode => $response) {
65+
if (isset($response['schema']['items']['$ref']) && !preg_match('/^#\/definitions\/[A-z]+$/', $response['schema']['items']['$ref'])) {
66+
$data['paths'][$path][$operation]['responses'][$statusCode]['schema']['items']['$ref'] = str_replace(['-', '_'], '', $response['schema']['items']['$ref']);
67+
}
68+
if (isset($response['schema']['$ref']) && !preg_match('/^#\/definitions\/[A-z]+$/', $response['schema']['$ref'])) {
69+
$data['paths'][$path][$operation]['responses'][$statusCode]['schema']['$ref'] = str_replace(['-', '_'], '', $response['schema']['$ref']);
70+
}
71+
}
72+
}
73+
}
74+
}
75+
76+
foreach ($data['definitions'] as $definition => $options) {
77+
if (!isset($options['properties'])) {
78+
continue;
79+
}
80+
foreach ($options['properties'] as $property => $propertyOptions) {
81+
if (isset($propertyOptions['readOnly'])) {
82+
unset($data['definitions'][$definition]['properties'][$property]['readOnly']);
83+
}
84+
if (isset($propertyOptions['$ref']) && !preg_match('/^#\/definitions\/[A-z]+$/', $propertyOptions['$ref'])) {
85+
$data['definitions'][$definition]['properties'][$property]['$ref'] = str_replace(['-', '_'], '', $propertyOptions['$ref']);
86+
}
87+
if (isset($propertyOptions['items']['$ref']) && !preg_match('/^#\/definitions\/[A-z]+$/', $propertyOptions['items']['$ref'])) {
88+
$data['definitions'][$definition]['properties'][$property]['items']['$ref'] = str_replace(['-', '_'], '', $propertyOptions['items']['$ref']);
89+
}
90+
}
91+
}
92+
93+
// $data['definitions'] is an instance of \ArrayObject
94+
foreach (array_keys($data['definitions']->getArrayCopy()) as $definition) {
95+
if (!preg_match('/^[A-z]+$/', $definition)) {
96+
$data['definitions'][str_replace(['-', '_'], '', $definition)] = $data['definitions'][$definition];
97+
unset($data['definitions'][$definition]);
98+
}
99+
}
100+
101+
return $data;
102+
}
103+
104+
/**
105+
* {@inheritdoc}
106+
*/
107+
public function supportsNormalization($data, $format = null)
108+
{
109+
return $this->documentationNormalizer->supportsNormalization($data, $format);
110+
}
111+
}

tests/Annotation/AnnotatedClass.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
* shortName="shortName",
2121
* description="description",
2222
* iri="http://example.com/res",
23-
* itemOperations={"foo":{"bar"}},
24-
* collectionOperations={"bar":{"foo"}},
23+
* itemOperations={"foo"={"bar"}},
24+
* collectionOperations={"bar"={"foo"}},
2525
* graphql={"query"={"normalization_context"={"groups"={"foo", "bar"}}}},
26-
* attributes={"foo":"bar"}
26+
* attributes={"foo"="bar"}
2727
* )
2828
*
2929
* @author Marcus Speight <[email protected]>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ private function getBaseContainerBuilderProphecy()
632632
'api_platform.jsonld.context_builder',
633633
'api_platform.jsonld.normalizer.item',
634634
'api_platform.swagger.normalizer.documentation',
635+
'api_platform.swagger.normalizer.api_gateway',
635636
'api_platform.swagger.command.swagger_command',
636637
'api_platform.swagger.action.ui',
637638
'api_platform.swagger.listener.ui',
@@ -670,7 +671,6 @@ private function getBaseContainerBuilderProphecy()
670671
'api_platform.problem.normalizer.error',
671672
'api_platform.swagger.action.ui',
672673
'api_platform.swagger.command.swagger_command',
673-
'api_platform.swagger.normalizer.documentation',
674674
'api_platform.http_cache.listener.response.configure',
675675
'api_platform.http_cache.purger.varnish',
676676
'api_platform.http_cache.purger.varnish_client',

tests/Documentation/Action/DocumentationActionTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use ApiPlatform\Core\Metadata\Resource\ResourceNameCollection;
2020
use PHPUnit\Framework\TestCase;
2121
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
22+
use Symfony\Component\HttpFoundation\ParameterBag;
2223
use Symfony\Component\HttpFoundation\Request;
2324

2425
/**
@@ -30,12 +31,15 @@ public function testDocumentationAction()
3031
{
3132
$requestProphecy = $this->prophesize(Request::class);
3233
$attributesProphecy = $this->prophesize(ParameterBagInterface::class);
34+
$queryProphecy = $this->prophesize(ParameterBag::class);
3335
$resourceNameCollectionFactoryProphecy = $this->prophesize(ResourceNameCollectionFactoryInterface::class);
3436
$resourceNameCollectionFactoryProphecy->create()->willReturn(new ResourceNameCollection(['dummies']));
3537
$requestProphecy->attributes = $attributesProphecy->reveal();
38+
$requestProphecy->query = $queryProphecy->reveal();
3639
$requestProphecy->getBaseUrl()->willReturn('/api')->shouldBeCalledTimes(1);
40+
$queryProphecy->getBoolean('api_gateway', false)->willReturn(true)->shouldBeCalledTimes(1);
3741
$attributesProphecy->get('_api_normalization_context', [])->willReturn(['foo' => 'bar'])->shouldBeCalledTimes(1);
38-
$attributesProphecy->set('_api_normalization_context', ['foo' => 'bar', 'base_url' => '/api'])->shouldBeCalledTimes(1);
42+
$attributesProphecy->set('_api_normalization_context', ['foo' => 'bar', 'base_url' => '/api', 'api_gateway' => true])->shouldBeCalledTimes(1);
3943
$documentation = new DocumentationAction($resourceNameCollectionFactoryProphecy->reveal(), 'My happy hippie api', 'lots of chocolate', '1.0.0', ['formats' => ['jsonld' => 'application/ld+json']]);
4044
$this->assertEquals(new Documentation(new ResourceNameCollection(['dummies']), 'My happy hippie api', 'lots of chocolate', '1.0.0', ['formats' => ['jsonld' => 'application/ld+json']]), $documentation($requestProphecy->reveal()));
4145
}

tests/Fixtures/TestBundle/Entity/AbstractDummy.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
*
2424
* @author Jérémy Derussé <[email protected]>
2525
*
26-
* @ApiResource(attributes={"filters": {"my_dummy.search", "my_dummy.order", "my_dummy.date"}})
26+
* @ApiResource(attributes={"filters"={"my_dummy.search", "my_dummy.order", "my_dummy.date"}})
2727
* @ORM\Entity
2828
* @ORM\InheritanceType("SINGLE_TABLE")
2929
* @ORM\DiscriminatorColumn(name="discr", type="string", length=16)
30-
* @ORM\DiscriminatorMap({"concrete" = "ConcreteDummy"})
30+
* @ORM\DiscriminatorMap({"concrete"="ConcreteDummy"})
3131
*/
3232
abstract class AbstractDummy
3333
{

tests/Fixtures/TestBundle/Entity/CircularReference.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*
2424
* @author Kévin Dunglas <[email protected]>
2525
*
26-
* @ApiResource(attributes={"normalization_context"={"groups": {"circular"}}})
26+
* @ApiResource(attributes={"normalization_context"={"groups"={"circular"}}})
2727
* @ORM\Entity
2828
*/
2929
class CircularReference

tests/Fixtures/TestBundle/Entity/Container.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ class Container
3535
/**
3636
* @ApiSubresource
3737
* @ORM\OneToMany(
38-
* targetEntity="Node",
39-
* mappedBy="container",
40-
* indexBy="serial",
41-
* fetch="LAZY",
42-
* cascade={},
43-
* orphanRemoval=false
38+
* targetEntity="Node",
39+
* mappedBy="container",
40+
* indexBy="serial",
41+
* fetch="LAZY",
42+
* cascade={},
43+
* orphanRemoval=false
4444
* )
4545
* @ORM\OrderBy({"serial"="ASC"})
4646
*

0 commit comments

Comments
 (0)