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: class X2List extends X2Model {
43:
44: 45: 46: 47: 48: 49:
50: public $criteriaInput;
51:
52: public $supportsWorkflow = false;
53:
54: private $_itemModel = null;
55:
56: private $_itemFields = array();
57:
58: private $_itemAttributeLabels = array();
59:
60: public static function model($className = __CLASS__){
61: return parent::model($className);
62: }
63:
64: 65: 66: 67:
68: public function tableName(){
69: return 'x2_lists';
70: }
71:
72: public function behaviors(){
73: return array(
74: 'ERememberFiltersBehavior' => array(
75: 'class' => 'application.components.ERememberFiltersBehavior',
76: 'defaults' => array(),
77: 'defaultStickOnClear' => false
78: ),
79: 'X2LinkableBehavior' => array(
80: 'class' => 'X2LinkableBehavior',
81: 'baseRoute' => '/contacts/contacts/list',
82: 'autoCompleteSource' => '/contacts/contacts/getLists',
83: ),
84: 'X2PermissionsBehavior' => array(
85: 'class' => 'application.components.permissions.'.Yii::app()->params->modelPermissions
86: ),
87: 'X2FlowTriggerBehavior' => array('class' => 'X2FlowTriggerBehavior'),
88: );
89: }
90:
91: public function rules(){
92:
93:
94: return array(
95: array('name, createDate, lastUpdated, modelName', 'required'),
96: array('id, count, visibility, createDate, lastUpdated', 'numerical', 'integerOnly' => true),
97: array('name, modelName', 'length', 'max' => 100),
98: array('description', 'length', 'max' => 250),
99: array('assignedTo, type, logicType', 'length', 'max' => 20),
100:
101:
102: array('id, assignedTo, name, modelName, count, visibility, description, type, createDate, lastUpdated', 'safe', 'on' => 'search'),
103: );
104: }
105:
106: public function relations(){
107:
108:
109: return array(
110: 'listItems' => array(self::HAS_MANY, 'X2ListItem', 'listId'),
111: 'campaign' => array(self::HAS_ONE, 'Campaign', array('listId' => 'nameId')),
112: 'criteria' => array(self::HAS_MANY,'X2ListCriterion','listId'),
113: );
114: }
115:
116: public function attributeLabels(){
117: return array(
118: 'id' => 'ID',
119: 'assignedTo' => Yii::t('contacts', 'Owner'),
120: 'name' => Yii::t('contacts', 'Name'),
121: 'description' => Yii::t('contacts', 'Description'),
122: 'type' => Yii::t('contacts', 'Type'),
123: 'logicType' => Yii::t('contacts', 'Logic Type'),
124: 'modelName' => Yii::t('contacts', 'Record Type'),
125: 'visibility' => Yii::t('contacts', 'Visibility'),
126: 'count' => Yii::t('contacts', 'Members'),
127: 'createDate' => Yii::t('contacts', 'Create Date'),
128: 'lastUpdated' => Yii::t('contacts', 'Last Updated'),
129: );
130: }
131:
132: 133: 134: 135:
136: public static function getComparisonList(){
137: return array(
138: '=' => Yii::t('contacts', 'equals'),
139: '>' => Yii::t('contacts', 'greater than'),
140: '<' => Yii::t('contacts', 'less than'),
141: '<>' => Yii::t('contacts', 'not equal to'),
142: 'contains' => Yii::t('contacts', 'contains'),
143: 'noContains' => Yii::t('contacts', 'does not contain'),
144: 'empty' => Yii::t('contacts', 'empty'),
145: 'notEmpty' => Yii::t('contacts', 'not empty'),
146: 'list' => Yii::t('contacts', 'in list'),
147: 'notList' => Yii::t('contacts', 'not in list'),
148: );
149: }
150:
151: public function getDefaultRoute(){
152: return '/contacts/contacts/list';
153: }
154:
155: public function getDisplayName ($plural=true, $ofModule=true) {
156: return Yii::t('contacts', '{contact} Lists|{contact} List', array(
157: (int) $plural,
158: '{contact}' => Modules::displayName(false, 'Contacts'),
159: ));
160: }
161:
162: public function createLink(){
163: if(isset($this->id))
164: return CHtml::link($this->name, array($this->getDefaultRoute(), 'id' => $this->id));
165: else
166: return $this->name;
167: }
168:
169: 170: 171:
172: public function afterDelete(){
173: CActiveRecord::model('X2ListItem')->deleteAllByAttributes(array('listId' => $this->id));
174:
175: parent::afterDelete();
176: }
177:
178: 179: 180: 181:
182: public function search(){
183:
184:
185:
186: $criteria = new CDbCriteria;
187:
188: $criteria->compare('id', $this->id, true);
189: $criteria->compare('name', $this->name, true);
190: $criteria->compare('description', $this->description, true);
191: $criteria->compare('type', $this->type, true);
192: $criteria->compare('logicType', $this->logicType, true);
193: $criteria->compare('modelName', $this->modelName, true);
194: $criteria->compare('createDate', $this->createDate, true);
195: $criteria->compare('lastUpdated', $this->lastUpdated, true);
196:
197: return new CActiveDataProvider(get_class($this), array(
198: 'criteria' => $criteria,
199: ));
200: }
201:
202:
203: public function getItemFields(){
204: if(empty($this->_itemFields)){
205: if(!isset($this->_itemModel) && class_exists($this->modelName))
206: $this->_itemModel = new $this->modelName;
207: $this->_itemFields = $this->_itemModel->fields;
208: }
209: return $this->_itemFields;
210: }
211:
212:
213: public function getItemAttributeLabels(){
214: if(empty($this->_itemAttributeLabels)){
215: if(!isset($this->_itemModel) && class_exists($this->modelName))
216: $this->_itemModel = new $this->modelName;
217: $this->_itemAttributeLabels = $this->_itemModel->attributeLabels();
218: }
219: return $this->_itemAttributeLabels;
220: }
221:
222: public static function load($id){
223: if(!Yii::app()->params->isAdmin){
224: $condition = 't.visibility="1" OR t.assignedTo="Anyone" OR t.assignedTo="'.Yii::app()->user->getName().'"';
225:
226: $groupLinks = Yii::app()->db->createCommand()->select('groupId')->from('x2_group_to_user')->where('userId='.Yii::app()->user->getId())->queryColumn();
227: if(!empty($groupLinks))
228: $condition .= ' OR t.assignedTo IN ('.implode(',', $groupLinks).')';
229:
230: $condition .= 'OR (t.visibility=2 AND t.assignedTo IN
231: (SELECT username FROM x2_group_to_user WHERE groupId IN
232: (SELECT groupId FROM x2_group_to_user WHERE userId='.Yii::app()->user->getId().')))';
233: } else{
234: $condition = '';
235: }
236: return self::model()->findByPk((int) $id, $condition);
237: }
238:
239: public function calculateCount () {
240: $criteria = $this->queryCriteria ();
241: return Contacts::model ()->count ($criteria);
242: }
243:
244:
245: 246: 247: 248:
249: public function queryCriteria($useAccessRules = true){
250: $search = new CDbCriteria;
251:
252: if($this->type == 'dynamic'){
253: $tagJoinCount = 0;
254: $logicMode = $this->logicType;
255: $criteria = X2Model::model('X2ListCriterion')
256: ->findAllByAttributes(array('listId' => $this->id, 'type' => 'attribute'));
257: foreach($criteria as $criterion){
258:
259: $dateType = false;
260:
261: foreach(X2Model::model($this->modelName)->fields as $field){
262: if($field->fieldName == $criterion->attribute){
263: switch($field->type){
264: case 'date':
265: case 'dateTime':
266: if(ctype_digit((string) $criterion->value) ||
267: (substr($criterion->value, 0, 1) == '-' &&
268: ctype_digit((string) substr($criterion->value, 1)))) {
269: $criterion->value = (int) $criterion->value;
270: } else {
271: $criterion->value = strtotime($criterion->value);
272: }
273: $dateType = true;
274: break;
275: case 'boolean':
276: case 'visibility':
277: $criterion->value = in_array(
278: strtolower($criterion->value),
279: array('1', 'yes', 'y', 't', 'true')) ? 1 : 0;
280: break;
281: }
282: break;
283: }
284: }
285:
286: if($criterion->attribute == 'tags' && $criterion->value){
287:
288: $tags = explode(',', preg_replace('/\s?,\s?/', ',', trim($criterion->value)));
289: for($i = 0; $i < count($tags); $i++){
290: if(empty($tags[$i])){
291: unset($tags[$i]);
292: $i--;
293: continue;
294: }else{
295: if($tags[$i][0] != '#')
296: $tags[$i] = '#'.$tags[$i];
297: $tags[$i] = 'x2_tags.tag = "'.$tags[$i].'"';
298: }
299: }
300: $tagCondition = implode(' OR ', $tags);
301: $search->join = 'LEFT JOIN x2_tags ON t.id = x2_tags.itemId';
302: $search->addCondition("x2_tags.id IS NOT NULL AND x2_tags.type='$this->modelName' AND " ."($tagCondition)", $logicMode);
303: } else if($dateType){
304:
305: $thisDay = $criterion->value;
306: $nextDay = $criterion->value + 86400;
307: switch($criterion->comparison){
308: case '=':
309: $subSearch = new CDbCriteria();
310: $subSearch->compare('t.'.$criterion->attribute, '>='.$thisDay, false, 'AND');
311: $subSearch->compare('t.'.$criterion->attribute, '<'.$nextDay, false, 'AND');
312: $search->mergeWith($subSearch, $logicMode);
313: break;
314: case '<>':
315: $subSearch = new CDbCriteria();
316: $subSearch->compare('t.'.$criterion->attribute, '<'.$thisDay, false, 'OR');
317: $subSearch->compare('t.'.$criterion->attribute, '>='.$nextDay, false, 'OR');
318: $search->mergeWith($subSearch, $logicMode);
319: break;
320: case '>':
321: $search->compare('t.'.$criterion->attribute, '>='.$thisDay, true, $logicMode);
322: break;
323: case '<':
324: $search->compare('t.'.$criterion->attribute, '<'.$thisDay, true, $logicMode);
325: break;
326: case 'notEmpty':
327: $search->addCondition('t.'.$criterion->attribute.' IS NOT NULL AND '.'t.'.$criterion->attribute.'!=""', $logicMode);
328: break;
329: case 'empty':
330: $search->addCondition('('.'t.'.$criterion->attribute.'="" OR '.'t.'.$criterion->attribute.' IS NULL)', $logicMode);
331: break;
332:
333:
334:
335:
336:
337: }
338: }else{
339: switch($criterion->comparison){
340: case '=':
341: $search->compare('t.'.$criterion->attribute, $criterion->value, false, $logicMode);
342: break;
343: case '>':
344: $search->compare('t.'.$criterion->attribute, '>='.$criterion->value, true, $logicMode);
345: break;
346: case '<':
347: $search->compare('t.'.$criterion->attribute, '<='.$criterion->value, true, $logicMode);
348: break;
349: case '<>':
350: $search->addCondition('('.'t.'.$criterion->attribute.' IS NULL OR '.'t.'.$criterion->attribute.'!='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount.')', $logicMode);
351: $search->params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++] = $criterion->value;
352: break;
353: case 'notEmpty':
354: $search->addCondition('t.'.$criterion->attribute.' IS NOT NULL AND '.'t.'.$criterion->attribute.'!=""', $logicMode);
355: break;
356: case 'empty':
357: $search->addCondition('('.'t.'.$criterion->attribute.'="" OR '.'t.'.$criterion->attribute.' IS NULL)', $logicMode);
358: break;
359: case 'list':
360: $search->addInCondition('t.'.$criterion->attribute, explode(',', $criterion->value), $logicMode);
361: break;
362: case 'notList':
363: $search->addNotInCondition('t.'.$criterion->attribute, explode(',', $criterion->value), $logicMode);
364: break;
365: case 'noContains':
366: $search->compare('t.'.$criterion->attribute, '<>'.$criterion->value, true, $logicMode);
367: break;
368: case 'contains':
369: default:
370: $search->compare('t.'.$criterion->attribute, $criterion->value, true, $logicMode);
371: }
372: }
373: }
374: }else{
375: $search->join = 'JOIN x2_list_items ON t.id = x2_list_items.contactId';
376: $search->addCondition('x2_list_items.listId='.$this->id);
377: }
378:
379: if($useAccessRules){
380: $accessCriteria = X2Model::model('Contacts')->getAccessCriteria();
381: $accessCriteria->mergeWith($search, 'AND');
382: return $accessCriteria;
383: }else{
384: return $search;
385: }
386: }
387:
388: 389: 390: 391:
392: public function queryCommand($useAccessRules = true){
393: $tableSchema = X2Model::model($this->modelName)->getTableSchema();
394: return $this->getCommandBuilder()->createFindCommand($tableSchema, $this->queryCriteria($useAccessRules));
395: }
396:
397: 398: 399: 400:
401: public function dataProvider($pageSize = null, $sort = null){
402: if(!isset($sort))
403: $sort = array();
404: return new CActiveDataProvider($this->modelName, array(
405: 'criteria' => $this->queryCriteria(),
406: 'pagination' => array(
407: 'pageSize' => isset($pageSize) ? $pageSize : Profile::getResultsPerPage(),
408: ),
409: 'sort' => $sort
410: ));
411: }
412:
413: 414: 415: 416: 417: 418: 419:
420: public static function getVcrLinks(&$dataProvider, $modelId){
421:
422: $criteria = $dataProvider->criteria;
423:
424: $tableSchema = X2Model::model($dataProvider->modelClass)->getTableSchema();
425: if($tableSchema === null)
426: return false;
427:
428:
429: $criteria->select = 't.id';
430:
431:
432: foreach(explode(',', $criteria->order) as $token){
433:
434:
435: $token = preg_replace('/\s|asc|desc/i', '', $token);
436: if($token !== '' && $token !== 'id' && $token != 't.id'){
437: if(strpos($token, '.') != 1){
438: $criteria->select .= ',t.'.$token;
439: }else{
440: $criteria->select .= ','.$token;
441: }
442: }
443: }
444:
445:
446: if(!preg_match('/\bid\b/', $criteria->order)){
447: if(!empty($criteria->order))
448: $criteria->order .= ',';
449: $criteria->order .= 't.id DESC';
450: }
451:
452:
453: $searchConditions = Yii::app()->db->getCommandBuilder()
454: ->createFindCommand($tableSchema, $criteria)->getText();
455:
456:
457: 458: 459: 460: 461: 462: 463: 464: 465: 466: 467: 468: 469:
470: $varPrefix = '@';
471: $varName = $varPrefix.'rownum';
472: $varText = 'SET '.$varName.' = 0';
473: Yii::app()->db->createCommand()
474: ->setText($varText)
475: ->execute();
476: $subQuery = Yii::app()->db->createCommand()
477: ->select('*, ('.$varName.':='.$varName.'+1) r')
478: ->from('('.$searchConditions.') t1')
479: ->getText();
480: $rowNumberQuery = Yii::app()->db->createCommand()
481: ->select('(r-1)')
482: ->from('('.$subQuery.') t2')
483: ->where('t2.id=:t2_id');
484:
485:
486:
487:
488:
489:
490:
491:
492:
493: $rowNumberQuery->params = array_merge(array(':t2_id'=>$modelId),$criteria->params);
494: $rowNumber = $rowNumberQuery->queryScalar();
495:
496: if($rowNumber === false){
497: return false;
498: }else{
499:
500: $criteria->select = '*';
501:
502: if($rowNumber == 0){
503: $criteria->offset = 0;
504: $criteria->limit = 2;
505: $vcrIndex = 0;
506: }else{
507: $criteria->offset = $rowNumber - 1;
508: $criteria->limit = 3;
509: $vcrIndex = 1;
510: }
511:
512: $vcrModels = Yii::app()->db->getCommandBuilder()
513: ->createFindCommand($tableSchema, $criteria)->queryAll();
514: $count = $dataProvider->getTotalItemCount();
515:
516: $vcrData = array();
517: $vcrData['index'] = $rowNumber + 1;
518: $vcrData['count'] = $dataProvider->getTotalItemCount();
519:
520: 521: 522: 523: 524: 525: 526: 527: 528: 529:
530: if($vcrIndex > 0 && isset($vcrModels[0])){
531: $vcrData['prev'] = CHtml::link(
532: '<', array('view', 'id' => $vcrModels[0]['id']),
533: array('title' => $vcrModels[0]['name'], 'class' => 'x2-button'));
534: }else{
535: $vcrData['prev'] = CHtml::link(
536: '<', 'javascript:void(0);', array('class' => 'x2-button disabled'));
537: }
538:
539: if(count($vcrModels) - 1 > $vcrIndex){
540: $vcrData['next'] = CHtml::link(
541: '>', array('view', 'id' => $vcrModels[$vcrIndex + 1]['id']),
542: array('title' => $vcrModels[$vcrIndex + 1]['name'], 'class' => 'x2-button'));
543: }else{
544: $vcrData['next'] = CHtml::link(
545: '>', 'javascript:void(0);', array('class' => 'x2-button disabled'));
546: }
547:
548: return $vcrData;
549: }
550: }
551:
552: 553: 554: 555: 556:
557: public function statusDataProvider($pageSize = null){
558: $tbl = X2Model::model($this->modelName)->tableName();
559: $lstTbl = X2ListItem::model()->tableName();
560: if($this->type == 'dynamic'){
561: $criteria = $this->queryCriteria();
562: $count = X2Model::model($this->modelName)->count($criteria);
563: $sql = $this->getCommandBuilder()->createFindCommand($tbl, $criteria)->getText();
564: $params = $criteria->params;
565: }else{
566: $count = X2ListItem::model()->count('listId=:listId', array('listId' => $this->id));
567: $sql = "SELECT t.*, c.* FROM {$lstTbl} as t LEFT JOIN {$tbl} as c ON t.contactId=c.id WHERE t.listId=:listId;";
568: $params = array('listId' => $this->id);
569: }
570: return new CSqlDataProvider($sql, array(
571: 'totalItemCount' => $count,
572: 'params' => $params,
573: 'pagination' => array(
574: 'pageSize' => isset($pageSize) ? $pageSize : Profile::getResultsPerPage(),
575: ),
576: 'sort' => array(
577:
578: 'attributes' => array('name', 'email', 'phone', 'address'),
579: 'defaultOrder' => 'lastUpdated DESC',
580: ),
581: ));
582: }
583:
584: 585: 586: 587: 588:
589: public function campaignDataProvider($pageSize = null){
590: $criteria = X2Model::model('Campaign')->getAccessCriteria();
591: $conditions =$criteria->condition;
592:
593: $params = array('listId' => $this->id);
594:
595: $count = Yii::app()->db->createCommand()
596: ->select('count(*)')
597: ->from(X2ListItem::model()->tableName().' as list')
598: ->leftJoin(X2Model::model($this->modelName)->tableName().' t', 'list.contactId=t.id')
599: ->where(
600: 'list.listId=:listId AND ('.$conditions.')',
601: array_merge (array(
602: ':listId' => $this->id
603: ), $criteria->params))
604: ->queryScalar();
605:
606: $sql = Yii::app()->db->createCommand()
607: ->select('list.*, t.*')
608: ->from(X2ListItem::model()->tableName().' as list')
609: ->leftJoin(X2Model::model($this->modelName)->tableName().' t', 'list.contactId=t.id')
610: ->where(
611: 'list.listId=:listId AND ('.$conditions.')')
612: ->getText();
613:
614: return new CSqlDataProvider($sql, array(
615: 'params' => array_merge ($params, $criteria->params),
616: 'totalItemCount' => $count,
617: 'pagination' => array(
618: 'pageSize' => !empty($pageSize) ? $pageSize : Profile::getResultsPerPage(),
619: ),
620: 'sort' => array(
621:
622: 'attributes' => array(
623: 'name',
624: 'email',
625: 'phone',
626: 'address',
627: 'sent',
628: 'opened',
629: 'clicked',
630: 'unsubscribed',
631: 'doNotEmail',
632: ),
633: 'defaultOrder' => 'opened DESC, sent DESC, name DESC',
634: ),
635: ));
636: }
637:
638: 639: 640: 641: 642:
643: public function statusCount($type){
644: $whitelist = array('sent', 'opened', 'clicked', 'unsubscribed');
645: if(!in_array($type, $whitelist)){
646: return 0;
647: }
648:
649: $lstTbl = X2ListItem::model()->tableName();
650: $count = Yii::app()->db->createCommand(
651: 'SELECT COUNT(*) FROM '.$lstTbl.' WHERE listId = :listid AND '.$type.' > 0')
652: ->queryScalar(array('listid' => $this->id));
653: return $count;
654: }
655:
656: 657: 658: 659: 660: 661:
662: public function staticDuplicate(){
663: $dup = new X2List();
664: $dup->attributes = $this->attributes;
665: $dup->id = null;
666: $dup->nameId = null;
667: $dup->type = 'static';
668: $dup->createDate = $dup->lastUpdated = time();
669: $dup->isNewRecord = true;
670: if(!$dup->save())
671: return;
672:
673: $count = 0;
674: $listItemRecords = array();
675: $params = array();
676: if($this->type == 'dynamic'){
677: $itemIds = $this->queryCommand(true)->select('id')->queryColumn();
678: foreach($itemIds as $id){
679: $listItemRecords[] = '(NULL,:contactId'.$count.',:listId'.$count.',0)';
680: $params[':contactId'.$count] = $id;
681: $params[':listId'.$count] = $dup->id;
682: $count++;
683: }
684: }else{
685:
686: foreach($this->listItems as $listItem){
687: if(!empty($listItem->emailAddress)){
688: $itemSql = '(:email'.$count;
689: $params[':email'.$count] = $listItem->emailAddress;
690: }else{
691: $itemSql = '(NULL';
692: }
693: if(!empty($listItem->contactId)){
694: $itemSql .= ',:contactId'.$count;
695: $params[':contactId'.$count] = $listItem->contactId;
696: }else{
697: $itemSql .= ',NULL';
698: }
699: $itemSql .= ',:listId'.$count.',:unsubd'.$count.')';
700: $params[':listId'.$count] = $dup->id;
701: $params[':unsubd'.$count] = $listItem->unsubscribed;
702: $listItemRecords[] = $itemSql;
703: $count++;
704: }
705: }
706: if(count($listItemRecords) == 0)
707: return;
708: $sql = 'INSERT into x2_list_items
709: (emailAddress, contactId, listId, unsubscribed)
710: VALUES '
711: .implode(',', $listItemRecords).';';
712: $dup->count = $count;
713:
714: $transaction = Yii::app()->db->beginTransaction();
715: try{
716: Yii::app()->db->createCommand($sql)->execute($params);
717: $transaction->commit();
718: }catch(Exception $e){
719: $transaction->rollBack();
720: $dup->delete();
721: Yii::log($e->getMessage(), 'error', 'application');
722: $dup = null;
723: }
724: return $dup;
725: }
726:
727: 728: 729: 730:
731: public function addIds($ids){
732: if($this->type !== 'static')
733: return false;
734:
735: $ids = (array) $ids;
736:
737: $parameters = AuxLib::bindArray($ids, 'addIds');
738: $existingIds = Yii::app()->db->createCommand()
739: ->select('contactId')
740: ->from('x2_list_items')
741: ->where('listId='.$this->id.' AND contactId IN('.implode(',', array_keys($parameters)).')', $parameters)
742: ->queryColumn();
743:
744: foreach($ids as $id){
745: if(in_array($id, $existingIds))
746: continue;
747: $listItem = new X2ListItem();
748: $listItem->listId = $this->id;
749: $listItem->contactId = $id;
750: $listItem->save();
751: }
752:
753: $this->count = CActiveRecord::model('X2ListItem')->countByAttributes(array('listId' => $this->id));
754: return $this->update(array('count'));
755: }
756:
757: 758: 759: 760: 761: 762:
763: public function processCriteria(){
764: X2ListCriterion::model()->deleteAllByAttributes(array('listId' => $this->id));
765: foreach(array('attribute', 'comparison', 'value') as $property){
766:
767:
768: ${"{$property}s"} = $this->criteriaInput[$property];
769: }
770: $comparisonList = self::getComparisonList();
771: $contactModel = Contacts::model();
772: $fields = $contactModel->getFields(true);
773:
774: for($i = 0; $i < count($attributes); $i++){
775: if((array_key_exists($attributes[$i], $contactModel->attributeLabels()) || $attributes[$i] == 'tags') && array_key_exists($comparisons[$i], $comparisonList)){
776: $fieldRef = isset($fields[$attributes[$i]]) ? $fields[$attributes[$i]] : null;
777: if($fieldRef instanceof Fields && $fieldRef->type == 'link'){
778: $nameList = explode(',', $values[$i]);
779: $namesParams = AuxLib::bindArray($nameList);
780: $namesIn = AuxLib::arrToStrList(array_keys($namesParams));
781: $lookupModel = X2Model::model(ucfirst($fieldRef->linkType));
782: $lookupModels = $lookupModel->findAllBySql(
783: 'SELECT * FROM `'.$lookupModel->tableName().'` '
784: .'WHERE `name` IN '.$namesIn, $namesParams);
785: if(!empty($lookupModels)){
786: $values[$i] = implode(',', array_map(function($m){
787: return $m->nameId;
788: }, $lookupModels));
789: }
790: }
791: $criterion = new X2ListCriterion;
792: $criterion->listId = $this->id;
793: $criterion->type = 'attribute';
794: $criterion->attribute = $attributes[$i];
795: $criterion->comparison = $comparisons[$i];
796: $criterion->value = $values[$i];
797: $criterion->save();
798: }
799: }
800: }
801:
802: 803: 804: 805:
806: public function removeIds($ids){
807: if($this->type !== 'static')
808: return false;
809:
810: $criteria = new CDbCriteria();
811: $criteria->compare('listId', $this->id);
812: $criteria->addInCondition('contactId', (array) $ids);
813:
814: $model = CActiveRecord::model('X2ListItem');
815:
816:
817: if(CActiveRecord::model('X2ListItem')->deleteAll($criteria)){
818: $this->count = CActiveRecord::model('X2ListItem')->countByAttributes(array('listId' => $this->id));
819: $this->update(array('count'));
820: return true;
821: }
822: return false;
823: }
824:
825: 826: 827: 828: 829:
830: 831: 832: 833: 834: 835:
836:
837: public function hasRecord ($model) {
838: if($this->modelName !== get_class($model))
839: return false;
840: $listCriteria = $this->queryCriteria(false);
841: $listCriteria->compare('t.id',$model->id);
842: return $model->exists($listCriteria);
843: }
844:
845: public static function getRoute($id){
846: if($id == 'all')
847: return array('/contacts/contacts/index');
848: else if($id == 'new')
849: return array('/contacts/contacts/newContacts');
850: else if(empty($id) || $id == 'my')
851: return array('/contacts/contacts/myContacts');
852: else
853: return array('/contacts/contacts/list', 'id' => $id);
854: }
855:
856: public static function getAllStaticListNames($controller){
857: $listNames = array();
858:
859:
860: foreach(X2List::model()->findAllByAttributes(array('type' => 'static')) as $list){
861: if($controller->checkPermissions($list, 'edit'))
862: $listNames[$list->id] = $list->name;
863: }
864: return $listNames;
865: }
866:
867: public function setAttributes($values, $safeOnly = true){
868: if($this->type == 'dynamic'){
869: $this->criteriaInput = array();
870: foreach(array('attribute', 'comparison', 'value') as $property){
871: if(isset($values[$property]))
872: $this->criteriaInput[$property] = $values[$property];
873: }
874: $criteria = array_combine ($this->criteriaInput['attribute'], $this->criteriaInput['value']);
875: if (array_key_exists ('tags', $criteria) && empty($criteria['tags'])) {
876: $this->addError ('tags', Yii::t ('contacts', 'Tag list must be non-empty'));
877: }
878: }
879: parent::setAttributes($values, $safeOnly);
880: }
881:
882: public function afterSave(){
883: if($this->type == 'dynamic' && isset($this->criteriaInput)) {
884: $this->processCriteria();
885: }
886: return parent::afterSave();
887: }
888:
889: 890: 891:
892: public function filter (array $lists) {
893: $filterAttrs = array ();
894: foreach ($this->getAttributes () as $attr => $val) {
895: if (isset ($val) && $val !== '') {
896: if ($attr === 'assignedTo') {
897: $filterAttrs[$attr] = $this->compareAssignment ($val);
898: if (is_array ($filterAttrs[$attr])) {
899: $filterAttrs[$attr] = array_map (function ($elem) {
900: return strtolower ($elem);
901: }, $filterAttrs[$attr]);
902: }
903: } else {
904: $filterAttrs[$attr] = $val;
905: }
906: }
907: }
908:
909: $filteredLists = array ();
910: foreach ($lists as $list) {
911: $pass = true;
912: foreach ($filterAttrs as $attr => $val) {
913: if ($attr === 'assignedTo') {
914: if (!is_array ($val) ||
915: !in_array (strtolower ($list->$attr), $val)) {
916:
917: $pass = false;
918: break;
919: }
920: } elseif (!preg_match ("/$val/i", (string) $list->$attr)) {
921: $pass = false;
922: break;
923: }
924: }
925: if ($pass) $filteredLists[] = $list;
926: }
927: return $filteredLists;
928: }
929:
930: }
931: