diff --git a/user/lib.php b/user/lib.php index 2d4b06fef78..a0f6bb8a0f1 100644 --- a/user/lib.php +++ b/user/lib.php @@ -296,18 +296,41 @@ function user_get_user_details($user, $course = null, array $userfields = array( $userfields[] = 'fullname'; } + // Callback check for plugins to allow or prevent access. + $forceallow = true; + $currentuser = ($user->id == $USER->id); + $isadmin = is_siteadmin($USER); + if (!$currentuser) { + $forceallow = false; + $callbackresult = user_process_profile_callbacks($user, $course); + if ($callbackresult === core_user::VIEWPROFILE_PREVENT) { + return null; // Access denied. + } else if ($callbackresult === core_user::VIEWPROFILE_FORCE_ALLOW) { + $forceallow = true; + } + } + if (!empty($course)) { $context = context_course::instance($course->id); $usercontext = context_user::instance($user->id); - $canviewdetailscap = (has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext)); } else { $context = context_user::instance($user->id); $usercontext = $context; - $canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext); } - $currentuser = ($user->id == $USER->id); - $isadmin = is_siteadmin($USER); + if (!$forceallow) { + // Existing capability checks. + if (!empty($course)) { + $canviewdetailscap = (has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext)); + } else { + $canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext); + } + + if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) { + // Skip this user details. + return null; + } + } // This does not need to include custom profile fields as it is only used to check specific // fields below. @@ -331,11 +354,6 @@ function user_get_user_details($user, $course = null, array $userfields = array( $canaccessallgroups = false; } - if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) { - // Skip this user details. - return null; - } - $userdetails = array(); $userdetails['id'] = $user->id; @@ -1162,29 +1180,10 @@ function user_can_view_profile($user, $course = null, $usercontext = null) { } // Use callbacks so that (primarily) local plugins can prevent or allow profile access. - $forceallow = false; - $plugintypes = get_plugins_with_function('control_view_profile'); - foreach ($plugintypes as $plugins) { - foreach ($plugins as $pluginfunction) { - $result = $pluginfunction($user, $course, $usercontext); - switch ($result) { - case core_user::VIEWPROFILE_DO_NOT_PREVENT: - // If the plugin doesn't stop access, just continue to next plugin or use - // default behaviour. - break; - case core_user::VIEWPROFILE_FORCE_ALLOW: - // Record that we are definitely going to allow it (unless another plugin - // returns _PREVENT). - $forceallow = true; - break; - case core_user::VIEWPROFILE_PREVENT: - // If any plugin returns PREVENT then we return false, regardless of what - // other plugins said. - return false; - } - } - } - if ($forceallow) { + $callbackresult = user_process_profile_callbacks($user, $course, $usercontext); + if ($callbackresult === core_user::VIEWPROFILE_PREVENT) { + return false; // Access denied. + } else if ($callbackresult === core_user::VIEWPROFILE_FORCE_ALLOW) { return true; } @@ -1230,6 +1229,34 @@ function user_can_view_profile($user, $course = null, $usercontext = null) { return false; } +/** + * Process plugin callbacks for profile visibility. + * + * @param stdClass $user The user whose profile is being checked. + * @param stdClass|null $course The course context, if applicable. + * @param context|null $usercontext The user context, if applicable. + * @return int One of the core_user::VIEWPROFILE_* constants. + */ +function user_process_profile_callbacks(stdClass $user, ?stdClass $course = null, ?stdClass $usercontext = null): int { + $plugintypes = get_plugins_with_function('control_view_profile'); + $forceallow = false; + + foreach ($plugintypes as $plugins) { + foreach ($plugins as $pluginfunction) { + $result = $pluginfunction($user, $course, $usercontext); + switch ($result) { + case core_user::VIEWPROFILE_FORCE_ALLOW: + $forceallow = true; + break; + case core_user::VIEWPROFILE_PREVENT: + return core_user::VIEWPROFILE_PREVENT; + } + } + } + + return $forceallow ? core_user::VIEWPROFILE_FORCE_ALLOW : core_user::VIEWPROFILE_DO_NOT_PREVENT; +} + /** * Returns users tagged with a specified tag. *