Use ?? operator instead of CRM_Utils_Array::value() in array assignments
[civicrm-core.git] / CRM / Activity / BAO / Activity.php
index 1f0e7a4fe8f95cf7f433aa3ce84322f9ca1f0ac1..de4479355025b56bf3cb4e9fcc5731d213a51f60 100644 (file)
@@ -618,7 +618,7 @@ class CRM_Activity_BAO_Activity extends CRM_Activity_DAO_Activity {
    *
    * @todo elaborate on what this does.
    *
-   * @param CRM_Core_DAO_Activity $activity
+   * @param CRM_Activity_DAO_Activity $activity
    * @param string $logMessage
    *
    * @return bool
@@ -697,6 +697,9 @@ class CRM_Activity_BAO_Activity extends CRM_Activity_DAO_Activity {
       'case_id',
       'campaign_id',
     ];
+    // Q. What does the code below achieve? case_id and campaign_id are already
+    // in the array, defined above, and this code adds them in again if their
+    // component is enabled? @fixme remove case_id and campaign_id from the array above?
     foreach (['case_id' => 'CiviCase', 'campaign_id' => 'CiviCampaign'] as $attr => $component) {
       if (in_array($component, self::activityComponents())) {
         $activityParams['return'][] = $attr;
@@ -746,11 +749,11 @@ class CRM_Activity_BAO_Activity extends CRM_Activity_DAO_Activity {
     foreach ($result as $id => $activity) {
       $activities[$id] = [
         'activity_id' => $activity['id'],
-        'activity_date_time' => CRM_Utils_Array::value('activity_date_time', $activity),
-        'subject' => CRM_Utils_Array::value('subject', $activity),
+        'activity_date_time' => $activity['activity_date_time'] ?? NULL,
+        'subject' => $activity['subject'] ?? NULL,
         'assignee_contact_name' => CRM_Utils_Array::value('assignee_contact_sort_name', $activity, []),
-        'source_contact_id' => CRM_Utils_Array::value('source_contact_id', $activity),
-        'source_contact_name' => CRM_Utils_Array::value('source_contact_sort_name', $activity),
+        'source_contact_id' => $activity['source_contact_id'] ?? NULL,
+        'source_contact_name' => $activity['source_contact_sort_name'] ?? NULL,
       ];
       $activities[$id]['activity_type_name'] = CRM_Core_PseudoConstant::getName('CRM_Activity_BAO_Activity', 'activity_type_id', $activity['activity_type_id']);
       $activities[$id]['activity_type'] = CRM_Core_PseudoConstant::getLabel('CRM_Activity_BAO_Activity', 'activity_type_id', $activity['activity_type_id']);
@@ -780,6 +783,7 @@ class CRM_Activity_BAO_Activity extends CRM_Activity_DAO_Activity {
 
     // Eventually this second iteration should just handle the target contacts. It's a bit muddled at
     // the moment as the bulk activity stuff needs unravelling & test coverage.
+    $caseIds = [];
     foreach ($result as $id => $activity) {
       $isBulkActivity = (!$bulkActivityTypeID || ($bulkActivityTypeID === $activity['activity_type_id']));
       foreach ($mappingParams as $apiKey => $expectedName) {
@@ -804,10 +808,9 @@ class CRM_Activity_BAO_Activity extends CRM_Activity_DAO_Activity {
 
           // fetch case subject for case ID found
           if (!empty($activity['case_id'])) {
-            $activities[$id]['case_subject'] = civicrm_api3('Case', 'getvalue', [
-              'return' => 'subject',
-              'id' => reset($activity['case_id']),
-            ]);
+            // Store cases; we'll look them up in one query below. We convert
+            // to int here so we can trust it for SQL.
+            $caseIds[$id] = (int) current($activity['case_id']);
           }
         }
         else {
@@ -827,6 +830,15 @@ class CRM_Activity_BAO_Activity extends CRM_Activity_DAO_Activity {
       $activities[$id]['is_recurring_activity'] = CRM_Core_BAO_RecurringEntity::getParentFor($id, 'civicrm_activity');
     }
 
+    // Look up any case subjects we need in a single query and add them in the relevant activities under 'case_subject'
+    if ($caseIds) {
+      $subjects = CRM_Core_DAO::executeQuery('SELECT id, subject FROM civicrm_case WHERE id IN (' . implode(',', array_unique($caseIds)) . ')')
+        ->fetchMap('id', 'subject');
+      foreach ($caseIds as $activityId => $caseId) {
+        $result[$activityId]['case_subject'] = $subjects[$caseId];
+      }
+    }
+
     return $activities;
   }
 
@@ -1817,6 +1829,7 @@ WHERE      activity.id IN ($activityIds)";
    *
    * @return int
    *   Id of parent activity otherwise false.
+   * @throws \CRM_Core_Exception
    */
   public static function getParentActivity($activityId) {
     static $parentActivities = [];
@@ -1845,8 +1858,10 @@ WHERE      activity.id IN ($activityIds)";
    *
    * @return int
    *   $params  count of prior activities otherwise false.
+   * @throws \CRM_Core_Exception
    */
   public static function getPriorCount($activityID) {
+    CRM_Core_Error::deprecatedFunctionWarning('unused function to be removed');
     static $priorCounts = [];
 
     $activityID = CRM_Utils_Type::escape($activityID, 'Integer');
@@ -1884,6 +1899,7 @@ AND id < {$activityID}
    *
    * @return array
    *   prior activities info.
+   * @throws \CRM_Core_Exception
    */
   public static function getPriorAcitivities($activityID, $onlyPriorRevisions = FALSE) {
     static $priorActivities = [];
@@ -1936,6 +1952,8 @@ AND cl.modified_id  = c.id
    *
    * @return int
    *   current activity id.
+   *
+   * @throws \CRM_Core_Exception
    */
   public static function getLatestActivityId($activityID) {
     static $latestActivityIds = [];
@@ -1953,7 +1971,7 @@ AND cl.modified_id  = c.id
         $activityID = $originalID;
       }
       $params = [1 => [$activityID, 'Integer']];
-      $query = "SELECT id from civicrm_activity where original_id = %1 and is_current_revision = 1";
+      $query = 'SELECT id from civicrm_activity where original_id = %1 and is_current_revision = 1';
 
       $latestActivityIds[$activityID] = CRM_Core_DAO::singleValueQuery($query, $params);
     }
@@ -1969,6 +1987,8 @@ AND cl.modified_id  = c.id
    * @param array $params
    *
    * @return CRM_Activity_BAO_Activity|null|object
+   *
+   * @throws \CRM_Core_Exception
    */
   public static function createFollowupActivity($activityId, $params) {
     if (!$activityId) {
@@ -2056,6 +2076,7 @@ AND cl.modified_id  = c.id
    * @param int $type
    *
    * @return array
+   * @throws \CiviCRM_API3_Exception
    */
   public static function getStatusesByType($type) {
     if (!isset(Civi::$statics[__CLASS__][__FUNCTION__])) {
@@ -2081,6 +2102,7 @@ AND cl.modified_id  = c.id
    * @param array $activity
    *
    * @return bool
+   * @throws \CiviCRM_API3_Exception
    */
   public static function isOverdue($activity) {
     return array_key_exists($activity['status_id'], self::getStatusesByType(self::INCOMPLETE)) && CRM_Utils_Date::overdue($activity['activity_date_time']);
@@ -2436,8 +2458,8 @@ INNER JOIN  civicrm_option_group grp ON (grp.id = option_group_id AND grp.name =
       'is_deleted' => 0,
       'is_current_revision' => 1,
       'is_test' => 0,
-      'contact_id' => CRM_Utils_Array::value('contact_id', $params),
-      'activity_date_time' => CRM_Utils_Array::value('activity_date_time', $params),
+      'contact_id' => $params['contact_id'] ?? NULL,
+      'activity_date_time' => $params['activity_date_time'] ?? NULL,
       'check_permissions' => 1,
       'options' => [
         'offset' => CRM_Utils_Array::value('offset', $params, 0),
@@ -2526,6 +2548,9 @@ INNER JOIN  civicrm_option_group grp ON (grp.id = option_group_id AND grp.name =
     // Format params and add links.
     $contactActivities = [];
 
+    // View-only activity types
+    $viewOnlyCaseActivityTypeIDs = array_flip(CRM_Activity_BAO_Activity::getViewOnlyActivityTypeIDs());
+
     if (!empty($activities)) {
       $activityStatus = CRM_Core_PseudoConstant::activityStatus();
 
@@ -2538,6 +2563,7 @@ INNER JOIN  civicrm_option_group grp ON (grp.id = option_group_id AND grp.name =
       }
 
       $mask = CRM_Core_Action::mask($permissions);
+      $userID = CRM_Core_Session::getLoggedInContactID();
 
       foreach ($activities as $activityId => $values) {
         $activity = ['source_contact_name' => '', 'target_contact_name' => ''];
@@ -2663,29 +2689,83 @@ INNER JOIN  civicrm_option_group grp ON (grp.id = option_group_id AND grp.name =
           $accessMailingReport = TRUE;
         }
 
-        $actionLinks = CRM_Activity_Selector_Activity::actionLinks(
-          CRM_Utils_Array::value('activity_type_id', $values),
-          CRM_Utils_Array::value('source_record_id', $values),
-          $accessMailingReport,
-          CRM_Utils_Array::value('activity_id', $values)
-        );
+        // Get action links.
+
+        // If this is a case activity, then we hand off to Case's actionLinks instead.
+        if (!empty($values['case_id']) && Civi::settings()->get('civicaseShowCaseActivities')) {
+          // This activity belongs to a case.
+          $caseId = current($values['case_id']);
+
+          $activity['subject'] = $values['subject'];
+
+          // Get the view and edit (update) links:
+          $caseActionLinks =
+            $actionLinks = array_intersect_key(
+              CRM_Case_Selector_Search::actionLinks(),
+              array_fill_keys([CRM_Core_Action::VIEW, CRM_Core_Action::UPDATE], NULL));
+
+          // Create a Manage Case link (using ADVANCED as can't use two VIEW ones)
+          $actionLinks[CRM_Core_Action::ADVANCED] = [
+            "name"  => 'Manage Case',
+            "url"   => 'civicrm/contact/view/case',
+            'qs'    => 'reset=1&id=%%caseid%%&cid=%%cid%%&action=view&context=&selectedChild=case',
+            "title" => ts('Manage Case %1', [1 => $caseId]),
+            'class' => 'no-popup',
+          ];
+
+          $caseLinkValues = [
+            'aid'    => $activityId,
+            'caseid' => $caseId,
+            'cid'    => current(CRM_Case_BAO_Case::getCaseClients($caseId) ?? []),
+            // Unlike other 'context' params, this 'ctx' param is appended raw to the URL.
+            'cxt'    => '',
+          ];
+
+          $caseActivityPermissions = CRM_Core_Action::VIEW | CRM_Core_Action::ADVANCED;
+          // Allow Edit link if:
+          // 1. Activity type is NOT view-only type. CRM-5871
+          // 2. User has edit permission.
+          if (!isset($viewOnlyCaseActivityTypeIDs[$values['activity_type_id']])
+            && CRM_Case_BAO_Case::checkPermission($activityId, 'edit', $values['activity_type_id'], $userID)) {
+            // We're allowed to edit.
+            $caseActivityPermissions |= CRM_Core_Action::UPDATE;
+          }
 
-        $actionMask = array_sum(array_keys($actionLinks)) & $mask;
-
-        $activity['links'] = CRM_Core_Action::formLink($actionLinks,
-          $actionMask,
-          [
-            'id' => $values['activity_id'],
-            'cid' => $params['contact_id'],
-            'cxt' => $context,
-            'caseid' => CRM_Utils_Array::value('case_id', $values),
-          ],
-          ts('more'),
-          FALSE,
-          'activity.tab.row',
-          'Activity',
-          $values['activity_id']
-        );
+          $activity['links'] = CRM_Core_Action::formLink($actionLinks,
+            $caseActivityPermissions,
+            $caseLinkValues,
+            ts('more'),
+            FALSE,
+            'activity.tab.row',
+            'Activity',
+            $values['activity_id']
+          );
+        }
+        else {
+          // Non-case activity
+          $actionLinks = CRM_Activity_Selector_Activity::actionLinks(
+            CRM_Utils_Array::value('activity_type_id', $values),
+            CRM_Utils_Array::value('source_record_id', $values),
+            $accessMailingReport,
+            CRM_Utils_Array::value('activity_id', $values)
+          );
+          $actionMask = array_sum(array_keys($actionLinks)) & $mask;
+
+          $activity['links'] = CRM_Core_Action::formLink($actionLinks,
+            $actionMask,
+            [
+              'id' => $values['activity_id'],
+              'cid' => $params['contact_id'],
+              'cxt' => $context,
+              'caseid' => NULL,
+            ],
+            ts('more'),
+            FALSE,
+            'activity.tab.row',
+            'Activity',
+            $values['activity_id']
+          );
+        }
 
         if ($values['is_recurring_activity']) {
           $activity['is_recurring_activity'] = CRM_Core_BAO_RecurringEntity::getPositionAndCount($values['activity_id'], 'civicrm_activity');