Skip to content

Commit d16c231

Browse files
committed
Merge 3.4
2 parents f7f9f54 + 90e71f0 commit d16c231

File tree

20 files changed

+211
-42
lines changed

20 files changed

+211
-42
lines changed

features/graphql/query.feature

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,3 +664,16 @@ Feature: GraphQL query support
664664
And the header "Content-Type" should be equal to "application/json"
665665
And the JSON node "data.dummyDifferentGraphQlSerializationGroup.name" should be equal to "Name #1"
666666
And the JSON node "data.dummyDifferentGraphQlSerializationGroup.title" should be equal to "Title #1"
667+
668+
Scenario: Call security after resolver
669+
When I send the following GraphQL request:
670+
"""
671+
{
672+
getSecurityAfterResolver(id: "/security_after_resolvers/1") {
673+
name
674+
}
675+
}
676+
"""
677+
Then the response status code should be 200
678+
And the header "Content-Type" should be equal to "application/json"
679+
And the JSON node "data.getSecurityAfterResolver.name" should be equal to "test"

features/jsonld/interface_as_resource.feature

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ Feature: JSON-LD using interface as resource
1515
"code": "WONDERFUL_TAXON"
1616
}
1717
"""
18-
When I send a "GET" request to "/taxa/WONDERFUL_TAXON"
18+
When I send a "GET" request to "/taxons/WONDERFUL_TAXON"
1919
Then the response status code should be 200
2020
And the response should be in JSON
2121
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
2222
And the JSON should be equal to:
2323
"""
2424
{
2525
"@context": "/contexts/Taxon",
26-
"@id": "/taxa/WONDERFUL_TAXON",
26+
"@id": "/taxons/WONDERFUL_TAXON",
2727
"@type": "Taxon",
2828
"code": "WONDERFUL_TAXON"
2929
}
@@ -49,7 +49,7 @@ Feature: JSON-LD using interface as resource
4949
"@type": "Product",
5050
"code": "GREAT_PRODUCT",
5151
"mainTaxon": {
52-
"@id": "/taxa/WONDERFUL_TAXON",
52+
"@id": "/taxons/WONDERFUL_TAXON",
5353
"@type": "Taxon",
5454
"code": "WONDERFUL_TAXON"
5555
}

src/JsonSchema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
2020
use ApiPlatform\Metadata\ResourceClassResolverInterface;
2121
use ApiPlatform\Metadata\Util\ResourceClassInfoTrait;
22+
use Doctrine\Common\Collections\ArrayCollection;
2223
use Ramsey\Uuid\UuidInterface;
2324
use Symfony\Component\PropertyInfo\Type;
2425
use Symfony\Component\Uid\Ulid;
@@ -110,6 +111,11 @@ public function create(string $resourceClass, string $property, array $options =
110111

111112
$valueSchema = [];
112113
foreach ($types as $type) {
114+
// Temp fix for https://github.com/symfony/symfony/pull/52699
115+
if (ArrayCollection::class === $type->getClassName()) {
116+
$type = new Type($type->getBuiltinType(), $type->isNullable(), $type->getClassName(), true, $type->getCollectionKeyTypes(), $type->getCollectionValueTypes());
117+
}
118+
113119
if ($isCollection = $type->isCollection()) {
114120
$keyType = $type->getCollectionKeyTypes()[0] ?? null;
115121
$valueType = $type->getCollectionValueTypes()[0] ?? null;

src/Metadata/GraphQl/Operation.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public function __construct(
4141
protected ?array $extraArgs = null,
4242
protected ?array $links = null,
4343
protected ?bool $validateAfterResolver = null,
44+
protected ?string $securityAfterResolver = null,
45+
protected ?string $securityMessageAfterResolver = null,
4446

4547
?string $shortName = null,
4648
?string $class = null,
@@ -209,4 +211,30 @@ public function withValidateAfterResolver(bool $validateAfterResolver = true): s
209211

210212
return $self;
211213
}
214+
215+
public function getSecurityAfterResolver(): ?string
216+
{
217+
return $this->securityAfterResolver;
218+
}
219+
220+
public function withSecurityAfterResolver(string $securityAfterResolver): self
221+
{
222+
$self = clone $this;
223+
$self->securityAfterResolver = $securityAfterResolver;
224+
225+
return $self;
226+
}
227+
228+
public function getSecurityMessageAfterResolver(): ?string
229+
{
230+
return $this->securityMessageAfterResolver;
231+
}
232+
233+
public function withSecurityMessageAfterResolver(string $securityMessageAfterResolver): self
234+
{
235+
$self = clone $this;
236+
$self->securityMessageAfterResolver = $securityMessageAfterResolver;
237+
238+
return $self;
239+
}
212240
}

src/Metadata/GraphQl/Query.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public function __construct(
2424
?array $args = null,
2525
?array $extraArgs = null,
2626
?array $links = null,
27+
?string $securityAfterResolver = null,
28+
?string $securityMessageAfterResolver = null,
2729

2830
?string $shortName = null,
2931
?string $class = null,
@@ -79,6 +81,8 @@ public function __construct(
7981
args: $args,
8082
extraArgs: $extraArgs,
8183
links: $links,
84+
securityAfterResolver: $securityAfterResolver,
85+
securityMessageAfterResolver: $securityMessageAfterResolver,
8286
shortName: $shortName,
8387
class: $class,
8488
paginationEnabled: $paginationEnabled,

src/Metadata/GraphQl/QueryCollection.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public function __construct(
2525
?array $args = null,
2626
?array $extraArgs = null,
2727
?array $links = null,
28+
?string $securityAfterResolver = null,
29+
?string $securityMessageAfterResolver = null,
2830

2931
?string $shortName = null,
3032
?string $class = null,
@@ -80,6 +82,8 @@ public function __construct(
8082
args: $args,
8183
extraArgs: $extraArgs,
8284
links: $links,
85+
securityAfterResolver: $securityAfterResolver,
86+
securityMessageAfterResolver: $securityMessageAfterResolver,
8387
shortName: $shortName,
8488
class: $class,
8589
paginationEnabled: $paginationEnabled,

src/Metadata/GraphQl/Subscription.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public function __construct(
2424
?array $args = null,
2525
?array $extraArgs = null,
2626
?array $links = null,
27+
?string $securityAfterResolver = null,
28+
?string $securityMessageAfterResolver = null,
2729

2830
?string $shortName = null,
2931
?string $class = null,
@@ -77,6 +79,8 @@ public function __construct(
7779
args: $args,
7880
extraArgs: $extraArgs,
7981
links: $links,
82+
securityAfterResolver: $securityAfterResolver,
83+
securityMessageAfterResolver: $securityMessageAfterResolver,
8084
shortName: $shortName,
8185
class: $class,
8286
paginationEnabled: $paginationEnabled,

src/Metadata/Property/Factory/PropertyInfoPropertyMetadataFactory.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
use ApiPlatform\Metadata\ApiProperty;
1717
use ApiPlatform\Metadata\Exception\PropertyNotFoundException;
18+
use Doctrine\Common\Collections\ArrayCollection;
1819
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
20+
use Symfony\Component\PropertyInfo\Type;
1921

2022
/**
2123
* PropertyInfo metadata loader decorator.
@@ -44,7 +46,16 @@ public function create(string $resourceClass, string $property, array $options =
4446
}
4547

4648
if (!$propertyMetadata->getBuiltinTypes()) {
47-
$propertyMetadata = $propertyMetadata->withBuiltinTypes($this->propertyInfo->getTypes($resourceClass, $property, $options) ?? []);
49+
$types = $this->propertyInfo->getTypes($resourceClass, $property, $options) ?? [];
50+
51+
foreach ($types as $i => $type) {
52+
// Temp fix for https://github.com/symfony/symfony/pull/52699
53+
if (ArrayCollection::class === $type->getClassName()) {
54+
$types[$i] = new Type($type->getBuiltinType(), $type->isNullable(), $type->getClassName(), true, $type->getCollectionKeyTypes(), $type->getCollectionValueTypes());
55+
}
56+
}
57+
58+
$propertyMetadata = $propertyMetadata->withBuiltinTypes($types);
4859
}
4960

5061
if (null === $propertyMetadata->getDescription() && null !== $description = $this->propertyInfo->getShortDescription($resourceClass, $property, $options)) {

src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,14 @@ private function addSchemaValidation(Parameter $parameter, ?array $schema = null
156156
{
157157
$assertions = [];
158158

159-
if ($required) {
159+
if ($required && false !== ($allowEmptyValue = $openApi?->getAllowEmptyValue())) {
160160
$assertions[] = new NotNull(message: sprintf('The parameter "%s" is required.', $parameter->getKey()));
161161
}
162162

163+
if (false === ($allowEmptyValue ?? $openApi?->getAllowEmptyValue())) {
164+
$assertions[] = new NotBlank(allowNull: !$required);
165+
}
166+
163167
if (isset($schema['exclusiveMinimum'])) {
164168
$assertions[] = new GreaterThan(value: $schema['exclusiveMinimum']);
165169
}
@@ -200,10 +204,6 @@ private function addSchemaValidation(Parameter $parameter, ?array $schema = null
200204
$assertions[] = new Choice(choices: $schema['enum']);
201205
}
202206

203-
if (false === $openApi?->getAllowEmptyValue()) {
204-
$assertions[] = new NotBlank(allowNull: !$required);
205-
}
206-
207207
if (!$assertions) {
208208
return $parameter;
209209
}

src/OpenApi/Command/OpenApiCommand.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int
5656
$data = $this->normalizer->normalize($this->openApiFactory->__invoke(), 'json', [
5757
'spec_version' => $input->getOption('spec-version'),
5858
]);
59+
60+
if ($input->getOption('yaml') && !class_exists(Yaml::class)) {
61+
$output->writeln('The "symfony/yaml" component is not installed.');
62+
63+
return 1;
64+
}
65+
5966
$content = $input->getOption('yaml')
6067
? Yaml::dump($data, 10, 2, Yaml::DUMP_OBJECT_AS_MAP | Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE | Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK | Yaml::DUMP_NUMERIC_KEY_AS_STRING)
6168
: (json_encode($data, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES) ?: '');

0 commit comments

Comments
 (0)