X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FActivity%2FBAO%2FActivity.php;h=d24c024803af9d8cba6ce564ab29a12c1e3385a6;hb=34769821c1a4c494e1828c1e7100aedf2eee2caf;hp=36fd46e59940c1078715edff78a9d6752d064eec;hpb=24704c73fe5f5ee2ca19a9fc98101841ee7c854a;p=civicrm-core.git diff --git a/CRM/Activity/BAO/Activity.php b/CRM/Activity/BAO/Activity.php index 36fd46e599..090ef3b103 100644 --- a/CRM/Activity/BAO/Activity.php +++ b/CRM/Activity/BAO/Activity.php @@ -706,7 +706,6 @@ class CRM_Activity_BAO_Activity extends CRM_Activity_DAO_Activity { 'source_contact_name', 'assignee_contact_id', 'target_contact_id', - 'target_contact_name', 'assignee_contact_name', 'status_id', 'subject', @@ -740,7 +739,6 @@ class CRM_Activity_BAO_Activity extends CRM_Activity_DAO_Activity { 'subject' => 'subject', 'campaign_id' => 'campaign_id', 'assignee_contact_name' => 'assignee_contact_name', - 'target_contact_name' => 'target_contact_name', 'source_contact_id' => 'source_contact_id', 'source_contact_name' => 'source_contact_name', 'case_id' => 'case_id', @@ -751,13 +749,19 @@ class CRM_Activity_BAO_Activity extends CRM_Activity_DAO_Activity { $activities[$id] = array(); $isBulkActivity = (!$bulkActivityTypeID || ($bulkActivityTypeID === $activity['activity_type_id'])); - + $activities[$id]['target_contact_counter'] = count($activity['target_contact_id']); + if ($activities[$id]['target_contact_counter']) { + try { + $activities[$id]['target_contact_name'][$activity['target_contact_id'][0]] = civicrm_api3('Contact', 'getvalue', ['id' => $activity['target_contact_id'][0], 'return' => 'sort_name']); + } + catch (CiviCRM_API3_Exception $e) { + // Really they should have names but a fatal here feels wrong. + $activities[$id]['target_contact_name'] = ''; + } + } foreach ($mappingParams as $apiKey => $expectedName) { if (in_array($apiKey, array('assignee_contact_name', 'target_contact_name'))) { $activities[$id][$expectedName] = CRM_Utils_Array::value($apiKey, $activity, array()); - if ($apiKey == 'target_contact_name' && count($activity['target_contact_name'])) { - $activities[$id]['target_contact_counter'] = count($activity['target_contact_name']); - } if ($isBulkActivity) { $activities[$id]['recipients'] = ts('(%1 recipients)', array(1 => count($activity['target_contact_name']))); @@ -1117,6 +1121,22 @@ ORDER BY fixed_sort_order return $values; } + /** + * @inheritDoc + */ + public function addSelectWhereClause() { + $clauses = parent::addSelectWhereClause(); + if (!CRM_Core_Permission::check('view all activities')) { + $permittedActivityTypeIDs = self::getPermittedActivityTypes(); + if (empty($permittedActivityTypeIDs)) { + // This just prevents a mysql fail if they have no access - should be extremely edge case. + $permittedActivityTypeIDs = [0]; + } + $clauses['activity_type_id'] = ('IN (' . implode(', ', $permittedActivityTypeIDs) . ')'); + } + return $clauses; + } + /** * Get an array of components that are accessible by the currenct user. * @@ -2341,7 +2361,6 @@ AND cl.modified_id = c.id $priorActivities[$index][$dao->activityID]['name'] = $dao->name; $priorActivities[$index][$dao->activityID]['date'] = $dao->date; } - $dao->free(); } } return $priorActivities[$index]; @@ -2409,9 +2428,7 @@ AND cl.modified_id = c.id $followupParams['target_contact_id'] = $params['target_contact_id']; } - $followupParams['activity_date_time'] = CRM_Utils_Date::processDate($params['followup_date'], - $params['followup_date_time'] - ); + $followupParams['activity_date_time'] = $params['followup_date']; $followupActivity = self::create($followupParams); return $followupActivity; @@ -2660,10 +2677,8 @@ AND cl.modified_id = c.id $result = self::deleteActivity($activityParams); } - $activityContactOther->free(); } - $activityContact->free(); $transaction->commit(); return $result; @@ -2693,15 +2708,17 @@ AND cl.modified_id = c.id return FALSE; } + if (!self::hasPermissionForActivityType($activity->activity_type_id)) { + // this check is redundant for api access / anything that calls the selectWhereClause + // to determine ACLs. + return FALSE; + } // Return early when it is case activity. // Check for CiviCase related permission. if (CRM_Case_BAO_Case::isCaseActivity($activityId)) { return self::isContactPermittedAccessToCaseActivity($activityId, $action, $activity->activity_type_id); } - // Component related permissions. - $allow = self::hasPermissionForActivityType($activity->activity_type_id); - // Check for this permission related to contact. $permission = CRM_Core_Permission::VIEW; if ($action == CRM_Core_Action::UPDATE) { @@ -2714,43 +2731,42 @@ AND cl.modified_id = c.id $targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts); // Check for source contact. - if ($allow) { - $sourceContactId = self::getActivityContact($activity->id, $sourceID); - // Account for possibility of activity not having a source contact (as it may have been deleted). - $allow = $sourceContactId ? CRM_Contact_BAO_Contact_Permission::allow($sourceContactId, $permission) : TRUE; + $sourceContactId = self::getActivityContact($activity->id, $sourceID); + // Account for possibility of activity not having a source contact (as it may have been deleted). + $allow = $sourceContactId ? CRM_Contact_BAO_Contact_Permission::allow($sourceContactId, $permission) : TRUE; + if (!$allow) { + return FALSE; } // Check for target and assignee contacts. - if ($allow) { - // First check for supper permission. - $supPermission = 'view all contacts'; - if ($action == CRM_Core_Action::UPDATE) { - $supPermission = 'edit all contacts'; - } - $allow = CRM_Core_Permission::check($supPermission); - - // User might have sufficient permission, through acls. - if (!$allow) { - $allow = TRUE; - // Get the target contacts. - $targetContacts = CRM_Activity_BAO_ActivityContact::retrieveContactIdsByActivityId($activity->id, $targetID); - foreach ($targetContacts as $cnt => $contactId) { + // First check for supper permission. + $supPermission = 'view all contacts'; + if ($action == CRM_Core_Action::UPDATE) { + $supPermission = 'edit all contacts'; + } + $allow = CRM_Core_Permission::check($supPermission); + + // User might have sufficient permission, through acls. + if (!$allow) { + $allow = TRUE; + // Get the target contacts. + $targetContacts = CRM_Activity_BAO_ActivityContact::retrieveContactIdsByActivityId($activity->id, $targetID); + foreach ($targetContacts as $cnt => $contactId) { + if (!CRM_Contact_BAO_Contact_Permission::allow($contactId, $permission)) { + $allow = FALSE; + break; + } + } + + // Get the assignee contacts. + if ($allow) { + $assigneeContacts = CRM_Activity_BAO_ActivityContact::retrieveContactIdsByActivityId($activity->id, $assigneeID); + foreach ($assigneeContacts as $cnt => $contactId) { if (!CRM_Contact_BAO_Contact_Permission::allow($contactId, $permission)) { $allow = FALSE; break; } } - - // Get the assignee contacts. - if ($allow) { - $assigneeContacts = CRM_Activity_BAO_ActivityContact::retrieveContactIdsByActivityId($activity->id, $assigneeID); - foreach ($assigneeContacts as $cnt => $contactId) { - if (!CRM_Contact_BAO_Contact_Permission::allow($contactId, $permission)) { - $allow = FALSE; - break; - } - } - } } } @@ -2767,57 +2783,58 @@ AND cl.modified_id = c.id * @return bool */ protected static function isContactPermittedAccessToCaseActivity($activityId, $action, $activityTypeID) { - $allow = FALSE; - foreach (['access my cases and activities', 'access all cases and activities'] as $per) { - if (CRM_Core_Permission::check($per)) { - $allow = TRUE; - break; - } - } - - // Check for case specific permissions. - if ($allow) { - $oper = 'view'; - if ($action == CRM_Core_Action::UPDATE) { - $oper = 'edit'; - } - $allow = CRM_Case_BAO_Case::checkPermission($activityId, - $oper, - $activityTypeID - ); + $oper = 'view'; + if ($action == CRM_Core_Action::UPDATE) { + $oper = 'edit'; } + $allow = CRM_Case_BAO_Case::checkPermission($activityId, + $oper, + $activityTypeID + ); return $allow; } /** + * Check if the logged in user has permission to access the given activity type. + * * @param int $activityTypeID + * * @return bool */ protected static function hasPermissionForActivityType($activityTypeID) { - $components = self::activityComponents(FALSE); - - // First check the component permission. - $sql = " - SELECT component_id - FROM civicrm_option_value val -INNER JOIN civicrm_option_group grp ON ( grp.id = val.option_group_id AND grp.name = %1 ) - WHERE val.value = %2"; - $params = [ - 1 => ['activity_type', 'String'], - 2 => [$activityTypeID, 'Integer'], - ]; - $componentId = CRM_Core_DAO::singleValueQuery($sql, $params); + $permittedActivityTypes = self::getPermittedActivityTypes(); + return isset($permittedActivityTypes[$activityTypeID]); + } - if ($componentId) { - if (!empty($components[$componentId])) { - return TRUE; - } - } - else { - return TRUE; - } - return FALSE; + /** + * Get the activity types the user is permitted to access. + * + * The types are filtered by the components they have access to. ie. a user + * with access CiviContribute but not CiviMember will see contribution related + * activities and activities with no component (e.g meetings) but not member related ones. + * + * @return array + */ + protected static function getPermittedActivityTypes() { + $userID = (int) CRM_Core_Session::getLoggedInContactID(); + if (!isset(Civi::$statics[__CLASS__]['permitted_activity_types'][$userID])) { + $permittedActivityTypes = []; + $components = self::activityComponents(FALSE); + $componentClause = empty($components) ? '' : (' OR component_id IN (' . implode(', ', array_keys($components)) . ')'); + + $types = CRM_Core_DAO::executeQuery( + " + SELECT option_value.value activity_type_id + FROM civicrm_option_value option_value +INNER JOIN civicrm_option_group grp ON (grp.id = option_group_id AND grp.name = 'activity_type') + WHERE component_id IS NULL $componentClause")->fetchAll(); + foreach ($types as $type) { + $permittedActivityTypes[$type['activity_type_id']] = (int) $type['activity_type_id']; + } + Civi::$statics[__CLASS__]['permitted_activity_types'][$userID] = $permittedActivityTypes; + } + return Civi::$statics[__CLASS__]['permitted_activity_types'][$userID]; } /** @@ -3111,7 +3128,7 @@ INNER JOIN civicrm_option_group grp ON ( grp.id = val.option_group_id AND grp.n $fileValues = CRM_Core_BAO_File::path($value, $params['activityID']); $customParams["custom_{$key}_-1"] = array( 'name' => $fileValues[0], - 'path' => $fileValues[1], + 'type' => $fileValues[1], ); } else { @@ -3211,4 +3228,14 @@ INNER JOIN civicrm_option_group grp ON ( grp.id = val.option_group_id AND grp.n return FALSE; } + /** + * @return array + */ + public static function getEntityRefFilters() { + return [ + ['key' => 'activity_type_id', 'value' => ts('Activity Type')], + ['key' => 'status_id', 'value' => ts('Activity Status')], + ]; + } + }