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

  • X2FlowAction
  • X2FlowItem
  • X2FlowTrigger
  • X2FlowTriggerBehavior
  • 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:  * @package application.components.x2flow
 39:  */
 40: abstract class X2FlowItem extends CComponent {
 41: 
 42:     const VALIDATION_WARNING = 2;
 43: 
 44:     /**
 45:      * "Cache" of instantiated triggers, for reference purposes
 46:      */
 47:     protected static $_instances;
 48: 
 49:     /**
 50:      * $var string the text label for this action
 51:      */
 52:     public $label = '';
 53: 
 54:     /**
 55:      * $var string the description of this action
 56:      */
 57:     public $info = '';
 58: 
 59:     /**
 60:      * $var array the config parameters for this action
 61:      */
 62:     public $config = '';
 63: 
 64:     /**
 65:      * $var bool distinguishes whether cron is required for running the action properly
 66:      */
 67:     public $requiresCron = false;
 68: 
 69:     /**
 70:      * @return array the param rules.
 71:      */
 72:     abstract public function paramRules();
 73: 
 74:     /**
 75:      * Checks if all all the params are ship-shape
 76:      */
 77:     abstract public function validate(&$params=array(), $flowId=null);
 78: 
 79:     /**
 80:      * Checks if all the config variables and runtime params are ship-shape
 81:      * Ignores param requirements if $params isn't provided
 82:      * @param bool $staticValidation If true, validation will include checks for warnings
 83:      */
 84:     public function validateOptions(&$paramRules,$params=null,$staticValidation=false) {
 85:         $configOptions = &$this->config['options'];
 86: 
 87:         // loop through options defined in paramRules() and make sure they're all set in $config
 88:         foreach($paramRules['options'] as &$optRule) {    
 89:             if(!isset($optRule['name']))        // don't worry about unnamed params
 90:                 continue;
 91:             $optName = &$optRule['name'];
 92: 
 93:             // each option must be present in $this->config and $params
 94:             if(!isset($configOptions[$optName])) {  
 95:                 if (isset ($optRule['defaultVal'])) {
 96:                     $configOptions[$optName] = array ();
 97:                 } else {
 98:                     continue; // but just ignore them for future proofing
 99:                 }
100:             }
101:             // if params are provided, check them for this option name
102:             // if($params !== null && !isset($params[$optName]))    
103:                 // return false;
104:             // this is disabled because it doesn't work if every option in $options doesn't 
105:             // correspond to a $param. the ultimate solution is to separate params and options 
106:             // completely. if a trigger/action is going to require params, it should define this 
107:             // separately. the reason for the way it is now is that you can set up an action with 
108:             // very little code. by assuming $params corresponds to $options, check() can
109:             // treat each option like a condition and compare it to the param.
110: 
111:             $option = &$configOptions[$optName];
112: 
113:             // set optional flag
114:             $option['optional'] = isset($optRule['optional']) && $optRule['optional'];
115:             $option['comparison'] = isset($optRule['comparison']) ? $optRule['comparison'] : true;
116: 
117:             // operator defaults to "=" if not set
118:             $option['operator'] = isset($option['operator']) ? $option['operator'] : '=';
119: 
120:             // if there's a type setting, set that in the config data
121:             if(isset($optRule['type']))
122:                 $option['type'] = $optRule['type'];
123: 
124:             // if there's an operator setting, it must be valid
125:             if(isset($optRule['operators']) &&
126:                !in_array($option['operator'], $optRule['operators'])) {
127: 
128:                 return array (
129:                     false,
130:                     Yii::t('studio', 'Flow item validation error: Invalid operator'));
131:             }
132:             
133:             // value must not be empty, unless it's an optional setting
134:             if(!isset($option['value']) || $option['value'] === null || $option['value'] === '') {
135:                 if(isset($optRule['defaultVal'])) { 
136: 
137:                     // use the default value 
138:                     $option['value'] = $optRule['defaultVal'];
139:                 } elseif(!$option['optional']) {
140: 
141:                     // if not, fail if it was required
142:                     if (YII_DEBUG) {
143:                         return array (
144:                             false,
145:                             Yii::t('studio', 
146:                                 'Required flow item input missing: {optName} was left blank.',
147:                                 array ('{optName}' => $optName)));
148:                     } else {
149:                         return array (
150:                             false,
151:                             Yii::t('studio', 'Required flow item input missing'));
152:                     }
153:                 }
154:             }
155:             
156:             if (isset ($option['type']) && isset ($option['value'])) {
157:                 switch ($option['type']) {
158:                     case 'dropdown':
159:                         list ($success, $message) = $this->validateDropdown ($option, $optRule);
160:                         if (!$success) return array (false, $message);
161:                         break;
162:                     case 'email':
163:                         list ($success, $message) = $this->validateEmail ($option, $optRule);
164:                         if (!$success) return array (false, $message);
165:                         break;
166:                 }
167:             }
168:         }
169: 
170:         return array (true, '');
171:     }
172: 
173:     public function validateEmail ($option, $optRule) {
174:         if (isset ($option['value']) && 
175:             !Formatter::isFormula ($option['value']) &&
176:             !Formatter::isShortcode ($option['value'])) {
177:             try {
178:                 EmailDeliveryBehavior::addressHeaderToArray ($option['value']);
179:             } catch (CException $e) {
180:                 return array (false, $e->getMessage ());
181:             }
182:         }
183:         return array (true, '');
184:     }
185: 
186:     public function validateDropdown (&$option, $optRule) {
187:         $name = $optRule['name'];
188:         if (!((isset ($option['operator']) && 
189:                in_array ($option['operator'], array ('list', 'notList', 'between'))) || 
190:               (isset ($optRule['multiple']) && $optRule['multiple'])) && 
191:              is_array ($option['value'])) {
192: 
193:             if (count ($option['value']) === 1 &&
194:                 isset ($option['value'][0])) { // repair value if possible
195: 
196:                 $option['value'] = $option['value'][0];
197:                 return array (true, '');
198:             }
199: 
200:             return array (false, Yii::t('studio', 'Invalid option value for {optionName}. '.
201:                 'Multiple values specified but only one is allowed.', array (
202:                     '{optionName}' => $name,
203:                 )));
204:         }
205:         return array (true, '');
206:     }
207: 
208:     /**
209:      * Gets the param rules for the specified flow item
210:      * @param string $type name of action class
211:      * @return mixed an array of param rules, or false if the action doesn't exist
212:      */
213:     public static function getParamRules($type) {
214:         $item = self::create(array('type'=>$type));
215:         if($item !== null) {
216:             $paramRules = $item->paramRules();
217:             $paramRules['class'] = get_class ($item);
218:             return $paramRules;
219:         }
220:         return false;
221:     }
222: 
223:     /**
224:      * Gets the title property of the specified flow item
225:      * @param string $type name of action class
226:      * @return string the title property, or '' if the type is invalid of if the class
227:      *  associated with the type doesn't have a title property
228:      */
229:     public static function getTitle ($type) {
230:         $item = self::create(array('type'=>$type));
231:         $title = '';
232:         if ($item !== null && property_exists ($item, 'title')) {
233:             $title = $item->title;
234:         }
235:         return $title;
236:     }
237: 
238:     /**
239:      * Creates a flow item with the provided config data
240:      * @return mixed a class extending X2FlowAction with the specified name
241:      */
242:     public static function create($config) {
243:         if(isset($config['type']) && class_exists($config['type'])) {
244:             $item = new $config['type'];
245:             $item->config = $config;
246:             return $item;
247:         }
248:         return null;
249:     }
250: 
251:     /**
252:      * Calculates a time offset from a number and a unit
253:      * @param int $time the number of time units to add
254:      * @param string $unit the unit of time
255:      * @return mixed the calculated timestamp, or false if the $unit is invalid
256:      */
257:     public static function calculateTimeOffset($time,$unit) {
258:         switch($unit) {
259:             case 'secs':
260:                 return $time;
261:             case 'mins':
262:                 return $time * 60;
263:             case 'hours':
264:                 return $time * 3600;
265:             case 'days':
266:                 return $time * 86400;
267:             case 'months':
268:                 return $time * 2629743;    // average seconds in a month
269:             default:
270:                 return false;
271:         }
272:     }
273: 
274:     /**
275:      * @param string $name the name of the option
276:      * @param array $params the parameters passed to trigger ()
277:      * @return mixed null if the option was not set by the user, the parsed value otherwise
278:      */
279:     public function parseOption($name,&$params) {
280:         $options = &$this->config['options'];
281:         if(!isset($options[$name]['value']))
282:             return null;
283: 
284:         $type = isset($options[$name]['type'])? $options[$name]['type'] : '';
285:         
286:         return X2Flow::parseValue($options[$name]['value'],$type,$params);
287:     }
288: 
289:     /**
290:      * Generalized mass-instantiation method.
291:      *
292:      * Loads and instantiates all X2Flow items of a given type (i.e. actions,
293:      * triggers).
294:      * 
295:      * @param type $type
296:      * @param type $excludeClasses
297:      * @return type
298:      */
299:     public static function getInstances($type,$excludeClasses=array()) {
300:         if(!isset(self::$_instances))
301:             self::$_instances = array();
302:         if(!isset(self::$_instances[$type])) {
303:             $excludeFiles = array();
304:             foreach($excludeClasses as $class) {
305:                 $excludedFiles[] = "$class.php";
306:             }
307:             $excludedFiles[] = '.';
308:             $excludedFiles[] = '..';
309: 
310:             self::$_instances[$type] = array();
311:             foreach(scandir(Yii::getPathOfAlias('application.components.x2flow.'.$type)) as $file) {
312:                 if(!preg_match ('/\.php$/', $file) || in_array($file,$excludedFiles)) {
313:                     continue;
314:                 }
315:                 $class = self::create(array('type'=>substr($file,0,-4)));
316:                 if($class !== null)
317:                     self::$_instances[$type][] = $class;
318:             }
319:         }
320:         return self::$_instances[$type];
321:     }
322: 
323: 
324: }
325: 
X2CRM Documentation API documentation generated by ApiGen 2.8.0