Skip to content

Commit b34b6b9

Browse files
[FrameworkBundle] allow container/routing configurators to vary by env
1 parent a379d9d commit b34b6b9

25 files changed

+240
-22
lines changed

Annotation/Route.php

+14-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Route
3434
private $schemes = [];
3535
private $condition;
3636
private $priority;
37+
private $env;
3738

3839
/**
3940
* @param array|string $data data array managed by the Doctrine Annotations library or the path
@@ -59,7 +60,8 @@ public function __construct(
5960
string $locale = null,
6061
string $format = null,
6162
bool $utf8 = null,
62-
bool $stateless = null
63+
bool $stateless = null,
64+
string $env = null
6365
) {
6466
if (\is_string($data)) {
6567
$data = ['path' => $data];
@@ -84,6 +86,7 @@ public function __construct(
8486
$data['format'] = $data['format'] ?? $format;
8587
$data['utf8'] = $data['utf8'] ?? $utf8;
8688
$data['stateless'] = $data['stateless'] ?? $stateless;
89+
$data['env'] = $data['env'] ?? $env;
8790

8891
$data = array_filter($data, static function ($value): bool {
8992
return null !== $value;
@@ -241,4 +244,14 @@ public function getPriority(): ?int
241244
{
242245
return $this->priority;
243246
}
247+
248+
public function setEnv(?string $env): void
249+
{
250+
$this->env = $env;
251+
}
252+
253+
public function getEnv(): ?string
254+
{
255+
return $this->env;
256+
}
244257
}

CHANGELOG.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
CHANGELOG
22
=========
33

4-
5.3.0
5-
-----
4+
5.3
5+
---
66

7-
* already encoded slashes are not decoded nor double-encoded anymore when generating URLs
7+
* Already encoded slashes are not decoded nor double-encoded anymore when generating URLs
8+
* Add support for per-env configuration in loaders
89

910
5.2.0
1011
-----

Loader/AnnotationClassLoader.php

+13-1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
abstract class AnnotationClassLoader implements LoaderInterface
7474
{
7575
protected $reader;
76+
protected $env;
7677

7778
/**
7879
* @var string
@@ -84,9 +85,10 @@ abstract class AnnotationClassLoader implements LoaderInterface
8485
*/
8586
protected $defaultRouteIndex = 0;
8687

87-
public function __construct(Reader $reader = null)
88+
public function __construct(Reader $reader = null, string $env = null)
8889
{
8990
$this->reader = $reader;
91+
$this->env = $env;
9092
}
9193

9294
/**
@@ -122,6 +124,10 @@ public function load($class, string $type = null)
122124
$collection = new RouteCollection();
123125
$collection->addResource(new FileResource($class->getFileName()));
124126

127+
if ($globals['env'] && $this->env !== $globals['env']) {
128+
return $collection;
129+
}
130+
125131
foreach ($class->getMethods() as $method) {
126132
$this->defaultRouteIndex = 0;
127133
foreach ($this->getAnnotations($method) as $annot) {
@@ -144,6 +150,10 @@ public function load($class, string $type = null)
144150
*/
145151
protected function addRoute(RouteCollection $collection, object $annot, array $globals, \ReflectionClass $class, \ReflectionMethod $method)
146152
{
153+
if ($annot->getEnv() && $annot->getEnv() !== $this->env) {
154+
return;
155+
}
156+
147157
$name = $annot->getName();
148158
if (null === $name) {
149159
$name = $this->getDefaultRouteName($class, $method);
@@ -317,6 +327,7 @@ protected function getGlobals(\ReflectionClass $class)
317327
}
318328

319329
$globals['priority'] = $annot->getPriority() ?? 0;
330+
$globals['env'] = $annot->getEnv();
320331

321332
foreach ($globals['requirements'] as $placeholder => $requirement) {
322333
if (\is_int($placeholder)) {
@@ -342,6 +353,7 @@ private function resetGlobals(): array
342353
'condition' => '',
343354
'name' => '',
344355
'priority' => 0,
356+
'env' => null,
345357
];
346358
}
347359

Loader/ClosureLoader.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class ClosureLoader extends Loader
3333
*/
3434
public function load($closure, string $type = null)
3535
{
36-
return $closure();
36+
return $closure($this->env);
3737
}
3838

3939
/**

Loader/Configurator/RoutingConfigurator.php

+18-1
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ class RoutingConfigurator
2424
private $loader;
2525
private $path;
2626
private $file;
27+
private $env;
2728

28-
public function __construct(RouteCollection $collection, PhpFileLoader $loader, string $path, string $file)
29+
public function __construct(RouteCollection $collection, PhpFileLoader $loader, string $path, string $file, string $env = null)
2930
{
3031
$this->collection = $collection;
3132
$this->loader = $loader;
3233
$this->path = $path;
3334
$this->file = $file;
35+
$this->env = $env;
3436
}
3537

3638
/**
@@ -58,6 +60,21 @@ final public function collection(string $name = ''): CollectionConfigurator
5860
return new CollectionConfigurator($this->collection, $name);
5961
}
6062

63+
/**
64+
* @return static
65+
*/
66+
final public function when(string $env): self
67+
{
68+
if ($env === $this->env) {
69+
return clone $this;
70+
}
71+
72+
$clone = clone $this;
73+
$clone->collection = new RouteCollection();
74+
75+
return $clone;
76+
}
77+
6178
/**
6279
* @return static
6380
*/

Loader/ContainerLoader.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ class ContainerLoader extends ObjectLoader
2222
{
2323
private $container;
2424

25-
public function __construct(ContainerInterface $container)
25+
public function __construct(ContainerInterface $container, string $env = null)
2626
{
2727
$this->container = $container;
28+
parent::__construct($env);
2829
}
2930

3031
/**

Loader/ObjectLoader.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function load($resource, string $type = null)
5959
throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s".', $method, get_debug_type($loaderObject), $resource));
6060
}
6161

62-
$routeCollection = $loaderObject->$method($this);
62+
$routeCollection = $loaderObject->$method($this, $this->env);
6363

6464
if (!$routeCollection instanceof RouteCollection) {
6565
$type = get_debug_type($routeCollection);

Loader/PhpFileLoader.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ protected function callConfigurator(callable $result, string $path, string $file
7171
{
7272
$collection = new RouteCollection();
7373

74-
$result(new RoutingConfigurator($collection, $this, $path, $file));
74+
$result(new RoutingConfigurator($collection, $this, $path, $file, $this->env));
7575

7676
return $collection;
7777
}

Loader/XmlFileLoader.php

+10
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ protected function parseNode(RouteCollection $collection, \DOMElement $node, str
8888
case 'import':
8989
$this->parseImport($collection, $node, $path, $file);
9090
break;
91+
case 'when':
92+
if (!$this->env || $node->getAttribute('env') !== $this->env) {
93+
break;
94+
}
95+
foreach ($node->childNodes as $node) {
96+
if ($node instanceof \DOMElement) {
97+
$this->parseNode($collection, $node, $path, $file);
98+
}
99+
}
100+
break;
91101
default:
92102
throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "route" or "import".', $node->localName, $path));
93103
}

Loader/YamlFileLoader.php

+18
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,24 @@ public function load($file, string $type = null)
8484
}
8585

8686
foreach ($parsedConfig as $name => $config) {
87+
if (0 === strpos($name, 'when@')) {
88+
if (!$this->env || 'when@'.$this->env !== $name) {
89+
continue;
90+
}
91+
92+
foreach ($config as $name => $config) {
93+
$this->validate($config, $name.'" when "@'.$this->env, $path);
94+
95+
if (isset($config['resource'])) {
96+
$this->parseImport($collection, $config, $path, $file);
97+
} else {
98+
$this->parseRoute($collection, $name, $config, $path);
99+
}
100+
}
101+
102+
continue;
103+
}
104+
87105
$this->validate($config, $name, $path);
88106

89107
if (isset($config['resource'])) {

Loader/schema/routing/routing-1.0.xsd

+9
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,18 @@
2121
<xsd:choice minOccurs="0" maxOccurs="unbounded">
2222
<xsd:element name="import" type="import" />
2323
<xsd:element name="route" type="route" />
24+
<xsd:element name="when" type="when" />
2425
</xsd:choice>
2526
</xsd:complexType>
2627

28+
<xsd:complexType name="when">
29+
<xsd:choice minOccurs="0" maxOccurs="unbounded">
30+
<xsd:element name="import" type="import" />
31+
<xsd:element name="route" type="route" />
32+
</xsd:choice>
33+
<xsd:attribute name="env" type="xsd:string" use="required" />
34+
</xsd:complexType>
35+
2736
<xsd:complexType name="localized-path">
2837
<xsd:simpleContent>
2938
<xsd:extension base="xsd:string">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
4+
5+
use Symfony\Component\Routing\Annotation\Route;
6+
7+
/**
8+
* @Route(env="some-env")
9+
*/
10+
class RouteWithEnv
11+
{
12+
/**
13+
* @Route("/path", name="action")
14+
*/
15+
public function action()
16+
{
17+
}
18+
19+
/**
20+
* @Route("/path2", name="action2", env="some-other-env")
21+
*/
22+
public function action2()
23+
{
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures;
4+
5+
use Symfony\Component\Routing\Annotation\Route;
6+
7+
#[Route(env: 'some-env')]
8+
class RouteWithEnv
9+
{
10+
#[Route(path: '/path', name: 'action')]
11+
public function action()
12+
{
13+
}
14+
15+
#[Route(path: '/path2', name: 'action2', env: 'some-other-env')]
16+
public function action2()
17+
{
18+
}
19+
}

Tests/Fixtures/when-env.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Symfony\Component\Routing\Loader\Configurator;
4+
5+
return function (RoutingConfigurator $routes) {
6+
$routes
7+
->when('some-env')
8+
->add('a', '/a2')
9+
->add('b', '/b');
10+
11+
$routes
12+
->when('some-other-env')
13+
->add('a', '/a3')
14+
->add('c', '/c');
15+
16+
$routes
17+
->add('a', '/a1');
18+
};

Tests/Fixtures/when-env.xml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<routes xmlns="http://symfony.com/schema/routing"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://symfony.com/schema/routing
5+
https://symfony.com/schema/routing/routing-1.0.xsd">
6+
<when env="some-env">
7+
<route id="a" path="/a2" />
8+
<route id="b" path="/b" />
9+
</when>
10+
11+
<when env="some-other-env">
12+
<route id="a" path="/a3" />
13+
<route id="c" path="/c" />
14+
</when>
15+
16+
<route id="a" path="/a1" />
17+
</routes>

Tests/Fixtures/when-env.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
when@some-env:
2+
a: {path: /a2}
3+
b: {path: /b}
4+
5+
when@some-other-env:
6+
a: {path: /a3}
7+
c: {path: /c}
8+
9+
a: {path: /a1}

Tests/Loader/AnnotationClassLoaderTest.php

+11
Original file line numberDiff line numberDiff line change
@@ -247,5 +247,16 @@ public function testLoadingRouteWithPrefix()
247247
$this->assertEquals('/prefix/path', $routes->get('action')->getPath());
248248
}
249249

250+
public function testWhenEnv()
251+
{
252+
$routes = $this->loader->load($this->getNamespace().'\RouteWithEnv');
253+
$this->assertCount(0, $routes);
254+
255+
$this->setUp('some-env');
256+
$routes = $this->loader->load($this->getNamespace().'\RouteWithEnv');
257+
$this->assertCount(1, $routes);
258+
$this->assertSame('/path', $routes->get('action')->getPath());
259+
}
260+
250261
abstract protected function getNamespace(): string;
251262
}

Tests/Loader/AnnotationClassLoaderWithAnnotationsTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99

1010
class AnnotationClassLoaderWithAnnotationsTest extends AnnotationClassLoaderTest
1111
{
12-
protected function setUp(): void
12+
protected function setUp(string $env = null): void
1313
{
1414
$reader = new AnnotationReader();
15-
$this->loader = new class($reader) extends AnnotationClassLoader {
15+
$this->loader = new class($reader, $env) extends AnnotationClassLoader {
1616
protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annot): void
1717
{
1818
}

Tests/Loader/AnnotationClassLoaderWithAttributesTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
*/
1111
class AnnotationClassLoaderWithAttributesTest extends AnnotationClassLoaderTest
1212
{
13-
protected function setUp(): void
13+
protected function setUp(string $env = null): void
1414
{
15-
$this->loader = new class() extends AnnotationClassLoader {
15+
$this->loader = new class(null, $env) extends AnnotationClassLoader {
1616
protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annot): void
1717
{
1818
}

0 commit comments

Comments
 (0)