3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
37 * This class is used to browse past mailings.
39 class CRM_Mailing_Selector_Browse
extends CRM_Core_Selector_Base
implements CRM_Core_Selector_API
{
42 * Array of supported links, currenly null
47 static $_links = NULL;
50 * We use desc to remind us what that column is, name is used in the tpl
55 static $_columnHeaders;
63 * @return \CRM_Mailing_Selector_Browse
66 function __construct() {
70 * This method returns the links that are given for each search row.
76 static function &links() {
81 * Getter for array of the parameters required for creating pager.
84 * @param array $params
88 function getPagerParams($action, &$params) {
89 $params['csvString'] = NULL;
90 $params['rowCount'] = CRM_Utils_Pager
::ROWCOUNT
;
91 $params['status'] = ts('Mailings %%StatusMessage%%');
92 $params['buttonTop'] = 'PagerTopButton';
93 $params['buttonBottom'] = 'PagerBottomButton';
97 * Returns the column headers as an array of tuples:
98 * (name, sortName (key to the sort array))
100 * @param string $action the action being performed
101 * @param enum $output what should the result set include (web/email/csv)
103 * @return array the column headers that need to be displayed
106 function &getColumnHeaders($action = NULL, $output = NULL) {
107 $mailing = CRM_Mailing_BAO_Mailing
::getTableName();
108 $job = CRM_Mailing_BAO_MailingJob
::getTableName();
109 if (!isset(self
::$_columnHeaders)) {
110 $completedOrder = NULL;
112 // Set different default sort depending on type of mailings (CRM-7652)
113 $unscheduledOrder = $scheduledOrder = $archivedOrder = CRM_Utils_Sort
::DONTCARE
;
114 if ($this->_parent
->get('unscheduled')) {
115 $unscheduledOrder = CRM_Utils_Sort
::DESCENDING
;
117 elseif ($this->_parent
->get('scheduled')) {
118 $scheduledOrder = CRM_Utils_Sort
::DESCENDING
;
121 // sort by completed date for archived and undefined get
122 $completedOrder = CRM_Utils_Sort
::DESCENDING
;
124 $nameHeaderLabel = ($this->_parent
->get('sms')) ?
ts('SMS Name') : ts('Mailing Name');
126 self
::$_columnHeaders = array(
128 'name' => $nameHeaderLabel,
130 'direction' => CRM_Utils_Sort
::DONTCARE
,
133 'name' => ts('Status'),
135 'direction' => CRM_Utils_Sort
::DONTCARE
,
138 'name' => ts('Created By'),
139 'sort' => 'created_by',
140 'direction' => CRM_Utils_Sort
::DONTCARE
,
143 'name' => ts('Created Date'),
144 'sort' => 'created_date',
145 'direction' => $unscheduledOrder,
148 'name' => ts('Sent By'),
149 'sort' => 'scheduled_by',
150 'direction' => CRM_Utils_Sort
::DONTCARE
,
153 'name' => ts('Scheduled'),
154 'sort' => 'scheduled_date',
155 'direction' => $scheduledOrder,
158 'name' => ts('Started'),
159 'sort' => 'start_date',
160 'direction' => CRM_Utils_Sort
::DONTCARE
,
163 'name' => ts('Completed'),
164 'sort' => 'end_date',
165 'direction' => $completedOrder,
169 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
170 self
::$_columnHeaders[] = array('name' => ts('Campaign'),
171 'sort' => 'campaign_id',
172 'direction' => CRM_Utils_Sort
::DONTCARE
,
176 if ($output != CRM_Core_Selector_Controller
::EXPORT
) {
177 self
::$_columnHeaders[] = array('name' => ts('Action'));
180 return self
::$_columnHeaders;
184 * Returns total number of rows for the query.
188 * @return int Total number of rows
191 function getTotalCount($action) {
192 $job = CRM_Mailing_BAO_MailingJob
::getTableName();
193 $mailing = CRM_Mailing_BAO_Mailing
::getTableName();
194 $mailingACL = CRM_Mailing_BAO_Mailing
::mailingACL();
196 //get the where clause.
198 $whereClause = "$mailingACL AND " . $this->whereClause($params);
200 // CRM-11919 added addition ON clauses to mailing_job to match getRows
202 SELECT COUNT( DISTINCT $mailing.id ) as count
204 LEFT JOIN $job ON ( $mailing.id = $job.mailing_id AND civicrm_mailing_job.is_test = 0 AND civicrm_mailing_job.parent_id IS NULL )
205 LEFT JOIN civicrm_contact createdContact ON ( $mailing.created_id = createdContact.id )
206 LEFT JOIN civicrm_contact scheduledContact ON ( $mailing.scheduled_id = scheduledContact.id )
209 return CRM_Core_DAO
::singleValueQuery($query, $params);
213 * Returns all the rows in the given offset and rowCount
215 * @param enum $action the action being performed
216 * @param int $offset the row number to start from
217 * @param int $rowCount the number of rows to return
218 * @param string $sort the sql string that describes the sort order
219 * @param enum $output what should the result set include (web/email/csv)
221 * @return int the total number of rows for this action
223 function &getRows($action, $offset, $rowCount, $sort, $output = NULL) {
224 static $actionLinks = NULL;
225 if (empty($actionLinks)) {
226 $cancelExtra = ts('Are you sure you want to cancel this mailing?');
227 $deleteExtra = ts('Are you sure you want to delete this mailing?');
228 $archiveExtra = ts('Are you sure you want to archive this mailing?');
230 $actionLinks = array(
231 CRM_Core_Action
::ENABLE
=> array(
232 'name' => ts('Approve/Reject'),
233 'url' => 'civicrm/mailing/approve',
234 'qs' => 'mid=%%mid%%&reset=1',
235 'title' => ts('Approve/Reject Mailing'),
237 CRM_Core_Action
::VIEW
=> array(
238 'name' => ts('Report'),
239 'url' => 'civicrm/mailing/report',
240 'qs' => 'mid=%%mid%%&reset=1',
241 'title' => ts('View Mailing Report'),
243 CRM_Core_Action
::UPDATE
=> array(
244 'name' => ts('Re-Use'),
245 'url' => 'civicrm/mailing/send',
246 'qs' => 'mid=%%mid%%&reset=1',
247 'title' => ts('Re-Send Mailing'),
249 CRM_Core_Action
::DISABLE
=> array(
250 'name' => ts('Cancel'),
251 'url' => 'civicrm/mailing/browse',
252 'qs' => 'action=disable&mid=%%mid%%&reset=1',
253 'extra' => 'onclick="if (confirm(\'' . $cancelExtra . '\')) this.href+=\'&confirmed=1\'; else return false;"',
254 'title' => ts('Cancel Mailing'),
256 CRM_Core_Action
::PREVIEW
=> array(
257 'name' => ts('Continue'),
258 'url' => 'civicrm/mailing/send',
259 'qs' => 'mid=%%mid%%&continue=true&reset=1',
260 'title' => ts('Continue Mailing'),
262 CRM_Core_Action
::DELETE
=> array(
263 'name' => ts('Delete'),
264 'url' => 'civicrm/mailing/browse',
265 'qs' => 'action=delete&mid=%%mid%%&reset=1',
266 'extra' => 'onclick="if (confirm(\'' . $deleteExtra . '\')) this.href+=\'&confirmed=1\'; else return false;"',
267 'title' => ts('Delete Mailing'),
269 CRM_Core_Action
::RENEW
=> array(
270 'name' => ts('Archive'),
271 'url' => 'civicrm/mailing/browse/archived',
272 'qs' => 'action=renew&mid=%%mid%%&reset=1',
273 'extra' => 'onclick="if (confirm(\'' . $archiveExtra . '\')) this.href+=\'&confirmed=1\'; else return false;"',
274 'title' => ts('Archive Mailing'),
280 $workFlow = $showApprovalLinks = $showScheduleLinks = $showCreateLinks = FALSE;
281 if (CRM_Mailing_Info
::workflowEnabled()) {
284 //supercedes all permission
285 if (CRM_Core_Permission
::check('access CiviMail')) {
289 if (CRM_Core_Permission
::check('approve mailings')) {
290 $showApprovalLinks = TRUE;
293 if (CRM_Core_Permission
::check('create mailings')) {
294 $showCreateLinks = TRUE;
297 if (CRM_Core_Permission
::check('schedule mailings')) {
298 $showScheduleLinks = TRUE;
301 $mailing = new CRM_Mailing_BAO_Mailing();
305 $whereClause = ' AND ' . $this->whereClause($params);
307 if (empty($params)) {
308 $this->_parent
->assign('isSearch', 0);
311 $this->_parent
->assign('isSearch', 1);
313 $rows = &$mailing->getRows($offset, $rowCount, $sort, $whereClause, $params);
315 //get the search base mailing Ids, CRM-3711.
316 $searchMailings = $mailing->searchMailingIDs();
318 //check for delete CRM-4418
319 $allowToDelete = CRM_Core_Permission
::check('delete in CiviMail');
321 if ($output != CRM_Core_Selector_Controller
::EXPORT
) {
323 //create the appropriate $op to use for hook_civicrm_links
324 $pageTypes = array('view', 'mailing', 'browse');
325 if ($this->_parent
->_unscheduled
) {
326 $pageTypes[] = 'unscheduled';
328 if ($this->_parent
->_scheduled
) {
329 $pageTypes[] = 'scheduled';
331 if ($this->_parent
->_archived
) {
332 $pageTypes[] = 'archived';
334 $opString = implode('.', $pageTypes);
336 foreach ($rows as $key => $row) {
338 if ($row['sms_provider_id']) {
339 $actionLinks[CRM_Core_Action
::PREVIEW
]['url'] = 'civicrm/sms/send';
342 if (!($row['status'] == 'Not scheduled') && !$row['sms_provider_id']) {
343 if ($allAccess ||
$showCreateLinks) {
344 $actionMask = CRM_Core_Action
::VIEW
;
347 if (!in_array($row['id'], $searchMailings)) {
348 if ($allAccess ||
$showCreateLinks) {
349 $actionMask |
= CRM_Core_Action
::UPDATE
;
354 if ($allAccess ||
($showCreateLinks ||
$showScheduleLinks)) {
355 $actionMask = CRM_Core_Action
::PREVIEW
;
358 if (in_array($row['status'], array(
359 'Scheduled', 'Running', 'Paused'))) {
361 ($showApprovalLinks && $showCreateLinks && $showScheduleLinks)
364 $actionMask |
= CRM_Core_Action
::DISABLE
;
366 if ($row['status'] == 'Scheduled' &&
367 empty($row['approval_status_id'])
369 if ($workFlow && ($allAccess ||
$showApprovalLinks)) {
370 $actionMask |
= CRM_Core_Action
::ENABLE
;
375 if (in_array($row['status'], array('Complete', 'Canceled')) &&
377 if ($allAccess ||
$showCreateLinks) {
378 $actionMask |
= CRM_Core_Action
::RENEW
;
382 //check for delete permission.
383 if ($allowToDelete) {
384 $actionMask |
= CRM_Core_Action
::DELETE
;
387 if ($actionMask == NULL) {
388 $actionMask = CRM_Core_Action
::ADD
;
390 //get status strings as per locale settings CRM-4411.
391 $rows[$key]['status'] = CRM_Mailing_BAO_MailingJob
::status($row['status']);
393 $rows[$key]['action'] = CRM_Core_Action
::formLink($actionLinks,
395 array('mid' => $row['id']),
403 //unset($rows[$key]['id']);
404 // if the scheduled date is 0, replace it with an empty string
405 if ($rows[$key]['scheduled_iso'] == '0000-00-00 00:00:00') {
406 $rows[$key]['scheduled'] = '';
408 unset($rows[$key]['scheduled_iso']);
412 // also initialize the AtoZ pager
418 * Name of export file.
420 * @param string $output type of output
422 * @return string name of the file
424 function getExportFileName($output = 'csv') {
425 return ts('CiviMail Mailings');
431 function setParent($parent) {
432 $this->_parent
= $parent;
436 * @param array $params
437 * @param bool $sortBy
441 function whereClause(&$params, $sortBy = TRUE) {
442 $values = $clauses = array();
443 $isFormSubmitted = $this->_parent
->get('hidden_find_mailings');
445 $title = $this->_parent
->get('mailing_name');
447 $clauses[] = 'name LIKE %1';
448 if (strpos($title, '%') !== FALSE) {
449 $params[1] = array($title, 'String', FALSE);
452 $params[1] = array($title, 'String', TRUE);
456 $dateClause1 = $dateClause2 = array();
457 $from = $this->_parent
->get('mailing_from');
458 if (!CRM_Utils_System
::isNull($from)) {
459 if ($this->_parent
->get('unscheduled')) {
460 $dateClause1[] = 'civicrm_mailing.created_date >= %2';
463 $dateClause1[] = 'civicrm_mailing_job.start_date >= %2';
464 $dateClause2[] = 'civicrm_mailing_job.scheduled_date >= %2';
466 $params[2] = array($from, 'String');
469 $to = $this->_parent
->get('mailing_to');
470 if (!CRM_Utils_System
::isNull($to)) {
471 if ($this->_parent
->get('unscheduled')) {
472 $dateClause1[] = ' civicrm_mailing.created_date <= %3 ';
475 $dateClause1[] = 'civicrm_mailing_job.start_date <= %3';
476 $dateClause2[] = 'civicrm_mailing_job.scheduled_date <= %3';
478 $params[3] = array($to, 'String');
481 $dateClauses = array();
482 if (!empty($dateClause1)) {
483 $dateClauses[] = implode(' AND ', $dateClause1);
485 if (!empty($dateClause2)) {
486 $dateClauses[] = implode(' AND ', $dateClause2);
488 $dateClauses = implode(' OR ', $dateClauses);
489 if (!empty($dateClauses)) {
490 $clauses[] = "({$dateClauses})";
493 if ($this->_parent
->get('sms')) {
494 $clauses[] = "civicrm_mailing.sms_provider_id IS NOT NULL";
497 $clauses[] = "civicrm_mailing.sms_provider_id IS NULL";
500 // get values submitted by form
501 $isDraft = $this->_parent
->get('status_unscheduled');
502 $isArchived = $this->_parent
->get('is_archived');
503 $mailingStatus = $this->_parent
->get('mailing_status');
505 if (!$isFormSubmitted && $this->_parent
->get('scheduled')) {
506 // mimic default behavior for scheduled screen
508 $mailingStatus = array('Scheduled' => 1, 'Complete' => 1, 'Running' => 1, 'Canceled' => 1);
510 if (!$isFormSubmitted && $this->_parent
->get('archived')) {
511 // mimic default behavior for archived screen
514 if (!$isFormSubmitted && $this->_parent
->get('unscheduled')) {
515 // mimic default behavior for draft screen
519 $statusClauses = array();
521 $statusClauses[] = "civicrm_mailing.scheduled_id IS NULL";
523 if (!empty($mailingStatus)) {
524 $statusClauses[] = "civicrm_mailing_job.status IN ('" . implode("', '", array_keys($mailingStatus)) . "')";
526 if (!empty($statusClauses)) {
527 $clauses[] = "(" . implode(' OR ', $statusClauses) . ")";
530 if (isset($isArchived)) {
532 $clauses[] = "civicrm_mailing.is_archived = 1";
534 $clauses[] = "(civicrm_mailing.is_archived IS NULL OR civicrm_mailing.is_archived = 0)";
539 $this->_parent
->_sortByCharacter
!== NULL
541 $clauses[] = "name LIKE '" . strtolower(CRM_Core_DAO
::escapeWildCardString($this->_parent
->_sortByCharacter
)) . "%'";
544 // dont do a the below assignement when doing a
547 if (count($clauses) > 1) {
548 $this->_parent
->assign('isSearch', 1);
551 $this->_parent
->assign('isSearch', 0);
555 $createOrSentBy = $this->_parent
->get('sort_name');
556 if (!CRM_Utils_System
::isNull($createOrSentBy)) {
557 $clauses[] = '(createdContact.sort_name LIKE %4 OR scheduledContact.sort_name LIKE %4)';
558 $params[4] = array('%' . $createOrSentBy . '%', 'String');
561 $createdId = $this->_parent
->get('createdId');
563 $clauses[] = "(created_id = {$createdId})";
564 $params[5] = array($createdId, 'Integer');
567 $campainIds = $this->_parent
->get('campaign_id');
568 if (!CRM_Utils_System
::isNull($campainIds)) {
569 if (!is_array($campainIds)) {
570 $campaignIds = array($campaignIds);
572 $clauses[] = '( campaign_id IN ( ' . implode(' , ', array_values($campainIds)) . ' ) )';
575 if (empty($clauses)) {
579 return implode(' AND ', $clauses);
582 function pagerAtoZ() {
585 $whereClause = $this->whereClause($params, FALSE);
588 SELECT DISTINCT UPPER(LEFT(name, 1)) as sort_name
590 LEFT JOIN civicrm_mailing_job ON (civicrm_mailing_job.mailing_id = civicrm_mailing.id)
591 LEFT JOIN civicrm_contact createdContact ON ( civicrm_mailing.created_id = createdContact.id )
592 LEFT JOIN civicrm_contact scheduledContact ON ( civicrm_mailing.scheduled_id = scheduledContact.id )
594 ORDER BY LEFT(name, 1)
597 $dao = CRM_Core_DAO
::executeQuery($query, $params);
599 $aToZBar = CRM_Utils_PagerAToZ
::getAToZBar($dao, $this->_parent
->_sortByCharacter
, TRUE);
600 $this->_parent
->assign('aToZ', $aToZBar);