route.php 7.71 KB
Newer Older
1 2 3
<?php namespace Laravel\Routing;

use Closure;
4
use Laravel\Bundle;
5
use Laravel\Request;
6
use Laravel\Response;
7

8
class Route {
9 10

	/**
11
	 * The URI the route response to.
12 13 14
	 *
	 * @var string
	 */
15
	public $uri;
16 17

	/**
18
	 * The request method the route responds to.
19
	 *
20
	 * @var string
21
	 */
22
	public $method;
23 24

	/**
25 26 27 28 29 30 31 32
	 * The bundle in which the route was registered.
	 *
	 * @var string
	 */
	public $bundle;

	/**
	 * The action that is assigned to the route.
33 34 35
	 *
	 * @var mixed
	 */
36
	public $action;
37 38

	/**
39
	 * The parameters that will passed to the route callback.
40 41 42 43 44 45 46 47
	 *
	 * @var array
	 */
	public $parameters;

	/**
	 * Create a new Route instance.
	 *
48 49
	 * @param  string   $method
	 * @param  string   $uri
50
	 * @param  array    $action
51
	 * @param  array    $parameters
52 53
	 * @return void
	 */
54
	public function __construct($method, $uri, $action, $parameters = array())
55
	{
56 57
		$this->uri = $uri;
		$this->method = $method;
58
		$this->action = $action;
59

60
		// Determine the bundle in which the route was registered. We will know
Taylor Otwell committed
61 62
		// the bundle by using the bundle::handles method, which will return
		// the bundle assigned to that URI.
63
		$this->bundle = Bundle::handles($uri);
Taylor Otwell committed
64

65 66 67 68
		// We'll set the parameters based on the number of parameters passed
		// compared to the parameters that were needed. If more parameters
		// are needed, we'll merge in defaults.
		$this->parameters($uri, $action, $parameters);
69 70 71
	}

	/**
72
	 * Set the parameters array to the correct value.
73
	 *
Taylor Otwell committed
74
	 * @param  string  $uri
75
	 * @param  array   $action
Taylor Otwell committed
76
	 * @param  array   $parameters
77
	 * @return void
78
	 */
79
	protected function parameters($uri, $action, $parameters)
80
	{
81 82 83 84 85
		$defaults = (array) array_get($action, 'defaults');

		// If there are less parameters than wildcards, we will figure out how
		// many parameters we need to inject from the array of defaults and
		// merge them in into the main array for the route.
86
		if (count($defaults) > count($parameters))
87
		{
88
			$defaults = array_slice($defaults, count($parameters));
89 90 91 92 93

			$parameters = array_merge($parameters, $defaults);
		}

		$this->parameters = $parameters;
94 95 96 97 98 99 100 101 102
	}

	/**
	 * Call a given route and return the route's response.
	 *
	 * @return Response
	 */
	public function call()
	{
103
		// The route is responsible for running the global filters, and any
Taylor Otwell committed
104 105
		// filters defined on the route itself, since all incoming requests
		// come through a route (either defined or ad-hoc).
106
		$response = Filter::run($this->filters('before'), array(), true);
107

108
		if (is_null($response))
109
		{
110
			$response = $this->response();
111
		}
112

Taylor Otwell committed
113 114 115
		// We always return a Response instance from the route calls, so
		// we'll use the prepare method on the Response class to make
		// sure we have a valid Response isntance.
116
		$response = Response::prepare($response);
117

118
		Filter::run($this->filters('after'), array($response));
119

120
		return $response;
121 122 123
	}

	/**
124
	 * Execute the route action and return the response.
125
	 *
126
	 * Unlike the "call" method, none of the attached filters will be run.
127
	 *
128 129
	 * @return mixed
	 */
130
	public function response()
131
	{
132 133 134 135 136 137
		// If the action is a string, it is pointing the route to a controller
		// action, and we can just call the action and return its response.
		// We'll just pass the action off to the Controller class.
		$delegate = $this->delegate();

		if ( ! is_null($delegate))
138
		{
139
			return Controller::call($delegate, $this->parameters);
140
		}
141

142 143 144 145 146 147
		// If the route does not have a delegate, then it must be a Closure
		// instance or have a Closure in its action array, so we will try
		// to locate the Closure and call it directly.
		$handler = $this->handler();

		if ( ! is_null($handler))
148
		{
149
			return call_user_func_array($handler, $this->parameters);
150
		}
151
	}
152

153
	/**
154
	 * Get the filters that are attached to the route for a given event.
155
	 *
Phill Sparks committed
156
	 * @param  string  $event
157 158
	 * @return array
	 */
159
	protected function filters($event)
160
	{
161 162 163
		$global = Bundle::prefix($this->bundle).$event;

		$filters = array_unique(array($event, $global));
164

165 166 167
		// Next we will check to see if there are any filters attached to
		// the route for the given event. If there are, we'll merge them
		// in with the global filters for the event.
168
		if (isset($this->action[$event]))
169
		{
170 171 172
			$assigned = Filter::parse($this->action[$event]);

			$filters = array_merge($filters, $assigned);
173 174
		}

175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
		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.
	 *
	 * @return Closure
	 */
	protected function handler()
	{
		return array_first($this->action, function($key, $value)
		{
			return $value instanceof Closure;
		});
201 202
	}

203
	/**
204
	 * Determine if the route has a given name.
205
	 *
206 207 208 209 210
	 * <code>
	 *		// Determine if the route is the "login" route
	 *		$login = Request::route()->is('login');
	 * </code>
	 *
211
	 * @param  string  $name
212 213 214 215
	 * @return bool
	 */
	public function is($name)
	{
216
		return array_get($this->action, 'as') === $name;
217 218 219
	}

	/**
220
	 * Register a controller with the router.
221
	 *
222 223 224
	 * @param  string|array  $controller
	 * @param  string|array  $defaults
	 * @return void
225
	 */
226
	public static function controller($controllers, $defaults = 'index')
227
	{
228 229
		Router::controller($controllers, $defaults);
	}
230

231 232 233 234 235 236 237 238 239 240
	/**
	 * Register a secure controller with the router.
	 *
	 * @param  string|array  $controllers
	 * @param  string|array  $defaults
	 * @return void
	 */
	public static function secure_controller($controllers, $defaults = 'index')
	{
		Router::controller($controllers, $defaults, true);
241 242
	}

243
	/**
244
	 * Register a GET route with the router.
Taylor Otwell committed
245
	 *
246 247 248 249 250 251 252 253 254 255 256
	 * @param  string|array  $route
	 * @param  mixed         $action
	 * @return void
	 */
	public static function get($route, $action)
	{
		Router::register('GET', $route, $action);
	}

	/**
	 * Register a POST route with the router.
Taylor Otwell committed
257
	 *
258 259 260 261 262 263 264 265 266 267 268
	 * @param  string|array  $route
	 * @param  mixed         $action
	 * @return void
	 */
	public static function post($route, $action)
	{
		Router::register('POST', $route, $action);
	}

	/**
	 * Register a PUT route with the router.
Taylor Otwell committed
269 270 271 272 273
	 *
	 * @param  string|array  $route
	 * @param  mixed         $action
	 * @return void
	 */
274
	public static function put($route, $action)
Taylor Otwell committed
275
	{
276
		Router::register('PUT', $route, $action);
Taylor Otwell committed
277 278 279
	}

	/**
280
	 * Register a DELETE route with the router.
Taylor Otwell committed
281 282 283 284 285
	 *
	 * @param  string|array  $route
	 * @param  mixed         $action
	 * @return void
	 */
286
	public static function delete($route, $action)
Taylor Otwell committed
287
	{
288
		Router::register('DELETE', $route, $action);
Taylor Otwell committed
289 290 291
	}

	/**
292
	 * Register a route that handles any request method.
293
	 *
294 295 296 297 298 299 300 301 302 303 304
	 * @param  string|array  $route
	 * @param  mixed         $action
	 * @return void
	 */
	public static function any($route, $action)
	{
		Router::register('*', $route, $action);
	}

	/**
	 * Register a group of routes that share attributes.
305
	 *
306 307 308 309 310 311 312 313 314 315
	 * @param  array    $attributes
	 * @param  Closure  $callback
	 * @return void
	 */
	public static function group($attributes, Closure $callback)
	{
		Router::group($attributes, $callback);
	}

	/**
316 317 318 319 320 321 322 323 324 325 326 327
	 * Register many request URIs to a single action.
	 *
	 * @param  array  $routes
	 * @param  mixed  $action
	 * @return void
	 */
	public static function share($routes, $action)
	{
		Router::share($routes, $action);
	}

	/**
328 329 330 331 332 333
	 * Register a HTTPS route with the router.
	 *
	 * @param  string        $method
	 * @param  string|array  $route
	 * @param  mixed         $action
	 * @return void
334
	 */
335
	public static function secure($method, $route, $action)
336
	{
337
		Router::secure($method, $route, $action);
338 339
	}

340 341 342 343 344 345 346 347 348 349 350 351
	/**
	 * Register a route filter.
	 *
	 * @param  string   $name
	 * @param  Closure  $callback
	 * @return void
	 */
	public static function filter($name, Closure $callback)
	{
		Filter::register($name, $callback);
	}

352
}