diff --git a/CRM/Activity/BAO/Activity.php b/CRM/Activity/BAO/Activity.php index f4dda7fb036c..e990994d56c9 100644 --- a/CRM/Activity/BAO/Activity.php +++ b/CRM/Activity/BAO/Activity.php @@ -663,19 +663,28 @@ public static function logActivityAction($activity, $logMessage = NULL) { * Relevant data object values of open activities */ public static function getActivities($params, $getCount = FALSE) { + $activities = array(); + // fetch all activity IDs whose target/assignee/source contact id is $params['contact_id'] // currently cannot be done via Activity.Get API so we are using SQL query instead - $activityIDs = CRM_Core_DAO::singleValueQuery("SELECT GROUP_CONCAT(DISTINCT activity_id SEPARATOR ',') - FROM civicrm_activity_contact - WHERE contact_id = %1", array(1 => array($params['contact_id'], 'Integer'))); - $activityIDs = explode(',', $activityIDs); + if (!empty($params['contact_id'])) { + $activityIDs = CRM_Core_DAO::singleValueQuery("SELECT GROUP_CONCAT(DISTINCT activity_id SEPARATOR ',') + FROM civicrm_activity_contact + WHERE contact_id = %1", array(1 => array($params['contact_id'], 'Integer'))); + + // if no activities found for given $params['contact_id'] then return empty array + if (empty($activityIDs)) { + return $getCount ? count($activities) : $activities; + } + $activityIDs = explode(',', $activityIDs); + } // fetch all active activity types $activityTypes = CRM_Core_OptionGroup::values('activity_type'); // Activity.Get API params $activityParams = array( - 'id' => array('IN' => $activityIDs), + 'id' => (!empty($activityIDs)) ? array('IN' => $activityIDs) : NULL, 'is_deleted' => 0, 'is_current_revision' => 1, 'is_test' => 0, @@ -702,7 +711,7 @@ public static function getActivities($params, $getCount = FALSE) { ); if ($params['context'] != 'activity') { - $activityParams['status_id'] = 'Scheduled'; + $activityParams['status_id'] = CRM_Core_PseudoConstant::getKey(__CLASS__, 'status_id', 'Scheduled'); } // activity type ID clause @@ -753,20 +762,18 @@ public static function getActivities($params, $getCount = FALSE) { $activityParams['options']['sort'] = (CRM_Utils_Array::value('context', $params) == 'activity') ? "activity_date_time DESC" : "status_id ASC, activity_date_time ASC"; } else { - $activityParams['options']['sort'] = $order; + $activityParams['options']['sort'] = str_replace('activity_type ', 'activity_type_id.label ', $order); } //TODO : - // 1. missing support for is_recurring_activity in API - // 2. check is_deleted source_contact_id, this earlier wrap <del> tag around deleted contact name - // 3. missing support to sort by activity_type in API, - // this will cause regression in selector column if someone sort by activity type + // 1. we should use Activity.Getcount for fetching count only, but in order to check that + // current logged in user has permission to view Case activities we are performing filtering out those activities from list (see below). + // This logic need to be incorporated in Activity.get definition $result = civicrm_api3('Activity', 'Get', $activityParams); - $activties = array(); $enabledComponents = self::activityComponents(); $allCampaigns = CRM_Campaign_BAO_Campaign::getCampaigns(NULL, NULL, FALSE, FALSE, FALSE, TRUE); - $bulkActivityTypeID = CRM_Core_OptionGroup::getValue('activity_type', 'Bulk Email', 'name'); + $bulkActivityTypeID = CRM_Core_PseudoConstant::getKey(__CLASS__, 'activity_type_id', 'Bulk Email'); // CRM-3553, need to check user has access to target groups. $mailingIDs = CRM_Mailing_BAO_Mailing::mailingACLIDs(); @@ -787,7 +794,6 @@ public static function getActivities($params, $getCount = FALSE) { 'source_contact_id' => 'source_contact_id', 'source_contact_name' => 'source_contact_name', 'case_id' => 'case_id', - 'case_subject' => 'case_subject', ); foreach ($result['values'] as $id => $activity) { @@ -822,8 +828,13 @@ public static function getActivities($params, $getCount = FALSE) { } } // case related fields - elseif (in_array($apiKey, array('case_id', 'case_subject')) && !$isBulkActivity) { + elseif ($apiKey == 'case_id' && !$isBulkActivity) { $activities[$id][$expectedName] = CRM_Utils_Array::value($apiKey, $activity); + + // fetch case subject for case ID found + if (!empty($activity['case_id'])) { + $activities[$id]['case_subject'] = CRM_Core_DAO::executeQuery('CRM_Case_DAO_Case', $activity['case_id'], 'subject'); + } } else { $activities[$id][$expectedName] = CRM_Utils_Array::value($apiKey, $activity); @@ -835,6 +846,13 @@ public static function getActivities($params, $getCount = FALSE) { } } } + // if deleted, wrap in <del> + if (!empty($activity['source_contact_id']) && + CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $activity['source_contact_id'], 'is_deleted') + ) { + $activities[$id]['source_contact_name'] = sprintf("<del>%s<del>", $activity['source_contact_name']); + } + $activities[$id]['is_recurring_activity'] = CRM_Core_BAO_RecurringEntity::getParentFor($id, 'civicrm_activity'); } return $getCount ? count($activities) : $activities; diff --git a/api/v3/Activity.php b/api/v3/Activity.php index cd783a0e730b..5815edc9e4b1 100644 --- a/api/v3/Activity.php +++ b/api/v3/Activity.php @@ -470,16 +470,10 @@ function _civicrm_api3_activity_get_formatResult($params, $activities, $options) break; case 'case_id': - case 'case_subject': - $dao = CRM_Core_DAO::executeQuery("SELECT activity_id, case_id, subject FROM civicrm_case_activity cca INNER JOIN civicrm_case cc ON cc.id = cca.case_id WHERE activity_id IN (%1)", + $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))); while ($dao->fetch()) { - if ($n == 'case_id') { - $activities[$dao->activity_id]['case_id'] = $dao->case_id; - } - else { - $activities[$dao->activity_id]['case_subject'] = $dao->subject; - } + $activities[$dao->activity_id]['case_id'] = $dao->case_id; } break; diff --git a/tests/phpunit/CRM/Activity/BAO/ActivityTest.php b/tests/phpunit/CRM/Activity/BAO/ActivityTest.php index 006307aa8092..77d16119ff87 100644 --- a/tests/phpunit/CRM/Activity/BAO/ActivityTest.php +++ b/tests/phpunit/CRM/Activity/BAO/ActivityTest.php @@ -271,7 +271,7 @@ public function testDeleteActivityAssignment() { } /** - * Test getActivitiesCount BAO method. + * Test getActivities BAO method for getting count. */ public function testGetActivitiesCountforAdminDashboard() { $op = new PHPUnit_Extensions_Database_Operation_Insert(); @@ -291,7 +291,7 @@ public function testGetActivitiesCountforAdminDashboard() { 'rowCount' => 0, 'sort' => NULL, ); - $activityCount = CRM_Activity_BAO_Activity::getActivitiesCount($params); + $activityCount = CRM_Activity_BAO_Activity::getActivities($params, TRUE); //since we are loading activities from dataset, we know total number of activities // 8 schedule activities that should be shown on dashboard @@ -300,7 +300,7 @@ public function testGetActivitiesCountforAdminDashboard() { } /** - * Test getActivitiesCount BAO method. + * Test getActivities BAO method for getting count */ public function testGetActivitiesCountforNonAdminDashboard() { $op = new PHPUnit_Extensions_Database_Operation_Insert(); @@ -321,7 +321,7 @@ public function testGetActivitiesCountforNonAdminDashboard() { 'sort' => NULL, ); - $activityCount = CRM_Activity_BAO_Activity::getActivitiesCount($params); + $activityCount = CRM_Activity_BAO_Activity::getActivities($params, TRUE); //since we are loading activities from dataset, we know total number of activities for this contact // 5 activities ( 2 scheduled, 3 Completed ), note that dashboard shows only scheduled activities @@ -330,7 +330,7 @@ public function testGetActivitiesCountforNonAdminDashboard() { } /** - * Test getActivitiesCount BAO method. + * Test getActivities BAO method for getting count */ public function testGetActivitiesCountforContactSummary() { $op = new PHPUnit_Extensions_Database_Operation_Insert(); @@ -350,7 +350,7 @@ public function testGetActivitiesCountforContactSummary() { 'rowCount' => 0, 'sort' => NULL, ); - $activityCount = CRM_Activity_BAO_Activity::getActivitiesCount($params); + $activityCount = CRM_Activity_BAO_Activity::getActivities($params, TRUE); //since we are loading activities from dataset, we know total number of activities for this contact // 5 activities, Contact Summary should show all activities @@ -394,7 +394,7 @@ public function testActivityFilters() { } /** - * Test getActivitiesCount BAO method. + * Test getActivities BAO method for getting count */ public function testGetActivitiesCountforContactSummaryWithNoActivities() { $op = new PHPUnit_Extensions_Database_Operation_Insert(); @@ -414,7 +414,7 @@ public function testGetActivitiesCountforContactSummaryWithNoActivities() { 'rowCount' => 0, 'sort' => NULL, ); - $activityCount = CRM_Activity_BAO_Activity::getActivitiesCount($params); + $activityCount = CRM_Activity_BAO_Activity::getActivities($params, TRUE); //since we are loading activities from dataset, we know total number of activities for this contact // this contact does not have any activity @@ -433,7 +433,7 @@ public function testGetActivitiesforAdminDashboard() { ); $params = array( - 'contact_id' => 5, + 'contact_id' => NULL, 'admin' => TRUE, 'caseId' => NULL, 'context' => 'home', @@ -445,7 +445,7 @@ public function testGetActivitiesforAdminDashboard() { $activities = CRM_Activity_BAO_Activity::getActivities($params); //since we are loading activities from dataset, we know total number of activities - // 8 schedule activities that should be shown on dashboard + // with no contact ID and there should be 8 schedule activities shown on dashboard $count = 8; $this->assertEquals($count, count($activities)); @@ -583,7 +583,7 @@ public function testGetActivitiesforContactSummary() { /** * Test getActivities BAO method. */ - public function testGetActivitiesforContactSummaryWithNoActivities() { + public function testGetActivitiesforContactSummaryWithActivities() { $op = new PHPUnit_Extensions_Database_Operation_Insert(); $op->execute($this->_dbconn, $this->createFlatXMLDataSet( @@ -591,21 +591,116 @@ public function testGetActivitiesforContactSummaryWithNoActivities() { ) ); - $params = array( - 'contact_id' => 17, - 'admin' => FALSE, - 'caseId' => NULL, - 'context' => 'home', - 'activity_type_id' => NULL, - 'offset' => 0, - 'rowCount' => 0, - 'sort' => NULL, - ); - $activities = CRM_Activity_BAO_Activity::getActivities($params); - - //since we are loading activities from dataset, we know total number of activities for this contact - // This contact does not have any activities - $this->assertEquals(0, count($activities)); + // parameters for different test casess, check each array key for the specific test-case + $testCases = array( + 'with-no-activity' => array( + 'params' => array( + 'contact_id' => 17, + 'admin' => FALSE, + 'caseId' => NULL, + 'context' => 'home', + 'activity_type_id' => NULL, + 'offset' => 0, + 'rowCount' => 0, + 'sort' => NULL, + ), + ), + 'with-activity' => array( + 'params' => array( + 'contact_id' => 1, + 'admin' => FALSE, + 'caseId' => NULL, + 'context' => 'home', + 'activity_type_id' => NULL, + 'offset' => 0, + 'rowCount' => 0, + 'sort' => NULL, + ), + ), + 'with-activity_type' => array( + 'params' => array( + 'contact_id' => 3, + 'admin' => FALSE, + 'caseId' => NULL, + 'context' => 'home', + 'activity_type_id' => 2, + 'offset' => 0, + 'rowCount' => 0, + 'sort' => NULL, + ), + ), + 'exclude-all-activity_type' => array( + 'params' => array( + 'contact_id' => 3, + 'admin' => FALSE, + 'caseId' => NULL, + 'context' => 'home', + 'activity_type_exclude_id' => array(1, 2), + 'offset' => 0, + 'rowCount' => 0, + 'sort' => NULL, + ), + ), + 'sort-by-subject' => array( + 'params' => array( + 'contact_id' => 1, + 'admin' => FALSE, + 'caseId' => NULL, + 'context' => 'home', + 'activity_type_id' => NULL, + 'offset' => 0, + 'rowCount' => 0, + 'sort' => 'subject DESC', + ), + ), + ); + + foreach ($testCases as $caseName => $testCase) { + $activities = CRM_Activity_BAO_Activity::getActivities($testCase['params']); + $activityCount = CRM_Activity_BAO_Activity::getActivities($testCase['params'], TRUE); + if ($caseName == 'with-no-activity') { + $this->assertEquals(0, count($activities)); + $this->assertEquals(0, $activityCount); + } + elseif ($caseName == 'with-activity') { + // contact id 1 is assigned as source, target and assignee for activity id 1, 7 and 8 respectively + $this->assertEquals(3, count($activities)); + $this->assertEquals(3, $activityCount); + $this->assertEquals(1, $activities[1]['source_contact_id']); + $this->assertEquals(TRUE, array_key_exists(1, $activities[7]['target_contact_name'])); + $this->assertEquals(TRUE, array_key_exists(1, $activities[8]['assignee_contact_name'])); + } + elseif ($caseName == 'with-activity_type') { + // contact id 3 for activity type 2 is assigned as assignee, source and target for + // activity id 1, 3 and 8 respectively + $this->assertEquals(3, count($activities)); + $this->assertEquals(3, $activityCount); + // ensure activity type id is 2 + $this->assertEquals(2, $activities[1]['activity_type_id']); + $this->assertEquals(3, $activities[3]['source_contact_id']); + $this->assertEquals(TRUE, array_key_exists(3, $activities[8]['target_contact_name'])); + $this->assertEquals(TRUE, array_key_exists(3, $activities[1]['assignee_contact_name'])); + } + if ($caseName == 'exclude-all-activity_type') { + $this->assertEquals(0, count($activities)); + $this->assertEquals(0, $activityCount); + } + if ($caseName == 'sort-by-subject') { + $this->assertEquals(3, count($activities)); + $this->assertEquals(3, $activityCount); + // activities should be order by 'subject DESC' + $subjectOrder = array( + 'subject 8', + 'subject 7', + 'subject 1', + ); + $count = 0; + foreach ($activities as $activity) { + $this->assertEquals($subjectOrder[$count], $activity['subject']); + $count++; + } + } + } } }