Skip to content

Commit 5d7aa1f

Browse files
Merge remote-tracking branch 'upstream/2.7' into main
2 parents 955dfcc + f2c8a61 commit 5d7aa1f

19 files changed

+545
-16
lines changed

.php-cs-fixer.dist.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
->exclude([
1717
'src/Core/Bridge/Symfony/Maker/Resources/skeleton',
1818
'tests/Fixtures/app/var',
19+
'tests/Fixtures/Symfony/Maker',
1920
])
2021
->notPath('src/Symfony/Bundle/DependencyInjection/Configuration.php')
2122
->notPath('src/Annotation/ApiFilter.php') // temporary

features/jsonld/iri_only.feature

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ Feature: JSON-LD using iri_only parameter
33
As a Vulcain user and as a developer
44
I should be able to only get an IRI list when I ask a resource.
55

6-
Scenario: Retrieve Dummy's resource context with iri_only
7-
When I send a "GET" request to "/contexts/IriOnlyDummy"
6+
Scenario Outline: Retrieve Dummy's resource context with iri_only
7+
When I send a "GET" request to "<uri>"
88
Then the response status code should be 200
99
And the response should be in JSON
1010
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
@@ -20,6 +20,14 @@ Feature: JSON-LD using iri_only parameter
2020
}
2121
}
2222
"""
23+
Examples:
24+
| uri |
25+
| /contexts/IriOnlyDummy |
26+
| /contexts/IriOnlyDummy.jsonld |
27+
28+
Scenario: Retrieve Dummy's resource context with invalid format returns an error
29+
When I send a "GET" request to "/contexts/IriOnlyDummy.json"
30+
Then the response status code should be 404
2331

2432
@createSchema
2533
Scenario: Retrieve Dummies with iri_only and jsonld_embed_context

features/main/sub_resource.feature

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ Feature: Sub-resource support
108108
"hydra:totalItems": 2,
109109
"hydra:search": {
110110
"@type": "hydra:IriTemplate",
111-
"hydra:template": "/dummies/1/related_dummies{?relatedToDummyFriend.dummyFriend,relatedToDummyFriend.dummyFriend[],name,age,age[]}",
111+
"hydra:template": "/dummies/1/related_dummies{?relatedToDummyFriend.dummyFriend,relatedToDummyFriend.dummyFriend[],name,age,age[],id,id[],symfony,symfony[],dummyDate[before],dummyDate[strictly_before],dummyDate[after],dummyDate[strictly_after]}",
112112
"hydra:variableRepresentation": "BasicRepresentation",
113113
"hydra:mapping": [
114114
{
@@ -140,6 +140,54 @@ Feature: Sub-resource support
140140
"variable": "age[]",
141141
"property": "age",
142142
"required": false
143+
},
144+
{
145+
"@type": "IriTemplateMapping",
146+
"variable": "id",
147+
"property": "id",
148+
"required": false
149+
},
150+
{
151+
"@type": "IriTemplateMapping",
152+
"variable": "id[]",
153+
"property": "id",
154+
"required": false
155+
},
156+
{
157+
"@type": "IriTemplateMapping",
158+
"variable": "symfony",
159+
"property": "symfony",
160+
"required": false
161+
},
162+
{
163+
"@type": "IriTemplateMapping",
164+
"variable": "symfony[]",
165+
"property": "symfony",
166+
"required": false
167+
},
168+
{
169+
"@type": "IriTemplateMapping",
170+
"variable": "dummyDate[before]",
171+
"property": "dummyDate",
172+
"required": false
173+
},
174+
{
175+
"@type": "IriTemplateMapping",
176+
"variable": "dummyDate[strictly_before]",
177+
"property": "dummyDate",
178+
"required": false
179+
},
180+
{
181+
"@type": "IriTemplateMapping",
182+
"variable": "dummyDate[after]",
183+
"property": "dummyDate",
184+
"required": false
185+
},
186+
{
187+
"@type": "IriTemplateMapping",
188+
"variable": "dummyDate[strictly_after]",
189+
"property": "dummyDate",
190+
"required": false
143191
}
144192
]
145193
}
@@ -185,7 +233,7 @@ Feature: Sub-resource support
185233
},
186234
"hydra:search": {
187235
"@type": "hydra:IriTemplate",
188-
"hydra:template": "/dummies/1/related_dummies{?relatedToDummyFriend.dummyFriend,relatedToDummyFriend.dummyFriend[],name,age,age[]}",
236+
"hydra:template": "/dummies/1/related_dummies{?relatedToDummyFriend.dummyFriend,relatedToDummyFriend.dummyFriend[],name,age,age[],id,id[],symfony,symfony[],dummyDate[before],dummyDate[strictly_before],dummyDate[after],dummyDate[strictly_after]}",
189237
"hydra:variableRepresentation": "BasicRepresentation",
190238
"hydra:mapping": [
191239
{
@@ -217,6 +265,54 @@ Feature: Sub-resource support
217265
"variable": "age[]",
218266
"property": "age",
219267
"required": false
268+
},
269+
{
270+
"@type": "IriTemplateMapping",
271+
"variable": "id",
272+
"property": "id",
273+
"required": false
274+
},
275+
{
276+
"@type": "IriTemplateMapping",
277+
"variable": "id[]",
278+
"property": "id",
279+
"required": false
280+
},
281+
{
282+
"@type": "IriTemplateMapping",
283+
"variable": "symfony",
284+
"property": "symfony",
285+
"required": false
286+
},
287+
{
288+
"@type": "IriTemplateMapping",
289+
"variable": "symfony[]",
290+
"property": "symfony",
291+
"required": false
292+
},
293+
{
294+
"@type": "IriTemplateMapping",
295+
"variable": "dummyDate[before]",
296+
"property": "dummyDate",
297+
"required": false
298+
},
299+
{
300+
"@type": "IriTemplateMapping",
301+
"variable": "dummyDate[strictly_before]",
302+
"property": "dummyDate",
303+
"required": false
304+
},
305+
{
306+
"@type": "IriTemplateMapping",
307+
"variable": "dummyDate[after]",
308+
"property": "dummyDate",
309+
"required": false
310+
},
311+
{
312+
"@type": "IriTemplateMapping",
313+
"variable": "dummyDate[strictly_after]",
314+
"property": "dummyDate",
315+
"required": false
220316
}
221317
]
222318
}

phpstan.neon.dist

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ parameters:
1717
- tests/Fixtures/app/AppKernel.php
1818
excludePaths:
1919
# Symfony cache
20-
- tests/Fixtures/app/var/cache
20+
- tests/Fixtures/app/var/
21+
- tests/Fixtures/Symfony/Maker
2122
# BC layer
2223
- src/deprecated_interfaces.php
2324
- tests/Fixtures/TestBundle/BrowserKit/Client.php
@@ -30,7 +31,7 @@ parameters:
3031
- tests/Symfony/Bundle/Test/WebTestCaseTest.php
3132
- tests/Fixtures/TestBundle/Security/AbstractSecurityUser.php
3233
# Templates for Maker
33-
- src/Bridge/Symfony/Maker/Resources/skeleton
34+
- src/Symfony/Maker/Resources/skeleton
3435
earlyTerminatingMethodCalls:
3536
PHPUnit\Framework\Constraint\Constraint:
3637
- fail

src/Symfony/Bundle/Resources/config/maker.xml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
66

77
<services>
8-
<!-- <service id="api_platform.maker.command.data_provider" class="ApiPlatform\Core\Bridge\Symfony\Maker\MakeDataProvider"> -->
9-
<!-- <argument type="service" id="api_platform.metadata.resource.name_collection_factory" /> -->
10-
<!-- <tag name="maker.command" /> -->
11-
<!-- </service> -->
12-
<!-- -->
13-
<!-- <service id="api_platform.maker.command.data_persister" class="ApiPlatform\Core\Bridge\Symfony\Maker\MakeDataPersister"> -->
14-
<!-- <argument type="service" id="api_platform.metadata.resource.name_collection_factory" /> -->
15-
<!-- <tag name="maker.command" /> -->
16-
<!-- </service> -->
8+
<service id="api_platform.maker.command.state_processor" class="ApiPlatform\Symfony\Maker\MakeStateProcessor">
9+
<argument type="service" id="api_platform.metadata.resource.name_collection_factory" />
10+
<tag name="maker.command" />
11+
</service>
12+
13+
<service id="api_platform.maker.command.state_provider" class="ApiPlatform\Symfony\Maker\MakeStateProvider">
14+
<argument type="service" id="api_platform.metadata.resource.name_collection_factory" />
15+
<tag name="maker.command" />
16+
</service>
1717
</services>
1818

1919
</container>

src/Symfony/Bundle/Resources/config/routing/jsonld.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
<default key="_format">jsonld</default>
1111
<default key="_api_respond">true</default>
1212

13-
<requirement key="shortName">.+</requirement>
13+
<requirement key="shortName">[^.]+</requirement>
14+
<requirement key="_format">jsonld</requirement>
1415
</route>
1516

1617
</routes>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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\Symfony\Maker;
15+
16+
use Symfony\Bundle\MakerBundle\ConsoleStyle;
17+
use Symfony\Bundle\MakerBundle\DependencyBuilder;
18+
use Symfony\Bundle\MakerBundle\Generator;
19+
use Symfony\Bundle\MakerBundle\InputConfiguration;
20+
use Symfony\Bundle\MakerBundle\Maker\AbstractMaker;
21+
use Symfony\Component\Console\Command\Command;
22+
use Symfony\Component\Console\Input\InputArgument;
23+
use Symfony\Component\Console\Input\InputInterface;
24+
25+
final class MakeStateProcessor extends AbstractMaker
26+
{
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
public static function getCommandName(): string
31+
{
32+
return 'make:state-processor';
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public static function getCommandDescription(): string
39+
{
40+
return 'Creates an API Platform state processor';
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
public function configureCommand(Command $command, InputConfiguration $inputConfig)
47+
{
48+
$command
49+
->addArgument('name', InputArgument::REQUIRED, 'Choose a class name for your state processor (e.g. <fg=yellow>AwesomeStateProcessor</>)')
50+
->setHelp(file_get_contents(__DIR__.'/Resources/help/MakeStateProcessor.txt'));
51+
}
52+
53+
/**
54+
* {@inheritdoc}
55+
*/
56+
public function configureDependencies(DependencyBuilder $dependencies)
57+
{
58+
}
59+
60+
/**
61+
* {@inheritdoc}
62+
*/
63+
public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator)
64+
{
65+
$stateProcessorClassNameDetails = $generator->createClassNameDetails(
66+
$input->getArgument('name'),
67+
'State\\'
68+
);
69+
70+
$generator->generateClass(
71+
$stateProcessorClassNameDetails->getFullName(),
72+
__DIR__.'/Resources/skeleton/StateProcessor.tpl.php'
73+
);
74+
$generator->writeChanges();
75+
76+
$this->writeSuccessMessage($io);
77+
$io->text([
78+
'Next: Open your new state processor class and start customizing it.',
79+
]);
80+
}
81+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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\Symfony\Maker;
15+
16+
use Symfony\Bundle\MakerBundle\ConsoleStyle;
17+
use Symfony\Bundle\MakerBundle\DependencyBuilder;
18+
use Symfony\Bundle\MakerBundle\Generator;
19+
use Symfony\Bundle\MakerBundle\InputConfiguration;
20+
use Symfony\Bundle\MakerBundle\Maker\AbstractMaker;
21+
use Symfony\Component\Console\Command\Command;
22+
use Symfony\Component\Console\Input\InputArgument;
23+
use Symfony\Component\Console\Input\InputInterface;
24+
25+
final class MakeStateProvider extends AbstractMaker
26+
{
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
public static function getCommandName(): string
31+
{
32+
return 'make:state-provider';
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public static function getCommandDescription(): string
39+
{
40+
return 'Creates an API Platform state provider';
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
public function configureCommand(Command $command, InputConfiguration $inputConfig)
47+
{
48+
$command
49+
->addArgument('name', InputArgument::REQUIRED, 'Choose a class name for your state provider (e.g. <fg=yellow>AwesomeStateProvider</>)')
50+
->setHelp(file_get_contents(__DIR__.'/Resources/help/MakeStateProvider.txt'));
51+
}
52+
53+
/**
54+
* {@inheritdoc}
55+
*/
56+
public function configureDependencies(DependencyBuilder $dependencies)
57+
{
58+
}
59+
60+
/**
61+
* {@inheritdoc}
62+
*/
63+
public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator)
64+
{
65+
$stateProviderClassNameDetails = $generator->createClassNameDetails(
66+
$input->getArgument('name'),
67+
'State\\'
68+
);
69+
70+
$generator->generateClass(
71+
$stateProviderClassNameDetails->getFullName(),
72+
__DIR__.'/Resources/skeleton/StateProvider.tpl.php'
73+
);
74+
$generator->writeChanges();
75+
76+
$this->writeSuccessMessage($io);
77+
$io->text([
78+
'Next: Open your new state provider class and start customizing it.',
79+
]);
80+
}
81+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The <info>%command.name%</info> command generates a new API Platform state processor class.
2+
3+
<info>php %command.full_name% AwesomeStateProcessor</info>
4+
5+
If the argument is missing, the command will ask for the class name interactively.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The <info>%command.name%</info> command generates a new API Platform state provider class.
2+
3+
<info>php %command.full_name% AwesomeStateProvider</info>
4+
5+
If the argument is missing, the command will ask for the class name interactively.

0 commit comments

Comments
 (0)