filter.php 5.0 KB

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