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