Unverified Commit 98eed2b1 authored by alexpott's avatar alexpott

Issue #2917331 by catch, martin107, Deepak Goyal, longwave, andypost,...

Issue #2917331 by catch, martin107, Deepak Goyal, longwave, andypost, ravi.shankar, daffie, larowlan: Decouple from Symfony CMF
parent e6853132
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Site\Settings; use Drupal\Core\Site\Settings;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Route;
// Change the directory to the Drupal root. // Change the directory to the Drupal root.
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\language\Entity\ConfigurableLanguage; use Drupal\language\Entity\ConfigurableLanguage;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
use Drupal\Component\Utility\ArgumentsResolverInterface; use Drupal\Component\Utility\ArgumentsResolverInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
/** /**
* Attaches access check services to routes and runs them on request. * Attaches access check services to routes and runs them on request.
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
use Drupal\Core\Routing\EnhancerInterface; use Drupal\Core\Routing\EnhancerInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Route;
/** /**
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
namespace Drupal\Core\EventSubscriber; namespace Drupal\Core\EventSubscriber;
use Symfony\Cmf\Component\Routing\RouteProviderInterface; use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\Event\RequestEvent;
...@@ -20,14 +20,14 @@ class OptionsRequestSubscriber implements EventSubscriberInterface { ...@@ -20,14 +20,14 @@ class OptionsRequestSubscriber implements EventSubscriberInterface {
/** /**
* The route provider. * The route provider.
* *
* @var \Symfony\Cmf\Component\Routing\RouteProviderInterface * @var \Drupal\Core\Routing\RouteProviderInterface
*/ */
protected $routeProvider; protected $routeProvider;
/** /**
* Creates a new OptionsRequestSubscriber instance. * Creates a new OptionsRequestSubscriber instance.
* *
* @param \Symfony\Cmf\Component\Routing\RouteProviderInterface $route_provider * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider. * The route provider.
*/ */
public function __construct(RouteProviderInterface $route_provider) { public function __construct(RouteProviderInterface $route_provider) {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
use Drupal\Core\Routing\RouteBuildEvent; use Drupal\Core\Routing\RouteBuildEvent;
use Drupal\Core\Routing\RouteSubscriberBase; use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouteCollection;
/** /**
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
namespace Drupal\Core\ParamConverter; namespace Drupal\Core\ParamConverter;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouteCollection;
/** /**
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
use Drupal\Core\Routing\RequestContext; use Drupal\Core\Routing\RequestContext;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url; use Drupal\Core\Url;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\MethodNotAllowedException;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
namespace Drupal\Core\Routing\Enhancer; namespace Drupal\Core\Routing\Enhancer;
use Drupal\Core\Routing\EnhancerInterface; use Drupal\Core\Routing\EnhancerInterface;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Route;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
namespace Drupal\Core\Routing\Enhancer; namespace Drupal\Core\Routing\Enhancer;
use Drupal\Core\Routing\EnhancerInterface; use Drupal\Core\Routing\EnhancerInterface;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Route;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
use Drupal\Core\ParamConverter\ParamConverterManagerInterface; use Drupal\Core\ParamConverter\ParamConverterManagerInterface;
use Drupal\Core\ParamConverter\ParamNotConvertedException; use Drupal\Core\ParamConverter\ParamNotConvertedException;
use Drupal\Core\Routing\EnhancerInterface; use Drupal\Core\Routing\EnhancerInterface;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
......
...@@ -2,11 +2,25 @@ ...@@ -2,11 +2,25 @@
namespace Drupal\Core\Routing; namespace Drupal\Core\Routing;
use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface; use Symfony\Component\HttpFoundation\Request;
/** /**
* A route enhance service to determine route enhance rules. * A route enhance service to determine route enhance rules.
*/ */
interface EnhancerInterface extends RouteEnhancerInterface { interface EnhancerInterface {
/**
* Updates the defaults for a route definition based on the request.
*
* @param array $defaults
* The defaults, maps to '_defaults' in the route definition YAML.
* @param \Symfony\Component\HttpFoundation\Request $request
* The Request instance.
*
* @return array
* The modified defaults. Each enhancer MUST return the
* $defaults but may add or remove values.
*/
public function enhance(array $defaults, Request $request);
} }
...@@ -2,11 +2,31 @@ ...@@ -2,11 +2,31 @@
namespace Drupal\Core\Routing; namespace Drupal\Core\Routing;
use Symfony\Cmf\Component\Routing\NestedMatcher\RouteFilterInterface; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouteCollection;
/** /**
* A route filter service to filter down the collection of route instances. * A route filter service to filter down the collection of route instances.
*/ */
interface FilterInterface extends RouteFilterInterface { interface FilterInterface {
/**
* Filters the route collection against a request and returns all matching
* routes.
*
* @param \Symfony\Component\Routing\RouteCollection $collection
* The collection against which to match.
* @param \Symfony\Component\HttpFoundation\Request $request
* A Request object against which to match.
*
* @return \Symfony\Component\Routing\RouteCollection
* A non-empty RouteCollection of matched routes
*
* @throws ResourceNotFoundException
* If none of the routes in $collection matches $request. This is a
* performance optimization to not continue the match process when a match
* will no longer be possible.
*/
public function filter(RouteCollection $collection, Request $request);
} }
<?php
namespace Drupal\Core\Routing;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\RouteCollection;
class LazyRouteCollection extends RouteCollection {
/**
* The route provider for this generator.
*
* @var \Symfony\Component\Routing\RouteProviderInterface
*/
protected $provider;
/**
* Constructs a LazyRouteCollection.
*/
public function __construct(RouteProviderInterface $provider) {
$this->provider = $provider;
}
/**
* {@inheritdoc}
*/
public function getIterator() {
return new \ArrayIterator($this->all());
}
/**
* Gets the number of Routes in this collection.
*
* @return int
* The number of routes
*/
public function count() {
return count($this->all());
}
/**
* Returns all routes in this collection.
*
* @return \Symfony\Component\Routing\Route[]
* An array of routes
*/
public function all() {
return $this->provider->getRoutesByNames(NULL);
}
/**
* Gets a route by name.
*
* @param string $name
* The route name
*
* @return \Symfony\Component\Routing\Route|null
* A Route instance or null when not found
*/
public function get($name) {
try {
return $this->provider->getRouteByName($name);
}
catch (RouteNotFoundException $e) {
return;
}
}
}
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
namespace Drupal\Core\Routing; namespace Drupal\Core\Routing;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Route;
......
<?php
namespace Drupal\Core\Routing;
/**
* Provides constants used for retrieving matched routes.
*/
interface RouteObjectInterface {
/**
* Key for the route name.
*
* @var string
*/
const ROUTE_NAME = '_route';
/**
* Key for the route object.
*
* @var string
*/
const ROUTE_OBJECT = '_route_object';
/**
* Key for the controller.
*/
const CONTROLLER_NAME = '_controller';
}
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
use Drupal\Core\Path\CurrentPathStack; use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Drupal\Core\State\StateInterface; use Drupal\Core\State\StateInterface;
use Symfony\Cmf\Component\Routing\PagedRouteCollection;
use Symfony\Cmf\Component\Routing\PagedRouteProviderInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\Exception\RouteNotFoundException;
...@@ -21,7 +19,7 @@ ...@@ -21,7 +19,7 @@
/** /**
* A Route Provider front-end for all Drupal-stored routes. * A Route Provider front-end for all Drupal-stored routes.
*/ */
class RouteProvider implements CacheableRouteProviderInterface, PreloadableRouteProviderInterface, PagedRouteProviderInterface, EventSubscriberInterface { class RouteProvider implements CacheableRouteProviderInterface, PreloadableRouteProviderInterface, EventSubscriberInterface {
/** /**
* The database connection from which to read route information. * The database connection from which to read route information.
...@@ -401,7 +399,16 @@ protected function routeProviderRouteCompare(array $a, array $b) { ...@@ -401,7 +399,16 @@ protected function routeProviderRouteCompare(array $a, array $b) {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getAllRoutes() { public function getAllRoutes() {
return new PagedRouteCollection($this); $select = $this->connection->select($this->tableName, 'router')
->fields('router', ['name', 'route']);
$routes = $select->execute()->fetchAllKeyed();
$result = [];
foreach ($routes as $name => $route) {
$result[$name] = unserialize($route);
}
return $result;
} }
/** /**
...@@ -422,9 +429,25 @@ public static function getSubscribedEvents() { ...@@ -422,9 +429,25 @@ public static function getSubscribedEvents() {
} }
/** /**
* {@inheritdoc} * Returns a chunk of routes.
*
* Should only be used in conjunction with an iterator.
*
* @param int $offset
* The query offset.
* @param int $length
* The number of records.
*
* @return \Symfony\Component\Routing\Route[]
* Routes keyed by the route name.
*
* @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. No direct
* replacement is provided.
*
* @see https://www.drupal.org/node/3151009
*/ */
public function getRoutesPaged($offset, $length = NULL) { public function getRoutesPaged($offset, $length = NULL) {
@trigger_error(__METHOD__ . '() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. No direct replacement is provided. See https://www.drupal.org/node/3151009', E_USER_DEPRECATED);
$select = $this->connection->select($this->tableName, 'router') $select = $this->connection->select($this->tableName, 'router')
->fields('router', ['name', 'route']); ->fields('router', ['name', 'route']);
...@@ -443,9 +466,18 @@ public function getRoutesPaged($offset, $length = NULL) { ...@@ -443,9 +466,18 @@ public function getRoutesPaged($offset, $length = NULL) {
} }
/** /**
* {@inheritdoc} * Gets the total count of routes provided by the router.
*
* @return int
* Number of routes.
*
* @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. No direct
* replacement is provided.
*
* @see https://www.drupal.org/node/3151009
*/ */
public function getRoutesCount() { public function getRoutesCount() {
@trigger_error(__METHOD__ . '() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. No direct replacement is provided. See https://www.drupal.org/node/3151009', E_USER_DEPRECATED);
return $this->connection->query("SELECT COUNT(*) FROM {" . $this->connection->escapeTable($this->tableName) . "}")->fetchField(); return $this->connection->query("SELECT COUNT(*) FROM {" . $this->connection->escapeTable($this->tableName) . "}")->fetchField();
} }
......
...@@ -2,14 +2,79 @@ ...@@ -2,14 +2,79 @@
namespace Drupal\Core\Routing; namespace Drupal\Core\Routing;
use Symfony\Cmf\Component\Routing\RouteProviderInterface as RouteProviderBaseInterface; use Symfony\Component\HttpFoundation\Request;
/** /**
* Extends the router provider interface * Extends the router provider interface
* *
* @see \Symfony\Cmf\Component\Routing * @see \Symfony\Cmf\Component\Routing
*/ */
interface RouteProviderInterface extends RouteProviderBaseInterface { interface RouteProviderInterface {
/**
* Finds routes that may potentially match the request.
*
* This may return a mixed list of class instances, but all routes returned
* must extend the core Symfony route. The classes may also implement
* RouteObjectInterface to link to a content document.
*
* This method may not throw an exception based on implementation specific
* restrictions on the url. That case is considered a not found - returning
* an empty array. Exceptions are only used to abort the whole request in
* case something is seriously broken, like the storage backend being down.
*
* Note that implementations may not implement an optimal matching
* algorithm, simply a reasonable first pass. That allows for potentially
* very large route sets to be filtered down to likely candidates, which
* may then be filtered in memory more completely.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* A request against which to match
*
* @return \Symfony\Component\Routing\RouteCollection
* All Routes that could potentially match $request.
* Empty collection if nothing can match
*/
public function getRouteCollectionForRequest(Request $request);
/**
* Find the route using the provided route name.
*
* @param string $name
* The route name to fetch
*
* @return \Symfony\Component\Routing\Route
* The Symfony route object.
*
* @throws \Symfony\Component\Routing\Exception\RouteNotFoundException
* If a matching route cannot be found.
*/
public function getRouteByName($name);
/**
* Find many routes by their names using the provided list of names.
*
* Note that this method may not throw an exception if some of the routes
* are not found or are not actually Route instances. It will just return the
* list of those Route instances it found.
*
* This method exists in order to allow performance optimizations. The
* simple implementation could be to just repeatedly call
* $this->getRouteByName() while catching and ignoring eventual exceptions.
*
* If $names is null, this method SHOULD return a collection of all routes
* known to this provider. If there are many routes to be expected, usage of
* a lazy loading collection is recommended. A provider MAY only return a
* subset of routes to e.g. support paging or other concepts.
*
* @param array|null $names
* The list of names to retrieve, In case of null, the provider will
* determine what routes to return
*
* @return \Symfony\Component\Routing\Route[]
* Iterable list with the keys being the names from the $names array
*/
public function getRoutesByNames($names);
/** /**
* Get all routes which match a certain pattern. * Get all routes which match a certain pattern.
......
...@@ -2,14 +2,13 @@ ...@@ -2,14 +2,13 @@
namespace Drupal\Core\Routing; namespace Drupal\Core\Routing;
use Symfony\Cmf\Component\Routing\PagedRouteProviderInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
/** /**
* A Route Provider front-end for all Drupal-stored routes. * A Route Provider front-end for all Drupal-stored routes.
*/ */
class RouteProviderLazyBuilder implements PreloadableRouteProviderInterface, PagedRouteProviderInterface, EventSubscriberInterface { class RouteProviderLazyBuilder implements PreloadableRouteProviderInterface, EventSubscriberInterface {
/** /**
* The route provider service. * The route provider service.
...@@ -122,16 +121,41 @@ public function reset() { ...@@ -122,16 +121,41 @@ public function reset() {
} }
/** /**
* {@inheritdoc} * Returns a chunk of routes.
*
* Should only be used in conjunction with an iterator.
*