Merge pull request #12611 from KarinG/FinancialAudit
[civicrm-core.git] / CRM / Report / Form / Activity.php
CommitLineData
6a488035 1<?php
6a488035
TO
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
8c9251b3 6 | Copyright CiviCRM LLC (c) 2004-2018 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
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. |
13 | |
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. |
18 | |
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
8c9251b3 31 * @copyright CiviCRM LLC (c) 2004-2018
6a488035
TO
32 */
33class CRM_Report_Form_Activity extends CRM_Report_Form {
1f220d30 34 protected $_selectAliasesTotal = array();
6a488035
TO
35
36 protected $_customGroupExtends = array(
21dfd5f5 37 'Activity',
430ae6dd
TO
38 );
39
09febbae 40 protected $_nonDisplayFields = array();
41
1728e9a0 42 /**
43 * This report has not been optimised for group filtering.
44 *
45 * The functionality for group filtering has been improved but not
46 * all reports have been adjusted to take care of it. This report has not
47 * and will run an inefficient query until fixed.
48 *
49 * CRM-19170
50 *
51 * @var bool
52 */
53 protected $groupFilterNotOptimised = TRUE;
54
74cf4551 55 /**
ab432335 56 * Class constructor.
74cf4551 57 */
00be9182 58 public function __construct() {
7116d719 59 // There could be multiple contacts. We not clear on which contact id to display.
83e74860
DS
60 // Lets hide it for now.
61 $this->_exposeContactID = FALSE;
8f621a01 62 // if navigated from count link of activity summary reports.
a3d827a7 63 $this->_resetDateFilter = CRM_Utils_Request::retrieve('resetDateFilter', 'Boolean');
83e74860 64
6a488035
TO
65 $config = CRM_Core_Config::singleton();
66 $campaignEnabled = in_array("CiviCampaign", $config->enableComponents);
d6c3d40f 67 $caseEnabled = in_array("CiviCase", $config->enableComponents);
6a488035
TO
68 if ($campaignEnabled) {
69 $getCampaigns = CRM_Campaign_BAO_Campaign::getPermissionedCampaigns(NULL, NULL, TRUE, FALSE, TRUE);
70 $this->activeCampaigns = $getCampaigns['campaigns'];
71 asort($this->activeCampaigns);
72 $this->engagementLevels = CRM_Campaign_PseudoConstant::engagementLevel();
73 }
6a488035 74
1023b3bc 75 $components = CRM_Core_Component::getEnabledComponents();
76 foreach ($components as $componentName => $componentInfo) {
d3e6c71f 77 // CRM-19201: Add support for reporting CiviCampaign activities
44d17ec8
BS
78 // For CiviCase, "access all cases and activities" is required here
79 // rather than "access my cases and activities" to prevent those with
80 // only the later permission from seeing a list of all cases which might
81 // present a privacy issue.
82 if (CRM_Core_Permission::access($componentName, TRUE, TRUE)) {
1023b3bc 83 $accessAllowed[] = $componentInfo->componentID;
84 }
85 }
86
87 $include = '';
88 if (!empty($accessAllowed)) {
89 $include = 'OR v.component_id IN (' . implode(', ', $accessAllowed) . ')';
90 }
91 $condition = " AND ( v.component_id IS NULL {$include} )";
92 $this->activityTypes = CRM_Core_OptionGroup::values('activity_type', FALSE, FALSE, FALSE, $condition);
93 asort($this->activityTypes);
d47468d0 94
95 // @todo split the 3 different contact tables into their own array items.
96 // this will massively simplify the needs of this report.
6a488035 97 $this->_columns = array(
af9b09df
TO
98 'civicrm_contact' => array(
99 'dao' => 'CRM_Contact_DAO_Contact',
100 'fields' => array(
101 'contact_source' => array(
102 'name' => 'sort_name',
8c0ff2a6 103 'title' => ts('Source Name'),
af9b09df
TO
104 'alias' => 'civicrm_contact_source',
105 'no_repeat' => TRUE,
6a488035 106 ),
af9b09df
TO
107 'contact_assignee' => array(
108 'name' => 'sort_name',
8c0ff2a6 109 'title' => ts('Assignee Name'),
af9b09df
TO
110 'alias' => 'civicrm_contact_assignee',
111 'dbAlias' => "civicrm_contact_assignee.sort_name",
112 'default' => TRUE,
113 ),
114 'contact_target' => array(
115 'name' => 'sort_name',
8c0ff2a6 116 'title' => ts('Target Name'),
af9b09df
TO
117 'alias' => 'civicrm_contact_target',
118 'dbAlias' => "civicrm_contact_target.sort_name",
119 'default' => TRUE,
120 ),
121 'contact_source_id' => array(
122 'name' => 'id',
123 'alias' => 'civicrm_contact_source',
124 'dbAlias' => "civicrm_contact_source.id",
125 'no_display' => TRUE,
126 'default' => TRUE,
127 'required' => TRUE,
128 ),
129 'contact_assignee_id' => array(
130 'name' => 'id',
131 'alias' => 'civicrm_contact_assignee',
132 'dbAlias' => "civicrm_contact_assignee.id",
133 'no_display' => TRUE,
134 'default' => TRUE,
135 'required' => TRUE,
136 ),
137 'contact_target_id' => array(
138 'name' => 'id',
139 'alias' => 'civicrm_contact_target',
140 'dbAlias' => "civicrm_contact_target.id",
141 'no_display' => TRUE,
142 'default' => TRUE,
143 'required' => TRUE,
482691e1 144 ),
6a488035 145 ),
af9b09df
TO
146 'filters' => array(
147 'contact_source' => array(
148 'name' => 'sort_name',
149 'alias' => 'civicrm_contact_source',
8c0ff2a6 150 'title' => ts('Source Name'),
af9b09df
TO
151 'operator' => 'like',
152 'type' => CRM_Report_Form::OP_STRING,
6a488035 153 ),
af9b09df
TO
154 'contact_assignee' => array(
155 'name' => 'sort_name',
156 'alias' => 'civicrm_contact_assignee',
8c0ff2a6 157 'title' => ts('Assignee Name'),
af9b09df
TO
158 'operator' => 'like',
159 'type' => CRM_Report_Form::OP_STRING,
160 ),
161 'contact_target' => array(
162 'name' => 'sort_name',
163 'alias' => 'civicrm_contact_target',
8c0ff2a6 164 'title' => ts('Target Name'),
af9b09df
TO
165 'operator' => 'like',
166 'type' => CRM_Report_Form::OP_STRING,
167 ),
168 'current_user' => array(
169 'name' => 'current_user',
170 'title' => ts('Limit To Current User'),
171 'type' => CRM_Utils_Type::T_INT,
172 'operatorType' => CRM_Report_Form::OP_SELECT,
173 'options' => array('0' => ts('No'), '1' => ts('Yes')),
6a488035
TO
174 ),
175 ),
af9b09df
TO
176 'grouping' => 'contact-fields',
177 ),
178 'civicrm_email' => array(
179 'dao' => 'CRM_Core_DAO_Email',
180 'fields' => array(
181 'contact_source_email' => array(
182 'name' => 'email',
8c0ff2a6 183 'title' => ts('Source Email'),
af9b09df 184 'alias' => 'civicrm_email_source',
6a488035 185 ),
af9b09df
TO
186 'contact_assignee_email' => array(
187 'name' => 'email',
8c0ff2a6 188 'title' => ts('Assignee Email'),
af9b09df 189 'alias' => 'civicrm_email_assignee',
6a488035 190 ),
af9b09df
TO
191 'contact_target_email' => array(
192 'name' => 'email',
8c0ff2a6 193 'title' => ts('Target Email'),
af9b09df 194 'alias' => 'civicrm_email_target',
6a488035
TO
195 ),
196 ),
af9b09df
TO
197 'order_bys' => array(
198 'source_contact_email' => array(
199 'name' => 'email',
8c0ff2a6 200 'title' => ts('Source Email'),
af9b09df 201 'dbAlias' => 'civicrm_email_contact_source_email',
6a488035
TO
202 ),
203 ),
af9b09df 204 ),
8c0ff2a6 205 'civicrm_phone' => array(
206 'dao' => 'CRM_Core_DAO_Phone',
207 'fields' => array(
208 'contact_source_phone' => array(
209 'name' => 'phone',
210 'title' => ts('Source Phone'),
211 'alias' => 'civicrm_phone_source',
212 ),
213 'contact_assignee_phone' => array(
214 'name' => 'phone',
215 'title' => ts('Assignee Phone'),
216 'alias' => 'civicrm_phone_assignee',
217 ),
218 'contact_target_phone' => array(
219 'name' => 'phone',
2afe8e0c 220 'title' => ts('Target Phone'),
8c0ff2a6 221 'alias' => 'civicrm_phone_target',
222 ),
223 ),
224 ),
af9b09df
TO
225 'civicrm_activity' => array(
226 'dao' => 'CRM_Activity_DAO_Activity',
227 'fields' => array(
228 'id' => array(
229 'no_display' => TRUE,
230 'title' => ts('Activity ID'),
231 'required' => TRUE,
232 ),
233 'source_record_id' => array(
234 'no_display' => TRUE,
235 'required' => TRUE,
236 ),
237 'activity_type_id' => array(
238 'title' => ts('Activity Type'),
239 'required' => TRUE,
240 'type' => CRM_Utils_Type::T_STRING,
241 ),
242 'activity_subject' => array(
243 'title' => ts('Subject'),
244 'default' => TRUE,
245 ),
246 'activity_date_time' => array(
247 'title' => ts('Activity Date'),
248 'required' => TRUE,
249 ),
250 'status_id' => array(
251 'title' => ts('Activity Status'),
252 'default' => TRUE,
253 'type' => CRM_Utils_Type::T_STRING,
254 ),
255 'duration' => array(
256 'title' => ts('Duration'),
257 'type' => CRM_Utils_Type::T_INT,
667abe3a 258 ),
c02f870b
JM
259 'location' => array(
260 'title' => ts('Location'),
261 'type' => CRM_Utils_Type::T_STRING,
262 ),
1efec7ff
DG
263 'details' => array(
264 'title' => ts('Activity Details'),
af9b09df 265 ),
da236f9a 266 'priority_id' => array(
267 'title' => ts('Priority'),
268 'default' => TRUE,
269 'type' => CRM_Utils_Type::T_STRING,
270 ),
6a488035 271 ),
1efec7ff
DG
272 'filters' => array(
273 'activity_date_time' => array(
1a6c8513 274 'default' => 'this.month',
6a488035
TO
275 'operatorType' => CRM_Report_Form::OP_DATE,
276 ),
af9b09df
TO
277 'activity_subject' => array('title' => ts('Activity Subject')),
278 'activity_type_id' => array(
279 'title' => ts('Activity Type'),
280 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
281 'options' => $this->activityTypes,
282 ),
283 'status_id' => array(
284 'title' => ts('Activity Status'),
8ee006e7 285 'type' => CRM_Utils_Type::T_STRING,
af9b09df
TO
286 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
287 'options' => CRM_Core_PseudoConstant::activityStatus(),
288 ),
c02f870b
JM
289 'location' => array(
290 'title' => ts('Location'),
291 'type' => CRM_Utils_Type::T_TEXT,
292 ),
1efec7ff
DG
293 'details' => array(
294 'title' => ts('Activity Details'),
295 'type' => CRM_Utils_Type::T_TEXT,
af9b09df 296 ),
71c30391 297 'priority_id' => array(
298 'title' => ts('Activity Priority'),
410e8105 299 'type' => CRM_Utils_Type::T_STRING,
71c30391 300 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
301 'options' => CRM_Core_PseudoConstant::get('CRM_Activity_DAO_Activity', 'priority_id'),
302 ),
af9b09df
TO
303 ),
304 'order_bys' => array(
305 'activity_date_time' => array(
306 'title' => ts('Activity Date'),
307 'default_weight' => '1',
308 'dbAlias' => 'civicrm_activity_activity_date_time',
309 ),
310 'activity_type_id' => array(
311 'title' => ts('Activity Type'),
312 'default_weight' => '2',
56bbb442 313 'dbAlias' => 'field(civicrm_activity_activity_type_id, ' . implode(', ', array_keys($this->activityTypes)) . ')',
af9b09df
TO
314 ),
315 ),
316 'grouping' => 'activity-fields',
317 'alias' => 'activity',
318 ),
56bbb442 319 // Hack to get $this->_alias populated for the table.
af9b09df
TO
320 'civicrm_activity_contact' => array(
321 'dao' => 'CRM_Activity_DAO_ActivityContact',
a0375fa3 322 'fields' => array(),
af9b09df
TO
323 ),
324 ) + $this->addressFields(TRUE);
6a488035 325
d6c3d40f 326 if ($caseEnabled && CRM_Core_Permission::check('access all cases and activities')) {
d6c3d40f 327 $this->_columns['civicrm_activity']['filters']['include_case_activities'] = array(
328 'name' => 'include_case_activities',
329 'title' => ts('Include Case Activities'),
330 'type' => CRM_Utils_Type::T_INT,
331 'operatorType' => CRM_Report_Form::OP_SELECT,
332 'options' => array('0' => ts('No'), '1' => ts('Yes')),
333 );
334 }
335
6a488035
TO
336 if ($campaignEnabled) {
337 // Add display column and filter for Survey Results, Campaign and Engagement Index if CiviCampaign is enabled
338
339 $this->_columns['civicrm_activity']['fields']['result'] = array(
fd6a6828 340 'title' => ts('Survey Result'),
6a488035
TO
341 'default' => 'false',
342 );
9d72cede
EM
343 $this->_columns['civicrm_activity']['filters']['result'] = array(
344 'title' => ts('Survey Result'),
6a488035
TO
345 'operator' => 'like',
346 'type' => CRM_Utils_Type::T_STRING,
347 );
348 if (!empty($this->activeCampaigns)) {
349 $this->_columns['civicrm_activity']['fields']['campaign_id'] = array(
fd6a6828 350 'title' => ts('Campaign'),
6a488035
TO
351 'default' => 'false',
352 );
9d72cede
EM
353 $this->_columns['civicrm_activity']['filters']['campaign_id'] = array(
354 'title' => ts('Campaign'),
09b5cdcf 355 'type' => CRM_Utils_Type::T_INT,
6a488035
TO
356 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
357 'options' => $this->activeCampaigns,
358 );
359 }
360 if (!empty($this->engagementLevels)) {
361 $this->_columns['civicrm_activity']['fields']['engagement_level'] = array(
fd6a6828 362 'title' => ts('Engagement Index'),
6a488035
TO
363 'default' => 'false',
364 );
9d72cede
EM
365 $this->_columns['civicrm_activity']['filters']['engagement_level'] = array(
366 'title' => ts('Engagement Index'),
09b5cdcf 367 'type' => CRM_Utils_Type::T_INT,
6a488035
TO
368 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
369 'options' => $this->engagementLevels,
370 );
371 }
372 }
373 $this->_groupFilter = TRUE;
374 $this->_tagFilter = TRUE;
ed795723 375 $this->_tagFilterTable = 'civicrm_activity';
6a488035
TO
376 parent::__construct();
377 }
378
be2e0c6a
TO
379 /**
380 * Adding address fields with dbAlias for order clause.
ab432335
EM
381 *
382 * @param bool $orderBy
383 *
a6c01b45 384 * @return array
ab432335 385 * Address fields
667abe3a 386 */
00be9182 387 public function addressFields($orderBy = FALSE) {
667abe3a 388 $address = parent::addAddressFields(FALSE, TRUE);
389 if ($orderBy) {
390 foreach ($address['civicrm_address']['order_bys'] as $fieldName => $field) {
391 $address['civicrm_address']['order_bys'][$fieldName]['dbAlias'] = "civicrm_address_{$fieldName}";
392 }
393 }
394 return $address;
395 }
396
74cf4551 397 /**
a0375fa3 398 * Build select clause.
399 *
d47468d0 400 * @todo get rid of $recordType param. It's only because 3 separate contact tables
401 * are mis-declared as one that we need it.
402 *
403 * @param null $recordType deprecated
404 * Parameter to hack around the bad decision made in construct to misrepresent
405 * different tables as the same table.
74cf4551 406 */
3ede1c56 407 public function select($recordType = 'target') {
9d72cede
EM
408 if (!array_key_exists("contact_{$recordType}", $this->_params['fields']) &&
409 $recordType != 'final'
410 ) {
09febbae 411 $this->_nonDisplayFields[] = "civicrm_contact_contact_{$recordType}";
09febbae 412 }
1f220d30 413 parent::select();
1f220d30 414
09febbae 415 if ($recordType == 'final' && !empty($this->_nonDisplayFields)) {
416 foreach ($this->_nonDisplayFields as $fieldName) {
417 unset($this->_columnHeaders[$fieldName]);
418 }
419 }
420
1f220d30
DS
421 if (empty($this->_selectAliasesTotal)) {
422 $this->_selectAliasesTotal = $this->_selectAliases;
423 }
424
425 $removeKeys = array();
426 if ($recordType == 'target') {
d47468d0 427 // @todo - fix up the way the tables are declared in construct & remove this.
1f220d30 428 foreach ($this->_selectClauses as $key => $clause) {
7116d719 429 if (strstr($clause, 'civicrm_contact_assignee.') ||
1f220d30
DS
430 strstr($clause, 'civicrm_contact_source.') ||
431 strstr($clause, 'civicrm_email_assignee.') ||
8c0ff2a6 432 strstr($clause, 'civicrm_email_source.') ||
433 strstr($clause, 'civicrm_phone_assignee.') ||
434 strstr($clause, 'civicrm_phone_source.')
1f220d30
DS
435 ) {
436 $removeKeys[] = $key;
437 unset($this->_selectClauses[$key]);
438 }
439 }
9d72cede 440 }
4c9b6178 441 elseif ($recordType == 'assignee') {
d47468d0 442 // @todo - fix up the way the tables are declared in construct & remove this.
1f220d30 443 foreach ($this->_selectClauses as $key => $clause) {
7116d719 444 if (strstr($clause, 'civicrm_contact_target.') ||
1f220d30
DS
445 strstr($clause, 'civicrm_contact_source.') ||
446 strstr($clause, 'civicrm_email_target.') ||
8c0ff2a6 447 strstr($clause, 'civicrm_email_source.') ||
448 strstr($clause, 'civicrm_phone_target.') ||
c00963a1 449 strstr($clause, 'civicrm_phone_source.') ||
450 strstr($clause, 'civicrm_address_')
1f220d30
DS
451 ) {
452 $removeKeys[] = $key;
453 unset($this->_selectClauses[$key]);
454 }
455 }
9d72cede 456 }
4c9b6178 457 elseif ($recordType == 'source') {
d47468d0 458 // @todo - fix up the way the tables are declared in construct & remove this.
1f220d30 459 foreach ($this->_selectClauses as $key => $clause) {
7116d719 460 if (strstr($clause, 'civicrm_contact_target.') ||
1f220d30
DS
461 strstr($clause, 'civicrm_contact_assignee.') ||
462 strstr($clause, 'civicrm_email_target.') ||
8c0ff2a6 463 strstr($clause, 'civicrm_email_assignee.') ||
464 strstr($clause, 'civicrm_phone_target.') ||
c00963a1 465 strstr($clause, 'civicrm_phone_assignee.') ||
466 strstr($clause, 'civicrm_address_')
1f220d30
DS
467 ) {
468 $removeKeys[] = $key;
469 unset($this->_selectClauses[$key]);
470 }
471 }
9d72cede 472 }
4c9b6178 473 elseif ($recordType == 'final') {
1f220d30
DS
474 $this->_selectClauses = $this->_selectAliasesTotal;
475 foreach ($this->_selectClauses as $key => $clause) {
d47468d0 476 // @todo - fix up the way the tables are declared in construct & remove this.
7116d719 477 if (strstr($clause, 'civicrm_contact_contact_target') ||
1f220d30 478 strstr($clause, 'civicrm_contact_contact_assignee') ||
8c0ff2a6 479 strstr($clause, 'civicrm_contact_contact_source') ||
480 strstr($clause, 'civicrm_phone_contact_source_phone') ||
481 strstr($clause, 'civicrm_phone_contact_assignee_phone') ||
482 strstr($clause, 'civicrm_email_contact_source_email') ||
483 strstr($clause, 'civicrm_email_contact_assignee_email') ||
484 strstr($clause, 'civicrm_email_contact_target_email') ||
66ad82d6 485 strstr($clause, 'civicrm_phone_contact_target_phone') ||
486 strstr($clause, 'civicrm_address_')
9d72cede 487 ) {
66ad82d6 488 $this->_selectClauses[$key] = "GROUP_CONCAT(DISTINCT $clause SEPARATOR ';') as $clause";
6a488035
TO
489 }
490 }
491 }
492
1f220d30
DS
493 if ($recordType) {
494 foreach ($removeKeys as $key) {
495 unset($this->_selectAliases[$key]);
496 }
497
c00963a1 498 if ($recordType == 'target') {
667abe3a 499 foreach ($this->_columns['civicrm_address']['order_bys'] as $fieldName => $field) {
500 $orderByFld = $this->_columns['civicrm_address']['order_bys'][$fieldName];
501 $fldInfo = $this->_columns['civicrm_address']['fields'][$fieldName];
502 $this->_selectAliases[] = $orderByFld['dbAlias'];
503 $this->_selectClauses[] = "{$fldInfo['dbAlias']} as {$orderByFld['dbAlias']}";
504 }
667abe3a 505 $this->_selectAliases = array_unique($this->_selectAliases);
506 $this->_selectClauses = array_unique($this->_selectClauses);
507 }
1f220d30 508 $this->_select = "SELECT " . implode(', ', $this->_selectClauses) . " ";
1f220d30 509 }
6a488035
TO
510 }
511
74cf4551 512 /**
a0375fa3 513 * Build from clause.
d47468d0 514 * @todo remove this function & declare the 3 contact tables separately
74cf4551 515 */
d47468d0 516 public function from() {
44f817d4 517 $activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate');
9d72cede 518 $targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts);
8c0ff2a6 519
d47468d0 520 $this->_from = "
521 FROM civicrm_activity {$this->_aliases['civicrm_activity']}
522 INNER JOIN civicrm_activity_contact {$this->_aliases['civicrm_activity_contact']}
523 ON {$this->_aliases['civicrm_activity']}.id = {$this->_aliases['civicrm_activity_contact']}.activity_id AND
524 {$this->_aliases['civicrm_activity_contact']}.record_type_id = {$targetID}
525 INNER JOIN civicrm_contact civicrm_contact_target
526 ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_contact_target.id
527 {$this->_aclFrom}";
528
529 if ($this->isTableSelected('civicrm_email')) {
530 $this->_from .= "
531 LEFT JOIN civicrm_email civicrm_email_target
532 ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_email_target.contact_id AND
533 civicrm_email_target.is_primary = 1";
2f4b4d54
DS
534 }
535
d47468d0 536 if ($this->isTableSelected('civicrm_phone')) {
537 $this->_from .= "
538 LEFT JOIN civicrm_phone civicrm_phone_target
539 ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_phone_target.contact_id AND
540 civicrm_phone_target.is_primary = 1 ";
6a488035 541 }
d47468d0 542 $this->_aliases['civicrm_contact'] = 'civicrm_contact_target';
56bbb442 543
e3c74b61 544 $this->joinAddressFromContact();
6a488035
TO
545 }
546
74cf4551 547 /**
a0375fa3 548 * Build where clause.
549 *
d47468d0 550 * @todo get rid of $recordType param. It's only because 3 separate contact tables
551 * are mis-declared as one that we need it.
552 *
a0375fa3 553 * @param string $recordType
74cf4551 554 */
00be9182 555 public function where($recordType = NULL) {
2f4b4d54 556 $this->_where = " WHERE {$this->_aliases['civicrm_activity']}.is_test = 0 AND
6a488035
TO
557 {$this->_aliases['civicrm_activity']}.is_deleted = 0 AND
558 {$this->_aliases['civicrm_activity']}.is_current_revision = 1";
559
560 $clauses = array();
561 foreach ($this->_columns as $tableName => $table) {
562 if (array_key_exists('filters', $table)) {
563
564 foreach ($table['filters'] as $fieldName => $field) {
565 $clause = NULL;
7116d719 566 if ($fieldName != 'contact_' . $recordType &&
567 (strstr($fieldName, '_target') ||
568 strstr($fieldName, '_assignee') ||
569 strstr($fieldName, '_source')
570 )
571 ) {
7116d719 572 continue;
573 }
6a488035
TO
574 if (CRM_Utils_Array::value('type', $field) & CRM_Utils_Type::T_DATE) {
575 $relative = CRM_Utils_Array::value("{$fieldName}_relative", $this->_params);
9d72cede
EM
576 $from = CRM_Utils_Array::value("{$fieldName}_from", $this->_params);
577 $to = CRM_Utils_Array::value("{$fieldName}_to", $this->_params);
6a488035
TO
578
579 $clause = $this->dateClause($field['name'], $relative, $from, $to, $field['type']);
580 }
581 else {
582 $op = CRM_Utils_Array::value("{$fieldName}_op", $this->_params);
024311d5 583 if ($op && ($op != 'nnll' && $op != 'nll')) {
6a488035
TO
584 $clause = $this->whereClause($field,
585 $op,
586 CRM_Utils_Array::value("{$fieldName}_value", $this->_params),
587 CRM_Utils_Array::value("{$fieldName}_min", $this->_params),
588 CRM_Utils_Array::value("{$fieldName}_max", $this->_params)
589 );
d6c3d40f 590 if ($field['name'] == 'include_case_activities') {
591 $clause = NULL;
592 }
9d72cede
EM
593 if ($fieldName == 'activity_type_id' &&
594 empty($this->_params['activity_type_id_value'])
595 ) {
355b8a20 596 if (empty($this->_params['include_case_activities_value'])) {
597 $this->activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, FALSE, FALSE, 'label', TRUE);
598 }
1023b3bc 599 $actTypes = array_flip($this->activityTypes);
6c552737 600 $clause = "( {$this->_aliases['civicrm_activity']}.activity_type_id IN (" .
9d72cede 601 implode(',', $actTypes) . ") )";
42b3be07 602 }
6a488035
TO
603 }
604 }
605
606 if ($field['name'] == 'current_user') {
9d72cede
EM
607 if (CRM_Utils_Array::value("{$fieldName}_value", $this->_params) ==
608 1
609 ) {
6a488035
TO
610 // get current user
611 $session = CRM_Core_Session::singleton();
612 if ($contactID = $session->get('userID')) {
389cfee7 613 $clause = "{$this->_aliases['civicrm_activity_contact']}.activity_id IN
614 (SELECT activity_id FROM civicrm_activity_contact WHERE contact_id = {$contactID})";
6a488035
TO
615 }
616 else {
617 $clause = NULL;
618 }
619 }
620 else {
621 $clause = NULL;
622 }
623 }
624 if (!empty($clause)) {
625 $clauses[] = $clause;
626 }
627 }
628 }
629 }
630
631 if (empty($clauses)) {
b6cab294 632 $this->_where .= " ";
6a488035
TO
633 }
634 else {
b6cab294 635 $this->_where .= " AND " . implode(' AND ', $clauses);
6a488035
TO
636 }
637
638 if ($this->_aclWhere) {
639 $this->_where .= " AND {$this->_aclWhere} ";
640 }
641 }
642
a0375fa3 643 /**
644 * Override group by function.
645 */
00be9182 646 public function groupBy() {
b708c08d 647 $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, "{$this->_aliases['civicrm_activity']}.id");
6a488035
TO
648 }
649
74cf4551 650 /**
a0375fa3 651 * Build ACL clause.
652 *
74cf4551
EM
653 * @param string $tableAlias
654 */
00be9182 655 public function buildACLClause($tableAlias = 'contact_a') {
2a3c101f 656 //override for ACL( Since Contact may be source
6a488035
TO
657 //contact/assignee or target also it may be null )
658
659 if (CRM_Core_Permission::check('view all contacts')) {
660 $this->_aclFrom = $this->_aclWhere = NULL;
661 return;
662 }
663
664 $session = CRM_Core_Session::singleton();
665 $contactID = $session->get('userID');
666 if (!$contactID) {
667 $contactID = 0;
668 }
669 $contactID = CRM_Utils_Type::escape($contactID, 'Integer');
670
671 CRM_Contact_BAO_Contact_Permission::cache($contactID);
672 $clauses = array();
673 foreach ($tableAlias as $k => $alias) {
674 $clauses[] = " INNER JOIN civicrm_acl_contact_cache aclContactCache_{$k} ON ( {$alias}.id = aclContactCache_{$k}.contact_id OR {$alias}.id IS NULL ) AND aclContactCache_{$k}.user_id = $contactID ";
675 }
676
677 $this->_aclFrom = implode(" ", $clauses);
678 $this->_aclWhere = NULL;
679 }
680
74cf4551 681 /**
100fef9d 682 * @param int $groupID
74cf4551
EM
683 *
684 * @throws Exception
685 */
00be9182 686 public function add2group($groupID) {
9a2f601e 687 if (CRM_Utils_Array::value("contact_target_op", $this->_params) == 'nll') {
688 CRM_Core_Error::fatal(ts('Current filter criteria didn\'t have any target contact to add to group'));
689 }
690
7f6464a0
JM
691 $new_select = 'AS addtogroup_contact_id';
692 $select = str_ireplace('AS civicrm_contact_contact_target_id', $new_select, $this->_select);
693 $new_having = ' addtogroup_contact_id';
694 $having = str_ireplace(' civicrm_contact_contact_target_id', $new_having, $this->_having);
695 $query = "$select
5a14305b 696FROM {$this->temporaryTables['activity_temp_table']} tar
7f6464a0 697GROUP BY civicrm_activity_id $having {$this->_orderBy}";
9a2f601e 698 $select = 'AS addtogroup_contact_id';
699 $query = str_ireplace('AS civicrm_contact_contact_target_id', $select, $query);
f38e3c19 700 $dao = $this->executeReportQuery($query);
9a2f601e 701
702 $contactIDs = array();
703 // Add resulting contacts to group
704 while ($dao->fetch()) {
705 if ($dao->addtogroup_contact_id) {
706 $contact_id = explode(';', $dao->addtogroup_contact_id);
707 if ($contact_id[0]) {
7bb16323 708 $contactIDs[$contact_id[0]] = $contact_id[0];
9a2f601e 709 }
710 }
711 }
712
9d72cede 713 if (!empty($contactIDs)) {
9a2f601e 714 CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIDs, $groupID);
715 CRM_Core_Session::setStatus(ts("Listed contact(s) have been added to the selected group."), ts('Contacts Added'), 'success');
716 }
717 else {
718 CRM_Core_Session::setStatus(ts("The listed records(s) cannot be added to the group."));
719 }
720 }
721
d6c3d40f 722 /**
723 * @param $fields
724 * @param $files
725 * @param $self
726 *
727 * @return array
728 */
729 public static function formRule($fields, $files, $self) {
730 $errors = array();
355b8a20 731 $config = CRM_Core_Config::singleton();
732 if (in_array("CiviCase", $config->enableComponents)) {
733 $componentId = CRM_Core_Component::getComponentID('CiviCase');
734 $caseActivityTypes = CRM_Core_OptionGroup::values('activity_type', TRUE, FALSE, FALSE, " AND v.component_id={$componentId}");
735 if (!empty($fields['activity_type_id_value']) && is_array($fields['activity_type_id_value']) && empty($fields['include_case_activities_value'])) {
736 foreach ($fields['activity_type_id_value'] as $activityTypeId) {
737 if (in_array($activityTypeId, $caseActivityTypes)) {
738 $errors['fields'] = ts("Please enable 'Include Case Activities' to filter with Case Activity types.");
739 }
d6c3d40f 740 }
741 }
742 }
743 return $errors;
744 }
745
a1bf1058
ML
746 /**
747 * @param $applyLimit
748 *
749 * @return string
750 */
751 public function buildQuery($applyLimit = TRUE) {
44f817d4 752 $activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate');
52272965 753 $sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts);
2f4b4d54 754
389cfee7 755 //Assign those recordtype to array which have filter operator as 'Is not empty' or 'Is empty'
756 $nullFilters = array();
b6cab294 757 foreach (array('target', 'source', 'assignee') as $type) {
9d72cede
EM
758 if (CRM_Utils_Array::value("contact_{$type}_op", $this->_params) ==
759 'nnll' || !empty($this->_params["contact_{$type}_value"])
760 ) {
3ae89fd7 761 $nullFilters[] = " civicrm_contact_contact_{$type}_id IS NOT NULL ";
389cfee7 762 }
4c9b6178 763 elseif (CRM_Utils_Array::value("contact_{$type}_op", $this->_params) ==
9d72cede
EM
764 'nll'
765 ) {
3ae89fd7 766 $nullFilters[] = " civicrm_contact_contact_{$type}_id IS NULL ";
b6cab294 767 }
768 }
769
d47468d0 770 // @todo - all this temp table stuff is here because pre 4.4 the activity contact
771 // form did not exist.
772 // Fixing the way the construct method declares them will make all this redundant.
9d72cede 773 // 1. fill temp table with target results
6e5e50a9 774 $this->buildACLClause(array('civicrm_contact_target'));
1f220d30 775 $this->select('target');
d47468d0 776 $this->from();
5b1ba2b8 777 $this->customDataFrom();
389cfee7 778 $this->where('target');
5a14305b 779 $tempTableName = $this->createTemporaryTable('activity_temp_table', "{$this->_select} {$this->_from} {$this->_where}");
2f4b4d54 780
1f220d30
DS
781 // 2. add new columns to hold assignee and source results
782 // fixme: add when required
783 $tempQuery = "
5a14305b 784 ALTER TABLE $tempTableName
e7b3275b 785 MODIFY COLUMN civicrm_contact_contact_target_id VARCHAR(128),
1f220d30
DS
786 ADD COLUMN civicrm_contact_contact_assignee VARCHAR(128),
787 ADD COLUMN civicrm_contact_contact_source VARCHAR(128),
7116d719 788 ADD COLUMN civicrm_contact_contact_assignee_id VARCHAR(128),
482691e1 789 ADD COLUMN civicrm_contact_contact_source_id VARCHAR(128),
8c0ff2a6 790 ADD COLUMN civicrm_phone_contact_assignee_phone VARCHAR(128),
791 ADD COLUMN civicrm_phone_contact_source_phone VARCHAR(128),
1f220d30
DS
792 ADD COLUMN civicrm_email_contact_assignee_email VARCHAR(128),
793 ADD COLUMN civicrm_email_contact_source_email VARCHAR(128)";
f38e3c19 794 $this->executeReportQuery($tempQuery);
1f220d30
DS
795
796 // 3. fill temp table with assignee results
6e5e50a9 797 $this->buildACLClause(array('civicrm_contact_assignee'));
389cfee7 798 $this->select('assignee');
d47468d0 799 $this->buildAssigneeFrom();
800
389cfee7 801 $this->customDataFrom();
802 $this->where('assignee');
803 $insertCols = implode(',', $this->_selectAliases);
5a14305b 804 $tempQuery = "INSERT INTO $tempTableName ({$insertCols})
1f220d30 805{$this->_select}
83e74860 806{$this->_from} {$this->_where}";
f38e3c19 807 $this->executeReportQuery($tempQuery);
2f4b4d54 808
1f220d30 809 // 4. fill temp table with source results
6e5e50a9 810 $this->buildACLClause(array('civicrm_contact_source'));
389cfee7 811 $this->select('source');
d47468d0 812 $this->buildSourceFrom();
389cfee7 813 $this->customDataFrom();
814 $this->where('source');
815 $insertCols = implode(',', $this->_selectAliases);
5a14305b 816 $tempQuery = "INSERT INTO $tempTableName ({$insertCols})
1f220d30 817{$this->_select}
83e74860 818{$this->_from} {$this->_where}";
f38e3c19 819 $this->executeReportQuery($tempQuery);
2f4b4d54 820
1f220d30 821 // 5. show final result set from temp table
2f4b4d54 822 $rows = array();
1f220d30 823 $this->select('final');
389cfee7 824 $this->_having = "";
825 if (!empty($nullFilters)) {
826 $this->_having = "HAVING " . implode(' AND ', $nullFilters);
827 }
83e74860 828 $this->orderBy();
ecf1e543 829 foreach ($this->_sections as $alias => $section) {
830 if (!empty($section) && $section['name'] == 'activity_date_time') {
5a14305b 831 $this->alterSectionHeaderForDateTime($tempTableName, $section['tplField']);
ecf1e543 832 }
e06df9af 833 }
a1bf1058
ML
834
835 if ($applyLimit) {
836 $this->limit();
837 }
838
d1641c51 839 $groupByFromSelect = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, 'civicrm_activity_id');
52272965 840
cbbc16ec 841 $this->_where = " WHERE (1)";
52272965 842 $this->buildPermissionClause();
cbbc16ec
TS
843 if ($this->_aclWhere) {
844 $this->_where .= " AND {$this->_aclWhere} ";
845 }
52272965 846
7116d719 847 $sql = "{$this->_select}
5a14305b 848 FROM $tempTableName tar
52272965
E
849 INNER JOIN civicrm_activity {$this->_aliases['civicrm_activity']} ON {$this->_aliases['civicrm_activity']}.id = tar.civicrm_activity_id
850 INNER JOIN civicrm_activity_contact {$this->_aliases['civicrm_activity_contact']} ON {$this->_aliases['civicrm_activity_contact']}.activity_id = {$this->_aliases['civicrm_activity']}.id
851 AND {$this->_aliases['civicrm_activity_contact']}.record_type_id = {$sourceID}
cbbc16ec
TS
852 LEFT JOIN civicrm_contact contact_civireport ON contact_civireport.id = {$this->_aliases['civicrm_activity_contact']}.contact_id
853 {$this->_where} {$groupByFromSelect} {$this->_having} {$this->_orderBy} {$this->_limit}";
52272965 854
a1bf1058 855 CRM_Utils_Hook::alterReportVar('sql', $this, $this);
cbbc16ec 856 $this->addToDeveloperTab($sql);
a1bf1058
ML
857
858 return $sql;
859 }
860
861 public function postProcess() {
862 //reset value of activity_date
863 if (!empty($this->_resetDateFilter)) {
864 $this->_formValues["activity_date_time_relative"] = NULL;
865 }
866
867 $this->beginPostProcess();
868 $sql = $this->buildQuery(TRUE);
2f4b4d54
DS
869 $this->buildRows($sql, $rows);
870
871 // format result set.
1f220d30 872 $this->formatDisplay($rows);
2f4b4d54
DS
873
874 // assign variables to templates
875 $this->doTemplateAssignment($rows);
876
877 // do print / pdf / instance stuff if needed
878 $this->endPostProcess($rows);
6a488035
TO
879 }
880
74cf4551 881 /**
4b62bc4f
EM
882 * Alter display of rows.
883 *
884 * Iterate through the rows retrieved via SQL and make changes for display purposes,
885 * such as rendering contacts as links.
886 *
887 * @param array $rows
888 * Rows generated by SQL, with an array for each row.
74cf4551 889 */
00be9182 890 public function alterDisplay(&$rows) {
9d72cede
EM
891 $entryFound = FALSE;
892 $activityType = CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'label', TRUE);
6a488035 893 $activityStatus = CRM_Core_PseudoConstant::activityStatus();
410e8105 894 $priority = CRM_Core_PseudoConstant::get('CRM_Activity_DAO_Activity', 'priority_id');
9d72cede 895 $viewLinks = FALSE;
f2e37338 896
d47468d0 897 // Would we ever want to retrieve from the form controller??
898 $form = $this->noController ? NULL : $this;
899 $context = CRM_Utils_Request::retrieve('context', 'Alphanumeric', $form, FALSE, 'report');
9d72cede 900 $actUrl = '';
6a488035
TO
901
902 if (CRM_Core_Permission::check('access CiviCRM')) {
9d72cede
EM
903 $viewLinks = TRUE;
904 $onHover = ts('View Contact Summary for this Contact');
6a488035
TO
905 $onHoverAct = ts('View Activity Record');
906 }
38ba593b 907 foreach ($rows as $rowNum => $row) {
1efec7ff 908 // if we have an activity type, format the View Activity link for use in various columns
9d72cede
EM
909 if ($viewLinks &&
910 array_key_exists('civicrm_activity_activity_type_id', $row)
911 ) {
1efec7ff
DG
912 // Check for target contact id(s) and use the first contact id in that list for view activity link if found,
913 // else use source contact id
914 if (!empty($rows[$rowNum]['civicrm_contact_contact_target_id'])) {
915 $targets = explode(';', $rows[$rowNum]['civicrm_contact_contact_target_id']);
916 $cid = $targets[0];
917 }
918 else {
919 $cid = $rows[$rowNum]['civicrm_contact_contact_source_id'];
920 }
921
922 $actActionLinks = CRM_Activity_Selector_Activity::actionLinks($row['civicrm_activity_activity_type_id'],
923 CRM_Utils_Array::value('civicrm_activity_source_record_id', $rows[$rowNum]),
924 FALSE,
925 $rows[$rowNum]['civicrm_activity_id']
926 );
927
928 $actLinkValues = array(
929 'id' => $rows[$rowNum]['civicrm_activity_id'],
930 'cid' => $cid,
931 'cxt' => $context,
932 );
933 $actUrl = CRM_Utils_System::url($actActionLinks[CRM_Core_Action::VIEW]['url'],
934 CRM_Core_Action::replace($actActionLinks[CRM_Core_Action::VIEW]['qs'], $actLinkValues), TRUE
935 );
936 }
937
482691e1
RN
938 if (array_key_exists('civicrm_contact_contact_source', $row)) {
939 if ($value = $row['civicrm_contact_contact_source_id']) {
940 if ($viewLinks) {
941 $url = CRM_Utils_System::url("civicrm/contact/view",
942 'reset=1&cid=' . $value,
943 $this->_absoluteUrl
944 );
945 $rows[$rowNum]['civicrm_contact_contact_source_link'] = $url;
946 $rows[$rowNum]['civicrm_contact_contact_source_hover'] = $onHover;
947 }
948 $entryFound = TRUE;
949 }
950 }
951
952 if (array_key_exists('civicrm_contact_contact_assignee', $row)) {
953 $assigneeNames = explode(';', $row['civicrm_contact_contact_assignee']);
954 if ($value = $row['civicrm_contact_contact_assignee_id']) {
955 $assigneeContactIds = explode(';', $value);
956 $link = array();
957 if ($viewLinks) {
958 foreach ($assigneeContactIds as $id => $value) {
959 if (isset($value) && isset($assigneeNames[$id])) {
960 $url = CRM_Utils_System::url("civicrm/contact/view",
961 'reset=1&cid=' . $value,
962 $this->_absoluteUrl
963 );
9d72cede
EM
964 $link[] = "<a title='" . $onHover . "' href='" . $url .
965 "'>{$assigneeNames[$id]}</a>";
482691e1
RN
966 }
967 }
968 $rows[$rowNum]['civicrm_contact_contact_assignee'] = implode('; ', $link);
969 }
970 $entryFound = TRUE;
971 }
972 }
973
974 if (array_key_exists('civicrm_contact_contact_target', $row)) {
975 $targetNames = explode(';', $row['civicrm_contact_contact_target']);
976 if ($value = $row['civicrm_contact_contact_target_id']) {
977 $targetContactIds = explode(';', $value);
978 $link = array();
979 if ($viewLinks) {
980 foreach ($targetContactIds as $id => $value) {
981 if (isset($value) && isset($targetNames[$id])) {
982 $url = CRM_Utils_System::url("civicrm/contact/view",
983 'reset=1&cid=' . $value,
984 $this->_absoluteUrl
985 );
9d72cede
EM
986 $link[] = "<a title='" . $onHover . "' href='" . $url .
987 "'>{$targetNames[$id]}</a>";
482691e1
RN
988 }
989 }
990 $rows[$rowNum]['civicrm_contact_contact_target'] = implode('; ', $link);
991 }
992 $entryFound = TRUE;
993 }
994 }
995
6a488035
TO
996 if (array_key_exists('civicrm_activity_activity_type_id', $row)) {
997 if ($value = $row['civicrm_activity_activity_type_id']) {
998 $rows[$rowNum]['civicrm_activity_activity_type_id'] = $activityType[$value];
482691e1 999 if ($viewLinks) {
1efec7ff 1000 $rows[$rowNum]['civicrm_activity_activity_type_id_link'] = $actUrl;
482691e1
RN
1001 $rows[$rowNum]['civicrm_activity_activity_type_id_hover'] = $onHoverAct;
1002 }
6a488035
TO
1003 $entryFound = TRUE;
1004 }
1005 }
1006
1007 if (array_key_exists('civicrm_activity_status_id', $row)) {
1008 if ($value = $row['civicrm_activity_status_id']) {
1009 $rows[$rowNum]['civicrm_activity_status_id'] = $activityStatus[$value];
1010 $entryFound = TRUE;
1011 }
1012 }
1013
410e8105 1014 if (array_key_exists('civicrm_activity_priority_id', $row)) {
1015 if ($value = $row['civicrm_activity_priority_id']) {
1016 $rows[$rowNum]['civicrm_activity_priority_id'] = $priority[$value];
1017 $entryFound = TRUE;
1018 }
1019 }
1020
34e0bdb6 1021 if (array_key_exists('civicrm_activity_details', $row) && $this->_outputMode == 'html') {
1efec7ff
DG
1022 if ($value = $row['civicrm_activity_details']) {
1023 $fullDetails = $rows[$rowNum]['civicrm_activity_details'];
1024 $rows[$rowNum]['civicrm_activity_details'] = substr($fullDetails, 0, strrpos(substr($fullDetails, 0, 80), ' '));
1025 if ($actUrl) {
6e5e50a9 1026 $rows[$rowNum]['civicrm_activity_details'] .= " <a href='{$actUrl}' title='{$onHoverAct}'>(more)</a>";
1efec7ff
DG
1027 }
1028 $entryFound = TRUE;
1029 }
1030 }
1031
6a488035
TO
1032 if (array_key_exists('civicrm_activity_campaign_id', $row)) {
1033 if ($value = $row['civicrm_activity_campaign_id']) {
1034 $rows[$rowNum]['civicrm_activity_campaign_id'] = $this->activeCampaigns[$value];
1035 $entryFound = TRUE;
1036 }
1037 }
1038
1039 if (array_key_exists('civicrm_activity_engagement_level', $row)) {
1040 if ($value = $row['civicrm_activity_engagement_level']) {
1041 $rows[$rowNum]['civicrm_activity_engagement_level'] = $this->engagementLevels[$value];
1042 $entryFound = TRUE;
1043 }
1044 }
1045
9d72cede
EM
1046 if (array_key_exists('civicrm_activity_activity_date_time', $row) &&
1047 array_key_exists('civicrm_activity_status_id', $row)
1048 ) {
6a488035
TO
1049 if (CRM_Utils_Date::overdue($rows[$rowNum]['civicrm_activity_activity_date_time']) &&
1050 $activityStatus[$row['civicrm_activity_status_id']] != 'Completed'
1051 ) {
1052 $rows[$rowNum]['class'] = "status-overdue";
1053 $entryFound = TRUE;
1054 }
1055 }
1056
66ad82d6 1057 $entryFound = $this->alterDisplayAddressFields($row, $rows, $rowNum, 'activity', 'List all activities for this', ';') ? TRUE : $entryFound;
482691e1 1058
6a488035
TO
1059 if (!$entryFound) {
1060 break;
1061 }
1062 }
1063 }
667abe3a 1064
00be9182 1065 public function sectionTotals() {
667abe3a 1066 // Reports using order_bys with sections must populate $this->_selectAliases in select() method.
1067 if (empty($this->_selectAliases)) {
1068 return;
1069 }
1070
1071 if (!empty($this->_sections)) {
1072 // pull section aliases out of $this->_sections
1073 $sectionAliases = array_keys($this->_sections);
1074
1075 $ifnulls = array();
1076 foreach (array_merge($sectionAliases, $this->_selectAliases) as $alias) {
1077 $ifnulls[] = "ifnull($alias, '') as $alias";
1078 }
b708c08d 1079 $this->_select = "SELECT " . implode(", ", $ifnulls);
36d2f4d5 1080 $this->_select = CRM_Contact_BAO_Query::appendAnyValueToSelect($ifnulls, $sectionAliases);
667abe3a 1081
b708c08d 1082 $query = $this->_select .
5a14305b 1083 ", count(DISTINCT civicrm_activity_id) as ct from {$this->temporaryTables['activity_temp_table']} group by " .
667abe3a 1084 implode(", ", $sectionAliases);
1085
1086 // initialize array of total counts
1087 $totals = array();
f38e3c19 1088 $dao = $this->executeReportQuery($query);
667abe3a 1089 while ($dao->fetch()) {
1090 // let $this->_alterDisplay translate any integer ids to human-readable values.
1091 $rows[0] = $dao->toArray();
1092 $this->alterDisplay($rows);
1093 $row = $rows[0];
1094
1095 // add totals for all permutations of section values
1096 $values = array();
1097 $i = 1;
1098 $aliasCount = count($sectionAliases);
1099 foreach ($sectionAliases as $alias) {
1100 $values[] = $row[$alias];
1101 $key = implode(CRM_Core_DAO::VALUE_SEPARATOR, $values);
1102 if ($i == $aliasCount) {
1103 // the last alias is the lowest-level section header; use count as-is
1104 $totals[$key] = $dao->ct;
1105 }
1106 else {
1107 // other aliases are higher level; roll count into their total
1108 $totals[$key] += $dao->ct;
1109 }
1110 }
1111 }
1112 $this->assign('sectionTotals', $totals);
1113 }
1114 }
96025800 1115
d47468d0 1116 /**
1117 * @todo remove this function & declare the 3 contact tables separately
1118 *
1119 * (Currently the construct method incorrectly melds them - this is an interim
1120 * refactor in order to get this under ReportTemplateTests)
1121 */
1122 protected function buildAssigneeFrom() {
1123 $activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate');
1124 $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts);
1125 $this->_from = "
1126 FROM civicrm_activity {$this->_aliases['civicrm_activity']}
1127 INNER JOIN civicrm_activity_contact {$this->_aliases['civicrm_activity_contact']}
1128 ON {$this->_aliases['civicrm_activity']}.id = {$this->_aliases['civicrm_activity_contact']}.activity_id AND
1129 {$this->_aliases['civicrm_activity_contact']}.record_type_id = {$assigneeID}
1130 INNER JOIN civicrm_contact civicrm_contact_assignee
1131 ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_contact_assignee.id
1132 {$this->_aclFrom}";
1133
1134 if ($this->isTableSelected('civicrm_email')) {
1135 $this->_from .= "
1136 LEFT JOIN civicrm_email civicrm_email_assignee
1137 ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_email_assignee.contact_id AND
1138 civicrm_email_assignee.is_primary = 1";
1139 }
1140 if ($this->isTableSelected('civicrm_phone')) {
1141 $this->_from .= "
1142 LEFT JOIN civicrm_phone civicrm_phone_assignee
1143 ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_phone_assignee.contact_id AND
1144 civicrm_phone_assignee.is_primary = 1 ";
1145 }
1146 $this->_aliases['civicrm_contact'] = 'civicrm_contact_assignee';
1147 $this->joinAddressFromContact();
1148 }
1149
1150 /**
1151 * @todo remove this function & declare the 3 contact tables separately
1152 *
1153 * (Currently the construct method incorrectly melds them - this is an interim
1154 * refactor in order to get this under ReportTemplateTests)
1155 */
1156 protected function buildSourceFrom() {
1157 $activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate');
1158 $sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts);
1159 $this->_from = "
1160 FROM civicrm_activity {$this->_aliases['civicrm_activity']}
1161 INNER JOIN civicrm_activity_contact {$this->_aliases['civicrm_activity_contact']}
1162 ON {$this->_aliases['civicrm_activity']}.id = {$this->_aliases['civicrm_activity_contact']}.activity_id AND
1163 {$this->_aliases['civicrm_activity_contact']}.record_type_id = {$sourceID}
1164 INNER JOIN civicrm_contact civicrm_contact_source
1165 ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_contact_source.id
1166 {$this->_aclFrom}";
1167
1168 if ($this->isTableSelected('civicrm_email')) {
1169 $this->_from .= "
1170 LEFT JOIN civicrm_email civicrm_email_source
1171 ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_email_source.contact_id AND
1172 civicrm_email_source.is_primary = 1";
1173 }
1174 if ($this->isTableSelected('civicrm_phone')) {
1175 $this->_from .= "
1176 LEFT JOIN civicrm_phone civicrm_phone_source
1177 ON {$this->_aliases['civicrm_activity_contact']}.contact_id = civicrm_phone_source.contact_id AND
1178 civicrm_phone_source.is_primary = 1 ";
1179 }
1180 $this->_aliases['civicrm_contact'] = 'civicrm_contact_source';
1181 $this->joinAddressFromContact();
1182 }
1183
6a488035 1184}