/** * Initialises the navigation object. * * This causes the navigation object to look at the current state of the page * that it is associated with and then load the appropriate content. * * This should only occur the first time that the navigation structure is utilised * which will normally be either when the navbar is called to be displayed or * when a block makes use of it. * * @return bool */ public function initialise() { global $CFG, $SITE, $USER, $DB; // Check if it has alread been initialised if ($this->initialised || during_initial_install()) { return true; } $this->initialised = true; // Set up the five base root nodes. These are nodes where we will put our // content and are as follows: // site: Navigation for the front page. // myprofile: User profile information goes here. // mycourses: The users courses get added here. // courses: Additional courses are added here. // users: Other users information loaded here. $this->rootnodes = array(); if (get_home_page() == HOMEPAGE_SITE) { // The home element should be my moodle because the root element is the site if (isloggedin() && !isguestuser()) { // Makes no sense if you aren't logged in $this->rootnodes['home'] = $this->add(get_string('myhome'), new moodle_url('/my/'), self::TYPE_SETTING, null, 'home'); } } else { // The home element should be the site because the root node is my moodle $this->rootnodes['home'] = $this->add(get_string('sitehome'), new moodle_url('/'), self::TYPE_SETTING, null, 'home'); if (!empty($CFG->defaulthomepage) && $CFG->defaulthomepage == HOMEPAGE_MY) { // We need to stop automatic redirection $this->rootnodes['home']->action->param('redirect', '0'); } } $this->rootnodes['site'] = $this->add_course($SITE); $this->rootnodes['myprofile'] = $this->add(get_string('myprofile'), null, self::TYPE_USER, null, 'myprofile'); $this->rootnodes['mycourses'] = $this->add(get_string('mycourses'), null, self::TYPE_ROOTNODE, null, 'mycourses'); $this->rootnodes['courses'] = $this->add(get_string('courses'), new moodle_url('/course/index.php'), self::TYPE_ROOTNODE, null, 'courses'); $this->rootnodes['users'] = $this->add(get_string('users'), null, self::TYPE_ROOTNODE, null, 'users'); // We always load the frontpage course to ensure it is available without // JavaScript enabled. $this->add_front_page_course_essentials($this->rootnodes['site'], $SITE); $this->load_course_sections($SITE, $this->rootnodes['site']); // Fetch all of the users courses. $mycourses = enrol_get_my_courses(); // We need to show categories if we can show categories and the user isn't enrolled in any courses or we're not showing all courses $showcategories = $this->show_categories() && (count($mycourses) == 0 || !empty($CFG->navshowallcourses)); // $issite gets set to true if the current pages course is the sites frontpage course $issite = $this->page->course->id == $SITE->id; // $ismycourse gets set to true if the user is enrolled in the current pages course. $ismycourse = !$issite && array_key_exists($this->page->course->id, $mycourses); // Check if any courses were returned. if (count($mycourses) > 0) { // Check if categories should be displayed within the my courses branch if (!empty($CFG->navshowmycoursecategories)) { // Find the category of each mycourse $categories = array(); foreach ($mycourses as $course) { $categories[] = $course->category; } // Do a single DB query to get the categories immediately associated with // courses the user is enrolled in. $categories = $DB->get_records_list('course_categories', 'id', array_unique($categories), 'depth ASC, sortorder ASC'); // Work out the parent categories that we need to load that we havn't // already got. $categoryids = array(); foreach ($categories as $category) { $categoryids = array_merge($categoryids, explode('/', trim($category->path, '/'))); } $categoryids = array_unique($categoryids); $categoryids = array_diff($categoryids, array_keys($categories)); if (count($categoryids)) { // Fetch any other categories we need. $allcategories = $DB->get_records_list('course_categories', 'id', $categoryids, 'depth ASC, sortorder ASC'); if (is_array($allcategories) && count($allcategories) > 0) { $categories = array_merge($categories, $allcategories); } } // We ONLY want the categories, we need to get rid of the keys $categories = array_values($categories); $addedcategories = array(); while (($category = array_shift($categories)) !== null) { if ($category->parent == '0') { $categoryparent = $this->rootnodes['mycourses']; } else { if (array_key_exists($category->parent, $addedcategories)) { $categoryparent = $addedcategories[$category->parent]; } else { // Prepare to count iterations. We don't want to loop forever // accidentally if for some reason a category can't be placed. if (!isset($category->loopcount)) { $category->loopcount = 0; } $category->loopcount++; if ($category->loopcount > 5) { // This is a pretty serious problem and this should never happen. // If it does then for some reason a category has been loaded but // its parents have now. It could be data corruption. debugging('Category ' . $category->id . ' could not be placed within the navigation', DEBUG_DEVELOPER); } else { // Add it back to the end of the categories array array_push($categories, $category); } continue; } } $url = new moodle_url('/course/category.php', array('id' => $category->id)); $addedcategories[$category->id] = $categoryparent->add($category->name, $url, self::TYPE_CATEGORY, $category->name, $category->id); if (!$category->visible) { // Let's decide the context where viewhidden cap checks will happen. if ($category->parent == '0') { $contexttocheck = context_system::instance(); } else { $contexttocheck = context_coursecat::instance($category->parent); } if (!has_capability('moodle/category:viewhiddencategories', $contexttocheck)) { $addedcategories[$category->id]->display = false; } else { $addedcategories[$category->id]->hidden = true; } } } } // Add all of the users courses to the navigation. // First up we need to add to the mycourses section. foreach ($mycourses as $course) { $course->coursenode = $this->add_course($course, false, true); } if (!empty($CFG->navshowallcourses)) { // Load all courses $this->load_all_courses(); } // Next if nasvshowallcourses is enabled then we need to add courses // to the courses branch as well. if (!empty($CFG->navshowallcourses)) { foreach ($mycourses as $course) { if (!empty($course->category) && !$this->can_add_more_courses_to_category($course->category)) { continue; } $genericcoursenode = $this->add_course($course, true); if ($genericcoursenode->isactive) { // We don't want this node to be active because we want the // node in the mycourses branch to be active. $genericcoursenode->make_inactive(); $genericcoursenode->collapse = true; if ($genericcoursenode->parent && $genericcoursenode->parent->type == self::TYPE_CATEGORY) { $parent = $genericcoursenode->parent; while ($parent && $parent->type == self::TYPE_CATEGORY) { $parent->collapse = true; $parent = $parent->parent; } } } } } } else { if (!empty($CFG->navshowallcourses) || !$this->show_categories()) { // Load all courses $this->load_all_courses(); } } $canviewcourseprofile = true; // Next load context specific content into the navigation switch ($this->page->context->contextlevel) { case CONTEXT_SYSTEM: // This has already been loaded we just need to map the variable if ($showcategories) { $this->load_all_categories(self::LOAD_ROOT_CATEGORIES, true); } break; case CONTEXT_COURSECAT: // This has already been loaded we just need to map the variable if ($this->show_categories()) { $this->load_all_categories($this->page->context->instanceid, true); } break; case CONTEXT_BLOCK: case CONTEXT_COURSE: if ($issite) { // If it is the front page course, or a block on it then // all we need to do is load the root categories if required if ($showcategories) { $this->load_all_categories(self::LOAD_ROOT_CATEGORIES, true); } break; } // Load the course associated with the page into the navigation $course = $this->page->course; if ($this->show_categories() && !$ismycourse) { // The user isn't enrolled in the course and we need to show categories in which case we need // to load the category relating to the course and depending up $showcategories all of the root categories as well. $this->load_all_categories($course->category, $showcategories); } $coursenode = $this->load_course($course); // If the course wasn't added then don't try going any further. if (!$coursenode) { $canviewcourseprofile = false; break; } // If the user is not enrolled then we only want to show the // course node and not populate it. // Not enrolled, can't view, and hasn't switched roles if (!can_access_course($course)) { // TODO: very ugly hack - do not force "parents" to enrol into course their child is enrolled in, // this hack has been propagated from user/view.php to display the navigation node. (MDL-25805) $isparent = false; if ($this->useridtouseforparentchecks) { if ($this->useridtouseforparentchecks != $USER->id) { $usercontext = get_context_instance(CONTEXT_USER, $this->useridtouseforparentchecks, MUST_EXIST); if ($DB->record_exists('role_assignments', array('userid' => $USER->id, 'contextid' => $usercontext->id)) and has_capability('moodle/user:viewdetails', $usercontext)) { $isparent = true; } } } if (!$isparent) { $coursenode->make_active(); $canviewcourseprofile = false; break; } } // Add the essentials such as reports etc... $this->add_course_essentials($coursenode, $course); if ($this->format_display_course_content($course->format)) { // Load the course sections $sections = $this->load_course_sections($course, $coursenode); } if (!$coursenode->contains_active_node() && !$coursenode->search_for_active_node()) { $coursenode->make_active(); } break; case CONTEXT_MODULE: if ($issite) { // If this is the site course then most information will have // already been loaded. // However we need to check if there is more content that can // yet be loaded for the specific module instance. $activitynode = $this->rootnodes['site']->get($this->page->cm->id, navigation_node::TYPE_ACTIVITY); if ($activitynode) { $this->load_activity($this->page->cm, $this->page->course, $activitynode); } break; } $course = $this->page->course; $cm = $this->page->cm; if ($this->show_categories() && !$ismycourse) { $this->load_all_categories($course->category, $showcategories); } // Load the course associated with the page into the navigation $coursenode = $this->load_course($course); // If the course wasn't added then don't try going any further. if (!$coursenode) { $canviewcourseprofile = false; break; } // If the user is not enrolled then we only want to show the // course node and not populate it. if (!can_access_course($course)) { $coursenode->make_active(); $canviewcourseprofile = false; break; } $this->add_course_essentials($coursenode, $course); // Get section number from $cm (if provided) - we need this // before loading sections in order to tell it to load this section // even if it would not normally display (=> it contains only // a label, which we are now editing) $sectionnum = isset($cm->sectionnum) ? $cm->sectionnum : 0; if ($sectionnum) { // This value has to be stored in a member variable because // otherwise we would have to pass it through a public API // to course formats and they would need to change their // functions to pass it along again... $this->includesectionnum = $sectionnum; } else { $this->includesectionnum = false; } // Load the course sections into the page $sections = $this->load_course_sections($course, $coursenode); if ($course->id != $SITE->id) { // Find the section for the $CM associated with the page and collect // its section number. if ($sectionnum) { $cm->sectionnumber = $sectionnum; } else { foreach ($sections as $section) { if ($section->id == $cm->section) { $cm->sectionnumber = $section->section; break; } } } // Load all of the section activities for the section the cm belongs to. if (isset($cm->sectionnumber) and !empty($sections[$cm->sectionnumber])) { list($sectionarray, $activityarray) = $this->generate_sections_and_activities($course); $activities = $this->load_section_activities($sections[$cm->sectionnumber]->sectionnode, $cm->sectionnumber, $activityarray); } else { $activities = array(); if ($activity = $this->load_stealth_activity($coursenode, get_fast_modinfo($course))) { // "stealth" activity from unavailable section $activities[$cm->id] = $activity; } } } else { $activities = array(); $activities[$cm->id] = $coursenode->get($cm->id, navigation_node::TYPE_ACTIVITY); } if (!empty($activities[$cm->id])) { // Finally load the cm specific navigaton information $this->load_activity($cm, $course, $activities[$cm->id]); // Check if we have an active ndoe if (!$activities[$cm->id]->contains_active_node() && !$activities[$cm->id]->search_for_active_node()) { // And make the activity node active. $activities[$cm->id]->make_active(); } } else { //TODO: something is wrong, what to do? (Skodak) } break; case CONTEXT_USER: if ($issite) { // The users profile information etc is already loaded // for the front page. break; } $course = $this->page->course; if ($this->show_categories() && !$ismycourse) { $this->load_all_categories($course->category, $showcategories); } // Load the course associated with the user into the navigation $coursenode = $this->load_course($course); // If the course wasn't added then don't try going any further. if (!$coursenode) { $canviewcourseprofile = false; break; } // If the user is not enrolled then we only want to show the // course node and not populate it. if (!can_access_course($course)) { $coursenode->make_active(); $canviewcourseprofile = false; break; } $this->add_course_essentials($coursenode, $course); $sections = $this->load_course_sections($course, $coursenode); break; } // Look for all categories which have been loaded if ($showcategories) { $categories = $this->find_all_of_type(self::TYPE_CATEGORY); if (count($categories) !== 0) { $categoryids = array(); foreach ($categories as $category) { $categoryids[] = $category->key; } list($categoriessql, $params) = $DB->get_in_or_equal($categoryids, SQL_PARAMS_NAMED); $params['limit'] = !empty($CFG->navcourselimit) ? $CFG->navcourselimit : 20; $sql = "SELECT cc.id, COUNT(c.id) AS coursecount\n FROM {course_categories} cc\n JOIN {course} c ON c.category = cc.id\n WHERE cc.id {$categoriessql}\n GROUP BY cc.id\n HAVING COUNT(c.id) > :limit"; $excessivecategories = $DB->get_records_sql($sql, $params); foreach ($categories as &$category) { if (array_key_exists($category->key, $excessivecategories) && !$this->can_add_more_courses_to_category($category)) { $url = new moodle_url('/course/category.php', array('id' => $category->key)); $category->add(get_string('viewallcourses'), $url, self::TYPE_SETTING); } } } } else { if ((!empty($CFG->navshowallcourses) || empty($mycourses)) && !$this->can_add_more_courses_to_category($this->rootnodes['courses'])) { $this->rootnodes['courses']->add(get_string('viewallcoursescategories'), new moodle_url('/course/index.php'), self::TYPE_SETTING); } } // Load for the current user $this->load_for_user(); if ($this->page->context->contextlevel >= CONTEXT_COURSE && $this->page->context->instanceid != $SITE->id && $canviewcourseprofile) { $this->load_for_user(null, true); } // Load each extending user into the navigation. foreach ($this->extendforuser as $user) { if ($user->id != $USER->id) { $this->load_for_user($user); } } // Give the local plugins a chance to include some navigation if they want. foreach (get_plugin_list_with_file('local', 'lib.php', true) as $plugin => $file) { $function = "local_{$plugin}_extends_navigation"; $oldfunction = "{$plugin}_extends_navigation"; if (function_exists($function)) { // This is the preferred function name as there is less chance of conflicts $function($this); } else { if (function_exists($oldfunction)) { // We continue to support the old function name to ensure backwards compatability $oldfunction($this); } } } // Remove any empty root nodes foreach ($this->rootnodes as $node) { // Dont remove the home node if ($node->key !== 'home' && !$node->has_children()) { $node->remove(); } } if (!$this->contains_active_node()) { $this->search_for_active_node(); } // If the user is not logged in modify the navigation structure as detailed // in {@link http://docs.moodle.org/dev/Navigation_2.0_structure} if (!isloggedin()) { $activities = clone $this->rootnodes['site']->children; $this->rootnodes['site']->remove(); $children = clone $this->children; $this->children = new navigation_node_collection(); foreach ($activities as $child) { $this->children->add($child); } foreach ($children as $child) { $this->children->add($child); } } return true; }
/** * This function gets called by {@link settings_navigation::load_user_settings()} and actually works out * what can be shown/done * * @param int $courseid The current course' id * @param int $userid The user id to load for * @param string $gstitle The string to pass to get_string for the branch title * @return navigation_node|false */ protected function generate_user_settings($courseid, $userid, $gstitle = 'usercurrentsettings') { global $DB, $CFG, $USER, $SITE; if ($courseid != $SITE->id) { if (!empty($this->page->course->id) && $this->page->course->id == $courseid) { $course = $this->page->course; } else { $select = context_helper::get_preload_record_columns_sql('ctx'); $sql = "SELECT c.*, {$select}\n FROM {course} c\n JOIN {context} ctx ON c.id = ctx.instanceid\n WHERE c.id = :courseid AND ctx.contextlevel = :contextlevel"; $params = array('courseid' => $courseid, 'contextlevel' => CONTEXT_COURSE); $course = $DB->get_record_sql($sql, $params, MUST_EXIST); context_helper::preload_from_record($course); } } else { $course = $SITE; } $coursecontext = context_course::instance($course->id); // Course context $systemcontext = context_system::instance(); $currentuser = $USER->id == $userid; if ($currentuser) { $user = $USER; $usercontext = context_user::instance($user->id); // User context } else { $select = context_helper::get_preload_record_columns_sql('ctx'); $sql = "SELECT u.*, {$select}\n FROM {user} u\n JOIN {context} ctx ON u.id = ctx.instanceid\n WHERE u.id = :userid AND ctx.contextlevel = :contextlevel"; $params = array('userid' => $userid, 'contextlevel' => CONTEXT_USER); $user = $DB->get_record_sql($sql, $params, IGNORE_MISSING); if (!$user) { return false; } context_helper::preload_from_record($user); // Check that the user can view the profile $usercontext = context_user::instance($user->id); // User context $canviewuser = has_capability('moodle/user:viewdetails', $usercontext); if ($course->id == $SITE->id) { if ($CFG->forceloginforprofiles && !has_coursecontact_role($user->id) && !$canviewuser) { // Reduce possibility of "browsing" userbase at site level // Teachers can browse and be browsed at site level. If not forceloginforprofiles, allow access (bug #4366) return false; } } else { $canviewusercourse = has_capability('moodle/user:viewdetails', $coursecontext); $userisenrolled = is_enrolled($coursecontext, $user->id, '', true); if (!$canviewusercourse && !$canviewuser || !$userisenrolled) { return false; } $canaccessallgroups = has_capability('moodle/site:accessallgroups', $coursecontext); if (!$canaccessallgroups && groups_get_course_groupmode($course) == SEPARATEGROUPS && !$canviewuser) { // If groups are in use, make sure we can see that group (MDL-45874). That does not apply to parents. if ($courseid == $this->page->course->id) { $mygroups = get_fast_modinfo($this->page->course)->groups; } else { $mygroups = groups_get_user_groups($courseid); } $usergroups = groups_get_user_groups($courseid, $userid); if (!array_intersect_key($mygroups[0], $usergroups[0])) { return false; } } } } $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $this->page->context)); $key = $gstitle; $prefurl = new moodle_url('/user/preferences.php'); if ($gstitle != 'usercurrentsettings') { $key .= $userid; $prefurl->param('userid', $userid); } // Add a user setting branch. if ($gstitle == 'usercurrentsettings') { $dashboard = $this->add(get_string('myhome'), new moodle_url('/my/'), self::TYPE_CONTAINER, null, 'dashboard'); // This should be set to false as we don't want to show this to the user. It's only for generating the correct // breadcrumb. $dashboard->display = false; if (get_home_page() == HOMEPAGE_MY) { $dashboard->mainnavonly = true; } $iscurrentuser = $user->id == $USER->id; $baseargs = array('id' => $user->id); if ($course->id != $SITE->id && !$iscurrentuser) { $baseargs['course'] = $course->id; $issitecourse = false; } else { // Load all categories and get the context for the system. $issitecourse = true; } // Add the user profile to the dashboard. $profilenode = $dashboard->add(get_string('profile'), new moodle_url('/user/profile.php', array('id' => $user->id)), self::TYPE_SETTING, null, 'myprofile'); if (!empty($CFG->navadduserpostslinks)) { // Add nodes for forum posts and discussions if the user can view either or both // There are no capability checks here as the content of the page is based // purely on the forums the current user has access too. $forumtab = $profilenode->add(get_string('forumposts', 'forum')); $forumtab->add(get_string('posts', 'forum'), new moodle_url('/mod/forum/user.php', $baseargs), null, 'myposts'); $forumtab->add(get_string('discussions', 'forum'), new moodle_url('/mod/forum/user.php', array_merge($baseargs, array('mode' => 'discussions'))), null, 'mydiscussions'); } // Add blog nodes. if (!empty($CFG->enableblogs)) { if (!$this->cache->cached('userblogoptions' . $user->id)) { require_once $CFG->dirroot . '/blog/lib.php'; // Get all options for the user. $options = blog_get_options_for_user($user); $this->cache->set('userblogoptions' . $user->id, $options); } else { $options = $this->cache->{'userblogoptions' . $user->id}; } if (count($options) > 0) { $blogs = $profilenode->add(get_string('blogs', 'blog'), null, navigation_node::TYPE_CONTAINER); foreach ($options as $type => $option) { if ($type == "rss") { $blogs->add($option['string'], $option['link'], self::TYPE_SETTING, null, null, new pix_icon('i/rss', '')); } else { $blogs->add($option['string'], $option['link'], self::TYPE_SETTING, null, 'blog' . $type); } } } } // Add the messages link. // It is context based so can appear in the user's profile and in course participants information. if (!empty($CFG->messaging)) { $messageargs = array('user1' => $USER->id); if ($USER->id != $user->id) { $messageargs['user2'] = $user->id; } if ($course->id != $SITE->id) { $messageargs['viewing'] = MESSAGE_VIEW_COURSE . $course->id; } $url = new moodle_url('/message/index.php', $messageargs); $dashboard->add(get_string('messages', 'message'), $url, self::TYPE_SETTING, null, 'messages'); } // Add the "My private files" link. // This link doesn't have a unique display for course context so only display it under the user's profile. if ($issitecourse && $iscurrentuser && has_capability('moodle/user:manageownfiles', $usercontext)) { $url = new moodle_url('/user/files.php'); $dashboard->add(get_string('privatefiles'), $url, self::TYPE_SETTING); } // Add a node to view the users notes if permitted. if (!empty($CFG->enablenotes) && has_any_capability(array('moodle/notes:manage', 'moodle/notes:view'), $coursecontext)) { $url = new moodle_url('/notes/index.php', array('user' => $user->id)); if ($coursecontext->instanceid != SITEID) { $url->param('course', $coursecontext->instanceid); } $profilenode->add(get_string('notes', 'notes'), $url); } // Show the grades node. if ($issitecourse && $iscurrentuser || has_capability('moodle/user:viewdetails', $usercontext)) { require_once $CFG->dirroot . '/user/lib.php'; // Set the grades node to link to the "Grades" page. if ($course->id == SITEID) { $url = user_mygrades_url($user->id, $course->id); } else { // Otherwise we are in a course and should redirect to the user grade report (Activity report version). $url = new moodle_url('/course/user.php', array('mode' => 'grade', 'id' => $course->id, 'user' => $user->id)); } $dashboard->add(get_string('grades', 'grades'), $url, self::TYPE_SETTING, null, 'mygrades'); } // Let plugins hook into user navigation. $pluginsfunction = get_plugins_with_function('extend_navigation_user', 'lib.php'); foreach ($pluginsfunction as $plugintype => $plugins) { if ($plugintype != 'report') { foreach ($plugins as $pluginfunction) { $pluginfunction($profilenode, $user, $usercontext, $course, $coursecontext); } } } $usersetting = navigation_node::create(get_string('preferences', 'moodle'), $prefurl, self::TYPE_CONTAINER, null, $key); $dashboard->add_node($usersetting); } else { $usersetting = $this->add(get_string('preferences', 'moodle'), $prefurl, self::TYPE_CONTAINER, null, $key); $usersetting->display = false; } $usersetting->id = 'usersettings'; // Check if the user has been deleted. if ($user->deleted) { if (!has_capability('moodle/user:update', $coursecontext)) { // We can't edit the user so just show the user deleted message. $usersetting->add(get_string('userdeleted'), null, self::TYPE_SETTING); } else { // We can edit the user so show the user deleted message and link it to the profile. if ($course->id == $SITE->id) { $profileurl = new moodle_url('/user/profile.php', array('id' => $user->id)); } else { $profileurl = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id)); } $usersetting->add(get_string('userdeleted'), $profileurl, self::TYPE_SETTING); } return true; } $userauthplugin = false; if (!empty($user->auth)) { $userauthplugin = get_auth_plugin($user->auth); } $useraccount = $usersetting->add(get_string('useraccount'), null, self::TYPE_CONTAINER, null, 'useraccount'); // Add the profile edit link. if (isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) { if (($currentuser || is_siteadmin($USER) || !is_siteadmin($user)) && has_capability('moodle/user:update', $systemcontext)) { $url = new moodle_url('/user/editadvanced.php', array('id' => $user->id, 'course' => $course->id)); $useraccount->add(get_string('editmyprofile'), $url, self::TYPE_SETTING); } else { if (has_capability('moodle/user:editprofile', $usercontext) && !is_siteadmin($user) || $currentuser && has_capability('moodle/user:editownprofile', $systemcontext)) { if ($userauthplugin && $userauthplugin->can_edit_profile()) { $url = $userauthplugin->edit_profile_url(); if (empty($url)) { $url = new moodle_url('/user/edit.php', array('id' => $user->id, 'course' => $course->id)); } $useraccount->add(get_string('editmyprofile'), $url, self::TYPE_SETTING); } } } } // Change password link. if ($userauthplugin && $currentuser && !\core\session\manager::is_loggedinas() && !isguestuser() && has_capability('moodle/user:changeownpassword', $systemcontext) && $userauthplugin->can_change_password()) { $passwordchangeurl = $userauthplugin->change_password_url(); if (empty($passwordchangeurl)) { $passwordchangeurl = new moodle_url('/login/change_password.php', array('id' => $course->id)); } $useraccount->add(get_string("changepassword"), $passwordchangeurl, self::TYPE_SETTING, null, 'changepassword'); } if (isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) { if ($currentuser && has_capability('moodle/user:editownprofile', $systemcontext) || has_capability('moodle/user:editprofile', $usercontext)) { $url = new moodle_url('/user/language.php', array('id' => $user->id, 'course' => $course->id)); $useraccount->add(get_string('preferredlanguage'), $url, self::TYPE_SETTING, null, 'preferredlanguage'); } } $pluginmanager = core_plugin_manager::instance(); $enabled = $pluginmanager->get_enabled_plugins('mod'); if (isset($enabled['forum']) && isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) { if ($currentuser && has_capability('moodle/user:editownprofile', $systemcontext) || has_capability('moodle/user:editprofile', $usercontext)) { $url = new moodle_url('/user/forum.php', array('id' => $user->id, 'course' => $course->id)); $useraccount->add(get_string('forumpreferences'), $url, self::TYPE_SETTING); } } $editors = editors_get_enabled(); if (count($editors) > 1) { if (isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) { if ($currentuser && has_capability('moodle/user:editownprofile', $systemcontext) || has_capability('moodle/user:editprofile', $usercontext)) { $url = new moodle_url('/user/editor.php', array('id' => $user->id, 'course' => $course->id)); $useraccount->add(get_string('editorpreferences'), $url, self::TYPE_SETTING); } } } // Add "Course preferences" link. if (isloggedin() && !isguestuser($user)) { if ($currentuser && has_capability('moodle/user:editownprofile', $systemcontext) || has_capability('moodle/user:editprofile', $usercontext)) { $url = new moodle_url('/user/course.php', array('id' => $user->id, 'course' => $course->id)); $useraccount->add(get_string('coursepreferences'), $url, self::TYPE_SETTING, null, 'coursepreferences'); } } // View the roles settings. if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:manage'), $usercontext)) { $roles = $usersetting->add(get_string('roles'), null, self::TYPE_SETTING); $url = new moodle_url('/admin/roles/usersroles.php', array('userid' => $user->id, 'courseid' => $course->id)); $roles->add(get_string('thisusersroles', 'role'), $url, self::TYPE_SETTING); $assignableroles = get_assignable_roles($usercontext, ROLENAME_BOTH); if (!empty($assignableroles)) { $url = new moodle_url('/admin/roles/assign.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id)); $roles->add(get_string('assignrolesrelativetothisuser', 'role'), $url, self::TYPE_SETTING); } if (has_capability('moodle/role:review', $usercontext) || count(get_overridable_roles($usercontext, ROLENAME_BOTH)) > 0) { $url = new moodle_url('/admin/roles/permissions.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id)); $roles->add(get_string('permissions', 'role'), $url, self::TYPE_SETTING); } $url = new moodle_url('/admin/roles/check.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id)); $roles->add(get_string('checkpermissions', 'role'), $url, self::TYPE_SETTING); } // Repositories. if (!$this->cache->cached('contexthasrepos' . $usercontext->id)) { require_once $CFG->dirroot . '/repository/lib.php'; $editabletypes = repository::get_editable_types($usercontext); $haseditabletypes = !empty($editabletypes); unset($editabletypes); $this->cache->set('contexthasrepos' . $usercontext->id, $haseditabletypes); } else { $haseditabletypes = $this->cache->{'contexthasrepos' . $usercontext->id}; } if ($haseditabletypes) { $repositories = $usersetting->add(get_string('repositories', 'repository'), null, self::TYPE_SETTING); $repositories->add(get_string('manageinstances', 'repository'), new moodle_url('/repository/manage_instances.php', array('contextid' => $usercontext->id))); } // Portfolio. if ($currentuser && !empty($CFG->enableportfolios) && has_capability('moodle/portfolio:export', $systemcontext)) { require_once $CFG->libdir . '/portfoliolib.php'; if (portfolio_has_visible_instances()) { $portfolio = $usersetting->add(get_string('portfolios', 'portfolio'), null, self::TYPE_SETTING); $url = new moodle_url('/user/portfolio.php', array('courseid' => $course->id)); $portfolio->add(get_string('configure', 'portfolio'), $url, self::TYPE_SETTING); $url = new moodle_url('/user/portfoliologs.php', array('courseid' => $course->id)); $portfolio->add(get_string('logs', 'portfolio'), $url, self::TYPE_SETTING); } } $enablemanagetokens = false; if (!empty($CFG->enablerssfeeds)) { $enablemanagetokens = true; } else { if (!is_siteadmin($USER->id) && !empty($CFG->enablewebservices) && has_capability('moodle/webservice:createtoken', context_system::instance())) { $enablemanagetokens = true; } } // Security keys. if ($currentuser && $enablemanagetokens) { $url = new moodle_url('/user/managetoken.php', array('sesskey' => sesskey())); $useraccount->add(get_string('securitykeys', 'webservice'), $url, self::TYPE_SETTING); } // Messaging. if ($currentuser && has_capability('moodle/user:editownmessageprofile', $systemcontext) || !isguestuser($user) && has_capability('moodle/user:editmessageprofile', $usercontext) && !is_primary_admin($user->id)) { $url = new moodle_url('/message/edit.php', array('id' => $user->id)); $useraccount->add(get_string('messaging', 'message'), $url, self::TYPE_SETTING); } // Blogs. if ($currentuser && !empty($CFG->enableblogs)) { $blog = $usersetting->add(get_string('blogs', 'blog'), null, navigation_node::TYPE_CONTAINER, null, 'blogs'); if (has_capability('moodle/blog:view', $systemcontext)) { $blog->add(get_string('preferences', 'blog'), new moodle_url('/blog/preferences.php'), navigation_node::TYPE_SETTING); } if (!empty($CFG->useexternalblogs) && $CFG->maxexternalblogsperuser > 0 && has_capability('moodle/blog:manageexternal', $systemcontext)) { $blog->add(get_string('externalblogs', 'blog'), new moodle_url('/blog/external_blogs.php'), navigation_node::TYPE_SETTING); $blog->add(get_string('addnewexternalblog', 'blog'), new moodle_url('/blog/external_blog_edit.php'), navigation_node::TYPE_SETTING); } // Remove the blog node if empty. $blog->trim_if_empty(); } // Badges. if ($currentuser && !empty($CFG->enablebadges)) { $badges = $usersetting->add(get_string('badges'), null, navigation_node::TYPE_CONTAINER, null, 'badges'); if (has_capability('moodle/badges:manageownbadges', $usercontext)) { $url = new moodle_url('/badges/mybadges.php'); $badges->add(get_string('managebadges', 'badges'), $url, self::TYPE_SETTING); } $badges->add(get_string('preferences', 'badges'), new moodle_url('/badges/preferences.php'), navigation_node::TYPE_SETTING); if (!empty($CFG->badges_allowexternalbackpack)) { $badges->add(get_string('backpackdetails', 'badges'), new moodle_url('/badges/mybackpack.php'), navigation_node::TYPE_SETTING); } } // Let plugins hook into user settings navigation. $pluginsfunction = get_plugins_with_function('extend_navigation_user_settings', 'lib.php'); foreach ($pluginsfunction as $plugintype => $plugins) { foreach ($plugins as $pluginfunction) { $pluginfunction($usersetting, $user, $usercontext, $course, $coursecontext); } } return $usersetting; }
/** * Initialises the navigation object. * * This causes the navigation object to look at the current state of the page * that it is associated with and then load the appropriate content. * * This should only occur the first time that the navigation structure is utilised * which will normally be either when the navbar is called to be displayed or * when a block makes use of it. * * @return bool */ public function initialise() { global $CFG, $SITE, $USER, $DB; // Check if it has alread been initialised if ($this->initialised || during_initial_install()) { return true; } $this->initialised = true; // Set up the five base root nodes. These are nodes where we will put our // content and are as follows: // site: Navigation for the front page. // myprofile: User profile information goes here. // mycourses: The users courses get added here. // courses: Additional courses are added here. // users: Other users information loaded here. $this->rootnodes = array(); if (get_home_page() == HOMEPAGE_SITE) { // The home element should be my moodle because the root element is the site if (isloggedin() && !isguestuser()) { // Makes no sense if you aren't logged in $this->rootnodes['home'] = $this->add(get_string('myhome'), new moodle_url('/my/'), self::TYPE_SETTING, null, 'home'); } } else { // The home element should be the site because the root node is my moodle $this->rootnodes['home'] = $this->add(get_string('sitehome'), new moodle_url('/'), self::TYPE_SETTING, null, 'home'); if ($CFG->defaulthomepage == HOMEPAGE_MY) { // We need to stop automatic redirection $this->rootnodes['home']->action->param('redirect', '0'); } } $this->rootnodes['site'] = $this->add_course($SITE); $this->rootnodes['myprofile'] = $this->add(get_string('myprofile'), null, self::TYPE_USER, null, 'myprofile'); $this->rootnodes['mycourses'] = $this->add(get_string('mycourses'), null, self::TYPE_ROOTNODE, null, 'mycourses'); $this->rootnodes['courses'] = $this->add(get_string('courses'), null, self::TYPE_ROOTNODE, null, 'courses'); $this->rootnodes['users'] = $this->add(get_string('users'), null, self::TYPE_ROOTNODE, null, 'users'); // Fetch all of the users courses. $limit = 20; if (!empty($CFG->navcourselimit)) { $limit = $CFG->navcourselimit; } $mycourses = enrol_get_my_courses(NULL, 'visible DESC,sortorder ASC', $limit); $showallcourses = count($mycourses) == 0 || !empty($CFG->navshowallcourses); $showcategories = $showallcourses && $this->show_categories(); $issite = $this->page->course->id != SITEID; $ismycourse = array_key_exists($this->page->course->id, $mycourses); // Check if any courses were returned. if (count($mycourses) > 0) { // Add all of the users courses to the navigation foreach ($mycourses as $course) { $course->coursenode = $this->add_course($course, false, true); } } if ($showallcourses) { // Load all courses $this->load_all_courses(); } // We always load the frontpage course to ensure it is available without // JavaScript enabled. $frontpagecourse = $this->load_course($SITE); $this->add_front_page_course_essentials($frontpagecourse, $SITE); $canviewcourseprofile = true; // Next load context specific content into the navigation switch ($this->page->context->contextlevel) { case CONTEXT_SYSTEM: // This has already been loaded we just need to map the variable $coursenode = $frontpagecourse; $this->load_all_categories(null, $showcategories); break; case CONTEXT_COURSECAT: // This has already been loaded we just need to map the variable $coursenode = $frontpagecourse; $this->load_all_categories($this->page->context->instanceid, $showcategories); break; case CONTEXT_BLOCK: case CONTEXT_COURSE: // Load the course associated with the page into the navigation $course = $this->page->course; if ($showcategories && !$issite && !$ismycourse) { $this->load_all_categories($course->category, $showcategories); } $coursenode = $this->load_course($course); // If the course wasn't added then don't try going any further. if (!$coursenode) { $canviewcourseprofile = false; break; } // If the user is not enrolled then we only want to show the // course node and not populate it. $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); // Not enrolled, can't view, and hasn't switched roles if (!can_access_course($coursecontext)) { // TODO: very ugly hack - do not force "parents" to enrol into course their child is enrolled in, // this hack has been propagated from user/view.php to display the navigation node. (MDL-25805) $isparent = false; if ($this->useridtouseforparentchecks) { if ($this->useridtouseforparentchecks != $USER->id) { $usercontext = get_context_instance(CONTEXT_USER, $this->useridtouseforparentchecks, MUST_EXIST); if ($DB->record_exists('role_assignments', array('userid' => $USER->id, 'contextid' => $usercontext->id)) and has_capability('moodle/user:viewdetails', $usercontext)) { $isparent = true; } } } if (!$isparent) { $coursenode->make_active(); $canviewcourseprofile = false; break; } } // Add the essentials such as reports etc... $this->add_course_essentials($coursenode, $course); if ($this->format_display_course_content($course->format)) { // Load the course sections $sections = $this->load_course_sections($course, $coursenode); } if (!$coursenode->contains_active_node() && !$coursenode->search_for_active_node()) { $coursenode->make_active(); } break; case CONTEXT_MODULE: $course = $this->page->course; $cm = $this->page->cm; if ($showcategories && !$issite && !$ismycourse) { $this->load_all_categories($course->category, $showcategories); } // Load the course associated with the page into the navigation $coursenode = $this->load_course($course); // If the course wasn't added then don't try going any further. if (!$coursenode) { $canviewcourseprofile = false; break; } // If the user is not enrolled then we only want to show the // course node and not populate it. $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); if (!can_access_course($coursecontext)) { $coursenode->make_active(); $canviewcourseprofile = false; break; } $this->add_course_essentials($coursenode, $course); // Load the course sections into the page $sections = $this->load_course_sections($course, $coursenode); if ($course->id != SITEID) { // Find the section for the $CM associated with the page and collect // its section number. if (isset($cm->sectionnum)) { $cm->sectionnumber = $cm->sectionnum; } else { foreach ($sections as $section) { if ($section->id == $cm->section) { $cm->sectionnumber = $section->section; break; } } } // Load all of the section activities for the section the cm belongs to. if (isset($cm->sectionnumber) and !empty($sections[$cm->sectionnumber])) { list($sectionarray, $activityarray) = $this->generate_sections_and_activities($course); $activities = $this->load_section_activities($sections[$cm->sectionnumber]->sectionnode, $cm->sectionnumber, $activityarray); } else { $activities = array(); if ($activity = $this->load_stealth_activity($coursenode, get_fast_modinfo($course))) { // "stealth" activity from unavailable section $activities[$cm->id] = $activity; } } } else { $activities = array(); $activities[$cm->id] = $coursenode->get($cm->id, navigation_node::TYPE_ACTIVITY); } if (!empty($activities[$cm->id])) { // Finally load the cm specific navigaton information $this->load_activity($cm, $course, $activities[$cm->id]); // Check if we have an active ndoe if (!$activities[$cm->id]->contains_active_node() && !$activities[$cm->id]->search_for_active_node()) { // And make the activity node active. $activities[$cm->id]->make_active(); } } else { //TODO: something is wrong, what to do? (Skodak) } break; case CONTEXT_USER: $course = $this->page->course; if ($course->id != SITEID) { if ($showcategories && !$issite && !$ismycourse) { $this->load_all_categories($course->category, $showcategories); } // Load the course associated with the user into the navigation $coursenode = $this->load_course($course); // If the course wasn't added then don't try going any further. if (!$coursenode) { $canviewcourseprofile = false; break; } // If the user is not enrolled then we only want to show the // course node and not populate it. $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); if (!can_access_course($coursecontext)) { $coursenode->make_active(); $canviewcourseprofile = false; break; } $this->add_course_essentials($coursenode, $course); $sections = $this->load_course_sections($course, $coursenode); } break; } $limit = 20; if (!empty($CFG->navcourselimit)) { $limit = $CFG->navcourselimit; } if ($showcategories) { $categories = $this->find_all_of_type(self::TYPE_CATEGORY); foreach ($categories as &$category) { if ($category->children->count() >= $limit) { $url = new moodle_url('/course/category.php', array('id' => $category->key)); $category->add(get_string('viewallcourses'), $url, self::TYPE_SETTING); } } } else { if ($this->rootnodes['courses']->children->count() >= $limit) { $this->rootnodes['courses']->add(get_string('viewallcoursescategories'), new moodle_url('/course/index.php'), self::TYPE_SETTING); } } // Load for the current user $this->load_for_user(); if ($this->page->context->contextlevel >= CONTEXT_COURSE && $this->page->context->instanceid != SITEID && $canviewcourseprofile) { $this->load_for_user(null, true); } // Load each extending user into the navigation. foreach ($this->extendforuser as $user) { if ($user->id != $USER->id) { $this->load_for_user($user); } } // Give the local plugins a chance to include some navigation if they want. foreach (get_list_of_plugins('local') as $plugin) { if (!file_exists($CFG->dirroot . '/local/' . $plugin . '/lib.php')) { continue; } require_once $CFG->dirroot . '/local/' . $plugin . '/lib.php'; $function = $plugin . '_extends_navigation'; if (function_exists($function)) { $function($this); } } // Remove any empty root nodes foreach ($this->rootnodes as $node) { // Dont remove the home node if ($node->key !== 'home' && !$node->has_children()) { $node->remove(); } } if (!$this->contains_active_node()) { $this->search_for_active_node(); } // If the user is not logged in modify the navigation structure as detailed // in {@link http://docs.moodle.org/dev/Navigation_2.0_structure} if (!isloggedin()) { $activities = clone $this->rootnodes['site']->children; $this->rootnodes['site']->remove(); $children = clone $this->children; $this->children = new navigation_node_collection(); foreach ($activities as $child) { $this->children->add($child); } foreach ($children as $child) { $this->children->add($child); } } return true; }
redirect($CFG->wwwroot . '/my/'); } /// Prepare redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and (strpos($SESSION->wantsurl, $CFG->wwwroot) === 0 or strpos($SESSION->wantsurl, str_replace('http://', 'https://', $CFG->wwwroot)) === 0)) { $urltogo = $SESSION->wantsurl; /// Because it's an address in this site unset($SESSION->wantsurl); } else { // no wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); $home_page = get_home_page(); // Go to my-moodle page instead of site homepage if defaulthomepage set to homepage_my if ($home_page == HOMEPAGE_MY && !is_siteadmin() && !isguestuser()) { if ($urltogo == $CFG->wwwroot or $urltogo == $CFG->wwwroot . '/' or $urltogo == $CFG->wwwroot . '/index.php') { $urltogo = $CFG->wwwroot . '/my/'; } } } } /// check if user password has expired /// Currently supported only for ldap-authentication module $userauth = get_auth_plugin($USER->auth); if (!empty($userauth->config->expiration) and $userauth->config->expiration == 1) { if ($userauth->can_change_password()) { $passwordchangeurl = $userauth->change_password_url(); if (!$passwordchangeurl) {
} else { user_accesstime_log(); } $hassiteconfig = has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)); /// If the site is currently under maintenance, then print a message if (!empty($CFG->maintenance_enabled) and !$hassiteconfig) { print_maintenance_message(); } if ($hassiteconfig && moodle_needs_upgrading()) { redirect($CFG->wwwroot .'/'. $CFG->admin .'/index.php'); } if (get_home_page() != HOMEPAGE_SITE) { // Redirect logged-in users to My Moodle overview if required if (optional_param('setdefaulthome', false, PARAM_BOOL)) { set_user_preference('user_home_page_preference', HOMEPAGE_SITE); } else if (!empty($CFG->defaulthomepage) && ($CFG->defaulthomepage == HOMEPAGE_MY) && optional_param('redirect', 1, PARAM_BOOL) === 1) { redirect($CFG->wwwroot .'/my/'); } else if (!empty($CFG->defaulthomepage) && ($CFG->defaulthomepage == HOMEPAGE_USER)) { $PAGE->settingsnav->get('usercurrentsettings')->add(get_string('makethismyhome'), new moodle_url('/', array('setdefaulthome'=>true)), navigation_node::TYPE_SETTING); } } if (isloggedin()) { add_to_log(SITEID, 'course', 'view', 'view.php?id='.SITEID, SITEID); } /// If the hub plugin is installed then we let it take over the homepage here
/** Determine where a user should be redirected after they have been logged in. * @return string url the user should be redirected to. */ function core_login_get_return_url() { global $CFG, $SESSION, $USER; // Prepare redirection. if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later. } else { if (isset($SESSION->wantsurl) and (strpos($SESSION->wantsurl, $CFG->wwwroot) === 0 or strpos($SESSION->wantsurl, str_replace('http://', 'https://', $CFG->wwwroot)) === 0)) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site. unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage. $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } // If the url to go to is the same as the site page, check for default homepage. if ($urltogo == $CFG->wwwroot . '/') { $homepage = get_home_page(); // Go to my-moodle page instead of site homepage if defaulthomepage set to homepage_my. if ($homepage == HOMEPAGE_MY && !is_siteadmin() && !isguestuser()) { if ($urltogo == $CFG->wwwroot or $urltogo == $CFG->wwwroot . '/' or $urltogo == $CFG->wwwroot . '/index.php') { $urltogo = $CFG->wwwroot . '/my/'; } } } return $urltogo; }
/** * Initialises the navigation object. * * This causes the navigation object to look at the current state of the page * that it is associated with and then load the appropriate content. * * This should only occur the first time that the navigation structure is utilised * which will normally be either when the navbar is called to be displayed or * when a block makes use of it. * * @return bool */ public function initialise() { global $CFG, $SITE, $USER; // Check if it has already been initialised if ($this->initialised || during_initial_install()) { return true; } $this->initialised = true; // Set up the five base root nodes. These are nodes where we will put our // content and are as follows: // site: Navigation for the front page. // myprofile: User profile information goes here. // currentcourse: The course being currently viewed. // mycourses: The users courses get added here. // courses: Additional courses are added here. // users: Other users information loaded here. $this->rootnodes = array(); if (get_home_page() == HOMEPAGE_SITE) { // The home element should be my moodle because the root element is the site if (isloggedin() && !isguestuser()) { // Makes no sense if you aren't logged in $this->rootnodes['home'] = $this->add(get_string('myhome'), new moodle_url('/my/'), self::TYPE_SETTING, null, 'home'); } } else { // The home element should be the site because the root node is my moodle $this->rootnodes['home'] = $this->add(get_string('sitehome'), new moodle_url('/'), self::TYPE_SETTING, null, 'home'); if (!empty($CFG->defaulthomepage) && $CFG->defaulthomepage == HOMEPAGE_MY) { // We need to stop automatic redirection $this->rootnodes['home']->action->param('redirect', '0'); } } $this->rootnodes['site'] = $this->add_course($SITE); $this->rootnodes['myprofile'] = $this->add(get_string('myprofile'), null, self::TYPE_USER, null, 'myprofile'); $this->rootnodes['currentcourse'] = $this->add(get_string('currentcourse'), null, self::TYPE_ROOTNODE, null, 'currentcourse'); $this->rootnodes['mycourses'] = $this->add(get_string('mycourses'), new moodle_url('/my/'), self::TYPE_ROOTNODE, null, 'mycourses'); $this->rootnodes['courses'] = $this->add(get_string('courses'), new moodle_url('/course/index.php'), self::TYPE_ROOTNODE, null, 'courses'); $this->rootnodes['users'] = $this->add(get_string('users'), null, self::TYPE_ROOTNODE, null, 'users'); // We always load the frontpage course to ensure it is available without // JavaScript enabled. $this->add_front_page_course_essentials($this->rootnodes['site'], $SITE); $this->load_course_sections($SITE, $this->rootnodes['site']); $course = $this->page->course; // $issite gets set to true if the current pages course is the sites frontpage course $issite = $this->page->course->id == $SITE->id; // Determine if the user is enrolled in any course. $enrolledinanycourse = enrol_user_sees_own_courses(); $this->rootnodes['currentcourse']->mainnavonly = true; if ($enrolledinanycourse) { $this->rootnodes['mycourses']->isexpandable = true; if ($CFG->navshowallcourses) { // When we show all courses we need to show both the my courses and the regular courses branch. $this->rootnodes['courses']->isexpandable = true; } } else { $this->rootnodes['courses']->isexpandable = true; } if ($this->rootnodes['mycourses']->isactive) { $this->load_courses_enrolled(); } $canviewcourseprofile = true; // Next load context specific content into the navigation switch ($this->page->context->contextlevel) { case CONTEXT_SYSTEM: // Nothing left to do here I feel. break; case CONTEXT_COURSECAT: // This is essential, we must load categories. $this->load_all_categories($this->page->context->instanceid, true); break; case CONTEXT_BLOCK: case CONTEXT_COURSE: if ($issite) { // Nothing left to do here. break; } // Load the course associated with the current page into the navigation. $coursenode = $this->add_course($course, false, self::COURSE_CURRENT); // If the course wasn't added then don't try going any further. if (!$coursenode) { $canviewcourseprofile = false; break; } // If the user is not enrolled then we only want to show the // course node and not populate it. // Not enrolled, can't view, and hasn't switched roles if (!can_access_course($course)) { // Very ugly hack - do not force "parents" to enrol into course their child is enrolled in, // this hack has been propagated from user/view.php to display the navigation node. (MDL-25805) if (!$this->current_user_is_parent_role()) { $coursenode->make_active(); $canviewcourseprofile = false; break; } } // Add the essentials such as reports etc... $this->add_course_essentials($coursenode, $course); // Extend course navigation with it's sections/activities $this->load_course_sections($course, $coursenode); if (!$coursenode->contains_active_node() && !$coursenode->search_for_active_node()) { $coursenode->make_active(); } break; case CONTEXT_MODULE: if ($issite) { // If this is the site course then most information will have // already been loaded. // However we need to check if there is more content that can // yet be loaded for the specific module instance. $activitynode = $this->rootnodes['site']->find($this->page->cm->id, navigation_node::TYPE_ACTIVITY); if ($activitynode) { $this->load_activity($this->page->cm, $this->page->course, $activitynode); } break; } $course = $this->page->course; $cm = $this->page->cm; // Load the course associated with the page into the navigation $coursenode = $this->add_course($course, false, self::COURSE_CURRENT); // If the course wasn't added then don't try going any further. if (!$coursenode) { $canviewcourseprofile = false; break; } // If the user is not enrolled then we only want to show the // course node and not populate it. if (!can_access_course($course)) { $coursenode->make_active(); $canviewcourseprofile = false; break; } $this->add_course_essentials($coursenode, $course); // Load the course sections into the page $this->load_course_sections($course, $coursenode, null, $cm); $activity = $coursenode->find($cm->id, navigation_node::TYPE_ACTIVITY); if (!empty($activity)) { // Finally load the cm specific navigaton information $this->load_activity($cm, $course, $activity); // Check if we have an active ndoe if (!$activity->contains_active_node() && !$activity->search_for_active_node()) { // And make the activity node active. $activity->make_active(); } } break; case CONTEXT_USER: if ($issite) { // The users profile information etc is already loaded // for the front page. break; } $course = $this->page->course; // Load the course associated with the user into the navigation $coursenode = $this->add_course($course, false, self::COURSE_CURRENT); // If the course wasn't added then don't try going any further. if (!$coursenode) { $canviewcourseprofile = false; break; } // If the user is not enrolled then we only want to show the // course node and not populate it. if (!can_access_course($course)) { $coursenode->make_active(); $canviewcourseprofile = false; break; } $this->add_course_essentials($coursenode, $course); $this->load_course_sections($course, $coursenode); break; } // Load for the current user $this->load_for_user(); if ($this->page->context->contextlevel >= CONTEXT_COURSE && $this->page->context->instanceid != $SITE->id && $canviewcourseprofile) { $this->load_for_user(null, true); } // Load each extending user into the navigation. foreach ($this->extendforuser as $user) { if ($user->id != $USER->id) { $this->load_for_user($user); } } // Give the local plugins a chance to include some navigation if they want. foreach (core_component::get_plugin_list_with_file('local', 'lib.php', true) as $plugin => $file) { $function = "local_{$plugin}_extends_navigation"; $oldfunction = "{$plugin}_extends_navigation"; if (function_exists($function)) { // This is the preferred function name as there is less chance of conflicts $function($this); } else { if (function_exists($oldfunction)) { // We continue to support the old function name to ensure backwards compatibility debugging("Deprecated local plugin navigation callback: Please rename '{$oldfunction}' to '{$function}'. Support for the old callback will be dropped after the release of 2.4", DEBUG_DEVELOPER); $oldfunction($this); } } } // Remove any empty root nodes foreach ($this->rootnodes as $node) { // Dont remove the home node /** @var navigation_node $node */ if ($node->key !== 'home' && !$node->has_children() && !$node->isactive) { $node->remove(); } } if (!$this->contains_active_node()) { $this->search_for_active_node(); } // If the user is not logged in modify the navigation structure as detailed // in {@link http://docs.moodle.org/dev/Navigation_2.0_structure} if (!isloggedin()) { $activities = clone $this->rootnodes['site']->children; $this->rootnodes['site']->remove(); $children = clone $this->children; $this->children = new navigation_node_collection(); foreach ($activities as $child) { $this->children->add($child); } foreach ($children as $child) { $this->children->add($child); } } return true; }
$context = context_system::instance(); // So we even see non-sticky blocks } // Start setting up the page $params = array(); $PAGE->set_context($context); $PAGE->set_url('/dashboard/dashboardview.php', $params); $PAGE->set_pagelayout('dashboardview'); //$PAGE->set_pagetype('my-index'); //$PAGE->blocks->add_region('content'); $PAGE->set_subpage($currentpage->id); $PAGE->set_title($header); $PAGE->set_heading($header); if (!isguestuser()) { // Skip default home page for guests if (get_home_page() != HOMEPAGE_MY) { if (optional_param('setdefaulthome', false, PARAM_BOOL)) { set_user_preference('user_home_page_preference', HOMEPAGE_MY); } else if (!empty($CFG->defaulthomepage) && $CFG->defaulthomepage == HOMEPAGE_USER) { $PAGE->settingsnav->get('usercurrentsettings')->add(get_string('makethismyhome'), new moodle_url('/my/', array('setdefaulthome'=>true)), navigation_node::TYPE_SETTING); } } } // Toggle the editing state and switches if ($PAGE->user_allowed_editing()) { if ($reset !== null) { if (!is_null($userid)) { require_sesskey(); if(!$currentpage = my_reset_page($userid, MY_PAGE_PRIVATE)){ print_error('reseterror', 'my');
/** * Return user information including profile picture + basic site information * Note: * - no capability checking because we return only known information about logged user * * @param array $serviceshortnames - DEPRECATED PARAMETER - values will be ignored - * it was an original design error, we keep for backward compatibility. * @return array site info * @since Moodle 2.2 */ public static function get_site_info($serviceshortnames = array()) { global $USER, $SITE, $CFG, $DB, $PAGE; $params = self::validate_parameters(self::get_site_info_parameters(), array('serviceshortnames' => $serviceshortnames)); $context = context_user::instance($USER->id); $userpicture = new user_picture($USER); $userpicture->size = 1; // Size f1. $profileimageurl = $userpicture->get_url($PAGE); // Site information. $siteinfo = array('sitename' => $SITE->fullname, 'siteurl' => $CFG->wwwroot, 'username' => $USER->username, 'firstname' => $USER->firstname, 'lastname' => $USER->lastname, 'fullname' => fullname($USER), 'lang' => current_language(), 'userid' => $USER->id, 'userpictureurl' => $profileimageurl->out(false)); // Retrieve the service and functions from the web service linked to the token // If you call this function directly from external (not a web service call), // then it will still return site info without information about a service // Note: wsusername/wspassword ws authentication is not supported. $functions = array(); if ($CFG->enablewebservices) { // No need to check token if web service are disabled and not a ws call. $token = optional_param('wstoken', '', PARAM_ALPHANUM); if (!empty($token)) { // No need to run if not a ws call. // Retrieve service shortname. $servicesql = 'SELECT s.* FROM {external_services} s, {external_tokens} t WHERE t.externalserviceid = s.id AND token = ? AND t.userid = ? AND s.enabled = 1'; $service = $DB->get_record_sql($servicesql, array($token, $USER->id)); $siteinfo['downloadfiles'] = $service->downloadfiles; $siteinfo['uploadfiles'] = $service->uploadfiles; if (!empty($service)) { // Return the release and version number for web service users only. $siteinfo['release'] = $CFG->release; $siteinfo['version'] = $CFG->version; // Retrieve the functions. $functionssql = "SELECT f.*\n FROM {external_functions} f, {external_services_functions} sf\n WHERE f.name = sf.functionname AND sf.externalserviceid = ?"; $functions = $DB->get_records_sql($functionssql, array($service->id)); } else { throw new coding_exception('No service found in get_site_info: something is buggy, \\ it should have fail at the ws server authentication layer.'); } } } // Build up the returned values of the list of functions. $componentversions = array(); $availablefunctions = array(); foreach ($functions as $function) { $functioninfo = array(); $functioninfo['name'] = $function->name; if ($function->component == 'moodle' || $function->component == 'core') { $version = $CFG->version; // Moodle version. } else { $versionpath = core_component::get_component_directory($function->component) . '/version.php'; if (is_readable($versionpath)) { // We store the component version once retrieved (so we don't load twice the version.php). if (!isset($componentversions[$function->component])) { $plugin = new stdClass(); include $versionpath; $componentversions[$function->component] = $plugin->version; $version = $plugin->version; } else { $version = $componentversions[$function->component]; } } else { // Function component should always have a version.php, // otherwise the function should have been described with component => 'moodle'. throw new moodle_exception('missingversionfile', 'webservice', '', $function->component); } } $functioninfo['version'] = $version; $availablefunctions[] = $functioninfo; } $siteinfo['functions'] = $availablefunctions; // Mobile CSS theme and alternative login url. $siteinfo['mobilecssurl'] = $CFG->mobilecssurl; // Retrieve some advanced features. Only enable/disable ones (bool). $advancedfeatures = array("usecomments", "usetags", "enablenotes", "messaging", "enableblogs", "enablecompletion", "enablebadges"); foreach ($advancedfeatures as $feature) { if (isset($CFG->{$feature})) { $siteinfo['advancedfeatures'][] = array('name' => $feature, 'value' => (int) $CFG->{$feature}); } } // Special case mnet_dispatcher_mode. $siteinfo['advancedfeatures'][] = array('name' => 'mnet_dispatcher_mode', 'value' => $CFG->mnet_dispatcher_mode == 'strict' ? 1 : 0); // User can manage own files. $siteinfo['usercanmanageownfiles'] = has_capability('moodle/user:manageownfiles', $context); // User quota. 0 means user can ignore the quota. $siteinfo['userquota'] = 0; if (!has_capability('moodle/user:ignoreuserquota', $context)) { $siteinfo['userquota'] = $CFG->userquota; } // User max upload file size. -1 means the user can ignore the upload file size. $siteinfo['usermaxuploadfilesize'] = get_user_max_upload_file_size($context, $CFG->maxbytes); // User home page. $siteinfo['userhomepage'] = get_home_page(); return $siteinfo; }
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * My Moodle -- a user's personal dashboard * * @package local_my * @category local * @reauthor Valery Fremaux <*****@*****.**> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die; require_once $CFG->dirroot . '/local/my/lib.php'; $localmyconfig = get_config('local_my'); /* * This hook redraws the my routing policy using local/my:overridemy switch and my force setting. */ if (get_home_page() != HOMEPAGE_SITE && !isguestuser($USER->id)) { // Redirect logged-in users to My Moodle overview if required. if (optional_param('setdefaulthome', false, PARAM_BOOL)) { set_user_preference('user_home_page_preference', HOMEPAGE_SITE); } else { if (!empty($CFG->defaulthomepage) && $CFG->defaulthomepage == HOMEPAGE_MY) { if ($localmyconfig->force && !local_has_myoverride_somewhere()) { redirect(new moodle_url('/my')); } if (optional_param('redirect', 1, PARAM_BOOL) === 1) { redirect(new moodle_url('/my')); } } else { if (!empty($CFG->defaulthomepage) && $CFG->defaulthomepage == HOMEPAGE_USER) { $linkurl = new moodle_url('/', array('setdefaulthome' => true)); $PAGE->settingsnav->get('usercurrentsettings')->add(get_string('makethismyhome'), $linkurl, navigation_node::TYPE_SETTING);