Skip to content

Commit 3f70fa0

Browse files
committed
[Routing] Deprecate ServiceRouterLoader and ObjectRouteLoader in favor of ContainerLoader and ObjectLoader
1 parent 25f1804 commit 3f70fa0

File tree

10 files changed

+438
-231
lines changed

10 files changed

+438
-231
lines changed

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

Lines 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.container" class="Symfony\Component\Routing\Loader\ContainerLoader">
4444
<tag name="routing.loader" />
4545
<argument type="service" id="service_container" />
4646
</service>

src/Symfony/Component/Routing/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
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+
* deprecated `ObjectLoader::getServiceObject()` in favor of `ObjectLoader::getObject()`
10+
* deprecated `ObjectLoader::supports()`, implement it directly in your class
11+
412
4.3.0
513
-----
614

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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
18+
* routes.
19+
*
20+
* @author Ryan Weaver <ryan@knpuniversity.com>
21+
*/
22+
class ContainerLoader extends ObjectLoader
23+
{
24+
private $container;
25+
26+
public function __construct(ContainerInterface $container)
27+
{
28+
$this->container = $container;
29+
}
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
public function supports($resource, $type = null)
35+
{
36+
return 'service' === $type;
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
protected function getServiceObject($id)
43+
{
44+
// Remove in Symfony 5.0
45+
}
46+
47+
/**
48+
* {@inheritdoc}
49+
*/
50+
protected function getObject(string $id)
51+
{
52+
return $this->container->get($id);
53+
}
54+
}

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

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,13 @@
1111

1212
namespace Symfony\Component\Routing\Loader\DependencyInjection;
1313

14-
use Psr\Container\ContainerInterface;
15-
use Symfony\Component\Routing\Loader\ObjectRouteLoader;
14+
use Symfony\Component\Routing\Loader\ContainerLoader;
15+
16+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4 and will be removed in 5.0, use "%s" instead.', ServiceRouterLoader::class, ContainerLoader::class), E_USER_DEPRECATED);
1617

1718
/**
18-
* A route loader that executes a service to load the routes.
19-
*
20-
* @author Ryan Weaver <ryan@knpuniversity.com>
19+
* @deprecated since Symfony 4.4 and will be removed in 5.0, use Symfony\Component\Routing\Loader\ContainerLoader instead.
2120
*/
22-
class ServiceRouterLoader extends ObjectRouteLoader
21+
class ServiceRouterLoader extends ContainerLoader
2322
{
24-
/**
25-
* @var ContainerInterface
26-
*/
27-
private $container;
28-
29-
public function __construct(ContainerInterface $container)
30-
{
31-
$this->container = $container;
32-
}
33-
34-
protected function getServiceObject($id)
35-
{
36-
return $this->container->get($id);
37-
}
3823
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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+
* @deprecated since Symfony 4.4 and will be removed in 5.0, implement and use "getObject" instead.
27+
*/
28+
abstract protected function getServiceObject($id);
29+
30+
/**
31+
* Returns the object that the method will be called on to load routes.
32+
*
33+
* For example, if your application uses a service container,
34+
* the $id may be a service id.
35+
*
36+
* @return object
37+
*/
38+
/*abstract in Symfony 5.0 */protected function getObject(string $id)
39+
{
40+
@trigger_error(sprintf('The "%s::getServiceObject()" method is deprecated since Symfony 4.4 and will be removed in 5.0, implement and use "%s" instead.', self::class, __FUNCTION__), E_USER_DEPRECATED);
41+
42+
return $this->getServiceObject($id);
43+
}
44+
45+
/**
46+
* Calls the object method that will load the routes.
47+
*
48+
* @param string $resource object_id::method
49+
* @param string|null $type The resource type
50+
*
51+
* @return RouteCollection
52+
*/
53+
public function load($resource, $type = null)
54+
{
55+
if (!preg_match('/^[^\:]+(?:::?(?:[^\:]+))?$/', $resource)) {
56+
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'));
57+
}
58+
59+
if (1 === substr_count($resource, ':')) {
60+
$resource = str_replace(':', '::', $resource);
61+
@trigger_error(sprintf('Referencing object route loaders with a single colon is deprecated since Symfony 4.1. Use %s instead.', $resource), E_USER_DEPRECATED);
62+
}
63+
64+
$parts = explode('::', $resource);
65+
$method = $parts[1] ?? '__invoke';
66+
67+
$loaderObject = $this->getObject($parts[0]);
68+
69+
if (!\is_object($loaderObject)) {
70+
throw new \LogicException(sprintf('%s:getObject() must return an object: %s returned', \get_class($this), \gettype($loaderObject)));
71+
}
72+
73+
if (!\is_callable([$loaderObject, $method])) {
74+
throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s"', $method, \get_class($loaderObject), $resource));
75+
}
76+
77+
$routeCollection = $loaderObject->$method($this);
78+
79+
if (!$routeCollection instanceof RouteCollection) {
80+
$type = \is_object($routeCollection) ? \get_class($routeCollection) : \gettype($routeCollection);
81+
82+
throw new \LogicException(sprintf('The %s::%s method must return a RouteCollection: %s returned', \get_class($loaderObject), $method, $type));
83+
}
84+
85+
// make the object file tracked so that if it changes, the cache rebuilds
86+
$this->addClassResource(new \ReflectionClass($loaderObject), $routeCollection);
87+
88+
return $routeCollection;
89+
}
90+
91+
/**
92+
* {@inheritdoc}
93+
*
94+
* @deprecated since Symfony 4.4 and will be removed in 5.0, implement it directly in your object loader instead.
95+
*/
96+
public function supports($resource, $type = null)
97+
{
98+
@trigger_error(sprintf('The "%s::%s()" method is deprecated since Symfony 4.4 and will be removed in 5.0, implement it directly in "%s" instead.', self::class, __FUNCTION__, static::class), E_USER_DEPRECATED);
99+
100+
return 'service' === $type;
101+
}
102+
103+
private function addClassResource(\ReflectionClass $class, RouteCollection $collection)
104+
{
105+
do {
106+
if (is_file($class->getFileName())) {
107+
$collection->addResource(new FileResource($class->getFileName()));
108+
}
109+
} while ($class = $class->getParentClass());
110+
}
111+
}

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

Lines changed: 3 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -11,90 +11,11 @@
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 and will be removed in 5.0, 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 and will be removed in 5.0, use ObjectLoader instead.
2218
*/
23-
abstract class ObjectRouteLoader extends Loader
19+
abstract class ObjectRouteLoader extends ObjectLoader
2420
{
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-
* @param string $id
32-
*
33-
* @return object
34-
*/
35-
abstract protected function getServiceObject($id);
36-
37-
/**
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
44-
*/
45-
public function load($resource, $type = null)
46-
{
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, ':')) {
52-
$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);
54-
}
55-
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));
76-
}
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;
82-
}
83-
84-
/**
85-
* {@inheritdoc}
86-
*/
87-
public function supports($resource, $type = null)
88-
{
89-
return 'service' === $type;
90-
}
91-
92-
private function addClassResource(\ReflectionClass $class, RouteCollection $collection)
93-
{
94-
do {
95-
if (is_file($class->getFileName())) {
96-
$collection->addResource(new FileResource($class->getFileName()));
97-
}
98-
} while ($class = $class->getParentClass());
99-
}
10021
}
Lines 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+
}
Lines 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 and will be removed in 5.0, 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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy