Skip to content

Commit 1548101

Browse files
committed
[Routing] Deprecate ServiceRouterLoader and ObjectRouteLoader in favor of ContainerLoader and ObjectLoader
1 parent 0d8f5fe commit 1548101

File tree

14 files changed

+398
-57
lines changed

14 files changed

+398
-57
lines changed

UPGRADE-4.4.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ FrameworkBundle
8383
has been deprecated.
8484
* The `ControllerResolver` and `DelegatingLoader` classes have been marked as `final`.
8585
* The `controller_name_converter` and `resolve_controller_name_subscriber` services have been deprecated.
86+
* Deprecated `routing.loader.service`, use `routing.loader.container` instead.
8687

8788
HttpClient
8889
----------
@@ -129,6 +130,12 @@ PropertyAccess
129130

130131
* Deprecated passing `null` as 2nd argument of `PropertyAccessor::createCache()` method (`$defaultLifetime`), pass `0` instead.
131132

133+
Routing
134+
-------
135+
136+
* Deprecated `ServiceRouterLoader` in favor of `ContainerLoader`.
137+
* Deprecated `ObjectRouteLoader` in favor of `ObjectLoader`.
138+
132139
Security
133140
--------
134141

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
* The `ControllerResolver` and `DelegatingLoader` classes have been marked as `final`
1111
* Added support for configuring chained cache pools
1212
* Deprecated booting the kernel before running `WebTestCase::createClient()`
13+
* Deprecated `routing.loader.service`, use `routing.loader.container` instead.
1314

1415
4.3.0
1516
-----

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
</service>
4242

4343
<service id="routing.loader.service" class="Symfony\Component\Routing\Loader\DependencyInjection\ServiceRouterLoader">
44+
<argument type="service" id="service_container" />
45+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4, use "routing.loader.container" instead.</deprecated>
46+
</service>
47+
48+
<service id="routing.loader.container" class="Symfony\Component\Routing\Loader\ContainerLoader">
4449
<tag name="routing.loader" />
4550
<argument type="service" id="service_container" />
4651
</service>

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines 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

Lines 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

Lines 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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@
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
/**
1821
* A route loader that executes a service to load the routes.
1922
*
2023
* @author Ryan Weaver <ryan@knpuniversity.com>
24+
*
25+
* @deprecated since Symfony 4.4, use Symfony\Component\Routing\Loader\ContainerLoader instead.
2126
*/
2227
class ServiceRouterLoader extends ObjectRouteLoader
2328
{
Lines 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

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@
1111

1212
namespace Symfony\Component\Routing\Loader;
1313

14-
use Symfony\Component\Config\Loader\Loader;
15-
use Symfony\Component\Config\Resource\FileResource;
1614
use Symfony\Component\Routing\RouteCollection;
1715

16+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ObjectRouteLoader::class, ObjectLoader::class), E_USER_DEPRECATED);
17+
1818
/**
1919
* A route loader that calls a method on an object to load the routes.
2020
*
2121
* @author Ryan Weaver <ryan@knpuniversity.com>
22+
*
23+
* @deprecated since Symfony 4.4, use ObjectLoader instead.
2224
*/
23-
abstract class ObjectRouteLoader extends Loader
25+
abstract class ObjectRouteLoader extends ObjectLoader
2426
{
2527
/**
2628
* Returns the object that the method will be called on to load routes.
@@ -53,32 +55,7 @@ public function load($resource, $type = null)
5355
@trigger_error(sprintf('Referencing service route loaders with a single colon is deprecated since Symfony 4.1. Use %s instead.', $resource), E_USER_DEPRECATED);
5456
}
5557

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;
58+
return parent::load($resource, $type);
8259
}
8360

8461
/**
@@ -89,12 +66,11 @@ public function supports($resource, $type = null)
8966
return 'service' === $type;
9067
}
9168

92-
private function addClassResource(\ReflectionClass $class, RouteCollection $collection)
69+
/**
70+
* {@inheritdoc}
71+
*/
72+
protected function getObject(string $id)
9373
{
94-
do {
95-
if (is_file($class->getFileName())) {
96-
$collection->addResource(new FileResource($class->getFileName()));
97-
}
98-
} while ($class = $class->getParentClass());
74+
return $this->getServiceObject($id);
9975
}
10076
}
Lines 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 $this->loaderMap[$id] ?? null;
23+
}
24+
}

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