/** * 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; }
/** * Send a reponse 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 * @return void * @access public * @static */ public static function send_unsub_response($queue_id, $groups, $is_domain = false, $job) { $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(); 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(); 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::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); } 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(); } }
/** * Function for validation * * @param array $params (ref.) an assoc array of name/value pairs * * @param $files * @param $self * * @return mixed true or array of errors * @access public * @static */ static function formRule($params, $files, $self) { if (!empty($_POST['_qf_Import_refresh'])) { return TRUE; } $errors = array(); $template = CRM_Core_Smarty::singleton(); $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]++; } $skipTextFile = $self->get('skipTextFile'); if (!$params['upload_type']) { if (!isset($files['textFile']) || !file_exists($files['textFile']['tmp_name'])) { if (!$skipTextFile) { $errors['textFile'] = ts('Please provide a Text'); } } } else { if (empty($params['text_message'])) { $errors['text_message'] = ts('Please provide a Text'); } else { if (!empty($params['text_message'])) { $messageCheck = CRM_Utils_Array::value('text_message', $params); if ($messageCheck && strlen($messageCheck) > CRM_SMS_Provider::MAX_SMS_CHAR) { $errors['text_message'] = ts("You can configure the SMS message body up to %1 characters", array(1 => CRM_SMS_Provider::MAX_SMS_CHAR)); } } } if (!empty($params['saveTemplate']) && empty($params['saveTemplateName'])) { $errors['saveTemplateName'] = ts('Please provide a Template Name.'); } } if ($params['upload_type'] || file_exists(CRM_Utils_Array::value('tmp_name', $files['textFile'])) || !$params['upload_type'] && $params['text_message']) { if (!$params['upload_type']) { $str = file_get_contents($files['textFile']['tmp_name']); $name = $files['textFile']['name']; } else { $str = $params['text_message']; $name = 'text message'; } $dataErrors = array(); /* 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_text"; $dummy_mail->{$mess} = $str; $tokens = $dummy_mail->getTokens(); $str = CRM_Utils_Token::replaceSubscribeInviteTokens($str); $str = CRM_Utils_Token::replaceDomainTokens($str, $domain, NULL, $tokens['text']); $str = CRM_Utils_Token::replaceMailingTokens($str, $mailing, NULL, $tokens['text']); $str = CRM_Utils_Token::replaceOrgTokens($str, $org); $str = CRM_Utils_Token::replaceActionTokens($str, $verp, $urls, NULL, $tokens['text']); $str = CRM_Utils_Token::replaceContactTokens($str, $contact, NULL, $tokens['text']); $unmatched = CRM_Utils_Token::unmatchedTokens($str); $contentCheck = CRM_Utils_String::htmlToText($str); if (!empty($unmatched) && 0) { foreach ($unmatched as $token) { $dataErrors[] = '<li>' . ts('Invalid token code') . ' {' . $token . '}</li>'; } } if (strlen($contentCheck) > CRM_SMS_Provider::MAX_SMS_CHAR) { $dataErrors[] = '<li>' . ts('The body of the SMS cannot exceed %1 characters.', array(1 => CRM_SMS_Provider::MAX_SMS_CHAR)) . '</li>'; } if (!empty($dataErrors)) { $errors['textFile'] = ts('The following errors were detected in %1:', array(1 => $name)) . ' <ul>' . implode('', $dataErrors) . '</ul>'; } } $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 mailing object and replaces subscribeInvite, * domain and mailing tokens */ public static function tokenReplace(&$mailing) { $domain = CRM_Core_BAO_Domain::getDomain(); foreach (array('text', 'html') as $type) { $tokens = $mailing->getTokens(); if (isset($mailing->templates[$type])) { $mailing->templates[$type] = CRM_Utils_Token::replaceSubscribeInviteTokens($mailing->templates[$type]); $mailing->templates[$type] = CRM_Utils_Token::replaceDomainTokens($mailing->templates[$type], $domain, $type == 'html' ? TRUE : FALSE, $tokens[$type]); $mailing->templates[$type] = CRM_Utils_Token::replaceMailingTokens($mailing->templates[$type], $mailing, NULL, $tokens[$type]); } } }
/** * 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; }
/** * 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); } }
/** * 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); } }
/** * * get mailing object and replaces subscribeInvite, * domain and mailing tokens * */ function tokenReplace(&$mailing) { require_once 'CRM/Core/BAO/Domain.php'; $domain =& CRM_Core_BAO_Domain::getDomain(); foreach (array('text', 'html') as $type) { require_once 'CRM/Utils/Token.php'; $tokens = $mailing->getTokens(); if (isset($mailing->templates[$type])) { $mailing->templates[$type] = CRM_Utils_Token::replaceSubscribeInviteTokens($mailing->templates[$type]); $mailing->templates[$type] = CRM_Utils_Token::replaceDomainTokens($mailing->templates[$type], $domain, $type == 'html' ? true : false, $tokens[$type]); $mailing->templates[$type] = CRM_Utils_Token::replaceMailingTokens($mailing->templates[$type], $mailing, null, $tokens[$type]); } } }
/** * 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(); } }
/** * Function for validation * * @param array $params (ref.) an assoc array of name/value pairs * * @return mixed true or array of errors * @access public * @static */ function dataRule(&$params, &$files, &$options) { if (CRM_Utils_Array::value('_qf_Import_refresh', $_POST)) { return true; } $errors = array(); require_once 'CRM/Core/BAO/Domain.php'; $domain =& CRM_Core_BAO_Domain::getCurrentDomain(); $mailing = null; $session =& CRM_Core_Session::singleton(); $values = array('contact_id' => $session->get('userID')); $contact = array(); $ids = array(); CRM_Contact_BAO_Contact::retrieve($values, $contact, $id); $verp = array_flip(array('optOut', 'reply', 'unsubscribe', 'owner')); foreach ($verp as $key => $value) { $verp[$key]++; } $urls = array_flip(array('forward')); foreach ($urls as $key => $value) { $urls[$key]++; } require_once 'CRM/Mailing/BAO/Component.php'; $header =& new CRM_Mailing_BAO_Component(); $header->id = $params['header_id']; $header->find(true); $footer =& new CRM_Mailing_BAO_Component(); $footer->id = $params['footer_id']; $footer->find(true); list($headerBody['htmlFile'], $headerBody['textFile']) = array($header->body_html, $header->body_text); list($footerBody['htmlFile'], $footerBody['textFile']) = array($footer->body_html, $footer->body_text); require_once 'CRM/Utils/Token.php'; if (!file_exists($files['textFile']['tmp_name'])) { $errors['textFile'] = ts('Please provide at least the text message.'); } foreach (array('textFile', 'htmlFile') as $file) { if (!file_exists($files[$file]['tmp_name'])) { continue; } $str = file_get_contents($files[$file]['tmp_name']); $name = $files[$file]['name']; /* append header/footer */ $str = $headerBody[$file] . $str . $footerBody[$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('Missing required token') . ' {' . $token . "}: {$desc}</li>"; } } /* Do a full token replacement on a dummy verp, the current contact * and domain. */ $str = CRM_Utils_Token::replaceDomainTokens($str, $domain); $str = CRM_Utils_Token::replaceMailingTokens($str, $mailing); $str = CRM_Utils_Token::replaceActionTokens($str, $verp, $urls); $str = CRM_Utils_Token::replaceContactTokens($str, $contact); $unmatched = CRM_Utils_Token::unmatchedTokens($str); if (!empty($unmatched)) { foreach ($unmatched as $token) { $dataErrors[] = '<li>' . ts('Invalid token code') . ' {' . $token . '}</li>'; } } if (!empty($dataErrors)) { $errors[$file] = ts('The following errors were detected in %1:', array(1 => $name)) . ': <ul>' . implode('', $dataErrors) . '</ul>'; } } return empty($errors) ? true : $errors; }
/** * Compose a message * * @param int $job_id ID of the Job associated with this message * @param int $event_queue_id ID of the EventQueue * @param string $hash Hash of the EventQueue * @param string $contactId ID of the Contact * @param string $email Destination address * @param string $recipient To: of the recipient * @param boolean $test Is this mailing a test? * @return object The mail object * @access public */ function &compose($job_id, $event_queue_id, $hash, $contactId, $email, &$recipient, $test = false) { if ($test) { $job_id = 'JOB'; $event_queue_id = 'QUEUE'; $hash = 'HASH'; } if ($this->_domain == null) { require_once 'CRM/Core/BAO/Domain.php'; $this->_domain =& CRM_Core_BAO_Domain::getDomainByID($this->domain_id); } /** * Inbound VERP keys: * reply: user replied to mailing * bounce: email address bounced * unsubscribe: contact opts out of all target lists for the mailing * optOut: contact unsubscribes from the domain */ $config =& CRM_Core_Config::singleton(); foreach (array('reply', 'bounce', 'unsubscribe', 'optOut') as $key) { $verp[$key] = implode($config->verpSeparator, array($key, $job_id, $event_queue_id, $hash)) . '@' . $this->_domain->email_domain; } $urls = array('forward' => CRM_Utils_System::url('civicrm/mailing/forward', "reset=1&jid={$job_id}&qid={$event_queue_id}&h={$hash}", true)); $headers = array('Reply-To' => CRM_Utils_Verp::encode($verp['reply'], $email), 'Return-Path' => CRM_Utils_Verp::encode($verp['bounce'], $email), 'From' => "\"{$this->from_name}\" <{$this->from_email}>", 'Subject' => $this->subject); require_once 'CRM/Utils/Token.php'; if ($this->html == null || $this->text == null) { $this->getHeaderFooter(); if ($this->body_html) { $this->html = $this->header->body_html . '<br />' . $this->body_html . '<br />' . $this->footer->body_html; $this->html = CRM_Utils_Token::replaceDomainTokens($this->html, $this->_domain, true); $this->html = CRM_Utils_Token::replaceMailingTokens($this->html, $this, true); } $this->text = $this->header->body_text . "\n" . $this->body_text . "\n" . $this->footer->body_text; $this->text = CRM_Utils_Token::replaceDomainTokens($this->text, $this->_domain, false); $this->text = CRM_Utils_Token::replaceMailingTokens($this->text, $this, true); } $html = $this->html; $text = $this->text; if ($html && !$test && $this->url_tracking) { CRM_Mailing_BAO_TrackableURL::scan_and_replace($html, $this->id, $event_queue_id); CRM_Mailing_BAO_TrackableURL::scan_and_replace($text, $this->id, $event_queue_id); } $params = array('contact_id' => $contactId, 'id' => $contactId); $contact = array(); $ids = array(); CRM_Contact_BAO_Contact::retrieve($params, $contact, $ids); $message =& new Mail_Mime("\n"); /* Do contact-specific token replacement in text mode, and add to the * message if necessary */ if ($test || !$html || $contact['preferred_mail_format'] == 'Text' || $contact['preferred_mail_format'] == 'Both') { $text = CRM_Utils_Token::replaceContactTokens($text, $contact, false); $text = CRM_Utils_Token::replaceActionTokens($text, $verp, $urls, false); // render the & entities in text mode, so that the links work $text = str_replace('&', '&', $text); $message->setTxtBody($text); } /* Do contact-specific token replacement in html mode, and add to the * message if necessary */ if ($html && ($test || $contact['preferred_mail_format'] == 'HTML' || $contact['preferred_mail_format'] == 'Both')) { $html = CRM_Utils_Token::replaceContactTokens($html, $contact, true); $html = CRM_Utils_Token::replaceActionTokens($html, $verp, $urls, true); if ($this->open_tracking) { $html .= '<img src="' . $config->userFrameworkResourceURL . "extern/open.php?q={$event_queue_id}\" width='1' height='1' alt='' border='0'>"; } $message->setHTMLBody($html); } $recipient = "\"{$contact['display_name']}\" <{$email}>"; $headers['To'] = $recipient; $mailMimeParams = array('text_encoding' => '8bit', 'html_encoding' => '8bit', 'head_charset' => 'utf-8', 'text_charset' => 'utf-8', 'html_charset' => 'utf-8'); $message->get($mailMimeParams); $message->headers($headers); return $message; }