Skip to content

Commit 3d0992d

Browse files
author
Igor Chepurnoy
committed
added base64_encode for pk value, update EditableAction
1 parent 8b66bfd commit 3d0992d

File tree

3 files changed

+64
-45
lines changed

3 files changed

+64
-45
lines changed

Editable.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ class Editable extends InputWidget
3333
*/
3434
public $mode = 'inline';
3535

36+
/**
37+
* @var string placement of bootstrap popover
38+
*/
39+
public $placement = 'top';
40+
3641
/**
3742
* @var string|array Url for submit, e.g. '/post'
3843
*/
@@ -69,9 +74,9 @@ public function init()
6974
*/
7075
public function run()
7176
{
72-
$linkText = $this->getLinkText();
73-
echo Html::a($linkText, null, $this->options);
7477
$this->registerClientScript();
78+
79+
return Html::a($this->getLinkText(), null, $this->options);
7580
}
7681

7782
/**
@@ -99,9 +104,6 @@ protected function registerClientScript()
99104
$id = ArrayHelper::remove($this->pluginOptions, 'selector', '#' . $this->options['id']);
100105
$id = preg_replace('/([.])/', '\\\\\\\$1', $id);
101106

102-
if ($this->hasActiveRecord() && $this->model->isNewRecord) {
103-
$this->pluginOptions['send'] = 'always'; // send to server without pk
104-
}
105107
$pluginOptions = $this->getPluginOptions();
106108
$js = "jQuery('$id').editable($pluginOptions);";
107109
$view->registerJs($js);
@@ -122,11 +124,16 @@ public function getPluginOptions()
122124
'pk',
123125
$this->hasActiveRecord() ? $this->model->getPrimaryKey() : null
124126
);
125-
$this->pluginOptions['pk'] = $pk;
127+
$this->pluginOptions['pk'] = base64_encode(serialize($pk));
126128
$this->pluginOptions['url'] = $this->url instanceof JsExpression ? $this->url : Url::toRoute($this->url);
127129
$this->pluginOptions['type'] = $this->type;
128130
$this->pluginOptions['mode'] = $this->mode;
129131
$this->pluginOptions['name'] = $this->attribute ?: $this->name;
132+
$this->pluginOptions['placement'] = $this->placement;
133+
134+
if ($this->hasActiveRecord() && $this->model->isNewRecord) {
135+
$this->pluginOptions['send'] = 'always';
136+
}
130137

131138
return Json::encode($this->pluginOptions);
132139
}

EditableAction.php

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Yii;
66
use yii\base\Action;
77
use yii\base\InvalidConfigException;
8+
use yii\base\Model;
89
use yii\web\BadRequestHttpException;
910

1011
/**
@@ -22,7 +23,7 @@ class EditableAction extends Action
2223
/**
2324
* @var string the scenario to be used (optional)
2425
*/
25-
public $scenario;
26+
public $scenario = Model::SCENARIO_DEFAULT;
2627

2728
/**
2829
* @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
3334
/**
3435
* @var bool whether to create a model if a primary key parameter was not found
3536
*/
36-
public $forceCreate = true;
37+
public $forceCreate = false;
3738

3839
/**
3940
* @var string default pk column name
@@ -42,13 +43,11 @@ class EditableAction extends Action
4243

4344
/**
4445
* @inheritdoc
45-
*
46-
* @throws \yii\base\InvalidConfigException
4746
*/
4847
public function init()
4948
{
5049
if ($this->modelClass === null) {
51-
throw new InvalidConfigException('ModelClass cannot be empty.');
50+
throw new InvalidConfigException('The "modelClass" property must be set.');
5251
}
5352
}
5453

@@ -61,50 +60,63 @@ public function init()
6160
*/
6261
public function run()
6362
{
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+
{
6687
$attribute = Yii::$app->request->post('name');
67-
//For attributes with format - relationName.attributeName
88+
6889
if (strpos($attribute, '.')) {
6990
$attributeParts = explode('.', $attribute);
7091
$attribute = array_pop($attributeParts);
7192
}
72-
$value = Yii::$app->request->post('value');
7393

7494
if ($attribute === null) {
7595
throw new BadRequestHttpException('Attribute cannot be empty.');
7696
}
7797

78-
if ($value === null) {
79-
throw new BadRequestHttpException('Value cannot be empty.');
80-
}
98+
return $attribute;
99+
}
81100

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;
83110
$model = $class::findOne(is_array($pk) ? $pk : [$this->pkColumn => $pk]);
111+
84112
if (!$model) {
85-
if ($this->forceCreate) { // only useful for models with one editable attribute or no validations
113+
if ($this->forceCreate) {
86114
$model = new $class();
87115
} else {
88116
throw new BadRequestHttpException('Entity not found by primary key ' . $pk);
89117
}
90118
}
91119

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;
109121
}
110122
}

EditableColumn.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,20 @@ class EditableColumn extends DataColumn
3939
*/
4040
public $type = 'text';
4141

42+
/**
43+
* @var string
44+
*/
45+
public $format = 'raw';
46+
4247
/**
4348
* @inheritdoc
44-
*
45-
* @throws \yii\base\InvalidConfigException
4649
*/
4750
public function init()
4851
{
49-
if ($this->url === null) {
50-
throw new InvalidConfigException('Url can not be empty.');
51-
}
5252
parent::init();
5353

54-
if (!$this->format) {
55-
$this->format = 'raw';
54+
if ($this->url === null) {
55+
throw new InvalidConfigException('The "url" property must be set.');
5656
}
5757

5858
$rel = $this->attribute . '_editable' . $this->classSuffix;
@@ -76,7 +76,7 @@ protected function renderDataCellContent($model, $key, $index)
7676
$value = parent::renderDataCellContent($model, $key, $index);
7777
$url = (array)$this->url;
7878
$this->options['data-url'] = Url::to($url);
79-
$this->options['data-pk'] = $key;
79+
$this->options['data-pk'] = base64_encode(serialize($key));
8080
$this->options['data-name'] = $this->attribute;
8181
$this->options['data-type'] = $this->type;
8282

0 commit comments

Comments
 (0)