Esempio n. 1
0
 /**
  * Confirm a pending subscription
  *
  * @param int $contact_id       The id of the contact
  * @param int $subscribe_id     The id of the subscription event
  * @param string $hash          The hash
  *
  * @return boolean              True on success
  * @access public
  * @static
  */
 public static function confirm($contact_id, $subscribe_id, $hash)
 {
     $se =& CRM_Mailing_Event_BAO_Subscribe::verify($contact_id, $subscribe_id, $hash);
     if (!$se) {
         return FALSE;
     }
     // before we proceed lets just check if this contact is already 'Added'
     // if so, we should ignore this request and hence avoid sending multiple
     // emails - CRM-11157
     $details = CRM_Contact_BAO_GroupContact::getMembershipDetail($contact_id, $se->group_id);
     if ($details && $details->status == 'Added') {
         // This contact is already subscribed
         // lets return the group title
         return CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $se->group_id, 'title');
     }
     $transaction = new CRM_Core_Transaction();
     $ce = new CRM_Mailing_Event_BAO_Confirm();
     $ce->event_subscribe_id = $se->id;
     $ce->time_stamp = date('YmdHis');
     $ce->save();
     CRM_Contact_BAO_GroupContact::addContactsToGroup(array($contact_id), $se->group_id, 'Email', 'Added', $ce->id);
     $transaction->commit();
     $config = CRM_Core_Config::singleton();
     $domain = CRM_Core_BAO_Domain::getDomain();
     list($domainEmailName, $_) = CRM_Core_BAO_Domain::getNameAndEmail();
     list($display_name, $email) = CRM_Contact_BAO_Contact_Location::getEmailDetails($se->contact_id);
     $group = new CRM_Contact_DAO_Group();
     $group->id = $se->group_id;
     $group->find(TRUE);
     $component = new CRM_Mailing_BAO_Component();
     $component->is_default = 1;
     $component->is_active = 1;
     $component->component_type = 'Welcome';
     $component->find(TRUE);
     $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain();
     $html = $component->body_html;
     if ($component->body_text) {
         $text = $component->body_text;
     } else {
         $text = CRM_Utils_String::htmlToText($component->body_html);
     }
     $bao = new CRM_Mailing_BAO_Mailing();
     $bao->body_text = $text;
     $bao->body_html = $html;
     $tokens = $bao->getTokens();
     $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, TRUE, $tokens['html']);
     $html = CRM_Utils_Token::replaceWelcomeTokens($html, $group->title, TRUE);
     $text = CRM_Utils_Token::replaceDomainTokens($text, $domain, FALSE, $tokens['text']);
     $text = CRM_Utils_Token::replaceWelcomeTokens($text, $group->title, FALSE);
     $mailParams = array('groupName' => 'Mailing Event ' . $component->component_type, 'subject' => $component->subject, 'from' => "\"{$domainEmailName}\" <do-not-reply@{$emailDomain}>", 'toEmail' => $email, 'toName' => $display_name, 'replyTo' => "do-not-reply@{$emailDomain}", 'returnPath' => "do-not-reply@{$emailDomain}", 'html' => $html, 'text' => $text);
     // send - ignore errors because the desired status change has already been successful
     $unused_result = CRM_Utils_Mail::send($mailParams);
     return $group->title;
 }
Esempio n. 2
0
 /**
  * Validation.
  *
  * @param array $params
  *   (ref.) an assoc array of name/value pairs.
  *
  * @param $files
  * @param $self
  *
  * @return bool|array
  *   mixed true or array of errors
  */
 public static function formRule($params, $files, $self)
 {
     if (!empty($_POST['_qf_Import_refresh'])) {
         return TRUE;
     }
     $errors = array();
     $template = CRM_Core_Smarty::singleton();
     if (isset($params['html_message'])) {
         $htmlMessage = str_replace(array("\n", "\r"), ' ', $params['html_message']);
         $htmlMessage = str_replace("'", "\\'", $htmlMessage);
         $template->assign('htmlContent', $htmlMessage);
     }
     $domain = CRM_Core_BAO_Domain::getDomain();
     $mailing = new CRM_Mailing_BAO_Mailing();
     $mailing->id = $self->_mailingID;
     $mailing->find(TRUE);
     $session = CRM_Core_Session::singleton();
     $values = array('contact_id' => $session->get('userID'), 'version' => 3);
     require_once 'api/api.php';
     $contact = civicrm_api('contact', 'get', $values);
     //CRM-4524
     $contact = reset($contact['values']);
     $verp = array_flip(array('optOut', 'reply', 'unsubscribe', 'resubscribe', 'owner'));
     foreach ($verp as $key => $value) {
         $verp[$key]++;
     }
     $urls = array_flip(array('forward', 'optOutUrl', 'unsubscribeUrl', 'resubscribeUrl'));
     foreach ($urls as $key => $value) {
         $urls[$key]++;
     }
     // set $header and $footer
     foreach (array('header', 'footer') as $part) {
         ${$part} = array();
         if ($params["{$part}_id"]) {
             //echo "found<p>";
             $component = new CRM_Mailing_BAO_Component();
             $component->id = $params["{$part}_id"];
             $component->find(TRUE);
             ${$part}['textFile'] = $component->body_text;
             ${$part}['htmlFile'] = $component->body_html;
             $component->free();
         } else {
             ${$part}['htmlFile'] = ${$part}['textFile'] = '';
         }
     }
     $skipTextFile = $self->get('skipTextFile');
     $skipHtmlFile = $self->get('skipHtmlFile');
     if (!$params['upload_type']) {
         if ((!isset($files['textFile']) || !file_exists($files['textFile']['tmp_name'])) && (!isset($files['htmlFile']) || !file_exists($files['htmlFile']['tmp_name']))) {
             if (!($skipTextFile || $skipHtmlFile)) {
                 $errors['textFile'] = ts('Please provide either a Text or HTML formatted message - or both.');
             }
         }
     } else {
         if (empty($params['text_message']) && empty($params['html_message'])) {
             $errors['html_message'] = ts('Please provide either a Text or HTML formatted message - or both.');
         }
         if (!empty($params['saveTemplate']) && empty($params['saveTemplateName'])) {
             $errors['saveTemplateName'] = ts('Please provide a Template Name.');
         }
     }
     foreach (array('text', 'html') as $file) {
         if (!$params['upload_type'] && !file_exists(CRM_Utils_Array::value('tmp_name', $files[$file . 'File']))) {
             continue;
         }
         if ($params['upload_type'] && !$params[$file . '_message']) {
             continue;
         }
         if (!$params['upload_type']) {
             $str = file_get_contents($files[$file . 'File']['tmp_name']);
             $name = $files[$file . 'File']['name'];
         } else {
             $str = $params[$file . '_message'];
             $str = $file == 'html' ? str_replace('%7B', '{', str_replace('%7D', '}', $str)) : $str;
             $name = $file . ' message';
         }
         /* append header/footer */
         $str = $header[$file . 'File'] . $str . $footer[$file . 'File'];
         $dataErrors = array();
         /* First look for missing tokens */
         if (!CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, 'disable_mandatory_tokens_check')) {
             $err = CRM_Utils_Token::requiredTokens($str);
             if ($err !== TRUE) {
                 foreach ($err as $token => $desc) {
                     $dataErrors[] = '<li>' . ts('This message is missing a required token - {%1}: %2', array(1 => $token, 2 => $desc)) . '</li>';
                 }
             }
         }
         /* Do a full token replacement on a dummy verp, the current
          * contact and domain, and the first organization. */
         // here we make a dummy mailing object so that we
         // can retrieve the tokens that we need to replace
         // so that we do get an invalid token error
         // this is qute hacky and I hope that there might
         // be a suggestion from someone on how to
         // make it a bit more elegant
         $dummy_mail = new CRM_Mailing_BAO_Mailing();
         $mess = "body_{$file}";
         $dummy_mail->{$mess} = $str;
         $tokens = $dummy_mail->getTokens();
         $str = CRM_Utils_Token::replaceSubscribeInviteTokens($str);
         $str = CRM_Utils_Token::replaceDomainTokens($str, $domain, NULL, $tokens[$file]);
         $str = CRM_Utils_Token::replaceMailingTokens($str, $mailing, NULL, $tokens[$file]);
         $str = CRM_Utils_Token::replaceOrgTokens($str, $org);
         $str = CRM_Utils_Token::replaceActionTokens($str, $verp, $urls, NULL, $tokens[$file]);
         $str = CRM_Utils_Token::replaceContactTokens($str, $contact, NULL, $tokens[$file]);
         $unmatched = CRM_Utils_Token::unmatchedTokens($str);
         if (!empty($unmatched) && 0) {
             foreach ($unmatched as $token) {
                 $dataErrors[] = '<li>' . ts('Invalid token code') . ' {' . $token . '}</li>';
             }
         }
         if (!empty($dataErrors)) {
             $errors[$file . 'File'] = ts('The following errors were detected in %1:', array(1 => $name)) . ' <ul>' . implode('', $dataErrors) . '</ul><br /><a href="' . CRM_Utils_System::docURL2('Sample CiviMail Messages', TRUE, NULL, NULL, NULL, "wiki") . '" target="_blank">' . ts('More information on required tokens...') . '</a>';
         }
     }
     $templateName = CRM_Core_BAO_MessageTemplate::getMessageTemplates();
     if (!empty($params['saveTemplate']) && in_array(CRM_Utils_Array::value('saveTemplateName', $params), $templateName)) {
         $errors['saveTemplate'] = ts('Duplicate Template Name.');
     }
     return empty($errors) ? TRUE : $errors;
 }
 /**
  * Get the content/components of mailing based on mailing Id
  *
  * @param array $report
  *   of mailing report.
  *
  * @param $form
  *   Reference of this.
  *
  * @param bool $isSMS
  *
  * @return array
  *   array content/component.
  */
 public static function getMailingContent(&$report, &$form, $isSMS = FALSE)
 {
     $htmlHeader = $textHeader = NULL;
     $htmlFooter = $textFooter = NULL;
     if (!$isSMS) {
         if ($report['mailing']['header_id']) {
             $header = new CRM_Mailing_BAO_Component();
             $header->id = $report['mailing']['header_id'];
             $header->find(TRUE);
             $htmlHeader = $header->body_html;
             $textHeader = $header->body_text;
         }
         if ($report['mailing']['footer_id']) {
             $footer = new CRM_Mailing_BAO_Component();
             $footer->id = $report['mailing']['footer_id'];
             $footer->find(TRUE);
             $htmlFooter = $footer->body_html;
             $textFooter = $footer->body_text;
         }
     }
     $mailingKey = $form->_mailing_id;
     if (!$isSMS) {
         if ($hash = CRM_Mailing_BAO_Mailing::getMailingHash($mailingKey)) {
             $mailingKey = $hash;
         }
     }
     if (!empty($report['mailing']['body_text'])) {
         $url = CRM_Utils_System::url('civicrm/mailing/view', 'reset=1&text=1&id=' . $mailingKey);
         $form->assign('textViewURL', $url);
     }
     if (!$isSMS) {
         if (!empty($report['mailing']['body_html'])) {
             $url = CRM_Utils_System::url('civicrm/mailing/view', 'reset=1&id=' . $mailingKey);
             $form->assign('htmlViewURL', $url);
         }
     }
     if (!$isSMS) {
         $report['mailing']['attachment'] = CRM_Core_BAO_File::attachmentInfo('civicrm_mailing', $form->_mailing_id);
     }
     return $report;
 }
Esempio n. 4
0
 /**
  * Ask a contact for subscription confirmation (opt-in)
  *
  * @param string $email
  *   The email address.
  *
  * @return void
  */
 public function send_confirm_request($email)
 {
     $config = CRM_Core_Config::singleton();
     $domain = CRM_Core_BAO_Domain::getDomain();
     //get the default domain email address.
     list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail();
     $localpart = CRM_Core_BAO_MailSettings::defaultLocalpart();
     $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain();
     $confirm = implode($config->verpSeparator, array($localpart . 'c', $this->contact_id, $this->id, $this->hash)) . "@{$emailDomain}";
     $group = new CRM_Contact_BAO_Group();
     $group->id = $this->group_id;
     $group->find(TRUE);
     $component = new CRM_Mailing_BAO_Component();
     $component->is_default = 1;
     $component->is_active = 1;
     $component->component_type = 'Subscribe';
     $component->find(TRUE);
     $headers = array('Subject' => $component->subject, 'From' => "\"{$domainEmailName}\" <{$domainEmailAddress}>", 'To' => $email, 'Reply-To' => $confirm, 'Return-Path' => "do-not-reply@{$emailDomain}");
     $url = CRM_Utils_System::url('civicrm/mailing/confirm', "reset=1&cid={$this->contact_id}&sid={$this->id}&h={$this->hash}", TRUE);
     $html = $component->body_html;
     if ($component->body_text) {
         $text = $component->body_text;
     } else {
         $text = CRM_Utils_String::htmlToText($component->body_html);
     }
     $bao = new CRM_Mailing_BAO_Mailing();
     $bao->body_text = $text;
     $bao->body_html = $html;
     $tokens = $bao->getTokens();
     $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, TRUE, $tokens['html']);
     $html = CRM_Utils_Token::replaceSubscribeTokens($html, $group->title, $url, TRUE);
     $text = CRM_Utils_Token::replaceDomainTokens($text, $domain, FALSE, $tokens['text']);
     $text = CRM_Utils_Token::replaceSubscribeTokens($text, $group->title, $url, FALSE);
     // render the &amp; entities in text mode, so that the links work
     $text = str_replace('&amp;', '&', $text);
     $message = new Mail_mime("\n");
     $message->setHTMLBody($html);
     $message->setTxtBody($text);
     $b = CRM_Utils_Mail::setMimeParams($message);
     $h = $message->headers($headers);
     CRM_Mailing_BAO_Mailing::addMessageIdHeader($h, 's', $this->contact_id, $this->id, $this->hash);
     $mailer = \Civi::service('pear_mail');
     if (is_object($mailer)) {
         $errorScope = CRM_Core_TemporaryErrorScope::ignoreException();
         $mailer->send($email, $h, $b);
         unset($errorScope);
     }
 }
Esempio n. 5
0
 /**
  * Process the form submission.
  */
 public function postProcess()
 {
     // store the submitted values in an array
     $params = $this->controller->exportValues($this->_name);
     if ($this->_action & CRM_Core_Action::UPDATE) {
         $params['id'] = $this->_id;
     }
     $component = CRM_Mailing_BAO_Component::add($params);
     CRM_Core_Session::setStatus(ts('The mailing component \'%1\' has been saved.', array(1 => $component->name)), ts('Saved'), 'success');
 }
 /**
  * Get the content/components of mailing based on mailing Id
  *
  * @param $report array of mailing report
  *
  * @param $form reference of this
  *
  * @return $report array content/component.
  * @access public
  */
 static function getMailingContent(&$report, &$form, $isSMS = FALSE)
 {
     $htmlHeader = $textHeader = NULL;
     $htmlFooter = $textFooter = NULL;
     if (!$isSMS) {
         if ($report['mailing']['header_id']) {
             $header = new CRM_Mailing_BAO_Component();
             $header->id = $report['mailing']['header_id'];
             $header->find(TRUE);
             $htmlHeader = $header->body_html;
             $textHeader = $header->body_text;
         }
         if ($report['mailing']['footer_id']) {
             $footer = new CRM_Mailing_BAO_Component();
             $footer->id = $report['mailing']['footer_id'];
             $footer->find(TRUE);
             $htmlFooter = $footer->body_html;
             $textFooter = $footer->body_text;
         }
     }
     $text = CRM_Utils_Request::retrieve('text', 'Boolean', $form);
     if ($text) {
         echo "<pre>{$textHeader}</br>{$report['mailing']['body_text']}</br>{$textFooter}</pre>";
         CRM_Utils_System::civiExit();
     }
     if (!$isSMS) {
         $html = CRM_Utils_Request::retrieve('html', 'Boolean', $form);
         if ($html) {
             $output = $htmlHeader . $report['mailing']['body_html'] . $htmlFooter;
             echo str_replace("\n", '<br />', $output);
             CRM_Utils_System::civiExit();
         }
     }
     if (!empty($report['mailing']['body_text'])) {
         $url = CRM_Utils_System::url('civicrm/mailing/report', 'reset=1&text=1&mid=' . $form->_mailing_id);
         $popup = "javascript:popUp(\"{$url}\");";
         $form->assign('textViewURL', $popup);
     }
     if (!$isSMS) {
         if (!empty($report['mailing']['body_html'])) {
             $url = CRM_Utils_System::url('civicrm/mailing/report', 'reset=1&html=1&mid=' . $form->_mailing_id);
             $popup = "javascript:popUp(\"{$url}\");";
             $form->assign('htmlViewURL', $popup);
         }
     }
     if (!$isSMS) {
         $report['mailing']['attachment'] = CRM_Core_BAO_File::attachmentInfo('civicrm_mailing', $form->_mailing_id);
     }
     return $report;
 }
Esempio n. 7
0
 /**
  * Send a response email informing the contact of the groups from which he.
  * has been unsubscribed.
  *
  * @param string $queue_id
  *   The queue event ID.
  * @param array $groups
  *   List of group IDs.
  * @param bool $is_domain
  *   Is this domain-level?.
  * @param int $job
  *   The job ID.
  */
 public static function send_unsub_response($queue_id, $groups, $is_domain = FALSE, $job)
 {
     $config = CRM_Core_Config::singleton();
     $domain = CRM_Core_BAO_Domain::getDomain();
     $jobObject = new CRM_Mailing_BAO_MailingJob();
     $jobTable = $jobObject->getTableName();
     $mailingObject = new CRM_Mailing_DAO_Mailing();
     $mailingTable = $mailingObject->getTableName();
     $contactsObject = new CRM_Contact_DAO_Contact();
     $contacts = $contactsObject->getTableName();
     $emailObject = new CRM_Core_DAO_Email();
     $email = $emailObject->getTableName();
     $queueObject = new CRM_Mailing_Event_BAO_Queue();
     $queue = $queueObject->getTableName();
     //get the default domain email address.
     list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail();
     $dao = new CRM_Mailing_BAO_Mailing();
     $dao->query("   SELECT * FROM {$mailingTable}\n                        INNER JOIN {$jobTable} ON\n                            {$jobTable}.mailing_id = {$mailingTable}.id\n                        WHERE {$jobTable}.id = {$job}");
     $dao->fetch();
     $component = new CRM_Mailing_BAO_Component();
     if ($is_domain) {
         $component->id = $dao->optout_id;
     } else {
         $component->id = $dao->unsubscribe_id;
     }
     $component->find(TRUE);
     $html = $component->body_html;
     if ($component->body_text) {
         $text = $component->body_text;
     } else {
         $text = CRM_Utils_String::htmlToText($component->body_html);
     }
     $eq = new CRM_Core_DAO();
     $eq->query("SELECT     {$contacts}.preferred_mail_format as format,\n                    {$contacts}.id as contact_id,\n                    {$email}.email as email,\n                    {$queue}.hash as hash\n        FROM        {$contacts}\n        INNER JOIN  {$queue} ON {$queue}.contact_id = {$contacts}.id\n        INNER JOIN  {$email} ON {$queue}.email_id = {$email}.id\n        WHERE       {$queue}.id = " . CRM_Utils_Type::escape($queue_id, 'Integer'));
     $eq->fetch();
     if ($groups) {
         foreach ($groups as $key => $value) {
             if (!$value) {
                 unset($groups[$key]);
             }
         }
     }
     $message = new Mail_mime("\n");
     list($addresses, $urls) = CRM_Mailing_BAO_Mailing::getVerpAndUrls($job, $queue_id, $eq->hash, $eq->email);
     $bao = new CRM_Mailing_BAO_Mailing();
     $bao->body_text = $text;
     $bao->body_html = $html;
     $tokens = $bao->getTokens();
     if ($eq->format == 'HTML' || $eq->format == 'Both') {
         $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, TRUE, $tokens['html']);
         $html = CRM_Utils_Token::replaceUnsubscribeTokens($html, $domain, $groups, TRUE, $eq->contact_id, $eq->hash);
         $html = CRM_Utils_Token::replaceActionTokens($html, $addresses, $urls, TRUE, $tokens['html']);
         $html = CRM_Utils_Token::replaceMailingTokens($html, $dao, NULL, $tokens['html']);
         $message->setHTMLBody($html);
     }
     if (!$html || $eq->format == 'Text' || $eq->format == 'Both') {
         $text = CRM_Utils_Token::replaceDomainTokens($text, $domain, FALSE, $tokens['text']);
         $text = CRM_Utils_Token::replaceUnsubscribeTokens($text, $domain, $groups, FALSE, $eq->contact_id, $eq->hash);
         $text = CRM_Utils_Token::replaceActionTokens($text, $addresses, $urls, FALSE, $tokens['text']);
         $text = CRM_Utils_Token::replaceMailingTokens($text, $dao, NULL, $tokens['text']);
         $message->setTxtBody($text);
     }
     $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain();
     $headers = array('Subject' => $component->subject, 'From' => "\"{$domainEmailName}\" <do-not-reply@{$emailDomain}>", 'To' => $eq->email, 'Reply-To' => "do-not-reply@{$emailDomain}", 'Return-Path' => "do-not-reply@{$emailDomain}");
     CRM_Mailing_BAO_Mailing::addMessageIdHeader($headers, 'u', $job, $queue_id, $eq->hash);
     $b = CRM_Utils_Mail::setMimeParams($message);
     $h = $message->headers($headers);
     $mailer = \Civi::service('pear_mail');
     if (is_object($mailer)) {
         $errorScope = CRM_Core_TemporaryErrorScope::ignoreException();
         $mailer->send($eq->email, $h, $b);
         unset($errorScope);
     }
 }
Esempio n. 8
0
 /**
  * Function to process the form
  *
  * @access public
  * @return None
  */
 public function postProcess()
 {
     // store the submitted values in an array
     $params = $this->controller->exportValues($this->_name);
     $ids = array();
     if ($this->_action & CRM_Core_Action::UPDATE) {
         $ids['id'] = $this->_id;
     }
     require_once 'CRM/Mailing/BAO/Component.php';
     CRM_Mailing_BAO_Component::add($params, $ids);
 }
Esempio n. 9
0
 /**
  * Send a reponse email informing the contact of the groups to which he/she
  * has been resubscribed.
  *
  * @param string $queue_id      The queue event ID
  * @param array $groups         List of group IDs
  * @param bool $is_domain       Is this domain-level?
  * @param int $job              The job ID
  * @return void
  * @access public
  * @static
  */
 public static function send_resub_response($queue_id, $groups, $is_domain = false, $job)
 {
     // param is_domain is not supported as of now.
     $config = CRM_Core_Config::singleton();
     $domain =& CRM_Core_BAO_Domain::getDomain();
     $jobTable = CRM_Mailing_BAO_Job::getTableName();
     $mailingTable = CRM_Mailing_DAO_Mailing::getTableName();
     $contacts = CRM_Contact_DAO_Contact::getTableName();
     $email = CRM_Core_DAO_Email::getTableName();
     $queue = CRM_Mailing_Event_BAO_Queue::getTableName();
     //get the default domain email address.
     list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail();
     $dao = new CRM_Mailing_BAO_Mailing();
     $dao->query("   SELECT * FROM {$mailingTable} \n                        INNER JOIN {$jobTable} ON\n                            {$jobTable}.mailing_id = {$mailingTable}.id \n                        WHERE {$jobTable}.id = {$job}");
     $dao->fetch();
     $component = new CRM_Mailing_BAO_Component();
     $component->id = $dao->resubscribe_id;
     $component->find(true);
     $html = $component->body_html;
     if ($component->body_text) {
         $text = $component->body_text;
     } else {
         $text = CRM_Utils_String::htmlToText($component->body_html);
     }
     $eq = new CRM_Core_DAO();
     $eq->query("SELECT     {$contacts}.preferred_mail_format as format,\n                    {$contacts}.id as contact_id,\n                    {$email}.email as email,\n                    {$queue}.hash as hash\n        FROM        {$contacts}\n        INNER JOIN  {$queue} ON {$queue}.contact_id = {$contacts}.id\n        INNER JOIN  {$email} ON {$queue}.email_id = {$email}.id\n        WHERE       {$queue}.id = " . CRM_Utils_Type::escape($queue_id, 'Integer'));
     $eq->fetch();
     foreach ($groups as $key => $value) {
         if (!$value) {
             unset($groups[$key]);
         }
     }
     $message = new Mail_mime("\n");
     list($addresses, $urls) = CRM_Mailing_BAO_Mailing::getVerpAndUrls($job, $queue_id, $eq->hash, $eq->email);
     $bao = new CRM_Mailing_BAO_Mailing();
     $bao->body_text = $text;
     $bao->body_html = $html;
     $tokens = $bao->getTokens();
     require_once 'CRM/Utils/Token.php';
     if ($eq->format == 'HTML' || $eq->format == 'Both') {
         $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, true, $tokens['html']);
         $html = CRM_Utils_Token::replaceResubscribeTokens($html, $domain, $groups, true, $eq->contact_id, $eq->hash);
         $html = CRM_Utils_Token::replaceActionTokens($html, $addresses, $urls, true, $tokens['html']);
         $html = CRM_Utils_Token::replaceMailingTokens($html, $dao, null, $tokens['html']);
         $message->setHTMLBody($html);
     }
     if (!$html || $eq->format == 'Text' || $eq->format == 'Both') {
         $text = CRM_Utils_Token::replaceDomainTokens($html, $domain, true, $tokens['text']);
         $text = CRM_Utils_Token::replaceResubscribeTokens($text, $domain, $groups, false, $eq->contact_id, $eq->hash);
         $text = CRM_Utils_Token::replaceActionTokens($text, $addresses, $urls, false, $tokens['text']);
         $text = CRM_Utils_Token::replaceMailingTokens($text, $dao, null, $tokens['text']);
         $message->setTxtBody($text);
     }
     require_once 'CRM/Core/BAO/MailSettings.php';
     $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain();
     $headers = array('Subject' => $component->subject, 'From' => "\"{$domainEmailName}\" <do-not-reply@{$emailDomain}>", 'To' => $eq->email, 'Reply-To' => "do-not-reply@{$emailDomain}", 'Return-Path' => "do-not-reply@{$emailDomain}");
     $b =& CRM_Utils_Mail::setMimeParams($message);
     $h =& $message->headers($headers);
     $mailer =& $config->getMailer();
     PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array('CRM_Core_Error', 'nullHandler'));
     if (is_object($mailer)) {
         $mailer->send($eq->email, $h, $b);
         CRM_Core_Error::setCallback();
     }
 }
Esempio n. 10
0
 /**
  * Send an automated response.
  *
  * @param object $mailing
  *   The mailing object.
  * @param int $queue_id
  *   The queue ID.
  * @param string $replyto
  *   Optional reply-to from the reply.
  *
  * @return void
  */
 private static function autoRespond(&$mailing, $queue_id, $replyto)
 {
     $config = CRM_Core_Config::singleton();
     $contacts = CRM_Contact_DAO_Contact::getTableName();
     $email = CRM_Core_DAO_Email::getTableName();
     $queue = CRM_Mailing_Event_DAO_Queue::getTableName();
     $eq = new CRM_Core_DAO();
     $eq->query("SELECT     {$contacts}.preferred_mail_format as format,\n                  {$email}.email as email,\n                  {$queue}.job_id as job_id,\n                  {$queue}.hash as hash\n        FROM        {$contacts}\n        INNER JOIN  {$queue} ON {$queue}.contact_id = {$contacts}.id\n        INNER JOIN  {$email} ON {$queue}.email_id = {$email}.id\n        WHERE       {$queue}.id = " . CRM_Utils_Type::escape($queue_id, 'Integer'));
     $eq->fetch();
     $to = empty($replyto) ? $eq->email : $replyto;
     $component = new CRM_Mailing_BAO_Component();
     $component->id = $mailing->reply_id;
     $component->find(TRUE);
     $message = new Mail_Mime("\n");
     $domain = CRM_Core_BAO_Domain::getDomain();
     list($domainEmailName, $_) = CRM_Core_BAO_Domain::getNameAndEmail();
     $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain();
     $headers = array('Subject' => $component->subject, 'To' => $to, 'From' => "\"{$domainEmailName}\" <do-not-reply@{$emailDomain}>", 'Reply-To' => "do-not-reply@{$emailDomain}", 'Return-Path' => "do-not-reply@{$emailDomain}");
     /* TODO: do we need reply tokens? */
     $html = $component->body_html;
     if ($component->body_text) {
         $text = $component->body_text;
     } else {
         $text = CRM_Utils_String::htmlToText($component->body_html);
     }
     $bao = new CRM_Mailing_BAO_Mailing();
     $bao->body_text = $text;
     $bao->body_html = $html;
     $tokens = $bao->getTokens();
     if ($eq->format == 'HTML' || $eq->format == 'Both') {
         $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, TRUE, $tokens['html']);
         $html = CRM_Utils_Token::replaceMailingTokens($html, $mailing, NULL, $tokens['html']);
         $message->setHTMLBody($html);
     }
     if (!$html || $eq->format == 'Text' || $eq->format == 'Both') {
         $text = CRM_Utils_Token::replaceDomainTokens($text, $domain, FALSE, $tokens['text']);
         $text = CRM_Utils_Token::replaceMailingTokens($text, $mailing, NULL, $tokens['text']);
         $message->setTxtBody($text);
     }
     $b = CRM_Utils_Mail::setMimeParams($message);
     $h = $message->headers($headers);
     CRM_Mailing_BAO_Mailing::addMessageIdHeader($h, 'a', $eq->job_id, queue_id, $eq->hash);
     $mailer = $config->getMailer();
     if (is_object($mailer)) {
         $errorScope = CRM_Core_TemporaryErrorScope::ignoreException();
         $mailer->send($to, $h, $b);
         unset($errorScope);
     }
 }
 /**
  * global validation rules for the form
  *
  * @param array $fields posted values of the form
  *
  * @return array list of errors to be posted back to the form
  * @static
  * @access public
  */
 static function formRule($fields)
 {
     $errors = array();
     // Validate include/exclude groups, mailings
     // Start
     if (isset($fields['includeGroups']) && isset($fields['excludeGroups']) && is_array($fields['excludeGroups'])) {
         $checkGroups = array();
         $checkGroups = in_array($fields['includeGroups'], $fields['excludeGroups']);
         if (!empty($checkGroups)) {
             $errors['excludeGroups'] = ts('Cannot have same groups in Include Group(s) and Exclude Group(s).');
         }
     }
     if (isset($fields['includeMailings']) && is_array($fields['includeMailings']) && isset($fields['excludeMailings']) && is_array($fields['excludeMailings'])) {
         $checkMailings = array();
         $checkMailings = array_intersect($fields['includeMailings'], $fields['excludeMailings']);
         if (!empty($checkMailings)) {
             $errors['excludeMailings'] = ts('Cannot have same mail in Include mailing(s) and Exclude mailing(s).');
         }
     }
     if (!empty($fields['search_id']) && empty($fields['group_id'])) {
         $errors['group_id'] = ts('You must select a group to filter on');
     }
     if (empty($fields['search_id']) && !empty($fields['group_id'])) {
         $errors['search_id'] = ts('You must select a search to filter');
     }
     // End
     // Validate message template html/text
     // Start
     $errors = array();
     $template = CRM_Core_Smarty::singleton();
     if (isset($fields['html_message'])) {
         $htmlMessage = str_replace(array("\n", "\r"), ' ', $fields['html_message']);
         $htmlMessage = str_replace("'", "\\'", $htmlMessage);
         $template->assign('htmlContent', $htmlMessage);
     }
     $domain = CRM_Core_BAO_Domain::getDomain();
     $session = CRM_Core_Session::singleton();
     $values = array('contact_id' => $session->get('userID'), 'version' => 3);
     require_once 'api/api.php';
     $contact = civicrm_api('contact', 'get', $values);
     //CRM-4524
     $contact = reset($contact['values']);
     $verp = array_flip(array('optOut', 'reply', 'unsubscribe', 'resubscribe', 'owner'));
     foreach ($verp as $key => $value) {
         $verp[$key]++;
     }
     $urls = array_flip(array('forward', 'optOutUrl', 'unsubscribeUrl', 'resubscribeUrl'));
     foreach ($urls as $key => $value) {
         $urls[$key]++;
     }
     // set $header and $footer
     foreach (array('header', 'footer') as $part) {
         ${$part} = array();
         if ($fields["{$part}_id"]) {
             //echo "found<p>";
             $component = new CRM_Mailing_BAO_Component();
             $component->id = $fields["{$part}_id"];
             $component->find(TRUE);
             ${$part}['textFile'] = $component->body_text;
             ${$part}['htmlFile'] = $component->body_html;
             $component->free();
         } else {
             ${$part}['htmlFile'] = ${$part}['textFile'] = '';
         }
     }
     if (!CRM_Utils_Array::value('text_message', $fields) && !CRM_Utils_Array::value('html_message', $fields)) {
         $errors['html_message'] = ts('Please provide either a Text or HTML formatted message - or both.');
     }
     foreach (array('text', 'html') as $file) {
         $str = $fields[$file . '_message'];
         $str = $file == 'html' ? str_replace('%7B', '{', str_replace('%7D', '}', $str)) : $str;
         $name = $file . ' message';
         /* append header/footer */
         $str = $header[$file . 'File'] . $str . $footer[$file . 'File'];
         $dataErrors = array();
         /* First look for missing tokens */
         $err = CRM_Utils_Token::requiredTokens($str);
         if ($err !== TRUE) {
             foreach ($err as $token => $desc) {
                 $dataErrors[] = '<li>' . ts('This message is missing a required token - {%1}: %2', array(1 => $token, 2 => $desc)) . '</li>';
             }
         }
         /* Do a full token replacement on a dummy verp, the current
          * contact and domain, and the first organization. */
         // here we make a dummy mailing object so that we
         // can retrieve the tokens that we need to replace
         // so that we do get an invalid token error
         // this is qute hacky and I hope that there might
         // be a suggestion from someone on how to
         // make it a bit more elegant
         $dummy_mail = new CRM_Mailing_BAO_Mailing();
         $mess = "body_{$file}";
         $dummy_mail->{$mess} = $str;
         $tokens = $dummy_mail->getTokens();
         $str = CRM_Utils_Token::replaceSubscribeInviteTokens($str);
         $str = CRM_Utils_Token::replaceDomainTokens($str, $domain, NULL, $tokens[$file]);
         $str = CRM_Utils_Token::replaceMailingTokens($str, $mailing, NULL, $tokens[$file]);
         $str = CRM_Utils_Token::replaceOrgTokens($str, $org);
         $str = CRM_Utils_Token::replaceActionTokens($str, $verp, $urls, NULL, $tokens[$file]);
         $str = CRM_Utils_Token::replaceContactTokens($str, $contact, NULL, $tokens[$file]);
         $unmatched = CRM_Utils_Token::unmatchedTokens($str);
         if (!empty($unmatched) && 0) {
             foreach ($unmatched as $token) {
                 $dataErrors[] = '<li>' . ts('Invalid token code') . ' {' . $token . '}</li>';
             }
         }
         if (!empty($dataErrors)) {
             $errors[$file . '_message'] = ts('The following errors were detected in %1:', array(1 => $name)) . ' <ul>' . implode('', $dataErrors) . '</ul><br /><a href="' . CRM_Utils_System::docURL2('Sample CiviMail Messages', TRUE, NULL, NULL, NULL, "wiki") . '" target="_blank">' . ts('More information on required tokens...') . '</a>';
         }
     }
     // End
     return empty($errors) ? TRUE : $errors;
 }
Esempio n. 12
0
 /**
  * Confirm a pending subscription
  *
  * @param int $contact_id       The id of the contact
  * @param int $subscribe_id     The id of the subscription event
  * @param string $hash          The hash
  * @return boolean              True on success
  * @access public
  * @static
  */
 public static function confirm($contact_id, $subscribe_id, $hash)
 {
     require_once 'CRM/Mailing/Event/BAO/Subscribe.php';
     $se =& CRM_Mailing_Event_BAO_Subscribe::verify($contact_id, $subscribe_id, $hash);
     if (!$se) {
         return false;
     }
     require_once 'CRM/Core/Transaction.php';
     $transaction = new CRM_Core_Transaction();
     $ce = new CRM_Mailing_Event_BAO_Confirm();
     $ce->event_subscribe_id = $se->id;
     $ce->time_stamp = date('YmdHis');
     $ce->save();
     require_once 'CRM/Contact/BAO/GroupContact.php';
     CRM_Contact_BAO_GroupContact::updateGroupMembershipStatus($contact_id, $se->group_id, 'Email', $ce->id);
     $transaction->commit();
     $config = CRM_Core_Config::singleton();
     require_once 'CRM/Core/BAO/Domain.php';
     $domain =& CRM_Core_BAO_Domain::getDomain();
     list($domainEmailName, $_) = CRM_Core_BAO_Domain::getNameAndEmail();
     require_once 'CRM/Contact/BAO/Contact/Location.php';
     list($display_name, $email) = CRM_Contact_BAO_Contact_Location::getEmailDetails($se->contact_id);
     require_once 'CRM/Contact/DAO/Group.php';
     $group = new CRM_Contact_DAO_Group();
     $group->id = $se->group_id;
     $group->find(true);
     require_once 'CRM/Mailing/BAO/Component.php';
     $component = new CRM_Mailing_BAO_Component();
     $component->is_default = 1;
     $component->is_active = 1;
     $component->component_type = 'Welcome';
     $component->find(true);
     require_once 'CRM/Core/BAO/MailSettings.php';
     $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain();
     $headers = array('Subject' => $component->subject, 'From' => "\"{$domainEmailName}\" <do-not-reply@{$emailDomain}>", 'To' => $email, 'Reply-To' => "do-not-reply@{$emailDomain}", 'Return-Path' => "do-not-reply@{$emailDomain}");
     $html = $component->body_html;
     if ($component->body_text) {
         $text = $component->body_text;
     } else {
         $text = CRM_Utils_String::htmlToText($component->body_html);
     }
     require_once 'CRM/Mailing/BAO/Mailing.php';
     $bao = new CRM_Mailing_BAO_Mailing();
     $bao->body_text = $text;
     $bao->body_html = $html;
     $tokens = $bao->getTokens();
     require_once 'CRM/Utils/Token.php';
     $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, true, $tokens['html']);
     $html = CRM_Utils_Token::replaceWelcomeTokens($html, $group->title, true);
     $text = CRM_Utils_Token::replaceDomainTokens($text, $domain, false, $tokens['text']);
     $text = CRM_Utils_Token::replaceWelcomeTokens($text, $group->title, false);
     $message = new Mail_mime("\n");
     $message->setHTMLBody($html);
     $message->setTxtBody($text);
     $b =& CRM_Utils_Mail::setMimeParams($message);
     $h =& $message->headers($headers);
     $mailer =& $config->getMailer();
     require_once 'CRM/Mailing/BAO/Mailing.php';
     PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array('CRM_Core_Error', 'nullHandler'));
     if (is_object($mailer)) {
         $mailer->send($email, $h, $b);
         CRM_Core_Error::setCallback();
     }
     return $group->title;
 }
Esempio n. 13
0
 /**
  * Get the content/components of mailing based on mailing Id
  *
  * @param $report array of mailing report
  * 
  * @param $form reference of this  
  *
  * @return $report array content/component.
  * @access public
  */
 public function getMailingContent(&$report, &$form)
 {
     require_once 'CRM/Mailing/BAO/Component.php';
     if ($report['mailing']['header_id']) {
         $header = new CRM_Mailing_BAO_Component();
         $header->id = $report['mailing']['header_id'];
         $header->find(true);
         $htmlHeader = $header->body_html;
         $textHeader = $header->body_text;
     }
     if ($report['mailing']['footer_id']) {
         $footer = new CRM_Mailing_BAO_Component();
         $footer->id = $report['mailing']['footer_id'];
         $footer->find(true);
         $htmlFooter = $footer->body_html;
         $textFooter = $footer->body_text;
     }
     $text = CRM_Utils_Request::retrieve('text', 'Boolean', $form);
     if ($text) {
         echo "<pre>{$textHeader}</br>{$report['mailing']['body_text']}</br>{$textFooter}</pre>";
         CRM_Utils_System::civiExit();
     }
     $html = CRM_Utils_Request::retrieve('html', 'Boolean', $form);
     if ($html) {
         echo $htmlHeader . $report['mailing']['body_html'] . $htmlFooter;
         CRM_Utils_System::civiExit();
     }
     if (!empty($report['mailing']['body_text'])) {
         $url = CRM_Utils_System::url('civicrm/mailing/report', 'reset=1&text=1&mid=' . $form->_mailing_id);
         $popup = "javascript:popUp(\"{$url}\");";
         $form->assign('textViewURL', $popup);
     }
     if (!empty($report['mailing']['body_html'])) {
         $url = CRM_Utils_System::url('civicrm/mailing/report', 'reset=1&html=1&mid=' . $form->_mailing_id);
         $popup = "javascript:popUp(\"{$url}\");";
         $form->assign('htmlViewURL', $popup);
     }
     require_once 'CRM/Core/BAO/File.php';
     $report['mailing']['attachment'] = CRM_Core_BAO_File::attachmentInfo('civicrm_mailing', $form->_mailing_id);
     return $report;
 }
Esempio n. 14
0
 /**
  * Ask a contact for subscription confirmation (opt-in)
  *
  * @param string $email         The email address
  * @return void
  * @access public
  */
 public function send_confirm_request($email)
 {
     $config = CRM_Core_Config::singleton();
     require_once 'CRM/Core/BAO/Domain.php';
     $domain =& CRM_Core_BAO_Domain::getDomain();
     //get the default domain email address.
     list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail();
     require_once 'CRM/Core/BAO/MailSettings.php';
     $localpart = CRM_Core_BAO_MailSettings::defaultLocalpart();
     $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain();
     require_once 'CRM/Utils/Verp.php';
     $confirm = implode($config->verpSeparator, array($localpart . 'c', $this->contact_id, $this->id, $this->hash)) . "@{$emailDomain}";
     require_once 'CRM/Contact/BAO/Group.php';
     $group = new CRM_Contact_BAO_Group();
     $group->id = $this->group_id;
     $group->find(true);
     require_once 'CRM/Mailing/BAO/Component.php';
     $component = new CRM_Mailing_BAO_Component();
     $component->is_default = 1;
     $component->is_active = 1;
     $component->component_type = 'Subscribe';
     $component->find(true);
     $headers = array('Subject' => $component->subject, 'From' => "\"{$domainEmailName}\" <{$domainEmailAddress}>", 'To' => $email, 'Reply-To' => $confirm, 'Return-Path' => "do-not-reply@{$emailDomain}");
     $url = CRM_Utils_System::url('civicrm/mailing/confirm', "reset=1&cid={$this->contact_id}&sid={$this->id}&h={$this->hash}", true);
     $html = $component->body_html;
     if ($component->body_text) {
         $text = $component->body_text;
     } else {
         $text = CRM_Utils_String::htmlToText($component->body_html);
     }
     require_once 'CRM/Mailing/BAO/Mailing.php';
     $bao = new CRM_Mailing_BAO_Mailing();
     $bao->body_text = $text;
     $bao->body_html = $html;
     $tokens = $bao->getTokens();
     require_once 'CRM/Utils/Token.php';
     $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, true, $tokens['html']);
     $html = CRM_Utils_Token::replaceSubscribeTokens($html, $group->title, $url, true);
     $text = CRM_Utils_Token::replaceDomainTokens($text, $domain, false, $tokens['text']);
     $text = CRM_Utils_Token::replaceSubscribeTokens($text, $group->title, $url, false);
     // render the &amp; entities in text mode, so that the links work
     $text = str_replace('&amp;', '&', $text);
     $message = new Mail_mime("\n");
     $message->setHTMLBody($html);
     $message->setTxtBody($text);
     $b =& CRM_Utils_Mail::setMimeParams($message);
     $h =& $message->headers($headers);
     $mailer =& $config->getMailer();
     require_once 'CRM/Mailing/BAO/Mailing.php';
     PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array('CRM_Core_Error', 'nullHandler'));
     if (is_object($mailer)) {
         $mailer->send($email, $h, $b);
         CRM_Core_Error::setCallback();
     }
 }
Esempio n. 15
0
 /**
  * Send an automated response
  *
  * @param object $mailing       The mailing object
  * @param int $queue_id         The queue ID
  * @param string $replyto       Optional reply-to from the reply
  * @return void
  * @access private
  * @static
  */
 private static function autoRespond(&$mailing, $queue_id, $replyto)
 {
     $config = CRM_Core_Config::singleton();
     $contacts = CRM_Contact_DAO_Contact::getTableName();
     $email = CRM_Core_DAO_Email::getTableName();
     $queue = CRM_Mailing_Event_DAO_Queue::getTableName();
     $eq = new CRM_Core_DAO();
     $eq->query("SELECT     {$contacts}.preferred_mail_format as format,\n                    {$email}.email as email\n        FROM        {$contacts}\n        INNER JOIN  {$queue} ON {$queue}.contact_id = {$contacts}.id\n        INNER JOIN  {$email} ON {$queue}.email_id = {$email}.id\n        WHERE       {$queue}.id = " . CRM_Utils_Type::escape($queue_id, 'Integer'));
     $eq->fetch();
     $to = empty($replyto) ? $eq->email : $replyto;
     $component = new CRM_Mailing_BAO_Component();
     $component->id = $mailing->reply_id;
     $component->find(true);
     $message = new Mail_Mime("\n");
     require_once 'CRM/Core/BAO/Domain.php';
     $domain =& CRM_Core_BAO_Domain::getDomain();
     list($domainEmailName, $_) = CRM_Core_BAO_Domain::getNameAndEmail();
     require_once 'CRM/Core/BAO/MailSettings.php';
     $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain();
     $headers = array('Subject' => $component->subject, 'To' => $to, 'From' => "\"{$domainEmailName}\" <do-not-reply@{$emailDomain}>", 'Reply-To' => "do-not-reply@{$emailDomain}", 'Return-Path' => "do-not-reply@{$emailDomain}");
     /* TODO: do we need reply tokens? */
     $html = $component->body_html;
     if ($component->body_text) {
         $text = $component->body_text;
     } else {
         $text = CRM_Utils_String::htmlToText($component->body_html);
     }
     require_once 'CRM/Mailing/BAO/Mailing.php';
     $bao = new CRM_Mailing_BAO_Mailing();
     $bao->body_text = $text;
     $bao->body_html = $html;
     $tokens = $bao->getTokens();
     if ($eq->format == 'HTML' || $eq->format == 'Both') {
         require_once 'CRM/Utils/Token.php';
         $html = CRM_Utils_Token::replaceDomainTokens($html, $domain, true, $tokens['html']);
         $html = CRM_Utils_Token::replaceMailingTokens($html, $mailing, null, $tokens['html']);
         $message->setHTMLBody($html);
     }
     if (!$html || $eq->format == 'Text' || $eq->format == 'Both') {
         require_once 'CRM/Utils/Token.php';
         $text = CRM_Utils_Token::replaceDomainTokens($text, $domain, false, $tokens['text']);
         $text = CRM_Utils_Token::replaceMailingTokens($text, $mailing, null, $tokens['text']);
         $message->setTxtBody($text);
     }
     $b =& CRM_Utils_Mail::setMimeParams($message);
     $h =& $message->headers($headers);
     $mailer =& $config->getMailer();
     PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array('CRM_Core_Error', 'nullHandler'));
     if (is_object($mailer)) {
         $mailer->send($to, $h, $b);
         CRM_Core_Error::setCallback();
     }
 }
Esempio n. 16
0
 /**
  * Generate a report.  Fetch event count information, mailing data, and job
  * status.
  *
  * @param int $id       The mailing id to report
  * @return array        Associative array of reporting data
  * @access public
  * @static
  */
 function &report($id)
 {
     $mailing_id = CRM_Utils_Type::escape($id, 'Integer');
     $mailing =& new CRM_Mailing_BAO_Mailing();
     require_once 'CRM/Mailing/Event/BAO/Opened.php';
     require_once 'CRM/Mailing/Event/BAO/Reply.php';
     require_once 'CRM/Mailing/Event/BAO/Unsubscribe.php';
     require_once 'CRM/Mailing/Event/BAO/Forward.php';
     require_once 'CRM/Mailing/Event/BAO/TrackableURLOpen.php';
     $t = array('mailing' => CRM_Mailing_BAO_Mailing::getTableName(), 'mailing_group' => CRM_Mailing_DAO_Group::getTableName(), 'group' => CRM_Contact_BAO_Group::getTableName(), 'job' => CRM_Mailing_BAO_Job::getTableName(), 'queue' => CRM_Mailing_Event_BAO_Queue::getTableName(), 'delivered' => CRM_Mailing_Event_BAO_Delivered::getTableName(), 'opened' => CRM_Mailing_Event_BAO_Opened::getTableName(), 'reply' => CRM_Mailing_Event_BAO_Reply::getTableName(), 'unsubscribe' => CRM_Mailing_Event_BAO_Unsubscribe::getTableName(), 'bounce' => CRM_Mailing_Event_BAO_Bounce::getTableName(), 'forward' => CRM_Mailing_Event_BAO_Forward::getTableName(), 'url' => CRM_Mailing_BAO_TrackableURL::getTableName(), 'urlopen' => CRM_Mailing_Event_BAO_TrackableURLOpen::getTableName(), 'component' => CRM_Mailing_BAO_Component::getTableName());
     $report = array();
     /* FIXME: put some permissioning in here */
     /* Get the mailing info */
     $mailing->query("\n            SELECT          {$t['mailing']}.*\n            FROM            {$t['mailing']}\n            WHERE           {$t['mailing']}.id = {$mailing_id}");
     $mailing->fetch();
     $report['mailing'] = array();
     foreach (array_keys(CRM_Mailing_BAO_Mailing::fields()) as $field) {
         $report['mailing'][$field] = $mailing->{$field};
     }
     /* Get the component info */
     $query = array();
     $components = array('header' => ts('Header'), 'footer' => ts('Footer'), 'reply' => ts('Reply'), 'unsubscribe' => ts('Unsubscribe'), 'optout' => ts('Opt-Out'));
     foreach (array_keys($components) as $type) {
         $query[] = "SELECT          {$t['component']}.name as name,\n                                        '{$type}' as type,\n                                        {$t['component']}.id as id\n                        FROM            {$t['component']}\n                        INNER JOIN      {$t['mailing']}\n                                ON      {$t['mailing']}.{$type}_id =\n                                                {$t['component']}.id\n                        WHERE           {$t['mailing']}.id = {$mailing_id}";
     }
     $q = '(' . implode(') UNION (', $query) . ')';
     $mailing->query($q);
     $report['component'] = array();
     while ($mailing->fetch()) {
         $report['component'][] = array('type' => $components[$mailing->type], 'name' => $mailing->name, 'link' => CRM_Utils_System::url('civicrm/mailing/component', "reset=1&action=update&id={$mailing->id}"));
     }
     /* Get the recipient group info */
     $mailing->query("\n            SELECT          {$t['mailing_group']}.group_type as group_type,\n                            {$t['group']}.id as group_id,\n                            {$t['group']}.name as group_name,\n                            {$t['mailing']}.id as mailing_id,\n                            {$t['mailing']}.name as mailing_name\n            FROM            {$t['mailing_group']}\n            LEFT JOIN       {$t['group']}\n                    ON      {$t['mailing_group']}.entity_id = {$t['group']}.id\n                    AND     {$t['mailing_group']}.entity_table =\n                                                                '{$t['group']}'\n            LEFT JOIN       {$t['mailing']}\n                    ON      {$t['mailing_group']}.entity_id =\n                                                            {$t['mailing']}.id\n                    AND     {$t['mailing_group']}.entity_table =\n                                                            '{$t['mailing']}'\n\n            WHERE           {$t['mailing_group']}.mailing_id = {$mailing_id}\n            ");
     $report['group'] = array('include' => array(), 'exclude' => array());
     while ($mailing->fetch()) {
         $row = array();
         if (isset($mailing->group_id)) {
             $row['id'] = $mailing->group_id;
             $row['name'] = $mailing->group_name;
             $row['link'] = CRM_Utils_System::url('civicrm/group/search', "reset=1&force=1&context=smog&gid={$row['id']}");
         } else {
             $row['id'] = $mailing->mailing_id;
             $row['name'] = $mailing->mailing_name;
             $row['mailing'] = true;
             $row['link'] = CRM_Utils_System::url('civicrm/mailing/report', "mid={$row['id']}");
         }
         if ($mailing->group_type == 'Include') {
             $report['group']['include'][] = $row;
         } else {
             $report['group']['exclude'][] = $row;
         }
     }
     /* Get the event totals, grouped by job (retries) */
     $mailing->query("\n            SELECT          {$t['job']}.*,\n                            COUNT(DISTINCT {$t['queue']}.id) as queue,\n                            COUNT(DISTINCT {$t['delivered']}.id) as delivered,\n                            COUNT(DISTINCT {$t['opened']}.id) as opened,\n                            COUNT(DISTINCT {$t['reply']}.id) as reply,\n                            COUNT(DISTINCT {$t['unsubscribe']}.id) as unsubscribe,\n                            COUNT(DISTINCT {$t['forward']}.id) as forward,\n                            COUNT(DISTINCT {$t['bounce']}.id) as bounce,\n                            COUNT(DISTINCT {$t['urlopen']}.id) as url\n            FROM            {$t['job']}\n            LEFT JOIN       {$t['queue']}\n                    ON      {$t['queue']}.job_id = {$t['job']}.id\n            LEFT JOIN       {$t['opened']}\n                    ON      {$t['opened']}.event_queue_id = {$t['queue']}.id\n            LEFT JOIN       {$t['reply']}\n                    ON      {$t['reply']}.event_queue_id = {$t['queue']}.id\n            LEFT JOIN       {$t['forward']}\n                    ON      {$t['forward']}.event_queue_id = {$t['queue']}.id\n            LEFT JOIN       {$t['unsubscribe']}\n                    ON      {$t['unsubscribe']}.event_queue_id = \n                                {$t['queue']}.id\n            LEFT JOIN       {$t['bounce']}\n                    ON      {$t['bounce']}.event_queue_id = {$t['queue']}.id\n            LEFT JOIN       {$t['delivered']}\n                    ON      {$t['delivered']}.event_queue_id = {$t['queue']}.id\n                    AND     {$t['bounce']}.id IS null\n            LEFT JOIN       {$t['urlopen']}\n                    ON      {$t['urlopen']}.event_queue_id = {$t['queue']}.id\n                    \n            WHERE           {$t['job']}.mailing_id = {$mailing_id}\n            GROUP BY        {$t['job']}.id");
     $report['jobs'] = array();
     $report['event_totals'] = array();
     while ($mailing->fetch()) {
         $row = array();
         foreach (array('queue', 'delivered', 'opened', 'url', 'forward', 'reply', 'unsubscribe', 'bounce') as $field) {
             $row[$field] = $mailing->{$field};
             $report['event_totals'][$field] += $mailing->{$field};
         }
         foreach (array_keys(CRM_Mailing_BAO_Job::fields()) as $field) {
             $row[$field] = $mailing->{$field};
         }
         if ($mailing->queue) {
             $row['delivered_rate'] = 100.0 * $mailing->delivered / $mailing->queue;
             $row['bounce_rate'] = 100.0 * $mailing->bounce / $mailing->queue;
             $row['unsubscribe_rate'] = 100.0 * $mailing->unsubscribe / $mailing->queue;
         } else {
             $row['delivered_rate'] = 0;
             $row['bounce_rate'] = 0;
             $row['unsubscribe_rate'] = 0;
         }
         $row['links'] = array('clicks' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=click&mid={$mailing_id}&jid={$mailing->id}"), 'queue' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=queue&mid={$mailing_id}&jid={$mailing->id}"), 'delivered' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=delivered&mid={$mailing_id}&jid={$mailing->id}"), 'bounce' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=bounce&mid={$mailing_id}&jid={$mailing->id}"), 'unsubscribe' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=unsubscribe&mid={$mailing_id}&jid={$mailing->id}"), 'forward' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=forward&mid={$mailing_id}&jid={$mailing->id}"), 'reply' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=reply&mid={$mailing_id}&jid={$mailing->id}"), 'opened' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=opened&mid={$mailing_id}&jid={$mailing->id}"));
         foreach (array('scheduled_date', 'start_date', 'end_date') as $key) {
             $row[$key] = CRM_Utils_Date::customFormat($row[$key]);
         }
         $report['jobs'][] = $row;
     }
     if ($report['event_totals']['queue']) {
         $report['event_totals']['delivered_rate'] = 100.0 * $report['event_totals']['delivered'] / $report['event_totals']['queue'];
         $report['event_totals']['bounce_rate'] = 100.0 * $report['event_totals']['bounce'] / $report['event_totals']['queue'];
         $report['event_totals']['unsubscribe_rate'] = 100.0 * $report['event_totals']['unsubscribe'] / $report['event_totals']['queue'];
     } else {
         $report['event_totals']['delivered_rate'] = 0;
         $report['event_totals']['bounce_rate'] = 0;
         $report['event_totals']['unsubscribe_rate'] = 0;
     }
     /* Get the click-through totals, grouped by URL */
     $mailing->query("\n            SELECT      {$t['url']}.url,\n                        {$t['url']}.id,\n                        COUNT({$t['urlopen']}.id) as clicks,\n                        COUNT(DISTINCT {$t['queue']}.id) as unique_clicks\n            FROM        {$t['url']}\n            LEFT JOIN   {$t['urlopen']}\n                    ON  {$t['urlopen']}.trackable_url_id = {$t['url']}.id\n            LEFT JOIN  {$t['queue']}\n                    ON  {$t['urlopen']}.event_queue_id = {$t['queue']}.id\n            LEFT JOIN  {$t['job']}\n                    ON  {$t['queue']}.job_id = {$t['job']}.id\n            WHERE       {$t['url']}.mailing_id = {$mailing_id}\n            GROUP BY    {$t['url']}.id");
     $report['click_through'] = array();
     while ($mailing->fetch()) {
         $report['click_through'][] = array('url' => $mailing->url, 'link' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=click&mid={$mailing_id}&uid={$mailing->id}"), 'link_unique' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=click&mid={$mailing_id}&uid={$mailing->id}&distinct=1"), 'clicks' => $mailing->clicks, 'unique' => $mailing->unique_clicks, 'rate' => $report['event_totals']['delivered'] ? 100.0 * $mailing->unique_clicks / $report['event_totals']['delivered'] : 0);
     }
     $report['event_totals']['links'] = array('clicks' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=click&mid={$mailing_id}"), 'clicks_unique' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=click&mid={$mailing_id}&distinct=1"), 'queue' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=queue&mid={$mailing_id}"), 'delivered' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=delivered&mid={$mailing_id}"), 'bounce' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=bounce&mid={$mailing_id}"), 'unsubscribe' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=unsubscribe&mid={$mailing_id}"), 'forward' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=forward&mid={$mailing_id}"), 'reply' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=reply&mid={$mailing_id}"), 'opened' => CRM_Utils_System::url('civicrm/mailing/event', "reset=1&event=opened&mid={$mailing_id}"));
     $report['retry'] = CRM_Utils_System::url('civicrm/mailing/retry', "reset=1&mid={$mailing_id}");
     return $report;
 }