1 <?php
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
18
19 Yii::import('yiiwheels.widgets.editable.WhEditable');
20
21 class WhEditableField extends WhEditable
22 {
23 24 25
26 public $model = null;
27
28 29 30
31 public $attribute = null;
32
33 34 35 36 37
38 private $staticModel = null;
39
40
41 42 43 44
45 public function init()
46 {
47 if (!$this->model) {
48 throw new CException('Parameter "model" should be provided for EditableField');
49 }
50
51 if (!$this->attribute) {
52 throw new CException('Parameter "attribute" should be provided for EditableField');
53 }
54
55 $originalModel = $this->model;
56 $originalAttribute = $this->attribute;
57 $originalText = strlen($this->text) ? $this->text : CHtml::value($this->model, $this->attribute);
58
59
60 if ($this->apply === false) {
61 $this->text = $originalText;
62 } else {
63 $this->apply = true;
64 }
65
66
67 $resolved = $this->resolveModels($this->model, $this->attribute);
68 $this->model = $resolved['model'];
69 $this->attribute = $resolved['attribute'];
70 $this->staticModel = $resolved['staticModel'];
71 $staticModel = $this->staticModel;
72 $isMongo = $resolved['isMongo'];
73 $isFormModel = $this->model instanceOf CFormModel;
74
75
76 if (!$this->model) {
77 $this->apply = false;
78 $this->text = $originalText;
79 }
80
81
82
83
84 if (!$staticModel->isAttributeSafe($this->attribute)) {
85 $this->apply = false;
86 $this->text = $originalText;
87 }
88
89 90 91
92 if ($this->type === null) {
93 $this->type = 'text';
94 if (!$isMongo && !$isFormModel && array_key_exists($this->attribute, $staticModel->tableSchema->columns)) {
95 $dbType = $staticModel->tableSchema->columns[$this->attribute]->dbType;
96 if ($dbType == 'date') {
97 $this->type = 'date';
98 }
99 if ($dbType == 'datetime') {
100 $this->type = 'datetime';
101 }
102 if (stripos($dbType, 'text') !== false) {
103 $this->type = 'textarea';
104 }
105 }
106 }
107
108
109 if (empty($this->name)) {
110 $this->name = $isMongo ? $originalAttribute : $this->attribute;
111 }
112
113
114 $pkModel = $isMongo ? $originalModel : $this->model;
115 if (!$isFormModel) {
116 if ($pkModel && !$pkModel->isNewRecord) {
117 $this->pk = $pkModel->primaryKey;
118 }
119 } else {
120
121 if (empty($this->send) && empty($this->options['send'])) {
122 $this->send = 'always';
123 }
124 }
125
126 parent::init();
127
128 129 130 131 132
133 if (!strlen($this->text) && !$this->_prepareToAutotext) {
134 $this->text = $originalText;
135 }
136
137
138 if ($this->model && $this->_prepareToAutotext) {
139 $this->value = CHtml::value($this->model, $this->attribute);
140 }
141
142
143 if ($this->title === null) {
144 $titles = array(
145 'Select' => array('select', 'date'),
146 'Check' => array('checklist')
147 );
148 $title = Yii::t('EditableField.editable', 'Enter');
149 foreach ($titles as $t => $types) {
150 if (in_array($this->type, $types)) {
151 $title = Yii::t('EditableField.editable', $t);
152 }
153 }
154 $this->title = $title . ' ' . $staticModel->getAttributeLabel($this->attribute);
155 } else {
156 $this->title = strtr($this->title, array('{label}' => $staticModel->getAttributeLabel($this->attribute)));
157 }
158
159
160 if ($pkModel && !isset($this->params['scenario'])) {
161 $this->params['scenario'] = $pkModel->getScenario();
162 }
163 }
164
165 166 167 168
169 public function getSelector()
170 {
171 return str_replace('\\', '_', get_class($this->staticModel)) . '_' . parent::getSelector();
172 }
173
174
175 176 177 178 179 180 181
182 public static function isMongo($model)
183 {
184 return in_array('EMongoEmbeddedDocument', class_parents($model, false));
185 }
186
187 188 189 190 191 192 193 194 195 196 197
198 public static function resolveModels($model, $attribute)
199 {
200
201 $explode = explode('.', $attribute);
202 $len = count($explode);
203
204 $isMongo = self::isMongo($model);
205
206 if ($len > 1) {
207 $attribute = $explode[$len - 1];
208
209 $resolved = true;
210 for ($i = 0; $i < $len - 1; $i++) {
211 $name = $explode[$i];
212 if ($model->$name instanceof CModel) {
213 $model = $model->$name;
214 } else {
215
216
217 $resolved = false;
218
219 break;
220 }
221 }
222
223 if ($resolved) {
224 $staticModel = $model;
225 } else {
226 $relationName = $explode[$len - 2];
227 if ($model instanceof CActiveRecord) {
228 $className = $model->getActiveRelation($relationName)->className;
229 } elseif ($isMongo) {
230 $embedded = $model->embeddedDocuments();
231 if (isset($embedded[$relationName])) {
232 $className = $embedded[$relationName];
233 } else {
234 throw new CException('Embedded relation not found');
235 }
236 } else {
237 throw new CException('Unsupported model class ' . $relationName);
238 }
239 $staticModel = new $className();
240 $model = null;
241 }
242 } else {
243 $staticModel = $model;
244 }
245
246 return array(
247 'model' => $model,
248 'staticModel' => $staticModel,
249 'attribute' => $attribute,
250 'isMongo' => $isMongo
251 );
252 }
253 }
254