1 <?php
2 3 4 5 6 7 8 9 10 11 12
13
14 class EditableSaver extends CComponent
15 {
16 17 18 19 20
21 public $scenario = 'editable';
22
23 24 25 26 27
28 public $modelClass;
29 30 31 32 33
34 public $primaryKey;
35 36 37 38 39
40 public $attribute;
41 42 43 44 45
46 public $model;
47
48 49 50
51 public $errorHttpCode = 400;
52
53 54 55 56 57
58 protected $changedAttributes = array();
59
60 61 62 63 64 65
66 public function __construct($modelClass)
67 {
68 if (empty($modelClass)) {
69 throw new CException(Yii::t('editable', 'You should provide modelClass in constructor of EditableSaver.'));
70 }
71 $this->modelClass = ucfirst($modelClass);
72 }
73
74 75 76 77
78 public function update()
79 {
80
81 $this->primaryKey = yii::app()->request->getParam('pk');
82 $this->attribute = yii::app()->request->getParam('name');
83 $value = yii::app()->request->getParam('value');
84
85
86 if (empty($this->attribute)) {
87 throw new CException(Yii::t('editable','Property "attribute" should be defined.'));
88 }
89 if (empty($this->primaryKey)) {
90 throw new CException(Yii::t('editable','Property "primaryKey" should be defined.'));
91 }
92
93
94 $this->model = CActiveRecord::model($this->modelClass)->findByPk($this->primaryKey);
95 if (!$this->model) {
96 throw new CException(Yii::t('editable', 'Model {class} not found by primary key "{pk}"', array(
97 '{class}'=>get_class($this->model), '{pk}'=>$this->primaryKey)));
98 }
99 $this->model->setScenario($this->scenario);
100
101
102 if (!$this->model->hasAttribute($this->attribute)) {
103 throw new CException(Yii::t('editable', 'Model {class} does not have attribute "{attr}"', array(
104 '{class}'=>get_class($this->model), '{attr}'=>$this->attribute)));
105 }
106
107
108 if (!$this->model->isAttributeSafe($this->attribute)) {
109 throw new CException(Yii::t('editable', 'Model {class} rules do not allow to update attribute "{attr}"', array(
110 '{class}'=>get_class($this->model), '{attr}'=>$this->attribute)));
111 }
112
113
114 $this->setAttribute($this->attribute, $value);
115
116
117 $this->model->validate(array($this->attribute));
118 if ($this->model->hasErrors()) {
119 $this->error($this->model->getError($this->attribute));
120 }
121
122
123 if ($this->beforeUpdate()) {
124
125 if ($this->model->save(false, $this->changedAttributes)) {
126 $this->afterUpdate();
127 } else {
128 $this->error(Yii::t('editable', 'Error while saving record!'));
129 }
130 } else {
131 $firstError = reset($this->model->getErrors());
132 $this->error($firstError[0]);
133 }
134 }
135
136 137 138 139
140 public function onBeforeUpdate($event)
141 {
142 $this->raiseEvent('onBeforeUpdate', $event);
143 }
144
145 146 147 148
149 public function onAfterUpdate($event)
150 {
151 $this->raiseEvent('onAfterUpdate', $event);
152 }
153
154 155 156 157 158
159 protected function error($msg)
160 {
161 throw new CHttpException($this->errorHttpCode, $msg);
162 }
163
164 165 166 167
168 protected function beforeUpdate()
169 {
170 $this->onBeforeUpdate(new CEvent($this));
171 return !$this->model->hasErrors();
172 }
173
174 175 176 177
178 protected function afterUpdate()
179 {
180 $this->onAfterUpdate(new CEvent($this));
181 }
182
183 184 185 186 187 188 189
190 public function setAttribute($name, $value)
191 {
192 $this->model->$name = $value;
193 $this->changedAttributes[] = $name;
194 $this->changedAttributes = array_unique($this->changedAttributes);
195 }
196 }
197