public function afterUpdate($event) { if ($this->updateTriggerEnabled) { X2Flow::trigger('RecordUpdateTrigger', array('model' => $this->getOwner())); $this->updateTriggerEnabled = false; } }
/** * Displays a particular model. * @param integer $id the ID of the model to be displayed */ public function actionView($id, $replyId = null, $latest = null) { $page = null; $model = $this->loadModel($id); if (!is_null($latest) && !Yii::app()->request->isAjaxRequest) { $replyId = $model->lastPost->id; } if (!is_null($replyId) && !Yii::app()->request->isAjaxRequest) { $post = TopicReplies::model()->findByPk($replyId); if (!is_null($post)) { $page = $post->getTopicPage(); } else { $replyId = null; } } $this->noBackdrop = true; $topicReply = new TopicReplies(); if (!isset($_GET['ajax'])) { $log = new ViewLog(); $log->user = Yii::app()->user->getName(); $log->recordType = get_class($model); $log->recordId = $model->id; $log->timestamp = time(); $log->save(); X2Flow::trigger('RecordViewTrigger', array('model' => $model)); } $dataProvider = new CArrayDataProvider($model->replies, array('id' => 'topic-replies', 'pagination' => array('pageSize' => Topics::PAGE_SIZE))); $dataProvider->getPagination()->setItemCount($dataProvider->getTotalItemCount()); if (!Yii::app()->request->isAjaxRequest && !is_null($page)) { $dataProvider->getPagination()->setCurrentPage($page); } $this->render('view', array('model' => $model, 'replyId' => $replyId, 'dataProvider' => $dataProvider, 'topicReply' => $topicReply, 'page' => is_null($page) ? $dataProvider->getPagination()->getCurrentPage() : $page)); }
/** * Displays a particular model. * @param integer $id the ID of the model to be displayed */ public function actionView($id) { $model = $this->loadModel($id); if (!$this->checkPermissions($model, 'view')) { $this->denied(); } // add doc to user's recent item list User::addRecentItem('d', $id, Yii::app()->user->getId()); X2Flow::trigger('RecordViewTrigger', array('model' => $model)); $this->render('view', array('model' => $model)); }
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); }
/** * Displays a particular model. * * This method is called in child controllers * which pass it a model to display and what type of model it is (i.e. Contact, * Opportunity, Account). It also creates an action history and provides appropriate * variables to the view. * * @param mixed $model The model to be displayed (subclass of {@link CActiveRecord} or {@link X2Model} * @param String $type The type of the module being displayed */ public function view(&$model, $type = null, $params = array()) { $this->noBackdrop = true; // should only happen when the model is known to have X2LinkableBehavior if ($type === null) { // && $model->asa('X2LinkableBehavior') !== null) $type = $model->module; } if (!isset($_GET['ajax'])) { $log = new ViewLog(); $log->user = Yii::app()->user->getName(); $log->recordType = get_class($model); $log->recordId = $model->id; $log->timestamp = time(); $log->save(); X2Flow::trigger('RecordViewTrigger', array('model' => $model)); } $this->render('view', array_merge($params, array('model' => $model, 'actionHistory' => $this->getHistory($model, $type), 'currentWorkflow' => $this->getCurrentWorkflow($model->id, $type)))); }
/** * Uncompletes a stage (if completed) or unstarts it (if started). * @param $unstarts bool If false, will not attempt to unstart an ongoing stage */ public static function revertStage($workflowId, $stageNumber, $model, $unstart = true, $workflowStatus = null) { //AuxLib::debugLogR ('reverting stage '.$stageNumber); $modelId = $model->id; $type = lcfirst(X2Model::getModuleName(get_class($model))); if (!$workflowStatus) { $workflowStatus = Workflow::getWorkflowStatus($workflowId, $modelId, $type); } $stageCount = count($workflowStatus['stages']); $reverted = false; // if stage has been started or completed if ($model !== null && self::isStarted($workflowStatus, $stageNumber)) { // find selected stage (and duplicates) $actions = X2Model::model('Actions')->findAllByAttributes(array('associationId' => $modelId, 'associationType' => $type, 'type' => 'workflow', 'workflowId' => $workflowId, 'stageNumber' => $stageNumber), new CDbCriteria(array('order' => 'createDate DESC'))); // if there is more than 1 action for this stage, if (count($actions) > 1) { // delete all but the most recent one for ($i = 1; $i < count($actions); $i++) { $actions[$i]->delete(); } } // the stage is complete, so just set it to 'started' if (self::isCompleted($workflowStatus, $stageNumber) && self::canUncomplete($workflowStatus, $stageNumber)) { //AuxLib::debugLogR ('uncompleting stage '.$stageNumber); $actions[0]->setScenario('workflow'); // don't genererate normal action changelog/triggers/events $actions[0]->disableBehavior('changelog'); $actions[0]->disableBehavior('tags'); // no tags up in here $actions[0]->complete = 'No'; $actions[0]->completeDate = null; $actions[0]->completedBy = ''; // original completion note no longer applies $actions[0]->actionDescription = ''; $actions[0]->save(); self::updateWorkflowChangelog($actions[0], 'revert', $model); X2Flow::trigger('WorkflowRevertStageTrigger', array('workflow' => $actions[0]->workflow, 'model' => $model, 'workflowId' => $actions[0]->workflow->id, 'stageNumber' => $stageNumber)); // delete all incomplete stages after this one // X2Model::model('Actions')->deleteAll(new CDbCriteria( // array('condition'=>"associationId=$modelId AND associationType='$type' AND type='workflow' AND workflowId=$workflowId AND stageNumber > $stageNumber AND (completeDate IS NULL OR completeDate=0)") // )); } else { if ($unstart) { // the stage is already incomplete, so delete it and all subsequent stages $subsequentActions = X2Model::model('Actions')->findAll(new CDbCriteria(array('condition' => "associationId={$modelId} AND associationType='{$type}' " . "AND type='workflow' AND workflowId={$workflowId} " . "AND stageNumber >= {$stageNumber}"))); foreach ($subsequentActions as &$action) { self::updateWorkflowChangelog($action, 'revert', $model); X2Flow::trigger('WorkflowRevertStageTrigger', array('workflow' => $action->workflow, 'model' => $model, 'workflowId' => $action->workflow->id, 'stageNumber' => $action->stageNumber)); $action->delete(); } } } $workflowStatus = Workflow::getWorkflowStatus($workflowId, $modelId, $type); $reverted = true; } //AuxLib::debugLogR ((int) $reverted); return array($reverted, $workflowStatus); }
public function execute(&$params) { $url = $this->parseOption('url', $params); if (strpos($url, 'http') === false) { $url = 'http://' . $url; } $method = $this->parseOption('method', $params); if ($this->parseOption('immediate', $params) || true) { $headers = array(); $httpOptions = array('timeout' => 5, 'method' => $method); if (isset($this->config['headerRows'])) { $headers = $this->getHeaders($this->config['headerRows'], $params); } if ($method !== 'GET' && $this->parseOption('jsonPayload', $params)) { $data = $this->parseOption('jsonBlob', $params); } elseif (isset($this->config['attributes']) && !empty($this->config['attributes'])) { $data = array(); foreach ($this->config['attributes'] as $param) { if (isset($param['name'], $param['value'])) { $data[$param['name']] = X2Flow::parseValue($param['value'], '', $params, false); } } } if (isset($data)) { if ($method === 'GET') { $data = http_build_query($data); // make sure the URL is ready for GET params $url .= strpos($url, '?') === false ? '?' : '&'; $url .= $data; } else { if ($this->parseOption('jsonPayload', $params)) { // nested JSON option if (!isset($headers['Content-Type'])) { $headers['Content-Type'] = 'application/json'; } $httpOptions['content'] = $data; } else { // set up default header for POST style data if (!isset($headers['Content-Type'])) { $headers['Content-Type'] = 'application/x-www-form-urlencoded'; } if (preg_match("/application\\/json/", $headers['Content-Type'])) { // legacy flat JSON object support $data = CJSON::encode($data); $httpOptions['content'] = $data; } else { $data = http_build_query($data); $httpOptions['content'] = $data; } } // set up default header for POST style data if (!isset($headers['Content-Length'])) { $headers['Content-Length'] = strlen($data); } } } if (count($headers)) { $formattedHeaders = $this->formatHeaders($headers); $httpOptions['header'] = implode("\r\n", $formattedHeaders); } $context = stream_context_create(array('http' => $httpOptions)); if (!$this->validateUrl($url)) { if (YII_UNIT_TESTING) { return array(false, array('url' => $url)); } else { return array(false, Yii::t('studio', 'Requests cannot be made to X2Engine\'s API from X2Flow.')); } } if (!$this->getMakeRequest()) { return array(true, array_merge(array('url' => $url), $httpOptions)); } else { $response = @file_get_contents($url, false, $context); $params['returnValue'] = $response; if ($response !== false) { if (YII_UNIT_TESTING) { return array(true, $response); } else { return array(true, Yii::t('studio', "Remote API call succeeded")); } } else { if (YII_UNIT_TESTING) { return array(false, print_r($http_response_header, true)); } else { return array(false, Yii::t('studio', "Remote API call failed!")); } } } } }
public function paramRules() { return array('title' => Yii::t('studio', $this->title), 'info' => Yii::t('studio', $this->info), 'modelClass' => 'modelClass', 'options' => array(array('name' => 'modelClass', 'label' => Yii::t('studio', 'Record Type'), 'type' => 'dropdown', 'options' => X2Flow::getModelTypes(true)))); }
/** * Logs the deletion of the model */ public function afterDelete($event) { $modelClass = get_class($this->getOwner()); if ($modelClass === 'Actions' && $this->getOwner()->workflowId !== null) { // no deletion events for workflow actions, that's somebody else's problem return; } if ($this->createEvent) { $event = new Events(); $event->type = 'record_deleted'; $event->associationType = $modelClass; $event->associationId = $this->getOwner()->id; if ($this->getOwner()->hasAttribute('visibility')) { $event->visibility = $this->getOwner()->visibility; } $event->text = $this->getOwner()->name; $event->user = $this->editingUsername; $event->save(); } $log = new Changelog(); $log->type = $modelClass; $log->itemId = $this->getOwner()->id; $log->recordName = $this->getOwner()->name; $log->changed = 'delete'; $log->changedBy = $this->editingUsername; $log->timestamp = time(); $log->save(); X2Flow::trigger('RecordDeleteTrigger', array('model' => $this->getOwner())); }
/** * Runs the user_logout automation trigger * * @return boolean whether or not to logout */ protected function beforeLogout() { X2Flow::trigger('UserLogoutTrigger', array('user' => $this->getName())); return parent::beforeLogout(); }
public static function getRecentItems() { $userRecord = X2Model::model('User')->findByPk(Yii::app()->user->getId()); //get array of type-ID pairs $recentItemsTemp = empty($userRecord->recentItems) ? array() : explode(',', $userRecord->recentItems); $recentItems = array(); //get record for each ID/type pair foreach ($recentItemsTemp as $item) { $itemType = strtok($item, '-'); $itemId = strtok('-'); switch ($itemType) { case 'c': // contact $record = X2Model::model('Contacts')->findByPk($itemId); break; case 't': // action $record = X2Model::model('Actions')->findByPk($itemId); break; case 'a': // account $record = X2Model::model('Accounts')->findByPk($itemId); break; case 'p': // campaign $record = X2Model::model('Campaign')->findByPk($itemId); break; case 'o': // opportunity $record = X2Model::model('Opportunity')->findByPk($itemId); break; case 'w': // workflow $record = X2Model::model('Workflow')->findByPk($itemId); break; case 's': // service case $record = X2Model::model('Services')->findByPk($itemId); break; case 'd': // document $record = X2Model::model('Docs')->findByPk($itemId); break; case 'l': // x2leads object $record = X2Model::model('X2Leads')->findByPk($itemId); break; case 'm': // media object $record = X2Model::model('Media')->findByPk($itemId); break; case 'r': // product $record = X2Model::model('Product')->findByPk($itemId); break; case 'q': // product $record = X2Model::model('Quote')->findByPk($itemId); break; case 'g': // group $record = X2Model::model('Groups')->findByPk($itemId); break; case 'f': // x2flow $record = X2Flow::model()->findByPk($itemId); break; default: printR('Warning: getRecentItems: invalid item type' . $itemType); continue; } if (!is_null($record)) { //only include item if the record ID exists array_push($recentItems, array('type' => $itemType, 'model' => $record)); } } return $recentItems; }
/** * Marks this campaign/newsletter item as unsubscribed. * If a contact record is available, unsubscribe them from all other lists as well. */ public function unsubscribe($email = null) { if ($this->opened == 0) { $this->markOpened(); } // mark as opened, run automation for email open if ($this->unsubscribed == 0) { $this->unsubscribed = time(); $this->update(array('unsubscribed')); } // unsubscribe this email from all other newsletters CActiveRecord::model('X2ListItem')->updateAll(array('unsubscribed' => time()), 'emailAddress=:email AND unsubscribed=0', array('email' => $this->emailAddress)); if ($this->list->campaign !== null) { if ($this->contact !== null) { // regular campaign // update the contact $this->contact->doNotEmail = true; $this->contact->lastActivity = time(); $this->contact->update(array('doNotEmail', 'lastActivity')); X2Flow::trigger('CampaignUnsubscribeTrigger', array('model' => $this->contact, 'campaign' => $this->list->campaign->name)); } elseif (isset($this->list)) { // no contact, must be a newsletter X2Flow::trigger('NewsletterUnsubscribeTrigger', array('item' => $this, 'email' => $this->emailAddress, 'campaign' => $this->list->campaign->name)); } } }
/** * Trigger the X2Workflow RecordCreateTrigger on the imported models * @param array $importedIds List of record ids * @param string $type Model name */ protected function triggerImportedRecords($importedIds, $type) { foreach ($importedIds as $id) { $model = X2Model::model($type)->findByPk($id); X2Flow::trigger('RecordCreateTrigger', array('model' => $model)); } }
private function handleWebleadFormSubmission(X2Model $model, $extractedParams) { $newRecord = $model->isNewRecord; if (isset($_POST['Contacts'])) { $model->createEvent = false; $model->setX2Fields($_POST['Contacts'], true); // Extra sanitizing $p = Fields::getPurifier(); foreach ($model->attributes as $name => $value) { if ($name != $model->primaryKey() && !empty($value)) { $model->{$name} = $p->purify($value); } } $now = time(); //require email field, check format /*if(preg_match( "/[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/", $_POST['Contacts']['email']) == 0) { $this->renderPartial('application.components.views.webFormSubmit', array ( 'type' => 'weblead', 'error' => Yii::t('contacts', 'Invalid Email Address') ) ); return; }*/ if (empty($model->visibility)) { $model->visibility = 1; } $model->validate(null, false); if (!$model->hasErrors()) { $duplicates = array(); if (!empty($model->email)) { //find any existing contacts with the same contact info $criteria = new CDbCriteria(); $criteria->compare('email', $model->email, false, "OR"); $emailFields = Yii::app()->db->createCommand()->select('fieldName')->from('x2_fields')->where('modelName = "Contacts" AND type = "email"')->queryColumn(); foreach ($emailFields as $field) { $criteria->compare($field, $model->email, false, "OR"); } $duplicates = $model->findAll($criteria); } if (count($duplicates) > 0) { //use existing record, update background info $newBgInfo = $model->backgroundInfo; $model = $duplicates[0]; $oldBgInfo = $model->backgroundInfo; if ($newBgInfo !== $oldBgInfo) { $model->backgroundInfo .= ($oldBgInfo && $newBgInfo ? "\n" : '') . $newBgInfo; } $success = $model->save(); } else { //create new record $model->assignedTo = $this->controller->getNextAssignee(); $model->visibility = 1; $model->createDate = $now; $model->lastUpdated = $now; $model->updatedBy = 'admin'; $success = $model->save(); //TODO: upload profile picture url from webleadfb } if ($success) { if ($extractedParams['generateLead']) { self::generateLead($model, $extractedParams['leadSource']); } if ($extractedParams['generateAccount']) { self::generateAccount($model); } self::addTags($model); $tags = !isset($_POST['tags']) || empty($_POST['tags']) ? array() : explode(',', $_POST['tags']); if ($newRecord) { X2Flow::trigger('WebleadTrigger', array('model' => $model, 'tags' => $tags)); } //use the submitted info to create an action $action = new Actions(); $action->actionDescription = Yii::t('contacts', 'Web Lead') . "\n\n" . Yii::t('contacts', 'Name') . ': ' . CHtml::decode($model->firstName) . " " . CHtml::decode($model->lastName) . "\n" . Yii::t('contacts', 'Email') . ": " . CHtml::decode($model->email) . "\n" . Yii::t('contacts', 'Phone') . ": " . CHtml::decode($model->phone) . "\n" . Yii::t('contacts', 'Background Info') . ": " . CHtml::decode($model->backgroundInfo); // create action $action->type = 'note'; $action->assignedTo = $model->assignedTo; $action->visibility = '1'; $action->associationType = 'contacts'; $action->associationId = $model->id; $action->associationName = $model->name; $action->createDate = $now; $action->lastUpdated = $now; $action->completeDate = $now; $action->complete = 'Yes'; $action->updatedBy = 'admin'; $action->save(); // create a notification if the record is assigned to someone $event = new Events(); $event->associationType = 'Contacts'; $event->associationId = $model->id; $event->user = $model->assignedTo; $event->type = 'weblead_create'; $event->save(); if ($model->assignedTo != 'Anyone' && $model->assignedTo != '') { $notif = new Notification(); $notif->user = $model->assignedTo; $notif->createdBy = 'API'; $notif->createDate = time(); $notif->type = 'weblead'; $notif->modelType = 'Contacts'; $notif->modelId = $model->id; $notif->save(); $profile = Profile::model()->findByAttributes(array('username' => $model->assignedTo)); /* send user that's assigned to this weblead an email if the user's email address is set and this weblead has a user email template */ if ($profile !== null && !empty($profile->emailAddress)) { $subject = Yii::t('marketing', 'New Web Lead'); $message = Yii::t('marketing', 'A new web lead has been assigned to you: ') . CHtml::link($model->firstName . ' ' . $model->lastName, array('/contacts/contacts/view', 'id' => $model->id)) . '.'; $address = array('to' => array(array('', $profile->emailAddress))); $emailFrom = Credentials::model()->getDefaultUserAccount(Credentials::$sysUseId['systemNotificationEmail'], 'email'); if ($emailFrom == Credentials::LEGACY_ID) { $emailFrom = array('name' => $profile->fullName, 'address' => $profile->emailAddress); } $status = $this->controller->sendUserEmail($address, $subject, $message, null, $emailFrom); } } } else { $errMsg = 'Error: WebListenerAction.php: model failed to save'; /**/ AuxLib::debugLog($errMsg); Yii::log($errMsg, '', 'application.debug'); } $this->controller->renderPartial('application.components.views.webFormSubmit', array('type' => 'weblead')); Yii::app()->end(); // success! } } $sanitizedGetParams = self::sanitizeGetParams(); $this->controller->renderPartial('application.components.views.webForm', array_merge(array('type' => 'weblead'), $sanitizedGetParams)); }
public function actionPublisherCreate() { if (isset($_POST['SelectedTab'], $_POST['Actions']) && (!Yii::app()->user->isGuest || Yii::app()->user->checkAccess($_POST['Actions']['associationType'] . 'View'))) { Yii::app()->clientScript->scriptMap['*.css'] = false; // if association name is sent without id, try to lookup the record by name and type if (isset($_POST['calendarEventTab']) && $_POST['calendarEventTab'] && isset($_POST['Actions']['associationName']) && empty($_POST['Actions']['associationId'])) { $associatedModel = X2Model::getModelOfTypeWithName($_POST['Actions']['associationType'], $_POST['Actions']['associationName']); if ($associatedModel) { $_POST['Actions']['associationId'] = $associatedModel->id; } else { echo CJSON::encode(array('error' => Yii::t('actions', 'Invalid association name'))); Yii::app()->end(); } } if (!Yii::app()->user->isGuest) { $model = new Actions(); } else { $model = new Actions('guestCreate'); $model->verifyCode = $_POST['Actions']['verifyCode']; } $model->setX2Fields($_POST['Actions']); // format dates, if (isset($_POST[get_class($model)]['dueDate'])) { $model->dueDate = Formatter::parseDateTime($_POST[get_class($model)]['dueDate']); } if ($_POST['SelectedTab'] == 'new-event' || $_POST['SelectedTab'] == 'new-small-calendar-event') { $model->disableBehavior('changelog'); $event = new Events(); $event->type = 'calendar_event'; $event->visibility = $model->visibility; $event->associationType = 'Actions'; $event->timestamp = $model->dueDate; $model->type = 'event'; if ($model->completeDate) { $model->completeDate = Formatter::parseDateTime($model->completeDate); } else { $model->completeDate = $model->dueDate; } } // format association if ($model->associationId == '') { $model->associationId = 0; } $association = $this->getAssociation($model->associationType, $model->associationId); if ($association) { $model->associationName = $association->name; if ($association->hasAttribute('lastActivity')) { $association->lastActivity = time(); $association->update(array('lastActivity')); X2Flow::trigger('RecordUpdateTrigger', array('model' => $association)); } } else { $model->associationName = 'none'; } if ($model->associationName == 'None' && $model->associationType != 'none') { $model->associationName = ucfirst($model->associationType); } if (in_array($_POST['SelectedTab'], array('log-a-call', 'new-comment', 'log-time-spent'))) { // Set the complete date accordingly: if (!empty($_POST[get_class($model)]['completeDate'])) { $model->completeDate = Formatter::parseDateTime($_POST[get_class($model)]['completeDate']); } foreach (array('dueDate', 'completeDate') as $attr) { if (empty($model->{$attr})) { $model->{$attr} = time(); } } if ($model->dueDate > $model->completeDate) { // User specified a negative time range! Let's say that the // starting time is equal to when it ended (which is earlier) $model->dueDate = $model->completeDate; } $model->complete = 'Yes'; $model->visibility = '1'; $model->assignedTo = Yii::app()->user->getName(); $model->completedBy = Yii::app()->user->getName(); if ($_POST['SelectedTab'] == 'log-a-call') { $model->type = 'call'; } elseif ($_POST['SelectedTab'] == 'log-time-spent') { $model->type = 'time'; } else { $model->type = 'note'; } } if (in_array($model->type, array('call', 'time', 'note'))) { $event = new Events(); $event->associationType = 'Actions'; $event->type = 'record_create'; $event->user = Yii::app()->user->getName(); $event->visibility = $model->visibility; $event->subtype = $model->type; } // save model $model->createDate = time(); if (!empty($model->type)) { $model->disableBehavior('changelog'); } if ($model->save()) { // action saved to database * if (isset($_POST['Actions']['reminder']) && $_POST['Actions']['reminder']) { $model->createNotifications($_POST['notificationUsers'], $model->dueDate - $_POST['notificationTime'] * 60, 'action_reminder'); } X2Model::updateTimerTotals($model->associationId, X2Model::getModelName($model->associationType)); if (isset($event)) { $event->associationId = $model->id; $event->save(); } $model->syncGoogleCalendar('create', true); } else { if ($model->hasErrors('verifyCode')) { echo CJSON::encode(array('error' => $model->getError('verifyCode'))); Yii::app()->end(); } } echo CJSON::encode(array('success')); Yii::app()->end(); } else { throw new CHttpException(400, Yii::t('app', 'Bad request')); } }
public function actionViewAction($id, $publisher = false) { $this->redirectOnNullModel = false; $this->throwOnNullModel = false; $model = $this->loadModel($id); if (isset($model)) { if (in_array($model->type, Actions::$emailTypes)) { $this->actionViewEmail($id); return; } X2Flow::trigger('RecordViewTrigger', array('model' => $model)); $this->renderPartial('_viewFrame', array('model' => $model, 'publisher' => $publisher)); } else { echo "<b>Error: 404</b><br><br>Unable to find the requested action."; } }
public function paramRules() { return array('title' => Yii::t('studio', $this->title), 'info' => Yii::t('studio', $this->info), 'modelClass' => 'modelClass', 'options' => array(array('name' => 'modelClass', 'label' => Yii::t('studio', 'Record Type'), 'type' => 'dropdown', 'options' => X2Flow::getModelTypes(true)), array('name' => 'subject', 'label' => Yii::t('emailInboxes', 'Subject'), 'operators' => array('=', '<>', 'list', 'notList', 'contains', 'noContains'), 'optional' => 1), array('name' => 'body', 'label' => Yii::t('emailInboxes', 'Body'), 'operators' => array('=', '<>', 'list', 'notList', 'contains', 'noContains'), 'optional' => 1), array('name' => 'to', 'label' => Yii::t('emailInboxes', 'To'), 'operators' => array('=', '<>', 'list', 'notList', 'contains', 'noContains'), 'optional' => 1), array('name' => 'from', 'label' => Yii::t('emailInboxes', 'From'), 'operators' => array('=', '<>', 'list', 'notList', 'contains', 'noContains'), 'optional' => 1))); }
/** * Removes the specified tag(s) from the owner model * @param mixed $tags a string or array of strings containing tags * @return boolean whether or not at least one tag was deleted successfully */ public function removeTags($tags) { $result = false; $removedTags = array(); $tags = Tags::normalizeTags((array) $tags); foreach ((array) $tags as $tag) { if (empty($tag)) { continue; } $attributes = array('type' => get_class($this->getOwner()), 'itemId' => $this->getOwner()->id, 'tag' => $tag); if ($this->hasTag($tag) && CActiveRecord::model('Tags')->deleteAllByAttributes($attributes) > 0) { if (false !== ($offset = array_search($tag, $this->_tags))) { unset($this->_tags[$offset]); } // update tag cache $removedTags[] = $tag; $result = true; } } if ($this->flowTriggersEnabled) { X2Flow::trigger('RecordTagRemoveTrigger', array('model' => $this->getOwner(), 'tags' => $removedTags)); } return $result; }
public function paramRules() { return array('title' => $this->title, 'modelClass' => 'modelClass', 'options' => array(array('name' => 'attributes'), array('name' => 'modelClass', 'label' => Yii::t('studio', 'Record Type'), 'type' => 'dropdown', 'options' => X2Flow::getModelTypes(true)), array('name' => 'createRelationship', 'label' => Yii::t('studio', 'Create Relationship') . '<span class="x2-hint" title="' . Yii::t('app', 'Check this box if you want a new relationship to be ' . 'established between the record created by this action and the record that' . ' triggered the flow.') . '"> [?]</span>', 'type' => 'boolean', 'defaultVal' => false))); }
/** * @param string $name the name of the option * @param array $params the parameters passed to trigger () * @return mixed null if the option was not set by the user, the parsed value otherwise */ public function parseOption($name, &$params) { $options =& $this->config['options']; if (!isset($options[$name]['value'])) { return null; } $type = isset($options[$name]['type']) ? $options[$name]['type'] : ''; return X2Flow::parseValue($options[$name]['value'], $type, $params); }
/** * @param Array $condition * @param Array $params * @return bool true for success, false otherwise */ public static function checkCondition($condition, &$params) { if ($condition['type'] === 'workflow_status') { return self::checkWorkflowStatusCondition($condition, $params); } $model = isset($params['model']) ? $params['model'] : null; $operator = isset($condition['operator']) ? $condition['operator'] : '='; // $type = isset($condition['type'])? $condition['type'] : null; $value = isset($condition['value']) ? $condition['value'] : null; // default to a doing basic value comparison if (isset($condition['name']) && $condition['type'] === '') { if (!isset($params[$condition['name']])) { return false; } return self::evalComparison($params[$condition['name']], $operator, $value); } switch ($condition['type']) { case 'attribute': if (!isset($condition['name'], $model)) { return false; } $attr =& $condition['name']; if (null === ($field = $model->getField($attr))) { return false; } if ($operator === 'changed') { return $model->attributeChanged($attr); } if ($field->type === 'link') { list($attrVal, $id) = Fields::nameAndId($model->getAttribute($attr)); } else { $attrVal = $model->getAttribute($attr); } return self::evalComparison($attrVal, $operator, X2Flow::parseValue($value, $field->type, $params), $field); case 'current_user': return self::evalComparison(Yii::app()->user->getName(), $operator, X2Flow::parseValue($value, 'assignment', $params)); case 'month': return self::evalComparison((int) date('n'), $operator, $value); // jan = 1, dec = 12 // jan = 1, dec = 12 case 'day_of_month': return self::evalComparison((int) date('j'), $operator, $value); // 1 through 31 // 1 through 31 case 'day_of_week': return self::evalComparison((int) date('N'), $operator, $value); // monday = 1, sunday = 7 // monday = 1, sunday = 7 case 'time_of_day': // - mktime(0,0,0) return self::evalComparison(time(), $operator, X2Flow::parseValue($value, 'time', $params)); // seconds since midnight // case 'current_local_time': // seconds since midnight // case 'current_local_time': case 'current_time': return self::evalComparison(time(), $operator, X2Flow::parseValue($value, 'dateTime', $params)); case 'user_active': return CActiveRecord::model('Session')->exists('user=:user AND status=1', array(':user' => X2Flow::parseValue($value, 'assignment', $params))); case 'on_list': if (!isset($model, $value)) { return false; } $value = X2Flow::parseValue($value, 'link'); // look up specified list if (is_numeric($value)) { $list = CActiveRecord::model('X2List')->findByPk($value); } else { $list = CActiveRecord::model('X2List')->findByAttributes(array('name' => $value)); } return $list !== null && $list->hasRecord($model); case 'has_tags': if (!isset($model, $value)) { return false; } $tags = X2Flow::parseValue($value, 'tags'); return $model->hasTags($tags, 'AND'); case 'workflow_status': if (!isset($model, $condition['workflowId'], $condition['stageNumber'])) { return false; } switch ($operator) { case 'started_workflow': return CActiveRecord::model('Actions')->exists('associationType=:type AND associationId=:modelId AND type="workflow" AND workflowId=:workflow', array(':type' => get_class($model), ':modelId' => $model->id, ':workflow' => $condition['workflowId'])); case 'started_stage': return CActiveRecord::model('Actions')->exists('associationType=:type AND associationId=:modelId AND type="workflow" AND workflowId=:workflow AND stageNumber=:stage AND (completeDate IS NULL OR completeDate=0)', array(':type' => get_class($model), ':modelId' => $model->id, ':workflow' => $condition['workflowId'], ':stageNumber' => $condition['stageNumber'])); case 'completed_stage': return CActiveRecord::model('Actions')->exists('associationType=:type AND associationId=:modelId AND type="workflow" AND workflowId=:workflow AND stageNumber=:stage AND completeDate > 0', array(':type' => get_class($model), ':modelId' => $model->id, ':workflow' => $condition['workflowId'], ':stageNumber' => $condition['stageNumber'])); case 'completed_workflow': $stageCount = CActiveRecord::model('WorkflowStage')->count('workflowId=:id', array(':id' => $condition['workflowId'])); $actionCount = CActiveRecord::model('Actions')->count('associationType=:type AND associationId=:modelId AND type="workflow" AND workflowId=:workflow', array(':type' => get_class($model), ':modelId' => $model->id, ':workflow' => $condition['workflowId'])); return $actionCount >= $stageCount; } return false; case 'email_open': if (isset($params['sentEmails'], $params['sentEmails'][$value])) { $trackEmail = TrackEmail::model()->findByAttributes(array('uniqueId' => $params['sentEmails'][$value])); return $trackEmail && !is_null($trackEmail->opened); } return false; } return false; // foreach($condition as $key = >$value) { // Record attribute (=, <, >, <>, in list, not in list, empty, not empty, contains) // Linked record attribute (eg. a contact's account has > 30 employees) // Current user // Current time (day of week, hours, etc) // Current time in record's timezone // Is user X logged in // Workflow status (in workflow X, started stage Y, completed Y, completed all) // } }
public function actionList($id = null) { $list = X2List::load($id); if (!isset($list)) { Yii::app()->user->setFlash('error', Yii::t('app', 'The requested page does not exist.')); $this->redirect(array('lists')); } $model = new Contacts('search'); Yii::app()->user->setState('vcr-list', $id); $dataProvider = $model->searchList($id); $list->count = $dataProvider->totalItemCount; $list->runWithoutBehavior('X2FlowTriggerBehavior', function () use($list) { $list->save(); }); X2Flow::trigger('RecordViewTrigger', array('model' => $list)); $this->render('list', array('listModel' => $list, 'dataProvider' => $dataProvider, 'model' => $model)); }
/** * Marks the action incomplete and updates the record. * @return boolean whether or not the action updated successfully */ public function uncomplete() { $this->complete = 'No'; $this->completedBy = null; $this->completeDate = null; $this->disableBehavior('changelog'); if ($result = $this->update()) { X2Flow::trigger('ActionUncompleteTrigger', array('model' => $this, 'user' => Yii::app()->user->getName())); } $this->enableBehavior('changelog'); return $result; }
/** * Displays a particular model. * @param integer $id the ID of the model to be displayed */ public function actionView($id) { $model = CActiveRecord::model('Docs')->findByPk($id); if (!$this->checkPermissions($model, 'view')) { $this->denied(); } if (isset($model)) { $permissions = explode(", ", $model->editPermissions); if (in_array(Yii::app()->user->getName(), $permissions)) { $editFlag = true; } else { $editFlag = false; } } if (!isset($model) || $model->visibility == 0 && $model->createdBy != Yii::app()->user->getName() && !Yii::app()->params->isAdmin && !$editFlag) { $this->redirect(array('/docs/docs/index')); } // add doc to user's recent item list User::addRecentItem('d', $id, Yii::app()->user->getId()); X2Flow::trigger('RecordViewTrigger', array('model' => $model)); $this->render('view', array('model' => $model)); }
public function recordEmailOpen() { if ($this->opened === null) { $openedAction = $this->createEmailOpenedAction(); $event = $this->createEmailOpenedEvent(); if ($openedAction->save() && $event->save()) { $this->opened = time(); $this->update(); $model = X2Model::getAssociationModel($openedAction->associationType, $openedAction->associationId); X2Flow::trigger('EmailOpenTrigger', array('model' => $model)); } } }
private function handleWebleadFormSubmission(X2Model $model, $extractedParams) { $newRecord = $model->isNewRecord; if (isset($_POST['Contacts'])) { $model->createEvent = false; $model->setX2Fields($_POST['Contacts'], true); // Extra sanitizing $p = Fields::getPurifier(); foreach ($model->attributes as $name => $value) { if ($name != $model->primaryKey() && !empty($value)) { $model->{$name} = $p->purify($value); } } $now = time(); $model->visibility = 1; $model->validate(null, false); if (!$model->hasErrors()) { $model->lastUpdated = $now; $model->updatedBy = 'admin'; if ($model->asa('X2DuplicateBehavior') && $model->checkForDuplicates()) { $duplicates = $model->getDuplicates(); $oldest = $duplicates[0]; $fields = $model->getFields(true); foreach ($fields as $field) { if (!in_array($field->fieldName, $model->X2MergeableBehavior->restrictedFields) && !is_null($model->{$field->fieldName})) { if ($field->type === 'text' && !empty($oldest->{$field->fieldName})) { $oldest->{$field->fieldName} .= "\n--\n" . $model->{$field->fieldName}; } else { $oldest->{$field->fieldName} = $model->{$field->fieldName}; } } } $model = $oldest; $newRecord = $model->isNewRecord; } if ($newRecord) { $model->createDate = $now; $model->assignedTo = $this->controller->getNextAssignee(); } $success = $model->save(); //TODO: upload profile picture url from webleadfb if ($success) { if ($extractedParams['generateLead']) { self::generateLead($model, $extractedParams['leadSource']); } if ($extractedParams['generateAccount']) { self::generateAccount($model); } self::addTags($model); $tags = !isset($_POST['tags']) || empty($_POST['tags']) ? array() : explode(',', $_POST['tags']); if ($newRecord) { X2Flow::trigger('WebleadTrigger', array('model' => $model, 'tags' => $tags)); } //use the submitted info to create an action Actions::associateAction($model, array('actionDescription' => Yii::t('contacts', 'Web Lead') . "\n\n" . Yii::t('contacts', 'Name') . ': ' . CHtml::decode($model->firstName) . " " . CHtml::decode($model->lastName) . "\n" . Yii::t('contacts', 'Email') . ": " . CHtml::decode($model->email) . "\n" . Yii::t('contacts', 'Phone') . ": " . CHtml::decode($model->phone) . "\n" . Yii::t('contacts', 'Background Info') . ": " . CHtml::decode($model->backgroundInfo), 'type' => 'note')); // create a notification if the record is assigned to someone $event = new Events(); $event->associationType = 'Contacts'; $event->associationId = $model->id; $event->user = $model->assignedTo; $event->type = 'weblead_create'; $event->save(); if ($model->assignedTo != 'Anyone' && $model->assignedTo != '') { $notif = new Notification(); $notif->user = $model->assignedTo; $notif->createdBy = 'API'; $notif->createDate = time(); $notif->type = 'weblead'; $notif->modelType = 'Contacts'; $notif->modelId = $model->id; $notif->save(); $profile = Profile::model()->findByAttributes(array('username' => $model->assignedTo)); /* send user that's assigned to this weblead an email if the user's email address is set and this weblead has a user email template */ if ($profile !== null && !empty($profile->emailAddress)) { $subject = Yii::t('marketing', 'New Web Lead'); $message = Yii::t('marketing', 'A new web lead has been assigned to you: ') . CHtml::link($model->firstName . ' ' . $model->lastName, array('/contacts/contacts/view', 'id' => $model->id)) . '.'; $address = array('to' => array(array('', $profile->emailAddress))); $emailFrom = Credentials::model()->getDefaultUserAccount(Credentials::$sysUseId['systemNotificationEmail'], 'email'); if ($emailFrom == Credentials::LEGACY_ID) { $emailFrom = array('name' => $profile->fullName, 'address' => $profile->emailAddress); } $status = $this->controller->sendUserEmail($address, $subject, $message, null, $emailFrom); } } } else { $errMsg = 'Error: WebListenerAction.php: model failed to save'; /**/ AuxLib::debugLog($errMsg); Yii::log($errMsg, '', 'application.debug'); } $this->controller->renderPartial('application.components.views.webFormSubmit', array('type' => 'weblead', 'redirectUrl' => $extractedParams['redirectUrl'])); Yii::app()->end(); // success! } } $sanitizedGetParams = self::sanitizeGetParams(); $this->controller->renderPartial('application.components.views.webForm', array_merge(array('type' => 'weblead'), $sanitizedGetParams)); }