Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4751a73

Browse filesBrowse files
Olivier Dolbeaufabpot
Olivier Dolbeau
authored andcommitted
[Routing] Deal with hosts per locale
1 parent 8f9ff4f commit 4751a73
Copy full SHA for 4751a73

31 files changed

+584
-30
lines changed

‎src/Symfony/Component/Routing/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ CHANGELOG
1111
* deprecated the `RouteCompiler::REGEX_DELIMITER` constant
1212
* added `ExpressionLanguageProvider` to expose extra functions to route conditions
1313
* added support for a `stateless` keyword for configuring route stateless in PHP, YAML and XML configurations.
14+
* added the "hosts" option to be able to configure the host per locale.
1415

1516
5.0.0
1617
-----

‎src/Symfony/Component/Routing/Loader/Configurator/CollectionConfigurator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/Configurator/CollectionConfigurator.php
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
class CollectionConfigurator
2121
{
2222
use Traits\AddTrait;
23+
use Traits\HostTrait;
2324
use Traits\RouteTrait;
2425

2526
private $parent;
2627
private $parentConfigurator;
2728
private $parentPrefixes;
29+
private $host;
2830

2931
public function __construct(RouteCollection $parent, string $name, self $parentConfigurator = null, array $parentPrefixes = null)
3032
{
@@ -41,6 +43,9 @@ public function __destruct()
4143
if (null === $this->prefixes) {
4244
$this->collection->addPrefix($this->route->getPath());
4345
}
46+
if (null !== $this->host) {
47+
$this->addHost($this->collection, $this->host);
48+
}
4449

4550
$this->parent->addCollection($this->collection);
4651
}
@@ -86,6 +91,20 @@ final public function prefix($prefix): self
8691
return $this;
8792
}
8893

94+
/**
95+
* Sets the host to use for all child routes.
96+
*
97+
* @param string|array $host the host, or the localized hosts
98+
*
99+
* @return $this
100+
*/
101+
final public function host($host): self
102+
{
103+
$this->host = $host;
104+
105+
return $this;
106+
}
107+
89108
private function createRoute(string $path): Route
90109
{
91110
return (clone $this->route)->setPath($path);

‎src/Symfony/Component/Routing/Loader/Configurator/ImportConfigurator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/Configurator/ImportConfigurator.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
class ImportConfigurator
2020
{
21+
use Traits\HostTrait;
2122
use Traits\PrefixTrait;
2223
use Traits\RouteTrait;
2324

@@ -59,4 +60,18 @@ final public function namePrefix(string $namePrefix): self
5960

6061
return $this;
6162
}
63+
64+
/**
65+
* Sets the host to use for all child routes.
66+
*
67+
* @param string|array $host the host, or the localized hosts
68+
*
69+
* @return $this
70+
*/
71+
final public function host($host): self
72+
{
73+
$this->addHost($this->route, $host);
74+
75+
return $this;
76+
}
6277
}

‎src/Symfony/Component/Routing/Loader/Configurator/RouteConfigurator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/Configurator/RouteConfigurator.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
class RouteConfigurator
2020
{
2121
use Traits\AddTrait;
22+
use Traits\HostTrait;
2223
use Traits\RouteTrait;
2324

2425
protected $parentConfigurator;
@@ -31,4 +32,18 @@ public function __construct(RouteCollection $collection, $route, string $name =
3132
$this->parentConfigurator = $parentConfigurator; // for GC control
3233
$this->prefixes = $prefixes;
3334
}
35+
36+
/**
37+
* Sets the host to use for all child routes.
38+
*
39+
* @param string|array $host the host, or the localized hosts
40+
*
41+
* @return $this
42+
*/
43+
final public function host($host): self
44+
{
45+
$this->addHost($this->route, $host);
46+
47+
return $this;
48+
}
3449
}
+49Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
namespace Symfony\Component\Routing\Loader\Configurator\Traits;
13+
14+
use Symfony\Component\Routing\RouteCollection;
15+
16+
/**
17+
* @internal
18+
*/
19+
trait HostTrait
20+
{
21+
final protected function addHost(RouteCollection $routes, $hosts)
22+
{
23+
if (!$hosts || !\is_array($hosts)) {
24+
$routes->setHost($hosts ?: '');
25+
26+
return;
27+
}
28+
29+
foreach ($routes->all() as $name => $route) {
30+
if (null === $locale = $route->getDefault('_locale')) {
31+
$routes->remove($name);
32+
foreach ($hosts as $locale => $host) {
33+
$localizedRoute = clone $route;
34+
$localizedRoute->setDefault('_locale', $locale);
35+
$localizedRoute->setRequirement('_locale', preg_quote($locale));
36+
$localizedRoute->setDefault('_canonical_route', $name);
37+
$localizedRoute->setHost($host);
38+
$routes->add($name.'.'.$locale, $localizedRoute);
39+
}
40+
} elseif (!isset($hosts[$locale])) {
41+
throw new \InvalidArgumentException(sprintf('Route "%s" with locale "%s" is missing a corresponding host in its parent collection.', $name, $locale));
42+
} else {
43+
$route->setHost($hosts[$locale]);
44+
$route->setRequirement('_locale', preg_quote($locale));
45+
$routes->add($name, $route);
46+
}
47+
}
48+
}
49+
}

‎src/Symfony/Component/Routing/Loader/Configurator/Traits/LocalizedRouteTrait.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/Configurator/Traits/LocalizedRouteTrait.php
+6-7Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ trait LocalizedRouteTrait
2626
* Creates one or many routes.
2727
*
2828
* @param string|array $path the path, or the localized paths of the route
29-
*
30-
* @return Route|RouteCollection
3129
*/
32-
final protected function createLocalizedRoute(RouteCollection $collection, string $name, $path, string $namePrefix = '', array $prefixes = null)
30+
final protected function createLocalizedRoute(RouteCollection $collection, string $name, $path, string $namePrefix = '', array $prefixes = null): RouteCollection
3331
{
3432
$paths = [];
3533

34+
$routes = new RouteCollection();
35+
3636
if (\is_array($path)) {
3737
if (null === $prefixes) {
3838
$paths = $path;
@@ -52,13 +52,12 @@ final protected function createLocalizedRoute(RouteCollection $collection, strin
5252
$paths[$locale] = $prefix.$path;
5353
}
5454
} else {
55-
$collection->add($namePrefix.$name, $route = $this->createRoute($path));
55+
$routes->add($namePrefix.$name, $route = $this->createRoute($path));
56+
$collection->add($namePrefix.$name, $route);
5657

57-
return $route;
58+
return $routes;
5859
}
5960

60-
$routes = new RouteCollection();
61-
6261
foreach ($paths as $locale => $path) {
6362
$routes->add($name.'.'.$locale, $route = $this->createRoute($path));
6463
$collection->add($namePrefix.$name.'.'.$locale, $route);

‎src/Symfony/Component/Routing/Loader/XmlFileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/XmlFileLoader.php
+27-14Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Config\Loader\FileLoader;
1515
use Symfony\Component\Config\Resource\FileResource;
1616
use Symfony\Component\Config\Util\XmlUtils;
17+
use Symfony\Component\Routing\Loader\Configurator\Traits\HostTrait;
1718
use Symfony\Component\Routing\Loader\Configurator\Traits\LocalizedRouteTrait;
1819
use Symfony\Component\Routing\Loader\Configurator\Traits\PrefixTrait;
1920
use Symfony\Component\Routing\RouteCollection;
@@ -26,6 +27,7 @@
2627
*/
2728
class XmlFileLoader extends FileLoader
2829
{
30+
use HostTrait;
2931
use LocalizedRouteTrait;
3032
use PrefixTrait;
3133

@@ -116,7 +118,7 @@ protected function parseRoute(RouteCollection $collection, \DOMElement $node, st
116118
$schemes = preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY);
117119
$methods = preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY);
118120

119-
list($defaults, $requirements, $options, $condition, $paths) = $this->parseConfigs($node, $filepath);
121+
list($defaults, $requirements, $options, $condition, $paths, /* $prefixes */, $hosts) = $this->parseConfigs($node, $filepath);
120122

121123
$path = $node->getAttribute('path');
122124

@@ -128,14 +130,17 @@ protected function parseRoute(RouteCollection $collection, \DOMElement $node, st
128130
throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must not have both a "path" attribute and <path> child nodes.', $filepath));
129131
}
130132

131-
$route = $this->createLocalizedRoute($collection, $id, $paths ?: $path);
132-
$route->addDefaults($defaults);
133-
$route->addRequirements($requirements);
134-
$route->addOptions($options);
135-
$route->setHost($node->getAttribute('host'));
136-
$route->setSchemes($schemes);
137-
$route->setMethods($methods);
138-
$route->setCondition($condition);
133+
$routes = $this->createLocalizedRoute($collection, $id, $paths ?: $path);
134+
$routes->addDefaults($defaults);
135+
$routes->addRequirements($requirements);
136+
$routes->addOptions($options);
137+
$routes->setSchemes($schemes);
138+
$routes->setMethods($methods);
139+
$routes->setCondition($condition);
140+
141+
if (null !== $hosts) {
142+
$this->addHost($routes, $hosts);
143+
}
139144
}
140145

141146
/**
@@ -155,13 +160,12 @@ protected function parseImport(RouteCollection $collection, \DOMElement $node, s
155160

156161
$type = $node->getAttribute('type');
157162
$prefix = $node->getAttribute('prefix');
158-
$host = $node->hasAttribute('host') ? $node->getAttribute('host') : null;
159163
$schemes = $node->hasAttribute('schemes') ? preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY) : null;
160164
$methods = $node->hasAttribute('methods') ? preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY) : null;
161165
$trailingSlashOnRoot = $node->hasAttribute('trailing-slash-on-root') ? XmlUtils::phpize($node->getAttribute('trailing-slash-on-root')) : true;
162166
$namePrefix = $node->getAttribute('name-prefix') ?: null;
163167

164-
list($defaults, $requirements, $options, $condition, /* $paths */, $prefixes) = $this->parseConfigs($node, $path);
168+
list($defaults, $requirements, $options, $condition, /* $paths */, $prefixes, $hosts) = $this->parseConfigs($node, $path);
165169

166170
if ('' !== $prefix && $prefixes) {
167171
throw new \InvalidArgumentException(sprintf('The <route> element in file "%s" must not have both a "prefix" attribute and <prefix> child nodes.', $path));
@@ -193,9 +197,10 @@ protected function parseImport(RouteCollection $collection, \DOMElement $node, s
193197
foreach ($imported as $subCollection) {
194198
$this->addPrefix($subCollection, $prefixes ?: $prefix, $trailingSlashOnRoot);
195199

196-
if (null !== $host) {
197-
$subCollection->setHost($host);
200+
if (null !== $hosts) {
201+
$this->addHost($subCollection, $hosts);
198202
}
203+
199204
if (null !== $condition) {
200205
$subCollection->setCondition($condition);
201206
}
@@ -245,6 +250,7 @@ private function parseConfigs(\DOMElement $node, string $path): array
245250
$condition = null;
246251
$prefixes = [];
247252
$paths = [];
253+
$hosts = [];
248254

249255
/** @var \DOMElement $n */
250256
foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) {
@@ -256,6 +262,9 @@ private function parseConfigs(\DOMElement $node, string $path): array
256262
case 'path':
257263
$paths[$n->getAttribute('locale')] = trim($n->textContent);
258264
break;
265+
case 'host':
266+
$hosts[$n->getAttribute('locale')] = trim($n->textContent);
267+
break;
259268
case 'prefix':
260269
$prefixes[$n->getAttribute('locale')] = trim($n->textContent);
261270
break;
@@ -309,7 +318,11 @@ private function parseConfigs(\DOMElement $node, string $path): array
309318
$defaults['_stateless'] = XmlUtils::phpize($stateless);
310319
}
311320

312-
return [$defaults, $requirements, $options, $condition, $paths, $prefixes];
321+
if (!$hosts) {
322+
$hosts = $node->hasAttribute('host') ? $node->getAttribute('host') : null;
323+
}
324+
325+
return [$defaults, $requirements, $options, $condition, $paths, $prefixes, $hosts];
313326
}
314327

315328
/**

‎src/Symfony/Component/Routing/Loader/YamlFileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/YamlFileLoader.php
+14-9Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Config\Loader\FileLoader;
1515
use Symfony\Component\Config\Resource\FileResource;
16+
use Symfony\Component\Routing\Loader\Configurator\Traits\HostTrait;
1617
use Symfony\Component\Routing\Loader\Configurator\Traits\LocalizedRouteTrait;
1718
use Symfony\Component\Routing\Loader\Configurator\Traits\PrefixTrait;
1819
use Symfony\Component\Routing\RouteCollection;
@@ -28,6 +29,7 @@
2829
*/
2930
class YamlFileLoader extends FileLoader
3031
{
32+
use HostTrait;
3133
use LocalizedRouteTrait;
3234
use PrefixTrait;
3335

@@ -137,14 +139,17 @@ protected function parseRoute(RouteCollection $collection, string $name, array $
137139
$defaults['_stateless'] = $config['stateless'];
138140
}
139141

140-
$route = $this->createLocalizedRoute($collection, $name, $config['path']);
141-
$route->addDefaults($defaults);
142-
$route->addRequirements($requirements);
143-
$route->addOptions($options);
144-
$route->setHost($config['host'] ?? '');
145-
$route->setSchemes($config['schemes'] ?? []);
146-
$route->setMethods($config['methods'] ?? []);
147-
$route->setCondition($config['condition'] ?? null);
142+
$routes = $this->createLocalizedRoute($collection, $name, $config['path']);
143+
$routes->addDefaults($defaults);
144+
$routes->addRequirements($requirements);
145+
$routes->addOptions($options);
146+
$routes->setSchemes($config['schemes'] ?? []);
147+
$routes->setMethods($config['methods'] ?? []);
148+
$routes->setCondition($config['condition'] ?? null);
149+
150+
if (isset($config['host'])) {
151+
$this->addHost($routes, $config['host']);
152+
}
148153
}
149154

150155
/**
@@ -198,7 +203,7 @@ protected function parseImport(RouteCollection $collection, array $config, strin
198203
$this->addPrefix($subCollection, $prefix, $trailingSlashOnRoot);
199204

200205
if (null !== $host) {
201-
$subCollection->setHost($host);
206+
$this->addHost($subCollection, $host);
202207
}
203208
if (null !== $condition) {
204209
$subCollection->setCondition($condition);

‎src/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
<xsd:sequence>
4646
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
4747
<xsd:element name="path" type="localized-path" minOccurs="0" maxOccurs="unbounded" />
48+
<xsd:element name="host" type="localized-path" minOccurs="0" maxOccurs="unbounded" />
4849
</xsd:sequence>
4950
<xsd:attribute name="id" type="xsd:string" use="required" />
5051
<xsd:attribute name="path" type="xsd:string" />
@@ -63,6 +64,7 @@
6364
<xsd:group ref="configs" minOccurs="0" maxOccurs="unbounded" />
6465
<xsd:element name="prefix" type="localized-path" minOccurs="0" maxOccurs="unbounded" />
6566
<xsd:element name="exclude" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
67+
<xsd:element name="host" type="localized-path" minOccurs="0" maxOccurs="unbounded" />
6668
</xsd:sequence>
6769
<xsd:attribute name="resource" type="xsd:string" use="required" />
6870
<xsd:attribute name="type" type="xsd:string" />

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.