From 4aa8f8046cbf703c104feba06a0b0c3d621ddf4c Mon Sep 17 00:00:00 2001 From: Jitendra Purohit Date: Tue, 13 Mar 2018 11:20:56 +0530 Subject: [PATCH] Mail#1 - Add pause/resume functionality to civicrm bulk mailing --- CRM/Mailing/BAO/MailingJob.php | 43 +++++++++++++++++++ CRM/Mailing/Form/Search.php | 2 +- CRM/Mailing/Page/Browse.php | 14 ++++++ CRM/Mailing/Selector/Browse.php | 20 ++++++++- .../phpunit/api/v3/JobProcessMailingTest.php | 28 ++++++++++++ 5 files changed, 105 insertions(+), 2 deletions(-) diff --git a/CRM/Mailing/BAO/MailingJob.php b/CRM/Mailing/BAO/MailingJob.php index 0d49819d64..dc62a1acdb 100644 --- a/CRM/Mailing/BAO/MailingJob.php +++ b/CRM/Mailing/BAO/MailingJob.php @@ -836,6 +836,49 @@ AND status IN ( 'Scheduled', 'Running', 'Paused' ) } } + /** + * Pause a mailing + */ + public static function pause($mailingID) { + $sql = " + UPDATE civicrm_mailing_job + SET status = 'Paused' + WHERE mailing_id = %1 + AND is_test = 0 + AND status IN ('Scheduled', 'Running') + "; + CRM_Core_DAO::executeQuery($sql, array(1 => array($mailingID, 'Integer'))); + + CRM_Core_Session::setStatus(ts('The mailing has been paused.'), ts('Paused'), 'success'); + } + + /** + * Resume a mailing + */ + public static function resume($mailingID) { + $sql = " + UPDATE civicrm_mailing_job + SET status = 'Scheduled' + WHERE mailing_id = %1 + AND is_test = 0 + AND start_date IS NULL + AND status = 'Paused' + "; + CRM_Core_DAO::executeQuery($sql, array(1 => array($mailingID, 'Integer'))); + + $sql = " + UPDATE civicrm_mailing_job + SET status = 'Running' + WHERE mailing_id = %1 + AND is_test = 0 + AND start_date IS NOT NULL + AND status = 'Paused' + "; + CRM_Core_DAO::executeQuery($sql, array(1 => array($mailingID, 'Integer'))); + + CRM_Core_Session::setStatus(ts('The mailing has been resumed.'), ts('Resumed'), 'success'); + } + /** * Return a translated status enum string. * diff --git a/CRM/Mailing/Form/Search.php b/CRM/Mailing/Form/Search.php index 9c7a5c0d56..56cf5dc02f 100644 --- a/CRM/Mailing/Form/Search.php +++ b/CRM/Mailing/Form/Search.php @@ -92,7 +92,7 @@ class CRM_Mailing_Form_Search extends CRM_Core_Form { $defaults['status_unscheduled'] = 1; } if ($parent->get('scheduled')) { - $statusVals = array('Scheduled', 'Complete', 'Running', 'Canceled'); + $statusVals = array('Scheduled', 'Complete', 'Running', 'Paused', 'Canceled'); $defaults['is_archived'] = 0; } if ($parent->get('archived')) { diff --git a/CRM/Mailing/Page/Browse.php b/CRM/Mailing/Page/Browse.php index d5376a200f..106d38f018 100644 --- a/CRM/Mailing/Page/Browse.php +++ b/CRM/Mailing/Page/Browse.php @@ -176,6 +176,20 @@ class CRM_Mailing_Page_Browse extends CRM_Core_Page { $controller->run(); } } + elseif ($this->_action & CRM_Core_Action::CLOSE) { + if (!CRM_Core_Permission::checkActionPermission('CiviMail', CRM_Core_Action::CLOSE)) { + CRM_Core_Error::fatal(ts('You do not have permission to access this page.')); + } + CRM_Mailing_BAO_MailingJob::pause($this->_mailingId); + CRM_Utils_System::redirect($context); + } + elseif ($this->_action & CRM_Core_Action::REOPEN) { + if (!CRM_Core_Permission::checkActionPermission('CiviMail', CRM_Core_Action::CLOSE)) { + CRM_Core_Error::fatal(ts('You do not have permission to access this page.')); + } + CRM_Mailing_BAO_MailingJob::resume($this->_mailingId); + CRM_Utils_System::redirect($context); + } elseif ($this->_action & CRM_Core_Action::DELETE) { if (CRM_Utils_Request::retrieve('confirmed', 'Boolean', $this)) { diff --git a/CRM/Mailing/Selector/Browse.php b/CRM/Mailing/Selector/Browse.php index 99eea7f50c..4c803e7d29 100644 --- a/CRM/Mailing/Selector/Browse.php +++ b/CRM/Mailing/Selector/Browse.php @@ -294,6 +294,18 @@ LEFT JOIN civicrm_contact scheduledContact ON ( $mailing.scheduled_id = schedul 'extra' => 'onclick="if (confirm(\'' . $archiveExtra . '\')) this.href+=\'&confirmed=1\'; else return false;"', 'title' => ts('Archive Mailing'), ), + CRM_Core_Action::REOPEN => array( + 'name' => ts('Resume'), + 'url' => 'civicrm/mailing/browse', + 'qs' => 'action=reopen&mid=%%mid%%&reset=1', + 'title' => ts('Resume mailing'), + ), + CRM_Core_Action::CLOSE => array( + 'name' => ts('Pause'), + 'url' => 'civicrm/mailing/browse', + 'qs' => 'action=close&mid=%%mid%%&reset=1', + 'title' => ts('Pause mailing'), + ), ); } @@ -389,6 +401,12 @@ LEFT JOIN civicrm_contact scheduledContact ON ( $mailing.scheduled_id = schedul ) { $actionMask |= CRM_Core_Action::DISABLE; + if ($row['status'] == "Paused") { + $actionMask |= CRM_Core_Action::REOPEN; + } + else { + $actionMask |= CRM_Core_Action::CLOSE; + } } if ($row['status'] == 'Scheduled' && empty($row['approval_status_id']) @@ -550,7 +568,7 @@ LEFT JOIN civicrm_contact scheduledContact ON ( $mailing.scheduled_id = schedul if (!$isFormSubmitted && $this->_parent->get('scheduled')) { // mimic default behavior for scheduled screen $isArchived = 0; - $mailingStatus = array('Scheduled' => 1, 'Complete' => 1, 'Running' => 1, 'Canceled' => 1); + $mailingStatus = array('Scheduled' => 1, 'Complete' => 1, 'Running' => 1, 'Paused' => 1, 'Canceled' => 1); } if (!$isFormSubmitted && $this->_parent->get('archived')) { // mimic default behavior for archived screen diff --git a/tests/phpunit/api/v3/JobProcessMailingTest.php b/tests/phpunit/api/v3/JobProcessMailingTest.php index 46ce51770a..dd47195973 100644 --- a/tests/phpunit/api/v3/JobProcessMailingTest.php +++ b/tests/phpunit/api/v3/JobProcessMailingTest.php @@ -108,6 +108,34 @@ class api_v3_JobProcessMailingTest extends CiviUnitTestCase { $this->_mut->assertRecipients($this->getRecipients(1, 2)); } + /** + * Test pause and resume on Mailing. + */ + public function testPauseAndResumeMailing() { + $this->createContactsInGroup(10, $this->_groupID); + Civi::settings()->add(array( + 'mailerBatchLimit' => 2, + )); + //Create a test mailing and check if the status is set to Scheduled. + $result = $this->callAPISuccess('mailing', 'create', $this->_params); + $jobs = $this->callAPISuccess('mailing_job', 'get', array('mailing_id' => $result['id'])); + $this->assertEquals('Scheduled', $jobs['values'][$jobs['id']]['status']); + + CRM_Mailing_BAO_MailingJob::pause($result['id']); + $jobs = $this->callAPISuccess('mailing_job', 'get', array('mailing_id' => $result['id'])); + $this->assertEquals('Paused', $jobs['values'][$jobs['id']]['status']); + + //Verify if Paused mailing isn't considered in process_mailing job. + $this->callAPISuccess('job', 'process_mailing', array()); + $jobs = $this->callAPISuccess('mailing_job', 'get', array('mailing_id' => $result['id'])); + $this->assertEquals('Paused', $jobs['values'][$jobs['id']]['status']); + + //Resume should set the status back to Scheduled. + CRM_Mailing_BAO_MailingJob::resume($result['id']); + $jobs = $this->callAPISuccess('mailing_job', 'get', array('mailing_id' => $result['id'])); + $this->assertEquals('Scheduled', $jobs['values'][$jobs['id']]['status']); + } + /** * Test mail when in non-production environment. * -- 2.25.1