1: <?php
  2: 
  3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36: 
 37: 
 38:  39:  40:  41:  42: 
 43: class X2MergeableBehavior extends CActiveRecordBehavior {
 44:     
 45:      46:  47:  48: 
 49:     public $restrictedFields = array(
 50:         'id',
 51:         'nameId',
 52:     );
 53:     
 54:     
 55:     
 56:      57:  58:  59:  60:  61:  62: 
 63:     public function setMergedField($field, $duplicates) {
 64:         $value = null;
 65:         $oldModelId = null;
 66:         $timestamp = 0;
 67:         foreach ($duplicates as $oldModel) {
 68:             if ($field->type === 'text') {
 69:                 
 70:                 if(!empty($oldModel->{$field->fieldName})){
 71:                     if (is_null($value)) {
 72:                         $value = $oldModel->{$field->fieldName};
 73:                     }else{
 74:                         $value .= "\n--\n" . $oldModel->{$field->fieldName};
 75:                     }
 76:                 }
 77:             } else if (!is_null($oldModel->{$field->fieldName}) && $oldModel->lastUpdated >= $timestamp) {
 78:                 $value = $oldModel->{$field->fieldName};
 79:                 
 80:                 $timestamp = $oldModel->lastUpdated;
 81:                 
 82:                 $oldModelId = $oldModel->id;
 83:             }
 84:         }
 85:         $this->owner->{$field->fieldName} = $value;
 86:         if ($field->uniqueConstraint) {
 87:             
 88:             $tmpModel = X2Model::model(get_class($this->owner))->findByPk($oldModelId);
 89:             if($tmpModel){
 90:                 $tmpModel->{$field->fieldName} = null;
 91:                 $tmpModel->update(array($field->fieldName));
 92:             }
 93:         }
 94:     }
 95: 
 96:      97:  98:  99: 
100:     public function setMergedCreateDate($duplicates) {
101:         foreach ($duplicates as $oldModel) {
102:             if (!empty($oldModel->createDate) && (empty($this->owner->createDate) || $oldModel->createDate < $this->owner->createDate)) {
103:                 $this->owner->createDate = $oldModel->createDate;
104:             }
105:         }
106:     }
107: 
108:     109: 110: 111: 112: 113: 
114:     public function massMergeRelatedRecords($duplicates, $logMerge) {
115:         foreach ($duplicates as $oldModel) {
116:             $this->owner->mergeRelatedRecords($oldModel, $logMerge);
117:             if ($oldModel->hasAttribute('visibility')) {
118:                 $oldModel->visibility = 0;
119:             }
120:             if ($oldModel->hasAttribute('assignedTo')) {
121:                 $oldModel->assignedTo = 'Anyone';
122:             }
123:             if ($oldModel->hasAttribute('doNotCall')) {
124:                 $oldModel->doNotCall = 1;
125:             }
126:             if ($oldModel->hasAttribute('doNotEmail')) {
127:                 $oldModel->doNotEmail = 1;
128:             }
129:             $oldModel->update();
130:         }
131:     }
132: 
133:     134: 135: 136: 
137:     public function mergeRelatedRecords(X2Model $model, $logMerge = false) {
138: 
139:         $mergeData = array();
140:         
141:         $ret = $this->owner->mergeActions($model, $logMerge);
142:         if ($logMerge && !empty($ret)) {
143:             $mergeData['data']['actions'] = $ret;
144:         }
145:         
146:         $ret = $this->owner->mergeEvents($model, $logMerge);
147:         if ($logMerge && !empty($ret)) {
148:             $mergeData['data']['events'] = $ret;
149:         }
150:          
151:         $ret = $this->owner->mergeNotifications($model, $logMerge);
152:         if ($logMerge && !empty($ret)) {
153:             $mergeData['data']['notifications'] = $ret;
154:         }
155:             
156:         $ret = $this->owner->mergeTags($model, $logMerge);
157:         if ($logMerge && !empty($ret)) {
158:             $mergeData['data']['tags'] = $ret;
159:         }
160:         
161:         $ret = $this->owner->mergeRelationships($model, $logMerge);
162:         if ($logMerge && !empty($ret)) {
163:             $mergeData['data']['relationships'] = $ret;
164:         }
165:         
166:         $ret = $this->owner->mergeLinkFields($model, $logMerge);
167:         if ($logMerge && !empty($ret)) {
168:             $mergeData['data']['linkFields'] = $ret;
169:         }
170:         
171:         if ($logMerge) {
172:             $mergeData['assignedTo'] = $model->assignedTo;
173:             $mergeData['visibility'] = $model->visibility;
174:             Yii::app()->db->createCommand()
175:                     ->insert('x2_merge_log', array(
176:                         'modelType' => get_class($model),
177:                         'modelId' => $model->id,
178:                         'mergeModelId' => $this->owner->id,
179:                         'mergeData' => json_encode($mergeData),
180:                         'mergeDate' => time(),
181:             ));
182:         }
183:     }
184: 
185:     186: 187: 
188:     public function mergeActions(X2Model $model, $logMerge = false) {
189:         $ret = array();
190:         $associationType = X2Model::getAssociationType(get_class($model));
191:         $tartgetAssociationType = X2Model::getAssociationType(get_class($this->owner));
192:         if ($logMerge) {
193:             $ids = Yii::app()->db->createCommand()
194:                     ->select('id')
195:                     ->from('x2_actions')
196:                     ->where(
197:                             'associationType = :type AND associationId = :id', array(':type' => $associationType, ':id' => $model->id))
198:                     ->queryColumn();
199:             $ret = $ids;
200:         }
201: 
202:         X2Model::model('Actions')->updateAll(array(
203:             'associationType' => $tartgetAssociationType,
204:             'associationId' => $this->owner->id,
205:                 ), 'associationType = :type AND associationId = :id', array(
206:             ':type' => $associationType,
207:             ':id' => $model->id
208:         ));
209: 
210:         return $ret;
211:     }
212: 
213:     214: 215: 
216:     public function mergeEvents(X2Model $model, $logMerge = false) {
217:         $ret = array();
218:         if ($logMerge) {
219:             $ids = Yii::app()->db->createCommand()
220:                     ->select('id')
221:                     ->from('x2_events')
222:                     ->where(
223:                             'associationType = :type AND associationId = :id', array(':type' => get_class($model), ':id' => $model->id))
224:                     ->queryColumn();
225:             $ret = $ids;
226:         }
227:         X2Model::model('Events')->updateAll(
228:                 array(
229:             'associationId' => $this->owner->id,
230:             'associationType' => get_class ($this->owner),
231:                 ), 'associationType = :type AND associationId = :id', array(':type' => get_class($model), ':id' => $model->id));
232:         return $ret;
233:     }
234: 
235:     236: 237: 
238:     public function mergeNotifications(X2Model $model, $logMerge = false) {
239:         $ret = array();
240:         $modelType = get_class($model);
241:         $targetModelType = get_class($this->owner);
242:         if ($logMerge) {
243:             $ids = Yii::app()->db->createCommand()
244:                     ->select('id')
245:                     ->from('x2_notifications')
246:                     ->where(
247:                             'modelType = :type and modelId = :id', array(':type' => $modelType, ':id' => $model->id))
248:                     ->queryColumn();
249:             $ret = $ids;
250:         }
251:         X2Model::model('Notification')
252:                 ->updateAll(array(
253:                     'modelId' => $this->owner->id,
254:                     'modelType' => $targetModelType,
255:                         ), 'modelType = :type AND modelId = :id', array(
256:                     ':type' => $modelType,
257:                     ':id' => $model->id
258:         ));
259:         return $ret;
260:     }
261: 
262:     263: 264: 
265:     public function mergeTags(X2Model $model, $logMerge = false) {
266:         $ret = array();
267:         if ($logMerge) {
268:             $ret = $model->getTags();
269:         }
270:         $this->owner->disableTagTriggers();
271:         $this->owner->addTags($model->getTags());
272:         $this->owner->enableTagTriggers();
273:         $model->clearTags();
274:         return $ret;
275:     }
276: 
277:     278: 279: 
280:     public function mergeRelationships(X2Model $model, $logMerge = false) {
281:         $ret = array();
282:         $modelType = get_class($model);
283:         $targetModelType = get_class($this->owner);
284:         if ($logMerge) {
285:             $firstIds = Yii::app()->db->createCommand()
286:                     ->select('id')
287:                     ->from('x2_relationships')
288:                     ->where(
289:                             'firstType = :type AND firstId = :id', array(':type' => $modelType, ':id' => $model->id))
290:                     ->queryColumn();
291:             if (!empty($firstIds)) {
292:                 $ret['first'] = $firstIds;
293:             }
294: 
295:             $secondIds = Yii::app()->db->createCommand()
296:                     ->select('id')
297:                     ->from('x2_relationships')
298:                     ->where(
299:                             'secondType = :type AND secondId = :id', array(':type' => $modelType, ':id' => $model->id))
300:                     ->queryColumn();
301:             if (!empty($secondIds)) {
302:                 $ret['second'] = $secondIds;
303:             }
304:         }
305:         Relationships::model()->updateAll(array(
306:             'firstId' => $this->owner->id,
307:             'firstType' => $targetModelType,
308:                 ), 'firstType = :type AND firstId = :id', array(
309:             ':type' => $modelType,
310:             ':id' => $model->id,
311:         ));
312:         Relationships::model()->updateAll(array(
313:             'secondId' => $this->owner->id,
314:             'secondType' => $targetModelType,
315:                 ), 'secondType = :type AND secondId = :id', array(
316:             ':type' => $modelType,
317:             ':id' => $model->id,
318:         ));
319:         return $ret;
320:     }
321: 
322:     323: 324: 
325:     public function mergeLinkFields(X2Model $model, $logMerge = false) {
326:         $ret = array();
327: 
328:         $linkFields = Fields::model()
329:                 ->findAllByAttributes(array('type' => 'Link', 'linkType' => get_class($model)));
330:         foreach ($linkFields as $field) {
331:             if ($logMerge) {
332:                 $ids = Yii::app()->db->createCommand()
333:                         ->select('id')
334:                         ->from(X2Model::model($field->modelName)->tableName())
335:                         ->where($field->fieldName . ' = :id', array(':id' => $model->nameId))
336:                         ->queryColumn();
337:                 if (!empty($ids)) {
338:                     $ret[$field->modelName]['field'] = $field->fieldName;
339:                     $ret[$field->modelName]['ids'] = $ids;
340:                 }
341:             }
342:             Yii::app()->db->createCommand()->update(
343:                     X2Model::model($field->modelName)->tableName(), array(
344:                 $field->fieldName => $this->owner->nameId,
345:                     ), $field->fieldName . ' = :id', array(':id' => $model->nameId));
346:         }
347:         return $ret;
348:     }
349:     
350:     351: 352: 353: 354: 355: 356: 
357:     public function revertMerge() {
358:         $mergeLog = Yii::app()->db->createCommand()
359:             ->select('*')
360:             ->from('x2_merge_log')
361:             ->where(
362:                 'mergeModelId = :id AND modelType = :type', 
363:                 array(':id' => $this->owner->id, ':type' => get_class($this->owner)))
364:             ->queryAll();
365:         if (!empty($mergeLog)) {
366:             foreach ($mergeLog as $log) {
367:                 $mergeData = json_decode($log['mergeData'], true);
368:                 $model = X2Model::model($log['modelType'])->findByPk($log['modelId']);
369:                 if (isset($model) && !empty($mergeData)) {
370:                     $model->assignedTo = $mergeData['assignedTo'];
371:                     $model->visibility = $mergeData['visibility'];
372:                     $model->save();
373:                     if (isset($mergeData['data']) && !empty($mergeData['data'])) {
374:                         foreach ($mergeData['data'] as $key => $data) {
375:                             switch ($key) {
376:                                 case 'actions':
377:                                     $this->owner->unmergeActions($model->id, $data);
378:                                     break;
379:                                 case 'events':
380:                                     $this->owner->unmergeEvents($model->id, $data);
381:                                     break;
382:                                 case 'notifications':
383:                                     $this->owner->unmergeNotifications($model->id, $data);
384:                                     break;
385:                                 case 'tags':
386:                                     $this->owner->unmergeTags($model->id, $data);
387:                                     break;
388:                                 case 'relationships':
389:                                     $this->owner->unmergeRelationships($model->id, $data);
390:                                     break;
391:                                 case 'linkFields':
392:                                     $this->owner->unmergeLinkFields($model->id, $data);
393:                                     break;
394:                             }
395:                         }
396:                     }
397:                 }
398:             }
399:             $mergeLog = Yii::app()->db->createCommand()
400:                 ->delete(
401:                     'x2_merge_log', 'mergeModelId = :id AND modelType = :type', 
402:                     array(':id' => $this->owner->id, ':type' => get_class($this->owner)));
403:             $this->owner->delete();
404:         }
405:     }
406: 
407:     public function unmergeActions($id, $actionIds) {
408:         X2Model::model('Actions')->updateByPk($actionIds, array('associationId' => $id));
409:     }
410: 
411:     public function unmergeEvents($id, $eventIds) {
412:         X2Model::model('Events')->updateByPk($eventIds, array('associationId' => $id));
413:     }
414: 
415:     public function unmergeNotifications($id, $notifIds) {
416:         X2Model::model('Notification')->updateByPk($notifIds, array('modelId' => $id));
417:     }
418: 
419:     public function unmergeTags($id, $tags) {
420:         $this->owner->removeTags($tags);
421:         $model = X2Model::model(get_class($this->owner))->findByPk($id);
422:         $model->addTags($tags);
423:     }
424: 
425:     public function unmergeRelationships($id, $data) {
426:         if (isset($data['first'])) {
427:             X2Model::model('Relationships')->updateByPk($data['first'], array('firstId' => $id));
428:         }
429:         if (isset($data['second'])) {
430:             X2Model::model('Relationships')->updateByPk($data['second'], array('secondId' => $id));
431:         }
432:     }
433: 
434:     public function unmergeLinkFields($id, $data) {
435:         $model = X2Model::model(get_class($this->owner))->findByPk($id);
436:         foreach ($data as $modelName => $fieldData) {
437:             X2Model::model($modelName)
438:                 ->updateByPk($fieldData['ids'], array($fieldData['field'] => $model->nameId));
439:         }
440:     }
441: 
442: }
443: