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