5
5
use Yii ;
6
6
use yii \base \Action ;
7
7
use yii \base \InvalidConfigException ;
8
+ use yii \base \Model ;
8
9
use yii \web \BadRequestHttpException ;
9
10
10
11
/**
@@ -22,7 +23,7 @@ class EditableAction extends Action
22
23
/**
23
24
* @var string the scenario to be used (optional)
24
25
*/
25
- public $ scenario ;
26
+ public $ scenario = Model:: SCENARIO_DEFAULT ;
26
27
27
28
/**
28
29
* @var \Closure a function to be called previous saving model. The anonymous function is preferable to have the
@@ -33,7 +34,7 @@ class EditableAction extends Action
33
34
/**
34
35
* @var bool whether to create a model if a primary key parameter was not found
35
36
*/
36
- public $ forceCreate = true ;
37
+ public $ forceCreate = false ;
37
38
38
39
/**
39
40
* @var string default pk column name
@@ -42,13 +43,11 @@ class EditableAction extends Action
42
43
43
44
/**
44
45
* @inheritdoc
45
- *
46
- * @throws \yii\base\InvalidConfigException
47
46
*/
48
47
public function init ()
49
48
{
50
49
if ($ this ->modelClass === null ) {
51
- throw new InvalidConfigException ('ModelClass cannot be empty . ' );
50
+ throw new InvalidConfigException ('The "modelClass" property must be set . ' );
52
51
}
53
52
}
54
53
@@ -61,50 +60,63 @@ public function init()
61
60
*/
62
61
public function run ()
63
62
{
64
- $ class = $ this ->modelClass ;
65
- $ pk = Yii::$ app ->request ->post ('pk ' );
63
+ $ model = $ this ->findModelOrCreate ();
64
+ $ attribute = $ this ->getModelAttribute ();
65
+
66
+ if ($ this ->preProcess && is_callable ($ this ->preProcess , true )) {
67
+ call_user_func ($ this ->preProcess , $ model );
68
+ }
69
+
70
+ $ model ->setScenario ($ this ->scenario );
71
+ $ model ->$ attribute = Yii::$ app ->request ->post ('value ' );
72
+
73
+ if ($ model ->validate ([$ attribute ])) {
74
+ return $ model ->save (false );
75
+ } else {
76
+ throw new BadRequestHttpException ($ model ->getFirstError ($ attribute ));
77
+ }
78
+ }
79
+
80
+ /**
81
+ * @return array|mixed
82
+ *
83
+ * @throws BadRequestHttpException
84
+ */
85
+ private function getModelAttribute ()
86
+ {
66
87
$ attribute = Yii::$ app ->request ->post ('name ' );
67
- //For attributes with format - relationName.attributeName
88
+
68
89
if (strpos ($ attribute , '. ' )) {
69
90
$ attributeParts = explode ('. ' , $ attribute );
70
91
$ attribute = array_pop ($ attributeParts );
71
92
}
72
- $ value = Yii::$ app ->request ->post ('value ' );
73
93
74
94
if ($ attribute === null ) {
75
95
throw new BadRequestHttpException ('Attribute cannot be empty. ' );
76
96
}
77
97
78
- if ($ value === null ) {
79
- throw new BadRequestHttpException ('Value cannot be empty. ' );
80
- }
98
+ return $ attribute ;
99
+ }
81
100
82
- /** @var \Yii\db\ActiveRecord $model */
101
+ /**
102
+ * @return yii\db\ActiveRecord
103
+ *
104
+ * @throws BadRequestHttpException
105
+ */
106
+ private function findModelOrCreate ()
107
+ {
108
+ $ pk = unserialize (base64_decode (Yii::$ app ->request ->post ('pk ' )));
109
+ $ class = $ this ->modelClass ;
83
110
$ model = $ class ::findOne (is_array ($ pk ) ? $ pk : [$ this ->pkColumn => $ pk ]);
111
+
84
112
if (!$ model ) {
85
- if ($ this ->forceCreate ) { // only useful for models with one editable attribute or no validations
113
+ if ($ this ->forceCreate ) {
86
114
$ model = new $ class ();
87
115
} else {
88
116
throw new BadRequestHttpException ('Entity not found by primary key ' . $ pk );
89
117
}
90
118
}
91
119
92
- // do we have a preProcess function
93
- if ($ this ->preProcess && is_callable ($ this ->preProcess , true )) {
94
- call_user_func ($ this ->preProcess , $ model );
95
- }
96
-
97
- if ($ this ->scenario !== null ) {
98
- $ model ->setScenario ($ this ->scenario );
99
- }
100
-
101
- $ model ->$ attribute = $ value ;
102
-
103
- if ($ model ->validate ([$ attribute ])) {
104
- // no need to specify which attributes as Yii2 handles that via [[BaseActiveRecord::getDirtyAttributes]]
105
- return $ model ->save (false );
106
- } else {
107
- throw new BadRequestHttpException ($ model ->getFirstError ($ attribute ));
108
- }
120
+ return $ model ;
109
121
}
110
122
}
0 commit comments