Skip to content

Commit d771b39

Browse files
committed
Merge branch '3.x' of github.com:FriendsOfSymfony/FOSRestBundle into 3.x
2 parents dc1aafb + d247368 commit d771b39

81 files changed

Lines changed: 1089 additions & 556 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/continuous-integration.yml

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,46 +14,75 @@ on:
1414
jobs:
1515
phpunit:
1616
name: "PHPUnit"
17-
runs-on: "ubuntu-20.04"
17+
runs-on: "ubuntu-22.04"
1818
continue-on-error: ${{ matrix.can-fail }}
1919

2020
strategy:
21+
fail-fast: false
2122
matrix:
2223
include:
23-
- php-version: 7.2
24-
composer-flags: "--prefer-lowest "
25-
can-fail: false
26-
- php-version: 7.3
27-
composer-flags: ""
24+
- php-version: "7.4"
25+
composer-flags: "--prefer-lowest"
26+
symfony-require: "5.4.*"
2827
can-fail: false
29-
- php-version: 7.4
28+
- php-version: "7.4"
3029
composer-flags: ""
31-
symfony-require: "4.4.*"
3230
can-fail: false
33-
- php-version: 7.4
31+
- php-version: "7.4"
3432
composer-flags: ""
35-
symfony-require: "5.3.*"
33+
symfony-require: "5.4.*"
3634
can-fail: false
3735
coverage: yes
38-
- php-version: 7.4
36+
- php-version: "8.0"
3937
composer-flags: ""
4038
can-fail: false
4139
symfony-require: "5.4.*"
42-
- php-version: 8.0
40+
- php-version: "8.1"
41+
composer-flags: ""
42+
can-fail: false
43+
symfony-require: "6.4.*"
44+
- php-version: "8.2"
45+
composer-flags: ""
46+
can-fail: false
47+
symfony-require: "6.4.*"
48+
- php-version: "8.3"
49+
composer-flags: ""
50+
can-fail: false
51+
symfony-require: "6.4.*"
52+
- php-version: "8.4"
4353
composer-flags: ""
4454
can-fail: false
45-
symfony-require: "6.0.*"
46-
- php-version: 8.1
55+
symfony-require: "6.4.*"
56+
- php-version: "8.3"
4757
composer-flags: ""
4858
can-fail: false
49-
symfony-require: "6.1.*"
50-
- php-version: 8.1
59+
symfony-require: "6.4.*"
60+
remove-sensio-bundle: yes # Smoke test with SensioFrameworkExtraBundle removed on latest Symfony LTS
61+
- php-version: "8.4"
5162
composer-flags: ""
5263
can-fail: false
64+
symfony-require: "6.4.*"
65+
remove-sensio-bundle: yes # Smoke test with SensioFrameworkExtraBundle removed on latest Symfony LTS
66+
- php-version: "8.2"
67+
composer-flags: ""
68+
can-fail: false
69+
symfony-require: "7.0.*"
70+
remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later
71+
- php-version: "8.3"
72+
composer-flags: ""
73+
can-fail: true # we don't want to fail the build if we are incompatible with the next (unstable) Symfony version
74+
remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later
75+
- php-version: "8.4"
76+
composer-flags: ""
77+
can-fail: true # we don't want to fail the build if we are incompatible with the next (unstable) Symfony version
78+
remove-sensio-bundle: yes # SensioFrameworkExtraBundle is not compatible with Symfony 7.0 or later
79+
80+
env:
81+
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5382

5483
steps:
5584
- name: "Checkout"
56-
uses: "actions/checkout@v3"
85+
uses: "actions/checkout@v4"
5786

5887
- name: "Install PHP with XDebug"
5988
uses: "shivammathur/setup-php@v2"
@@ -72,17 +101,23 @@ jobs:
72101
tools: "composer:v2,flex"
73102

74103
- name: "Cache dependencies installed with composer"
75-
uses: "actions/cache@v3"
104+
uses: "actions/cache@v4"
76105
with:
77106
path: "~/.composer/cache"
78107
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
79108
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
80109

110+
- name: "Remove SensioFrameworkExtraBundle if required"
111+
if: "${{ matrix.remove-sensio-bundle == 'yes' }}"
112+
env:
113+
SYMFONY_REQUIRE: "${{ matrix.symfony-require }}"
114+
run: |
115+
composer remove --no-update --dev sensio/framework-extra-bundle
116+
81117
- name: "Install dependencies with composer"
82118
env:
83119
SYMFONY_REQUIRE: "${{ matrix.symfony-require }}"
84120
run: |
85-
composer remove friendsofphp/php-cs-fixer --dev --no-update
86121
composer update --no-interaction --no-progress ${{ matrix.composer-flags }}
87122
88123
- name: "Run PHPUnit"

.php-cs-fixer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
->setRules([
1414
'psr_autoloading' => true,
1515
'header_comment' => ['header' => $header],
16+
'nullable_type_declaration_for_default_null_value' => true,
1617
])
1718
->setRiskyAllowed(true)
1819
->setFinder(

Context/Context.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public function getGroups(): ?array
111111
*
112112
* @param string[]|null $groups
113113
*/
114-
public function setGroups(array $groups = null): self
114+
public function setGroups(?array $groups = null): self
115115
{
116116
$this->groups = $groups;
117117

Controller/Annotations/FileParam.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
*
2323
* @Annotation
2424
* @NamedArgumentConstructor
25-
* @Target("METHOD")
25+
* @Target({"CLASS", "METHOD"})
2626
*
2727
* @author Ener-Getick <egetick@gmail.com>
2828
*/
29-
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)]
29+
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
3030
class FileParam extends AbstractParam
3131
{
3232
/** @var bool */

Controller/Annotations/RequestParam.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
*
1919
* @Annotation
2020
* @NamedArgumentConstructor
21-
* @Target("METHOD")
21+
* @Target({"CLASS", "METHOD"})
2222
*
2323
* @author Jordi Boggiano <j.boggiano@seld.be>
2424
* @author Boris Guéry <guery.b@gmail.com>
2525
*/
26-
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)]
26+
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
2727
class RequestParam extends AbstractScalarParam
2828
{
2929
/** @var bool */

Controller/Annotations/Route.php

Lines changed: 86 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,28 @@
1111

1212
namespace FOS\RestBundle\Controller\Annotations;
1313

14-
use Symfony\Component\Routing\Annotation\Route as BaseRoute;
14+
use Symfony\Component\Routing\Annotation\Route as BaseAnnotationRoute;
15+
use Symfony\Component\Routing\Attribute\Route as BaseAttributeRoute;
16+
17+
if (class_exists(BaseAttributeRoute::class)) {
18+
/**
19+
* Compatibility layer for Symfony 6.4 and later.
20+
*
21+
* @internal
22+
*/
23+
class CompatRoute extends BaseAttributeRoute
24+
{
25+
}
26+
} else {
27+
/**
28+
* Compatibility layer for Symfony 6.3 and earlier.
29+
*
30+
* @internal
31+
*/
32+
class CompatRoute extends BaseAnnotationRoute
33+
{
34+
}
35+
}
1536

1637
/**
1738
* Route annotation class.
@@ -21,98 +42,85 @@
2142
* @Target({"CLASS", "METHOD"})
2243
*/
2344
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
24-
class Route extends BaseRoute
45+
class Route extends CompatRoute
2546
{
47+
/**
48+
* @param array|string $data
49+
* @param array|string|null $path
50+
* @param array<string|\Stringable> $requirements
51+
* @param string[]|string $methods
52+
* @param string[]|string $schemes
53+
*
54+
* @throws \TypeError if the $data argument is an unsupported type
55+
*/
2656
public function __construct(
2757
$data = [],
2858
$path = null,
29-
string $name = null,
59+
?string $name = null,
3060
array $requirements = [],
3161
array $options = [],
3262
array $defaults = [],
33-
string $host = null,
63+
?string $host = null,
3464
$methods = [],
3565
$schemes = [],
36-
string $condition = null,
37-
int $priority = null,
38-
string $locale = null,
39-
string $format = null,
40-
bool $utf8 = null,
41-
bool $stateless = null,
42-
string $env = null
66+
?string $condition = null,
67+
?int $priority = null,
68+
?string $locale = null,
69+
?string $format = null,
70+
?bool $utf8 = null,
71+
?bool $stateless = null,
72+
?string $env = null
4373
) {
44-
// BC layer for symfony < 5.2
45-
// Before symfony/routing 5.2 the constructor only had one parameter
46-
$method = new \ReflectionMethod(BaseRoute::class, '__construct');
47-
if (1 === $method->getNumberOfParameters()) {
74+
// Use Reflection to get the constructor from the parent class two levels up (accounting for our compat definition)
75+
$method = (new \ReflectionClass($this))->getParentClass()->getParentClass()->getMethod('__construct');
76+
77+
// The $data constructor parameter was removed in Symfony 6.0 in favor of named arguments
78+
if ('data' === $method->getParameters()[0]->getName()) {
79+
parent::__construct(
80+
$data,
81+
$path,
82+
$name,
83+
$requirements,
84+
$options,
85+
$defaults,
86+
$host,
87+
$methods,
88+
$schemes,
89+
$condition,
90+
$priority,
91+
$locale,
92+
$format,
93+
$utf8,
94+
$stateless,
95+
$env
96+
);
97+
} else {
4898
if (\is_string($data)) {
49-
$path = $data;
50-
$data = [];
99+
$data = ['path' => $data];
51100
} elseif (!\is_array($data)) {
52101
throw new \TypeError(sprintf('"%s": Argument $data is expected to be a string or array, got "%s".', __METHOD__, get_debug_type($data)));
102+
} elseif (0 !== count($data) && [] === \array_intersect(\array_keys($data), ['path', 'name', 'requirements', 'options', 'defaults', 'host', 'methods', 'schemes', 'condition', 'priority', 'locale', 'format', 'utf8', 'stateless', 'env'])) {
103+
$localizedPaths = $data;
104+
$data = ['path' => $localizedPaths];
53105
}
54106

55-
$data['path'] = $path;
56-
$data['name'] = $name;
57-
$data['requirements'] = $requirements;
58-
$data['options'] = $options;
59-
$data['defaults'] = $defaults;
60-
$data['host'] = $host;
61-
$data['methods'] = $methods;
62-
$data['schemes'] = $schemes;
63-
$data['condition'] = $condition;
64-
65-
parent::__construct($data);
66-
} else {
67-
// BC layer for symfony < 6.0
68-
// The constructor parameter $data has been removed since symfony 6.0
69-
if ('data' === $method->getParameters()[0]->getName()) {
70-
parent::__construct(
71-
$data,
72-
$path,
73-
$name,
74-
$requirements,
75-
$options,
76-
$defaults,
77-
$host,
78-
$methods,
79-
$schemes,
80-
$condition,
81-
$priority,
82-
$locale,
83-
$format,
84-
$utf8,
85-
$stateless,
86-
$env
87-
);
88-
} else {
89-
if (\is_string($data)) {
90-
$data = ['path' => $data];
91-
} elseif (!\is_array($data)) {
92-
throw new \TypeError(sprintf('"%s": Argument $data is expected to be a string or array, got "%s".', __METHOD__, get_debug_type($data)));
93-
} elseif (0 !== count($data) && [] === \array_intersect(\array_keys($data), ['path', 'name', 'requirements', 'options', 'defaults', 'host', 'methods', 'schemes', 'condition', 'priority', 'locale', 'format', 'utf8', 'stateless', 'env'])) {
94-
$localizedPaths = $data;
95-
$data = ['path' => $localizedPaths];
96-
}
97-
98-
parent::__construct(
99-
$data['path'] ?? $path,
100-
$data['name'] ?? $name,
101-
$data['requirements'] ?? $requirements,
102-
$data['options'] ?? $options,
103-
$data['defaults'] ?? $defaults,
104-
$data['host'] ?? $host,
105-
$data['methods'] ?? $methods,
106-
$data['schemes'] ?? $schemes,
107-
$data['condition'] ?? $condition,
108-
$data['priority'] ?? $priority,
109-
$data['locale'] ?? $locale,
110-
$data['format'] ?? $format,
111-
$data['utf8'] ?? $utf8,
112-
$data['stateless'] ?? $stateless,
113-
$data['env'] ?? $env
114-
);
115-
}
107+
parent::__construct(
108+
$data['path'] ?? $path,
109+
$data['name'] ?? $name,
110+
$data['requirements'] ?? $requirements,
111+
$data['options'] ?? $options,
112+
$data['defaults'] ?? $defaults,
113+
$data['host'] ?? $host,
114+
$data['methods'] ?? $methods,
115+
$data['schemes'] ?? $schemes,
116+
$data['condition'] ?? $condition,
117+
$data['priority'] ?? $priority,
118+
$data['locale'] ?? $locale,
119+
$data['format'] ?? $format,
120+
$data['utf8'] ?? $utf8,
121+
$data['stateless'] ?? $stateless,
122+
$data['env'] ?? $env
123+
);
116124
}
117125

118126
if (!$this->getMethods()) {

0 commit comments

Comments
 (0)