3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
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 |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * This class is used to retrieve and display a range of contacts that match the given criteria.
21 class CRM_Case_Selector_Search
extends CRM_Core_Selector_Base
{
24 * This defines two actions- View and Edit.
28 public static $_links = NULL;
31 * The action links that we need to display for the browse screen.
35 private static $_actionLinks;
38 * We use desc to remind us what that column is, name is used in the tpl
42 public static $_columnHeaders;
45 * Properties of contact we're interested in displaying
48 public static $_properties = [
64 * Are we restricting ourselves to a single contact
68 protected $_single = FALSE;
71 * Are we restricting ourselves to a single contact
75 protected $_limit = NULL;
78 * What context are we being invoked from
82 protected $_context = NULL;
85 * QueryParams is the array returned by exportValues called on
86 * the HTML_QuickForm_Controller for that page.
93 * Represent the type of selector
100 * The additional clause that we restrict the search with
104 protected $_additionalClause = NULL;
116 * @param array $queryParams
117 * Array of parameters for query.
118 * @param \const|int $action - action of search basic or advanced.
119 * @param string $additionalClause
120 * If the caller wants to further restrict the search (used in participations).
121 * @param bool $single
122 * Are we dealing only with one contact?.
124 * How many signers do we want returned.
126 * @param string $context
128 * @return \CRM_Case_Selector_Search
130 public function __construct(
132 $action = CRM_Core_Action
::NONE
,
133 $additionalClause = NULL,
138 // submitted form values
139 $this->_queryParams
= &$queryParams;
141 $this->_single
= $single;
142 $this->_limit
= $limit;
143 $this->_context
= $context;
145 $this->_additionalClause
= $additionalClause;
148 $this->_action
= $action;
150 $this->_query
= new CRM_Contact_BAO_Query($this->_queryParams
,
151 CRM_Case_BAO_Query
::defaultReturnProperties(CRM_Contact_BAO_Query
::MODE_CASE
,
155 CRM_Contact_BAO_Query
::MODE_CASE
158 $this->_query
->_distinctComponentClause
= " civicrm_case.id ";
159 $this->_query
->_groupByComponentClause
= " GROUP BY civicrm_case.id ";
163 * This method returns the links that are given for each search row.
164 * currently the links added for each row are
169 * @param bool $isDeleted
174 public static function &links($isDeleted = FALSE, $key = NULL) {
175 $extraParams = ($key) ?
"&key={$key}" : NULL;
179 CRM_Core_Action
::RENEW
=> [
180 'name' => ts('Restore'),
181 'url' => 'civicrm/contact/view/case',
182 'qs' => 'reset=1&action=renew&id=%%id%%&cid=%%cid%%&context=%%cxt%%' . $extraParams,
183 'ref' => 'restore-case',
184 'title' => ts('Restore Case'),
190 CRM_Core_Action
::VIEW
=> [
191 'name' => ts('Manage'),
192 'url' => 'civicrm/contact/view/case',
193 'qs' => 'reset=1&id=%%id%%&cid=%%cid%%&action=view&context=%%cxt%%&selectedChild=case' . $extraParams,
194 'ref' => 'manage-case',
195 'class' => 'no-popup',
196 'title' => ts('Manage Case'),
198 CRM_Core_Action
::DELETE
=> [
199 'name' => ts('Delete'),
200 'url' => 'civicrm/contact/view/case',
201 'qs' => 'reset=1&action=delete&id=%%id%%&cid=%%cid%%&context=%%cxt%%' . $extraParams,
202 'ref' => 'delete-case',
203 'title' => ts('Delete Case'),
205 CRM_Core_Action
::UPDATE
=> [
206 'name' => ts('Assign to Another Client'),
207 'url' => 'civicrm/contact/view/case/editClient',
208 'qs' => 'reset=1&action=update&id=%%id%%&cid=%%cid%%&context=%%cxt%%' . $extraParams,
210 'class' => 'medium-popup',
211 'title' => ts('Assign to Another Client'),
217 foreach (self
::$_links as $key => $value) {
218 $actionLinks['primaryActions'][$key] = $value;
225 * Getter for array of the parameters required for creating pager.
228 * @param array $params
230 public function getPagerParams($action, &$params) {
231 $params['status'] = ts('Case') . ' %%StatusMessage%%';
232 $params['csvString'] = NULL;
234 $params['rowCount'] = $this->_limit
;
237 $params['rowCount'] = CRM_Utils_Pager
::ROWCOUNT
;
240 $params['buttonTop'] = 'PagerTopButton';
241 $params['buttonBottom'] = 'PagerBottomButton';
245 * Returns total number of rows for the query.
250 * Total number of rows
252 public function getTotalCount($action) {
253 return $this->_query
->searchQuery(0, 0, NULL,
257 $this->_additionalClause
262 * Returns all the rows in the given offset and rowCount.
264 * @param string $action
265 * The action being performed.
267 * The row number to start from.
268 * @param int $rowCount
269 * The number of rows to return.
270 * @param string $sort
271 * The sql string that describes the sort order.
272 * @param string $output
273 * What should the result set include (web/email/csv).
276 * the total number of rows for this action
278 public function &getRows($action, $offset, $rowCount, $sort, $output = NULL) {
279 $result = $this->_query
->searchQuery($offset, $rowCount, $sort,
283 $this->_additionalClause
285 // process the result of the query
288 //CRM-4418 check for view, edit, delete
289 $permissions = [CRM_Core_Permission
::VIEW
];
290 if (CRM_Core_Permission
::check('access all cases and activities')
291 || CRM_Core_Permission
::check('access my cases and activities')
293 $permissions[] = CRM_Core_Permission
::EDIT
;
295 if (CRM_Core_Permission
::check('delete in CiviCase')) {
296 $permissions[] = CRM_Core_Permission
::DELETE
;
298 $mask = CRM_Core_Action
::mask($permissions);
300 $caseStatus = CRM_Core_OptionGroup
::values('case_status', FALSE, FALSE, FALSE, " AND v.name = 'Urgent' ");
304 while ($result->fetch()) {
306 // the columns we are interested in
307 foreach (self
::$_properties as $property) {
308 if (isset($result->$property)) {
309 $row[$property] = $result->$property;
314 if ($result->case_deleted
) {
316 $row['case_status_id'] = empty($row['case_status_id']) ?
"" : $row['case_status_id'] . '<br />' . ts('(deleted)');
319 $scheduledInfo['case_id'][] = $result->case_id
;
320 $scheduledInfo['contact_id'][] = $result->contact_id
;
321 $scheduledInfo['case_deleted'] = $result->case_deleted
;
322 $row['checkbox'] = CRM_Core_Form
::CB_PREFIX
. $result->case_id
;
324 $links = self
::links($isDeleted, $this->_key
);
325 $row['action'] = CRM_Core_Action
::formLink($links['primaryActions'],
327 'id' => $result->case_id
,
328 'cid' => $result->contact_id
,
329 'cxt' => $this->_context
,
333 'case.selector.actions',
338 $row['contact_type'] = CRM_Contact_BAO_Contact_Utils
::getImage($result->contact_sub_type ?
$result->contact_sub_type
: $result->contact_type
341 //adding case manager to case selector.CRM-4510.
342 $caseType = CRM_Case_BAO_Case
::getCaseType($result->case_id
, 'name');
343 $row['casemanager'] = CRM_Case_BAO_Case
::getCaseManagerContact($caseType, $result->case_id
);
345 if (isset($result->case_status_id
) &&
346 array_key_exists($result->case_status_id
, $caseStatus)
348 $row['class'] = "status-urgent";
351 $row['class'] = "status-normal";
354 $rows[$result->case_id
] = $row;
357 //retrive the scheduled & recent Activity type and date for selector
358 if (!empty($scheduledInfo)) {
359 $schdeduledActivity = CRM_Case_BAO_Case
::getNextScheduledActivity($scheduledInfo, 'upcoming');
360 foreach ($schdeduledActivity as $key => $value) {
361 $rows[$key]['case_scheduled_activity_date'] = $value['date'];
362 $rows[$key]['case_scheduled_activity_type'] = $value['type'];
364 $recentActivity = CRM_Case_BAO_Case
::getNextScheduledActivity($scheduledInfo, 'recent');
365 foreach ($recentActivity as $key => $value) {
366 $rows[$key]['case_recent_activity_date'] = $value['date'];
367 $rows[$key]['case_recent_activity_type'] = $value['type'];
376 public function getQILL() {
377 return $this->_query
->qill();
381 * Returns the column headers as an array of tuples:
382 * (name, sortName (key to the sort array))
384 * @param string $action
385 * The action being performed.
386 * @param string $output
387 * What should the result set include (web/email/csv).
390 * the column headers that need to be displayed
392 public function &getColumnHeaders($action = NULL, $output = NULL) {
393 if (!isset(self
::$_columnHeaders)) {
394 self
::$_columnHeaders = [
396 'name' => ts('Subject'),
397 'direction' => CRM_Utils_Sort
::DONTCARE
,
400 'name' => ts('Status'),
401 'sort' => 'case_status',
402 'direction' => CRM_Utils_Sort
::DONTCARE
,
405 'name' => ts('Case Type'),
406 'sort' => 'case_type',
407 'direction' => CRM_Utils_Sort
::DONTCARE
,
410 'name' => ts('My Role'),
411 'sort' => 'case_role',
412 'direction' => CRM_Utils_Sort
::DONTCARE
,
415 'name' => ts('Case Manager'),
416 'direction' => CRM_Utils_Sort
::DONTCARE
,
419 'name' => ts('Most Recent'),
420 'sort' => 'case_recent_activity_date',
421 'direction' => CRM_Utils_Sort
::DONTCARE
,
424 'name' => ts('Next Sched.'),
425 'sort' => 'case_scheduled_activity_date',
426 'direction' => CRM_Utils_Sort
::DONTCARE
,
428 ['name' => ts('Actions')],
431 if (!$this->_single
) {
434 'name' => ts('Client'),
435 'sort' => 'sort_name',
436 'direction' => CRM_Utils_Sort
::ASCENDING
,
440 self
::$_columnHeaders = array_merge($pre, self
::$_columnHeaders);
443 return self
::$_columnHeaders;
449 public function alphabetQuery() {
450 return $this->_query
->alphabetQuery();
456 public function &getQuery() {
457 return $this->_query
;
461 * Name of export file.
463 * @param string $output
469 public function getExportFileName($output = 'csv') {
470 return ts('Case Search');
474 * Add the set of "actionLinks" to the case activity
477 * @param int $contactID
479 * @param string $context
480 * @param \CRM_Activity_BAO_Activity $dao
481 * @param bool $allowView
483 * @return string $linksMarkup
485 public static function addCaseActivityLinks($caseID, $contactID, $userID, $context, $dao, $allowView = TRUE) {
486 $caseDeleted = CRM_Core_DAO
::getFieldValue('CRM_Case_DAO_Case', $caseID, 'is_deleted');
487 $actionLinks = self
::actionLinks();
488 // Check logged in user for permission.
489 if (CRM_Case_BAO_Case
::checkPermission($dao->id
, 'view', $dao->activity_type_id
, $userID)) {
490 $permissions[] = CRM_Core_Permission
::VIEW
;
493 unset($actionLinks[CRM_Core_Action
::VIEW
]);
495 if (!$dao->deleted
) {
496 // Activity is not deleted, allow user to edit/delete if they have permission
497 // hide Edit link if:
498 // 1. User does not have edit permission.
499 // 2. Activity type is NOT editable (special case activities).CRM-5871
500 if (CRM_Case_BAO_Case
::checkPermission($dao->id
, 'edit', $dao->activity_type_id
, $userID)) {
501 $permissions[] = CRM_Core_Permission
::EDIT
;
503 if (in_array($dao->activity_type_id
, CRM_Activity_BAO_Activity
::getViewOnlyActivityTypeIDs())) {
504 unset($actionLinks[CRM_Core_Action
::UPDATE
]);
506 if (CRM_Case_BAO_Case
::checkPermission($dao->id
, 'delete', $dao->activity_type_id
, $userID)) {
507 $permissions[] = CRM_Core_Permission
::DELETE
;
509 unset($actionLinks[CRM_Core_Action
::RENEW
]);
512 if ($dao->deleted
&& !$caseDeleted
513 && (CRM_Case_BAO_Case
::checkPermission($dao->id
, 'delete', $dao->activity_type_id
, $userID))) {
514 // Case is not deleted but activity is.
515 // Allow user to restore activity if they have delete permissions
516 unset($actionLinks[CRM_Core_Action
::DELETE
]);
517 $extraMask = CRM_Core_Action
::RENEW
;
519 if (!CRM_Case_BAO_Case
::checkPermission($dao->id
, 'Move To Case', $dao->activity_type_id
)) {
520 unset($actionLinks[CRM_Core_Action
::DETACH
]);
522 if (!CRM_Case_BAO_Case
::checkPermission($dao->id
, 'Copy To Case', $dao->activity_type_id
)) {
523 unset($actionLinks[CRM_Core_Action
::COPY
]);
525 $actionMask = CRM_Core_Action
::mask($permissions) |
$extraMask;
529 'cxt' => empty($context) ?
'' : "&context={$context}",
532 $linksMarkup = CRM_Core_Action
::formLink($actionLinks,
541 // if there are file attachments we will return how many and, if only one, add a link to it
542 if (!empty($dao->attachment_ids
)) {
543 $linksMarkup .= implode(' ', CRM_Core_BAO_File
::paperIconAttachment('civicrm_activity', $dao->id
));
550 * @param int $contactID
552 * @param string $context
553 * @param int $activityTypeID
554 * @param int $activityDeleted
555 * @param int $activityID
556 * @param bool $allowView
560 public static function permissionedActionLinks($caseID, $contactID, $userID, $context, $activityTypeID, $activityDeleted, $activityID, $allowView = TRUE) {
561 $caseDeleted = CRM_Core_DAO
::getFieldValue('CRM_Case_DAO_Case', $caseID, 'is_deleted');
563 'aid' => $activityID,
565 'cxt' => empty($context) ?
'' : "&context={$context}",
568 $actionLinks = self
::actionLinks();
570 // Check logged in user for permission.
571 if (CRM_Case_BAO_Case
::checkPermission($activityID, 'view', $activityTypeID, $userID)) {
572 $permissions[] = CRM_Core_Permission
::VIEW
;
575 unset($actionLinks[CRM_Core_Action
::VIEW
]);
577 if (!$activityDeleted) {
578 // Activity is not deleted, allow user to edit/delete if they have permission
580 // hide Edit link if:
581 // 1. User does not have edit permission.
582 // 2. Activity type is NOT editable (special case activities).CRM-5871
583 if (CRM_Case_BAO_Case
::checkPermission($activityID, 'edit', $activityTypeID, $userID)) {
584 $permissions[] = CRM_Core_Permission
::EDIT
;
586 if (in_array($activityTypeID, CRM_Activity_BAO_Activity
::getViewOnlyActivityTypeIDs())) {
587 unset($actionLinks[CRM_Core_Action
::UPDATE
]);
589 if (CRM_Case_BAO_Case
::checkPermission($activityID, 'delete', $activityTypeID, $userID)) {
590 $permissions[] = CRM_Core_Permission
::DELETE
;
592 unset($actionLinks[CRM_Core_Action
::RENEW
]);
595 if ($activityDeleted && !$caseDeleted
596 && (CRM_Case_BAO_Case
::checkPermission($activityID, 'delete', $activityTypeID, $userID))) {
597 // Case is not deleted but activity is.
598 // Allow user to restore activity if they have delete permissions
599 unset($actionLinks[CRM_Core_Action
::DELETE
]);
600 $extraMask = CRM_Core_Action
::RENEW
;
602 if (!CRM_Case_BAO_Case
::checkPermission($activityID, 'Move To Case', $activityTypeID)) {
603 unset($actionLinks[CRM_Core_Action
::DETACH
]);
605 if (!CRM_Case_BAO_Case
::checkPermission($activityID, 'Copy To Case', $activityTypeID)) {
606 unset($actionLinks[CRM_Core_Action
::COPY
]);
609 $actionMask = CRM_Core_Action
::mask($permissions) |
$extraMask;
610 return CRM_Core_Action
::filterLinks($actionLinks, $actionMask, $values, 'case.activity', 'Activity', $activityID);
614 * Get the action links for this page.
618 public static function actionLinks() {
619 // check if variable _actionsLinks is populated
620 if (!isset(self
::$_actionLinks)) {
621 self
::$_actionLinks = [
622 CRM_Core_Action
::VIEW
=> [
623 'name' => ts('View'),
624 'url' => 'civicrm/case/activity/view',
625 'qs' => 'reset=1&cid=%%cid%%&caseid=%%caseid%%&aid=%%aid%%',
626 'title' => ts('View'),
628 CRM_Core_Action
::UPDATE
=> [
629 'name' => ts('Edit'),
630 'url' => 'civicrm/case/activity',
631 'qs' => 'reset=1&cid=%%cid%%&caseid=%%caseid%%&id=%%aid%%&action=update%%cxt%%',
632 'title' => ts('Edit'),
633 'icon' => 'fa-pencil',
635 CRM_Core_Action
::DELETE
=> [
636 'name' => ts('Delete'),
637 'url' => 'civicrm/case/activity',
638 'qs' => 'reset=1&cid=%%cid%%&caseid=%%caseid%%&id=%%aid%%&action=delete%%cxt%%',
639 'title' => ts('Delete'),
640 'icon' => 'fa-trash',
642 CRM_Core_Action
::RENEW
=> [
643 'name' => ts('Restore'),
644 'url' => 'civicrm/case/activity',
645 'qs' => 'reset=1&cid=%%cid%%&caseid=%%caseid%%&id=%%aid%%&action=renew%%cxt%%',
646 'title' => ts('Restore'),
649 CRM_Core_Action
::DETACH
=> [
650 'name' => ts('Move To Case'),
651 'ref' => 'move_to_case_action',
652 'title' => ts('Move To Case'),
653 'extra' => 'onclick = "Javascript:fileOnCase( \'move\', %%aid%%, %%caseid%%, this ); return false;"',
654 'icon' => 'fa-clipboard',
656 CRM_Core_Action
::COPY
=> [
657 'name' => ts('Copy To Case'),
658 'ref' => 'copy_to_case_action',
659 'title' => ts('Copy To Case'),
660 'extra' => 'onclick = "Javascript:fileOnCase( \'copy\', %%aid%%, %%caseid%%, this ); return false;"',
661 'icon' => 'fa-files-o',
665 return self
::$_actionLinks;