VerbFilter.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\filters;
  8. use Yii;
  9. use yii\base\ActionEvent;
  10. use yii\base\Behavior;
  11. use yii\web\Controller;
  12. use yii\web\MethodNotAllowedHttpException;
  13. /**
  14. * VerbFilter is an action filter that filters by HTTP request methods.
  15. *
  16. * It allows to define allowed HTTP request methods for each action and will throw
  17. * an HTTP 405 error when the method is not allowed.
  18. *
  19. * To use VerbFilter, declare it in the `behaviors()` method of your controller class.
  20. * For example, the following declarations will define a typical set of allowed
  21. * request methods for REST CRUD actions.
  22. *
  23. * ```php
  24. * public function behaviors()
  25. * {
  26. * return [
  27. * 'verbs' => [
  28. * 'class' => \yii\filters\VerbFilter::className(),
  29. * 'actions' => [
  30. * 'index' => ['GET'],
  31. * 'view' => ['GET'],
  32. * 'create' => ['GET', 'POST'],
  33. * 'update' => ['GET', 'PUT', 'POST'],
  34. * 'delete' => ['POST', 'DELETE'],
  35. * ],
  36. * ],
  37. * ];
  38. * }
  39. * ```
  40. *
  41. * @see https://tools.ietf.org/html/rfc2616#section-14.7
  42. * @author Carsten Brandt <mail@cebe.cc>
  43. * @since 2.0
  44. */
  45. class VerbFilter extends Behavior
  46. {
  47. /**
  48. * @var array this property defines the allowed request methods for each action.
  49. * For each action that should only support limited set of request methods
  50. * you add an entry with the action id as array key and an array of
  51. * allowed methods (e.g. GET, HEAD, PUT) as the value.
  52. * If an action is not listed all request methods are considered allowed.
  53. *
  54. * You can use `'*'` to stand for all actions. When an action is explicitly
  55. * specified, it takes precedence over the specification given by `'*'`.
  56. *
  57. * For example,
  58. *
  59. * ```php
  60. * [
  61. * 'create' => ['GET', 'POST'],
  62. * 'update' => ['GET', 'PUT', 'POST'],
  63. * 'delete' => ['POST', 'DELETE'],
  64. * '*' => ['GET'],
  65. * ]
  66. * ```
  67. */
  68. public $actions = [];
  69. /**
  70. * Declares event handlers for the [[owner]]'s events.
  71. * @return array events (array keys) and the corresponding event handler methods (array values).
  72. */
  73. public function events()
  74. {
  75. return [Controller::EVENT_BEFORE_ACTION => 'beforeAction'];
  76. }
  77. /**
  78. * @param ActionEvent $event
  79. * @return bool
  80. * @throws MethodNotAllowedHttpException when the request method is not allowed.
  81. */
  82. public function beforeAction($event)
  83. {
  84. $action = $event->action->id;
  85. if (isset($this->actions[$action])) {
  86. $verbs = $this->actions[$action];
  87. } elseif (isset($this->actions['*'])) {
  88. $verbs = $this->actions['*'];
  89. } else {
  90. return $event->isValid;
  91. }
  92. $verb = Yii::$app->getRequest()->getMethod();
  93. $allowed = array_map('strtoupper', $verbs);
  94. if (!in_array($verb, $allowed)) {
  95. $event->isValid = false;
  96. // https://tools.ietf.org/html/rfc2616#section-14.7
  97. Yii::$app->getResponse()->getHeaders()->set('Allow', implode(', ', $allowed));
  98. throw new MethodNotAllowedHttpException('Method Not Allowed. This URL can only handle the following request methods: ' . implode(', ', $allowed) . '.');
  99. }
  100. return $event->isValid;
  101. }
  102. }