예제 #1
0
 /**
  * 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
 }
예제 #2
0
파일: Workflow.php 프로젝트: keyeMyria/CRM
 /**
  * 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);
 }
예제 #3
0
 /**
  * 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.
 }
예제 #4
0
 public function getAction($new = false)
 {
     if (!isset($this->_action) || $new) {
         if (!Yii::app()->user->isGuest) {
             $model = new Actions();
         } else {
             $model = new Actions('guestCreate');
         }
         if (!empty($this->type)) {
             $model->disableBehavior('changelog');
         }
         $this->_action = $model;
     }
     return $this->_action;
 }