Skip to content

Commit 525ec95

Browse files
santysisinicolas-grekas
authored andcommitted
[Routing] allow setting multiple envs in #[Route] attribute
1 parent b317ccd commit 525ec95

File tree

6 files changed

+60
-7
lines changed

6 files changed

+60
-7
lines changed

UPGRADE-7.4.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ Mime
6464

6565
* Deprecate implementing `__sleep/wakeup()` on `AbstractPart` implementations; use `__(un)serialize()` instead
6666

67+
Routing
68+
-------
69+
70+
* Deprecate `getEnv()` and `setEnv()` methods of the `Symfony\Component\Routing\Attribute\Route` class in favor of the plurialized `getEnvs()` and `setEnvs()` methods
71+
6772
Security
6873
--------
6974

src/Symfony/Component/Routing/Attribute/Route.php

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Routing\Attribute;
1313

14+
use Symfony\Component\Routing\Exception\LogicException;
15+
1416
/**
1517
* @author Fabien Potencier <fabien@symfony.com>
1618
* @author Alexander M. Turek <me@derrabus.de>
@@ -21,6 +23,8 @@ class Route
2123
private ?string $path = null;
2224
private array $localizedPaths = [];
2325
private array $methods;
26+
/** @var string[] */
27+
private array $env;
2428
private array $schemes;
2529
/**
2630
* @var (string|DeprecatedAlias)[]
@@ -42,7 +46,7 @@ class Route
4246
* @param string|null $format The format returned by the route (i.e. "json", "xml")
4347
* @param bool|null $utf8 Whether the route accepts UTF-8 in its parameters
4448
* @param bool|null $stateless Whether the route is defined as stateless or stateful, @see https://symfony.com/doc/current/routing.html#stateless-routes
45-
* @param string|null $env The env in which the route is defined (i.e. "dev", "test", "prod")
49+
* @param string|string[]|null $env The env(s) in which the route is defined (i.e. "dev", "test", "prod", ["dev", "test"])
4650
* @param string|DeprecatedAlias|(string|DeprecatedAlias)[] $alias The list of aliases for this route
4751
*/
4852
public function __construct(
@@ -60,7 +64,7 @@ public function __construct(
6064
?string $format = null,
6165
?bool $utf8 = null,
6266
?bool $stateless = null,
63-
private ?string $env = null,
67+
string|array|null $env = null,
6468
string|DeprecatedAlias|array $alias = [],
6569
) {
6670
if (\is_array($path)) {
@@ -71,6 +75,7 @@ public function __construct(
7175
$this->setMethods($methods);
7276
$this->setSchemes($schemes);
7377
$this->setAliases($alias);
78+
$this->setEnvs((array) $env);
7479

7580
if (null !== $locale) {
7681
$this->defaults['_locale'] = $locale;
@@ -199,12 +204,37 @@ public function getPriority(): ?int
199204
return $this->priority;
200205
}
201206

207+
/**
208+
* @deprecated since Symfony 7.4, use the {@see setEnvs()} method instead
209+
*/
202210
public function setEnv(?string $env): void
203211
{
204-
$this->env = $env;
212+
trigger_deprecation('symfony/routing', '7.4', 'The "%s()" method is deprecated, use "setEnvs()" instead.', __METHOD__);
213+
$this->env = (array) $env;
205214
}
206215

216+
/**
217+
* @deprecated since Symfony 7.4, use {@see getEnvs()} method instead
218+
*/
207219
public function getEnv(): ?string
220+
{
221+
trigger_deprecation('symfony/routing', '7.4', 'The "%s()" method is deprecated, use "getEnvs()" instead.', __METHOD__);
222+
if (!$this->env) {
223+
return null;
224+
}
225+
if (\count($this->env) > 1) {
226+
throw new LogicException(\sprintf('The "env" property has %d environments. Use "getEnvs()" to get all of them.', \count($this->env)));
227+
}
228+
229+
return $this->env[0];
230+
}
231+
232+
public function setEnvs(array|string $env): void
233+
{
234+
$this->env = (array) $env;
235+
}
236+
237+
public function getEnvs(): array
208238
{
209239
return $this->env;
210240
}

src/Symfony/Component/Routing/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Allow query-specific parameters in `UrlGenerator` using `_query`
8+
* Add support of multiple env names in the `Symfony\Component\Routing\Attribute\Route` attribute
89

910
7.3
1011
---

src/Symfony/Component/Routing/Loader/AttributeClassLoader.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public function load(mixed $class, ?string $type = null): RouteCollection
105105
$globals = $this->getGlobals($class);
106106
$collection = new RouteCollection();
107107
$collection->addResource(new FileResource($class->getFileName()));
108-
if ($globals['env'] && $this->env !== $globals['env']) {
108+
if ($globals['env'] && !\in_array($this->env, $globals['env'], true)) {
109109
return $collection;
110110
}
111111
$fqcnAlias = false;
@@ -161,7 +161,7 @@ public function load(mixed $class, ?string $type = null): RouteCollection
161161
*/
162162
protected function addRoute(RouteCollection $collection, object $attr, array $globals, \ReflectionClass $class, \ReflectionMethod $method): void
163163
{
164-
if ($attr->getEnv() && $attr->getEnv() !== $this->env) {
164+
if ($attr->getEnvs() && !\in_array($this->env, $attr->getEnvs(), true)) {
165165
return;
166166
}
167167

@@ -338,7 +338,7 @@ protected function getGlobals(\ReflectionClass $class): array
338338
}
339339

340340
$globals['priority'] = $attr->getPriority() ?? 0;
341-
$globals['env'] = $attr->getEnv();
341+
$globals['env'] = $attr->getEnvs();
342342

343343
foreach ($globals['requirements'] as $placeholder => $requirement) {
344344
if (\is_int($placeholder)) {

src/Symfony/Component/Routing/Tests/Fixtures/AttributeFixtures/RouteWithEnv.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,19 @@ public function action()
1616
public function action2()
1717
{
1818
}
19+
20+
#[Route(path: '/path3', name: 'action3', env: ['some-other-env', 'some-other-env-two'])]
21+
public function action3()
22+
{
23+
}
24+
25+
#[Route(path: '/path4', name: 'action4', env: null)]
26+
public function action4()
27+
{
28+
}
29+
30+
#[Route(path: '/path5', name: 'action5', env: ['some-other-env', 'some-env'])]
31+
public function action5()
32+
{
33+
}
1934
}

src/Symfony/Component/Routing/Tests/Loader/AttributeClassLoaderTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,10 @@ public function testWhenEnv()
330330

331331
$this->setUp('some-env');
332332
$routes = $this->loader->load(RouteWithEnv::class);
333-
$this->assertCount(1, $routes);
333+
$this->assertCount(3, $routes);
334334
$this->assertSame('/path', $routes->get('action')->getPath());
335+
$this->assertSame('/path4', $routes->get('action4')->getPath());
336+
$this->assertSame('/path5', $routes->get('action5')->getPath());
335337
}
336338

337339
public function testMethodsAndSchemes()

0 commit comments

Comments
 (0)