Example #1
0
 /**
  * Form rule to send out a test mailing.
  *
  * @param aray $testParams
  * @param array $files
  *   Any files posted to the form.
  * @param array $self
  *   An current this object.
  *
  * @return bool
  *   true on successful SMTP handoff
  */
 public static function testMail($testParams, $files, $self)
 {
     $error = NULL;
     $urlString = 'civicrm/mailing/send';
     $urlParams = "_qf_Test_display=true&qfKey={$testParams['qfKey']}";
     $ssID = $self->get('ssID');
     if ($ssID && $self->_searchBasedMailing) {
         if ($self->_action == CRM_Core_Action::BASIC) {
             $fragment = 'search';
         } elseif ($self->_action == CRM_Core_Action::PROFILE) {
             $fragment = 'search/builder';
         } elseif ($self->_action == CRM_Core_Action::ADVANCED) {
             $fragment = 'search/advanced';
         } else {
             $fragment = 'search/custom';
         }
         $urlString = 'civicrm/contact/' . $fragment;
     }
     $emails = NULL;
     if (!empty($testParams['sendtest'])) {
         if (!($testParams['test_group'] || $testParams['test_email'])) {
             CRM_Core_Session::setStatus(ts('You did not provide an email address or select a group.'), ts('Test not sent.'), 'error');
             $error = TRUE;
         }
         if ($testParams['test_email']) {
             $emailAdd = explode(',', $testParams['test_email']);
             foreach ($emailAdd as $key => $value) {
                 $email = trim($value);
                 $testParams['emails'][] = $email;
                 $emails .= ($emails ? ',' : '') . "'" . CRM_Core_DAO::escapeString($email) . "'";
                 if (!CRM_Utils_Rule::email($email)) {
                     CRM_Core_Session::setStatus(ts('Please enter a valid email address.'), ts('Test not sent.'), 'error');
                     $error = TRUE;
                 }
             }
         }
         if ($error) {
             $url = CRM_Utils_System::url($urlString, $urlParams);
             CRM_Utils_System::redirect($url);
             return $error;
         }
     }
     if (!empty($testParams['_qf_Test_submit'])) {
         //when user perform mailing from search context
         //redirect it to search result CRM-3711.
         if ($ssID && $self->_searchBasedMailing) {
             $draftURL = CRM_Utils_System::url('civicrm/mailing/browse/unscheduled', 'scheduled=false&reset=1');
             $status = ts("You can continue later by clicking the 'Continue' action to resume working on it.<br />From <a href='%1'>Draft and Unscheduled Mailings</a>.", array(1 => $draftURL));
             //replace user context to search.
             $context = $self->get('context');
             if (!CRM_Contact_Form_Search::isSearchContext($context)) {
                 $context = 'search';
             }
             $urlParams = "force=1&reset=1&ssID={$ssID}&context={$context}&qfKey={$testParams['qfKey']}";
             $url = CRM_Utils_System::url($urlString, $urlParams);
         } else {
             $status = ts("Click the 'Continue' action to resume working on it.");
             $url = CRM_Utils_System::url('civicrm/mailing/browse/unscheduled', 'scheduled=false&reset=1');
         }
         CRM_Core_Session::setStatus($status, ts('Mailing Saved'), 'success');
         CRM_Utils_System::redirect($url);
     }
     if (CRM_Mailing_Info::workflowEnabled()) {
         if (!CRM_Core_Permission::check('schedule mailings') && CRM_Core_Permission::check('create mailings')) {
             $url = CRM_Utils_System::url('civicrm/mailing/browse/unscheduled', 'scheduled=false&reset=1');
             CRM_Utils_System::redirect($url);
         }
     }
     if (!empty($testParams['_qf_Test_next']) && $self->get('count') <= 0) {
         return array('_qf_default' => ts("You can not schedule or send this mailing because there are currently no recipients selected. Click 'Previous' to return to the Select Recipients step, OR click 'Save & Continue Later'."));
     }
     if (!empty($_POST['_qf_Import_refresh']) || !empty($testParams['_qf_Test_next']) || empty($testParams['sendtest'])) {
         $error = TRUE;
         return $error;
     }
     $job = new CRM_Mailing_BAO_MailingJob();
     $job->mailing_id = $self->get('mailing_id');
     $job->is_test = TRUE;
     $job->save();
     $newEmails = NULL;
     $session = CRM_Core_Session::singleton();
     if (!empty($testParams['emails'])) {
         $query = "\nSELECT     e.id, e.contact_id, e.email\nFROM       civicrm_email e\nINNER JOIN civicrm_contact c ON e.contact_id = c.id\nWHERE      e.email IN ({$emails})\nAND        e.on_hold = 0\nAND        c.is_opt_out = 0\nAND        c.do_not_email = 0\nAND        c.is_deleted = 0\nAND        c.is_deceased = 0\nGROUP BY   e.id\nORDER BY   e.is_bulkmail DESC, e.is_primary DESC\n";
         $dao = CRM_Core_DAO::executeQuery($query);
         $emailDetail = array();
         // fetch contact_id and email id for all existing emails
         while ($dao->fetch()) {
             $emailDetail[$dao->email] = array('contact_id' => $dao->contact_id, 'email_id' => $dao->id);
         }
         $dao->free();
         foreach ($testParams['emails'] as $key => $email) {
             // Email addresses are forced to lower case when saved, so ensure
             // we have the same case when comparing.
             $email = trim(strtolower($email));
             $contactId = $emailId = NULL;
             if (array_key_exists($email, $emailDetail)) {
                 $emailId = $emailDetail[$email]['email_id'];
                 $contactId = $emailDetail[$email]['contact_id'];
             }
             if (!$contactId) {
                 //create new contact.
                 $params = array('contact_type' => 'Individual', 'email' => array(1 => array('email' => $email, 'is_primary' => 1, 'location_type_id' => 1)));
                 $contact = CRM_Contact_BAO_Contact::create($params);
                 $emailId = $contact->email[0]->id;
                 $contactId = $contact->id;
                 $contact->free();
             }
             $params = array('job_id' => $job->id, 'email_id' => $emailId, 'contact_id' => $contactId);
             CRM_Mailing_Event_BAO_Queue::create($params);
         }
     }
     $testParams['job_id'] = $job->id;
     $isComplete = FALSE;
     while (!$isComplete) {
         $isComplete = CRM_Mailing_BAO_MailingJob::runJobs($testParams);
     }
     if (!empty($testParams['sendtest'])) {
         $status = NULL;
         if (CRM_Mailing_Info::workflowEnabled()) {
             if (CRM_Core_Permission::check('schedule mailings') && CRM_Core_Permission::check('create mailings') || CRM_Core_Permission::check('access CiviMail')) {
                 $status = ts("Click 'Next' when you are ready to Schedule or Send your live mailing (you will still have a chance to confirm or cancel sending this mailing on the next page).");
             }
         } else {
             $status = ts("Click 'Next' when you are ready to Schedule or Send your live mailing (you will still have a chance to confirm or cancel sending this mailing on the next page).");
         }
         if ($status) {
             CRM_Core_Session::setStatus($status, ts('Test message sent'), 'success');
         }
         $url = CRM_Utils_System::url($urlString, $urlParams);
         CRM_Utils_System::redirect($url);
     }
     $error = TRUE;
     return $error;
 }
if (isset($options['h'])) {
    print "\nUsage: php civimail-spooler.php [-bh] [-c <config>] [-t <period>]\n";
    print "   -b  Run this process continuously\n";
    print "   -c  Path to CiviCRM civicrm.settings.php\n";
    print "   -h  Print this help message\n";
    print "   -t  In continuous mode, the period (in seconds) to wait between queue events\n\n";
    exit;
}
if (isset($options['c'])) {
    $config_file = $options['c'];
}
eval('
require_once "$config_file";
require_once "CRM/Core/Config.php";
');
$config =& CRM_Core_Config::singleton();
/* Temporary permissioning hack for now */
CRM_Utils_System_Soap::swapUF();
if (isset($options['t']) && is_int($options['t']) && $options['t'] > 0) {
    $config->mailerPeriod = $options['t'];
}
if (isset($options['b'])) {
    while (TRUE) {
        /* TODO: put some syslog calls in here.  Also, we may want to fork the
         * process into the background and provide init.d scripts */
        CRM_Mailing_BAO_MailingJob::runJobs();
        sleep($config->mailerPeriod);
    }
} else {
    CRM_Mailing_BAO_MailingJob::runJobs();
}
 /**
  * @param null $mode
  *
  * @return bool
  * @throws Exception
  */
 public static function processQueue($mode = NULL)
 {
     $config = CRM_Core_Config::singleton();
     if ($mode == NULL && CRM_Core_BAO_MailSettings::defaultDomain() == "EXAMPLE.ORG") {
         throw new CRM_Core_Exception(ts('The <a href="%1">default mailbox</a> has not been configured. You will find <a href="%2">more info in the online user and administrator guide</a>', array(1 => CRM_Utils_System::url('civicrm/admin/mailSettings', 'reset=1'), 2 => "http://book.civicrm.org/user/advanced-configuration/email-system-configuration/")));
     }
     // check if we are enforcing number of parallel cron jobs
     // CRM-8460
     $gotCronLock = FALSE;
     if (property_exists($config, 'mailerJobsMax') && $config->mailerJobsMax && $config->mailerJobsMax > 0) {
         $lockArray = range(1, $config->mailerJobsMax);
         shuffle($lockArray);
         // check if we are using global locks
         foreach ($lockArray as $lockID) {
             $cronLock = Civi\Core\Container::singleton()->get('lockManager')->acquire("worker.mailing.send.{$lockID}");
             if ($cronLock->isAcquired()) {
                 $gotCronLock = TRUE;
                 break;
             }
         }
         // exit here since we have enuf cronjobs running
         if (!$gotCronLock) {
             CRM_Core_Error::debug_log_message('Returning early, since max number of cronjobs running');
             return TRUE;
         }
         if (getenv('CIVICRM_CRON_HOLD')) {
             // In testing, we may need to simulate some slow activities.
             sleep(getenv('CIVICRM_CRON_HOLD'));
         }
     }
     // load bootstrap to call hooks
     // Split up the parent jobs into multiple child jobs
     $mailerJobSize = property_exists($config, 'mailerJobSize') ? $config->mailerJobSize : NULL;
     CRM_Mailing_BAO_MailingJob::runJobs_pre($mailerJobSize, $mode);
     CRM_Mailing_BAO_MailingJob::runJobs(NULL, $mode);
     CRM_Mailing_BAO_MailingJob::runJobs_post($mode);
     // lets release the global cron lock if we do have one
     if ($gotCronLock) {
         $cronLock->release();
     }
     return TRUE;
 }
Example #4
0
/**
 * Send test mailing.
 *
 * @param array $params
 *
 * @return array
 * @throws \API_Exception
 * @throws \CiviCRM_API3_Exception
 */
function civicrm_api3_mailing_send_test($params)
{
    if (!array_key_exists('test_group', $params) && !array_key_exists('test_email', $params)) {
        throw new API_Exception("Mandatory key(s) missing from params array: test_group and/or test_email field are required");
    }
    civicrm_api3_verify_mandatory($params, 'CRM_Mailing_DAO_MailingJob', array('mailing_id'), FALSE);
    $testEmailParams = _civicrm_api3_generic_replace_base_params($params);
    $testEmailParams['is_test'] = 1;
    $job = civicrm_api3('MailingJob', 'create', $testEmailParams);
    $testEmailParams['job_id'] = $job['id'];
    $testEmailParams['emails'] = explode(',', $testEmailParams['test_email']);
    if (!empty($params['test_email'])) {
        $query = CRM_Utils_SQL_Select::from('civicrm_email e')->select(array('e.id', 'e.contact_id', 'e.email'))->join('c', 'INNER JOIN civicrm_contact c ON e.contact_id = c.id')->where('e.email IN (@emails)', array('@emails' => $testEmailParams['emails']))->where('e.on_hold = 0')->where('c.is_opt_out = 0')->where('c.do_not_email = 0')->where('c.is_deceased = 0')->where('c.is_deleted = 0')->groupBy('e.id')->orderBy(array('e.is_bulkmail DESC', 'e.is_primary DESC'))->toSQL();
        $dao = CRM_Core_DAO::executeQuery($query);
        $emailDetail = array();
        // fetch contact_id and email id for all existing emails
        while ($dao->fetch()) {
            $emailDetail[$dao->email] = array('contact_id' => $dao->contact_id, 'email_id' => $dao->id);
        }
        $dao->free();
        foreach ($testEmailParams['emails'] as $key => $email) {
            $email = trim($email);
            $contactId = $emailId = NULL;
            if (array_key_exists($email, $emailDetail)) {
                $emailId = $emailDetail[$email]['email_id'];
                $contactId = $emailDetail[$email]['contact_id'];
            }
            if (!$contactId) {
                //create new contact.
                $contact = civicrm_api3('Contact', 'create', array('contact_type' => 'Individual', 'email' => $email, 'api.Email.get' => array('return' => 'id')));
                $contactId = $contact['id'];
                $emailId = $contact['values'][$contactId]['api.Email.get']['id'];
            }
            civicrm_api3('MailingEventQueue', 'create', array('job_id' => $job['id'], 'email_id' => $emailId, 'contact_id' => $contactId));
        }
    }
    $isComplete = FALSE;
    $config = CRM_Core_Config::singleton();
    $mailerJobSize = Civi::settings()->get('mailerJobSize');
    while (!$isComplete) {
        // Q: In CRM_Mailing_BAO_Mailing::processQueue(), the three runJobs*()
        // functions are all called. Why does Mailing.send_test only call one?
        // CRM_Mailing_BAO_MailingJob::runJobs_pre($mailerJobSize, NULL);
        $isComplete = CRM_Mailing_BAO_MailingJob::runJobs($testEmailParams);
        // CRM_Mailing_BAO_MailingJob::runJobs_post(NULL);
    }
    //return delivered mail info
    $mailDelivered = CRM_Mailing_Event_BAO_Delivered::getRows($params['mailing_id'], $job['id'], TRUE, NULL, NULL, NULL, TRUE);
    return civicrm_api3_create_success($mailDelivered);
}
Example #5
0
 /**
  * Run this page (figure out the action needed and perform it).
  */
 public function run()
 {
     $this->preProcess();
     $newArgs = func_get_args();
     // since we want only first function argument
     $newArgs = $newArgs[0];
     if (isset($_GET['runJobs']) || CRM_Utils_Array::value('2', $newArgs) == 'queue') {
         $mailerJobSize = Civi::settings()->get('mailerJobSize');
         CRM_Mailing_BAO_MailingJob::runJobs_pre($mailerJobSize);
         CRM_Mailing_BAO_MailingJob::runJobs();
         CRM_Mailing_BAO_MailingJob::runJobs_post();
     }
     $this->_sortByCharacter = CRM_Utils_Request::retrieve('sortByCharacter', 'String', $this);
     // CRM-11920 all should set sortByCharacter to null, not empty string
     if (strtolower($this->_sortByCharacter) == 'all' || !empty($_POST)) {
         $this->_sortByCharacter = NULL;
         $this->set('sortByCharacter', NULL);
     }
     if (CRM_Utils_Array::value(3, $newArgs) == 'unscheduled') {
         $this->_unscheduled = TRUE;
     }
     $this->set('unscheduled', $this->_unscheduled);
     if (CRM_Utils_Array::value(3, $newArgs) == 'archived') {
         $this->_archived = TRUE;
     }
     $this->set('archived', $this->_archived);
     if (CRM_Utils_Array::value(3, $newArgs) == 'scheduled') {
         $this->_scheduled = TRUE;
     }
     $this->set('scheduled', $this->_scheduled);
     $this->_createdId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE, 0);
     if ($this->_createdId) {
         $this->set('createdId', $this->_createdId);
     }
     if ($this->_sms) {
         $this->set('sms', $this->_sms);
     }
     $session = CRM_Core_Session::singleton();
     $context = $session->readUserContext();
     if ($this->_action & CRM_Core_Action::DISABLE) {
         if (CRM_Utils_Request::retrieve('confirmed', 'Boolean', $this)) {
             CRM_Mailing_BAO_MailingJob::cancel($this->_mailingId);
             CRM_Utils_System::redirect($context);
         } else {
             $controller = new CRM_Core_Controller_Simple('CRM_Mailing_Form_Browse', ts('Cancel Mailing'), $this->_action);
             $controller->setEmbedded(TRUE);
             $controller->run();
         }
     } elseif ($this->_action & CRM_Core_Action::DELETE) {
         if (CRM_Utils_Request::retrieve('confirmed', 'Boolean', $this)) {
             // check for action permissions.
             if (!CRM_Core_Permission::checkActionPermission('CiviMail', $this->_action)) {
                 CRM_Core_Error::fatal(ts('You do not have permission to access this page.'));
             }
             CRM_Mailing_BAO_Mailing::del($this->_mailingId);
             CRM_Utils_System::redirect($context);
         } else {
             $controller = new CRM_Core_Controller_Simple('CRM_Mailing_Form_Browse', ts('Delete Mailing'), $this->_action);
             $controller->setEmbedded(TRUE);
             $controller->run();
         }
     } elseif ($this->_action & CRM_Core_Action::RENEW) {
         // archive this mailing, CRM-3752.
         if (CRM_Utils_Request::retrieve('confirmed', 'Boolean', $this)) {
             // set is_archived to 1
             CRM_Core_DAO::setFieldValue('CRM_Mailing_DAO_Mailing', $this->_mailingId, 'is_archived', TRUE);
             CRM_Utils_System::redirect($context);
         } else {
             $controller = new CRM_Core_Controller_Simple('CRM_Mailing_Form_Browse', ts('Archive Mailing'), $this->_action);
             $controller->setEmbedded(TRUE);
             $controller->run();
         }
     }
     $selector = new CRM_Mailing_Selector_Browse();
     $selector->setParent($this);
     $controller = new CRM_Core_Selector_Controller($selector, $this->get(CRM_Utils_Pager::PAGE_ID), $this->get(CRM_Utils_Sort::SORT_ID) . $this->get(CRM_Utils_Sort::SORT_DIRECTION), CRM_Core_Action::VIEW, $this, CRM_Core_Selector_Controller::TEMPLATE);
     $controller->setEmbedded(TRUE);
     $controller->run();
     // hack to display results as per search
     $rows = $controller->getRows($controller);
     $this->assign('rows', $rows);
     $urlParams = 'reset=1';
     $urlString = 'civicrm/mailing/browse';
     if ($this->get('sms')) {
         $urlParams .= '&sms=1';
     }
     if (CRM_Utils_Array::value(3, $newArgs) == 'unscheduled') {
         $urlString .= '/unscheduled';
         $urlParams .= '&scheduled=false';
         $this->assign('unscheduled', TRUE);
     } elseif (CRM_Utils_Array::value(3, $newArgs) == 'archived') {
         $urlString .= '/archived';
         $this->assign('archived', TRUE);
     } elseif (CRM_Utils_Array::value(3, $newArgs) == 'scheduled') {
         $urlString .= '/scheduled';
         $urlParams .= '&scheduled=true';
     }
     if ($this->get('sms')) {
         CRM_Utils_System::setTitle(ts('Find Mass SMS'));
     }
     $crmRowCount = CRM_Utils_Request::retrieve('crmRowCount', 'Integer', CRM_Core_DAO::$_nullObject);
     $crmPID = CRM_Utils_Request::retrieve('crmPID', 'Integer', CRM_Core_DAO::$_nullObject);
     if ($crmRowCount || $crmPID) {
         $urlParams .= '&force=1';
         $urlParams .= $crmRowCount ? '&crmRowCount=' . $crmRowCount : '';
         $urlParams .= $crmPID ? '&crmPID=' . $crmPID : '';
     }
     $crmSID = CRM_Utils_Request::retrieve('crmSID', 'Integer', CRM_Core_DAO::$_nullObject);
     if ($crmSID) {
         $urlParams .= '&crmSID=' . $crmSID;
     }
     $session = CRM_Core_Session::singleton();
     $url = CRM_Utils_System::url($urlString, $urlParams);
     $session->pushUserContext($url);
     // CRM-6862 -run form cotroller after
     // selector, since it erase $_POST
     $this->search();
     return parent::run();
 }
 /**
  * @param $job
  * @param $groupId
  */
 private static function runTestEmailJobs($job, $groupId = NULL)
 {
     $testJobParams = array();
     $testJobParams['job_id'] = $job->id;
     if ($groupId) {
         $testJobParams['test_group'] = $groupId;
     }
     $isComplete = FALSE;
     while (!$isComplete) {
         $isComplete = CRM_Mailing_BAO_MailingJob::runJobs($testJobParams);
     }
 }
 static function processQueue($mode = NULL)
 {
     $config =& CRM_Core_Config::singleton();
     //   CRM_Core_Error::debug_log_message("Beginning processQueue run: {$config->mailerJobsMax}, {$config->mailerJobSize}");
     if ($mode == NULL && CRM_Core_BAO_MailSettings::defaultDomain() == "EXAMPLE.ORG") {
         CRM_Core_Error::fatal(ts('The <a href="%1">default mailbox</a> has not been configured. You will find <a href="%2">more info in the online user and administrator guide</a>', array(1 => CRM_Utils_System::url('civicrm/admin/mailSettings', 'reset=1'), 2 => "http://book.civicrm.org/user/advanced-configuration/email-system-configuration/")));
     }
     // check if we are enforcing number of parallel cron jobs
     // CRM-8460
     $gotCronLock = FALSE;
     if (property_exists($config, 'mailerJobsMax') && $config->mailerJobsMax && $config->mailerJobsMax > 1) {
         $lockArray = range(1, $config->mailerJobsMax);
         shuffle($lockArray);
         // check if we are using global locks
         $serverWideLock = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, 'civimail_server_wide_lock');
         foreach ($lockArray as $lockID) {
             $cronLock = new CRM_Core_Lock("civimail.cronjob.{$lockID}", NULL, $serverWideLock);
             if ($cronLock->isAcquired()) {
                 $gotCronLock = TRUE;
                 break;
             }
         }
         // exit here since we have enuf cronjobs running
         if (!$gotCronLock) {
             CRM_Core_Error::debug_log_message('Returning early, since max number of cronjobs running');
             return TRUE;
         }
     }
     // load bootstrap to call hooks
     // Split up the parent jobs into multiple child jobs
     $mailerJobSize = property_exists($config, 'mailerJobSize') ? $config->mailerJobSize : NULL;
     CRM_Mailing_BAO_MailingJob::runJobs_pre($mailerJobSize, $mode);
     CRM_Mailing_BAO_MailingJob::runJobs(NULL, $mode);
     CRM_Mailing_BAO_MailingJob::runJobs_post($mode);
     // lets release the global cron lock if we do have one
     if ($gotCronLock) {
         $cronLock->release();
     }
     //   CRM_Core_Error::debug_log_message('Ending processQueue run');
     return TRUE;
 }