Merge pull request #17588 from artfulrobot/artfulrobot-property-bag-support-empty
[civicrm-core.git] / CRM / Mailing / Selector / Event.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
16 */
17
18/**
19 * This class is used to retrieve and display a range of
20 * contacts that match the given criteria (specifically for
21 * results of advanced search options.
6a488035
TO
22 */
23class CRM_Mailing_Selector_Event extends CRM_Core_Selector_Base implements CRM_Core_Selector_API {
24
25 /**
b44e3f84 26 * Array of supported links, currently null
6a488035
TO
27 *
28 * @var array
6a488035 29 */
7e8c8317 30 public static $_links = NULL;
6a488035
TO
31
32 /**
100fef9d 33 * What event type are we browsing?
7e8c8317 34 * @var sting
6a488035
TO
35 */
36 private $_event;
37
38 /**
100fef9d 39 * Should we only count distinct contacts?
7e8c8317 40 * @var bool
6a488035
TO
41 */
42 private $_is_distinct;
43
44 /**
100fef9d 45 * Which mailing are we browsing events from?
7e8c8317 46 * @var int
6a488035
TO
47 */
48 private $_mailing_id;
49
50 /**
100fef9d 51 * Do we want events tied to a specific job?
7e8c8317 52 * @var int
6a488035
TO
53 */
54 private $_job_id;
55
56 /**
100fef9d 57 * For click-through events, do we only want those from a specific url?
7e8c8317 58 * @var int
6a488035
TO
59 */
60 private $_url_id;
61
62 /**
100fef9d 63 * We use desc to remind us what that column is, name is used in the tpl
6a488035
TO
64 *
65 * @var array
66 */
67 public $_columnHeaders;
68
69 /**
fe482240 70 * Class constructor.
6a488035 71 *
90c8230e
TO
72 * @param string $event
73 * The event type (queue/delivered/open...).
74 * @param bool $distinct
75 * Count only distinct contact events?.
76 * @param int $mailing
77 * ID of the mailing to query.
78 * @param int $job
79 * ID of the job to query. If null, all jobs from $mailing are queried.
80 * @param int $url
81 * If the event type is a click-through, do we want only those from a specific url?.
6a488035 82 *
6c8f6e67 83 * @return \CRM_Mailing_Selector_Event
6a488035 84 */
00be9182 85 public function __construct($event, $distinct, $mailing, $job = NULL, $url = NULL) {
353ffa53 86 $this->_event_type = $event;
6a488035 87 $this->_is_distinct = $distinct;
353ffa53
TO
88 $this->_mailing_id = $mailing;
89 $this->_job_id = $job;
90 $this->_url_id = $url;
6a488035 91 }
6a488035
TO
92
93 /**
94 * This method returns the links that are given for each search row.
95 *
96 * @return array
6a488035 97 */
00be9182 98 public static function &links() {
6a488035
TO
99 return self::$_links;
100 }
6a488035
TO
101
102 /**
100fef9d 103 * Getter for array of the parameters required for creating pager.
6a488035 104 *
da6b46f4 105 * @param $action
c490a46a 106 * @param array $params
6a488035 107 */
00be9182 108 public function getPagerParams($action, &$params) {
6a488035 109 $params['csvString'] = NULL;
353ffa53 110 $params['rowCount'] = CRM_Utils_Pager::ROWCOUNT;
be2fb01f 111 $params['status'] = ts('%1 %%StatusMessage%%', [1 => $this->eventToTitle()]);
6a488035
TO
112 $params['buttonTop'] = 'PagerTopButton';
113 $params['buttonBottom'] = 'PagerBottomButton';
114 }
6a488035
TO
115
116 /**
100fef9d 117 * Returns the column headers as an array of tuples:
6a488035
TO
118 * (name, sortName (key to the sort array))
119 *
90c8230e
TO
120 * @param string $action
121 * The action being performed.
3f8d2862 122 * @param string $output
90c8230e 123 * What should the result set include (web/email/csv).
6a488035 124 *
a6c01b45
CW
125 * @return array
126 * the column headers that need to be displayed
6a488035 127 */
00be9182 128 public function &getColumnHeaders($action = NULL, $output = NULL) {
6a488035
TO
129 $mailing = CRM_Mailing_BAO_Mailing::getTableName();
130
131 $contact = CRM_Contact_BAO_Contact::getTableName();
132
133 $email = CRM_Core_BAO_Email::getTableName();
134
9da8dc8c 135 $job = CRM_Mailing_BAO_MailingJob::getTableName();
6a488035
TO
136 if (!isset($this->_columnHeaders)) {
137
be2fb01f
CW
138 $this->_columnHeaders = [
139 'sort_name' => [
6a488035
TO
140 'name' => ts('Contact'),
141 'sort' => $contact . '.sort_name',
142 'direction' => CRM_Utils_Sort::ASCENDING,
be2fb01f
CW
143 ],
144 'email' => [
6a488035
TO
145 'name' => ts('Email Address'),
146 'sort' => $email . '.email',
147 'direction' => CRM_Utils_Sort::DONTCARE,
be2fb01f
CW
148 ],
149 ];
6a488035
TO
150
151 switch ($this->_event_type) {
152 case 'queue':
153 $dateSort = $job . '.start_date';
154 break;
155
156 case 'delivered':
be2fb01f
CW
157 $this->_columnHeaders = [
158 'contact_id' => [
b812c745 159 'name' => ts('Internal Contact ID'),
160 'sort' => $contact . '.id',
161 'direction' => CRM_Utils_Sort::ASCENDING,
be2fb01f
CW
162 ],
163 ] + $this->_columnHeaders;
6a488035
TO
164 $dateSort = CRM_Mailing_Event_BAO_Delivered::getTableName() . '.time_stamp';
165 break;
166
167 case 'opened':
168 $dateSort = CRM_Mailing_Event_BAO_Opened::getTableName() . '.time_stamp';
169 break;
170
171 case 'bounce':
172 $dateSort = CRM_Mailing_Event_BAO_Bounce::getTableName() . '.time_stamp';
173 $this->_columnHeaders = array_merge($this->_columnHeaders,
be2fb01f
CW
174 [
175 [
6a488035 176 'name' => ts('Bounce Type'),
be2fb01f
CW
177 ],
178 [
6a488035 179 'name' => ts('Bounce Reason'),
be2fb01f
CW
180 ],
181 ]
6a488035
TO
182 );
183 break;
184
185 case 'forward':
186 $dateSort = CRM_Mailing_Event_BAO_Forward::getTableName() . '.time_stamp';
187
188 $this->_columnHeaders = array_merge($this->_columnHeaders,
be2fb01f
CW
189 [
190 [
6a488035 191 'name' => ts('Forwarded Email'),
be2fb01f
CW
192 ],
193 ]
6a488035
TO
194 );
195 break;
196
197 case 'reply':
198 $dateSort = CRM_Mailing_Event_BAO_Reply::getTableName() . '.time_stamp';
199 break;
200
201 case 'unsubscribe':
202 $dateSort = CRM_Mailing_Event_BAO_Unsubscribe::getTableName() . '.time_stamp';
be2fb01f
CW
203 $this->_columnHeaders = array_merge($this->_columnHeaders, [
204 [
353ffa53 205 'name' => ts('Unsubscribe'),
be2fb01f
CW
206 ],
207 ]);
6a488035
TO
208 break;
209
210 case 'optout':
211 $dateSort = CRM_Mailing_Event_BAO_Unsubscribe::getTableName() . '.time_stamp';
be2fb01f
CW
212 $this->_columnHeaders = array_merge($this->_columnHeaders, [
213 [
353ffa53 214 'name' => ts('Opt-Out'),
be2fb01f
CW
215 ],
216 ]);
6a488035
TO
217 break;
218
219 case 'click':
220 $dateSort = CRM_Mailing_Event_BAO_TrackableURLOpen::getTableName() . '.time_stamp';
be2fb01f
CW
221 $this->_columnHeaders = array_merge($this->_columnHeaders, [
222 [
353ffa53 223 'name' => ts('URL'),
be2fb01f
CW
224 ],
225 ]);
6a488035
TO
226 break;
227
228 default:
229 return 0;
230 }
231
be2fb01f
CW
232 $this->_columnHeaders = array_merge($this->_columnHeaders, [
233 'date' => [
388ffbf6 234 'name' => ts('Date'),
235 'sort' => $dateSort,
236 'direction' => CRM_Utils_Sort::DESCENDING,
be2fb01f
CW
237 ],
238 ]);
6a488035
TO
239 }
240 return $this->_columnHeaders;
241 }
242
243 /**
244 * Returns total number of rows for the query.
245 *
25606795 246 * @param string $action
6a488035 247 *
a6c01b45
CW
248 * @return int
249 * Total number of rows
6a488035 250 */
00be9182 251 public function getTotalCount($action) {
6a488035
TO
252 switch ($this->_event_type) {
253 case 'queue':
254 $event = new CRM_Mailing_Event_BAO_Queue();
795492f3 255 $result = $event->getTotalCount($this->_mailing_id,
6a488035
TO
256 $this->_job_id
257 );
795492f3 258 return $result;
6a488035
TO
259
260 case 'delivered':
261 $event = new CRM_Mailing_Event_BAO_Delivered();
795492f3 262 $result = $event->getTotalCount($this->_mailing_id,
6a488035
TO
263 $this->_job_id,
264 $this->_is_distinct
265 );
795492f3 266 return $result;
6a488035
TO
267
268 case 'opened':
269 $event = new CRM_Mailing_Event_BAO_Opened();
795492f3 270 $result = $event->getTotalCount($this->_mailing_id,
6a488035
TO
271 $this->_job_id,
272 $this->_is_distinct
273 );
795492f3 274 return $result;
6a488035
TO
275
276 case 'bounce':
277 $event = new CRM_Mailing_Event_BAO_Bounce();
795492f3 278 $result = $event->getTotalCount($this->_mailing_id,
6a488035
TO
279 $this->_job_id,
280 $this->_is_distinct
281 );
795492f3 282 return $result;
6a488035
TO
283
284 case 'forward':
285 $event = new CRM_Mailing_Event_BAO_Forward();
795492f3 286 $result = $event->getTotalCount($this->_mailing_id,
6a488035
TO
287 $this->_job_id,
288 $this->_is_distinct
289 );
795492f3 290 return $result;
6a488035
TO
291
292 case 'reply':
293 $event = new CRM_Mailing_Event_BAO_Reply();
795492f3 294 $result = $event->getTotalCount($this->_mailing_id,
6a488035
TO
295 $this->_job_id,
296 $this->_is_distinct
297 );
795492f3 298 return $result;
6a488035
TO
299
300 case 'unsubscribe':
301 $event = new CRM_Mailing_Event_BAO_Unsubscribe();
795492f3 302 $result = $event->getTotalCount($this->_mailing_id,
6a488035
TO
303 $this->_job_id,
304 $this->_is_distinct
305 );
795492f3 306 return $result;
6a488035
TO
307
308 case 'optout':
309 $event = new CRM_Mailing_Event_BAO_Unsubscribe();
795492f3 310 $result = $event->getTotalCount($this->_mailing_id,
6a488035
TO
311 $this->_job_id,
312 $this->_is_distinct,
313 FALSE
314 );
795492f3 315 return $result;
6a488035
TO
316
317 case 'click':
318 $event = new CRM_Mailing_Event_BAO_TrackableURLOpen();
795492f3 319 $result = $event->getTotalCount($this->_mailing_id,
6a488035
TO
320 $this->_job_id,
321 $this->_is_distinct,
322 $this->_url_id
323 );
795492f3 324 return $result;
6a488035
TO
325
326 default:
327 return 0;
328 }
329 }
330
331 /**
fe482240 332 * Returns all the rows in the given offset and rowCount.
6a488035 333 *
3f8d2862 334 * @param string $action
90c8230e
TO
335 * The action being performed.
336 * @param int $offset
337 * The row number to start from.
338 * @param int $rowCount
339 * The number of rows to return.
340 * @param string $sort
341 * The sql string that describes the sort order.
3f8d2862 342 * @param string $output
90c8230e 343 * What should the result set include (web/email/csv).
6a488035 344 *
a6c01b45
CW
345 * @return int
346 * the total number of rows for this action
6a488035 347 */
00be9182 348 public function &getRows($action, $offset, $rowCount, $sort, $output = NULL) {
6a488035
TO
349 switch ($this->_event_type) {
350 case 'queue':
795492f3 351 $rows = CRM_Mailing_Event_BAO_Queue::getRows($this->_mailing_id,
6a488035
TO
352 $this->_job_id, $offset, $rowCount, $sort
353 );
795492f3 354 return $rows;
6a488035
TO
355
356 case 'delivered':
795492f3 357 $rows = CRM_Mailing_Event_BAO_Delivered::getRows($this->_mailing_id,
6a488035
TO
358 $this->_job_id, $this->_is_distinct,
359 $offset, $rowCount, $sort
360 );
795492f3 361 return $rows;
6a488035
TO
362
363 case 'opened':
795492f3 364 $rows = CRM_Mailing_Event_BAO_Opened::getRows($this->_mailing_id,
6a488035
TO
365 $this->_job_id, $this->_is_distinct,
366 $offset, $rowCount, $sort
367 );
795492f3 368 return $rows;
6a488035
TO
369
370 case 'bounce':
795492f3 371 $rows = CRM_Mailing_Event_BAO_Bounce::getRows($this->_mailing_id,
6a488035
TO
372 $this->_job_id, $this->_is_distinct,
373 $offset, $rowCount, $sort
374 );
795492f3 375 return $rows;
6a488035
TO
376
377 case 'forward':
795492f3 378 $rows = CRM_Mailing_Event_BAO_Forward::getRows($this->_mailing_id,
6a488035
TO
379 $this->_job_id, $this->_is_distinct,
380 $offset, $rowCount, $sort
381 );
795492f3 382 return $rows;
6a488035
TO
383
384 case 'reply':
795492f3 385 $rows = CRM_Mailing_Event_BAO_Reply::getRows($this->_mailing_id,
6a488035
TO
386 $this->_job_id, $this->_is_distinct,
387 $offset, $rowCount, $sort
388 );
795492f3 389 return $rows;
6a488035
TO
390
391 case 'unsubscribe':
795492f3 392 $rows = CRM_Mailing_Event_BAO_Unsubscribe::getRows($this->_mailing_id,
6a488035
TO
393 $this->_job_id, $this->_is_distinct,
394 $offset, $rowCount, $sort, TRUE
395 );
795492f3 396 return $rows;
6a488035
TO
397
398 case 'optout':
795492f3 399 $rows = CRM_Mailing_Event_BAO_Unsubscribe::getRows($this->_mailing_id,
6a488035
TO
400 $this->_job_id, $this->_is_distinct,
401 $offset, $rowCount, $sort, FALSE
402 );
795492f3 403 return $rows;
6a488035
TO
404
405 case 'click':
795492f3 406 $rows = CRM_Mailing_Event_BAO_TrackableURLOpen::getRows(
6a488035
TO
407 $this->_mailing_id, $this->_job_id,
408 $this->_is_distinct, $this->_url_id,
409 $offset, $rowCount, $sort
410 );
795492f3 411 return $rows;
6a488035
TO
412
413 default:
414 return NULL;
415 }
416 }
417
418 /**
100fef9d 419 * Name of export file.
6a488035 420 *
90c8230e
TO
421 * @param string $output
422 * Type of output.
6a488035 423 *
795492f3 424 * @return string|NULL
a6c01b45 425 * name of the file
6a488035 426 */
6ea503d4 427 public function getExportFileName($output = 'csv') {
795492f3 428 return NULL;
6ea503d4 429 }
6a488035 430
bc854509 431 /**
432 * Get the title for the mailing event type.
433 *
434 * @return string
435 */
00be9182 436 public function eventToTitle() {
6a488035
TO
437 static $events = NULL;
438
439 if (empty($events)) {
be2fb01f 440 $events = [
6a488035
TO
441 'queue' => ts('Intended Recipients'),
442 'delivered' => ts('Successful Deliveries'),
443 'bounce' => ts('Bounces'),
444 'forward' => ts('Forwards'),
795492f3 445 'reply' => $this->_is_distinct ? ts('Unique Replies') : ts('Replies'),
6a488035
TO
446 'unsubscribe' => ts('Unsubscribe Requests'),
447 'optout' => ts('Opt-out Requests'),
795492f3 448 'click' => $this->_is_distinct ? ts('Unique Click-throughs') : ts('Click-throughs'),
aa6b3363 449 'opened' => $this->_is_distinct ? ts('Unique Tracked Opens') : ts('Total Tracked Opens'),
be2fb01f 450 ];
6a488035
TO
451 }
452 return $events[$this->_event_type];
453 }
454
bc854509 455 /**
456 * Get the title of the event.
457 *
458 * @return string
459 */
00be9182 460 public function getTitle() {
6a488035
TO
461 return $this->eventToTitle();
462 }
96025800 463
6a488035 464}