Action.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. /**
  3. * @link https://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license https://www.yiiframework.com/license/
  6. */
  7. namespace yii\base;
  8. use Yii;
  9. /**
  10. * Action is the base class for all controller action classes.
  11. *
  12. * Action provides a way to reuse action method code. An action method in an Action
  13. * class can be used in multiple controllers or in different projects.
  14. *
  15. * Derived classes must implement a method named `run()`. This method
  16. * will be invoked by the controller when the action is requested.
  17. * The `run()` method can have parameters which will be filled up
  18. * with user input values automatically according to their names.
  19. * For example, if the `run()` method is declared as follows:
  20. *
  21. * ```php
  22. * public function run($id, $type = 'book') { ... }
  23. * ```
  24. *
  25. * And the parameters provided for the action are: `['id' => 1]`.
  26. * Then the `run()` method will be invoked as `run(1)` automatically.
  27. *
  28. * For more details and usage information on Action, see the [guide article on actions](guide:structure-controllers).
  29. *
  30. * @template T of Controller
  31. * @property-read string $uniqueId The unique ID of this action among the whole application.
  32. * @phpstan-property T $controller
  33. * @psalm-property T $controller
  34. *
  35. * @author Qiang Xue <qiang.xue@gmail.com>
  36. * @since 2.0
  37. */
  38. class Action extends Component
  39. {
  40. /**
  41. * @var string ID of the action
  42. */
  43. public $id;
  44. /**
  45. * @var Controller|\yii\web\Controller|\yii\console\Controller the controller that owns this action
  46. *
  47. * @phpstan-var T
  48. * @psalm-var T
  49. */
  50. public $controller;
  51. /**
  52. * Constructor.
  53. *
  54. * @param string $id the ID of this action
  55. * @param Controller $controller the controller that owns this action
  56. * @param array $config name-value pairs that will be used to initialize the object properties
  57. *
  58. * @phpstan-param array<string, mixed> $config
  59. * @psalm-param array<string, mixed> $config
  60. */
  61. public function __construct($id, $controller, $config = [])
  62. {
  63. $this->id = $id;
  64. $this->controller = $controller;
  65. parent::__construct($config);
  66. }
  67. /**
  68. * Returns the unique ID of this action among the whole application.
  69. *
  70. * @return string the unique ID of this action among the whole application.
  71. */
  72. public function getUniqueId()
  73. {
  74. return $this->controller->getUniqueId() . '/' . $this->id;
  75. }
  76. /**
  77. * Runs this action with the specified parameters.
  78. * This method is mainly invoked by the controller.
  79. *
  80. * @param array $params the parameters to be bound to the action's run() method.
  81. * @return mixed the result of the action
  82. * @throws InvalidConfigException if the action class does not have a run() method
  83. */
  84. public function runWithParams($params)
  85. {
  86. if (!method_exists($this, 'run')) {
  87. throw new InvalidConfigException(get_class($this) . ' must define a "run()" method.');
  88. }
  89. $args = $this->controller->bindActionParams($this, $params);
  90. Yii::debug('Running action: ' . get_class($this) . '::run(), invoked by ' . get_class($this->controller), __METHOD__);
  91. if (Yii::$app->requestedParams === null) {
  92. Yii::$app->requestedParams = $args;
  93. }
  94. if ($this->beforeRun()) {
  95. $result = call_user_func_array([$this, 'run'], $args);
  96. $this->afterRun();
  97. return $result;
  98. }
  99. return null;
  100. }
  101. /**
  102. * This method is called right before `run()` is executed.
  103. * You may override this method to do preparation work for the action run.
  104. * If the method returns false, it will cancel the action.
  105. *
  106. * @return bool whether to run the action.
  107. */
  108. protected function beforeRun()
  109. {
  110. return true;
  111. }
  112. /**
  113. * This method is called right after `run()` is executed.
  114. * You may override this method to do post-processing work for the action run.
  115. */
  116. protected function afterRun()
  117. {
  118. }
  119. }