diff --git a/lib/myprofilelib.php b/lib/myprofilelib.php index a341fbf51c4..4c5e09d6ccb 100644 --- a/lib/myprofilelib.php +++ b/lib/myprofilelib.php @@ -35,7 +35,7 @@ defined('MOODLE_INTERNAL') || die(); * @return bool */ function core_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) { - global $CFG, $USER, $DB; + global $CFG, $USER, $DB, $PAGE; $usercontext = context_user::instance($user->id, MUST_EXIST); $systemcontext = context_system::instance(); @@ -101,8 +101,8 @@ function core_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, } } - // Preference page. Only visible by administrators. - if (!$iscurrentuser && is_siteadmin()) { + // Preference page. + if (!$iscurrentuser && $PAGE->settingsnav->can_view_user_preferences($user->id)) { $url = new moodle_url('/user/preferences.php', array('userid' => $user->id)); $title = get_string('preferences', 'moodle'); $node = new core_user\output\myprofile\node('administration', 'preferences', $title, null, $url); diff --git a/lib/navigationlib.php b/lib/navigationlib.php index 19284f772ed..d60c461de31 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -4773,6 +4773,33 @@ class settings_navigation extends navigation_node { public function clear_cache() { $this->cache->volatile(); } + + /** + * Checks to see if there are child nodes available in the specific user's preference node. + * If so, then they have the appropriate permissions view this user's preferences. + * + * @since Moodle 3.0 + * @param int $userid The user's ID. + * @return bool True if child nodes exist to view, otherwise false. + */ + public function can_view_user_preferences($userid) { + if (is_siteadmin()) { + return true; + } + // See if any nodes are present in the preferences section for this user. + $preferencenode = $this->find('userviewingsettings' . $userid, null); + if ($preferencenode && $preferencenode->has_children()) { + // Run through each child node. + foreach ($preferencenode->children as $childnode) { + // If the child node has children then this user has access to a link in the preferences page. + if ($childnode->has_children()) { + return true; + } + } + } + // No links found for the user to access on the preferences page. + return false; + } } /** diff --git a/user/preferences.php b/user/preferences.php index f0895cabf04..d4b736e37ad 100644 --- a/user/preferences.php +++ b/user/preferences.php @@ -33,11 +33,6 @@ if (isguestuser()) { $userid = optional_param('userid', $USER->id, PARAM_INT); $currentuser = $userid == $USER->id; -// Only administrators can access another user's preferences. -if (!$currentuser && !is_siteadmin($USER)) { - throw new moodle_exception('cannotedituserpreferences', 'error'); -} - // Check that the user is a valid user. $user = core_user::get_user($userid); if (!$user || !core_user::is_real_user($userid)) { @@ -53,10 +48,16 @@ $PAGE->set_heading(fullname($user)); if (!$currentuser) { $PAGE->navigation->extend_for_user($user); - $settings = $PAGE->settingsnav->find('userviewingsettings' . $user->id, null); - $settings->make_active(); + // Need to check that settings exist. + if ($settings = $PAGE->settingsnav->find('userviewingsettings' . $user->id, null)) { + $settings->make_active(); + } $url = new moodle_url('/user/preferences.php', array('userid' => $userid)); $navbar = $PAGE->navbar->add(get_string('preferences', 'moodle'), $url); + // Show an error if there are no preferences that this user has access to. + if (!$PAGE->settingsnav->can_view_user_preferences($userid)) { + throw new moodle_exception('cannotedituserpreferences', 'error'); + } } else { // Shutdown the users node in the navigation menu. $usernode = $PAGE->navigation->find('users', null);