Ensure reports use nested group selector and remove boilerplate
[civicrm-core.git] / CRM / Report / Form / Mailing / Detail.php
CommitLineData
6a488035 1<?php
6a488035
TO
2
3/*
4 +--------------------------------------------------------------------+
06b69b18 5 | CiviCRM version 4.5 |
6a488035 6 +--------------------------------------------------------------------+
06b69b18 7 | Copyright CiviCRM LLC (c) 2004-2014 |
6a488035
TO
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
10 | |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public |
21 | License and the CiviCRM Licensing Exception along |
22 | with this program; if not, contact CiviCRM LLC |
23 | at info[AT]civicrm[DOT]org. If you have questions about the |
24 | GNU Affero General Public License or the licensing of CiviCRM, |
25 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
26 +--------------------------------------------------------------------+
27*/
28
29/**
30 *
31 * @package CRM
06b69b18 32 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
33 * $Id$
34 *
35 */
36class CRM_Report_Form_Mailing_Detail extends CRM_Report_Form {
37
38 protected $_exposeContactID = FALSE;
2f4c2f5d 39
74cf4551
EM
40 /**
41 *
42 */
43 /**
44 *
45 */
6a488035
TO
46 function __construct() {
47 $this->_columns = array();
48
49 $this->_columns['civicrm_contact'] = array(
50 'dao' => 'CRM_Contact_DAO_Contact',
51 'fields' =>
52 array(
53 'id' =>
54 array(
55 'name' => 'id',
56 'title' => ts('Contact ID'),
57 'required' => TRUE,
58 'no_display' => TRUE,
59 ),
60 'sort_name' =>
61 array(
62 'title' => ts('Contact Name'),
63 'required' => TRUE,
64 ),
65 ),
66 'filters' =>
67 array(
68 'sort_name' =>
69 array(
70 'title' => ts('Contact Name'),
71 ),
72 'id' =>
73 array(
74 'title' => ts('Contact ID'),
75 'no_display' => TRUE,
76 ),
77 ),
78 'order_bys' =>
79 array(
80 'sort_name' =>
81 array('title' => ts('Contact Name'),
82 'default' => TRUE,
83 'default_order' => 'ASC',
84 ),
85 ),
86 'grouping' => 'contact-fields',
87 );
88
89 $this->_columns['civicrm_mailing'] = array(
90 'dao' => 'CRM_Mailing_DAO_Mailing',
91 'fields' =>
92 array(
93 'mailing_name' =>
94 array(
95 'name' => 'name',
96 'title' => ts('Mailing'),
97 'default' => TRUE,
98 ),
99 ),
100 'filters' =>
101 array(
102 'mailing_id' =>
103 array(
104 'name' => 'id',
105 'title' => ts('Mailing'),
106 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
107 'type' => CRM_Utils_Type::T_INT,
108 'options' => CRM_Mailing_BAO_Mailing::getMailingsList(),
109 ),
110 ),
111 'order_bys' =>
112 array(
113 'mailing_name' =>
114 array(
115 'name' => 'name',
116 'title' => ts('Mailing'),
117 ),
118 ),
119 'grouping' => 'mailing-fields',
120 );
121
122 // adding dao just to have alias
123 $this->_columns['civicrm_mailing_event_bounce'] = array(
124 'dao' => 'CRM_Mailing_Event_DAO_Bounce',
125 );
126
127 $this->_columns['civicrm_mailing_event_delivered'] = array(
128 'dao' => 'CRM_Mailing_Event_DAO_Delivered',
129 'fields' =>
130 array(
131 'delivery_id' =>
132 array(
133 'name' => 'id',
134 'title' => ts('Delivery Status'),
135 'default' => TRUE,
136 ),
137 ),
138 'filters' =>
139 array(
140 'delivery_status' =>
141 array(
142 'name' => 'delivery_status',
143 'title' => ts('Delivery Status'),
144 'operatorType' => CRM_Report_Form::OP_SELECT,
145 'type' => CRM_Utils_Type::T_STRING,
146 'options' => array(
147 '' => 'Any',
148 'successful' => 'Successful',
149 'bounced' => 'Bounced',
150 ),
151 ),
152 ),
153 'grouping' => 'mailing-fields',
154 );
155
156 $this->_columns['civicrm_mailing_event_unsubscribe'] = array(
157 'dao' => 'CRM_Mailing_Event_DAO_Unsubscribe',
158 'fields' =>
159 array(
160 'unsubscribe_id' =>
161 array(
162 'name' => 'id',
163 'title' => ts('Unsubscribe'),
164 'default' => TRUE,
165 ),
166 'optout_id' =>
167 array(
168 'name' => 'id',
169 'title' => ts('Opt-out'),
170 'default' => TRUE,
171 'alias' => 'mailing_event_unsubscribe_civireport2',
172 ),
173 ),
174 'filters' =>
175 array(
176 'is_unsubscribed' =>
177 array(
178 'name' => 'id',
179 'title' => ts('Unsubscribed'),
180 'type' => CRM_Utils_Type::T_INT,
181 'operatorType' => CRM_Report_Form::OP_SELECT,
182 'options' => array('' => ts('Any'), '0' => ts('No'), '1' => ts('Yes')),
183 'clause' => 'mailing_event_unsubscribe_civireport.id IS NULL',
184 ),
185 'is_optout' =>
186 array(
187 'title' => ts('Opted-out'),
188 'type' => CRM_Utils_Type::T_INT,
189 'operatorType' => CRM_Report_Form::OP_SELECT,
190 'options' => array('' => ts('Any'), '0' => ts('No'), '1' => ts('Yes')),
191 'clause' => 'mailing_event_unsubscribe_civireport2.id IS NULL',
192 ),
193 ),
194 'grouping' => 'mailing-fields',
195 );
196
197 $this->_columns['civicrm_mailing_event_reply'] = array(
198 'dao' => 'CRM_Mailing_Event_DAO_Reply',
199 'fields' =>
200 array(
201 'reply_id' =>
202 array(
203 'name' => 'id',
204 'title' => ts('Reply'),
205 ),
206 ),
207 'filters' =>
208 array(
209 'is_replied' =>
210 array(
211 'name' => 'id',
212 'title' => ts('Replied'),
213 'type' => CRM_Utils_Type::T_INT,
214 'operatorType' => CRM_Report_Form::OP_SELECT,
215 'options' => array('' => ts('Any'), '0' => ts('No'), '1' => ts('Yes')),
216 'clause' => 'mailing_event_reply_civireport.id IS NULL',
217 ),
218 ),
219 'grouping' => 'mailing-fields',
220 );
221
222 $this->_columns['civicrm_mailing_event_forward'] = array(
223 'dao' => 'CRM_Mailing_Event_DAO_Forward',
224 'fields' =>
225 array(
226 'forward_id' =>
227 array(
228 'name' => 'id',
229 'title' => ts('Forwarded to Email'),
230 ),
231 ),
232 'filters' =>
233 array(
234 'is_forwarded' =>
235 array(
236 'name' => 'id',
237 'title' => ts('Forwarded'),
238 'type' => CRM_Utils_Type::T_INT,
239 'operatorType' => CRM_Report_Form::OP_SELECT,
240 'options' => array('' => ts('Any'), '0' => ts('No'), '1' => ts('Yes')),
241 'clause' => 'mailing_event_forward_civireport.id IS NULL',
242 ),
243 ),
244 'grouping' => 'mailing-fields',
245 );
246
247 $this->_columns['civicrm_email'] = array(
248 'dao' => 'CRM_Core_DAO_Email',
249 'fields' =>
250 array(
251 'email' =>
252 array(
253 'title' => ts('Email'),
254 'required' => TRUE,
255 ),
256 ),
257 'grouping' => 'contact-fields',
258 );
259
260 $this->_columns['civicrm_phone'] = array(
261 'dao' => 'CRM_Core_DAO_Phone',
262 'fields' => array('phone' => NULL),
263 'grouping' => 'contact-fields',
264 );
265
16e2e80c
CW
266 $this->_groupFilter = TRUE;
267 $this->_tagFilter = TRUE;
6a488035
TO
268
269 parent::__construct();
270 }
271
272 function select() {
273 $select = $columns = array();
274 foreach ($this->_columns as $tableName => $table) {
275 if (array_key_exists('fields', $table)) {
276 foreach ($table['fields'] as $fieldName => $field) {
8cc574cf 277 if (!empty($field['required']) || !empty($this->_params['fields'][$fieldName])) {
6a488035
TO
278 if (in_array($fieldName, array(
279 'unsubscribe_id', 'optout_id', 'forward_id', 'reply_id'))) {
280 $select[] = "IF({$field['dbAlias']} IS NULL, 'No', 'Yes') as {$tableName}_{$fieldName}";
281 $this->_columnHeaders["{$tableName}_{$fieldName}"]['type'] = CRM_Utils_Array::value('type', $field);
282 $this->_columnHeaders["{$tableName}_{$fieldName}"]['no_display'] = CRM_Utils_Array::value('no_display', $field);
283 $this->_columnHeaders["{$tableName}_{$fieldName}"]['title'] = CRM_Utils_Array::value('title', $field);
284 unset($this->_columns[$tableName]['fields'][$fieldName]);
285 $columns[$tableName][$fieldName] = $field;
286 }
287 elseif ($fieldName == 'delivery_id') {
288 $select[] = "IF(mailing_event_delivered_civireport.id IS NOT NULL, 'Successful', IF(mailing_event_bounce_civireport.id IS NOT NULL, 'Bounced ', 'Unknown')) as {$tableName}_{$fieldName}";
289 $this->_columnHeaders["{$tableName}_{$fieldName}"]['type'] = CRM_Utils_Array::value('type', $field);
290 $this->_columnHeaders["{$tableName}_{$fieldName}"]['no_display'] = CRM_Utils_Array::value('no_display', $field);
291 $this->_columnHeaders["{$tableName}_{$fieldName}"]['title'] = CRM_Utils_Array::value('title', $field);
292 unset($this->_columns[$tableName]['fields'][$fieldName]);
293 $columns[$tableName][$fieldName] = $field;
294 }
295 }
296 }
297 }
298 }
299
300 parent::select();
301 if (!empty($select)) {
302 $this->_select .= ', ' . implode(', ', $select) . " ";
303 }
304
305 // put the fields that were unset, back in place
306 foreach ($columns as $tableName => $table) {
307 foreach ($table as $fieldName => $fields) {
308 $this->_columns[$tableName]['fields'][$fieldName] = $fields;
309 }
310 }
311
312 // simple sort
313 ksort($this->_columnHeaders);
314 }
315
316 function from() {
317 $this->_from = "
318 FROM civicrm_contact {$this->_aliases['civicrm_contact']}";
319
320 $this->_from .= "
2f4c2f5d 321 INNER JOIN civicrm_mailing_event_queue
322 ON civicrm_mailing_event_queue.contact_id = {$this->_aliases['civicrm_contact']}.id
323 INNER JOIN civicrm_email {$this->_aliases['civicrm_email']}
324 ON civicrm_mailing_event_queue.email_id = {$this->_aliases['civicrm_email']}.id";
6a488035
TO
325
326 if (array_key_exists('delivery_id', $this->_params['fields'])) {
327 $this->_from .= "
328 LEFT JOIN civicrm_mailing_event_delivered {$this->_aliases['civicrm_mailing_event_delivered']}
329 ON {$this->_aliases['civicrm_mailing_event_delivered']}.event_queue_id = civicrm_mailing_event_queue.id
2f4c2f5d 330 LEFT JOIN civicrm_mailing_event_bounce {$this->_aliases['civicrm_mailing_event_bounce']}
331 ON {$this->_aliases['civicrm_mailing_event_bounce']}.event_queue_id = civicrm_mailing_event_queue.id";
6a488035
TO
332 if (CRM_Utils_Array::value('delivery_status_value', $this->_params) == 'bounced') {
333 $this->_columns['civicrm_mailing_event_delivered']['filters']['delivery_status']['clause'] = "{$this->_aliases['civicrm_mailing_event_bounce']}.id IS NOT NULL";
334 }
335 elseif (CRM_Utils_Array::value('delivery_status_value', $this->_params) == 'successful') {
336 $this->_columns['civicrm_mailing_event_delivered']['filters']['delivery_status']['clause'] = "{$this->_aliases['civicrm_mailing_event_delivered']}.id IS NOT NULL";
337 }
338 }
339 else {
340 unset($this->_columns['civicrm_mailing_event_delivered']['filters']['delivery_status']);
341 }
342
343 if (array_key_exists('reply_id', $this->_params['fields']) ||
344 is_numeric(CRM_Utils_Array::value('is_replied_value', $this->_params))
345 ) {
346 if (CRM_Utils_Array::value('is_replied_value', $this->_params) == 1) {
347 $joinType = 'INNER';
348 $this->_columns['civicrm_mailing_event_reply']['filters']['is_replied']['clause'] = '(1)';
349 }
350 else {
351 $joinType = 'LEFT';
352 }
353 $this->_from .= "
354 {$joinType} JOIN civicrm_mailing_event_reply {$this->_aliases['civicrm_mailing_event_reply']}
355 ON {$this->_aliases['civicrm_mailing_event_reply']}.event_queue_id = civicrm_mailing_event_queue.id";
356 }
357 else {
358 unset($this->_columns['civicrm_mailing_event_reply']['filters']['is_replied']);
359 }
360
361 if (array_key_exists('unsubscribe_id', $this->_params['fields']) ||
362 is_numeric(CRM_Utils_Array::value('is_unsubscribed_value', $this->_params))
363 ) {
364 if (CRM_Utils_Array::value('is_unsubscribed_value', $this->_params) == 1) {
365 $joinType = 'INNER';
366 $this->_columns['civicrm_mailing_event_unsubscribe']['filters']['is_unsubscribed']['clause'] = '(1)';
367 }
368 else {
369 $joinType = 'LEFT';
370 }
371 $this->_from .= "
372 {$joinType} JOIN civicrm_mailing_event_unsubscribe {$this->_aliases['civicrm_mailing_event_unsubscribe']}
373 ON {$this->_aliases['civicrm_mailing_event_unsubscribe']}.event_queue_id = civicrm_mailing_event_queue.id
374 AND {$this->_aliases['civicrm_mailing_event_unsubscribe']}.org_unsubscribe = 0";
375 }
376 else {
377 unset($this->_columns['civicrm_mailing_event_unsubscribe']['filters']['is_unsubscribed']);
378 }
379
380 if (array_key_exists('optout_id', $this->_params['fields']) ||
381 is_numeric(CRM_Utils_Array::value('is_optout_value', $this->_params))
382 ) {
383 if (CRM_Utils_Array::value('is_optout_value', $this->_params) == 1) {
384 $joinType = 'INNER';
385 $this->_columns['civicrm_mailing_event_unsubscribe']['filters']['is_optout']['clause'] = '(1)';
386 }
387 else {
388 $joinType = 'LEFT';
389 }
390 $this->_from .= "
391 {$joinType} JOIN civicrm_mailing_event_unsubscribe {$this->_aliases['civicrm_mailing_event_unsubscribe']}2
392 ON {$this->_aliases['civicrm_mailing_event_unsubscribe']}2.event_queue_id = civicrm_mailing_event_queue.id
393 AND {$this->_aliases['civicrm_mailing_event_unsubscribe']}2.org_unsubscribe = 1";
394 }
395 else {
396 unset($this->_columns['civicrm_mailing_event_unsubscribe']['filters']['is_optout']);
397 }
398
399 if (array_key_exists('forward_id', $this->_params['fields']) ||
400 is_numeric(CRM_Utils_Array::value('is_forwarded_value', $this->_params))
401 ) {
402 if (CRM_Utils_Array::value('is_forwarded_value', $this->_params) == 1) {
403 $joinType = 'INNER';
404 $this->_columns['civicrm_mailing_event_forward']['filters']['is_forwarded']['clause'] = '(1)';
405 }
406 else {
407 $joinType = 'LEFT';
408 }
409 $this->_from .= "
410 {$joinType} JOIN civicrm_mailing_event_forward {$this->_aliases['civicrm_mailing_event_forward']}
411 ON {$this->_aliases['civicrm_mailing_event_forward']}.event_queue_id = civicrm_mailing_event_queue.id";
412 }
413 else {
414 unset($this->_columns['civicrm_mailing_event_forward']['filters']['is_forwarded']);
415 }
416
417 $this->_from .= "
2f4c2f5d 418 INNER JOIN civicrm_mailing_job
419 ON civicrm_mailing_event_queue.job_id = civicrm_mailing_job.id
420 INNER JOIN civicrm_mailing {$this->_aliases['civicrm_mailing']}
421 ON civicrm_mailing_job.mailing_id = {$this->_aliases['civicrm_mailing']}.id
422 AND civicrm_mailing_job.is_test = 0";
6a488035
TO
423
424 if ($this->_phoneField) {
425 $this->_from .= "
2f4c2f5d 426 LEFT JOIN civicrm_phone {$this->_aliases['civicrm_phone']}
427 ON {$this->_aliases['civicrm_contact']}.id = {$this->_aliases['civicrm_phone']}.contact_id AND
6a488035
TO
428 {$this->_aliases['civicrm_phone']}.is_primary = 1 ";
429 }
430 }
431
432 function where() {
433 parent::where();
434 $this->_where .= " AND {$this->_aliases['civicrm_mailing']}.sms_provider_id IS NULL";
435 }
436
74cf4551
EM
437 /**
438 * @return array
439 */
6a488035
TO
440 function mailingList() {
441
442 $data = array();
443 $mailing = new CRM_Mailing_BAO_Mailing();
444 $query = "SELECT name FROM civicrm_mailing ";
445 $mailing->query($query);
446
447 while ($mailing->fetch()) {
448 $data[mysql_real_escape_string($mailing->name)] = $mailing->name;
449 }
450
451 return $data;
452 }
453
74cf4551
EM
454 /**
455 * @param $rows
456 */
6a488035
TO
457 function alterDisplay(&$rows) {
458 // custom code to alter rows
459 $entryFound = FALSE;
460 foreach ($rows as $rowNum => $row) {
461 // make count columns point to detail report
462 // convert display name to links
463 if (array_key_exists('civicrm_contact_sort_name', $row) &&
464 array_key_exists('civicrm_contact_id', $row)
465 ) {
466 $url = CRM_Utils_System::url('civicrm/contact/view',
467 'reset=1&cid=' . $row['civicrm_contact_id'],
468 $this->_absoluteUrl
469 );
470 $rows[$rowNum]['civicrm_contact_sort_name_link'] = $url;
471 $rows[$rowNum]['civicrm_contact_sort_name_hover'] = ts("View Contact details for this contact.");
472 $entryFound = TRUE;
473 }
474
475 // skip looking further in rows, if first row itself doesn't
476 // have the column we need
477 if (!$entryFound) {
478 break;
479 }
480 }
481 }
482}
483