/** * Updates a particular model. * If update is successful, the browser will be redirected to the 'view' page. * @param integer $id the ID of the model to be updated */ public function actionUpdate($id) { $model = $this->loadModel($id); $users = User::getNames(); $fields = Fields::model()->findAllByAttributes(array('modelName' => 'Product')); foreach ($fields as $field) { if ($field->type == 'link') { $fieldName = $field->fieldName; $type = ucfirst($field->linkType); if (is_numeric($model->{$fieldName}) && $model->{$fieldName} != 0) { eval("\$lookupModel={$type}::model()->findByPk(" . $model->{$fieldName} . ");"); if (isset($lookupModel)) { $model->{$fieldName} = $lookupModel->name; } } } } if (isset($_POST['Product'])) { $temp = $model->attributes; $model->setX2Fields($_POST['Product']); // generate history $action = new Actions(); $action->associationType = 'product'; $action->associationId = $model->id; $action->associationName = $model->name; $action->assignedTo = Yii::app()->user->getName(); $action->completedBy = Yii::app()->user->getName(); $action->dueDate = time(); $action->completeDate = time(); $action->visibility = 1; $action->complete = 'Yes'; $action->actionDescription = "Update: {$model->name}\n Type: {$model->type}\n Price: {$model->price}\n Currency: {$model->currency}\n Inventory: {$model->inventory}"; $action->save(); parent::update($model, $temp, '0'); } $this->render('update', array('model' => $model, 'users' => $users)); }
/** * Add note to model * @param X2Model $model model to which note should be added * @param string $note */ public static function associateAction(X2Model $model, array $attributes) { $now = time(); $action = new Actions(); $action->setAttributes(array_merge(array('assignedTo' => $model->assignedTo, 'visibility' => '1', 'associationType' => X2Model::getAssociationType(get_class($model)), 'associationId' => $model->id, 'associationName' => $model->name, 'createDate' => $now, 'lastUpdated' => $now, 'completeDate' => $now, 'complete' => 'Yes', 'updatedBy' => 'admin'), $attributes), false); return $action->save(); }
public function execute(&$params) { $model = new Actions(); $model->type = 'note'; $model->complete = 'Yes'; $model->associationId = $params['model']->id; $model->associationType = $params['model']->module; $model->actionDescription = $this->parseOption('comment', $params); $model->assignedTo = $this->parseOption('assignedTo', $params); $model->completedBy = $this->parseOption('assignedTo', $params); if (empty($model->assignedTo) && $params['model']->hasAttribute('assignedTo')) { $model->assignedTo = $params['model']->assignedTo; $model->completedBy = $params['model']->assignedTo; } if ($params['model']->hasAttribute('visibility')) { $model->visibility = $params['model']->visibility; } $model->createDate = time(); $model->completeDate = time(); if ($model->save()) { return array(true, Yii::t('studio', 'View created action: ') . $model->getLink()); } else { $errors = $model->getErrors(); return array(false, array_shift($errors)); } }
public function testMergeActions() { $contact = $this->contact('testAnyone'); $action = new Actions(); $action->actionDescription = "TEST"; $action->visibility = 1; $action->associationType = "contacts"; $action->associationId = $contact->id; $action->save(); $model = new Contacts(); foreach ($contact->attributes as $key => $val) { if ($key != 'id' && $key != 'nameId') { $model->{$key} = $val; } } $model->save(); $this->assertEquals(0, Yii::app()->db->createCommand()->select('COUNT(*)')->from('x2_actions')->where('associationType = "contacts" AND associationId = :id', array(':id' => $model->id))->queryScalar()); $this->assertEquals(1, Yii::app()->db->createCommand()->select('COUNT(*)')->from('x2_actions')->where('associationType = "contacts" AND associationId = :id', array(':id' => $contact->id))->queryScalar()); $mergeData = $model->mergeActions($contact, true); $this->assertEquals(1, Yii::app()->db->createCommand()->select('COUNT(*)')->from('x2_actions')->where('associationType = "contacts" AND associationId = :id', array(':id' => $model->id))->queryScalar()); $this->assertEquals(0, Yii::app()->db->createCommand()->select('COUNT(*)')->from('x2_actions')->where('associationType = "contacts" AND associationId = :id', array(':id' => $contact->id))->queryScalar()); $model->unmergeActions($contact->id, $mergeData); $this->assertEquals(1, Yii::app()->db->createCommand()->select('COUNT(*)')->from('x2_actions')->where('associationType = "contacts" AND associationId = :id', array(':id' => $contact->id))->queryScalar()); $this->assertEquals(0, Yii::app()->db->createCommand()->select('COUNT(*)')->from('x2_actions')->where('associationType = "contacts" AND associationId = :id', array(':id' => $model->id))->queryScalar()); }
/** * Creates a new model. * If creation is successful, the browser will be redirected to the 'view' page. */ public function actionCreate() { $model = new Actions(); // Uncomment the following line if AJAX validation is needed // $this->performAjaxValidation($model); if (isset($_POST['Actions'])) { $model->attributes = $_POST['Actions']; if ($model->save()) { $this->redirect(array('view', 'id' => $model->id)); } } $this->render('create', array('model' => $model)); }
public function execute(&$params) { $options = $this->config['options']; $action = new Actions(); $action->subject = $this->parseOption('subject', $params); $action->dueDate = $this->parseOption('dueDate', $params); $action->actionDescription = $this->parseOption('description', $params); $action->priority = $this->parseOption('priority', $params); $action->visibility = $this->parseOption('visibility', $params); if (isset($params['model'])) { $action->assignedTo = $this->parseOption('assignedTo', $params); } // if(isset($this->config['attributes'])) // $this->setModelAttributes($action,$this->config['attributes'],$params); if ($action->save()) { return array(true, Yii::t('studio', "View created action: ") . $action->getLink()); } else { $errors = $action->getErrors(); return array(false, array_shift($errors)); } // if($this->parseOption('reminder',$params)) { // $notif=new Notification; // $notif->modelType='Actions'; // $notif->createdBy=Yii::app()->user->getName(); // $notif->modelId=$model->id; // if($_POST['notificationUsers']=='me'){ // $notif->user=Yii::app()->user->getName(); // }else{ // $notif->user=$model->assignedTo; // } // $notif->createDate=$model->dueDate-($_POST['notificationTime']*60); // $notif->type='action_reminder'; // $notif->save(); // if($_POST['notificationUsers']=='both' && Yii::app()->user->getName()!=$model->assignedTo){ // $notif2=new Notification; // $notif2->modelType='Actions'; // $notif2->createdBy=Yii::app()->user->getName(); // $notif2->modelId=$model->id; // $notif2->user=Yii::app()->user->getName(); // $notif2->createDate=$model->dueDate-($_POST['notificationTime']*60); // $notif2->type='action_reminder'; // $notif2->save(); // } // } }
public function execute(&$params) { $action = new Actions(); $action->associationType = lcfirst(get_class($params['model'])); $action->associationId = $params['model']->id; $action->subject = $this->parseOption('subject', $params); $action->actionDescription = $this->parseOption('description', $params); if ($params['model']->hasAttribute('assignedTo')) { $action->assignedTo = $params['model']->assignedTo; } if ($params['model']->hasAttribute('priority')) { $action->priority = $params['model']->priority; } if ($params['model']->hasAttribute('visibility')) { $action->visibility = $params['model']->visibility; } if ($action->save()) { return array(true, Yii::t('studio', "View created action: ") . $action->getLink()); } else { return array(false, array_shift($action->getErrors())); } }
public function testQuoteEmailOpen() { $quote = $this->quote('docsTest'); $this->assertNullEmailOpenAction($quote); $quoteInitialActionCount = Yii::app()->db->createCommand()->select('COUNT(*)')->from('x2_actions')->where('associationType = :type AND associationId = :id', array(':type' => $quote->module, ':id' => $quote->id))->queryScalar(); $action = new Actions(); $action->completedBy = 'admin'; $action->createDate = time(); $action->dueDate = time(); $action->subject = 'Test Subject'; $action->completeDate = time(); $action->complete = 'Yes'; $action->actionDescription = 'Test Body'; // These attributes are context-sensitive and subject to change: $action->associationId = $quote->id; $action->associationType = $quote->module; $action->type = 'email'; $action->visibility = 1; $action->assignedTo = 'admin'; $action->save(); $track = new TrackEmail(); $track->actionId = $action->id; $track->uniqueId = md5(uniqid(rand(), true)); $this->assertSaves($track); $this->assertEquals($quoteInitialActionCount + 1, Yii::app()->db->createCommand()->select('COUNT(*)')->from('x2_actions')->where('associationType = :type AND associationId = :id', array(':type' => $quote->module, ':id' => $quote->id))->queryScalar()); $track->recordEmailOpen(); $this->assertEquals($quoteInitialActionCount + 2, Yii::app()->db->createCommand()->select('COUNT(*)')->from('x2_actions')->where('associationType = :type AND associationId = :id', array(':type' => $quote->module, ':id' => $quote->id))->queryScalar()); $this->assertEmailOpenAction($quote); }
/** * Clear out records associated with this quote before deletion. */ public function beforeDelete() { QuoteProduct::model()->deleteAllByAttributes(array('quoteId' => $this->id)); // for old relationships generated with incorrect type name Relationships::model()->deleteAllByAttributes(array('firstType' => 'quotes', 'firstId' => $this->id)); // generate action record for history $contact = $this->contact; if (!empty($contact)) { $action = new Actions(); $action->associationType = 'contacts'; $action->type = 'quotesDeleted'; $action->associationId = $contact->id; $action->associationName = $contact->name; $action->assignedTo = Yii::app()->getSuModel()->username; $action->completedBy = Yii::app()->getSuModel()->username; $action->createDate = time(); $action->dueDate = time(); $action->completeDate = time(); $action->visibility = 1; $action->complete = 'Yes'; $action->actionDescription = "Deleted Quote: <span style=\"font-weight:bold;\">{$this->id}</span> {$this->name}"; // Save after deletion of the model so that this action itself doensn't get deleted $action->save(); } return parent::beforeDelete(); }
/** * Track when an email is viewed, a link is clicked, or the recipient unsubscribes * * Campaign emails include an img tag to a blank image to track when the message was opened, * an unsubscribe link, and converted links to track when a recipient clicks a link. * All those links are handled by this action. * * @param integer $uid The unique id of the recipient * @param string $type 'open', 'click', or 'unsub' * @param string $url For click types, this is the urlencoded URL to redirect to * @param string $email For unsub types, this is the urlencoded email address * of the person unsubscribing */ public function actionClick($uid, $type, $url = null, $email = null) { $now = time(); $item = CActiveRecord::model('X2ListItem')->with('contact', 'list')->findByAttributes(array('uniqueId' => $uid)); // It should never happen that we have a list item without a campaign, // but it WILL happen on any old db where x2_list_items does not cascade on delete // we can't track anything if the listitem was deleted, but at least prevent breaking links if ($item === null || $item->list->campaign === null) { if ($type == 'click') { // campaign redirect link click $this->redirect(urldecode($url)); } elseif ($type == 'open') { //return a one pixel transparent gif header('Content-Type: image/gif'); echo base64_decode('R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='); } elseif ($type == 'unsub' && !empty($email)) { Contacts::model()->updateAll(array('doNotEmail' => true), 'email=:email', array(':email' => $email)); X2ListItem::model()->updateAll(array('unsubscribed' => time()), 'emailAddress=:email AND unsubscribed=0', array('email' => $email)); $message = Yii::t('marketing', 'You have been unsubscribed'); echo '<html><head><title>' . $message . '</title></head><body>' . $message . '</body></html>'; } return; } $contact = $item->contact; $list = $item->list; $event = new Events(); $notif = new Notification(); $action = new Actions(); $action->completeDate = $now; $action->complete = 'Yes'; $action->updatedBy = 'API'; $skipActionEvent = true; if ($contact !== null) { $skipActionEvent = false; if ($email === null) { $email = $contact->email; } $action->associationType = 'contacts'; $action->associationId = $contact->id; $action->associationName = $contact->name; $action->visibility = $contact->visibility; $action->assignedTo = $contact->assignedTo; $event->associationId = $action->associationId; $event->associationType = 'Contacts'; if ($action->assignedTo !== '' && $action->assignedTo !== 'Anyone') { $notif->user = $contact->assignedTo; $notif->modelType = 'Contacts'; $notif->modelId = $contact->id; $notif->createDate = $now; $notif->value = $item->list->campaign->getLink(); } } elseif ($list !== null) { $action = new Actions(); $action->type = 'note'; $action->createDate = $now; $action->lastUpdated = $now; $action->completeDate = $now; $action->complete = 'Yes'; $action->updatedBy = 'admin'; $action->associationType = 'X2List'; $action->associationId = $list->id; $action->associationName = $list->name; $action->visibility = $list->visibility; $action->assignedTo = $list->assignedTo; } if ($type == 'unsub') { $item->unsubscribe(); // find any weblists associated with the email address and create unsubscribe actions // for each of them $sql = 'SELECT t.* FROM x2_lists as t JOIN x2_list_items as li ON t.id=li.listId WHERE li.emailAddress=:email AND t.type="weblist";'; $weblists = Yii::app()->db->createCommand($sql)->queryAll(true, array('email' => $email)); foreach ($weblists as $weblist) { $weblistAction = new Actions(); $weblistAction->disableBehavior('changelog'); //$weblistAction->id = 0; // this causes primary key contraint violation errors $weblistAction->isNewRecord = true; $weblistAction->type = 'email_unsubscribed'; $weblistAction->associationType = 'X2List'; $weblistAction->associationId = $weblist['id']; $weblistAction->associationName = $weblist['name']; $weblistAction->visibility = $weblist['visibility']; $weblistAction->assignedTo = $weblist['assignedTo']; $weblistAction->actionDescription = Yii::t('marketing', 'Campaign') . ': ' . $item->list->campaign->name . "\n\n" . $email . " " . Yii::t('marketing', 'has unsubscribed') . "."; $weblistAction->save(); } $action->type = 'email_unsubscribed'; $notif->type = 'email_unsubscribed'; if ($contact === null) { $action->actionDescription = Yii::t('marketing', 'Campaign') . ': ' . $item->list->campaign->name . "\n\n" . $item->emailAddress . ' ' . Yii::t('marketing', 'has unsubscribed') . "."; } else { $action->actionDescription = Yii::t('marketing', 'Campaign') . ': ' . $item->list->campaign->name . "\n\n" . Yii::t('marketing', 'Contact has unsubscribed') . ".\n" . Yii::t('marketing', '\'Do Not Email\' has been set') . "."; } $message = Yii::t('marketing', 'You have been unsubscribed'); echo '<html><head><title>' . $message . '</title></head><body>' . $message . '</body></html>'; } elseif ($type == 'open') { //return a one pixel transparent gif header('Content-Type: image/gif'); echo base64_decode('R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='); // Check if it has been marked as opened already, or if the contact // no longer exists. If so, exit; nothing more need be done. if ($item->opened != 0) { Yii::app()->end(); } // This needs to happen before the skip option to accomodate the case of newsletters $item->markOpened(); if ($skipActionEvent) { Yii::app()->end(); } $action->disableBehavior('changelog'); $action->type = 'campaignEmailOpened'; $event->type = 'email_opened'; $notif->type = 'email_opened'; $event->save(); if ($contact === null) { $action->actionDescription = Yii::t('marketing', 'Campaign') . ': ' . $item->list->campaign->name . "\n\n" . $item->emailAddress . ' ' . Yii::t('marketing', 'has opened the email') . "."; } else { $action->actionDescription = Yii::t('marketing', 'Campaign') . ': ' . $item->list->campaign->name . "\n\n" . Yii::t('marketing', 'Contact has opened the email') . "."; } } elseif ($type == 'click') { // redirect link click $item->markClicked($url); $action->type = 'email_clicked'; $notif->type = 'email_clicked'; if ($contact === null) { $action->actionDescription = Yii::t('marketing', 'Campaign') . ': ' . $item->list->campaign->name . "\n\n" . Yii::t('marketing', 'Contact has clicked a link') . ":\n" . urldecode($url); } else { $action->actionDescription = Yii::t('marketing', 'Campaign') . ': ' . $item->list->campaign->name . "\n\n" . $item->emailAddress . ' ' . Yii::t('marketing', 'has clicked a link') . ":\n" . urldecode($url); } $this->redirect(urldecode($url)); } $action->save(); // if any of these hasn't been fully configured $notif->save(); // it will simply not validate and not be saved }
/** * Updates a particular model. * If update is successful, the browser will be redirected to the 'view' page. * @param integer $id the ID of the model to be updated */ public function actionUpdate($id) { $model = $this->loadModel($id); $users = User::getNames(); $fields = Fields::model()->findAllByAttributes(array('modelName' => "Products")); foreach ($fields as $field) { if ($field->type == 'link') { $fieldName = $field->fieldName; $type = ucfirst($field->linkType); if (is_numeric($model->{$fieldName}) && $model->{$fieldName} != 0) { eval("\$lookupModel={$type}::model()->findByPk(" . $model->{$fieldName} . ");"); if (isset($lookupModel)) { $model->{$fieldName} = $lookupModel->name; } } } } if (isset($_POST['Product'])) { $temp = $model->attributes; foreach ($_POST['Product'] as $name => $value) { if ($value == $model->getAttributeLabel($name)) { $_POST['Product'][$name] = ''; } } foreach ($_POST as $key => $arr) { $pieces = explode("_", $key); if (isset($pieces[0]) && $pieces[0] == 'autoselect') { $newKey = $pieces[1]; if (isset($_POST[$newKey . "_id"]) && $_POST[$newKey . "_id"] != "") { $val = $_POST[$newKey . "_id"]; } else { $field = Fields::model()->findByAttributes(array('fieldName' => $newKey)); if (isset($field)) { $type = ucfirst($field->linkType); if ($type != "Contacts") { eval("\$lookupModel={$type}::model()->findByAttributes(array('name'=>'{$arr}'));"); } else { $names = explode(" ", $arr); $lookupModel = Contacts::model()->findByAttributes(array('firstName' => $names[0], 'lastName' => $names[1])); } if (isset($lookupModel)) { $val = $lookupModel->id; } else { $val = $arr; } } } $model->{$newKey} = $val; } } foreach (array_keys($model->attributes) as $field) { if (isset($_POST['Product'][$field])) { $model->{$field} = $_POST['Product'][$field]; $fieldData = Fields::model()->findByAttributes(array('modelName' => 'Products', 'fieldName' => $field)); if ($fieldData->type == 'assignment' && $fieldData->linkType == 'multiple') { $model->{$field} = Accounts::parseUsers($model->{$field}); } elseif ($fieldData->type == 'date') { $model->{$field} = strtotime($model->{$field}); } } } // generate history $action = new Actions(); $action->associationType = 'product'; $action->associationId = $model->id; $action->associationName = $model->name; $action->assignedTo = Yii::app()->user->getName(); $action->completedBy = Yii::app()->user->getName(); $action->dueDate = time(); $action->completeDate = time(); $action->visibility = 1; $action->complete = 'Yes'; $action->actionDescription = "Update: <b>{$model->name}</b>\n\t\t\t\tType: <b>{$model->type}</b>\n\t\t\t\tPrice: <b>{$model->price}</b>\n\t\t\t\tCurrency: <b>{$model->currency}</b>\n\t\t\t\tInventory: <b>{$model->inventory}</b>"; $action->save(); parent::update($model, $temp, '0'); } $this->render('update', array('model' => $model, 'users' => $users)); }
public function actionCompleteStage($workflowId, $stageNumber, $modelId, $type, $comment = '') { if (!(is_numeric($workflowId) && is_numeric($stageNumber) && is_numeric($modelId) && ctype_alpha($type))) { return; } $comment = trim($comment); $workflowStatus = Workflow::getWorkflowStatus($workflowId, $modelId, $type); $stageCount = count($workflowStatus) - 1; $stage =& $workflowStatus[$stageNumber]; if (isset($stage['createDate']) && empty($stage['completeDate'])) { $previousCheck = true; if ($workflowStatus[$stageNumber]['requirePrevious'] == 1) { // check if all stages before this one are complete for ($i = 1; $i < $stageNumber; $i++) { if (empty($workflowStatus[$i]['complete'])) { $previousCheck = false; break; } } } else { if ($workflowStatus[$stageNumber]['requirePrevious'] < 0) { // or just check if the specified stage is complete if (empty($workflowStatus[-1 * $workflowStatus[$stageNumber]['requirePrevious']]['complete'])) { $previousCheck = false; } } } // is this stage is OK to complete? if a comment is required, then is $comment empty? if ($previousCheck && (!$stage['requireComment'] || $stage['requireComment'] && !empty($comment))) { // find selected stage (and duplicates) $actionModels = CActiveRecord::model('Actions')->findAllByAttributes(array('associationId' => $modelId, 'associationType' => $type, 'type' => 'workflow', 'workflowId' => $workflowId, 'stageNumber' => $stageNumber), new CDbCriteria(array('order' => 'createDate DESC'))); if (count($actionModels) > 1) { // if there is more than 1 action for this stage, for ($i = 1; $i < count($actionModels); $i++) { // delete all but the most recent one $actionModels[$i]->delete(); } } $actionModels[0]->setScenario('workflow'); $actionModels[0]->completeDate = time(); // set completeDate and save model $actionModels[0]->complete = 'Yes'; $actionModels[0]->completedBy = Yii::app()->user->getName(); // $actionModels[0]->actionDescription = $workflowId.':'.$stageNumber.$comment; $actionModels[0]->actionDescription = $comment; $actionModels[0]->save(); $this->updateWorkflowChangelog($actionModels[0], 'complete'); for ($i = 0; $i <= $stageCount; $i++) { if ($i != $stageNumber && empty($workflowStatus[$i]['completeDate']) && !empty($workflowStatus[$i]['createDate'])) { break; } if (empty($workflowStatus[$i]['createDate'])) { $nextAction = new Actions('workflow'); // start the next one (unless there is already one) $nextAction->associationId = $modelId; $nextAction->associationType = $type; $nextAction->assignedTo = Yii::app()->user->getName(); $nextAction->type = 'workflow'; $nextAction->complete = 'No'; $nextAction->visibility = 1; $nextAction->createDate = time(); $nextAction->workflowId = $workflowId; $nextAction->stageNumber = $i; // $nextAction->actionDescription = $comment; $nextAction->save(); $this->updateWorkflowChangelog($nextAction, 'start'); // $changes=$this->calculateChanges($oldAttributes, $model->attributes, $model); // $this->updateChangelog($model,$changes); break; } } // if($stageNumber < $stageCount && empty($workflowStatus[$stageNumber+1]['createDate'])) { // if this isn't the final stage, // } $workflowStatus = Workflow::getWorkflowStatus($workflowId, $modelId, $type); // refresh the workflow status } } echo Workflow::renderWorkflow($workflowStatus); }
public function testMigration() { $model = $this->contacts('contact935'); $workflowActions = Actions::model()->findAllByAttributes(array('associationType' => 'contacts', 'associationId' => $model->id, 'type' => 'workflow')); $this->assertEquals(4, count($workflowActions)); $stage1 = $this->workflowStages('stage1'); $stage1Action = Actions::model()->findByAttributes(array('associationType' => 'contacts', 'associationId' => $model->id, 'type' => 'workflow', 'workflowId' => 2, 'stageNumber' => 1)); $this->assertInstanceOf('Actions', $stage1Action); $this->assertEquals($stage1->workflowId, $stage1Action->workflowId); $this->assertEquals($stage1->stageNumber, $stage1Action->stageNumber); //Confirm that saving an action with non-existent stageNumber is okay $badAction = new Actions(); $badAction->type = 'workflow'; $badAction->workflowId = 2; $badAction->stageNumber = -1; $badAction->associationType = 'contacts'; $badAction->associationId = $model->id; $this->assertSaves($badAction); //Confirm that saving an action with non-existent workflowId is okay $badAction->stageNumber = 1; $badAction->workflowId = -1; $this->assertSaves($badAction); //Confirm that saving an action with non-existent workflowId and stageNumber is okay $badAction->stageNumber = -1; $this->assertSaves($badAction); //Confirm that saving duplicate workflow stages is okay $badAction2 = new Actions(); $badAction2->type = 'workflow'; $badAction2->workflowId = -1; $badAction2->stageNumber = -1; $badAction2->associationType = 'contacts'; $badAction2->associationId = $model->id; $this->assertSaves($badAction2); //Non-duplicate action to confirm deletion of actions with bad workflowId $badAction3 = new Actions(); $badAction3->type = 'workflow'; $badAction3->workflowId = -99; $badAction3->stageNumber = 1; $badAction3->associationType = 'contacts'; $badAction3->associationId = $model->id; $this->assertSaves($badAction3); //Non-duplicate action to confirm deletion of actions with bad stageNumber $badAction4 = new Actions(); $badAction4->type = 'workflow'; $badAction4->workflowId = 2; $badAction4->stageNumber = -99; $badAction4->associationType = 'contacts'; $badAction4->associationId = $model->id; $this->assertSaves($badAction4); $workflowActions = Actions::model()->findAllByAttributes(array('associationType' => 'contacts', 'associationId' => $model->id, 'type' => 'workflow')); $this->assertEquals(8, count($workflowActions)); $this->runMigrationScript(); $workflowActions = Actions::model()->findAllByAttributes(array('associationType' => 'contacts', 'associationId' => $model->id, 'type' => 'workflow')); $this->assertEquals(4, count($workflowActions)); $this->assertNull(Actions::model()->findByPk($badAction->id)); $this->assertNull(Actions::model()->findByPk($badAction2->id)); $this->assertNull(Actions::model()->findByPk($badAction3->id)); $this->assertNull(Actions::model()->findByPk($badAction4->id)); $stage1ActionPostMigrate = Actions::model()->findByPK($stage1Action->id); $this->assertEquals($stage1->workflowId, $stage1ActionPostMigrate->workflowId); $this->assertEquals($stage1->id, $stage1ActionPostMigrate->stageNumber); //Fails new foreign key constraint $badAction5 = new Actions(); $badAction5->type = 'workflow'; $badAction5->workflowId = 2; $badAction5->stageNumber = -1; $badAction5->associationType = 'contacts'; $badAction5->associationId = $model->id; try { $badAction5->save(); $this->assertFalse(true); } catch (CDbException $e) { $this->assertTrue(true); } //Fails new unique constraint $badAction6 = new Actions(); $badAction6->type = 'workflow'; $badAction6->workflowId = 2; $badAction6->stageNumber = 5; $badAction6->associationType = 'contacts'; $badAction6->associationId = $model->id; try { $badAction6->save(); $this->assertFalse(true); } catch (CDbException $e) { $this->assertTrue(true); } }
public function run() { $preview = false; $emailBody = ''; $signature = ''; $template = null; if (!isset($this->model)) { $this->model = new InlineEmail(); } if (isset($_POST['InlineEmail'])) { if (isset($_GET['preview']) || isset($_POST['InlineEmail']['submit']) && $_POST['InlineEmail']['submit'] == Yii::t('app', 'Preview')) { $preview = true; } $this->model->attributes = $_POST['InlineEmail']; // if the user specified a template, look it up and use it for the message if ($this->model->template != 0) { $matches = array(); if (preg_match('/<!--BeginSig-->(.*)<!--EndSig-->/u', $this->model->message, $matches) && count($matches) > 1) { // extract signature $signature = $matches[1]; } $this->model->message = preg_replace('/<!--BeginSig-->(.*)<!--EndSig-->/u', '', $this->model->message); // remove signatures $matches = array(); if (preg_match('/<!--BeginMsg-->(.*)<!--EndMsg-->/u', $this->model->message, $matches) && count($matches) > 1) { $this->model->message = $matches[1]; } if (empty($signature)) { $signature = Yii::app()->params->profile->getSignature(true); } // load default signature if empty $template = CActiveRecord::model('Docs')->findByPk($this->model->template); if (isset($template)) { $this->model->message = str_replace('\\\\', '\\\\\\', $this->model->message); $this->model->message = str_replace('$', '\\$', $this->model->message); $emailBody = preg_replace('/{content}/u', '<!--BeginMsg-->' . $this->model->message . '<!--EndMsg-->', $template->text); $emailBody = preg_replace('/{signature}/u', '<!--BeginSig-->' . $signature . '<!--EndSig-->', $emailBody); // check if subject is empty, or is from another template if (empty($this->model->subject) || CActiveRecord::model('Docs')->countByAttributes(array('type' => 'email', 'title' => $this->model->subject))) { $this->model->subject = $template->title; } if (isset($this->model->modelName, $this->model->modelId)) { // if there is a model name/id available, look it up and use its attributes $targetModel = CActiveRecord::model($this->model->modelName)->findByPk($this->model->modelId); if (isset($targetModel)) { $attributes = $targetModel->getAttributes(); $attributeNames = array_keys($attributes); $attributeNames[] = 'content'; $attributes = array_values($attributes); $attributes[] = $this->model->message; foreach ($attributeNames as &$name) { $name = '/{' . $name . '}/'; } unset($name); $emailBody = preg_replace($attributeNames, $attributes, $emailBody); } } // $this->model->template = 0; $this->model->message = $emailBody; } } elseif (!empty($this->model->message)) { // if no template, use the user's custom message, and include a signature $emailBody = $this->model->message; // } elseif(!empty($this->model->message)) { // if no template, use the user's custom message, and include a signature // $emailBody = $this->model->message.'<br><br>'.Yii::app()->params->profile->getSignature(true); } if ($this->model->template == 0) { $this->model->setScenario('custom'); } if ($this->model->validate() && !$preview) { $this->model->status = $this->controller->sendUserEmail($this->model->mailingList, $this->model->subject, $emailBody); if (in_array('200', $this->model->status)) { foreach ($this->model->mailingList['to'] as &$target) { $contact = Contacts::model()->findByAttributes(array('email' => $target[1])); if (isset($contact)) { $action = new Actions(); $action->associationType = 'contacts'; $action->associationId = $contact->id; $action->associationName = $contact->name; $action->visibility = $contact->visibility; $action->complete = 'Yes'; $action->type = 'email'; $action->completedBy = Yii::app()->user->getName(); $action->assignedTo = $contact->assignedTo; $action->createDate = time(); $action->dueDate = time(); $action->completeDate = time(); if ($template == null) { $action->actionDescription = '<b>' . $this->model->subject . "</b>\n\n" . $this->model->message; } else { $action->actionDescription = CHtml::link($template->title, array('/docs/' . $template->id)); } if ($action->save()) { } // $message="2"; // $email=$toEmail; // $id=$contact['id']; // $note.="\n\nSent to Contact"; } } } } } echo $this->controller->renderPartial('application.components.views.inlineEmailForm', array('model' => $this->model, 'preview' => $preview ? $emailBody : null)); // } }
private function createAttachmentAction($model) { if (!empty($model->associationType) && !empty($model->associationId) && is_numeric($model->associationId)) { $note = new Actions(); $note->createDate = time(); $note->dueDate = time(); $note->completeDate = time(); $note->complete = 'Yes'; $note->visibility = '1'; $note->completedBy = Yii::app()->user->getName(); if ($model->private) { $note->assignedTo = Yii::app()->user->getName(); $note->visibility = '0'; } else { $note->assignedTo = 'Anyone'; } $note->type = 'attachment'; $note->associationId = $model->associationId; $note->associationType = $model->associationType; if ($modelName = X2Model::getModelName($model->associationType)) { $association = X2Model::model($modelName)->findByPk($model->associationId); if ($association != null) { $note->associationName = $association->name; } } $note->actionDescription = $model->fileName . ':' . $model->id; return $note->save(); } return false; }
/** * Looks up notification criteria in x2_criteria relevant to this model * and field and performs the specified operation. * Soon to be eliminated in wake of x2flow automation system. * * @param string $fieldName the name of the current field * @param string $old the old value * @param string $new the new value */ public function checkNotificationCriteria($fieldName, $old, $new) { $model = $this->getOwner(); $modelClass = get_class($model); $allCriteria = Criteria::model()->findAllByAttributes(array('modelType' => $modelClass, 'modelField' => $fieldName)); foreach ($allCriteria as $criteria) { if ($criteria->comparisonOperator == "=" && $new == $criteria->modelValue || $criteria->comparisonOperator == ">" && $new >= $criteria->modelValue || $criteria->comparisonOperator == "<" && $new <= $criteria->modelValue || $criteria->comparisonOperator == "change" && $new != $old) { $users = preg_split('/[\\s,]+/', $criteria->users, null, PREG_SPLIT_NO_EMPTY); if ($criteria->type == 'notification') { foreach ($users as $user) { $event = new Events(); $event->user = $user; $event->associationType = 'Notification'; $event->type = 'notif'; $notif = new Notification(); $notif->type = 'change'; $notif->fieldName = $fieldName; $notif->modelType = get_class($model); $notif->modelId = $model->id; if ($criteria->comparisonOperator == 'change') { $notif->comparison = 'change'; // if the criteria is just 'changed' $notif->value = $new; // record the new value } else { $notif->comparison = $criteria->comparisonOperator; // otherwise record the operator type $notif->value = mb_substr($criteria->modelValue, 0, 250, 'UTF-8'); // and the comparison value } $notif->user = $user; $notif->createdBy = $this->editingUsername; $notif->createDate = time(); if ($notif->save()) { $event->associationId = $notif->id; $event->save(); } } } elseif ($criteria->type == 'action') { foreach ($users as $user) { $action = new Actions(); $action->assignedTo = $user; if ($criteria->comparisonOperator == "=") { $action->actionDescription = "A record of type " . $modelClass . " has been modified to meet {$criteria->modelField} {$criteria->comparisonOperator} {$criteria->modelValue}" . " by " . $this->editingUsername; } else { if ($criteria->comparisonOperator == ">") { $action->actionDescription = "A record of type " . $modelClass . " has been modified to meet {$criteria->modelField} {$criteria->comparisonOperator} {$criteria->modelValue}" . " by " . $this->editingUsername; } else { if ($criteria->comparisonOperator == "<") { $action->actionDescription = "A record of type " . $modelClass . " has been modified to meet {$criteria->modelField} {$criteria->comparisonOperator} {$criteria->modelValue}" . " by " . $this->editingUsername; } else { if ($criteria->comparisonOperator == "change") { $action->actionDescription = "A record of type " . $modelClass . " has had its {$criteria->modelField} field changed from " . $old . ' to ' . $new . ' by ' . $this->editingUsername; } } } } $action->dueDate = mktime('23', '59', '59'); $action->createDate = time(); $action->lastUpdated = time(); $action->updatedBy = 'admin'; $action->visibility = 1; $action->associationType = lcfirst($modelClass); $action->associationId = $model->id; $action->associationName = $model->name; $action->save(); } } elseif ($criteria->type == 'assignment') { $model->assignedTo = $criteria->users; if ($model->save()) { $event = new Events(); $event->type = 'notif'; $event->user = $model->assignedTo; $event->associationType = 'Notification'; $notif = new Notification(); $notif->user = $model->assignedTo; $notif->createDate = time(); $notif->type = 'assignment'; $notif->modelType = $modelClass; $notif->modelId = $model->id; if ($notif->save()) { $event->associationId = $notif->id; if ($this->createEvent) { $event->save(); } } } } } } }
private function handleServiceFormSubmission($model, $extractedParams) { if (isset($_POST['Services'])) { // web form submitted if (isset($_POST['Services']['firstName'])) { $firstName = $_POST['Services']['firstName']; $fullName = $firstName; } if (isset($_POST['Services']['lastName'])) { $lastName = $_POST['Services']['lastName']; if (isset($fullName)) { $fullName .= ' ' . $lastName; } else { $fullName = $lastName; } } if (isset($_POST['Services']['email'])) { $email = $_POST['Services']['email']; } if (isset($_POST['Services']['phone'])) { $phone = $_POST['Services']['phone']; } if (isset($_POST['Services']['desription'])) { $description = $_POST['Services']['description']; } // Extra sanitizing $p = Fields::getPurifier(); foreach ($model->attributes as $name => $value) { if ($name != $model->primaryKey() && !empty($value)) { $model->{$name} = $p->purify($value); } } if (isset($email) && $email) { $contact = Contacts::model()->findByAttributes(array('email' => $email)); } else { $contact = false; } if ($contact) { $model->contactId = $contact->nameId; } else { $model->contactId = "Unregistered"; } if (isset($fullName) || isset($email)) { $model->subject = Yii::t('services', 'Web Form Case entered by {name}', array('{name}' => isset($fullName) ? $fullName : $email)); } else { $model->subject = Yii::t('services', 'Web Form Case'); } $model->origin = 'Web'; if (!isset($model->impact) || $model->impact == '') { $model->impact = Yii::t('services', '3 - Moderate'); } if (!isset($model->status) || $model->status == '') { $model->status = Yii::t('services', 'New'); } if (!isset($model->mainIssue) || $model->mainIssue == '') { $model->mainIssue = Yii::t('services', 'General Request'); } if (!isset($model->subIssue) || $model->subIssue == '') { $model->subIssue = Yii::t('services', 'Other'); } $model->assignedTo = $this->controller->getNextAssignee(); if (isset($email)) { $model->email = CHtml::encode($email); } $now = time(); $model->createDate = $now; $model->lastUpdated = $now; $model->updatedBy = 'admin'; if (isset($description)) { $model->description = CHtml::encode($description); } if (!$model->hasErrors()) { if ($model->save()) { $model->name = $model->id; $model->update(array('name')); self::addTags($model); //use the submitted info to create an action $action = new Actions(); $action->actionDescription = Yii::t('contacts', 'Web Form') . "\n\n" . (isset($fullName) ? Yii::t('contacts', 'Name') . ': ' . $fullName . "\n" : '') . (isset($email) ? Yii::t('contacts', 'Email') . ": " . $email . "\n" : '') . (isset($phone) ? Yii::t('contacts', 'Phone') . ": " . $phone . "\n" : '') . (isset($description) ? Yii::t('services', 'Description') . ": " . $description : ''); // create action $action->type = 'note'; $action->assignedTo = $model->assignedTo; $action->visibility = '1'; $action->associationType = 'services'; $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(); if (isset($email)) { //send email $emailBody = Yii::t('services', 'Hello') . ' ' . $fullName . ",<br><br>"; $emailBody .= Yii::t('services', 'Thank you for contacting our Technical Support ' . 'team. This is to verify we have received your request for Case# ' . '{casenumber}. One of our Technical Analysts will contact you shortly.', array('{casenumber}' => $model->id)); $emailBody = Yii::app()->settings->serviceCaseEmailMessage; if (isset($firstName)) { $emailBody = preg_replace('/{first}/u', $firstName, $emailBody); } if (isset($lastName)) { $emailBody = preg_replace('/{last}/u', $lastName, $emailBody); } if (isset($phone)) { $emailBody = preg_replace('/{phone}/u', $phone, $emailBody); } if (isset($email)) { $emailBody = preg_replace('/{email}/u', $email, $emailBody); } if (isset($description)) { $emailBody = preg_replace('/{description}/u', $description, $emailBody); } $emailBody = preg_replace('/{case}/u', $model->id, $emailBody); $emailBody = preg_replace('/\\n|\\r\\n/', "<br>", $emailBody); $uniqueId = md5(uniqid(rand(), true)); $emailBody .= '<img src="' . $this->controller->createAbsoluteUrl('/actions/actions/emailOpened', array('uid' => $uniqueId, 'type' => 'open')) . '"/>'; $emailSubject = Yii::app()->settings->serviceCaseEmailSubject; if (isset($firstName)) { $emailSubject = preg_replace('/{first}/u', $firstName, $emailSubject); } if (isset($lastName)) { $emailSubject = preg_replace('/{last}/u', $lastName, $emailSubject); } if (isset($phone)) { $emailSubject = preg_replace('/{phone}/u', $phone, $emailSubject); } if (isset($email)) { $emailSubject = preg_replace('/{email}/u', $email, $emailSubject); } if (isset($description)) { $emailSubject = preg_replace('/{description}/u', $description, $emailSubject); } $emailSubject = preg_replace('/{case}/u', $model->id, $emailSubject); if (Yii::app()->settings->serviceCaseEmailAccount != Credentials::LEGACY_ID) { $from = (int) Yii::app()->settings->serviceCaseEmailAccount; } else { $from = array('name' => Yii::app()->settings->serviceCaseFromEmailName, 'address' => Yii::app()->settings->serviceCaseFromEmailAddress); } $useremail = array('to' => array(array(isset($fullName) ? $fullName : '', $email))); $status = $this->controller->sendUserEmail($useremail, $emailSubject, $emailBody, null, $from); if ($status['code'] == 200) { if ($model->assignedTo != 'Anyone') { $profile = X2Model::model('Profile')->findByAttributes(array('username' => $model->assignedTo)); if (isset($profile)) { $useremail['to'] = array(array($profile->fullName, $profile->emailAddress)); $emailSubject = 'Service Case Created'; $emailBody = "A new service case, #" . $model->id . ", has been created in X2Engine. To view the case, click " . "this link: " . $model->getLink(); $status = $this->controller->sendUserEmail($useremail, $emailSubject, $emailBody, null, $from); } } //email action $action = new Actions(); $action->associationType = 'services'; $action->associationId = $model->id; $action->associationName = $model->name; $action->visibility = 1; $action->complete = 'Yes'; $action->type = 'email'; $action->completedBy = 'admin'; $action->assignedTo = $model->assignedTo; $action->createDate = time(); $action->dueDate = time(); $action->completeDate = time(); $action->actionDescription = '<b>' . $model->subject . "</b>\n\n" . $emailBody; if ($action->save()) { $track = new TrackEmail(); $track->actionId = $action->id; $track->uniqueId = $uniqueId; $track->save(); } } else { $errMsg = 'Error: actionWebForm.php: sendUserEmail failed'; /**/ AuxLib::debugLog($errMsg); Yii::log($errMsg, '', 'application.debug'); } } $this->controller->renderPartial('application.components.views.webFormSubmit', array('type' => 'service', 'caseNumber' => $model->id)); Yii::app()->end(); // success! } } } $sanitizedGetParams = self::sanitizeGetParams(); $this->controller->renderPartial('application.components.views.webForm', array_merge(array('model' => $model, 'type' => 'service'), $sanitizedGetParams)); }
/** * Called when a Contact opens an email sent from Inline Email Form. Inline Email Form * appends an image to the email with src pointing to this function. This function * creates an action associated with the Contact indicating that the email was opened. * * @param integer $uid The unique id of the recipient * @param string $type 'open', 'click', or 'unsub' * */ public function actionEmailOpened($uid, $type) { // If the request is coming from within the web application, ignore it. $referrer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; $baseUrl = Yii::app()->request->getBaseUrl(true); $fromApp = strpos($referrer, $baseUrl) === 0; if ($type == 'open' && !$fromApp) { $track = TrackEmail::model()->findByAttributes(array('uniqueId' => $uid)); if ($track && $track->opened == null) { $action = $track->action; if ($action) { $note = new Actions(); switch ($action->type) { case 'email_quote': case 'email_invoice': $subType = str_replace('email_', '', $action->type); $note->type = "emailOpened_{$subType}"; $quote = Quote::model()->findByPk($action->associationId); if ($quote instanceof Quote) { $contact = $quote->associatedContactsModel; if ($contact instanceof Contacts) { $note->associationType = 'contacts'; $note->associationId = $contact->id; } } break; default: $note->type = 'emailOpened'; $note->associationType = $action->associationType; $note->associationId = $action->associationId; } $now = time(); $note->createDate = $now; $note->lastUpdated = $now; $note->completeDate = $now; $note->complete = 'Yes'; $note->updatedBy = 'admin'; $note->associationName = $action->associationName; $note->visibility = $action->visibility; $note->assignedTo = $action->assignedTo; $note->actionDescription = Yii::t('marketing', 'Contact has opened the email sent on '); $note->actionDescription .= Formatter::formatLongDateTime($action->createDate) . "<br>"; $note->actionDescription .= $action->actionDescription; if ($note->save()) { $event = new Events(); $event->type = 'email_opened'; switch ($action->type) { case 'email_quote': $event->subtype = 'quote'; break; case 'email_invoice': $event->subtype = 'invoice'; break; default: $event->subtype = 'email'; } $contact = isset($quote) && $quote instanceof Quote ? $quote->associatedContactsModel : X2Model::model('Contacts')->findByPk($action->associationId); if (isset($contact)) { $event->user = $contact->assignedTo; } $event->associationType = 'Contacts'; $event->associationId = isset($contact) ? $contact->id : $note->associationId; if ($action->associationType == 'services') { $case = X2Model::model('Services')->findByPk($action->associationId); if (isset($case) && is_numeric($case->contactId)) { $event->associationId = $case->contactId; } elseif (isset($case)) { $event->associationType = 'Services'; $event->associationId = $case->id; } } $event->save(); $track->opened = $now; $track->update(); } } } } //return a one pixel transparent png header('Content-Type: image/png'); echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAAXNSR0IArs4c6QAAAAJiS0dEAP+Hj8y/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAC0lEQVQI12NgYAAAAAMAASDVlMcAAAAASUVORK5CYII='); }
/** * Records a phone call as a notification. * * Given a phone number, if a contact matching that phone number exists, a * notification assigned to that contact's assignee will be created. * Software-based telephony systems such as Asterisk can thus immediately * notify sales reps of a phone call by making a cURL request to a url * formatted as follows: * * api/voip/data/[phone number] * * (Note: the phone number itself must not contain anything but digits, i.e. * no periods or dashes.) * * For Asterisk, one possible integration method is to insert into the * dialplan, at the appropriate position, a call to a script that uses * {@link http://phpagi.sourceforge.net/ PHPAGI} to extract the phone * number. The script can then make the necessary request to this action. * @param bool $actionHist If set to 1, create an action history item for the contact. */ public function actionVoip($actionHist = 0) { if (isset($_GET['data'])) { $matches = array(); if (preg_match('/\\d{10,}/', $_GET['data'], $matches)) { $number = ltrim($matches[0], '1'); $phoneCrit = new CDbCriteria(array('condition' => "modelType='Contacts' AND number LIKE :number", 'params' => array(':number' => "%{$number}%"))); $phoneCrit->join = 'join x2_contacts on modelId=x2_contacts.id AND ' . Contacts::model()->getHiddenCondition('x2_contacts'); $phoneNumber = PhoneNumber::model()->find($phoneCrit); if (!empty($phoneNumber)) { $contact = X2Model::model('Contacts')->findByPk($phoneNumber->modelId); if (isset($contact)) { $contact->disableBehavior('changelog'); $contact->updateLastActivity(); $assignees = array($contact->assignedTo); if ($contact->assignedTo == 'Anyone' || $contact->assignedTo == null) { $users = User::model()->findAll(); $assignees = array_map(function ($u) { return $u->username; }, $users); } $multiUser = count($assignees) > 1; $usersSuccess = array(); $usersFailure = array(); // Format the phone number: $formattedNumber = ''; $strNumber = (string) $number; $strl = strlen($strNumber); $formattedNumber = substr($strNumber, $strl - 4, $strl); $formattedNumber = substr($strNumber, $strl - 7, 3) . "-{$formattedNumber}"; if ($strl >= 10) { $formattedNumber = substr($strNumber, $strl - 10, 3) . "-{$formattedNumber}"; if ($strl > 10) { $formattedNumber = substr($strNumber, 0, $strl - 10) . "-{$formattedNumber}"; } } $time = time(); // Create notifications: foreach ($assignees as $user) { $notif = new Notification(); $notif->type = 'voip_call'; $notif->user = $user; $notif->modelType = 'Contacts'; $notif->modelId = $contact->id; $notif->value = $formattedNumber; $notif->createDate = $time; if ($notif->save()) { $usersSuccess[] = $user; } else { $usersFailure = array(); } } if ($actionHist) { // Create an action: $action = new Actions(); $action->assignedTo = 'Anyone'; $action->visibility = 1; $action->associationId = $contact->id; $action->associationType = 'contacts'; $action->associationName = $contact->name; $action->dueDate = $time; $action->createDate = $time; $action->completeDate = $time; $action->lastUpdated = $time; $action->type = 'call'; $action->complete = 'Yes'; $action->completedBy = 'Anyone'; $action->save(); $action->actionText = Yii::t('app', 'Phone system reported inbound call from contact.'); } $failure = count($usersSuccess) == 0; $partialFailure = count($usersFailure) > 0; if ($failure) { $message = 'Saving notifications failed.'; } else { /*X2Flow::trigger('RecordVoipInboundTrigger', array( 'model' => $contact, 'number' => $matches[0] ));*/ $message = 'Notifications created for user(s): ' . implode(',', $usersSuccess); if ($partialFailure) { $message .= '; saving notifications failed for users(s): ' . implode(',', $usersFailure); } } // Create an event record for the feed: $event = new Events(); $event->type = 'voip_call'; $event->associationType = get_class($contact); $event->associationId = $contact->id; $event->save(); $this->_sendResponse($failure ? 500 : 200, $message); } else { $this->_sendResponse(404, 'Phone number record refers to a contact that no longer exists.'); } } else { $this->_sendResponse(404, 'No matching phone number found.'); // $notif = new Notification; // $notif->type = 'voip_call'; // $notif->user = ?; // $notif->modelType = 'Contacts'; // $notif->value = $matches[0]; // $notif->createDate = time(); // $notif->save(); } } else { $this->_sendResponse(400, 'Invalid phone number format.'); } } else { $this->_sendResponse(400, 'Phone number required as "data" URL parameter.'); } }
/** * Upload contact profile picture from Facebook. */ public function actionUploadProfilePicture() { if (isset($_POST['photourl'])) { $photourl = $_POST['photourl']; $name = 'profile_picture_' . $_POST['associationId'] . '.jpg'; $model = new Media(); $check = Media::model()->findAllByAttributes(array('fileName' => $name)); if (count($check) != 0) { $count = 1; $newName = $name; $arr = explode('.', $name); $name = $arr[0]; while (count($check) != 0) { $newName = $name . '(' . $count . ').jpg'; $check = Media::model()->findAllByAttributes(array('fileName' => $newName)); $count++; } $name = $newName; } $model->associationId = $_POST['associationId']; $model->associationType = $_POST['type']; $model->createDate = time(); $model->fileName = $name; // download and save picture $img = FileUtil::ccopy($photourl, "uploads/{$name}"); $model->save(); // put picture into new action $note = new Actions(); $note->createDate = time(); $note->dueDate = time(); $note->completeDate = time(); $note->complete = 'Yes'; $note->visibility = '1'; $note->completedBy = "Web Lead"; $note->assignedTo = 'Anyone'; $note->type = 'attachment'; $note->associationId = $_POST['associationId']; $note->associationType = $_POST['type']; $association = $this->getAssociation($note->associationType, $note->associationId); if ($association != null) { $note->associationName = $association->name; } $note->actionDescription = $model->fileName . ':' . $model->id; if ($note->save()) { } else { unlink('uploads/' . $name); } $this->redirect(array($model->associationType . '/' . $model->associationId)); } }
protected function calculateChanges($old, $new, &$model = null) { $arr = array(); $keys = array_keys($new); for ($i = 0; $i < count($keys); $i++) { if ($old[$keys[$i]] != $new[$keys[$i]]) { $arr[$keys[$i]] = $new[$keys[$i]]; $allCriteria = Criteria::model()->findAllByAttributes(array('modelType' => $this->modelClass, 'modelField' => $keys[$i])); foreach ($allCriteria as $criteria) { if ($criteria->comparisonOperator == "=" && $new[$keys[$i]] == $criteria->modelValue || $criteria->comparisonOperator == ">" && $new[$keys[$i]] >= $criteria->modelValue || $criteria->comparisonOperator == "<" && $new[$keys[$i]] <= $criteria->modelValue || $criteria->comparisonOperator == "change" && $new[$keys[$i]] != $old[$keys[$i]]) { if ($criteria->type == 'notification') { $pieces = explode(", ", $criteria->users); foreach ($pieces as $piece) { $notif = new Notifications(); $profile = CActiveRecord::model('ProfileChild')->findByAttributes(array('username' => Yii::app()->user->getName())); if ($criteria->comparisonOperator == "=") { $notif->text = "A record of type " . $this->modelClass . " has been modified to meet {$criteria->modelField} {$criteria->comparisonOperator} {$criteria->modelValue}" . " by " . Yii::app()->user->getName(); } else { if ($criteria->comparisonOperator == ">") { $notif->text = "A record of type " . $this->modelClass . " has been modified to meet {$criteria->modelField} {$criteria->comparisonOperator} {$criteria->modelValue}" . " by " . Yii::app()->user->getName(); } else { if ($criteria->comparisonOperator == "<") { $notif->text = "A record of type " . $this->modelClass . " has been modified to meet {$criteria->modelField} {$criteria->comparisonOperator} {$criteria->modelValue}" . " by " . Yii::app()->user->getName(); } else { if ($criteria->comparisonOperator == "change") { $notif->text = "A record of type " . $this->modelClass . " has had its {$criteria->modelField} field changed from " . $old[$keys[$i]] . " to " . $new[$keys[$i]] . " by " . Yii::app()->user->getName(); } } } } $notif->user = $piece; $notif->createDate = time(); $notif->viewed = 0; $notif->record = $this->modelClass . ":" . $new['id']; $notif->save(); } } else { if ($criteria->type == 'action') { $pieces = explode(", ", $criteria->users); foreach ($pieces as $piece) { $action = new Actions(); $action->assignedTo = $piece; if ($criteria->comparisonOperator == "=") { $action->actionDescription = "A record of type " . $this->modelClass . " has been modified to meet {$criteria->modelField} {$criteria->comparisonOperator} {$criteria->modelValue}" . " by " . Yii::app()->user->getName(); } else { if ($criteria->comparisonOperator == ">") { $action->actionDescription = "A record of type " . $this->modelClass . " has been modified to meet {$criteria->modelField} {$criteria->comparisonOperator} {$criteria->modelValue}" . " by " . Yii::app()->user->getName(); } else { if ($criteria->comparisonOperator == "<") { $action->actionDescription = "A record of type " . $this->modelClass . " has been modified to meet {$criteria->modelField} {$criteria->comparisonOperator} {$criteria->modelValue}" . " by " . Yii::app()->user->getName(); } else { if ($criteria->comparisonOperator == "change") { $action->actionDescription = "A record of type " . $this->modelClass . " has had its {$criteria->modelField} field changed from " . $old[$keys[$i]] . " to " . $new[$keys[$i]] . " by " . Yii::app()->user->getName(); } } } } $action->dueDate = mktime('23', '59', '59'); $action->createDate = time(); $action->lastUpdated = time(); $action->updatedBy = 'admin'; $action->visibility = 1; $action->associationType = strtolower($this->modelClass); $action->associationId = $new['id']; $model = CActiveRecord::model($this->modelClass)->findByPk($new['id']); $action->associationName = $model->name; $action->save(); } } else { if ($criteria->type == 'assignment') { $model->assignedTo = $criteria->users; $model->save(); $notif = new Notifications(); $notif->text = "A record of type " . $this->modelClass . " has been re-assigned to you."; $notif->user = $model->assignedTo; $notif->createDate = time(); $notif->viewed = 0; $notif->record = $this->modelClass . ":" . $new['id']; $notif->save(); } } } } } } } $str = ''; foreach ($arr as $key => $item) { $str .= "<b>{$key}</b> <u>FROM:</u> {$old[$key]} <u>TO:</u> {$item} <br />"; } return $str; }
/** * Make records of the email in every shape and form. * * This method is to be called only once the email has been sent. * * The basic principle behind what all is happening here: emails are getting * sent to people. Since the "To:" field in the inline email form is not * read-only, the emails could be sent to completely different people. Thus, * creating action and event records must be based exclusively on who the * email is addressed to and not the model from whose view the inline email * form (if that's how this model is being used) is submitted. */ public function recordEmailSent($makeEvent = true) { // The email record, with action header for display purposes: $emailRecordBody = $this->insertInBody(self::insertedPattern('ah', $this->actionHeader), 1, 1); $now = time(); $recipientContacts = array_filter($this->recipientContacts); if (!empty($this->targetModel)) { $model = $this->targetModel; if ((bool) $model) { if ($model->hasAttribute('lastActivity')) { $model->lastActivity = $now; $model->save(); } } $action = new Actions(); // These attributes will be the same regardless of the type of // email being sent: $action->completedBy = $this->userProfile->username; $action->createDate = $now; $action->dueDate = $now; $action->subject = $this->subject; $action->completeDate = $now; $action->complete = 'Yes'; $action->actionDescription = $emailRecordBody; // These attributes are context-sensitive and subject to change: $action->associationId = $model->id; $action->associationType = $model->module; $action->type = 'email'; $action->visibility = isset($model->visibility) ? $model->visibility : 1; $action->assignedTo = $this->userProfile->username; if ($this->modelName == 'Quote') { // Is an email being sent to the primary // contact on the quote? If so, the user is "issuing" the quote or // invoice, and it should have a special type. if (!empty($this->targetModel->contact)) { if (array_key_exists($this->targetModel->contact->email, $recipientContacts)) { $action->associationType = lcfirst(get_class($model)); $action->associationId = $model->id; $action->type .= '_' . ($model->type == 'invoice' ? 'invoice' : 'quote'); $action->visibility = 1; $action->assignedTo = $model->assignedTo; } } } if ($makeEvent && $action->save()) { $this->trackEmail($action->id); // Create a corresponding event record. Note that special cases // may have to be written in the method Events->getText to // accommodate special association types apart from contacts, // in addition to special-case-handling here. if ($makeEvent) { $event = new Events(); $event->type = 'email_sent'; $event->subtype = 'email'; $event->associationType = $model->myModelName; $event->associationId = $model->id; $event->user = $this->userProfile->username; if ($this->modelName == 'Quote') { // Special "quote issued" or "invoice issued" event: $event->subtype = 'quote'; if ($this->targetModel->type == 'invoice') { $event->subtype = 'invoice'; } $event->associationType = $this->modelName; $event->associationId = $this->modelId; } $event->save(); } } } // Create action history events and event feed events for all contacts that were in the // recipient list: if ($this->contactFlag) { foreach ($recipientContacts as $email => $contact) { $contact->lastActivity = $now; $contact->update(array('lastActivity')); $skip = false; $skipEvent = false; if ($this->targetModel && get_class($this->targetModel) === 'Contacts') { $skip = $this->targetModel->id == $contact->id; } else { if ($this->modelName == 'Quote') { // An event has already been made for issuing the quote and // so another event would be redundant. $skipEvent = $this->targetModel->associatedContacts == $contact->nameId; } } if ($skip) { // Only save the action history item/event if this hasn't // already been done. continue; } // These attributes will be the same regardless of the type of // email being sent: $action = new Actions(); $action->completedBy = $this->userProfile->username; $action->createDate = $now; $action->dueDate = $now; $action->completeDate = $now; $action->complete = 'Yes'; // These attributes are context-sensitive and subject to change: $action->associationId = $contact->id; $action->associationType = 'contacts'; $action->type = 'email'; $action->visibility = isset($contact->visibility) ? $contact->visibility : 1; $action->assignedTo = $this->userProfile->username; // Set the action's text to the modified email body $action->actionDescription = $emailRecordBody; // We don't really care about changelog events for emails; they're // set in stone anyways. $action->disableBehavior('changelog'); if ($action->save()) { // Now create an event for it: if ($makeEvent && !$skipEvent) { $event = new Events(); $event->type = 'email_sent'; $event->subtype = 'email'; $event->associationType = $contact->myModelName; $event->associationId = $contact->id; $event->user = $this->userProfile->username; $event->save(); } } } // Loop over contacts } // Conditional statement: do all this only if the flag to perform action history creation for all contacts has been set // At this stage, if email tracking is to take place, "$action" should // refer to the action history item of the one and only recipient contact, // because there has been only one element in the recipient array to loop // over. If the target model is a contact, and the one recipient is the // contact itself, the action will be as declared before the above loop, // and it will thus still be properly associated with that contact. }
public static function recordEmailSent(Campaign $campaign, Contacts $contact) { $action = new Actions(); // Disable the unsightly notifications for loads of emails: $action->scenario = 'noNotif'; $now = time(); $action->associationType = 'contacts'; $action->associationId = $contact->id; $action->associationName = $contact->firstName . ' ' . $contact->lastName; $action->visibility = $contact->visibility; $action->type = 'email'; $action->assignedTo = $contact->assignedTo; $action->createDate = $now; $action->completeDate = $now; $action->complete = 'Yes'; $action->actionDescription = '<b>' . Yii::t('marketing', 'Campaign') . ': ' . $campaign->name . "</b>\n\n" . Yii::t('marketing', 'Subject') . ": " . Docs::replaceVariables($campaign->subject, $contact) . "\n\n" . Docs::replaceVariables($campaign->content, $contact); if (!$action->save()) { throw new CException('Campaing email action history record failed to save with validation errors: ' . CJSON::encode($action->errors)); } }
public function actionQuickDelete($id) { $model = $this->loadModel($id); if ($model) { // delete associated actions Actions::model()->deleteAllByAttributes(array('associationId' => $id, 'associationType' => 'quotes')); // delete product relationships QuoteProduct::model()->deleteAllByAttributes(array('quoteId' => $id)); // delete contact relationships Relationships::model()->deleteAllByAttributes(array('firstType' => 'quotes', 'firstId' => $id, 'secondType' => 'contacts')); $name = $model->name; // generate history $contact = Contacts::model()->findByPk($_GET['contactId']); $action = new Actions(); $action->associationType = 'contacts'; $action->type = 'quotes'; $action->associationId = $contact->id; $action->associationName = $contact->name; $action->assignedTo = Yii::app()->user->getName(); $action->completedBy = Yii::app()->user->getName(); $action->createDate = time(); $action->dueDate = time(); $action->completeDate = time(); $action->visibility = 1; $action->complete = 'Yes'; $action->actionDescription = "Deleted Quote: <span style=\"font-weight:bold;\">{$model->id}</span> {$model->name}"; $action->save(); $this->cleanUpTags($model); $model->delete(); } else { throw new CHttpException(400, Yii::t('app', 'Invalid request. Please do not repeat this request again.')); } if ($_GET['contactId']) { Yii::app()->clientScript->scriptMap['*.js'] = false; $contact = Contacts::model()->findByPk($_GET['contactId']); $this->renderPartial('quoteFormWrapper', array('model' => $contact), false, true); } }
/** * Starts a workflow stage * @param int $workflowId * @param int $stageNumber the stage to start * @param object $model model associated with workflow */ public static function startStage($workflowId, $stageNumber, $model, $workflowStatus = null) { //AuxLib::debugLogR ('starting stage '.$stageNumber); $modelId = $model->id; $type = lcfirst(X2Model::getModuleName(get_class($model))); if (!$workflowStatus) { $workflowStatus = Workflow::getWorkflowStatus($workflowId, $modelId, $type); } //AuxLib::debugLogR ($workflowStatus); //assert ($model !== null); $started = false; // if stage has not yet been started or completed if ($model !== null && self::checkStageRequirement($stageNumber, $workflowStatus) && !self::isStarted($workflowStatus, $stageNumber)) { $action = new Actions('workflow'); // don't genererate normal action changelog/triggers/events $action->disableBehavior('changelog'); $action->disableBehavior('tags'); // no tags up in here $action->associationId = $modelId; $action->associationType = $type; $action->assignedTo = Yii::app()->user->getName(); $action->updatedBy = Yii::app()->user->getName(); $action->complete = 'No'; $action->type = 'workflow'; $action->visibility = 1; $action->createDate = time(); $action->lastUpdated = time(); $action->workflowId = (int) $workflowId; $action->stageNumber = (int) $stageNumber; $action->save(); $model->updateLastActivity(); X2Flow::trigger('WorkflowStartStageTrigger', array('workflow' => $action->workflow, 'model' => $model, 'workflowId' => $action->workflow->id, 'stageNumber' => $stageNumber)); if (!$workflowStatus['started']) { X2Flow::trigger('WorkflowStartTrigger', array('workflow' => $action->workflow, 'model' => $model, 'workflowId' => $action->workflow->id)); } self::updateWorkflowChangelog($action, 'start', $model); $workflowStatus = Workflow::getWorkflowStatus($workflowId, $modelId, $type); $started = true; } //AuxLib::debugLogR ((int) $started); return array($started, $workflowStatus); }
public function actionTempImportWorkflow() { $file = "workflowData.csv"; $fp = fopen($file, 'r+'); $meta = fgetcsv($fp); $workflowList = array('1' => 'Contacted', '2' => 'Appointment Set', '3' => 'Interview Conducted', '4' => 'Essay/Assessment Completed', '5' => 'Transcript Request Form', '6' => 'Unofficial Transcript', '7' => 'Application Completed', '8' => 'Recommendation', '9' => 'Notify FA/Prelim', '10' => 'FAFSA Completed', '11' => 'Transcribe Application', '12' => 'Enrolled', '13' => 'FA Complete', '14' => 'Official Transcript', '15' => 'Started', '16' => '3 2 1 Checklist', '17' => 'Services Lead Card', '18' => 'Q Drive'); while ($arr = fgetcsv($fp)) { $attributes = array_combine($meta, $arr); $record = Contacts::model()->findByPk($attributes['id']); if (isset($record)) { $modelId = $record->id; $type = "contacts"; $workflowId = 1; foreach ($workflowList as $stageNumber => $stage) { if (isset($attributes[$stage]) && $attributes[$stage] != "") { if (is_numeric($workflowId) && is_numeric($stageNumber) && is_numeric($modelId) && ctype_alpha($type)) { $workflowStatus = Workflow::getWorkflowStatus($workflowId, $modelId, $type); if ((!isset($workflowStatus[$stageNumber]['createDate']) || $workflowStatus[$stageNumber]['createDate'] == 0) && (!isset($workflowStatus[$stageNumber]['completeDate']) || $workflowStatus[$stageNumber]['completeDate'] == 0)) { $action = new Actions('workflow'); $action->associationId = $modelId; $action->associationType = $type; $action->assignedTo = 'Anyone'; $action->updatedBy = 'admin'; $action->complete = 'Yes'; $action->completeDate = strtotime($attributes[$stage]); $action->completedBy = 'admin'; $action->type = 'workflow'; $action->visibility = 1; $action->createDate = strtotime($attributes[$stage]); $action->lastUpdated = time(); $action->workflowId = (int) $workflowId; $action->stageNumber = (int) $stageNumber; // $action->actionDescription = ''; $action->save(); // echo var_dump($action->getErrors()); // echo var_dump($action->attributes); // echo var_dump($action->save()); // echo'derp'; } } } } } } }