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

  • ActionFormModel
  • ArrayUtil
  • ArrayValidator
  • AssociatedMediaBehavior
  • AuxLib
  • Changelog
  • DetailView
  • EncryptUtilTmp
  • EventsWidgetFieldFormatter
  • FailedLogins
  • FieldFormatter
  • FieldFormatterBase
  • FieldInputRenderer
  • FileFieldBehavior
  • FiltersForm
  • FilterUtil
  • FineDiff
  • FineDiffCopyOp
  • FineDiffDeleteOp
  • FineDiffInsertOp
  • FineDiffOp
  • FineDiffOps
  • FineDiffReplaceOp
  • GlobalCSSFormModel
  • GlobalImportFormModel
  • GoogleAuthenticator
  • JSONFieldsBehavior
  • JSONResponse
  • MediaFieldFormatter
  • MediaSelector
  • MobileActiveRecordFieldFormatter
  • MobileActivityFeed
  • MobileChartDashboard
  • MobileFieldFormatter
  • MobileFieldInputRenderer
  • ModuleModelNameValidator
  • MultiChildNode
  • MultiTypeAutocomplete
  • PasswordUtil
  • ProductFeature
  • ProfileWidgetLayout
  • QueryParamGenerator
  • RecordLimitBehavior
  • RecordView
  • RecordViewWidgetLayout
  • RelationshipsGridModel
  • RelationshipsJoin
  • RepairUserDataCommand
  • RequestUtil
  • RequiredIfNotSetValidator
  • ResponseUtil
  • RunMigrationScriptCommand
  • ServiceWebFormDesigner
  • Settings
  • StringUtil
  • TestEmailAction
  • TestEmailActionForm
  • ThemeGenerator
  • TimerUtil
  • TopicsFieldFormatter
  • TopicsWidgetLayout
  • TransactionalViewFieldFormatter
  • UrlUtil
  • ValidLinkValidator
  • WebFormDesigner
  • WebLeadFormDesigner
  • X2ActiveRecordBehavior
  • X2ActiveRecordFieldFormatter
  • X2ButtonColumn
  • X2ConditionList
  • X2ConsoleCommand
  • X2ControllerBehavior
  • X2DataColumn
  • X2DuplicateBehavior
  • X2Flashes
  • X2GridViewFieldFormatter
  • X2IPAddress
  • X2LeadsDataColumn
  • X2MergeableBehavior
  • X2MessageSource
  • X2MobileControllerBehavior
  • X2MobileProfileControllerBehavior
  • X2MobileQuotesControllerBehavior
  • X2MobileSiteControllerBehavior
  • X2MobileTopicsControllerBehavior
  • X2ModelConversionBehavior
  • X2ModelConversionWidget
  • X2ModelForeignKeyValidator
  • X2ModelUniqueIndexValidator
  • X2NonWebUser
  • X2StaticDropdown
  • X2StaticField
  • X2StaticFieldsBehavior
  • X2UrlManager
  • X2Validator
  • X2WidgetBehavior

Interfaces

  • AdminOwnedCredentials

Exceptions

  • CampaignMailingException
  • CodeExchangeException
  • GetCredentialsException
  • NoRefreshTokenException
  • NoUserIdException
  • StringUtilException

Functions

  • checkCurrency
  • checkDNS
  • checkServerVar
  • checkTimezone
  • decodeQuotes
  • echoIcons
  • encodeQuotes
  • exceptionForError
  • getField
  • getLanguageName
  • getModuleTitle
  • handleReqError
  • handleReqException
  • installer_t
  • installer_tr
  • isAllowedDir
  • mediaMigrationRrmdir
  • migrateMediaDir
  • printGraph
  • printR
  • renderFields
  • reqShutdown
  • RIP
  • translateOptions
  • tryGetRemote
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /*****************************************************************************************
  4:  * X2Engine Open Source Edition is a customer relationship management program developed by
  5:  * X2Engine, Inc. Copyright (C) 2011-2016 X2Engine Inc.
  6:  * 
  7:  * This program is free software; you can redistribute it and/or modify it under
  8:  * the terms of the GNU Affero General Public License version 3 as published by the
  9:  * Free Software Foundation with the addition of the following permission added
 10:  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
 11:  * IN WHICH THE COPYRIGHT IS OWNED BY X2ENGINE, X2ENGINE DISCLAIMS THE WARRANTY
 12:  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 13:  * 
 14:  * This program is distributed in the hope that it will be useful, but WITHOUT
 15:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 16:  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
 17:  * details.
 18:  * 
 19:  * You should have received a copy of the GNU Affero General Public License along with
 20:  * this program; if not, see http://www.gnu.org/licenses or write to the Free
 21:  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 22:  * 02110-1301 USA.
 23:  * 
 24:  * You can contact X2Engine, Inc. P.O. Box 66752, Scotts Valley,
 25:  * California 95067, USA. or at email address contact@x2engine.com.
 26:  * 
 27:  * The interactive user interfaces in modified source and object code versions
 28:  * of this program must display Appropriate Legal Notices, as required under
 29:  * Section 5 of the GNU Affero General Public License version 3.
 30:  * 
 31:  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
 32:  * these Appropriate Legal Notices must retain the display of the "Powered by
 33:  * X2Engine" logo. If the display of the logo is not reasonably feasible for
 34:  * technical reasons, the Appropriate Legal Notices must display the words
 35:  * "Powered by X2Engine".
 36:  *****************************************************************************************/
 37: 
 38: /**
 39:  * Behavior to provide requisite methods for checking for potential duplicate
 40:  * records. Currently only implemented in Contacts and Accounts.
 41:  */
 42: class X2DuplicateBehavior extends CActiveRecordBehavior {
 43: 
 44:     // Set constants so that we can change these in the future without issue
 45:     CONST DUPLICATE_FIELD = 'dupeCheck';
 46:     CONST DUPLICATE_LIMIT = 5;
 47: 
 48:     /**
 49:      * Returns whether or not any duplicate records exist in the database. 
 50:      * 
 51:      * Commonly used as a gate in an if statement for other duplicate 
 52:      * checking functionality.
 53:      * @return boolean 
 54:      */
 55:     public function checkForDuplicates() {
 56:         if ($this->owner->{X2DuplicateBehavior::DUPLICATE_FIELD} == 0) {
 57:             $criteria = $this->getDuplicateCheckCriteria();
 58:             return $this->owner->count($criteria) > 0;
 59:         }
 60:         return false;
 61:     }
 62: 
 63:     /**
 64:      * Return a list of potential duplicate records.
 65:      * 
 66:      * Capts at 5 records unless a special parameter is provided so as to prevent
 67:      * possible server crashes from attempting to render large numbers of records.
 68:      * @param boolean $getAll Whether to return all records or just 5
 69:      * @return CActiveDataProvider
 70:      */
 71:     public function getDuplicates($getAll = false, $strict = false) {
 72:         $criteria = $this->getDuplicateCheckCriteria(false, 't', $strict);
 73:         if ($getAll && !empty($criteria->limit)) {
 74:             $criteria = $this->getDuplicateCheckCriteria(true, 't', $strict);
 75:         }
 76:         if (!$getAll) {
 77:             $criteria->limit = X2DuplicateBehavior::DUPLICATE_LIMIT;
 78:         }
 79:         return $this->owner->findAll($criteria);
 80:     }
 81: 
 82:     /**
 83:      * Returns the total number of duplicates found (unrestricted by the limit on
 84:      * getDuplicates)
 85:      * @return int
 86:      */
 87:     public function countDuplicates() {
 88:         $criteria = $this->getDuplicateCheckCriteria();
 89:         return $this->owner->count($criteria);
 90:     }
 91: 
 92:     /**
 93:      * Mark a record as a duplicate.
 94:      * 
 95:      * Set all relevant fields to the proper values for marking a record as duplicate.
 96:      * A duplicate record is private and assigned to 'Anyone', and if there
 97:      * are options for "doNotCall" and "doNotEmail" they need to be turned on.
 98:      * Alternatively, the "delete" string can be passed to delete the record instead
 99:      * of hiding it. This functionality exists in case some future code requires
100:      * more things to be done on deleting duplicates.
101:      * @param string $action
102:      */
103:     public function markAsDuplicate($action = 'hide') {
104:         if ($action === 'hide') {
105:             if ($this->owner->hasAttribute('visibility')) {
106:                 $this->owner->visibility = 0;
107:             }
108:             if ($this->owner->hasAttribute('assignedTo')) {
109:                 $this->owner->assignedTo = 'Anyone';
110:             }
111:             if ($this->owner->hasAttribute('doNotCall')) {
112:                 $this->owner->doNotCall = 1;
113:             }
114:             if ($this->owner->hasAttribute('doNotEmail')) {
115:                 $this->owner->doNotEmail = 1;
116:             }
117:             $this->owner->{X2DuplicateBehavior::DUPLICATE_FIELD} = 1;
118:             $this->owner->update();
119:         } elseif ($action === 'delete') {
120:             $this->owner->delete();
121:         }
122:     }
123: 
124:     /**
125:      * Reset dupeCheck field if duplicate defining fields are changed.
126:      * 
127:      * Records have a concept of "duplicate-defining fields" which are the fields
128:      * that are checked when searching for duplicates (name, email, etc.). If one
129:      * of those fields is changed in an update, the dupeCheck parameter needs to
130:      * be reset and the record needs to be checked for possible duplicates again.
131:      * @param CEvent $event
132:      */
133:     public function afterSave($event) {
134:         if (!$this->owner->getIsNewRecord()) {
135:             $dupeFields = $this->owner->duplicateFields();
136:             $oldAttributes = $this->owner->getOldAttributes();
137:             foreach ($dupeFields as $field) {
138:                 if (array_key_exists($field, $oldAttributes) &&
139:                         $oldAttributes[$field] !== $this->owner->$field) {
140:                     $this->resetDuplicateField();
141:                     break;
142:                 }
143:             }
144:         }
145:     }
146: 
147:     /**
148:      * Update the dupeCheck field to reflect that a record has been checked.
149:      * 
150:      * Set the value in the current record and use updateByPk so that no validation
151:      * or behaviors from afterSave are called.
152:      */
153:     public function duplicateChecked() {
154:         if ($this->owner->{X2DuplicateBehavior::DUPLICATE_FIELD} == 0) {
155:             $this->owner->{X2DuplicateBehavior::DUPLICATE_FIELD} = 1;
156:             $this->owner->updateByPk($this->owner->id, array(X2DuplicateBehavior::DUPLICATE_FIELD => 1));
157:         }
158:     }
159: 
160:     /**
161:      * Reset the dupeCheck field to its unchecked state.
162:      */
163:     public function resetDuplicateField() {
164:         $this->owner->{X2DuplicateBehavior::DUPLICATE_FIELD} = 0;
165:         $this->owner->updateByPk($this->owner->id, array(X2DuplicateBehavior::DUPLICATE_FIELD => 0));
166:     }
167: 
168:     /**
169:      * Hide all potential duplicate records.
170:      * 
171:      * This is equivalent to a mass version of "markAsDuplicate" but it affects
172:      * records other than the currenly loaded one.
173:      */
174:     public function hideDuplicates() {
175:         $criteria = $this->getDuplicateCheckCriteria(false, null);
176:         $attributes = array(
177:             X2DuplicateBehavior::DUPLICATE_FIELD => 1,
178:         );
179:         if ($this->owner->hasAttribute('visibility')) {
180:             $attributes['visibility'] = 0;
181:         }
182:         if ($this->owner->hasAttribute('assignedTo')) {
183:             $attributes['assignedTo'] = 'Anyone';
184:         }
185:         if ($this->owner->hasAttribute('doNotCall')) {
186:             $attributes['doNotCall'] = 1;
187:         }
188:         if ($this->owner->hasAttribute('doNotEmail')) {
189:             $attributes['doNotEmail'] = 1;
190:         }
191:         $this->owner->updateAll($attributes, $criteria);
192:     }
193: 
194:     /**
195:      * Delete all potential duplicate records.
196:      */
197:     public function deleteDuplicates() {
198:         $criteria = $this->getDuplicateCheckCriteria(false, null);
199:         $this->owner->deleteAll($criteria);
200:     }
201:     
202:     /**
203:      * Private helper function to get the duplicate criteria.
204:      * 
205:      * Caches criteria for later use.
206:      * @param boolean $refresh Force refresh of cached criteria
207:      * @return CDbCriteria
208:      */
209:     private $_duplicateCheckCriteria = array ();
210:     private function getDuplicateCheckCriteria($refresh = false, $alias='t', $strict = false) {
211:         if (!$refresh && isset($this->_duplicateCheckCriteria[$alias])) {
212:             return $this->_duplicateCheckCriteria[$alias];
213:         }
214:         $dupeFields = $this->owner->duplicateFields();
215:         $criteria = new CDbCriteria();
216:         $criteria->order = 'createDate ASC';
217:         foreach ($dupeFields as $fieldName) {
218:             if (!empty($this->owner->$fieldName)) {
219:                 $criteria->compare($fieldName, $this->owner->$fieldName, false, $strict?"AND":"OR");
220:             }
221:         }
222:         if (empty($criteria->condition)) {
223:             $criteria->condition = "FALSE";
224:         } else {
225:             $criteria->compare('id', "<>" . $this->owner->id, false, "AND");
226:             if ($this->owner->asa('permissions')) {
227:                 $criteria->mergeWith($this->owner->getAccessCriteria($alias));
228:             }
229:         }
230:         $this->_duplicateCheckCriteria[$alias] = $criteria;
231:         return $this->_duplicateCheckCriteria[$alias];
232:     }
233: 
234: }
235: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0