/** * Wrapper around _executeFlow which respects trigger depth restriction */ public static function executeFlow(&$flow, &$params, $actionId = null) { if (self::$_triggerDepth > self::MAX_TRIGGER_DEPTH) { // ...have we delved too deep? return; } self::$_triggerDepth++; $triggerInfo = array('triggerName' => Yii::t('studio', X2FlowItem::getTitle('MacroTrigger'))); if (isset($params['model']) && is_subclass_of($params['model'], 'X2Model') && $params['model']->asa('X2LinkableBehavior')) { $triggerInfo['modelLink'] = Yii::t('studio', 'View record: ') . $params['model']->getLink(); } $triggerLog = new TriggerLog(); $triggerLog->triggeredAt = time(); $triggerLog->flowId = $flow->id; $triggerLog->save(); $flowRetArr = self::_executeFlow($flow, $params, $actionId, $triggerLog->id); $flowTrace = $flowRetArr['trace']; // save log for triggered flow $triggerLog->triggerLog = CJSON::encode(array_merge(array($triggerInfo), array($flowTrace))); $triggerLog->save(); self::$_triggerDepth--; // this trigger call is done; decrement the stack depth return $flowRetArr; }
/** * Looks up and runs automation actions that match the provided trigger name and parameters. * * @param string $trigger the name of the trigger to fire * @param array $params an associative array of params, usually including 'model'=>$model, * the primary X2Model to which this trigger applies. * @staticvar int $triggerDepth the current depth of the call stack * @return mixed Null or return value of extractRetValFromTrace */ public static function trigger($triggerName, $params = array()) { if (self::$_triggerDepth > self::MAX_TRIGGER_DEPTH) { // ...have we delved too deep? return; } $triggeredAt = time(); if (isset($params['model']) && (!is_object($params['model']) || !$params['model'] instanceof X2Model)) { // Invalid model provided return false; } // Communicate the event to third-party systems, if any ApiHook::runAll($triggerName, $params); // increment stack depth before doing anything that might call X2Flow::trigger() self::$_triggerDepth++; $flowAttributes = array('triggerType' => $triggerName, 'active' => 1); if (isset($params['model'])) { $flowAttributes['modelClass'] = get_class($params['model']); $params['modelClass'] = get_class($params['model']); } // if flow id is specified, only execute flow with specified id if (isset($params['flowId'])) { $flowAttributes['id'] = $params['flowId']; } $flowTraces = array(); $flows = CActiveRecord::model('X2Flow')->findAllByAttributes($flowAttributes); // collect information about trigger for the trigger log. $triggerInfo = array('triggerName' => Yii::t('studio', X2FlowItem::getTitle($triggerName))); if (isset($params['model']) && is_subclass_of($params['model'], 'X2Model') && $params['model']->asa('X2LinkableBehavior')) { $triggerInfo['modelLink'] = Yii::t('studio', 'View record: ') . $params['model']->getLink(); } // find all flows matching this trigger and modelClass $triggerLog; $flowTrace; $flowRetVal = null; foreach ($flows as &$flow) { $triggerLog = new TriggerLog(); $triggerLog->triggeredAt = $triggeredAt; $triggerLog->flowId = $flow->id; $triggerLog->save(); $flowRetArr = self::executeFlow($flow, $params, null, $triggerLog->id); $flowTrace = $flowRetArr['trace']; $flowRetVal = isset($flowRetArr['retVal']) ? $flowRetArr['retVal'] : null; $flowRetVal = self::extractRetValFromTrace($flowTrace); $flowTraces[] = $flowTrace; // save log for triggered flow $triggerLog->triggerLog = CJSON::encode(array_merge(array($triggerInfo), array($flowTrace))); $triggerLog->save(); } // old logging system, uncomment to enable file based logging /*file_put_contents('triggerLog.txt', $triggerName.":\n", FILE_APPEND); file_put_contents('triggerLog.txt', print_r($flowTraces, true).":\n", FILE_APPEND);*/ self::$_triggerDepth--; // this trigger call is done; decrement the stack depth return $flowRetVal; }