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 2593241

Browse filesBrowse files
committed
[Routing] Deprecate ServiceRouterLoader and ObjectRouteLoader in favor of ContainerLoader and ObjectLoader
1 parent 25f1804 commit 2593241
Copy full SHA for 2593241

File tree

12 files changed

+391
-76
lines changed
Filter options

12 files changed

+391
-76
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<argument type="service" id="file_locator" />
4141
</service>
4242

43-
<service id="routing.loader.service" class="Symfony\Component\Routing\Loader\DependencyInjection\ServiceRouterLoader">
43+
<service id="routing.loader.service" class="Symfony\Component\Routing\Loader\ContainerLoader">
4444
<tag name="routing.loader" />
4545
<argument type="service" id="service_container" />
4646
</service>

‎src/Symfony/Bundle/FrameworkBundle/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/composer.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"symfony/polyfill-mbstring": "~1.0",
2828
"symfony/filesystem": "^3.4|^4.0|^5.0",
2929
"symfony/finder": "^3.4|^4.0|^5.0",
30-
"symfony/routing": "^4.3|^5.0"
30+
"symfony/routing": "^4.4|^5.0"
3131
},
3232
"require-dev": {
3333
"doctrine/cache": "~1.0",

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/CHANGELOG.md
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
4.4.0
5+
-----
6+
7+
* deprecated `ServiceRouterLoader` in favor of `ContainerLoader`
8+
* deprecated `ObjectRouteLoader` in favor of `ObjectLoader`
9+
410
4.3.0
511
-----
612

+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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;
13+
14+
use Psr\Container\ContainerInterface;
15+
16+
/**
17+
* A route loader that executes a service from a PSR-11 container to load the routes.
18+
*
19+
* @author Ryan Weaver <ryan@knpuniversity.com>
20+
*/
21+
class ContainerLoader extends ObjectLoader
22+
{
23+
private $container;
24+
25+
public function __construct(ContainerInterface $container)
26+
{
27+
$this->container = $container;
28+
}
29+
30+
/**
31+
* {@inheritdoc}
32+
*/
33+
public function supports($resource, $type = null)
34+
{
35+
return 'service' === $type;
36+
}
37+
38+
/**
39+
* {@inheritdoc}
40+
*/
41+
protected function getObject(string $id)
42+
{
43+
return $this->container->get($id);
44+
}
45+
}

‎src/Symfony/Component/Routing/Loader/DependencyInjection/ServiceRouterLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/DependencyInjection/ServiceRouterLoader.php
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
namespace Symfony\Component\Routing\Loader\DependencyInjection;
1313

1414
use Psr\Container\ContainerInterface;
15+
use Symfony\Component\Routing\Loader\ContainerLoader;
1516
use Symfony\Component\Routing\Loader\ObjectRouteLoader;
1617

18+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ServiceRouterLoader::class, ContainerLoader::class), E_USER_DEPRECATED);
19+
1720
/**
18-
* A route loader that executes a service to load the routes.
19-
*
20-
* @author Ryan Weaver <ryan@knpuniversity.com>
21+
* @deprecated since Symfony 4.4, use Symfony\Component\Routing\Loader\ContainerLoader instead.
2122
*/
2223
class ServiceRouterLoader extends ObjectRouteLoader
2324
{
+84Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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;
13+
14+
use Symfony\Component\Config\Loader\Loader;
15+
use Symfony\Component\Config\Resource\FileResource;
16+
use Symfony\Component\Routing\RouteCollection;
17+
18+
/**
19+
* A route loader that calls a method on an object to load the routes.
20+
*
21+
* @author Ryan Weaver <ryan@knpuniversity.com>
22+
*/
23+
abstract class ObjectLoader extends Loader
24+
{
25+
/**
26+
* Returns the object that the method will be called on to load routes.
27+
*
28+
* For example, if your application uses a service container,
29+
* the $id may be a service id.
30+
*
31+
* @return object
32+
*/
33+
abstract protected function getObject(string $id);
34+
35+
/**
36+
* Calls the object method that will load the routes.
37+
*
38+
* @param string $resource object_id::method
39+
* @param string|null $type The resource type
40+
*
41+
* @return RouteCollection
42+
*/
43+
public function load($resource, $type = null)
44+
{
45+
if (!preg_match('/^[^\:]+(?:::?(?:[^\:]+))?$/', $resource)) {
46+
throw new \InvalidArgumentException(sprintf('Invalid resource "%s" passed to the %s route loader: use the format "object_id::method" or "object_id" if your object class has an "__invoke" method.', $resource, \is_string($type) ? '"'.$type.'"' : 'object'));
47+
}
48+
49+
$parts = explode('::', $resource);
50+
$method = $parts[1] ?? '__invoke';
51+
52+
$loaderObject = $this->getObject($parts[0]);
53+
54+
if (!\is_object($loaderObject)) {
55+
throw new \LogicException(sprintf('%s:getObject() must return an object: %s returned', \get_class($this), \gettype($loaderObject)));
56+
}
57+
58+
if (!\is_callable([$loaderObject, $method])) {
59+
throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s"', $method, \get_class($loaderObject), $resource));
60+
}
61+
62+
$routeCollection = $loaderObject->$method($this);
63+
64+
if (!$routeCollection instanceof RouteCollection) {
65+
$type = \is_object($routeCollection) ? \get_class($routeCollection) : \gettype($routeCollection);
66+
67+
throw new \LogicException(sprintf('The %s::%s method must return a RouteCollection: %s returned', \get_class($loaderObject), $method, $type));
68+
}
69+
70+
// make the object file tracked so that if it changes, the cache rebuilds
71+
$this->addClassResource(new \ReflectionClass($loaderObject), $routeCollection);
72+
73+
return $routeCollection;
74+
}
75+
76+
private function addClassResource(\ReflectionClass $class, RouteCollection $collection)
77+
{
78+
do {
79+
if (is_file($class->getFileName())) {
80+
$collection->addResource(new FileResource($class->getFileName()));
81+
}
82+
} while ($class = $class->getParentClass());
83+
}
84+
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php
+18-50Lines changed: 18 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,12 @@
1111

1212
namespace Symfony\Component\Routing\Loader;
1313

14-
use Symfony\Component\Config\Loader\Loader;
15-
use Symfony\Component\Config\Resource\FileResource;
16-
use Symfony\Component\Routing\RouteCollection;
14+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ObjectRouteLoader::class, ObjectLoader::class), E_USER_DEPRECATED);
1715

1816
/**
19-
* A route loader that calls a method on an object to load the routes.
20-
*
21-
* @author Ryan Weaver <ryan@knpuniversity.com>
17+
* @deprecated since Symfony 4.4, use ObjectLoader instead.
2218
*/
23-
abstract class ObjectRouteLoader extends Loader
19+
abstract class ObjectRouteLoader extends ObjectLoader
2420
{
2521
/**
2622
* Returns the object that the method will be called on to load routes.
@@ -35,50 +31,23 @@ abstract class ObjectRouteLoader extends Loader
3531
abstract protected function getServiceObject($id);
3632

3733
/**
38-
* Calls the service that will load the routes.
39-
*
40-
* @param string $resource Some value that will resolve to a callable
41-
* @param string|null $type The resource type
42-
*
43-
* @return RouteCollection
34+
* {@inheritdoc}
4435
*/
4536
public function load($resource, $type = null)
4637
{
47-
if (!preg_match('/^[^\:]+(?:::?(?:[^\:]+))?$/', $resource)) {
48-
throw new \InvalidArgumentException(sprintf('Invalid resource "%s" passed to the "service" route loader: use the format "service::method" or "service" if your service has an "__invoke" method.', $resource));
49-
}
50-
51-
if (1 === substr_count($resource, ':')) {
38+
if ($useSingleColon = (1 === substr_count($resource, ':'))) {
5239
$resource = str_replace(':', '::', $resource);
53-
@trigger_error(sprintf('Referencing service route loaders with a single colon is deprecated since Symfony 4.1. Use %s instead.', $resource), E_USER_DEPRECATED);
5440
}
5541

56-
$parts = explode('::', $resource);
57-
$serviceString = $parts[0];
58-
$method = $parts[1] ?? '__invoke';
59-
60-
$loaderObject = $this->getServiceObject($serviceString);
61-
62-
if (!\is_object($loaderObject)) {
63-
throw new \LogicException(sprintf('%s:getServiceObject() must return an object: %s returned', \get_class($this), \gettype($loaderObject)));
64-
}
65-
66-
if (!\is_callable([$loaderObject, $method])) {
67-
throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s"', $method, \get_class($loaderObject), $resource));
68-
}
69-
70-
$routeCollection = $loaderObject->$method($this);
71-
72-
if (!$routeCollection instanceof RouteCollection) {
73-
$type = \is_object($routeCollection) ? \get_class($routeCollection) : \gettype($routeCollection);
74-
75-
throw new \LogicException(sprintf('The %s::%s method must return a RouteCollection: %s returned', \get_class($loaderObject), $method, $type));
42+
try {
43+
return parent::load($resource, $type);
44+
} catch (\InvalidArgumentException $e) {
45+
throw $e;
46+
} finally {
47+
if ($useSingleColon && !isset($e)) {
48+
@trigger_error(sprintf('Referencing service route loaders with a single colon is deprecated since Symfony 4.1. Use %s instead.', $resource), E_USER_DEPRECATED);
49+
}
7650
}
77-
78-
// make the service file tracked so that if it changes, the cache rebuilds
79-
$this->addClassResource(new \ReflectionClass($loaderObject), $routeCollection);
80-
81-
return $routeCollection;
8251
}
8352

8453
/**
@@ -89,12 +58,11 @@ public function supports($resource, $type = null)
8958
return 'service' === $type;
9059
}
9160

92-
private function addClassResource(\ReflectionClass $class, RouteCollection $collection)
61+
/**
62+
* {@inheritdoc}
63+
*/
64+
protected function getObject(string $id)
9365
{
94-
do {
95-
if (is_file($class->getFileName())) {
96-
$collection->addResource(new FileResource($class->getFileName()));
97-
}
98-
} while ($class = $class->getParentClass());
66+
return $this->getServiceObject($id);
9967
}
10068
}
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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\Tests\Fixtures;
13+
14+
use Symfony\Component\Routing\Loader\ObjectRouteLoader;
15+
16+
class TestObjectRouteLoader extends ObjectRouteLoader
17+
{
18+
public $loaderMap = [];
19+
20+
protected function getServiceObject($id)
21+
{
22+
return isset($this->loaderMap[$id]) ? $this->loaderMap[$id] : null;
23+
}
24+
}
+36Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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\Tests\Loader;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\DependencyInjection\Container;
16+
use Symfony\Component\Routing\Loader\ContainerLoader;
17+
18+
class ContainerLoaderTest extends TestCase
19+
{
20+
/**
21+
* @dataProvider supportsProvider
22+
*/
23+
public function testSupports(bool $expected, string $type = null)
24+
{
25+
$this->assertSame($expected, (new ContainerLoader(new Container()))->supports('foo', $type));
26+
}
27+
28+
public function supportsProvider()
29+
{
30+
return [
31+
[true, 'service'],
32+
[false, 'bar'],
33+
[false, null],
34+
];
35+
}
36+
}
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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\Tests\Loader;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\DependencyInjection\Container;
16+
use Symfony\Component\Routing\Loader\DependencyInjection\ServiceRouterLoader;
17+
18+
class ServiceRouterLoaderTest extends TestCase
19+
{
20+
/**
21+
* @group legacy
22+
* @expectedDeprecation The "Symfony\Component\Routing\Loader\DependencyInjection\ServiceRouterLoader" class is deprecated since Symfony 4.4, use "Symfony\Component\Routing\Loader\ContainerLoader" instead.
23+
*/
24+
public function testDeprecationWarning()
25+
{
26+
new ServiceRouterLoader(new Container());
27+
}
28+
}

0 commit comments

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