Issue #2098197 by dawehner, vijaycs85, damiankloip, tstoeckler: Add getAllRoutes() method to RouteProvider .
parent
9145204f16
commit
6819e5e0d6
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Routing\LazyLoadingRouteCollection.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Routing;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Iterator;
|
||||
|
||||
/**
|
||||
* Provides a route collection that lists all routes of drupal.
|
||||
*
|
||||
* Internally this does load multiple routes over time, so it never have all the
|
||||
* routes stored in memory.
|
||||
*/
|
||||
class LazyLoadingRouteCollection implements Iterator {
|
||||
|
||||
/**
|
||||
* Stores the current loaded routes.
|
||||
*
|
||||
* @var \Symfony\Component\Routing\Route[]
|
||||
*/
|
||||
protected $elements;
|
||||
|
||||
/**
|
||||
* Contains the amount of route which are loaded on each sql query.
|
||||
*/
|
||||
const ROUTE_LOADED_PER_TIME = 50;
|
||||
|
||||
/**
|
||||
* Contains the current item the iterator points to.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $currentRoute = 0;
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* The name of the SQL table from which to read the routes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tableName;
|
||||
|
||||
/**
|
||||
* The number of routes in the router table.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $count;
|
||||
|
||||
/**
|
||||
* Creates a LazyLoadingRouteCollection instance.
|
||||
*
|
||||
* @param \Drupal\Core\Database\Connection $database
|
||||
* The database connection.
|
||||
* @param string $table
|
||||
* (optional) The table to retrieve the route information.
|
||||
*/
|
||||
public function __construct(Connection $database, $table = 'router') {
|
||||
$this->database = $database;
|
||||
$this->tableName = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the next routes into the elements array.
|
||||
*
|
||||
* @param int $offset
|
||||
* The offset used in the db query.
|
||||
*/
|
||||
protected function loadNextElements($offset) {
|
||||
$this->elements = array();
|
||||
|
||||
$query = $this->database->select($this->tableName);
|
||||
$query->addField($this->tableName, 'name');
|
||||
$query->addField($this->tableName, 'route');
|
||||
$query->orderBy('name', 'ASC');
|
||||
$query->range($offset, static::ROUTE_LOADED_PER_TIME);
|
||||
$result = $query->execute()->fetchAllKeyed();
|
||||
|
||||
$routes = array();
|
||||
foreach ($result as $name => $route) {
|
||||
$routes[$name] = unserialize($route);
|
||||
}
|
||||
$this->elements = $routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {inheritdoc}
|
||||
*/
|
||||
public function count() {
|
||||
if (!isset($this->count)) {
|
||||
$this->count = (int) $this->database->select($this->tableName)->countQuery()->execute();
|
||||
}
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function current() {
|
||||
return current($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function next() {
|
||||
$result = next($this->elements);
|
||||
if ($result === FALSE) {
|
||||
$this->loadNextElements($this->currentRoute + 1);
|
||||
}
|
||||
$this->currentRoute++;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function key() {
|
||||
return key($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function valid() {
|
||||
return key($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rewind() {
|
||||
$this->currentRoute = 0;
|
||||
$this->loadNextElements($this->currentRoute);
|
||||
}
|
||||
|
||||
}
|
|
@ -262,4 +262,11 @@ class RouteProvider implements RouteProviderInterface {
|
|||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAllRoutes() {
|
||||
return new LazyLoadingRouteCollection($this->connection, $this->tableName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,4 +28,16 @@ interface RouteProviderInterface extends RouteProviderBaseInterface {
|
|||
*/
|
||||
public function getRoutesByPattern($pattern);
|
||||
|
||||
/**
|
||||
* Returns all the routes on the system.
|
||||
*
|
||||
* Usage of this method is discouraged for performance reasons. If possible,
|
||||
* use RouteProviderInterface::getRoutesByNames() or
|
||||
* RouteProviderInterface::getRoutesByPattern() instead.
|
||||
*
|
||||
* @return \Symfony\Component\Routing\Route[]
|
||||
* An iterator of routes keyed by route name.
|
||||
*/
|
||||
public function getAllRoutes();
|
||||
|
||||
}
|
||||
|
|
|
@ -75,5 +75,11 @@ class MockRouteProvider implements RouteProviderInterface {
|
|||
return new RouteCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc}
|
||||
*/
|
||||
public function getAllRoutes() {
|
||||
return $this->routes->all();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Routing\LazyLoadingRouteCollectionTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Routing;
|
||||
|
||||
use Drupal\Core\Routing\LazyLoadingRouteCollection;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
/**
|
||||
* Tests the lazy loaded route collection.
|
||||
*
|
||||
* @group \Drupal
|
||||
*
|
||||
* @see \Drupal\Core\Routing\LazyLoadingRouteCollection
|
||||
*/
|
||||
class LazyLoadingRouteCollectionTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Stores all the routes used in the test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routes = array();
|
||||
|
||||
/**
|
||||
* The tested route collection.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\LazyLoadingRouteCollection
|
||||
*/
|
||||
protected $routeCollection;
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Lazy loaded route collection',
|
||||
'description' => 'Tests the lazy loaded route collection.',
|
||||
'group' => 'Routing',
|
||||
);
|
||||
}
|
||||
|
||||
protected function setUp() {
|
||||
for ($i = 0; $i < 20; $i++) {
|
||||
$this->routes['test_route_' . $i] = new Route('/test-route-' . $i);
|
||||
}
|
||||
|
||||
$this->routeCollection = new TestRouteCollection($this->routes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests iterating the lazy loading route collection.
|
||||
*
|
||||
* @see \Drupal\Core\Routing\LazyLoadingRouteCollection::current()
|
||||
* @see \Drupal\Core\Routing\LazyLoadingRouteCollection::key()
|
||||
* @see \Drupal\Core\Routing\LazyLoadingRouteCollection::rewind()
|
||||
*/
|
||||
public function testIterating() {
|
||||
// Execute the foreach loop twice to ensure that rewind is called.
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$route_names = array_keys($this->routes);
|
||||
$count = 0;
|
||||
foreach ($this->routeCollection as $route_name => $route) {
|
||||
$this->assertEquals($route_names[$count], $route_name);
|
||||
$this->assertEquals($this->routes[$route_names[$count]], $route);
|
||||
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class to "inject" loaded routes.
|
||||
*/
|
||||
class TestRouteCollection extends LazyLoadingRouteCollection {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
const ROUTE_LOADED_PER_TIME = 2;
|
||||
|
||||
/**
|
||||
* Stores all elements.
|
||||
*
|
||||
* @var \Symfony\Component\Routing\Route[]
|
||||
*/
|
||||
protected $allRoutes;
|
||||
|
||||
/**
|
||||
* Creates a TestCollection instance.
|
||||
*
|
||||
* @param \Symfony\Component\Routing\Route[] $all_routes
|
||||
* Contains all the routes used in the test.
|
||||
*/
|
||||
public function __construct(array $all_routes) {
|
||||
$this->allRoutes = $all_routes;
|
||||
$this->loadNextElements($this->currentRoute);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function loadNextElements($offset) {
|
||||
$elements = array_slice($this->allRoutes, $offset, static::ROUTE_LOADED_PER_TIME);
|
||||
|
||||
$this->elements = $elements;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue