filter.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <?php namespace Laravel\Routing;
  2. use Laravel\Request;
  3. class Filter {
  4. /**
  5. * The route filters for the application.
  6. *
  7. * @var array
  8. */
  9. protected static $filters = array();
  10. /**
  11. * Register an array of route filters.
  12. *
  13. * @param array $filters
  14. * @return void
  15. */
  16. public static function register($filters)
  17. {
  18. static::$filters = array_merge(static::$filters, $filters);
  19. }
  20. /**
  21. * Call a filter or set of filters.
  22. *
  23. * @param array|string $filters
  24. * @param array $pass
  25. * @param bool $override
  26. * @return mixed
  27. */
  28. public static function run($filters, $pass = array(), $override = false)
  29. {
  30. foreach (static::parse($filters) as $filter)
  31. {
  32. $parameters = array();
  33. // Parameters may be passed into routes by specifying the list of
  34. // parameters after a colon. If parameters are present, we will
  35. // merge them into the parameter array that was passed to the
  36. // method and slice the parameters off of the filter string.
  37. if (($colon = strpos($filter, ':')) !== false)
  38. {
  39. $parameters = explode(',', substr($filter, $colon + 1));
  40. $filter = substr($filter, 0, $colon);
  41. }
  42. if ( ! isset(static::$filters[$filter])) continue;
  43. $parameters = array_merge($pass, $parameters);
  44. $response = call_user_func_array(static::$filters[$filter], $parameters);
  45. // "Before" filters may override the request cycle. For example,
  46. // an authentication filter may redirect a user to a login view
  47. // if they are not logged in. Because of this, we will return
  48. // the first filter response if overriding is enabled.
  49. if ( ! is_null($response) and $override) return $response;
  50. }
  51. }
  52. /**
  53. * Parse a string of filters into an array.
  54. *
  55. * @param string|array $filters
  56. * @return array
  57. */
  58. public static function parse($filters)
  59. {
  60. return (is_string($filters)) ? explode('|', $filters) : (array) $filters;
  61. }
  62. }
  63. class Filter_Collection {
  64. /**
  65. * The event being filtered.
  66. *
  67. * @var string
  68. */
  69. public $name;
  70. /**
  71. * The included controller methods.
  72. *
  73. * @var array
  74. */
  75. public $only = array();
  76. /**
  77. * The excluded controller methods.
  78. *
  79. * @var array
  80. */
  81. public $except = array();
  82. /**
  83. * The filters contained by the collection.
  84. *
  85. * @var string|array
  86. */
  87. public $filters = array();
  88. /**
  89. * The HTTP methods for which the filter applies.
  90. *
  91. * @var array
  92. */
  93. public $methods = array();
  94. /**
  95. * Create a new filter collection instance.
  96. *
  97. * @param string $name
  98. * @param string|array $filters
  99. */
  100. public function __construct($name, $filters)
  101. {
  102. $this->name = $name;
  103. $this->filters = Filter::parse($filters);
  104. }
  105. /**
  106. * Determine if this collection's filters apply to a given method.
  107. *
  108. * Methods may be included / excluded using the "only" and "except" methods on the
  109. * filter collection. Also, the "on" method may be used to set certain filters to
  110. * only run when the request uses a given HTTP verb.
  111. *
  112. * @param string $method
  113. * @return bool
  114. */
  115. public function applies($method)
  116. {
  117. if (count($this->only) > 0 and ! in_array($method, $this->only))
  118. {
  119. return false;
  120. }
  121. if (count($this->except) > 0 and in_array($method, $this->except))
  122. {
  123. return false;
  124. }
  125. if (count($this->methods) > 0 and ! in_array(strtolower(Request::method()), $this->methods))
  126. {
  127. return false;
  128. }
  129. return true;
  130. }
  131. /**
  132. * Set the excluded controller methods.
  133. *
  134. * When methods are excluded, the collection's filters will be run for each
  135. * controller method except those explicitly specified via this method.
  136. *
  137. * <code>
  138. * // Specify a filter for all methods except "index"
  139. * $this->filter('before', 'auth')->except('index');
  140. *
  141. * // Specify a filter for all methods except "index" and "home"
  142. * $this->filter('before', 'auth')->except('index', 'home');
  143. * </code>
  144. *
  145. * @param array $methods
  146. * @return Filter_Collection
  147. */
  148. public function except($methods)
  149. {
  150. $this->except = (count(func_get_args()) > 1) ? func_get_args() : (array) $methods;
  151. return $this;
  152. }
  153. /**
  154. * Set the included controller methods.
  155. *
  156. * This method is the inverse of the "except" methods. The methods specified
  157. * via this method are the only controller methods on which the collection's
  158. * filters will be run.
  159. *
  160. * <code>
  161. * // Specify a filter for only the "index" method
  162. * $this->filter('before', 'auth')->only('index');
  163. *
  164. * // Specify a filter for only the "index" and "home" methods
  165. * $this->filter('before', 'auth')->only('index', 'home');
  166. * </code>
  167. *
  168. * @param array $methods
  169. * @return Filter_Collection
  170. */
  171. public function only($methods)
  172. {
  173. $this->only = (count(func_get_args()) > 1) ? func_get_args() : (array) $methods;
  174. return $this;
  175. }
  176. /**
  177. * Set the HTTP methods for which the filter applies.
  178. *
  179. * Since some filters, such as the CSRF filter, only make sense in a POST
  180. * request context, this method allows you to limit which HTTP methods
  181. * the filter will apply to.
  182. *
  183. * <code>
  184. * // Specify that a filter only applies on POST requests
  185. * $this->filter('before', 'csrf')->on('post');
  186. *
  187. * // Specify that a filter applies for multiple HTTP request methods
  188. * $this->filter('before', 'csrf')->on('post', 'put');
  189. * </code>
  190. *
  191. * @param array $methods
  192. * @return Filter_Collection
  193. */
  194. public function on($methods)
  195. {
  196. $methods = (count(func_get_args()) > 1) ? func_get_args() : (array) $methods;
  197. foreach ($methods as $method)
  198. {
  199. $this->methods[] = strtolower($method);
  200. }
  201. return $this;
  202. }
  203. }