Action是所有控制器的基类,接下来了解一下它的源码。yii2\base\Action.php
<span style="color: #008080;"> 1</span> <span style="color: #000000;">php </span><span style="color: #008080;"> 2</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 3</span> <span style="color: #008000;"> * @link </span><span style="color: #008000; text-decoration: underline;">http://www.yiiframework.com/</span> <span style="color: #008080;"> 4</span> <span style="color: #008000;"> * @copyright Copyright (c) 2008 Yii Software LLC </span><span style="color: #008080;"> 5</span> <span style="color: #008000;"> * @license </span><span style="color: #008000; text-decoration: underline;">http://www.yiiframework.com/license/</span> <span style="color: #008080;"> 6</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 7</span> <span style="color: #008080;"> 8</span> <span style="color: #0000ff;">namespace</span> yii\<span style="color: #0000ff;">base</span><span style="color: #000000;">; </span><span style="color: #008080;"> 9</span> <span style="color: #008080;"> 10</span> <span style="color: #000000;">use Yii; </span><span style="color: #008080;"> 11</span> <span style="color: #008080;"> 12</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 13</span> <span style="color: #008000;"> * Action is the base class for all controller action classes. </span><span style="color: #008080;"> 14</span> <span style="color: #008000;"> * 是所有控制器的基类 </span><span style="color: #008080;"> 15</span> <span style="color: #008000;"> * Action provides a way to divide a complex controller into </span><span style="color: #008080;"> 16</span> <span style="color: #008000;"> * smaller actions in separate class files. </span><span style="color: #008080;"> 17</span> <span style="color: #008000;"> * 控制器提供了一种重复使用操作方法的代码,在多个控制器或不同的项目中使用 </span><span style="color: #008080;"> 18</span> <span style="color: #008000;"> * Derived classes must implement a method named `run()`. This method </span><span style="color: #008080;"> 19</span> <span style="color: #008000;"> * will be invoked by the controller when the action is requested. </span><span style="color: #008080;"> 20</span> <span style="color: #008000;"> * The `run()` method can have parameters which will be filled up </span><span style="color: #008080;"> 21</span> <span style="color: #008000;"> * with user input values automatically according to their names. </span><span style="color: #008080;"> 22</span> <span style="color: #008000;"> * 派生类必须实现一个名为run()的方法,这个方法会在控制器被请求时调用。 </span><span style="color: #008080;"> 23</span> <span style="color: #008000;"> * 它可以有参数,将用户输入值的根据他们的名字自动填补。 </span><span style="color: #008080;"> 24</span> <span style="color: #008000;"> * For example, if the `run()` method is declared as follows: </span><span style="color: #008080;"> 25</span> <span style="color: #008000;"> * 例:run()方法调用声明如下: </span><span style="color: #008080;"> 26</span> <span style="color: #008000;"> * ~~~ </span><span style="color: #008080;"> 27</span> <span style="color: #008000;"> * public function run($id, $type = 'book') { ... } </span><span style="color: #008080;"> 28</span> <span style="color: #008000;"> * ~~~ </span><span style="color: #008080;"> 29</span> <span style="color: #008000;"> * </span><span style="color: #008080;"> 30</span> <span style="color: #008000;"> * And the parameters provided for the action are: `['id' => 1]`. </span><span style="color: #008080;"> 31</span> <span style="color: #008000;"> * Then the `run()` method will be invoked as `run(1)` automatically. </span><span style="color: #008080;"> 32</span> <span style="color: #008000;"> * 并且提供了操作的参数 ['id'=>1]; </span><span style="color: #008080;"> 33</span> <span style="color: #008000;"> * 当run(1)时自动调用run(); </span><span style="color: #008080;"> 34</span> <span style="color: #008000;"> * @property string $uniqueId The unique ID of this action among the whole application. This property is </span><span style="color: #008080;"> 35</span> <span style="color: #008000;"> * read-only. </span><span style="color: #008080;"> 36</span> <span style="color: #008000;"> * 整个应用程序中,这一行动的唯一标识。此属性是只读 </span><span style="color: #008080;"> 37</span> <span style="color: #008000;"> * @author Qiang Xue <qiang.xue> </qiang.xue></span><span style="color: #008080;"> 38</span> <span style="color: #008000;"> * @since 2.0 </span><span style="color: #008080;"> 39</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 40</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Action extends Component </span><span style="color: #008080;"> 41</span> <span style="color: #000000;">{ </span><span style="color: #008080;"> 42</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 43</span> <span style="color: #008000;"> * @var string ID of the action ID的动作 </span><span style="color: #008080;"> 44</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 45</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> $id; </span><span style="color: #008080;"> 46</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 47</span> <span style="color: #008000;"> * @var Controller|\yii\web\Controller the controller that owns this action </span><span style="color: #008080;"> 48</span> <span style="color: #008000;"> * 拥有这一行动的控制器 </span><span style="color: #008080;"> 49</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 50</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> $controller; </span><span style="color: #008080;"> 51</span> <span style="color: #008080;"> 52</span> <span style="color: #008080;"> 53</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 54</span> <span style="color: #008000;"> * Constructor. </span><span style="color: #008080;"> 55</span> <span style="color: #008000;"> * 构造函数 </span><span style="color: #008080;"> 56</span> <span style="color: #008000;"> * @param string $id the ID of this action 这一行动的ID </span><span style="color: #008080;"> 57</span> <span style="color: #008000;"> * @param Controller $controller the controller that owns this action 拥有这一行动的控制器 </span><span style="color: #008080;"> 58</span> <span style="color: #008000;"> * @param array $config name-value pairs that will be used to initialize the object properties </span><span style="color: #008080;"> 59</span> <span style="color: #008000;"> * 用来初始化对象属性的 name-value </span><span style="color: #008080;"> 60</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 61</span> <span style="color: #0000ff;">public</span> function __construct($id, $controller, $config =<span style="color: #000000;"> []) </span><span style="color: #008080;"> 62</span> <span style="color: #000000;"> { </span><span style="color: #008080;"> 63</span> $<span style="color: #0000ff;">this</span>->id =<span style="color: #000000;"> $id; </span><span style="color: #008080;"> 64</span> $<span style="color: #0000ff;">this</span>->controller =<span style="color: #000000;"> $controller; </span><span style="color: #008080;"> 65</span> <span style="color: #008000;">//</span><span style="color: #008000;">调用父类的__construct()方法</span> <span style="color: #008080;"> 66</span> <span style="color: #000000;"> parent::__construct($config); </span><span style="color: #008080;"> 67</span> <span style="color: #000000;"> } </span><span style="color: #008080;"> 68</span> <span style="color: #008080;"> 69</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 70</span> <span style="color: #008000;"> * Returns the unique ID of this action among the whole application. </span><span style="color: #008080;"> 71</span> <span style="color: #008000;"> * 返回整个应用程序中的唯一ID。 </span><span style="color: #008080;"> 72</span> <span style="color: #008000;"> * @return string the unique ID of this action among the whole application. </span><span style="color: #008080;"> 73</span> <span style="color: #008000;"> * 在整个应用程序中,这一行动的唯一ID。 </span><span style="color: #008080;"> 74</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 75</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> function getUniqueId() </span><span style="color: #008080;"> 76</span> <span style="color: #000000;"> { </span><span style="color: #008080;"> 77</span> <span style="color: #0000ff;">return</span> $<span style="color: #0000ff;">this</span>->controller->getUniqueId() . <span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span> . $<span style="color: #0000ff;">this</span>-><span style="color: #000000;">id; </span><span style="color: #008080;"> 78</span> <span style="color: #000000;"> } </span><span style="color: #008080;"> 79</span> <span style="color: #008080;"> 80</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 81</span> <span style="color: #008000;"> * Runs this action with the specified parameters. 用指定的参数运行此操作。 </span><span style="color: #008080;"> 82</span> <span style="color: #008000;"> * This method is mainly invoked by the controller. 该方法主要由控制器调用。 </span><span style="color: #008080;"> 83</span> <span style="color: #008000;"> * </span><span style="color: #008080;"> 84</span> <span style="color: #008000;"> * @param array $params the parameters to be bound to the action's run() method.绑定到行动的run()方法的参数。 </span><span style="color: #008080;"> 85</span> <span style="color: #008000;"> * @return mixed the result of the action 行动的结果 命名参数是否有效的 </span><span style="color: #008080;"> 86</span> <span style="color: #008000;"> * @throws InvalidConfigException if the action class does not have a run() method </span><span style="color: #008080;"> 87</span> <span style="color: #008000;"> * 如果动作类没有run()方法 扔出异常 </span><span style="color: #008080;"> 88</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 89</span> <span style="color: #0000ff;">public</span> function runWithParams($<span style="color: #0000ff;">params</span><span style="color: #000000;">) </span><span style="color: #008080;"> 90</span> <span style="color: #000000;"> { </span><span style="color: #008080;"> 91</span> <span style="color: #0000ff;">if</span> (!method_exists($<span style="color: #0000ff;">this</span>, <span style="color: #800000;">'</span><span style="color: #800000;">run</span><span style="color: #800000;">'</span>)) {<span style="color: #008000;">//</span><span style="color: #008000;">如果动作类没有run()方法 抛出异常</span> <span style="color: #008080;"> 92</span> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> InvalidConfigException(get_class($<span style="color: #0000ff;">this</span>) . <span style="color: #800000;">'</span><span style="color: #800000;"> must define a "run()" method.</span><span style="color: #800000;">'</span><span style="color: #000000;">); </span><span style="color: #008080;"> 93</span> <span style="color: #000000;"> } </span><span style="color: #008080;"> 94</span> <span style="color: #008000;">//</span><span style="color: #008000;">调用bindActionParams()方法将参数绑定到动作。</span> <span style="color: #008080;"> 95</span> $args = $<span style="color: #0000ff;">this</span>->controller->bindActionParams($<span style="color: #0000ff;">this</span>, $<span style="color: #0000ff;">params</span><span style="color: #000000;">); </span><span style="color: #008080;"> 96</span> <span style="color: #008000;">//</span><span style="color: #008000;">记录跟踪消息</span> <span style="color: #008080;"> 97</span> Yii::trace(<span style="color: #800000;">'</span><span style="color: #800000;">Running action: </span><span style="color: #800000;">'</span> . get_class($<span style="color: #0000ff;">this</span>) . <span style="color: #800000;">'</span><span style="color: #800000;">::run()</span><span style="color: #800000;">'</span><span style="color: #000000;">, __METHOD__); </span><span style="color: #008080;"> 98</span> <span style="color: #0000ff;">if</span> (Yii::$app->requestedParams === <span style="color: #0000ff;">null</span><span style="color: #000000;">) { </span><span style="color: #008080;"> 99</span> <span style="color: #008000;">//</span><span style="color: #008000;">请求的动作提供的参数</span> <span style="color: #008080;">100</span> Yii::$app->requestedParams =<span style="color: #000000;"> $args; </span><span style="color: #008080;">101</span> <span style="color: #000000;"> } </span><span style="color: #008080;">102</span> <span style="color: #0000ff;">if</span> ($<span style="color: #0000ff;">this</span>-><span style="color: #000000;">beforeRun()) { </span><span style="color: #008080;">103</span> <span style="color: #008000;">//</span><span style="color: #008000;">执行run()方法</span> <span style="color: #008080;">104</span> $result = call_user_func_array([$<span style="color: #0000ff;">this</span>, <span style="color: #800000;">'</span><span style="color: #800000;">run</span><span style="color: #800000;">'</span><span style="color: #000000;">], $args); </span><span style="color: #008080;">105</span> $<span style="color: #0000ff;">this</span>-><span style="color: #000000;">afterRun(); </span><span style="color: #008080;">106</span> <span style="color: #008080;">107</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> $result; </span><span style="color: #008080;">108</span> } <span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span><span style="color: #008080;">109</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">; </span><span style="color: #008080;">110</span> <span style="color: #000000;"> } </span><span style="color: #008080;">111</span> <span style="color: #000000;"> } </span><span style="color: #008080;">112</span> <span style="color: #008080;">113</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;">114</span> <span style="color: #008000;"> * This method is called right before `run()` is executed. </span><span style="color: #008080;">115</span> <span style="color: #008000;"> * ` run() `执行前方法被调用。 </span><span style="color: #008080;">116</span> <span style="color: #008000;"> * You may override this method to do preparation work for the action run. </span><span style="color: #008080;">117</span> <span style="color: #008000;"> * 可以重写此方法,为该操作运行的准备工作。 </span><span style="color: #008080;">118</span> <span style="color: #008000;"> * If the method returns false, it will cancel the action. </span><span style="color: #008080;">119</span> <span style="color: #008000;"> * 如果该方法返回false,取消该操作。 </span><span style="color: #008080;">120</span> <span style="color: #008000;"> * @return boolean whether to run the action. </span><span style="color: #008080;">121</span> <span style="color: #008000;">*/</span> <span style="color: #008080;">122</span> <span style="color: #0000ff;">protected</span><span style="color: #000000;"> function beforeRun() </span><span style="color: #008080;">123</span> <span style="color: #000000;"> { </span><span style="color: #008080;">124</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">; </span><span style="color: #008080;">125</span> <span style="color: #000000;"> } </span><span style="color: #008080;">126</span> <span style="color: #008080;">127</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;">128</span> <span style="color: #008000;"> * This method is called right after `run()` is executed. ` run() `执行后 方法被调用。 </span><span style="color: #008080;">129</span> <span style="color: #008000;"> * You may override this method to do post-processing work for the action run. </span><span style="color: #008080;">130</span> <span style="color: #008000;"> * 可以重写此方法来处理该动作的后续处理工作。 </span><span style="color: #008080;">131</span> <span style="color: #008000;">*/</span> <span style="color: #008080;">132</span> <span style="color: #0000ff;">protected</span><span style="color: #000000;"> function afterRun() </span><span style="color: #008080;">133</span> <span style="color: #000000;"> { </span><span style="color: #008080;">134</span> <span style="color: #000000;"> } </span><span style="color: #008080;">135</span> }
接下来我们看一下事件参数相关重要的一个类ActionEvent。yii2\base\ActionEvent.php
<span style="color: #008080;"> 1</span> <span style="color: #000000;">php </span><span style="color: #008080;"> 2</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 3</span> <span style="color: #008000;"> * @link </span><span style="color: #008000; text-decoration: underline;">http://www.yiiframework.com/</span> <span style="color: #008080;"> 4</span> <span style="color: #008000;"> * @copyright Copyright (c) 2008 Yii Software LLC </span><span style="color: #008080;"> 5</span> <span style="color: #008000;"> * @license </span><span style="color: #008000; text-decoration: underline;">http://www.yiiframework.com/license/</span> <span style="color: #008080;"> 6</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 7</span> <span style="color: #008080;"> 8</span> <span style="color: #0000ff;">namespace</span> yii\<span style="color: #0000ff;">base</span><span style="color: #000000;">; </span><span style="color: #008080;"> 9</span> <span style="color: #008080;">10</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;">11</span> <span style="color: #008000;"> * ActionEvent represents the event parameter used for an action event. </span><span style="color: #008080;">12</span> <span style="color: #008000;"> * 用于操作事件的事件参数 </span><span style="color: #008080;">13</span> <span style="color: #008000;"> * By setting the [[isValid]] property, one may control whether to continue running the action. </span><span style="color: #008080;">14</span> <span style="color: #008000;"> * 通过设置[[isValid]]属性,控制是否继续运行action。 </span><span style="color: #008080;">15</span> <span style="color: #008000;"> * @author Qiang Xue <qiang.xue> </qiang.xue></span><span style="color: #008080;">16</span> <span style="color: #008000;"> * @since 2.0 </span><span style="color: #008080;">17</span> <span style="color: #008000;">*/</span> <span style="color: #008080;">18</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> ActionEvent extends Event </span><span style="color: #008080;">19</span> <span style="color: #000000;">{ </span><span style="color: #008080;">20</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;">21</span> <span style="color: #008000;"> * @var Action the action currently being executed </span><span style="color: #008080;">22</span> <span style="color: #008000;"> * 目前正在执行的行动 </span><span style="color: #008080;">23</span> <span style="color: #008000;">*/</span> <span style="color: #008080;">24</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> $action; </span><span style="color: #008080;">25</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;">26</span> <span style="color: #008000;"> * @var mixed the action result. Event handlers may modify this property to change the action result. </span><span style="color: #008080;">27</span> <span style="color: #008000;"> * 操作结果 事件处理程序可以修改此属性来更改操作结果。 </span><span style="color: #008080;">28</span> <span style="color: #008000;">*/</span> <span style="color: #008080;">29</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> $result; </span><span style="color: #008080;">30</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;">31</span> <span style="color: #008000;"> * @var boolean whether to continue running the action. Event handlers of </span><span style="color: #008080;">32</span> <span style="color: #008000;"> * [[Controller::EVENT_BEFORE_ACTION]] may set this property to decide whether </span><span style="color: #008080;">33</span> <span style="color: #008000;"> * to continue running the current action. </span><span style="color: #008080;">34</span> <span style="color: #008000;"> * 是否继续运行该动作。设置[[Controller::EVENT_BEFORE_ACTION]]属性决定是否执行当前的操作 </span><span style="color: #008080;">35</span> <span style="color: #008000;">*/</span> <span style="color: #008080;">36</span> <span style="color: #0000ff;">public</span> $isValid = <span style="color: #0000ff;">true</span><span style="color: #000000;">; </span><span style="color: #008080;">37</span> <span style="color: #008080;">38</span> <span style="color: #008080;">39</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;">40</span> <span style="color: #008000;"> * Constructor.构造函数。 </span><span style="color: #008080;">41</span> <span style="color: #008000;"> * @param Action $action the action associated with this action event.与此事件相关联的动作。 </span><span style="color: #008080;">42</span> <span style="color: #008000;"> * @param array $config name-value pairs that will be used to initialize the object properties </span><span style="color: #008080;">43</span> <span style="color: #008000;"> * 用来初始化对象属性的 name-value </span><span style="color: #008080;">44</span> <span style="color: #008000;">*/</span> <span style="color: #008080;">45</span> <span style="color: #0000ff;">public</span> function __construct($action, $config =<span style="color: #000000;"> []) </span><span style="color: #008080;">46</span> <span style="color: #000000;"> { </span><span style="color: #008080;">47</span> $<span style="color: #0000ff;">this</span>->action =<span style="color: #000000;"> $action; </span><span style="color: #008080;">48</span> <span style="color: #000000;"> parent::__construct($config); </span><span style="color: #008080;">49</span> <span style="color: #000000;"> } </span><span style="color: #008080;">50</span> }
今天最后看一下操作过滤器的基类吧ActionFilter。yii2\base\ActionFilter.php。
<span style="color: #008080;"> 1</span> <span style="color: #000000;">php </span><span style="color: #008080;"> 2</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 3</span> <span style="color: #008000;"> * @link </span><span style="color: #008000; text-decoration: underline;">http://www.yiiframework.com/</span> <span style="color: #008080;"> 4</span> <span style="color: #008000;"> * @copyright Copyright (c) 2008 Yii Software LLC </span><span style="color: #008080;"> 5</span> <span style="color: #008000;"> * @license </span><span style="color: #008000; text-decoration: underline;">http://www.yiiframework.com/license/</span> <span style="color: #008080;"> 6</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 7</span> <span style="color: #008080;"> 8</span> <span style="color: #0000ff;">namespace</span> yii\<span style="color: #0000ff;">base</span><span style="color: #000000;">; </span><span style="color: #008080;"> 9</span> <span style="color: #008080;"> 10</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 11</span> <span style="color: #008000;"> * ActionFilter is the base class for action filters. </span><span style="color: #008080;"> 12</span> <span style="color: #008000;"> * 是操作过滤器的基类。 </span><span style="color: #008080;"> 13</span> <span style="color: #008000;"> * An action filter will participate in the action execution workflow by responding to </span><span style="color: #008080;"> 14</span> <span style="color: #008000;"> * the `beforeAction` and `afterAction` events triggered by modules and controllers. </span><span style="color: #008080;"> 15</span> <span style="color: #008000;"> * 一个操作过滤器将参与行动的执行工作流程,通过触发模型和控制器的`beforeAction` 和`afterAction` 事件 </span><span style="color: #008080;"> 16</span> <span style="color: #008000;"> * Check implementation of [[\yii\filters\AccessControl]], [[\yii\filters\PageCache]] and [[\yii\filters\HttpCache]] as examples on how to use it. </span><span style="color: #008080;"> 17</span> <span style="color: #008000;"> * </span><span style="color: #008080;"> 18</span> <span style="color: #008000;"> * @author Qiang Xue <qiang.xue> </qiang.xue></span><span style="color: #008080;"> 19</span> <span style="color: #008000;"> * @since 2.0 </span><span style="color: #008080;"> 20</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 21</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> ActionFilter extends Behavior </span><span style="color: #008080;"> 22</span> <span style="color: #000000;">{ </span><span style="color: #008080;"> 23</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 24</span> <span style="color: #008000;"> * @var array list of action IDs that this filter should apply to. If this property is not set, </span><span style="color: #008080;"> 25</span> <span style="color: #008000;"> * then the filter applies to all actions, unless they are listed in [[except]]. </span><span style="color: #008080;"> 26</span> <span style="color: #008000;"> * 操作标识列表。如果该属性未设置,过滤器适用于所有的行动,除非它们被列入[[except]]中。 </span><span style="color: #008080;"> 27</span> <span style="color: #008000;"> * If an action ID appears in both [[only]] and [[except]], this filter will NOT apply to it. </span><span style="color: #008080;"> 28</span> <span style="color: #008000;"> * 如果一个操作ID 出现在[[only]] 和[[except]]中,该筛选器将不适用它 </span><span style="color: #008080;"> 29</span> <span style="color: #008000;"> * Note that if the filter is attached to a module, the action IDs should also include child module IDs (if any) </span><span style="color: #008080;"> 30</span> <span style="color: #008000;"> * and controller IDs. </span><span style="color: #008080;"> 31</span> <span style="color: #008000;"> * 如果过滤器是链接到一个模块,操作检测还应包括子模块和控制器 </span><span style="color: #008080;"> 32</span> <span style="color: #008000;"> * </span><span style="color: #008080;"> 33</span> <span style="color: #008000;"> * @see except </span><span style="color: #008080;"> 34</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 35</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> $only; </span><span style="color: #008080;"> 36</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 37</span> <span style="color: #008000;"> * @var array list of action IDs that this filter should not apply to. </span><span style="color: #008080;"> 38</span> <span style="color: #008000;"> * 此筛选器不应适用于操作ID。 </span><span style="color: #008080;"> 39</span> <span style="color: #008000;"> * @see only </span><span style="color: #008080;"> 40</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 41</span> <span style="color: #0000ff;">public</span> $except =<span style="color: #000000;"> []; </span><span style="color: #008080;"> 42</span> <span style="color: #008080;"> 43</span> <span style="color: #008080;"> 44</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 45</span> <span style="color: #008000;"> * @inheritdoc </span><span style="color: #008080;"> 46</span> <span style="color: #008000;"> * 将行为对象附加到组件。 </span><span style="color: #008080;"> 47</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 48</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> function attach($owner) </span><span style="color: #008080;"> 49</span> <span style="color: #000000;"> { </span><span style="color: #008080;"> 50</span> $<span style="color: #0000ff;">this</span>->owner =<span style="color: #000000;"> $owner; </span><span style="color: #008080;"> 51</span> $owner->on(Controller::EVENT_BEFORE_ACTION, [$<span style="color: #0000ff;">this</span>, <span style="color: #800000;">'</span><span style="color: #800000;">beforeFilter</span><span style="color: #800000;">'</span><span style="color: #000000;">]); </span><span style="color: #008080;"> 52</span> <span style="color: #000000;"> } </span><span style="color: #008080;"> 53</span> <span style="color: #008080;"> 54</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 55</span> <span style="color: #008000;"> * @inheritdoc </span><span style="color: #008080;"> 56</span> <span style="color: #008000;"> * 将行为对象和组件分离。 </span><span style="color: #008080;"> 57</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 58</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> function detach() </span><span style="color: #008080;"> 59</span> <span style="color: #000000;"> { </span><span style="color: #008080;"> 60</span> <span style="color: #0000ff;">if</span> ($<span style="color: #0000ff;">this</span>-><span style="color: #000000;">owner) { </span><span style="color: #008080;"> 61</span> $<span style="color: #0000ff;">this</span>->owner->off(Controller::EVENT_BEFORE_ACTION, [$<span style="color: #0000ff;">this</span>, <span style="color: #800000;">'</span><span style="color: #800000;">beforeFilter</span><span style="color: #800000;">'</span><span style="color: #000000;">]); </span><span style="color: #008080;"> 62</span> $<span style="color: #0000ff;">this</span>->owner->off(Controller::EVENT_AFTER_ACTION, [$<span style="color: #0000ff;">this</span>, <span style="color: #800000;">'</span><span style="color: #800000;">afterFilter</span><span style="color: #800000;">'</span><span style="color: #000000;">]); </span><span style="color: #008080;"> 63</span> $<span style="color: #0000ff;">this</span>->owner = <span style="color: #0000ff;">null</span><span style="color: #000000;">; </span><span style="color: #008080;"> 64</span> <span style="color: #000000;"> } </span><span style="color: #008080;"> 65</span> <span style="color: #000000;"> } </span><span style="color: #008080;"> 66</span> <span style="color: #008080;"> 67</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 68</span> <span style="color: #008000;"> * @param ActionEvent $event 在动作之前调用 </span><span style="color: #008080;"> 69</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 70</span> <span style="color: #0000ff;">public</span> function beforeFilter($<span style="color: #0000ff;">event</span><span style="color: #000000;">) </span><span style="color: #008080;"> 71</span> <span style="color: #000000;"> { </span><span style="color: #008080;"> 72</span> <span style="color: #0000ff;">if</span> (!$<span style="color: #0000ff;">this</span>->isActive($<span style="color: #0000ff;">event</span>-><span style="color: #000000;">action)) { </span><span style="color: #008080;"> 73</span> <span style="color: #0000ff;">return</span><span style="color: #000000;">; </span><span style="color: #008080;"> 74</span> <span style="color: #000000;"> } </span><span style="color: #008080;"> 75</span> <span style="color: #008080;"> 76</span> $<span style="color: #0000ff;">event</span>->isValid = $<span style="color: #0000ff;">this</span>->beforeAction($<span style="color: #0000ff;">event</span>-><span style="color: #000000;">action); </span><span style="color: #008080;"> 77</span> <span style="color: #0000ff;">if</span> ($<span style="color: #0000ff;">event</span>-><span style="color: #000000;">isValid) { </span><span style="color: #008080;"> 78</span> <span style="color: #008000;">//</span><span style="color: #008000;"> call afterFilter only if beforeFilter succeeds beforeFilter 执行成功调用afterFilter </span><span style="color: #008080;"> 79</span> <span style="color: #008000;">//</span><span style="color: #008000;"> beforeFilter and afterFilter should be properly nested 两者要配合应用</span> <span style="color: #008080;"> 80</span> $<span style="color: #0000ff;">this</span>->owner->on(Controller::EVENT_AFTER_ACTION, [$<span style="color: #0000ff;">this</span>, <span style="color: #800000;">'</span><span style="color: #800000;">afterFilter</span><span style="color: #800000;">'</span>], <span style="color: #0000ff;">null</span>, <span style="color: #0000ff;">false</span><span style="color: #000000;">); </span><span style="color: #008080;"> 81</span> } <span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span><span style="color: #008080;"> 82</span> $<span style="color: #0000ff;">event</span>->handled = <span style="color: #0000ff;">true</span><span style="color: #000000;">; </span><span style="color: #008080;"> 83</span> <span style="color: #000000;"> } </span><span style="color: #008080;"> 84</span> <span style="color: #000000;"> } </span><span style="color: #008080;"> 85</span> <span style="color: #008080;"> 86</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 87</span> <span style="color: #008000;"> * @param ActionEvent $event </span><span style="color: #008080;"> 88</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 89</span> <span style="color: #0000ff;">public</span> function afterFilter($<span style="color: #0000ff;">event</span><span style="color: #000000;">) </span><span style="color: #008080;"> 90</span> <span style="color: #000000;"> { </span><span style="color: #008080;"> 91</span> $<span style="color: #0000ff;">event</span>->result = $<span style="color: #0000ff;">this</span>->afterAction($<span style="color: #0000ff;">event</span>->action, $<span style="color: #0000ff;">event</span>-><span style="color: #000000;">result); </span><span style="color: #008080;"> 92</span> $<span style="color: #0000ff;">this</span>->owner->off(Controller::EVENT_AFTER_ACTION, [$<span style="color: #0000ff;">this</span>, <span style="color: #800000;">'</span><span style="color: #800000;">afterFilter</span><span style="color: #800000;">'</span><span style="color: #000000;">]); </span><span style="color: #008080;"> 93</span> <span style="color: #000000;"> } </span><span style="color: #008080;"> 94</span> <span style="color: #008080;"> 95</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;"> 96</span> <span style="color: #008000;"> * This method is invoked right before an action is to be executed (after all possible filters.) </span><span style="color: #008080;"> 97</span> <span style="color: #008000;"> * 此方法是在一个动作之前被调用的( </span><span style="color: #008080;"> 98</span> <span style="color: #008000;"> * You may override this method to do last-minute preparation for the action. </span><span style="color: #008080;"> 99</span> <span style="color: #008000;"> * @param Action $action the action to be executed.要执行的动作 </span><span style="color: #008080;">100</span> <span style="color: #008000;"> * @return boolean whether the action should continue to be executed. </span><span style="color: #008080;">101</span> <span style="color: #008000;"> * 是否应继续执行该动作。 </span><span style="color: #008080;">102</span> <span style="color: #008000;">*/</span> <span style="color: #008080;">103</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> function beforeAction($action) </span><span style="color: #008080;">104</span> <span style="color: #000000;"> { </span><span style="color: #008080;">105</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">; </span><span style="color: #008080;">106</span> <span style="color: #000000;"> } </span><span style="color: #008080;">107</span> <span style="color: #008080;">108</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;">109</span> <span style="color: #008000;"> * This method is invoked right after an action is executed. </span><span style="color: #008080;">110</span> <span style="color: #008000;"> * 此方法是在执行动作之后调用的。 </span><span style="color: #008080;">111</span> <span style="color: #008000;"> * You may override this method to do some postprocessing for the action. </span><span style="color: #008080;">112</span> <span style="color: #008000;"> * @param Action $action the action just executed. 刚刚执行的动作 </span><span style="color: #008080;">113</span> <span style="color: #008000;"> * @param mixed $result the action execution result 行动执行结果 </span><span style="color: #008080;">114</span> <span style="color: #008000;"> * @return mixed the processed action result. 处理结果。 </span><span style="color: #008080;">115</span> <span style="color: #008000;">*/</span> <span style="color: #008080;">116</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> function afterAction($action, $result) </span><span style="color: #008080;">117</span> <span style="color: #000000;"> { </span><span style="color: #008080;">118</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> $result; </span><span style="color: #008080;">119</span> <span style="color: #000000;"> } </span><span style="color: #008080;">120</span> <span style="color: #008080;">121</span> <span style="color: #008000;">/*</span><span style="color: #008000;">* </span><span style="color: #008080;">122</span> <span style="color: #008000;"> * Returns a value indicating whether the filer is active for the given action. </span><span style="color: #008080;">123</span> <span style="color: #008000;"> * 返回一个值,给定的过滤器的行动是否为是积极的。 </span><span style="color: #008080;">124</span> <span style="color: #008000;"> * @param Action $action the action being filtered 被过滤的动作 </span><span style="color: #008080;">125</span> <span style="color: #008000;"> * @return boolean whether the filer is active for the given action. </span><span style="color: #008080;">126</span> <span style="color: #008000;"> * 给定的过滤器的行动是否为是积极的。 </span><span style="color: #008080;">127</span> <span style="color: #008000;">*/</span> <span style="color: #008080;">128</span> <span style="color: #0000ff;">protected</span><span style="color: #000000;"> function isActive($action) </span><span style="color: #008080;">129</span> <span style="color: #000000;"> { </span><span style="color: #008080;">130</span> <span style="color: #0000ff;">if</span> ($<span style="color: #0000ff;">this</span>-><span style="color: #000000;">owner instanceof Module) { </span><span style="color: #008080;">131</span> <span style="color: #008000;">//</span><span style="color: #008000;"> convert action uniqueId into an ID relative to the module</span> <span style="color: #008080;">132</span> $mid = $<span style="color: #0000ff;">this</span>->owner-><span style="color: #000000;">getUniqueId(); </span><span style="color: #008080;">133</span> $id = $action-><span style="color: #000000;">getUniqueId(); </span><span style="color: #008080;">134</span> <span style="color: #0000ff;">if</span> ($mid !== <span style="color: #800000;">''</span> && strpos($id, $mid) === <span style="color: #800080;">0</span><span style="color: #000000;">) { </span><span style="color: #008080;">135</span> $id = substr($id, strlen($mid) + <span style="color: #800080;">1</span><span style="color: #000000;">); </span><span style="color: #008080;">136</span> <span style="color: #000000;"> } </span><span style="color: #008080;">137</span> } <span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span><span style="color: #008080;">138</span> $id = $action-><span style="color: #000000;">id; </span><span style="color: #008080;">139</span> <span style="color: #000000;"> } </span><span style="color: #008080;">140</span> <span style="color: #0000ff;">return</span> !in_array($id, $<span style="color: #0000ff;">this</span>->except, <span style="color: #0000ff;">true</span>) && (empty($<span style="color: #0000ff;">this</span>->only) || in_array($id, $<span style="color: #0000ff;">this</span>->only, <span style="color: #0000ff;">true</span><span style="color: #000000;">)); </span><span style="color: #008080;">141</span> <span style="color: #000000;"> } </span><span style="color: #008080;">142</span> }