/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php
https://gitlab.com/Pasantias/pasantiasASLG · PHP · 314 lines · 128 code · 41 blank · 145 comment · 9 complexity · 0235495748d6fcf2056b2f1ddfd190ae MD5 · raw file
- <?php
- namespace Illuminate\Routing;
- use Countable;
- use ArrayIterator;
- use IteratorAggregate;
- use Illuminate\Support\Arr;
- use Illuminate\Http\Request;
- use Illuminate\Http\Response;
- use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
- use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
- class RouteCollection implements Countable, IteratorAggregate
- {
- /**
- * An array of the routes keyed by method.
- *
- * @var array
- */
- protected $routes = [];
- /**
- * An flattened array of all of the routes.
- *
- * @var array
- */
- protected $allRoutes = [];
- /**
- * A look-up table of routes by their names.
- *
- * @var array
- */
- protected $nameList = [];
- /**
- * A look-up table of routes by controller action.
- *
- * @var array
- */
- protected $actionList = [];
- /**
- * Add a Route instance to the collection.
- *
- * @param \Illuminate\Routing\Route $route
- * @return \Illuminate\Routing\Route
- */
- public function add(Route $route)
- {
- $this->addToCollections($route);
- $this->addLookups($route);
- return $route;
- }
- /**
- * Add the given route to the arrays of routes.
- *
- * @param \Illuminate\Routing\Route $route
- * @return void
- */
- protected function addToCollections($route)
- {
- $domainAndUri = $route->domain().$route->getUri();
- foreach ($route->methods() as $method) {
- $this->routes[$method][$domainAndUri] = $route;
- }
- $this->allRoutes[$method.$domainAndUri] = $route;
- }
- /**
- * Add the route to any look-up tables if necessary.
- *
- * @param \Illuminate\Routing\Route $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 any route associate with a name and not have
- // to iterate through every route every time we need to perform a look-up.
- $action = $route->getAction();
- if (isset($action['as'])) {
- $this->nameList[$action['as']] = $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.
- if (isset($action['controller'])) {
- $this->addToActionList($action, $route);
- }
- }
- /**
- * Refresh the name look-up table.
- *
- * This is done in case any names are fluently defined.
- *
- * @return void
- */
- public function refreshNameLookups()
- {
- $this->nameList = [];
- foreach ($this->allRoutes as $route) {
- if ($route->getName()) {
- $this->nameList[$route->getName()] = $route;
- }
- }
- }
- /**
- * Add a route to the controller action dictionary.
- *
- * @param array $action
- * @param \Illuminate\Routing\Route $route
- * @return void
- */
- protected function addToActionList($action, $route)
- {
- $this->actionList[trim($action['controller'], '\\')] = $route;
- }
- /**
- * Find the first route matching a given request.
- *
- * @param \Illuminate\Http\Request $request
- * @return \Illuminate\Routing\Route
- *
- * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
- */
- 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->check($routes, $request);
- if (! is_null($route)) {
- return $route->bind($request);
- }
- // If no route was found we will now check if a matching route is specified by
- // another HTTP verb. If it is we will need to throw a MethodNotAllowed and
- // inform the user agent of which HTTP verb it should use for this route.
- $others = $this->checkForAlternateVerbs($request);
- if (count($others) > 0) {
- return $this->getRouteForMethods($request, $others);
- }
- throw new NotFoundHttpException;
- }
- /**
- * Determine if any routes match on another HTTP verb.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- protected function checkForAlternateVerbs($request)
- {
- $methods = array_diff(Router::$verbs, [$request->getMethod()]);
- // Here we will spin through all verbs except for the current request verb and
- // check to see if any routes respond to them. If they do, we will return a
- // proper error response with the correct headers on the response string.
- $others = [];
- foreach ($methods as $method) {
- if (! is_null($this->check($this->get($method), $request, false))) {
- $others[] = $method;
- }
- }
- return $others;
- }
- /**
- * Get a route (if necessary) that responds when other available methods are present.
- *
- * @param \Illuminate\Http\Request $request
- * @param array $methods
- * @return \Illuminate\Routing\Route
- *
- * @throws \Symfony\Component\Routing\Exception\MethodNotAllowedHttpException
- */
- protected function getRouteForMethods($request, array $methods)
- {
- if ($request->method() == 'OPTIONS') {
- return (new Route('OPTIONS', $request->path(), function () use ($methods) {
- return new Response('', 200, ['Allow' => implode(',', $methods)]);
- }))->bind($request);
- }
- $this->methodNotAllowed($methods);
- }
- /**
- * Throw a method not allowed HTTP exception.
- *
- * @param array $others
- * @return void
- *
- * @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
- */
- protected function methodNotAllowed(array $others)
- {
- throw new MethodNotAllowedHttpException($others);
- }
- /**
- * Determine if a route in the array matches the request.
- *
- * @param array $routes
- * @param \Illuminate\http\Request $request
- * @param bool $includingMethod
- * @return \Illuminate\Routing\Route|null
- */
- protected function check(array $routes, $request, $includingMethod = true)
- {
- return Arr::first($routes, function ($key, $value) use ($request, $includingMethod) {
- return $value->matches($request, $includingMethod);
- });
- }
- /**
- * Get all of the routes in the collection.
- *
- * @param string|null $method
- * @return array
- */
- protected function get($method = null)
- {
- if (is_null($method)) {
- return $this->getRoutes();
- }
- return Arr::get($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 \Illuminate\Routing\Route|null
- */
- public function getByName($name)
- {
- return isset($this->nameList[$name]) ? $this->nameList[$name] : null;
- }
- /**
- * Get a route instance by its controller action.
- *
- * @param string $action
- * @return \Illuminate\Routing\Route|null
- */
- public function getByAction($action)
- {
- return isset($this->actionList[$action]) ? $this->actionList[$action] : null;
- }
- /**
- * Get all of the routes in the collection.
- *
- * @return array
- */
- public function getRoutes()
- {
- return array_values($this->allRoutes);
- }
- /**
- * Get an iterator for the items.
- *
- * @return \ArrayIterator
- */
- public function getIterator()
- {
- return new ArrayIterator($this->getRoutes());
- }
- /**
- * Count the number of items in the collection.
- *
- * @return int
- */
- public function count()
- {
- return count($this->getRoutes());
- }
- }