Merge pull request #13134 from agileware/CIVICRM-1006
[civicrm-core.git] / CRM / Activity / Selector / Activity.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
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 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2019
32 */
33
34 /**
35 * This class is used to retrieve and display activities for a contact.
36 */
37 class CRM_Activity_Selector_Activity extends CRM_Core_Selector_Base implements CRM_Core_Selector_API {
38
39 /**
40 * We use desc to remind us what that column is, name is used in the tpl
41 *
42 * @var array
43 */
44 static $_columnHeaders;
45
46 /**
47 * ContactId - contact id of contact whose activies are displayed
48 *
49 * @var int
50 */
51 protected $_contactId;
52
53 protected $_admin;
54
55 protected $_context;
56
57 protected $_activityTypeIDs;
58
59 protected $_viewOptions;
60
61 /**
62 * Class constructor.
63 *
64 * @param int $contactId
65 * Contact whose activities we want to display.
66 * @param int $permission
67 * The permission we have for this contact.
68 *
69 * @param bool $admin
70 * @param string $context
71 * @param null $activityTypeIDs
72 *
73 * @return \CRM_Activity_Selector_Activity
74 */
75 public function __construct(
76 $contactId,
77 $permission,
78 $admin = FALSE,
79 $context = 'activity',
80 $activityTypeIDs = NULL) {
81 $this->_contactId = $contactId;
82 $this->_permission = $permission;
83 $this->_admin = $admin;
84 $this->_context = $context;
85 $this->_activityTypeIDs = $activityTypeIDs;
86
87 // get all enabled view componentc (check if case is enabled)
88 $this->_viewOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
89 'contact_view_options', TRUE, NULL, TRUE
90 );
91 }
92
93 /**
94 * This method returns the action links that are given for each search row.
95 * currently the action links added for each row are
96 *
97 * - View
98 *
99 * @param int $activityTypeId
100 * @param int $sourceRecordId
101 * @param bool $accessMailingReport
102 * @param int $activityId
103 * @param null $key
104 * @param null $compContext
105 *
106 * @return array
107 */
108 public static function actionLinks(
109 $activityTypeId,
110 $sourceRecordId = NULL,
111 $accessMailingReport = FALSE,
112 $activityId = NULL,
113 $key = NULL,
114 $compContext = NULL) {
115 static $activityActTypes = NULL;
116 //CRM-14277 added addtitional param to handle activity search
117 $extraParams = "&searchContext=activity";
118
119 $extraParams .= ($key) ? "&key={$key}" : NULL;
120 if ($compContext) {
121 $extraParams .= "&compContext={$compContext}";
122 }
123
124 $showView = TRUE;
125 $showUpdate = $showDelete = FALSE;
126 $qsUpdate = NULL;
127
128 if (!$activityActTypes) {
129 $activeActTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name', TRUE);
130 }
131 $activityTypeName = CRM_Utils_Array::value($activityTypeId, $activeActTypes);
132
133 // CRM-7607
134 // Lets allow to have normal operation for only activity types.
135 // When activity type is disabled or no more exists give only delete.
136 switch ($activityTypeName) {
137 case 'Event Registration':
138 case 'Change Registration':
139 $url = 'civicrm/contact/view/participant';
140 $qsView = "action=view&reset=1&id={$sourceRecordId}&cid=%%cid%%&context=%%cxt%%{$extraParams}";
141 break;
142
143 case 'Contribution':
144 $url = 'civicrm/contact/view/contribution';
145 $qsView = "action=view&reset=1&id={$sourceRecordId}&cid=%%cid%%&context=%%cxt%%{$extraParams}";
146 break;
147
148 case 'Payment':
149 case 'Refund':
150 $participantId = CRM_Core_DAO::getFieldValue('CRM_Event_BAO_ParticipantPayment', $sourceRecordId, 'participant_id', 'contribution_id');
151 if (!empty($participantId)) {
152 $url = 'civicrm/contact/view/participant';
153 $qsView = "action=view&reset=1&id={$participantId}&cid=%%cid%%&context=%%cxt%%{$extraParams}";
154 }
155 break;
156
157 case 'Membership Signup':
158 case 'Membership Renewal':
159 case 'Change Membership Status':
160 case 'Change Membership Type':
161 $url = 'civicrm/contact/view/membership';
162 $qsView = "action=view&reset=1&id={$sourceRecordId}&cid=%%cid%%&context=%%cxt%%{$extraParams}";
163 break;
164
165 case 'Pledge Reminder':
166 case 'Pledge Acknowledgment':
167 $url = 'civicrm/contact/view/activity';
168 $qsView = "atype={$activityTypeId}&action=view&reset=1&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}";
169 break;
170
171 case 'Email':
172 case 'Bulk Email':
173 $url = 'civicrm/activity/view';
174 $delUrl = 'civicrm/activity';
175 $qsView = "atype={$activityTypeId}&action=view&reset=1&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}";
176 if ($activityTypeName == 'Email') {
177 $showDelete = TRUE;
178 }
179 break;
180
181 case 'Inbound Email':
182 $url = 'civicrm/contact/view/activity';
183 $qsView = "atype={$activityTypeId}&action=view&reset=1&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}";
184
185 if (CRM_Core_Permission::check('edit inbound email basic information')
186 || CRM_Core_Permission::check('edit inbound email basic information and content')
187 ) {
188 $showDelete = $showUpdate = TRUE;
189 $qsUpdate = "atype={$activityTypeId}&action=update&reset=1&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}";
190 }
191 break;
192
193 case 'Open Case':
194 case 'Change Case Type':
195 case 'Change Case Status':
196 case 'Change Case Start Date':
197 $showUpdate = $showDelete = FALSE;
198 $url = 'civicrm/activity';
199 $qsView = "atype={$activityTypeId}&action=view&reset=1&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}";
200 $qsUpdate = "atype={$activityTypeId}&action=update&reset=1&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}";
201 break;
202
203 default:
204 $url = 'civicrm/activity';
205 $showView = $showDelete = $showUpdate = TRUE;
206 $qsView = "atype={$activityTypeId}&action=view&reset=1&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}";
207 $qsUpdate = "atype={$activityTypeId}&action=update&reset=1&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}";
208
209 // When type is not available lets hide view and update.
210 if (empty($activityTypeName)) {
211 $showView = $showUpdate = FALSE;
212 }
213 break;
214 }
215
216 $qsDelete = "atype={$activityTypeId}&action=delete&reset=1&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}";
217
218 $actionLinks = array();
219
220 if ($showView) {
221 $actionLinks += array(
222 CRM_Core_Action::
223 VIEW => array(
224 'name' => ts('View'),
225 'url' => $url,
226 'qs' => $qsView,
227 'title' => ts('View Activity'),
228 ),
229 );
230 }
231
232 if ($showUpdate) {
233 $updateUrl = 'civicrm/activity/add';
234 if ($activityTypeName == 'Email') {
235 $updateUrl = 'civicrm/activity/email/add';
236 }
237 elseif ($activityTypeName == 'Print PDF Letter') {
238 $updateUrl = 'civicrm/activity/pdf/add';
239 }
240 if (CRM_Activity_BAO_Activity::checkPermission($activityId, CRM_Core_Action::UPDATE)) {
241 $actionLinks += array(
242 CRM_Core_Action::
243 UPDATE => array(
244 'name' => ts('Edit'),
245 'url' => $updateUrl,
246 'qs' => $qsUpdate,
247 'title' => ts('Update Activity'),
248 ),
249 );
250 }
251 }
252
253 if (
254 $activityTypeName &&
255 CRM_Case_BAO_Case::checkPermission($activityId, 'File On Case', $activityTypeId)
256 ) {
257 $actionLinks += array(
258 CRM_Core_Action::
259 ADD => array(
260 'name' => ts('File on Case'),
261 'url' => '#',
262 'extra' => 'onclick="javascript:fileOnCase( \'file\', \'%%id%%\', null, this ); return false;"',
263 'title' => ts('File on Case'),
264 ),
265 );
266 }
267
268 if ($showDelete) {
269 if (!isset($delUrl) || !$delUrl) {
270 $delUrl = $url;
271 }
272 $actionLinks += array(
273 CRM_Core_Action::
274 DELETE => array(
275 'name' => ts('Delete'),
276 'url' => $delUrl,
277 'qs' => $qsDelete,
278 'title' => ts('Delete Activity'),
279 ),
280 );
281 }
282
283 if ($accessMailingReport) {
284 $actionLinks += array(
285 CRM_Core_Action::
286 BROWSE => array(
287 'name' => ts('Mailing Report'),
288 'url' => 'civicrm/mailing/report',
289 'qs' => "mid={$sourceRecordId}&reset=1&cid=%%cid%%&context=activitySelector",
290 'title' => ts('View Mailing Report'),
291 ),
292 );
293 }
294
295 return $actionLinks;
296 }
297
298 /**
299 * Getter for array of the parameters required for creating pager.
300 *
301 * @param $action
302 * @param array $params
303 */
304 public function getPagerParams($action, &$params) {
305 $params['status'] = ts('Activities %%StatusMessage%%');
306 $params['csvString'] = NULL;
307 $params['rowCount'] = CRM_Utils_Pager::ROWCOUNT;
308
309 $params['buttonTop'] = 'PagerTopButton';
310 $params['buttonBottom'] = 'PagerBottomButton';
311 }
312
313 /**
314 * Returns the column headers as an array of tuples:
315 * (name, sortName (key to the sort array))
316 *
317 * @param string $action
318 * The action being performed.
319 * @param string $output
320 * What should the result set include (web/email/csv).
321 *
322 * @return array
323 * the column headers that need to be displayed
324 */
325 public function &getColumnHeaders($action = NULL, $output = NULL) {
326 if ($output == CRM_Core_Selector_Controller::EXPORT || $output == CRM_Core_Selector_Controller::SCREEN) {
327 $csvHeaders = array(ts('Activity Type'), ts('Description'), ts('Activity Date'));
328 foreach (self::_getColumnHeaders() as $column) {
329 if (array_key_exists('name', $column)) {
330 $csvHeaders[] = $column['name'];
331 }
332 }
333 return $csvHeaders;
334 }
335 else {
336 return self::_getColumnHeaders();
337 }
338 }
339
340 /**
341 * Returns total number of rows for the query.
342 *
343 * @param string $action
344 * Action being performed.
345 *
346 * @param null $case
347 *
348 * @return int
349 * Total number of rows
350 */
351 public function getTotalCount($action, $case = NULL) {
352 $params = array(
353 'contact_id' => $this->_contactId,
354 'admin' => $this->_admin,
355 'caseId' => $case,
356 'context' => $this->_context,
357 'activity_type_id' => $this->_activityTypeIDs,
358 'offset' => 0,
359 'rowCount' => 0,
360 'sort' => NULL,
361 );
362 return CRM_Activity_BAO_Activity::deprecatedGetActivitiesCount($params);
363 }
364
365 /**
366 * Returns all the rows in the given offset and rowCount.
367 *
368 * @param string $action
369 * The action being performed.
370 * @param int $offset
371 * The row number to start from.
372 * @param int $rowCount
373 * The number of rows to return.
374 * @param string $sort
375 * The sql string that describes the sort order.
376 * @param string $output
377 * What should the result set include (web/email/csv).
378 *
379 * @param null $case
380 *
381 * @return int
382 * the total number of rows for this action
383 */
384 public function &getRows($action, $offset, $rowCount, $sort, $output = NULL, $case = NULL) {
385 $params = array(
386 'contact_id' => $this->_contactId,
387 'admin' => $this->_admin,
388 'caseId' => $case,
389 'context' => $this->_context,
390 'activity_type_id' => $this->_activityTypeIDs,
391 'offset' => $offset,
392 'rowCount' => $rowCount,
393 'sort' => $sort,
394 );
395 $config = CRM_Core_Config::singleton();
396 $rows = CRM_Activity_BAO_Activity::deprecatedGetActivities($params);
397
398 if (empty($rows)) {
399 return $rows;
400 }
401
402 $activityStatus = CRM_Core_PseudoConstant::activityStatus();
403
404 $engagementLevels = CRM_Campaign_PseudoConstant::engagementLevel();
405
406 // CRM-4418
407 $permissions = array($this->_permission);
408 if (CRM_Core_Permission::check('delete activities')) {
409 $permissions[] = CRM_Core_Permission::DELETE;
410 }
411 $mask = CRM_Core_Action::mask($permissions);
412
413 foreach ($rows as $k => $row) {
414 $row = &$rows[$k];
415
416 // DRAFTING: provide a facility for db-stored strings
417 // localize the built-in activity names for display
418 // (these are not enums, so we can't use any automagic here)
419 switch ($row['activity_type']) {
420 case 'Meeting':
421 $row['activity_type'] = ts('Meeting');
422 break;
423
424 case 'Phone Call':
425 $row['activity_type'] = ts('Phone Call');
426 break;
427
428 case 'Email':
429 $row['activity_type'] = ts('Email');
430 break;
431
432 case 'SMS':
433 $row['activity_type'] = ts('SMS');
434 break;
435
436 case 'Event':
437 $row['activity_type'] = ts('Event');
438 break;
439 }
440
441 // add class to this row if overdue
442 if (CRM_Utils_Date::overdue(CRM_Utils_Array::value('activity_date_time', $row))
443 && CRM_Utils_Array::value('status_id', $row) == 1
444 ) {
445 $row['overdue'] = 1;
446 $row['class'] = 'status-overdue';
447 }
448 else {
449 $row['overdue'] = 0;
450 $row['class'] = 'status-ontime';
451 }
452
453 $row['status'] = $row['status_id'] ? $activityStatus[$row['status_id']] : NULL;
454
455 if ($engagementLevel = CRM_Utils_Array::value('engagement_level', $row)) {
456 $row['engagement_level'] = CRM_Utils_Array::value($engagementLevel, $engagementLevels, $engagementLevel);
457 }
458
459 // CRM-3553
460 $accessMailingReport = FALSE;
461 if (!empty($row['mailingId'])) {
462 $accessMailingReport = TRUE;
463 }
464
465 $actionLinks = $this->actionLinks(CRM_Utils_Array::value('activity_type_id', $row),
466 CRM_Utils_Array::value('source_record_id', $row),
467 $accessMailingReport,
468 CRM_Utils_Array::value('activity_id', $row),
469 $this->_key
470 );
471
472 $actionMask = array_sum(array_keys($actionLinks)) & $mask;
473
474 if ($output != CRM_Core_Selector_Controller::EXPORT && $output != CRM_Core_Selector_Controller::SCREEN) {
475 $row['action'] = CRM_Core_Action::formLink($actionLinks,
476 $actionMask,
477 array(
478 'id' => $row['activity_id'],
479 'cid' => $this->_contactId,
480 'cxt' => $this->_context,
481 'caseid' => CRM_Utils_Array::value('case_id', $row),
482 ),
483 ts('more'),
484 FALSE,
485 'activity.selector.action',
486 'Activity',
487 $row['activity_id']
488 );
489 }
490
491 unset($row);
492 }
493
494 return $rows;
495 }
496
497 /**
498 * Name of export file.
499 *
500 * @param string $output
501 * Type of output.
502 *
503 * @return string
504 * name of the file
505 */
506 public function getExportFileName($output = 'csv') {
507 return ts('CiviCRM Activity');
508 }
509
510 /**
511 * Get colunmn headers for search selector.
512 *
513 *
514 * @return array
515 */
516 private static function &_getColumnHeaders() {
517 if (!isset(self::$_columnHeaders)) {
518 self::$_columnHeaders = array(
519 array(
520 'name' => ts('Type'),
521 'sort' => 'activity_type',
522 'direction' => CRM_Utils_Sort::DONTCARE,
523 ),
524 array(
525 'name' => ts('Subject'),
526 'sort' => 'subject',
527 'direction' => CRM_Utils_Sort::DONTCARE,
528 ),
529 array(
530 'name' => ts('Added By'),
531 'sort' => 'source_contact_name',
532 'direction' => CRM_Utils_Sort::DONTCARE,
533 ),
534 array('name' => ts('With')),
535 array('name' => ts('Assigned')),
536 array(
537 'name' => ts('Date'),
538 'sort' => 'activity_date_time',
539 'direction' => CRM_Utils_Sort::DONTCARE,
540 ),
541 array(
542 'name' => ts('Status'),
543 'sort' => 'status_id',
544 'direction' => CRM_Utils_Sort::DONTCARE,
545 ),
546 array('desc' => ts('Actions')),
547 );
548 }
549
550 return self::$_columnHeaders;
551 }
552
553 }