Overview

Packages

  • application
    • commands
    • components
      • actions
      • filters
      • leftWidget
      • permissions
      • sortableWidget
      • util
      • webupdater
      • x2flow
        • actions
        • triggers
      • X2GridView
      • X2Settings
    • controllers
    • models
      • embedded
    • modules
      • accounts
        • controllers
        • models
      • actions
        • controllers
        • models
      • calendar
        • controllers
        • models
      • charts
        • models
      • contacts
        • controllers
        • models
      • docs
        • components
        • controllers
        • models
      • groups
        • controllers
        • models
      • marketing
        • components
        • controllers
        • models
      • media
        • controllers
        • models
      • mobile
        • components
      • opportunities
        • controllers
        • models
      • products
        • controllers
        • models
      • quotes
        • controllers
        • models
      • services
        • controllers
        • models
      • template
        • models
      • users
        • controllers
        • models
      • workflow
        • controllers
        • models
      • x2Leads
        • controllers
        • models
  • None
  • system
    • base
    • caching
    • console
    • db
      • ar
      • schema
    • validators
    • web
      • actions
      • auth
      • helpers
      • widgets
        • captcha
        • pagers
  • zii
    • widgets
      • grid

Classes

  • ActionMetaData
  • ActionText
  • Admin
  • AmorphousModel
  • ApiHook
  • APIModel
  • ChartSetting
  • ContactForm
  • ContactList
  • Credentials
  • Criteria
  • Dropdowns
  • Events
  • EventsData
  • Fields
  • FormLayout
  • Imports
  • InlineEmail
  • LeadRouting
  • Locations
  • LoginForm
  • Maps
  • Modules
  • Notes
  • Notification
  • PhoneNumber
  • Profile
  • Record
  • Relationships
  • Roles
  • RoleToPermission
  • RoleToUser
  • RoleToWorkflow
  • Rules
  • Session
  • SessionLog
  • Social
  • Tags
  • TempFile
  • Tips
  • Tours
  • TrackEmail
  • TriggerLog
  • URL
  • ViewLog
  • Widgets
  • X2List
  • X2ListCriterion
  • X2ListItem
  • X2Model
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /*****************************************************************************************
  3:  * X2Engine Open Source Edition is a customer relationship management program developed by
  4:  * X2Engine, Inc. Copyright (C) 2011-2016 X2Engine Inc.
  5:  * 
  6:  * This program is free software; you can redistribute it and/or modify it under
  7:  * the terms of the GNU Affero General Public License version 3 as published by the
  8:  * Free Software Foundation with the addition of the following permission added
  9:  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
 10:  * IN WHICH THE COPYRIGHT IS OWNED BY X2ENGINE, X2ENGINE DISCLAIMS THE WARRANTY
 11:  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 12:  * 
 13:  * This program is distributed in the hope that it will be useful, but WITHOUT
 14:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 15:  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
 16:  * details.
 17:  * 
 18:  * You should have received a copy of the GNU Affero General Public License along with
 19:  * this program; if not, see http://www.gnu.org/licenses or write to the Free
 20:  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 21:  * 02110-1301 USA.
 22:  * 
 23:  * You can contact X2Engine, Inc. P.O. Box 66752, Scotts Valley,
 24:  * California 95067, USA. or at email address contact@x2engine.com.
 25:  * 
 26:  * The interactive user interfaces in modified source and object code versions
 27:  * of this program must display Appropriate Legal Notices, as required under
 28:  * Section 5 of the GNU Affero General Public License version 3.
 29:  * 
 30:  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
 31:  * these Appropriate Legal Notices must retain the display of the "Powered by
 32:  * X2Engine" logo. If the display of the logo is not reasonably feasible for
 33:  * technical reasons, the Appropriate Legal Notices must display the words
 34:  * "Powered by X2Engine".
 35:  *****************************************************************************************/
 36: 
 37: /**
 38:  * This is the model class for table "x2_relationships".
 39:  *
 40:  * @package application.models
 41:  * @property integer $id
 42:  * @property string $firstType
 43:  * @property integer $firstId
 44:  * @property string $secondType
 45:  * @property integer $secondId
 46:  */
 47: class Relationships extends X2ActiveRecord {
 48: 
 49:     /**
 50:      * Returns the static model of the specified AR class.
 51:      * @return Relationships the static model class
 52:      */
 53:     public static function model($className=__CLASS__) {
 54:         return parent::model($className);
 55:     }
 56: 
 57:     /**
 58:      * @return array model titles indexed by type name for types for which the current user has 
 59:      *  module view permissions
 60:      */
 61:     public static function getRelationshipTypeOptions () {
 62:         $options = X2Model::getModelTypesWhichSupportRelationships (true);
 63:         foreach ($options as $model => $title) {
 64:             $accessLevel = $model::model ()->getAccessLevel ();
 65:             if ($accessLevel === X2PermissionsBehavior::QUERY_NONE) {
 66:                 unset ($options[$model]);
 67:             }
 68:         }
 69:         return $options;
 70:     }
 71: 
 72:     /**
 73:      * @return string the associated database table name
 74:      */
 75:     public function tableName() {
 76:         return 'x2_relationships';
 77:     }
 78: 
 79:     /**
 80:      * @return array validation rules for model attributes.
 81:      */
 82:     public function rules() {
 83:         // NOTE: you should only define rules for those attributes that
 84:         // will receive user inputs.
 85:         return array(
 86:             array('firstId, secondId', 'numerical', 'integerOnly'=>true),
 87:             array('firstType, secondType, firstLabel, secondLabel', 'length', 'max'=>100),
 88:             array('firstType, secondType', 'linkables','on'=>'api'),
 89:             array('firstType, firstId, secondType, secondId','required','on'=>'api'),
 90:             array('firstType, secondType','validateType'),
 91:             array('firstId, secondId','validateModel'),
 92:             // The following rule is used by search().
 93:             // Please remove those attributes that should not be searched.
 94:             array(
 95:                 'firstType, firstId, firstLabel, secondType, secondId, secondLabel', 
 96:                 'safe', 'on'=>'search,api'),
 97:         );
 98:     }
 99: 
100:     /**
101:      * Ensure that type corresponds to child of X2Model which supports relationships 
102:      */
103:     public function validateType ($attr) {
104:         $value = $this->$attr;
105:         $validTypes = X2Model::getModelTypesWhichSupportRelationships (true);
106:         if (!class_exists ($value) || !isset ($validTypes[$value])) {
107:             $this->addError ($attr, Yii::t('app', 'Invalid record type') );
108:         }
109:     }
110: 
111:     /**
112:      * Assuming that type is valid, ensure that id corresponds to an existing record 
113:      */
114:     public function validateModel ($attr) {
115:         $value = $this->$attr;
116:         $position = preg_replace ('/Id$/', '', $attr);
117:         $type = $this->{$position.'Type'};
118:         if (!$type::model ()->findByPk ($value)) {
119:             $this->addError ($attr, Yii::t('app', 'Record could not be found'));
120:         }
121:     }
122: 
123:     /**
124:      * @return bool true if relationship already exists, false otherwise 
125:      */
126:     public function hasDuplicates () {
127:         return ((int) Yii::app()->db->createCommand ()
128:             ->select ('count(*)')
129:             ->from ('x2_relationships')
130:             ->where ('
131:                 firstType=:firstType0 AND firstId=:firstId0 AND secondType=:secondType0 AND
132:                 secondId=:secondId0', 
133:                 array (
134:                     ':firstType0' => $this->firstType,
135:                     ':firstId0' => $this->firstId,
136:                     ':secondType0' => $this->secondType,
137:                     ':secondId0' => $this->secondId,
138:                 ))
139:             ->orWhere ('
140:                 firstType=:firstType1 AND firstId=:firstId1 AND secondType=:secondType1 AND
141:                 secondId=:secondId1', 
142:                 array (
143:                     ':firstType1' => $this->secondType,
144:                     ':firstId1' => $this->secondId,
145:                     ':secondType1' => $this->firstType,
146:                     ':secondId1' => $this->firstId,
147:                 ))
148:             ->queryScalar ()) > 0;
149:     }
150: 
151:     /**
152:      * Add duplicate validation  
153:      */
154:     public function beforeValidate () {
155:         $valid = parent::beforeValidate ();
156:         if ($valid) {
157:             if ($this->hasDuplicates ()) {
158:                 $this->addError ('secondType', Yii::t('app', 'Relationship already exists'));
159:                 $this->addErrors (
160:                     array_map (
161:                         function () { return null; }, 
162:                         array_flip (array ('firstType', 'firstId', 'secondId'))));
163:                 $valid = false;
164:             }
165:         }
166:         return $valid;
167:     }
168: 
169:     /**
170:      * @return array relational rules.
171:      */
172:     public function relations() {
173:         // NOTE: you may need to adjust the relation name and the related
174:         // class name for the relations automatically generated below.
175:         return array(
176:         );
177:     }
178: 
179:     /**
180:      * @return array customized attribute labels (name=>label)
181:      */
182:     public function attributeLabels() {
183:         return array(
184:             'id' => 'ID',
185:             'firstType' => 'First Type',
186:             'firstId' => 'First',
187:             'firstLabel' => 'First Label',
188:             'secondType' => 'Second Type',
189:             'secondId' => 'Second',
190:             'secondLabel' => 'Second Label',
191:         );
192:     }
193: 
194:     /**
195:      * @param string $myType 
196:      * @param string $myId 
197:      * @return string
198:      * @throws CException
199:      */
200:     public function getLabel ($myType, $myId) {
201:         if ($this->firstType === $myType && $this->firstId == $myId) {
202:             return $this->secondLabel;
203:         } elseif ($this->secondType === $myType && $this->secondId == $myId) {
204:             return $this->firstLabel;
205:         }
206:         throw new CException ('myType and myId don\'t match either related model');
207:     }
208: 
209:     public function setFirstModel (X2Model $model) {
210:         $this->firstType = get_class ($model);
211:         $this->firstId = $model->id;
212:     }
213: 
214:     public function setSecondModel (X2Model $model) {
215:         $this->secondType = get_class ($model);
216:         $this->secondId = $model->id;
217:     }
218: 
219:     /**
220:      * @param string $myType 
221:      * @param string $myId 
222:      * @return null|CActiveRecord
223:      * @throws CException
224:      */
225:     private $_otherModel = array ();
226:     public function getOtherModel ($myType, $myId) {
227:         if (!isset ($this->_otherModel[$myType.$myId])) {
228:             if ($this->firstType === $myType && $this->firstId == $myId) {
229:                 $model = X2Model::model ($this->secondType)->findByPk ($this->secondId);
230:             } elseif ($this->secondType === $myType && $this->secondId == $myId) {
231:                 $model = X2Model::model ($this->firstType)->findByPk ($this->firstId);
232:             } else {
233:                 throw new CException ('myType and myId don\'t match either related model');
234:             }
235:             $this->_otherModel[$myType.$myId] = $model;
236:         }
237:         return $this->_otherModel[$myType.$myId];
238:     }
239:     
240:     /**
241:      * Retrieves a list of models based on the current search/filter conditions.
242:      * @return CActiveDataProvider the data provider that can return the models based on the 
243:      *  search/filter conditions.
244:      */
245:     public function search() {
246:         // Warning: Please modify the following code to remove attributes that
247:         // should not be searched.
248: 
249:         $criteria=new CDbCriteria;
250: 
251:         $criteria->compare('id',$this->id);
252:         $criteria->compare('firstType',$this->firstType,true);
253:         $criteria->compare('firstId',$this->firstId);
254:         $criteria->compare('firstLabel',$this->firstLabel);
255:         $criteria->compare('secondType',$this->secondType,true);
256:         $criteria->compare('secondId',$this->secondId);
257:         $criteria->compare('secondLabel',$this->secondLabel);
258: 
259:         return new CActiveDataProvider(get_class($this), array(
260:             'criteria'=>$criteria,
261:         ));
262:     }
263: 
264:     public function linkables($attribute, $params) {
265:         if(!class_exists($this->$attribute))
266:             $this->addError(
267:                 $attribute,
268:                 Yii::t('app','Class "{class}" specified for {attribute} does not exist, so cannot create relationships with it.',array('{class}'=>$this->$attribute)));
269: 
270:         // See if the active record class has the linkable behavior:
271:         $staticModel = CActiveRecord::model($this->$attribute);
272:         $has = false;
273:         foreach($staticModel->behaviors() as $name=>$config){
274:             if($config['class'] == 'X2LinkableBehavior'){
275:                 $has = true;
276:                 break;
277:             }
278:         }
279:         if(!$has)
280:             $this->addError(
281:                 $attribute,
282:                 Yii::t('app','Class "{class}" specified for {attribute} does not have X2LinkableBehavior, and thus cannot be used with relationships.',array('{class}'=>$this->$attribute)));
283: 
284:         $model = $staticModel->findByPk($attribute=='firstType' ? $this->firstId : $this->secondId);
285:         if(!$model)
286:             $this->addError($attribute,Yii::t('app','Model record not found for {attribute}.'));
287:     }
288: 
289: }
290: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0