Merge pull request #13906 from agh1/whygroupcontribamt
[civicrm-core.git] / api / v3 / Activity.php
index 374faaa929fca08f43e65cbedd9b8afe846cff1d..5fa7492538e79da7d6b05bf5552df35b71da1f7e 100644 (file)
@@ -49,11 +49,11 @@ function civicrm_api3_activity_create($params) {
     // an update does not require any mandatory parameters
     civicrm_api3_verify_one_mandatory($params,
       NULL,
-      array(
+      [
         'activity_name',
         'activity_type_id',
         'activity_label',
-      )
+      ]
     );
   }
 
@@ -69,7 +69,7 @@ function civicrm_api3_activity_create($params) {
   }
 
   // processing for custom data
-  $values = $activityArray = array();
+  $values = $activityArray = [];
   _civicrm_api3_custom_format_params($params, $values, 'Activity');
 
   if (!empty($values['custom'])) {
@@ -85,7 +85,7 @@ function civicrm_api3_activity_create($params) {
   // this handling should all be moved to the BAO layer
   $case_id = '';
   $createRevision = FALSE;
-  $oldActivityValues = array();
+  $oldActivityValues = [];
   // Lookup case id if not supplied
   if (!isset($params['case_id']) && !empty($params['id'])) {
     $params['case_id'] = CRM_Core_DAO::singleValueQuery("SELECT case_id FROM civicrm_case_activity WHERE activity_id = " . (int) $params['id']);
@@ -93,7 +93,7 @@ function civicrm_api3_activity_create($params) {
   if (!empty($params['case_id'])) {
     $case_id = $params['case_id'];
     if (!empty($params['id']) && Civi::settings()->get('civicaseActivityRevisions')) {
-      $oldActivityParams = array('id' => $params['id']);
+      $oldActivityParams = ['id' => $params['id']];
       if (!$oldActivityValues) {
         CRM_Activity_BAO_Activity::retrieve($oldActivityParams, $oldActivityValues);
       }
@@ -105,9 +105,6 @@ function civicrm_api3_activity_create($params) {
         $activityDAO->id = $params['id'];
         $activityDAO->is_current_revision = 0;
         if (!$activityDAO->save()) {
-          if (is_object($activityDAO)) {
-            $activityDAO->free();
-          }
           throw new API_Exception(ts("Unable to revision existing case activity."));
         }
         $createRevision = TRUE;
@@ -162,7 +159,7 @@ function civicrm_api3_activity_create($params) {
     if ($case_id && $isNew && !$createRevision) {
       // If this is a brand new case activity, add to case(s)
       foreach ((array) $case_id as $singleCaseId) {
-        $caseActivityParams = array('activity_id' => $activityBAO->id, 'case_id' => $singleCaseId);
+        $caseActivityParams = ['activity_id' => $activityBAO->id, 'case_id' => $singleCaseId];
         CRM_Case_BAO_Case::processCaseActivity($caseActivityParams);
       }
     }
@@ -183,26 +180,26 @@ function civicrm_api3_activity_create($params) {
  */
 function _civicrm_api3_activity_create_spec(&$params) {
 
-  $params['status_id']['api.aliases'] = array('activity_status');
+  $params['status_id']['api.aliases'] = ['activity_status'];
 
-  $params['assignee_contact_id'] = array(
+  $params['assignee_contact_id'] = [
     'name' => 'assignee_id',
     'title' => 'Activity Assignee',
     'description' => 'Contact(s) assigned to this activity.',
     'type' => 1,
     'FKClassName' => 'CRM_Contact_DAO_Contact',
     'FKApiName' => 'Contact',
-  );
-  $params['target_contact_id'] = array(
+  ];
+  $params['target_contact_id'] = [
     'name' => 'target_id',
     'title' => 'Activity Target',
     'description' => 'Contact(s) participating in this activity.',
     'type' => 1,
     'FKClassName' => 'CRM_Contact_DAO_Contact',
     'FKApiName' => 'Contact',
-  );
+  ];
 
-  $params['source_contact_id'] = array(
+  $params['source_contact_id'] = [
     'name' => 'source_contact_id',
     'title' => 'Activity Source Contact',
     'description' => 'Person who created this activity. Defaults to current user.',
@@ -211,16 +208,16 @@ function _civicrm_api3_activity_create_spec(&$params) {
     'api.default' => 'user_contact_id',
     'FKApiName' => 'Contact',
     'api.required' => TRUE,
-  );
+  ];
 
-  $params['case_id'] = array(
+  $params['case_id'] = [
     'name' => 'case_id',
     'title' => 'Case ID',
     'description' => 'For creating an activity as part of a case.',
     'type' => 1,
     'FKClassName' => 'CRM_Case_DAO_Case',
     'FKApiName' => 'Case',
-  );
+  ];
 
 }
 
@@ -230,62 +227,62 @@ function _civicrm_api3_activity_create_spec(&$params) {
  * @param array $params
  */
 function _civicrm_api3_activity_get_spec(&$params) {
-  $params['tag_id'] = array(
+  $params['tag_id'] = [
     'title' => 'Tags',
     'description' => 'Find activities with specified tags.',
     'type' => CRM_Utils_Type::T_INT,
     'FKClassName' => 'CRM_Core_DAO_Tag',
     'FKApiName' => 'Tag',
     'supports_joins' => TRUE,
-  );
-  $params['file_id'] = array(
+  ];
+  $params['file_id'] = [
     'title' => 'Attached Files',
     'description' => 'Find activities with attached files.',
     'type' => CRM_Utils_Type::T_INT,
     'FKClassName' => 'CRM_Core_DAO_File',
     'FKApiName' => 'File',
-  );
-  $params['case_id'] = array(
+  ];
+  $params['case_id'] = [
     'title' => 'Cases',
     'description' => 'Find activities within specified cases.',
     'type' => CRM_Utils_Type::T_INT,
     'FKClassName' => 'CRM_Case_DAO_Case',
     'FKApiName' => 'Case',
     'supports_joins' => TRUE,
-  );
-  $params['contact_id'] = array(
+  ];
+  $params['contact_id'] = [
     'title' => 'Activity Contact ID',
     'description' => 'Find activities involving this contact (as target, source, OR assignee).',
     'type' => CRM_Utils_Type::T_INT,
     'FKClassName' => 'CRM_Contact_DAO_Contact',
     'FKApiName' => 'Contact',
-  );
-  $params['target_contact_id'] = array(
+  ];
+  $params['target_contact_id'] = [
     'title' => 'Target Contact ID',
     'description' => 'Find activities with specified target contact.',
     'type' => CRM_Utils_Type::T_INT,
     'FKClassName' => 'CRM_Contact_DAO_Contact',
     'FKApiName' => 'Contact',
-  );
-  $params['source_contact_id'] = array(
+  ];
+  $params['source_contact_id'] = [
     'title' => 'Source Contact ID',
     'description' => 'Find activities with specified source contact.',
     'type' => CRM_Utils_Type::T_INT,
     'FKClassName' => 'CRM_Contact_DAO_Contact',
     'FKApiName' => 'Contact',
-  );
-  $params['assignee_contact_id'] = array(
+  ];
+  $params['assignee_contact_id'] = [
     'title' => 'Assignee Contact ID',
     'description' => 'Find activities with specified assignee contact.',
     'type' => CRM_Utils_Type::T_INT,
     'FKClassName' => 'CRM_Contact_DAO_Contact',
     'FKApiName' => 'Contact',
-  );
-  $params['is_overdue'] = array(
+  ];
+  $params['is_overdue'] = [
     'title' => 'Is Activity Overdue',
     'description' => 'Incomplete activities with a past date.',
     'type' => CRM_Utils_Type::T_BOOLEAN,
-  );
+  ];
 }
 
 /**
@@ -305,16 +302,6 @@ function civicrm_api3_activity_get($params) {
   $options = _civicrm_api3_get_options_from_params($params, FALSE, 'Activity', 'get');
   $sql = CRM_Utils_SQL_Select::fragment();
 
-  if (empty($params['target_contact_id']) && empty($params['source_contact_id'])
-    && empty($params['assignee_contact_id']) &&
-    !empty($params['check_permissions']) && !CRM_Core_Permission::check('view all activities')
-    && !CRM_Core_Permission::check('view all contacts')
-  ) {
-    // Force join on the activity contact table.
-    // @todo get this & other acl filters to work, remove check further down.
-    //$params['contact_id'] = array('IS NOT NULL' => TRUE);
-  }
-
   _civicrm_api3_activity_get_extraFilters($params, $sql);
 
   // Handle is_overdue sort
@@ -345,15 +332,6 @@ function civicrm_api3_activity_get($params) {
     return civicrm_api3_create_success($activities, $params, 'Activity', 'get');
   }
 
-  if (!empty($params['check_permissions']) && !CRM_Core_Permission::check('view all activities')) {
-    // @todo get this to work at the query level - see contact_id join above.
-    foreach ($activities as $activity) {
-      if (!CRM_Activity_BAO_Activity::checkPermission($activity['id'], CRM_Core_Action::VIEW)) {
-        unset($activities[$activity['id']]);
-      }
-    }
-  }
-
   $activities = _civicrm_api3_activity_get_formatResult($params, $activities, $options);
   //legacy custom data get - so previous formatted response is still returned too
   return civicrm_api3_create_success($activities, $params, 'Activity', 'get');
@@ -369,21 +347,21 @@ function civicrm_api3_activity_get($params) {
  */
 function _civicrm_api3_activity_get_extraFilters(&$params, &$sql) {
   // Filter by activity contacts
-  $activityContactOptions = array(
+  $activityContactOptions = [
     'contact_id' => NULL,
     'target_contact_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_ActivityContact', 'record_type_id', 'Activity Targets'),
     'source_contact_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_ActivityContact', 'record_type_id', 'Activity Source'),
     'assignee_contact_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_ActivityContact', 'record_type_id', 'Activity Assignees'),
-  );
+  ];
   foreach ($activityContactOptions as $activityContactName => $activityContactValue) {
     if (!empty($params[$activityContactName])) {
       if (!is_array($params[$activityContactName])) {
-        $params[$activityContactName] = array('=' => $params[$activityContactName]);
+        $params[$activityContactName] = ['=' => $params[$activityContactName]];
       }
       $clause = \CRM_Core_DAO::createSQLFilter('contact_id', $params[$activityContactName]);
       $typeClause = $activityContactValue ? 'record_type_id = #typeId AND ' : '';
       $sql->where("a.id IN (SELECT activity_id FROM civicrm_activity_contact WHERE $typeClause !clause)",
-        array('#typeId' => $activityContactValue, '!clause' => $clause)
+        ['#typeId' => $activityContactValue, '!clause' => $clause]
       );
     }
   }
@@ -405,41 +383,41 @@ function _civicrm_api3_activity_get_extraFilters(&$params, &$sql) {
   // Subqueries are nice in (a) avoiding duplicates and (b) when the result
   // list is expected to be bite-sized. Joins are nice (a) with larger
   // datasets and (b) checking for non-existent relations.
-  $rels = array(
-    'tag_id' => array(
+  $rels = [
+    'tag_id' => [
       'subquery' => 'a.id IN (SELECT entity_id FROM civicrm_entity_tag WHERE entity_table = "civicrm_activity" AND !clause)',
       'join' => '!joinType civicrm_entity_tag !alias ON (!alias.entity_table = "civicrm_activity" AND !alias.entity_id = a.id)',
       'column' => 'tag_id',
-    ),
-    'file_id' => array(
+    ],
+    'file_id' => [
       'subquery' => 'a.id IN (SELECT entity_id FROM civicrm_entity_file WHERE entity_table = "civicrm_activity" AND !clause)',
       'join' => '!joinType civicrm_entity_file !alias ON (!alias.entity_table = "civicrm_activity" AND !alias.entity_id = a.id)',
       'column' => 'file_id',
-    ),
-    'case_id' => array(
+    ],
+    'case_id' => [
       'subquery' => 'a.id IN (SELECT activity_id FROM civicrm_case_activity WHERE !clause)',
       'join' => '!joinType civicrm_case_activity !alias ON (!alias.activity_id = a.id)',
       'column' => 'case_id',
-    ),
-  );
+    ],
+  ];
   foreach ($rels as $filter => $relSpec) {
     if (!empty($params[$filter])) {
       if (!is_array($params[$filter])) {
-        $params[$filter] = array('=' => $params[$filter]);
+        $params[$filter] = ['=' => $params[$filter]];
       }
       // $mode is one of ('LEFT JOIN', 'INNER JOIN', 'SUBQUERY')
       $mode = isset($params[$filter]['IS NULL']) ? 'LEFT JOIN' : 'SUBQUERY';
       if ($mode === 'SUBQUERY') {
         $clause = \CRM_Core_DAO::createSQLFilter($relSpec['column'], $params[$filter]);
         if ($clause) {
-          $sql->where($relSpec['subquery'], array('!clause' => $clause));
+          $sql->where($relSpec['subquery'], ['!clause' => $clause]);
         }
       }
       else {
         $alias = 'actjoin_' . $filter;
         $clause = \CRM_Core_DAO::createSQLFilter($alias . "." . $relSpec['column'], $params[$filter]);
         if ($clause) {
-          $sql->join($alias, $relSpec['join'], array('!alias' => $alias, 'joinType' => $mode));
+          $sql->join($alias, $relSpec['join'], ['!alias' => $alias, 'joinType' => $mode]);
           $sql->where($clause);
         }
       }
@@ -455,6 +433,8 @@ function _civicrm_api3_activity_get_extraFilters(&$params, &$sql) {
  * @param array $params
  *   API request parameters.
  * @param array $activities
+ * @param array $options
+ *   Options array (pre-processed to extract 'return' from params).
  *
  * @return array
  *   new activities list
@@ -466,22 +446,17 @@ function _civicrm_api3_activity_get_formatResult($params, $activities, $options)
 
   $returns = $options['return'];
   foreach ($params as $n => $v) {
+    // @todo - the per-parsing on options should have already done this.
     if (substr($n, 0, 7) == 'return.') {
       $returnkey = substr($n, 7);
       $returns[$returnkey] = $v;
     }
   }
 
-  $returns['source_contact_id'] = 1;
-  if (!empty($returns['target_contact_name'])) {
-    $returns['target_contact_id'] = 1;
-  }
-  if (!empty($returns['assignee_contact_name'])) {
-    $returns['assignee_contact_id'] = 1;
-  }
+  _civicrm_api3_activity_fill_activity_contact_names($activities, $params, $returns);
 
-  $tagGet = array('tag_id', 'entity_id');
-  $caseGet = $caseIds = array();
+  $tagGet = ['tag_id', 'entity_id'];
+  $caseGet = $caseIds = [];
   foreach (array_keys($returns) as $key) {
     if (strpos($key, 'tag_id.') === 0) {
       $tagGet[] = $key;
@@ -496,43 +471,23 @@ function _civicrm_api3_activity_get_formatResult($params, $activities, $options)
   foreach ($returns as $n => $v) {
     switch ($n) {
       case 'assignee_contact_id':
-        foreach ($activities as $key => $activityArray) {
-          $cids = $activities[$key]['assignee_contact_id'] = CRM_Activity_BAO_ActivityAssignment::retrieveAssigneeIdsByActivityId($activityArray['id']);
-          if ($cids && !empty($returns['assignee_contact_name'])) {
-            foreach ($cids as $cid) {
-              $activities[$key]['assignee_contact_name'][$cid] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name');
-            }
-          }
-        }
-        break;
-
       case 'target_contact_id':
-        foreach ($activities as $key => $activityArray) {
-          $cids = $activities[$key]['target_contact_id'] = CRM_Activity_BAO_ActivityTarget::retrieveTargetIdsByActivityId($activityArray['id']);
-          if ($cids && !empty($returns['target_contact_name'])) {
-            foreach ($cids as $cid) {
-              $activities[$key]['target_contact_name'][$cid] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name');
-            }
+        foreach ($activities as &$activity) {
+          if (!isset($activity[$n])) {
+            $activity[$n] = [];
           }
         }
-        break;
 
       case 'source_contact_id':
-        foreach ($activities as $key => $activityArray) {
-          $cid = $activities[$key]['source_contact_id'] = CRM_Activity_BAO_Activity::getSourceContactID($activityArray['id']);
-          if ($cid && !empty($returns['source_contact_name'])) {
-            $activities[$key]['source_contact_name'] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name');
-          }
-        }
         break;
 
       case 'tag_id':
-        $tags = civicrm_api3('EntityTag', 'get', array(
+        $tags = civicrm_api3('EntityTag', 'get', [
           'entity_table' => 'civicrm_activity',
-          'entity_id' => array('IN' => array_keys($activities)),
+          'entity_id' => ['IN' => array_keys($activities)],
           'return' => $tagGet,
-          'options' => array('limit' => 0),
-        ));
+          'options' => ['limit' => 0],
+        ]);
         foreach ($tags['values'] as $tag) {
           $key = (int) $tag['entity_id'];
           unset($tag['entity_id'], $tag['id']);
@@ -542,7 +497,7 @@ function _civicrm_api3_activity_get_formatResult($params, $activities, $options)
 
       case 'file_id':
         $dao = CRM_Core_DAO::executeQuery("SELECT entity_id, file_id FROM civicrm_entity_file WHERE entity_table = 'civicrm_activity' AND entity_id IN (%1)",
-          array(1 => array(implode(',', array_keys($activities)), 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES)));
+          [1 => [implode(',', array_keys($activities)), 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES]]);
         while ($dao->fetch()) {
           $activities[$dao->entity_id]['file_id'][] = $dao->file_id;
         }
@@ -550,7 +505,7 @@ function _civicrm_api3_activity_get_formatResult($params, $activities, $options)
 
       case 'case_id':
         $dao = CRM_Core_DAO::executeQuery("SELECT activity_id, case_id FROM civicrm_case_activity WHERE activity_id IN (%1)",
-          array(1 => array(implode(',', array_keys($activities)), 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES)));
+          [1 => [implode(',', array_keys($activities)), 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES]]);
         while ($dao->fetch()) {
           $activities[$dao->activity_id]['case_id'][] = $dao->case_id;
           $caseIds[$dao->case_id] = $dao->case_id;
@@ -573,12 +528,12 @@ function _civicrm_api3_activity_get_formatResult($params, $activities, $options)
   // Fetch case fields via the join syntax
   // Note this is limited to the first case if the activity belongs to more than one
   if ($caseGet && $caseIds) {
-    $cases = civicrm_api3('Case', 'get', array(
-      'id' => array('IN' => $caseIds),
-      'options' => array('limit' => 0),
+    $cases = civicrm_api3('Case', 'get', [
+      'id' => ['IN' => $caseIds],
+      'options' => ['limit' => 0],
       'check_permissions' => !empty($params['check_permissions']),
       'return' => $caseGet,
-    ));
+    ]);
     foreach ($activities as &$activity) {
       if (!empty($activity['case_id'])) {
         $case = CRM_Utils_Array::value($activity['case_id'][0], $cases['values']);
@@ -616,6 +571,66 @@ function _civicrm_api3_activity_get_formatResult($params, $activities, $options)
   return $activities;
 }
 
+/**
+ * Append activity contact details to activity results.
+ *
+ * Adds id & name of activity contacts to results array if check_permissions
+ * does not block access to them.
+ *
+ * For historical reasons source_contact_id is always added & is not an array.
+ * The others are added depending on requested return params.
+ *
+ * @param array $activities
+ * @param array $params
+ * @param array $returns
+ */
+function _civicrm_api3_activity_fill_activity_contact_names(&$activities, $params, $returns) {
+  $contactTypes = array_flip(CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate'));
+  $assigneeType = $contactTypes['Activity Assignees'];
+  $targetType = $contactTypes['Activity Targets'];
+  $sourceType = $contactTypes['Activity Source'];
+  $typeMap = [
+    $assigneeType => 'assignee',
+    $sourceType => 'source',
+    $targetType => 'target'
+  ];
+
+  $activityContactTypes = [$sourceType];
+
+  if (!empty($returns['target_contact_name']) || !empty($returns['target_contact_id'])) {
+    $activityContactTypes[] = $targetType;
+  }
+  if (!empty($returns['assignee_contact_name']) || (!empty($returns['assignee_contact_id']))) {
+    $activityContactTypes[] = $assigneeType;
+  }
+  $activityContactParams = [
+    'activity_id' => ['IN' => array_keys($activities)],
+    'return' => [
+      'activity_id',
+      'record_type_id',
+      'contact_id.display_name',
+      'contact_id'
+    ],
+    'check_permissions' => !empty($params['check_permissions']),
+  ];
+  if (count($activityContactTypes) < 3) {
+    $activityContactParams['record_type_id'] = ['IN' => $activityContactTypes];
+  }
+  $activityContacts = civicrm_api3('ActivityContact', 'get', $activityContactParams)['values'];
+  foreach ($activityContacts as $activityContact) {
+    $contactID = $activityContact['contact_id'];
+    $recordType = $typeMap[$activityContact['record_type_id']];
+    if (in_array($recordType, ['target', 'assignee'])) {
+      $activities[$activityContact['activity_id']][$recordType . '_contact_id'][] = $contactID;
+      $activities[$activityContact['activity_id']][$recordType . '_contact_name'][$contactID] = isset($activityContact['contact_id.display_name']) ? $activityContact['contact_id.display_name'] : '';
+    }
+    else {
+      $activities[$activityContact['activity_id']]['source_contact_id'] = $contactID;
+      $activities[$activityContact['activity_id']]['source_contact_name'] = isset($activityContact['contact_id.display_name']) ? $activityContact['contact_id.display_name'] : '';
+    }
+  }
+}
+
 
 /**
  * Delete a specified Activity.
@@ -650,11 +665,11 @@ function civicrm_api3_activity_delete($params) {
  *   array with errors
  */
 function _civicrm_api3_activity_check_params(&$params) {
-  $activityIds = array(
+  $activityIds = [
     'activity' => CRM_Utils_Array::value('id', $params),
     'parent' => CRM_Utils_Array::value('parent_id', $params),
     'original' => CRM_Utils_Array::value('original_id', $params),
-  );
+  ];
 
   foreach ($activityIds as $id => $value) {
     if ($value &&
@@ -720,18 +735,18 @@ function _civicrm_api3_activity_check_params(&$params) {
  *   API request.
  */
 function _civicrm_api3_activity_getlist_params(&$request) {
-  $fieldsToReturn = array(
+  $fieldsToReturn = [
     'activity_date_time',
     'activity_type_id',
     'subject',
     'source_contact_id',
-  );
+  ];
   $request['params']['return'] = array_unique(array_merge($fieldsToReturn, $request['extra']));
   $request['params']['options']['sort'] = 'activity_date_time DESC';
-  $request['params'] += array(
+  $request['params'] += [
     'is_current_revision' => 1,
     'is_deleted' => 0,
-  );
+  ];
 }
 
 /**
@@ -745,29 +760,29 @@ function _civicrm_api3_activity_getlist_params(&$request) {
  * @return array
  */
 function _civicrm_api3_activity_getlist_output($result, $request) {
-  $output = array();
+  $output = [];
   if (!empty($result['values'])) {
     foreach ($result['values'] as $row) {
-      $data = array(
+      $data = [
         'id' => $row[$request['id_field']],
         'label' => $row[$request['label_field']] ? $row[$request['label_field']] : ts('(no subject)'),
-        'description' => array(
+        'description' => [
           CRM_Core_Pseudoconstant::getLabel('CRM_Activity_BAO_Activity', 'activity_type_id', $row['activity_type_id']),
-        ),
-      );
+        ],
+      ];
       if (!empty($row['activity_date_time'])) {
         $data['description'][0] .= ': ' . CRM_Utils_Date::customFormat($row['activity_date_time']);
       }
       if (!empty($row['source_contact_id'])) {
-        $data['description'][] = ts('By %1', array(
+        $data['description'][] = ts('By %1', [
           1 => CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $row['source_contact_id'], 'display_name'),
-        ));
+        ]);
       }
       // Add repeating info
       $repeat = CRM_Core_BAO_RecurringEntity::getPositionAndCount($row['id'], 'civicrm_activity');
       $data['extra']['is_recur'] = FALSE;
       if ($repeat) {
-        $data['suffix'] = ts('(%1 of %2)', array(1 => $repeat[0], 2 => $repeat[1]));
+        $data['suffix'] = ts('(%1 of %2)', [1 => $repeat[0], 2 => $repeat[1]]);
         $data['extra']['is_recur'] = TRUE;
       }
       $output[] = $data;