diff --git a/CRM/Event/BAO/Event.php b/CRM/Event/BAO/Event.php index 203c47f4c20b..e90e7c34aa27 100644 --- a/CRM/Event/BAO/Event.php +++ b/CRM/Event/BAO/Event.php @@ -2060,44 +2060,108 @@ public static function checkRegistration($params) { * @param int $eventId * @param int $type * - * @return string - * the permission that the user has (or null) + * @return bool|array + * Whether the user has permission for this event (or if eventId=NULL an array of permissions) + * @throws \CiviCRM_API3_Exception */ public static function checkPermission($eventId = NULL, $type = CRM_Core_Permission::VIEW) { - static $permissions = NULL; + if (empty($eventId)) { + return self::getAllPermissions($type); + } + + $params = array( + 'id' => $eventId, + 'check_permissions' => 1, + 'return' => 'id, created_id', + ); + + $allEvents = []; + $createdEvents = []; + $contactId = CRM_Core_Session::getLoggedInContactID(); + $eventResult = civicrm_api3('Event', 'get', $params); + if ($eventResult['count'] > 0) { + foreach ($eventResult['values'] as $eventId => $eventDetail) { + $allEvents[$eventId] = $eventId; + if (isset($eventDetails['created_id']) && $contactId == $eventDetail['created_id']) { + $createdEvents[$eventId] = $eventId; + } + } + } + + // Note: for a multisite setup, a user with edit all events, can edit all events + // including those from other sites + if (($type == CRM_Core_Permission::EDIT) && CRM_Core_Permission::check('edit all events')) { + return TRUE; + } + else if (in_array($eventId, CRM_ACL_API::group(CRM_Core_Permission::EDIT, $contactId, 'civicrm_event', $allEvents, $createdEvents))) { + return TRUE; + } + + if (($type == CRM_Core_Permission::EDIT) && CRM_Core_Permission::check('edit all events')) { + return TRUE; + } + else { + if (CRM_Core_Permission::check('access CiviEvent') && CRM_Core_Permission::check('view event participants')) { + // use case: allow "view all events" but NOT "edit all events" + // so for a normal site allow users with these two permissions to view all events AND + // at the same time also allow any hook to override if needed. + if (in_array($eventId, CRM_ACL_API::group(CRM_Core_Permission::VIEW, $contactId, 'civicrm_event', $allEvents, array_keys($allEvents)))) { + return TRUE; + } + } + } - if (empty($permissions)) { + if (($type == CRM_Core_Permission::DELETE) && CRM_Core_Permission::check('delete in CiviEvent')) { + return TRUE; + } + + return FALSE; + } + + /** + * Make sure that the user has permission to access this event. + * + * @param int $type + * Type of CRM_Core_Permission + * + * @return array + * Array of events with permissions (array_keys=permissions) + * @throws \CiviCRM_API3_Exception + */ + public static function getAllPermissions($type = CRM_Core_Permission::VIEW) { + if (!isset(Civi::$statics[__CLASS__]['permissions'])) { $params = array( 'check_permissions' => 1, - 'return' => 'title', + 'return' => 'id, created_id', 'options' => array( 'limit' => 0, ), ); - if ($eventId) { - $params['id'] = $eventId; + $allEvents = []; + $createdEvents = []; + $eventResult = civicrm_api3('Event', 'get', $params); + if ($eventResult['count'] > 0) { + $contactId = CRM_Core_Session::getLoggedInContactID(); + foreach ($eventResult['values'] as $eventId => $eventDetail) { + $allEvents[$eventId] = $eventId; + if (isset($eventDetails['created_id']) && $contactId == $eventDetail['created_id']) { + $createdEvents[$eventId] = $eventId; + } + } } - $result = civicrm_api3('Event', 'get', $params); - $allEvents = CRM_Utils_Array::collect('title', $result['values']); - - // Search again, but only events created by the user. - $params['created_id'] = 'user_contact_id'; - $result = civicrm_api3('Event', 'get', $params); - $createdEvents = CRM_Utils_Array::collect('title', $result['values']); - // Note: for a multisite setup, a user with edit all events, can edit all events // including those from other sites if (CRM_Core_Permission::check('edit all events')) { - $permissions[CRM_Core_Permission::EDIT] = array_keys($allEvents); + Civi::$statics[__CLASS__]['permissions'][CRM_Core_Permission::EDIT] = array_keys($allEvents); } else { - $permissions[CRM_Core_Permission::EDIT] = CRM_ACL_API::group(CRM_Core_Permission::EDIT, NULL, 'civicrm_event', $allEvents, $createdEvents); + Civi::$statics[__CLASS__]['permissions'][CRM_Core_Permission::EDIT] = CRM_ACL_API::group(CRM_Core_Permission::EDIT, NULL, 'civicrm_event', $allEvents, $createdEvents); } if (CRM_Core_Permission::check('edit all events')) { - $permissions[CRM_Core_Permission::VIEW] = array_keys($allEvents); + Civi::$statics[__CLASS__]['permissions'][CRM_Core_Permission::VIEW] = array_keys($allEvents); } else { if (CRM_Core_Permission::check('access CiviEvent') && @@ -2108,25 +2172,21 @@ public static function checkPermission($eventId = NULL, $type = CRM_Core_Permiss // at the same time also allow any hook to override if needed. $createdEvents = array_keys($allEvents); } - $permissions[CRM_Core_Permission::VIEW] = CRM_ACL_API::group(CRM_Core_Permission::VIEW, NULL, 'civicrm_event', $allEvents, $createdEvents); + Civi::$statics[__CLASS__]['permissions'][CRM_Core_Permission::VIEW] = CRM_ACL_API::group(CRM_Core_Permission::VIEW, NULL, 'civicrm_event', $allEvents, $createdEvents); } - $permissions[CRM_Core_Permission::DELETE] = array(); + Civi::$statics[__CLASS__]['permissions'][CRM_Core_Permission::DELETE] = array(); if (CRM_Core_Permission::check('delete in CiviEvent')) { // Note: we want to restrict the scope of delete permission to // events that are editable/viewable (usecase multisite). // We can remove array_intersect once we have ACL support for delete functionality. - $permissions[CRM_Core_Permission::DELETE] = array_intersect($permissions[CRM_Core_Permission::EDIT], - $permissions[CRM_Core_Permission::VIEW] + Civi::$statics[__CLASS__]['permissions'][CRM_Core_Permission::DELETE] = array_intersect(Civi::$statics[__CLASS__]['permissions'][CRM_Core_Permission::EDIT], + Civi::$statics[__CLASS__]['permissions'][CRM_Core_Permission::VIEW] ); } } - if ($eventId) { - return in_array($eventId, $permissions[$type]) ? TRUE : FALSE; - } - - return $permissions; + return Civi::$statics[__CLASS__]['permissions']; } /**