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 | |||||
8 | namespace yii\base; |
||||
9 | |||||
10 | use yii\helpers\StringHelper; |
||||
11 | |||||
12 | /** |
||||
13 | * ActionFilter is the base class for action filters. |
||||
14 | * |
||||
15 | * An action filter will participate in the action execution workflow by responding to |
||||
16 | * the `beforeAction` and `afterAction` events triggered by modules and controllers. |
||||
17 | * |
||||
18 | * Check implementation of [[\yii\filters\AccessControl]], [[\yii\filters\PageCache]] and [[\yii\filters\HttpCache]] as examples on how to use it. |
||||
19 | * |
||||
20 | * For more details and usage information on ActionFilter, see the [guide article on filters](guide:structure-filters). |
||||
21 | * |
||||
22 | * @author Qiang Xue <[email protected]> |
||||
23 | * @since 2.0 |
||||
24 | */ |
||||
25 | class ActionFilter extends Behavior |
||||
26 | { |
||||
27 | /** |
||||
28 | * @var array list of action IDs that this filter should apply to. If this property is not set, |
||||
29 | * then the filter applies to all actions, unless they are listed in [[except]]. |
||||
30 | * If an action ID appears in both [[only]] and [[except]], this filter will NOT apply to it. |
||||
31 | * |
||||
32 | * Note that if the filter is attached to a module, the action IDs should also include child module IDs (if any) |
||||
33 | * and controller IDs. |
||||
34 | * |
||||
35 | * Since version 2.0.9 action IDs can be specified as wildcards, e.g. `site/*`. |
||||
36 | * |
||||
37 | * @see except |
||||
38 | */ |
||||
39 | public $only; |
||||
40 | /** |
||||
41 | * @var array list of action IDs that this filter should not apply to. |
||||
42 | * @see only |
||||
43 | */ |
||||
44 | public $except = []; |
||||
45 | |||||
46 | |||||
47 | /** |
||||
48 | * {@inheritdoc} |
||||
49 | */ |
||||
50 | 62 | public function attach($owner) |
|||
51 | { |
||||
52 | 62 | $this->owner = $owner; |
|||
53 | 62 | $owner->on(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']); |
|||
54 | 62 | } |
|||
55 | |||||
56 | /** |
||||
57 | * {@inheritdoc} |
||||
58 | */ |
||||
59 | public function detach() |
||||
60 | { |
||||
61 | if ($this->owner) { |
||||
62 | $this->owner->off(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']); |
||||
63 | $this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']); |
||||
64 | $this->owner = null; |
||||
65 | } |
||||
66 | } |
||||
67 | |||||
68 | /** |
||||
69 | * @param ActionEvent $event |
||||
70 | */ |
||||
71 | 62 | public function beforeFilter($event) |
|||
72 | { |
||||
73 | 62 | if (!$this->isActive($event->action)) { |
|||
74 | return; |
||||
75 | } |
||||
76 | |||||
77 | 62 | $event->isValid = $this->beforeAction($event->action); |
|||
78 | 60 | if ($event->isValid) { |
|||
79 | // call afterFilter only if beforeFilter succeeds |
||||
80 | // beforeFilter and afterFilter should be properly nested |
||||
81 | 60 | $this->owner->on(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter'], null, false); |
|||
0 ignored issues
–
show
|
|||||
82 | } else { |
||||
83 | 1 | $event->handled = true; |
|||
84 | } |
||||
85 | 60 | } |
|||
86 | |||||
87 | /** |
||||
88 | * @param ActionEvent $event |
||||
89 | */ |
||||
90 | 60 | public function afterFilter($event) |
|||
91 | { |
||||
92 | 60 | $event->result = $this->afterAction($event->action, $event->result); |
|||
93 | 60 | $this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']); |
|||
94 | 60 | } |
|||
95 | |||||
96 | /** |
||||
97 | * This method is invoked right before an action is to be executed (after all possible filters.) |
||||
98 | * You may override this method to do last-minute preparation for the action. |
||||
99 | * @param Action $action the action to be executed. |
||||
100 | * @return bool whether the action should continue to be executed. |
||||
101 | */ |
||||
102 | public function beforeAction($action) |
||||
103 | { |
||||
104 | return true; |
||||
105 | } |
||||
106 | |||||
107 | /** |
||||
108 | * This method is invoked right after an action is executed. |
||||
109 | * You may override this method to do some postprocessing for the action. |
||||
110 | * @param Action $action the action just executed. |
||||
111 | * @param mixed $result the action execution result |
||||
112 | * @return mixed the processed action result. |
||||
113 | */ |
||||
114 | 59 | public function afterAction($action, $result) |
|||
0 ignored issues
–
show
The parameter
$action is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.
Loading history...
|
|||||
115 | { |
||||
116 | 59 | return $result; |
|||
117 | } |
||||
118 | |||||
119 | /** |
||||
120 | * Returns an action ID by converting [[Action::$uniqueId]] into an ID relative to the module. |
||||
121 | * @param Action $action |
||||
122 | * @return string |
||||
123 | * @since 2.0.7 |
||||
124 | */ |
||||
125 | 76 | protected function getActionId($action) |
|||
126 | { |
||||
127 | 76 | if ($this->owner instanceof Module) { |
|||
128 | $mid = $this->owner->getUniqueId(); |
||||
129 | $id = $action->getUniqueId(); |
||||
130 | if ($mid !== '' && strpos($id, $mid) === 0) { |
||||
131 | $id = substr($id, strlen($mid) + 1); |
||||
132 | } |
||||
133 | } else { |
||||
134 | 76 | $id = $action->id; |
|||
135 | } |
||||
136 | |||||
137 | 76 | return $id; |
|||
138 | } |
||||
139 | |||||
140 | /** |
||||
141 | * Returns a value indicating whether the filter is active for the given action. |
||||
142 | * @param Action $action the action being filtered |
||||
143 | * @return bool whether the filter is active for the given action. |
||||
144 | */ |
||||
145 | 74 | protected function isActive($action) |
|||
146 | { |
||||
147 | 74 | $id = $this->getActionId($action); |
|||
148 | |||||
149 | 74 | if (empty($this->only)) { |
|||
150 | 72 | $onlyMatch = true; |
|||
151 | } else { |
||||
152 | 69 | $onlyMatch = false; |
|||
153 | 69 | foreach ($this->only as $pattern) { |
|||
154 | 69 | if (StringHelper::matchWildcard($pattern, $id)) { |
|||
155 | 69 | $onlyMatch = true; |
|||
156 | 69 | break; |
|||
157 | } |
||||
158 | } |
||||
159 | } |
||||
160 | |||||
161 | 74 | $exceptMatch = false; |
|||
162 | 74 | foreach ($this->except as $pattern) { |
|||
163 | 67 | if (StringHelper::matchWildcard($pattern, $id)) { |
|||
164 | 12 | $exceptMatch = true; |
|||
165 | 67 | break; |
|||
166 | } |
||||
167 | } |
||||
168 | |||||
169 | 74 | return !$exceptMatch && $onlyMatch; |
|||
170 | } |
||||
171 | } |
||||
172 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.