EditableAction.php 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2013 2amigOS! Consulting Group LLC
  4. * @link http://2amigos.us
  5. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  6. */
  7. namespace dosamigos\editable;
  8. use Yii;
  9. use yii\base\Action;
  10. use yii\base\InvalidConfigException;
  11. use yii\web\BadRequestHttpException;
  12. /**
  13. * EditableAction is a server side Action that helps to update the record in db.
  14. *
  15. * @author Antonio Ramirez <amigo.cobos@gmail.com>
  16. * @link http://www.ramirezcobos.com/
  17. * @link http://www.2amigos.us/
  18. * @package dosamigos\editable
  19. */
  20. class EditableAction extends Action
  21. {
  22. /**
  23. * @var string the class name to handle
  24. */
  25. public $modelClass;
  26. /**
  27. * @var string the scenario to be used (optional)
  28. */
  29. public $scenario;
  30. /**
  31. * @var \Closure a function to be called previous saving model. The anonymous function is preferable to have the
  32. * model passed by reference. This is useful when we need to set model with extra data previous update.
  33. */
  34. public $preProcess;
  35. /**
  36. * @var bool whether to create a model if a primary key parameter was not found.
  37. */
  38. public $forceCreate = true;
  39. /**
  40. * @inheritdoc
  41. * @throws \yii\base\InvalidConfigException
  42. */
  43. public function init()
  44. {
  45. if ($this->modelClass === null) {
  46. throw new InvalidConfigException("'modelClass' cannot be empty.");
  47. }
  48. }
  49. /**
  50. * Runs the action
  51. * @return bool
  52. * @throws BadRequestHttpException
  53. */
  54. public function run()
  55. {
  56. $class = $this->modelClass;
  57. $pk = Yii::$app->request->post('pk');
  58. $pk = unserialize(base64_decode($pk));
  59. $attribute = Yii::$app->request->post('name');
  60. $value = Yii::$app->request->post('value');
  61. if ($attribute === null) {
  62. throw new BadRequestHttpException("'name' parameter cannot be empty.");
  63. }
  64. if ($value === null) {
  65. throw new BadRequestHttpException("'value' parameter cannot be empty.");
  66. }
  67. /** @var \Yii\db\ActiveRecord $model */
  68. $model = $class::findOne($pk);
  69. if (!$model) {
  70. if ($this->forceCreate) { // only useful for models with one editable attribute or no validations
  71. $model = new $class;
  72. } else {
  73. throw new BadRequestHttpException('Entity not found by primary key ' . $pk);
  74. }
  75. }
  76. // do we have a preProcess function
  77. if ($this->preProcess && is_callable($this->preProcess, true)) {
  78. call_user_func($this->preProcess, $model);
  79. }
  80. if ($this->scenario !== null) {
  81. $model->setScenario($this->scenario);
  82. }
  83. $model->$attribute = $value;
  84. if ($model->validate([$attribute])) {
  85. // no need to specify which attributes as Yii2 handles that via [[BaseActiveRecord::getDirtyAttributes]]
  86. return $model->save(false);
  87. } else {
  88. throw new BadRequestHttpException($model->getFirstError($attribute));
  89. }
  90. }
  91. }