Skip to content

[Routing] allow setting multiple envs in #[Route] attribute #61358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 7.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions UPGRADE-7.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ HttpFoundation

* Deprecate using `Request::sendHeaders()` after headers have already been sent; use a `StreamedResponse` instead

Routing
-------

* Deprecate `getEnv()` and `setEnv()` methods of the `Symfony\Component\Routing\Attribute\Route` class in favor of the plurialized `getEnvs()` and `setEnvs()` methods. They get and return an array of env names

Security
--------

Expand Down
36 changes: 33 additions & 3 deletions src/Symfony/Component/Routing/Attribute/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace Symfony\Component\Routing\Attribute;

use Symfony\Component\Routing\Exception\LogicException;

/**
* @author Fabien Potencier <fabien@symfony.com>
* @author Alexander M. Turek <me@derrabus.de>
Expand All @@ -21,6 +23,8 @@ class Route
private ?string $path = null;
private array $localizedPaths = [];
private array $methods;
/** @var string[] */
private array $env;
private array $schemes;
/**
* @var (string|DeprecatedAlias)[]
Expand All @@ -42,7 +46,7 @@ class Route
* @param string|null $format The format returned by the route (i.e. "json", "xml")
* @param bool|null $utf8 Whether the route accepts UTF-8 in its parameters
* @param bool|null $stateless Whether the route is defined as stateless or stateful, @see https://symfony.com/doc/current/routing.html#stateless-routes
* @param string|null $env The env in which the route is defined (i.e. "dev", "test", "prod")
* @param string|string[]|null $env The env(s) in which the route is defined (i.e. "dev", "test", "prod", ["dev", "test"])
* @param string|DeprecatedAlias|(string|DeprecatedAlias)[] $alias The list of aliases for this route
*/
public function __construct(
Expand All @@ -60,7 +64,7 @@ public function __construct(
?string $format = null,
?bool $utf8 = null,
?bool $stateless = null,
private ?string $env = null,
string|array|null $env = null,
string|DeprecatedAlias|array $alias = [],
) {
if (\is_array($path)) {
Expand All @@ -71,6 +75,7 @@ public function __construct(
$this->setMethods($methods);
$this->setSchemes($schemes);
$this->setAliases($alias);
$this->setEnvs((array) $env);

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

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

/**
* @deprecated since Symfony 7.4, use {@see getEnvs()} method instead
*/
public function getEnv(): ?string
{
trigger_deprecation('symfony/routing', '7.4', 'The "%s()" method is deprecated, use "getEnvs()" instead.', __METHOD__);
if (!$this->env) {
return null;
}
if (\count($this->env) > 1) {
throw new LogicException(\sprintf('The "env" property has %d environments. Use "getEnvs()" to get all of them.', \count($this->env)));
}

return $this->env[0];
}

public function setEnvs(array|string $env): void
{
$this->env = (array) $env;
}

public function getEnvs(): array
{
return $this->env;
}
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Routing/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ CHANGELOG
---

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

7.3
---
Expand Down
6 changes: 3 additions & 3 deletions src/Symfony/Component/Routing/Loader/AttributeClassLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public function load(mixed $class, ?string $type = null): RouteCollection
$globals = $this->getGlobals($class);
$collection = new RouteCollection();
$collection->addResource(new FileResource($class->getFileName()));
if ($globals['env'] && $this->env !== $globals['env']) {
if ($globals['env'] && !\in_array($this->env, $globals['env'])) {
return $collection;
}
$fqcnAlias = false;
Expand Down Expand Up @@ -161,7 +161,7 @@ public function load(mixed $class, ?string $type = null): RouteCollection
*/
protected function addRoute(RouteCollection $collection, object $attr, array $globals, \ReflectionClass $class, \ReflectionMethod $method): void
{
if ($attr->getEnv() && $attr->getEnv() !== $this->env) {
if ($attr->getEnvs() && !\in_array($this->env, $attr->getEnvs())) {
return;
}

Expand Down Expand Up @@ -338,7 +338,7 @@ protected function getGlobals(\ReflectionClass $class): array
}

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

foreach ($globals['requirements'] as $placeholder => $requirement) {
if (\is_int($placeholder)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,19 @@ public function action()
public function action2()
{
}

#[Route(path: '/path3', name: 'action3', env: ['some-other-env', 'some-other-env-two'])]
public function action3()
{
}

#[Route(path: '/path4', name: 'action4', env: null)]
public function action4()
{
}

#[Route(path: '/path5', name: 'action5', env: ['some-other-env', 'some-env'])]
public function action5()
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,10 @@ public function testWhenEnv()

$this->setUp('some-env');
$routes = $this->loader->load(RouteWithEnv::class);
$this->assertCount(1, $routes);
$this->assertCount(3, $routes);
$this->assertSame('/path', $routes->get('action')->getPath());
$this->assertSame('/path4', $routes->get('action4')->getPath());
$this->assertSame('/path5', $routes->get('action5')->getPath());
}

public function testMethodsAndSchemes()
Expand Down
Loading