Пример #1
0
 /**
  * Return the proper mail store implementation, based on config settings
  *
  * @param  string $name  name of the settings set from civimail_mail_settings to use (null for default)
  * @return object        mail store implementation for processing CiviMail-bound emails
  */
 function getStore($name = null)
 {
     $dao = new CRM_Core_DAO_MailSettings();
     $dao->domain_id = CRM_Core_Config::domainID();
     $name ? $dao->name = $name : ($dao->is_default = 1);
     if (!$dao->find(true)) {
         throw new Exception("Could not find entry named {$name} in civicrm_mail_settings");
     }
     $protocols =& CRM_Core_PseudoConstant::mailProtocol();
     switch ($protocols[$dao->protocol]) {
         case 'IMAP':
             require_once 'CRM/Mailing/MailStore/Imap.php';
             return new CRM_Mailing_MailStore_Imap($dao->server, $dao->username, $dao->password, (bool) $dao->is_ssl, $dao->source);
         case 'POP3':
             require_once 'CRM/Mailing/MailStore/Pop3.php';
             return new CRM_Mailing_MailStore_Pop3($dao->server, $dao->username, $dao->password, (bool) $dao->is_ssl);
         case 'Maildir':
             require_once 'CRM/Mailing/MailStore/Maildir.php';
             return new CRM_Mailing_MailStore_Maildir($dao->source);
         case 'Localdir':
             require_once 'CRM/Mailing/MailStore/Localdir.php';
             return new CRM_Mailing_MailStore_Localdir($dao->source);
             // DO NOT USE the mbox transport for anything other than testing
             // in particular, it does not clear the mbox afterwards
         // DO NOT USE the mbox transport for anything other than testing
         // in particular, it does not clear the mbox afterwards
         case 'mbox':
             require_once 'CRM/Mailing/MailStore/Mbox.php';
             return new CRM_Mailing_MailStore_Mbox($dao->source);
         default:
             throw new Exception("Unknown protocol {$dao->protocol}");
     }
 }
Пример #2
0
 /**
  * Browse all mail settings.
  *
  * @return void
  */
 public function browse()
 {
     //get all mail settings.
     $allMailSettings = array();
     $mailSetting = new CRM_Core_DAO_MailSettings();
     $allProtocols = CRM_Core_PseudoConstant::get('CRM_Core_DAO_MailSettings', 'protocol');
     //multi-domain support for mail settings. CRM-5244
     $mailSetting->domain_id = CRM_Core_Config::domainID();
     //find all mail settings.
     $mailSetting->find();
     while ($mailSetting->fetch()) {
         //replace protocol value with name
         $mailSetting->protocol = CRM_Utils_Array::value($mailSetting->protocol, $allProtocols);
         CRM_Core_DAO::storeValues($mailSetting, $allMailSettings[$mailSetting->id]);
         //form all action links
         $action = array_sum(array_keys($this->links()));
         // disallow the DELETE action for the default set of settings
         if ($mailSetting->is_default) {
             $action &= ~CRM_Core_Action::DELETE;
         }
         //add action links.
         $allMailSettings[$mailSetting->id]['action'] = CRM_Core_Action::formLink(self::links(), $action, array('id' => $mailSetting->id), ts('more'), FALSE, 'mailSetting.manage.action', 'MailSetting', $mailSetting->id);
     }
     $this->assign('rows', $allMailSettings);
 }
Пример #3
0
 /**
  * Return the proper mail store implementation, based on config settings
  *
  * @param string $name
  *   Name of the settings set from civimail_mail_settings to use (null for default).
  *
  * @throws Exception
  * @return object
  *   mail store implementation for processing CiviMail-bound emails
  */
 public static function getStore($name = NULL)
 {
     $dao = new CRM_Core_DAO_MailSettings();
     $dao->domain_id = CRM_Core_Config::domainID();
     $name ? $dao->name = $name : ($dao->is_default = 1);
     if (!$dao->find(TRUE)) {
         throw new Exception("Could not find entry named {$name} in civicrm_mail_settings");
     }
     $protocols = CRM_Core_PseudoConstant::get('CRM_Core_DAO_MailSettings', 'protocol');
     if (empty($protocols[$dao->protocol])) {
         throw new Exception("Empty mail protocol");
     }
     switch ($protocols[$dao->protocol]) {
         case 'IMAP':
             return new CRM_Mailing_MailStore_Imap($dao->server, $dao->username, $dao->password, (bool) $dao->is_ssl, $dao->source);
         case 'POP3':
             return new CRM_Mailing_MailStore_Pop3($dao->server, $dao->username, $dao->password, (bool) $dao->is_ssl);
         case 'Maildir':
             return new CRM_Mailing_MailStore_Maildir($dao->source);
         case 'Localdir':
             return new CRM_Mailing_MailStore_Localdir($dao->source);
             // DO NOT USE the mbox transport for anything other than testing
             // in particular, it does not clear the mbox afterwards
         // DO NOT USE the mbox transport for anything other than testing
         // in particular, it does not clear the mbox afterwards
         case 'mbox':
             return new CRM_Mailing_MailStore_Mbox($dao->source);
         default:
             throw new Exception("Unknown protocol {$dao->protocol}");
     }
 }
 /**
  * Return the proper mail store implementation, based on config settings
  *
  * @param  string $name  name of the settings set from civimail_mail_settings to use (null for default)
  *
  * @return object        mail store implementation for processing CiviMail-bound emails
  */
 function getStore($name = NULL)
 {
     $dao = new CRM_Core_DAO_MailSettings();
     $dao->domain_id = CRM_Core_Config::domainID();
     $name ? $dao->name = $name : ($dao->is_default = 1);
     if (!$dao->find(TRUE)) {
         throw new Exception("Could not find entry named {$name} in civicrm_mail_settings");
     }
     $protocols = CRM_Core_PseudoConstant::get('CRM_Core_DAO_MailSettings', 'protocol');
     switch ($protocols[$dao->protocol]) {
         case 'IMAP':
             return new CRM_Mailing_MailStore_Imap($dao->server, $dao->username, $dao->password, (bool) $dao->is_ssl, $dao->source);
         case 'POP3':
             return new CRM_Mailing_MailStore_Pop3($dao->server, $dao->username, $dao->password, (bool) $dao->is_ssl);
         case 'Maildir':
             return new CRM_Mailing_MailStore_Maildir($dao->source);
         case 'Localdir':
             return new CRM_Mailing_MailStore_Localdir($dao->source);
             // DO NOT USE the mbox transport for anything other than testing
             // in particular, it does not clear the mbox afterwards
         // DO NOT USE the mbox transport for anything other than testing
         // in particular, it does not clear the mbox afterwards
         case 'mbox':
             return new CRM_Mailing_MailStore_Mbox($dao->source);
         default:
             $class_name = 'CRM_Mailing_MailStore_' . $protocols[$dao->protocol];
             /*
              * Whilst this may seem the logical way to test for the class it will cause errors if it does not exist
              * This is because the autoloader will try and require_once the classname without checking for the existance of the file
              * This still seems the best way to implement this as if this falls back then the app will throw an exception anyway
              * In an ideal world the autoloader would also throw an exception if the file does not exist which could have been caught here
              */
             if (class_exists($class_name)) {
                 return new $class_name($dao->username, $dao->password);
             }
             throw new Exception("Unknown protocol {$dao->protocol}");
     }
 }
Пример #5
0
 /**
  * Process the mailbox for all the settings from civicrm_mail_settings.
  *
  * @param bool|string $civiMail if true, processing is done in CiviMail context, or Activities otherwise.
  */
 public static function process($civiMail = TRUE)
 {
     $dao = new CRM_Core_DAO_MailSettings();
     $dao->domain_id = CRM_Core_Config::domainID();
     $dao->find();
     while ($dao->fetch()) {
         self::_process($civiMail, $dao);
     }
 }
Пример #6
0
 /**
  * Delete the mail settings.
  *
  * @param int $id
  *   Mail settings id.
  *
  * @return mixed|null
  */
 public static function deleteMailSettings($id)
 {
     $results = NULL;
     $transaction = new CRM_Core_Transaction();
     $mailSettings = new CRM_Core_DAO_MailSettings();
     $mailSettings->id = $id;
     $results = $mailSettings->delete();
     $transaction->commit();
     return $results;
 }
Пример #7
0
 /**
  * Returns the list of fields that can be exported
  *
  * @param bool $prefix
  *
  * @return array
  */
 static function &export($prefix = false)
 {
     if (!self::$_export) {
         self::$_export = array();
         $fields = self::fields();
         foreach ($fields as $name => $field) {
             if (CRM_Utils_Array::value('export', $field)) {
                 if ($prefix) {
                     self::$_export['mail_settings'] =& $fields[$name];
                 } else {
                     self::$_export[$name] =& $fields[$name];
                 }
             }
         }
     }
     return self::$_export;
 }
Пример #8
0
 /**
  * Process the mailbox for all the settings from civicrm_mail_settings
  *
  * @param string $civiMail  if true, processing is done in CiviMail context, or Activities otherwise.
  * @return void
  */
 static function process($civiMail = true)
 {
     require_once 'CRM/Core/DAO/MailSettings.php';
     $dao = new CRM_Core_DAO_MailSettings();
     $dao->domain_id = CRM_Core_Config::domainID();
     $dao->find();
     while ($dao->fetch()) {
         EmailProcessor::_process($civiMail, $dao);
     }
 }
Пример #9
0
 /**
  * Process the mailbox defined by the named set of settings from civicrm_mail_settings
  *
  * @param string $name  name of the set of settings from civicrm_mail_settings (null for default set)
  * @return void
  */
 static function process($name = null)
 {
     require_once 'CRM/Core/DAO/MailSettings.php';
     $dao = new CRM_Core_DAO_MailSettings();
     $dao->domain_id = CRM_Core_Config::domainID();
     $name ? $dao->name = $name : ($dao->is_default = 1);
     if (!$dao->find(true)) {
         throw new Exception("Could not find entry named {$name} in civicrm_mail_settings");
     }
     $config =& CRM_Core_Config::singleton();
     $verpSeperator = preg_quote($config->verpSeparator);
     $twoDigitStringMin = $verpSeperator . '(\\d+)' . $verpSeperator . '(\\d+)';
     $twoDigitString = $twoDigitStringMin . $verpSeperator;
     $threeDigitString = $twoDigitString . '(\\d+)' . $verpSeperator;
     // FIXME: legacy regexen to handle CiviCRM 2.1 address patterns, with domain id and possible VERP part
     $commonRegex = '/^' . preg_quote($dao->localpart) . '(b|bounce|c|confirm|o|optOut|r|reply|re|e|resubscribe|u|unsubscribe)' . $threeDigitString . '([0-9a-f]{16})(-.*)?@' . preg_quote($dao->domain) . '$/';
     $subscrRegex = '/^' . preg_quote($dao->localpart) . '(s|subscribe)' . $twoDigitStringMin . '@' . preg_quote($dao->domain) . '$/';
     // a common-for-all-actions regex to handle CiviCRM 2.2 address patterns
     $regex = '/^' . preg_quote($dao->localpart) . '(b|c|e|o|r|u)' . $twoDigitString . '([0-9a-f]{16})@' . preg_quote($dao->domain) . '$/';
     // a tighter regex for finding bounce info in soft bounces’ mail bodies
     $rpRegex = '/Return-Path: ' . preg_quote($dao->localpart) . '(b)' . $twoDigitString . '([0-9a-f]{16})@' . preg_quote($dao->domain) . '/';
     // retrieve the emails
     require_once 'CRM/Mailing/MailStore.php';
     $store = CRM_Mailing_MailStore::getStore($name);
     require_once 'api/Mailer.php';
     // process fifty at a time, CRM-4002
     while ($mails = $store->fetchNext(50)) {
         foreach ($mails as $key => $mail) {
             // for every addressee: match address elements if it's to CiviMail
             $matches = array();
             foreach ($mail->to as $address) {
                 if (preg_match($regex, $address->email, $matches)) {
                     list($match, $action, $job, $queue, $hash) = $matches;
                     break;
                     // FIXME: the below elseifs should be dropped when we drop legacy support
                 } elseif (preg_match($commonRegex, $address->email, $matches)) {
                     list($match, $action, $_, $job, $queue, $hash) = $matches;
                     break;
                 } elseif (preg_match($subscrRegex, $address->email, $matches)) {
                     list($match, $action, $_, $job) = $matches;
                     break;
                 }
             }
             // CRM-5471: if $matches is empty, it still might be a soft bounce sent
             // to another address, so scan the body for ‘Return-Path: …bounce-pattern…’
             if (!$matches and preg_match($rpRegex, $mail->generateBody(), $matches)) {
                 list($match, $action, $job, $queue, $hash) = $matches;
             }
             // if $matches is empty, this email is not CiviMail-bound
             if (!$matches) {
                 $store->markIgnored($key);
                 continue;
             }
             // get $replyTo from either the Reply-To header or from From
             // FIXME: make sure it works with Reply-Tos containing non-email stuff
             $replyTo = $mail->getHeader('Reply-To') ? $mail->getHeader('Reply-To') : $mail->from->email;
             // handle the action by passing it to the proper API call
             // FIXME: leave only one-letter cases when dropping legacy support
             switch ($action) {
                 case 'b':
                 case 'bounce':
                     $text = '';
                     if ($mail->body instanceof ezcMailText) {
                         $text = $mail->body->text;
                     } elseif ($mail->body instanceof ezcMailMultipart) {
                         if ($mail->body instanceof ezcMailMultipartRelated) {
                             foreach ($mail->body->getRelatedParts() as $part) {
                                 if (isset($part->subType) and $part->subType == 'plain') {
                                     $text = $part->text;
                                     break;
                                 }
                             }
                         } else {
                             foreach ($mail->body->getParts() as $part) {
                                 if (isset($part->subType) and $part->subType == 'plain') {
                                     $text = $part->text;
                                     break;
                                 }
                             }
                         }
                     }
                     crm_mailer_event_bounce($job, $queue, $hash, $text);
                     break;
                 case 'c':
                 case 'confirm':
                     crm_mailer_event_confirm($job, $queue, $hash);
                     break;
                 case 'o':
                 case 'optOut':
                     crm_mailer_event_domain_unsubscribe($job, $queue, $hash);
                     break;
                 case 'r':
                 case 'reply':
                     // instead of text and HTML parts (4th and 6th params) send the whole email as the last param
                     crm_mailer_event_reply($job, $queue, $hash, null, $replyTo, null, $mail->generate());
                     break;
                 case 'e':
                 case 're':
                 case 'resubscribe':
                     crm_mailer_event_resubscribe($job, $queue, $hash);
                     break;
                 case 's':
                 case 'subscribe':
                     crm_mailer_event_subscribe($mail->from->email, $job);
                     break;
                 case 'u':
                 case 'unsubscribe':
                     crm_mailer_event_unsubscribe($job, $queue, $hash);
                     break;
             }
             $store->markProcessed($key);
         }
     }
 }
Пример #10
0
 /**
  * Function to delete the mail settings.
  *
  * @param int $id mail settings id
  *
  * @access public
  * @static
  *
  */
 static function deleteMailSettings($id)
 {
     $results = null;
     require_once 'CRM/Core/Transaction.php';
     $transaction = new CRM_Core_Transaction();
     $mailSettings = new CRM_Core_DAO_MailSettings();
     $mailSettings->id = $id;
     $results = $mailSettings->delete();
     $transaction->commit();
     return $results;
 }
Пример #11
0
 /**
  * Process the mailbox for all the settings from civicrm_mail_settings
  *
  * @param string $civiMail  if true, processing is done in CiviMail context, or Activities otherwise.
  * @return void
  */
 static function process($civiMail = true)
 {
     require_once 'CRM/Core/OptionGroup.php';
     $emailActivityTypeId = defined('EMAIL_ACTIVITY_TYPE_ID') && EMAIL_ACTIVITY_TYPE_ID ? EMAIL_ACTIVITY_TYPE_ID : CRM_Core_OptionGroup::getValue('activity_type', 'Inbound Email', 'name');
     if (!$emailActivityTypeId) {
         CRM_Core_Error::fatal(ts('Could not find a valid Activity Type ID for Inbound Email'));
     }
     require_once 'CRM/Core/DAO/MailSettings.php';
     $dao = new CRM_Core_DAO_MailSettings();
     $dao->domain_id = CRM_Core_Config::domainID();
     $dao->find();
     while ($dao->fetch()) {
         // FIXME: legacy regexen to handle CiviCRM 2.1 address patterns, with domain id and possible VERP part
         $commonRegex = '/^' . preg_quote($dao->localpart) . '(b|bounce|c|confirm|o|optOut|r|reply|re|e|resubscribe|u|unsubscribe)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\.([0-9a-f]{16})(-.*)?@' . preg_quote($dao->domain) . '$/';
         $subscrRegex = '/^' . preg_quote($dao->localpart) . '(s|subscribe)\\.(\\d+)\\.(\\d+)@' . preg_quote($dao->domain) . '$/';
         // a common-for-all-actions regex to handle CiviCRM 2.2 address patterns
         $regex = '/^' . preg_quote($dao->localpart) . '(b|c|e|o|r|u)\\.(\\d+)\\.(\\d+)\\.([0-9a-f]{16})@' . preg_quote($dao->domain) . '$/';
         // retrieve the emails
         require_once 'CRM/Mailing/MailStore.php';
         $store = CRM_Mailing_MailStore::getStore($dao->name);
         require_once 'api/Mailer.php';
         // process fifty at a time, CRM-4002
         while ($mails = $store->fetchNext(MAIL_BATCH_SIZE)) {
             foreach ($mails as $key => $mail) {
                 // for every addressee: match address elements if it's to CiviMail
                 $matches = array();
                 if ($civiMail) {
                     foreach ($mail->to as $address) {
                         if (preg_match($regex, $address->email, $matches)) {
                             list($match, $action, $job, $queue, $hash) = $matches;
                             break;
                             // FIXME: the below elseifs should be dropped when we drop legacy support
                         } elseif (preg_match($commonRegex, $address->email, $matches)) {
                             list($match, $action, $_, $job, $queue, $hash) = $matches;
                             break;
                         } elseif (preg_match($subscrRegex, $address->email, $matches)) {
                             list($match, $action, $_, $job) = $matches;
                             break;
                         }
                     }
                 } else {
                     // if its the activities that needs to be processed ..
                     require_once 'CRM/Utils/Mail/Incoming.php';
                     $mailParams = CRM_Utils_Mail_Incoming::parseMailingObject($mail);
                     require_once 'api/v2/Activity.php';
                     $params = _civicrm_activity_buildmailparams($mailParams, $emailActivityTypeId);
                     $result = civicrm_activity_create($params);
                     if ($result['is_error']) {
                         $matches = false;
                         echo "Failed Processing: {$mail->subject}. Reason: {$result['error_message']}\n";
                     } else {
                         $matches = true;
                         echo "Processed: {$mail->subject}\n";
                     }
                 }
                 // if $matches is empty, this email is not CiviMail-bound
                 if (!$matches) {
                     $store->markIgnored($key);
                     continue;
                 }
                 // get $replyTo from either the Reply-To header or from From
                 // FIXME: make sure it works with Reply-Tos containing non-email stuff
                 $replyTo = $mail->getHeader('Reply-To') ? $mail->getHeader('Reply-To') : $mail->from->email;
                 // handle the action by passing it to the proper API call
                 // FIXME: leave only one-letter cases when dropping legacy support
                 if (!empty($action)) {
                     switch ($action) {
                         case 'b':
                         case 'bounce':
                             $text = '';
                             if ($mail->body instanceof ezcMailText) {
                                 $text = $mail->body->text;
                             } elseif ($mail->body instanceof ezcMailMultipart) {
                                 foreach ($mail->body->getParts() as $part) {
                                     if (isset($part->subType) and $part->subType == 'plain') {
                                         $text = $part->text;
                                         break;
                                     }
                                 }
                             }
                             crm_mailer_event_bounce($job, $queue, $hash, $text);
                             break;
                         case 'c':
                         case 'confirm':
                             crm_mailer_event_confirm($job, $queue, $hash);
                             break;
                         case 'o':
                         case 'optOut':
                             crm_mailer_event_domain_unsubscribe($job, $queue, $hash);
                             break;
                         case 'r':
                         case 'reply':
                             // instead of text and HTML parts (4th and 6th params) send the whole email as the last param
                             crm_mailer_event_reply($job, $queue, $hash, null, $replyTo, null, $mail->generate());
                             break;
                         case 'e':
                         case 're':
                         case 'resubscribe':
                             crm_mailer_event_resubscribe($job, $queue, $hash);
                             break;
                         case 's':
                         case 'subscribe':
                             crm_mailer_event_subscribe($mail->from->email, $job);
                             break;
                         case 'u':
                         case 'unsubscribe':
                             crm_mailer_event_unsubscribe($job, $queue, $hash);
                             break;
                     }
                 }
                 $store->markProcessed($key);
             }
         }
     }
 }