DoAction.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. /**
  3. * Author: lf
  4. * Blog: https://blog.feehi.com
  5. * Email: job@feehi.com
  6. * Created at: 2020-04-03 09:50
  7. */
  8. namespace backend\actions;
  9. use Yii;
  10. use Closure;
  11. use stdClass;
  12. use backend\actions\helpers\Helper;
  13. use yii\base\Exception;
  14. use yii\web\Response;
  15. use yii\web\UnprocessableEntityHttpException;
  16. /**
  17. * backend execute action
  18. * Often use to for none page display, and only execute action.
  19. *
  20. * Class DoAction
  21. * @package backend\actions
  22. */
  23. class DoAction extends \yii\base\Action
  24. {
  25. /**
  26. * @var string|array primary key(s) name
  27. */
  28. public $primaryKeyIdentity = null;
  29. /**
  30. * @var string primary keys(s) from (GET or POST)
  31. */
  32. public $primaryKeyFromMethod = "GET";
  33. /** @var string|array success do redirect to url (this value will pass yii::$app->controller->redirect($this->successRedirect) to generate url), default is referer url
  34. */
  35. public $successRedirect = null;
  36. /**
  37. * @var Closure the real do logic
  38. */
  39. public $do;
  40. /**
  41. * @var string after success doUpdate tips message showed in page top
  42. */
  43. public $successTipsMessage = "success";
  44. public function init()
  45. {
  46. parent::init();
  47. if( $this->successTipsMessage === "success"){
  48. $this->successTipsMessage = Yii::t("app", "success");
  49. }
  50. }
  51. /**
  52. * do
  53. *
  54. * @return mixed
  55. * @throws UnprocessableEntityHttpException
  56. * @throws Exception
  57. */
  58. public function run()
  59. {
  60. //according assigned HTTP Method and param name to get value. will be passed to $this->doUpdate closure and $this->data closure.Often use for get value of primary key.
  61. $primaryKeys = Helper::getPrimaryKeys($this->primaryKeyIdentity, $this->primaryKeyFromMethod);
  62. if (!$this->do instanceof Closure) {
  63. throw new Exception(__CLASS__ . "::do must be closure");
  64. }
  65. $postData = Yii::$app->getRequest()->post();
  66. $doData = [];
  67. if (!empty($primaryKeys)) {
  68. foreach ($primaryKeys as $primaryKey) {
  69. array_push($doData, $primaryKey);
  70. }
  71. }
  72. array_push($doData, $postData, $this);
  73. /**
  74. * do action, function(primaryKey1, primaryKey2 ..., $_POST, DoAction)
  75. */
  76. $doResult = call_user_func_array($this->do, $doData);//call do closure
  77. if (Yii::$app->getRequest()->getIsAjax()) { //ajax
  78. if ($doResult === true) {//only $doResult is true represent create success
  79. Yii::$app->getResponse()->format = Response::FORMAT_JSON;
  80. return ['code' => 0, 'msg' => 'success', 'data' => new stdClass()];
  81. } else {//not ajax
  82. throw new UnprocessableEntityHttpException(Helper::getErrorString($doResult));
  83. }
  84. } else {
  85. if ($doResult === true) {//only $doResult is true represent create success
  86. Yii::$app->getSession()->setFlash('success', $this->successTipsMessage);
  87. if ($this->successRedirect) return $this->controller->redirect($this->successRedirect);//if $this->successRedirect not empty will redirect to this url
  88. $url = Yii::$app->getRequest()->getReferrer();
  89. if ($url) return $this->controller->redirect($url);//get an not empty referer will redirect to this url(often, before do page.)
  90. return $this->controller->redirect(["index"]);//default is redirect to current controller index action(attention: if current controller has no index action will get a HTTP 404 error)
  91. } else {
  92. Yii::$app->getSession()->setFlash('error', Helper::getErrorString($doResult));
  93. }
  94. }
  95. }
  96. }