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 8c4a1e7

Browse filesBrowse files
feature #23227 Add support for "controller" keyword for configuring routes controllers (voronkovich)
This PR was merged into the 3.4 branch. Discussion ---------- Add support for "controller" keyword for configuring routes controllers | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | License | MIT This PR adds a syntax sugar for configuring routes controllers in more user-friendly way by using a `controller` keyword. ```yaml # Current syntax # It looks strange and exposes Symfony's internals blog_show: path: /blog/{slug} defaults: { _controller: AppBundle:Blog:show } # Suggested syntax blog_show: path: /blog/{slug} controller: AppBundle:Blog:show ``` ```xml <?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="http://symfony.com/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- Current syntax --> <route id="blog_list" path="/blog"> <default key="_controller">AppBundle:Blog:list</default> </route> <!-- Suggested syntax --> <route id="blog_list" path="/blog" controller="AppBundle:Blog:list" /> </routes> ``` Commits ------- 06bbee8 [Routing] Use "controller" keyword for configuring routes controllers
2 parents 9026aed + 06bbee8 commit 8c4a1e7
Copy full SHA for 8c4a1e7

16 files changed

+253
-1
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
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Added support for prioritized routing loaders.
88
* Add matched and default parameters to redirect responses
9+
* Added support for a `controller` keyword for configuring route controllers in YAML and XML configurations.
910

1011
3.3.0
1112
-----

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/XmlFileLoader.php
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,16 @@ private function parseConfigs(\DOMElement $node, $path)
229229
}
230230
}
231231

232+
if ($controller = $node->getAttribute('controller')) {
233+
if (isset($defaults['_controller'])) {
234+
$name = $node->hasAttribute('id') ? sprintf('"%s"', $node->getAttribute('id')) : sprintf('the "%s" tag', $node->tagName);
235+
236+
throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" attribute and the defaults key "_controller" for %s.', $path, $name));
237+
}
238+
239+
$defaults['_controller'] = $controller;
240+
}
241+
232242
return array($defaults, $requirements, $options, $condition);
233243
}
234244

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/YamlFileLoader.php
+12-1Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
class YamlFileLoader extends FileLoader
2828
{
2929
private static $availableKeys = array(
30-
'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition',
30+
'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', 'controller',
3131
);
3232
private $yamlParser;
3333

@@ -115,6 +115,10 @@ protected function parseRoute(RouteCollection $collection, $name, array $config,
115115
$methods = isset($config['methods']) ? $config['methods'] : array();
116116
$condition = isset($config['condition']) ? $config['condition'] : null;
117117

118+
if (isset($config['controller'])) {
119+
$defaults['_controller'] = $config['controller'];
120+
}
121+
118122
$route = new Route($config['path'], $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
119123

120124
$collection->add($name, $route);
@@ -140,6 +144,10 @@ protected function parseImport(RouteCollection $collection, array $config, $path
140144
$schemes = isset($config['schemes']) ? $config['schemes'] : null;
141145
$methods = isset($config['methods']) ? $config['methods'] : null;
142146

147+
if (isset($config['controller'])) {
148+
$defaults['_controller'] = $config['controller'];
149+
}
150+
143151
$this->setCurrentDir(dirname($path));
144152

145153
$subCollection = $this->import($config['resource'], $type, false, $file);
@@ -203,5 +211,8 @@ protected function validate($config, $name, $path)
203211
$name, $path
204212
));
205213
}
214+
if (isset($config['controller']) && isset($config['defaults']['_controller'])) {
215+
throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" key and the defaults key "_controller" for "%s".', $path, $name));
216+
}
206217
}
207218
}

‎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
@@ -41,6 +41,7 @@
4141
<xsd:attribute name="host" type="xsd:string" />
4242
<xsd:attribute name="schemes" type="xsd:string" />
4343
<xsd:attribute name="methods" type="xsd:string" />
44+
<xsd:attribute name="controller" type="xsd:string" />
4445
</xsd:complexType>
4546

4647
<xsd:complexType name="import">
@@ -52,6 +53,7 @@
5253
<xsd:attribute name="host" type="xsd:string" />
5354
<xsd:attribute name="schemes" type="xsd:string" />
5455
<xsd:attribute name="methods" type="xsd:string" />
56+
<xsd:attribute name="controller" type="xsd:string" />
5557
</xsd:complexType>
5658

5759
<xsd:complexType name="default" mixed="true">
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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+
http://symfony.com/schema/routing/routing-1.0.xsd">
6+
7+
<import resource="routing.xml">
8+
<default key="_controller">FrameworkBundle:Template:template</default>
9+
</import>
10+
</routes>
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
_static:
2+
resource: routing.yml
3+
defaults:
4+
_controller: FrameworkBundle:Template:template
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
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+
http://symfony.com/schema/routing/routing-1.0.xsd">
6+
7+
<import resource="routing.xml" controller="FrameworkBundle:Template:template" />
8+
</routes>
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
_static:
2+
resource: routing.yml
3+
controller: FrameworkBundle:Template:template
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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+
http://symfony.com/schema/routing/routing-1.0.xsd">
6+
7+
<import resource="routing.xml" controller="FrameworkBundle:Template:template">
8+
<default key="_controller">AppBundle:Blog:index</default>
9+
</import>
10+
</routes>
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
_static:
2+
resource: routing.yml
3+
controller: FrameworkBundle:Template:template
4+
defaults:
5+
_controller: AppBundle:Homepage:show
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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+
http://symfony.com/schema/routing/routing-1.0.xsd">
6+
7+
<route id="app_blog" path="/blog" controller="AppBundle:Homepage:show">
8+
<default key="_controller">AppBundle:Blog:index</default>
9+
</route>
10+
</routes>
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
app_blog:
2+
path: /blog
3+
controller: AppBundle:Homepage:show
4+
defaults:
5+
_controller: AppBundle:Blog:index
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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+
http://symfony.com/schema/routing/routing-1.0.xsd">
6+
7+
<route id="app_homepage" path="/" controller="AppBundle:Homepage:show" />
8+
9+
<route id="app_blog" path="/blog">
10+
<default key="_controller">AppBundle:Blog:list</default>
11+
</route>
12+
13+
<route id="app_logout" path="/logout" />
14+
</routes>
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
app_homepage:
2+
path: /
3+
controller: AppBundle:Homepage:show
4+
5+
app_blog:
6+
path: /blog
7+
defaults:
8+
_controller: AppBundle:Blog:list
9+
10+
app_logout:
11+
path: /logout

‎src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php
+74Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,4 +287,78 @@ public function testNullValuesInMap()
287287
$route->getDefault('map')
288288
);
289289
}
290+
291+
public function testLoadRouteWithControllerAttribute()
292+
{
293+
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
294+
$routeCollection = $loader->load('routing.xml');
295+
296+
$route = $routeCollection->get('app_homepage');
297+
298+
$this->assertSame('AppBundle:Homepage:show', $route->getDefault('_controller'));
299+
}
300+
301+
public function testLoadRouteWithoutControllerAttribute()
302+
{
303+
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
304+
$routeCollection = $loader->load('routing.xml');
305+
306+
$route = $routeCollection->get('app_logout');
307+
308+
$this->assertNull($route->getDefault('_controller'));
309+
}
310+
311+
public function testLoadRouteWithControllerSetInDefaults()
312+
{
313+
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
314+
$routeCollection = $loader->load('routing.xml');
315+
316+
$route = $routeCollection->get('app_blog');
317+
318+
$this->assertSame('AppBundle:Blog:list', $route->getDefault('_controller'));
319+
}
320+
321+
/**
322+
* @expectedException \InvalidArgumentException
323+
* @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" attribute and the defaults key "_controller" for "app_blog"/
324+
*/
325+
public function testOverrideControllerInDefaults()
326+
{
327+
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
328+
$loader->load('override_defaults.xml');
329+
}
330+
331+
/**
332+
* @dataProvider provideFilesImportingRoutesWithControllers
333+
*/
334+
public function testImportRouteWithController($file)
335+
{
336+
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
337+
$routeCollection = $loader->load($file);
338+
339+
$route = $routeCollection->get('app_homepage');
340+
$this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
341+
342+
$route = $routeCollection->get('app_blog');
343+
$this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
344+
345+
$route = $routeCollection->get('app_logout');
346+
$this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
347+
}
348+
349+
public function provideFilesImportingRoutesWithControllers()
350+
{
351+
yield array('import_controller.xml');
352+
yield array('import__controller.xml');
353+
}
354+
355+
/**
356+
* @expectedException \InvalidArgumentException
357+
* @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" attribute and the defaults key "_controller" for the "import" tag/
358+
*/
359+
public function testImportWithOverriddenController()
360+
{
361+
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
362+
$loader->load('import_override_defaults.xml');
363+
}
290364
}

‎src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php
+74Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,78 @@ public function testLoadWithResource()
108108
$this->assertSame('context.getMethod() == "POST"', $route->getCondition());
109109
}
110110
}
111+
112+
public function testLoadRouteWithControllerAttribute()
113+
{
114+
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
115+
$routeCollection = $loader->load('routing.yml');
116+
117+
$route = $routeCollection->get('app_homepage');
118+
119+
$this->assertSame('AppBundle:Homepage:show', $route->getDefault('_controller'));
120+
}
121+
122+
public function testLoadRouteWithoutControllerAttribute()
123+
{
124+
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
125+
$routeCollection = $loader->load('routing.yml');
126+
127+
$route = $routeCollection->get('app_logout');
128+
129+
$this->assertNull($route->getDefault('_controller'));
130+
}
131+
132+
public function testLoadRouteWithControllerSetInDefaults()
133+
{
134+
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
135+
$routeCollection = $loader->load('routing.yml');
136+
137+
$route = $routeCollection->get('app_blog');
138+
139+
$this->assertSame('AppBundle:Blog:list', $route->getDefault('_controller'));
140+
}
141+
142+
/**
143+
* @expectedException \InvalidArgumentException
144+
* @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" key and the defaults key "_controller" for "app_blog"/
145+
*/
146+
public function testOverrideControllerInDefaults()
147+
{
148+
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
149+
$loader->load('override_defaults.yml');
150+
}
151+
152+
/**
153+
* @dataProvider provideFilesImportingRoutesWithControllers
154+
*/
155+
public function testImportRouteWithController($file)
156+
{
157+
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
158+
$routeCollection = $loader->load($file);
159+
160+
$route = $routeCollection->get('app_homepage');
161+
$this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
162+
163+
$route = $routeCollection->get('app_blog');
164+
$this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
165+
166+
$route = $routeCollection->get('app_logout');
167+
$this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));
168+
}
169+
170+
public function provideFilesImportingRoutesWithControllers()
171+
{
172+
yield array('import_controller.yml');
173+
yield array('import__controller.yml');
174+
}
175+
176+
/**
177+
* @expectedException \InvalidArgumentException
178+
* @expectedExceptionMessageRegExp /The routing file "[^"]*" must not specify both the "controller" key and the defaults key "_controller" for "_static"/
179+
*/
180+
public function testImportWithOverriddenController()
181+
{
182+
$loader = new YamlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures/controller')));
183+
$loader->load('import_override_defaults.yml');
184+
}
111185
}

0 commit comments

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