123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- <?php namespace Laravel\Routing;
- use Closure;
- use Laravel\Bundle;
- use Laravel\Response;
- class Route {
- /**
- * The route key, including request method and URI.
- *
- * @var string
- */
- public $key;
- /**
- * The URI the route responds to.
- *
- * @var string
- */
- public $uris;
- /**
- * The bundle in which the route was registered.
- *
- * @var string
- */
- public $bundle;
- /**
- * The action that is assigned to the route.
- *
- * @var mixed
- */
- public $action;
- /**
- * The parameters that will passed to the route callback.
- *
- * @var array
- */
- public $parameters;
- /**
- * Create a new Route instance.
- *
- * @param string $key
- * @param array $action
- * @param array $parameters
- * @return void
- */
- public function __construct($key, $action, $parameters = array())
- {
- $this->key = $key;
- $this->action = $action;
- // Extract each URI from the route key. Since the route key has the request
- // method, we will extract that from the string. If the URI points to the
- // root of the application, a single forward slash will be returned.
- $uris = array_get($action, 'handles', array($key));
- $this->uris = array_map(array($this, 'extract'), $uris);
- // Determine the bundle in which the route was registered. We will know
- // the bundle by feeding the URI into the bundle::handles method, which
- // will return the bundle assigned to that URI.
- $this->bundle = Bundle::handles($this->uris[0]);
- $this->parameters = array_map('urldecode', $parameters);
- }
- /**
- * Retrieve the URI from a given route destination.
- *
- * If the request is to the application root, a slash is returned.
- *
- * @param string $segment
- * @return string
- */
- protected static function extract($segment)
- {
- $uri = substr($segment, strpos($segment, ' ') + 1);
- return ($uri !== '/') ? trim($uri, '/') : $uri;
- }
- /**
- * Call a given route and return the route's response.
- *
- * @return Response
- */
- public function call()
- {
- // The route is responsible for running the global filters, and any
- // filters defined on the route itself. Since all incoming requests
- // come through a route (either defined or ad-hoc), it makes sense
- // to let the route handle the global filters.
- $response = Filter::run($this->filters('before'), array(), true);
- if (is_null($response))
- {
- $response = $this->response();
- }
- $response = Response::prepare($response);
- Filter::run($this->filters('after'), array($response));
- return $response;
- }
- /**
- * Execute the route action and return the response.
- *
- * Unlike the "call" method, none of the attached filters will be run.
- *
- * @return mixed
- */
- public function response()
- {
- // If the action is a string, it is simply pointing the route to a
- // controller action, and we can just call the action and return
- // its response. This is the most basic form of route, and is
- // the simplest to handle.
- if ( ! is_null($delegate = $this->delegate()))
- {
- return Controller::call($delegate, $this->parameters);
- }
- // If the route does not have a delegate, it should either be a
- // Closure instance or have a Closure in its action array, so
- // we will attempt to get the Closure and call it.
- elseif ( ! is_null($handler = $this->handler()))
- {
- return call_user_func_array($handler, $this->parameters);
- }
- }
- /**
- * Get the filters that are attached to the route for a given event.
- *
- * If the route belongs to a bundle, the bundle's global filters are returned too.
- *
- * @param string $event
- * @return array
- */
- protected function filters($event)
- {
- $filters = array_unique(array($event, Bundle::prefix($this->bundle).$event));
- // Next wee will check to see if there are any filters attached
- // for the given event. If there are, we'll merge them in with
- // the global filters for the application event.
- if (isset($this->action[$event]))
- {
- $filters = array_merge($filters, Filter::parse($this->action[$event]));
- }
- return array(new Filter_Collection($filters));
- }
- /**
- * Get the controller action delegate assigned to the route.
- *
- * If no delegate is assigned, null will be returned by the method.
- *
- * @return string
- */
- protected function delegate()
- {
- return array_get($this->action, 'uses');
- }
- /**
- * Get the anonymous function assigned to handle the route.
- *
- * If no anonymous function is assigned, null will be returned by the method.
- *
- * @return Closure
- */
- protected function handler()
- {
- return array_first($this->action, function($key, $value)
- {
- return $value instanceof Closure;
- });
- }
- /**
- * Determine if the route has a given name.
- *
- * <code>
- * // Determine if the route is the "login" route
- * $login = Request::route()->is('login');
- * </code>
- *
- * @param string $name
- * @return bool
- */
- public function is($name)
- {
- return is_array($this->action) and array_get($this->action, 'name') === $name;
- }
- /**
- * Determine if the route handles a given URI.
- *
- * @param string $uri
- * @return bool
- */
- public function handles($uri)
- {
- $pattern = ($uri !== '/') ? str_replace('*', '(.*)', $uri).'\z' : '^/$';
- return ! is_null(array_first($this->uris, function($key, $uri) use ($pattern)
- {
- return preg_match('#'.$pattern.'#', $uri);
- }));
- }
- }
|