Файл: vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php
Строк: 373
<?php
namespace IlluminateRouting;
use IlluminateContainerContainer;
use IlluminateHttpRequest;
class RouteCollection extends AbstractRouteCollection
{
/**
* An array of the routes keyed by method.
*
* @var array
*/
protected $routes = [];
/**
* Domain routes keyed by method, used to maintain domain-first ordering.
*
* @var array
*/
protected $domainRoutes = [];
/**
* A flattened array of all of the routes.
*
* @var IlluminateRoutingRoute[]
*/
protected $allRoutes = [];
/**
* Domain routes in the flattened array, used to maintain domain-first ordering.
*
* @var IlluminateRoutingRoute[]
*/
protected $allDomainRoutes = [];
/**
* A look-up table of routes by their names.
*
* @var IlluminateRoutingRoute[]
*/
protected $nameList = [];
/**
* A look-up table of routes by controller action.
*
* @var IlluminateRoutingRoute[]
*/
protected $actionList = [];
/**
* Add a Route instance to the collection.
*
* @param IlluminateRoutingRoute $route
* @return IlluminateRoutingRoute
*/
public function add(Route $route)
{
$this->addToCollections($route);
$this->addLookups($route);
return $route;
}
/**
* Add the given route to the arrays of routes.
*
* @param IlluminateRoutingRoute $route
* @return void
*/
protected function addToCollections($route)
{
$methods = $route->methods();
$domainAndUri = $route->getDomain().$route->uri();
$allRoutesKey = implode('|', $methods).$domainAndUri;
if ($route->getDomain()) {
foreach ($methods as $method) {
$this->domainRoutes[$method][$domainAndUri] = $route;
}
$this->allDomainRoutes[$allRoutesKey] = $route;
} else {
foreach ($methods as $method) {
$this->routes[$method][$domainAndUri] = $route;
}
$this->allRoutes[$allRoutesKey] = $route;
}
}
/**
* Add the route to any look-up tables if necessary.
*
* @param IlluminateRoutingRoute $route
* @return void
*/
protected function addLookups($route)
{
// If the route has a name, we will add it to the name look-up table, so that we
// will quickly be able to find the route associated with a name and not have
// to iterate through every route every time we need to find a named route.
if (($name = $route->getName()) && ! $this->inNameLookup($name)) {
$this->nameList[$name] = $route;
}
// When the route is routing to a controller we will also store the action that
// is used by the route. This will let us reverse route to controllers while
// processing a request and easily generate URLs to the given controllers.
$action = $route->getAction();
if (($controller = $action['controller'] ?? null) && ! $this->inActionLookup($controller)) {
$this->addToActionList($action, $route);
}
}
/**
* Add a route to the controller action dictionary.
*
* @param array $action
* @param IlluminateRoutingRoute $route
* @return void
*/
protected function addToActionList($action, $route)
{
$this->actionList[trim($action['controller'], '\')] = $route;
}
/**
* Determine if the given controller is in the action lookup table.
*
* @param string $controller
* @return bool
*/
protected function inActionLookup($controller)
{
return array_key_exists($controller, $this->actionList);
}
/**
* Determine if the given name is in the name lookup table.
*
* @param string $name
* @return bool
*/
protected function inNameLookup($name)
{
return array_key_exists($name, $this->nameList);
}
/**
* Refresh the name look-up table.
*
* This is done in case any names are fluently defined or if routes are overwritten.
*
* @return void
*/
public function refreshNameLookups()
{
$this->nameList = [];
foreach ($this->allDomainRoutes + $this->allRoutes as $route) {
if (($name = $route->getName()) && ! $this->inNameLookup($name)) {
$this->nameList[$name] = $route;
}
}
}
/**
* Refresh the action look-up table.
*
* This is done in case any actions are overwritten with new controllers.
*
* @return void
*/
public function refreshActionLookups()
{
$this->actionList = [];
foreach ($this->allDomainRoutes + $this->allRoutes as $route) {
if (($controller = $route->getAction()['controller'] ?? null) && ! $this->inActionLookup($controller)) {
$this->addToActionList($route->getAction(), $route);
}
}
}
/**
* Find the first route matching a given request.
*
* @param IlluminateHttpRequest $request
* @return IlluminateRoutingRoute
*
* @throws SymfonyComponentHttpKernelExceptionMethodNotAllowedHttpException
* @throws SymfonyComponentHttpKernelExceptionNotFoundHttpException
*/
public function match(Request $request)
{
$routes = $this->get($request->getMethod());
// First, we will see if we can find a matching route for this current request
// method. If we can, great, we can just return it so that it can be called
// by the consumer. Otherwise we will check for routes with another verb.
$route = $this->matchAgainstRoutes($routes, $request);
return $this->handleMatchedRoute($request, $route);
}
/**
* Get routes from the collection by method.
*
* @param string|null $method
* @return IlluminateRoutingRoute[]
*/
public function get($method = null)
{
return is_null($method)
? $this->getRoutes()
: ($this->domainRoutes[$method] ?? []) + ($this->routes[$method] ?? []);
}
/**
* Determine if the route collection contains a given named route.
*
* @param string $name
* @return bool
*/
public function hasNamedRoute($name)
{
return ! is_null($this->getByName($name));
}
/**
* Get a route instance by its name.
*
* @param string $name
* @return IlluminateRoutingRoute|null
*/
public function getByName($name)
{
return $this->nameList[$name] ?? null;
}
/**
* Get a route instance by its controller action.
*
* @param string $action
* @return IlluminateRoutingRoute|null
*/
public function getByAction($action)
{
return $this->actionList[$action] ?? null;
}
/**
* Get all of the routes in the collection.
*
* @return IlluminateRoutingRoute[]
*/
public function getRoutes()
{
return array_values($this->allDomainRoutes + $this->allRoutes);
}
/**
* Get all of the routes keyed by their HTTP verb / method.
*
* @return array
*/
public function getRoutesByMethod()
{
$result = $this->domainRoutes;
foreach ($this->routes as $method => $routes) {
$result[$method] = ($result[$method] ?? []) + $routes;
}
return $result;
}
/**
* Get all of the routes keyed by their name.
*
* @return IlluminateRoutingRoute[]
*/
public function getRoutesByName()
{
return $this->nameList;
}
/**
* Convert the collection to a Symfony RouteCollection instance.
*
* @return SymfonyComponentRoutingRouteCollection
*/
public function toSymfonyRouteCollection()
{
$symfonyRoutes = parent::toSymfonyRouteCollection();
$this->refreshNameLookups();
return $symfonyRoutes;
}
/**
* Convert the collection to a CompiledRouteCollection instance.
*
* @param IlluminateRoutingRouter $router
* @param IlluminateContainerContainer $container
* @return IlluminateRoutingCompiledRouteCollection
*/
public function toCompiledRouteCollection(Router $router, Container $container)
{
['compiled' => $compiled, 'attributes' => $attributes] = $this->compile();
return (new CompiledRouteCollection($compiled, $attributes))
->setRouter($router)
->setContainer($container);
}
}