/** * Ensure that update and create trigger appropriate flows */ public function testContacts() { X2FlowTestingAuxLib::clearLogs($this); $this->action = 'model'; $this->assertEquals(array(), TriggerLog::model()->findAll()); // Create $contact = array('firstName' => 'Walt', 'lastName' => 'White', 'email' => '*****@*****.**', 'visibility' => 1, 'trackingKey' => '1234'); $ch = $this->getCurlHandle('POST', array('{modelAction}' => 'Contacts'), 'admin', $contact); $response = json_decode(curl_exec($ch), 1); $id = $response['id']; $this->assertResponseCodeIs(201, $ch); $this->assertTrue((bool) ($newContact = Contacts::model()->findBySql('SELECT * FROM x2_contacts WHERE firstName="Walt" AND lastName="White" AND email="*****@*****.**" AND trackingKey="1234"'))); $logs = TriggerLog::model()->findAll(); $this->assertEquals(1, count($logs)); $trace = X2FlowTestingAuxLib::getTraceByFlowId($this->flows('flow1')->id); $this->assertTrue(is_array($trace)); $this->assertTrue(X2FlowTestingAuxLib::checkTrace($trace)); // Update $contact['firstName'] = 'Walter'; $ch = $this->getCurlHandle('PUT', array('{modelAction}' => "Contacts/{$id}.json"), 'admin', $contact); $response = json_decode(curl_exec($ch), 1); $this->assertResponseCodeIs(200, $ch); $newContact->refresh(); $this->assertEquals($contact['firstName'], $newContact['firstName']); $logs = TriggerLog::model()->findAll(); $this->assertEquals(2, count($logs)); $trace = X2FlowTestingAuxLib::getTraceByFlowId($this->flows('flow2')->id); $this->assertTrue(is_array($trace)); $this->assertTrue(X2FlowTestingAuxLib::checkTrace($trace)); }
/** * Returns trace of log for specified flow * @return null|array */ public static function getTraceByFlowId($flowId) { $log = TriggerLog::model()->findByAttributes(array('flowId' => $flowId)); if ($log) { $decodedLog = CJSON::decode($log->triggerLog); return $decodedLog[1]; } else { return $log; } }
public function testRecordLimit() { $this->clearLogs(); Yii::app()->settings->triggerLogMax = 5; Yii::app()->settings->save(); //TriggerLog::model ()->asa ('RecordLimitBehavior')->limit = 5; $contact = $this->contacts('testUser'); $params = array('model' => $this->contacts('testUser')); X2Flow::trigger('RecordViewTrigger', $params); $this->assertEquals(1, TriggerLog::model()->count()); sleep(1); // ensure that log timestamps differ X2Flow::trigger('RecordViewTrigger', $params); $this->assertEquals(2, TriggerLog::model()->count()); sleep(1); X2Flow::trigger('RecordViewTrigger', $params); $this->assertEquals(3, TriggerLog::model()->count()); sleep(1); X2Flow::trigger('RecordViewTrigger', $params); $this->assertEquals(4, TriggerLog::model()->count()); sleep(1); X2Flow::trigger('RecordViewTrigger', $params); $this->assertEquals(5, TriggerLog::model()->count()); $triggerLogMinTS = Yii::app()->db->createCommand()->select('min(triggeredAt)')->from('x2_trigger_logs')->queryScalar(); sleep(1); X2Flow::trigger('RecordViewTrigger', $params); $this->assertEquals(5, TriggerLog::model()->count()); $triggerLogNewMinTS = Yii::app()->db->createCommand()->select('min(triggeredAt)')->from('x2_trigger_logs')->queryScalar(); // ensure that oldest log was removed $this->assertNotEquals($triggerLogMinTS, $triggerLogNewMinTS); // now remove the limit $triggerLogMinTS = $triggerLogNewMinTS; Yii::app()->settings->triggerLogMax = null; Yii::app()->settings->save(); //TriggerLog::model ()->asa ('RecordLimitBehavior')->limit = null; sleep(1); X2Flow::trigger('RecordViewTrigger', $params); $this->assertEquals(6, TriggerLog::model()->count()); $triggerLogNewMinTS = Yii::app()->db->createCommand()->select('min(triggeredAt)')->from('x2_trigger_logs')->queryScalar(); $this->assertEquals($triggerLogMinTS, $triggerLogNewMinTS); }
/** * 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; }
public function actionDeleteTriggerLog($id) { if (isset($id)) { $triggerLog = TriggerLog::model()->findByAttributes(array('id' => $id)); if (!empty($triggerLog)) { $triggerLog->delete(); echo "success"; return; } } echo "failure"; }