1 : <?php
2 :
3 :
4 :
5 :
6 :
7 : class BasicRelationsModel extends CActiveRecord {
8 :
9 : protected $_magic_attributes=array();
10 :
11 :
12 :
13 :
14 : protected $_eligible_for_delete=array();
15 :
16 :
17 :
18 :
19 : protected $_relation_updated=array();
20 :
21 :
22 :
23 :
24 :
25 :
26 :
27 :
28 : protected $_delete_commands=array ();
29 :
30 :
31 :
32 :
33 :
34 :
35 :
36 :
37 : protected $_insert_commands=array ();
38 :
39 :
40 : protected $cascade_on_delete=false;
41 :
42 :
43 :
44 :
45 :
46 :
47 :
48 : public function pivots() {
49 0 : return array();
50 : }
51 :
52 :
53 :
54 :
55 :
56 :
57 :
58 : public function idPresent ($check_for_id) {
59 3 : if (empty ($check_for_id))
60 3 : return false;
61 3 : $primary_key=$this->tableSchema->primaryKey;
62 3 : if (Yii::app()->db->createCommand()
63 3 : ->select($primary_key)
64 3 : ->from($this->tableName())
65 3 : ->where($primary_key.'=:id', array (':id'=>$check_for_id))
66 3 : ->queryRow() )
67 3 : return true;
68 1 : return false;
69 : }
70 :
71 :
72 :
73 :
74 :
75 : public function refresh () {
76 0 : $this->_magic_attributes=array();
77 0 : return parent::refresh();
78 : }
79 :
80 :
81 :
82 :
83 :
84 :
85 :
86 : public function magicRelationEligibleForDelete ($relation_name, $relation_object) {
87 0 : $relations=$this->relations();
88 0 : $relation_primary_key=$relation_object->tableSchema->primaryKey;
89 :
90 0 : $pk=$relation_object->$relation_primary_key;
91 0 : if (isset ($this->_relation_updated[$relation_name][$pk]))
92 0 : unset ($this->_relation_updated[$relation_name][$pk]);
93 0 : $this->_eligible_for_delete[]=$relation_object;
94 0 : }
95 :
96 :
97 :
98 :
99 :
100 :
101 : public function magicRelationUpdated ($relation_name, $relation_object) {
102 :
103 4 : $relations=$this->relations();
104 4 : $relation_settings=$relations[$relation_name];
105 4 : $relation_primary_key=$relation_object->tableSchema->primaryKey;
106 4 : $attributes=$relation_object->attributes;
107 :
108 4 : unset ($attributes[$relation_primary_key]);
109 :
110 4 : unset ($attributes[$relation_settings[2]]);
111 4 : if (empty ($attributes)) {
112 :
113 0 : $this->magicRelationEligibleForDelete ($relation_name, $relation_object);
114 0 : return;
115 : }
116 :
117 4 : if (!isset ($this->_relation_updated[$relation_name]))
118 4 : $this->_relation_updated[$relation_name]=array ('new' => array());
119 4 : if ($relation_object->isNewRecord) {
120 3 : $this->_relation_updated[$relation_name]['new'][]=$relation_object;
121 3 : } else {
122 1 : $pk=$relation_object->$relation_primary_key;
123 1 : $this->_relation_updated[$relation_name][$pk]=$relation_object;
124 : }
125 4 : }
126 :
127 :
128 :
129 :
130 :
131 : public function setPost_Attributes($POST) {
132 1 : if (!isset ($POST[get_class ($this)]))
133 1 : return;
134 1 : $this->attributes=$POST[get_class ($this)];
135 1 : foreach ($this->relations() as $relation_name => $relation_settings) {
136 1 : $relation_type=$relation_settings[0];
137 1 : $relation_class=$relation_settings[1];
138 1 : $relation_fk=$relation_settings[2];
139 : switch ($relation_type) {
140 :
141 1 : case 'CHasOneRelation':
142 1 : if ($this->isNewRecord || empty ($this->$relation_name)) {
143 1 : if (!isset ($POST[$relation_class]))
144 1 : continue;
145 :
146 1 : $this->$relation_name=new $relation_class;
147 1 : } elseif (!isset ($POST[$relation_class])) {
148 0 : $this->$relation_name->unsetAttributes();
149 0 : $this->magicRelationUpdated ($relation_name, $this->$relation_name);
150 0 : $this->$relation_name=null;
151 0 : continue;
152 : }
153 1 : $this->$relation_name->attributes=$POST[$relation_class];
154 1 : $this->magicRelationUpdated ($relation_name, $this->$relation_name);
155 1 : break;
156 :
157 1 : case 'CHasManyRelation':
158 1 : if ($this->isNewRecord || empty ($this->$relation_name)) {
159 :
160 1 : $model_list=array ();
161 1 : foreach ($POST[$relation_class] as $post_attributes) {
162 1 : $model=new $relation_class;
163 1 : $model->attributes=$post_attributes;
164 1 : $this->magicRelationUpdated ($relation_name, $model);
165 1 : $model_list[]=$model;
166 1 : }
167 1 : $this->$relation_name=$model_list;
168 1 : } else {
169 0 : $model_list=array ();
170 0 : $delete_models=$this->$relation_name;
171 :
172 0 : $relation_pk=$relation_class::model()->tableSchema->primaryKey;
173 0 : if (!empty ($POST[$relation_class])) {
174 0 : $post_attribute_list=$POST[$relation_class];
175 0 : foreach ($delete_models as $delete_models_key => $model) {
176 0 : foreach ($post_attribute_list as $post_attributes_key => $post_attributes) {
177 :
178 0 : if ($post_attributes[$relation_pk] === $model->$relation_pk) {
179 :
180 0 : $model->attributes=$post_attributes;
181 0 : $this->magicRelationUpdated ($relation_name, $model);
182 0 : $model_list[]=$model;
183 :
184 0 : unset ($delete_models[$delete_models_key]);
185 0 : unset ($post_attribute_list[$post_attributes_key]);
186 0 : continue 2;
187 : }
188 0 : }
189 0 : }
190 :
191 :
192 0 : if (!empty ($post_attribute_list)) {
193 0 : foreach ($post_attribute_list as $post_attributes) {
194 0 : $model=new $relation_class;
195 0 : $model->attributes=$post_attributes;
196 0 : $this->magicRelationUpdated ($relation_name, $model);
197 0 : $model_list[]=$model;
198 0 : }
199 0 : }
200 0 : $this->$relation_name=$model_list;
201 :
202 :
203 :
204 0 : }
205 :
206 0 : if (!empty ($delete_models)) {
207 0 : foreach ($delete_models as $model) {
208 0 : $this->magicRelationEligibleForDelete ($relation_name, $model);
209 0 : }
210 0 : }
211 : }
212 1 : break;
213 :
214 1 : case 'CManyManyRelation':
215 1 : $pivots=$this->pivots();
216 1 : if (isset ($pivots[$relation_name])) {
217 :
218 0 : } else {
219 :
220 : }
221 :
222 :
223 :
224 :
225 :
226 :
227 :
228 :
229 :
230 1 : break;
231 : }
232 1 : }
233 1 : }
234 :
235 :
236 :
237 :
238 :
239 :
240 :
241 : public function magicRelationHasOneRead ($relation_name, $relation_column_name) {
242 1 : if (empty ($this->$relation_name))
243 1 : return null;
244 1 : return $this->$relation_name->$relation_column_name;
245 : }
246 :
247 :
248 :
249 :
250 :
251 : public function magicRelationHasOneWrite ($relation_name, $relation_column_name, $new_value) {
252 3 : if (empty ($new_value)) {
253 0 : if (!empty ($this->$relation_name)) {
254 :
255 0 : $this->$relation_name->$relation_column_name=null;
256 0 : $this->magicRelationUpdated ($relation_name, $this->$relation_name);
257 0 : }
258 0 : return;
259 : }
260 3 : if (empty ($this->$relation_name)) {
261 :
262 2 : $relations=$this->relations();
263 2 : $this->$relation_name=new $relations[$relation_name][1];
264 2 : if (!$this->isNewRecord) {
265 0 : $primary_key=$this->tableSchema->primaryKey;
266 0 : $this->$relation_name->$relations[$relation_name][2]=$this->$primary_key;
267 0 : }
268 2 : }
269 3 : $this->$relation_name->$relation_column_name=$new_value;
270 3 : $this->magicRelationUpdated ($relation_name, $this->$relation_name);
271 3 : }
272 :
273 :
274 :
275 :
276 :
277 :
278 : public function magicRelationHasOneValidate ($relation_name, $relation_column_name, $magic_attribute_name, $params) {
279 5 : if (empty ($this->$relation_name))
280 5 : return;
281 3 : if ($this->$relation_name->validate ($relation_column_name))
282 3 : return;
283 1 : $errors=array ($magic_attribute_name => $this->$relation_name->getErrors ($relation_column_name));
284 1 : $this->addErrors ($errors);
285 1 : }
286 :
287 :
288 :
289 :
290 :
291 : public function magicRelationHasManyRead ($relation_name) {
292 0 : if (empty ($this->$relation_name))
293 0 : return array ();
294 0 : if (isset ($this->_magic_attributes[$relation_name]))
295 0 : return $this->_magic_attributes[$relation_name];
296 0 : $relations=$this->relations();
297 0 : $relation_settings=$relations[$relation_name];
298 0 : $all_related_attributes=array ();
299 0 : foreach ($this->$relation_name as $related_object) {
300 0 : $related_object_attributes=$related_object->attributes;
301 0 : unset ($related_object_attributes[$relation_settings[2]]);
302 :
303 0 : $all_related_attributes[]=$related_object_attributes;
304 0 : }
305 0 : return $this->_magic_attributes[$relation_name]=$all_related_attributes;
306 : }
307 :
308 :
309 :
310 :
311 :
312 :
313 :
314 : public function magicRelationHasManyWrite ($new_values) {
315 0 : }
316 :
317 :
318 :
319 :
320 :
321 :
322 :
323 : public function magicRelationHasManyValidate ($relation_name) {
324 0 : }
325 :
326 :
327 :
328 :
329 :
330 :
331 : public function magicRelationManyManyAdd () {
332 0 : }
333 :
334 :
335 :
336 :
337 :
338 : public function magicRelationManyManyDel () {
339 0 : }
340 :
341 :
342 :
343 :
344 :
345 : public function magicRelationManyManySet () {
346 0 : }
347 :
348 :
349 :
350 : public function getAllErrors () {
351 0 : $errors=$this->getErrors();
352 0 : $relations=$this->relations();
353 0 : if (empty ($relations))
354 0 : return $errors;
355 0 : foreach ($relations as $relation_name => $relation_settings) {
356 0 : if (empty ($this->$relation_name))
357 0 : continue;
358 0 : if (is_object ($this->$relation_name)) {
359 0 : if (!empty ($this->$relation_name->errors))
360 0 : $errors[$relation_name]=$this->$relation_name->getErrors ();
361 0 : } elseif (is_array ($this->$relation_name)) {
362 0 : $errors[$relation_name]=array ();
363 0 : foreach ($this->$relation_name as $related_key => $related_model) {
364 0 : if (!empty ($related_model->errors))
365 0 : $errors[$relation_name][$related_key]=$related_model->getErrors ();
366 0 : }
367 0 : if (empty ($errors[$relation_name]))
368 0 : unset ($errors[$relation_name]);
369 0 : }
370 0 : }
371 0 : return $errors;
372 : }
373 :
374 :
375 :
376 :
377 :
378 :
379 :
380 : public function beforeSave () {
381 :
382 :
383 2 : if (!empty ($this->_eligible_for_delete)) {
384 0 : foreach ($this->_eligible_for_delete as $related_object) {
385 0 : $related_object->delete();
386 0 : }
387 0 : }
388 2 : return parent::beforeSave();
389 : }
390 :
391 :
392 :
393 :
394 :
395 : protected function afterSave () {
396 :
397 2 : if (!empty ($this->_relation_updated)) {
398 2 : $primary_key=$this->primaryKey();
399 2 : if (empty ($primary_key))
400 2 : $primary_key=$this->tableSchema->primaryKey;
401 2 : $relations=$this->relations();
402 2 : foreach ($this->_relation_updated as $relation_name => $related_objects) {
403 2 : if (empty ($related_objects))
404 2 : continue;
405 2 : $relation_settings=$relations[$relation_name];
406 :
407 :
408 2 : foreach ($related_objects as $pk_or_new => $r_object) {
409 2 : if ($pk_or_new === 'new') {
410 2 : foreach ($r_object as $new_object) {
411 2 : if (empty($new_object->$relation_settings[2]))
412 2 : $new_object->$relation_settings[2]=$this->$primary_key;
413 2 : $new_object->save();
414 2 : }
415 2 : continue;
416 : }
417 0 : $r_object->save();
418 2 : }
419 2 : }
420 2 : }
421 :
422 2 : return parent::afterSave();
423 : }
424 :
425 : public function cascade ($cascade_setting) {
426 1 : $this->cascade_on_delete=$cascade_setting;
427 1 : }
428 :
429 :
430 :
431 :
432 : protected function beforeDelete () {
433 1 : if (!$this->cascade_on_delete)
434 1 : return parent::beforeDelete();
435 :
436 :
437 :
438 1 : foreach ($this->relations () as $relation_name => $relation_settings) {
439 1 : if (empty ($this->$relation_name))
440 1 : continue;
441 1 : switch ($relation_settings[0]) {
442 1 : case 'CHasOneRelation':
443 1 : $this->$relation_name->delete();
444 1 : break;
445 1 : case 'CHasManyRelation':
446 1 : foreach ($this->$relation_name as $relation_entry)
447 1 : $relation_entry->delete();
448 1 : break;
449 1 : case 'CManyManyRelation':
450 1 : $primary_key=$this->tableSchema->primaryKey;
451 1 : $pivot_table=$this->metaData->relations[$relation_name]->getJunctionTableName();
452 1 : $foreign_keys=$this->metaData->relations[$relation_name]->getJunctionForeignKeys();
453 1 : $primary_key_column=array_shift ($foreign_keys);
454 1 : $conditions="$primary_key_column = :id";
455 1 : $params=array (':id' => $this->$primary_key);
456 1 : $rows_affected=Yii::app()->db->createCommand()->delete ($pivot_table, $conditions, $params);
457 1 : break;
458 1 : default:
459 1 : continue;
460 1 : }
461 1 : }
462 1 : return parent::beforeDelete();
463 : }
464 :
465 : public function afterDelete () {
466 :
467 1 : return parent::afterDelete();
468 : }
469 :
470 : }
|