/** * Get a list of essential user navigation items. * * @param stdclass $user user object. * @param moodle_page $page page object. * @return stdClass $returnobj navigation information object, where: * * $returnobj->navitems array array of links where each link is a * stdClass with fields url, title, and * pix * $returnobj->metadata array array of useful user metadata to be * used when constructing navigation; * fields include: * * ROLE FIELDS * asotherrole bool whether viewing as another role * rolename string name of the role * * USER FIELDS * These fields are for the currently-logged in user, or for * the user that the real user is currently logged in as. * * userid int the id of the user in question * userfullname string the user's full name * userprofileurl moodle_url the url of the user's profile * useravatar string a HTML fragment - the rendered * user_picture for this user * userloginfail string an error string denoting the number * of login failures since last login * * "REAL USER" FIELDS * These fields are for when asotheruser is true, and * correspond to the underlying "real user". * * asotheruser bool whether viewing as another user * realuserid int the id of the user in question * realuserfullname string the user's full name * realuserprofileurl moodle_url the url of the user's profile * realuseravatar string a HTML fragment - the rendered * user_picture for this user * * MNET PROVIDER FIELDS * asmnetuser bool whether viewing as a user from an * MNet provider * mnetidprovidername string name of the MNet provider * mnetidproviderwwwroot string URL of the MNet provider */ function user_get_user_navigation_info($user, $page) { global $OUTPUT, $DB, $SESSION, $CFG; $returnobject = new stdClass(); $returnobject->navitems = array(); $returnobject->metadata = array(); $course = $page->course; // Query the environment. $context = context_course::instance($course->id); // Get basic user metadata. $returnobject->metadata['userid'] = $user->id; $returnobject->metadata['userfullname'] = fullname($user, true); $returnobject->metadata['userprofileurl'] = new moodle_url('/user/profile.php', array('id' => $user->id)); $returnobject->metadata['useravatar'] = $OUTPUT->user_picture($user, array('link' => false, 'visibletoscreenreaders' => false)); // Build a list of items for a regular user. // Query MNet status. if ($returnobject->metadata['asmnetuser'] = is_mnet_remote_user($user)) { $mnetidprovider = $DB->get_record('mnet_host', array('id' => $user->mnethostid)); $returnobject->metadata['mnetidprovidername'] = $mnetidprovider->name; $returnobject->metadata['mnetidproviderwwwroot'] = $mnetidprovider->wwwroot; } // Did the user just log in? if (isset($SESSION->justloggedin)) { // Don't unset this flag as login_info still needs it. if (!empty($CFG->displayloginfailures)) { // We're already in /user/lib.php, so we don't need to include. if ($count = user_count_login_failures($user)) { // Get login failures string. $a = new stdClass(); $a->attempts = html_writer::tag('span', $count, array('class' => 'value')); $returnobject->metadata['userloginfail'] = get_string('failedloginattempts', '', $a); } } } // Links: Dashboard. $myhome = new stdClass(); $myhome->itemtype = 'link'; $myhome->url = new moodle_url('/my/'); $myhome->title = get_string('mymoodle', 'admin'); $myhome->pix = "i/course"; $returnobject->navitems[] = $myhome; // Links: My Profile. $myprofile = new stdClass(); $myprofile->itemtype = 'link'; $myprofile->url = new moodle_url('/user/profile.php', array('id' => $user->id)); $myprofile->title = get_string('profile'); $myprofile->pix = "i/user"; $returnobject->navitems[] = $myprofile; // Links: Role-return or logout link. $lastobj = null; $buildlogout = true; $returnobject->metadata['asotherrole'] = false; if (is_role_switched($course->id)) { if ($role = $DB->get_record('role', array('id' => $user->access['rsw'][$context->path]))) { // Build role-return link instead of logout link. $rolereturn = new stdClass(); $rolereturn->itemtype = 'link'; $rolereturn->url = new moodle_url('/course/switchrole.php', array('id' => $course->id, 'sesskey' => sesskey(), 'switchrole' => 0, 'returnurl' => $page->url->out_as_local_url(false))); $rolereturn->pix = "a/logout"; $rolereturn->title = get_string('switchrolereturn'); $lastobj = $rolereturn; $returnobject->metadata['asotherrole'] = true; $returnobject->metadata['rolename'] = role_get_name($role, $context); $buildlogout = false; } } if ($returnobject->metadata['asotheruser'] = \core\session\manager::is_loggedinas()) { $realuser = \core\session\manager::get_realuser(); // Save values for the real user, as $user will be full of data for the // user the user is disguised as. $returnobject->metadata['realuserid'] = $realuser->id; $returnobject->metadata['realuserfullname'] = fullname($realuser, true); $returnobject->metadata['realuserprofileurl'] = new moodle_url('/user/profile.php', array('id' => $realuser->id)); $returnobject->metadata['realuseravatar'] = $OUTPUT->user_picture($realuser, array('link' => false, 'visibletoscreenreaders' => false)); // Build a user-revert link. $userrevert = new stdClass(); $userrevert->itemtype = 'link'; $userrevert->url = new moodle_url('/course/loginas.php', array('id' => $course->id, 'sesskey' => sesskey())); $userrevert->pix = "a/logout"; $userrevert->title = get_string('logout'); $lastobj = $userrevert; $buildlogout = false; } if ($buildlogout) { // Build a logout link. $logout = new stdClass(); $logout->itemtype = 'link'; $logout->url = new moodle_url('/login/logout.php', array('sesskey' => sesskey())); $logout->pix = "a/logout"; $logout->title = get_string('logout'); $lastobj = $logout; } // Before we add the last item (usually a logout link), add any // custom-defined items. $customitems = user_convert_text_to_menu_items($CFG->customusermenuitems, $page); foreach ($customitems as $item) { $returnobject->navitems[] = $item; } // Add the last item to the list. if (!is_null($lastobj)) { $returnobject->navitems[] = $lastobj; } return $returnobject; }
/** * Return the standard string that says whether you are logged in (and switched * roles/logged in as another user). * @param bool $withlinks if false, then don't include any links in the HTML produced. * If not set, the default is the nologinlinks option from the theme config.php file, * and if that is not set, then links are included. * @return string HTML fragment. */ public function login_info($withlinks = null) { global $USER, $CFG, $DB, $SESSION; if (during_initial_install()) { return ''; } if (is_null($withlinks)) { $withlinks = empty($this->page->layout_options['nologinlinks']); } $course = $this->page->course; if (\core\session\manager::is_loggedinas()) { $realuser = \core\session\manager::get_realuser(); $fullname = fullname($realuser, true); if ($withlinks) { $loginastitle = get_string('loginas'); $realuserinfo = " [<a href=\"$CFG->wwwroot/course/loginas.php?id=$course->id&sesskey=".sesskey()."\""; $realuserinfo .= "title =\"".$loginastitle."\">$fullname</a>] "; } else { $realuserinfo = " [$fullname] "; } } else { $realuserinfo = ''; } $loginpage = $this->is_login_page(); $loginurl = get_login_url(); if (empty($course->id)) { // $course->id is not defined during installation return ''; } else if (isloggedin()) { $context = context_course::instance($course->id); $fullname = fullname($USER, true); // Since Moodle 2.0 this link always goes to the public profile page (not the course profile page) if ($withlinks) { $linktitle = get_string('viewprofile'); $username = "******"$CFG->wwwroot/user/profile.php?id=$USER->id\" title=\"$linktitle\">$fullname</a>"; } else { $username = $fullname; } if (is_mnet_remote_user($USER) and $idprovider = $DB->get_record('mnet_host', array('id'=>$USER->mnethostid))) { if ($withlinks) { $username .= " from <a href=\"{$idprovider->wwwroot}\">{$idprovider->name}</a>"; } else { $username .= " from {$idprovider->name}"; } } if (isguestuser()) { $loggedinas = $realuserinfo.get_string('loggedinasguest'); if (!$loginpage && $withlinks) { $loggedinas .= " (<a href=\"$loginurl\">".get_string('login').'</a>)'; } } else if (is_role_switched($course->id)) { // Has switched roles $rolename = ''; if ($role = $DB->get_record('role', array('id'=>$USER->access['rsw'][$context->path]))) { $rolename = ': '.role_get_name($role, $context); } $loggedinas = get_string('loggedinas', 'moodle', $username).$rolename; if ($withlinks) { $url = new moodle_url('/course/switchrole.php', array('id'=>$course->id,'sesskey'=>sesskey(), 'switchrole'=>0, 'returnurl'=>$this->page->url->out_as_local_url(false))); $loggedinas .= ' ('.html_writer::tag('a', get_string('switchrolereturn'), array('href' => $url)).')'; } } else { $loggedinas = $realuserinfo.get_string('loggedinas', 'moodle', $username); if ($withlinks) { $loggedinas .= " (<a href=\"$CFG->wwwroot/login/logout.php?sesskey=".sesskey()."\">".get_string('logout').'</a>)'; } } } else { $loggedinas = get_string('loggedinnot', 'moodle'); if (!$loginpage && $withlinks) { $loggedinas .= " (<a href=\"$loginurl\">".get_string('login').'</a>)'; } } $loggedinas = '<div class="logininfo">'.$loggedinas.'</div>'; if (isset($SESSION->justloggedin)) { unset($SESSION->justloggedin); if (!empty($CFG->displayloginfailures)) { if (!isguestuser()) { // Include this file only when required. require_once($CFG->dirroot . '/user/lib.php'); if ($count = user_count_login_failures($USER)) { $loggedinas .= '<div class="loginfailures">'; $a = new stdClass(); $a->attempts = $count; $loggedinas .= get_string('failedloginattempts', '', $a); if (file_exists("$CFG->dirroot/report/log/index.php") and has_capability('report/log:view', context_system::instance())) { $loggedinas .= ' ('.html_writer::link(new moodle_url('/report/log/index.php', array('chooselog' => 1, 'id' => 0 , 'modid' => 'site_errors')), get_string('logs')).')'; } $loggedinas .= '</div>'; } } } } return $loggedinas; }
/** * Start output by sending the HTTP headers, and printing the HTML <head> * and the start of the <body>. * * To control what is printed, you should set properties on $PAGE. If you * are familiar with the old {@link print_header()} function from Moodle 1.9 * you will find that there are properties on $PAGE that correspond to most * of the old parameters to could be passed to print_header. * * Not that, in due course, the remaining $navigation, $menu parameters here * will be replaced by more properties of $PAGE, but that is still to do. * * @return string HTML that you must output this, preferably immediately. */ public function header() { global $USER, $CFG, $SESSION; if (\core\session\manager::is_loggedinas()) { $this->page->add_body_class('userloggedinas'); } if (isset($SESSION->justloggedin) && !empty($CFG->displayloginfailures)) { require_once $CFG->dirroot . '/user/lib.php'; // Set second parameter to false as we do not want reset the counter, the same message appears on footer. if ($count = user_count_login_failures($USER, false)) { $this->page->add_body_class('loginfailures'); } } // If the user is logged in, and we're not in initial install, // check to see if the user is role-switched and add the appropriate // CSS class to the body element. if (!during_initial_install() && isloggedin() && is_role_switched($this->page->course->id)) { $this->page->add_body_class('userswitchedrole'); } // Give themes a chance to init/alter the page object. $this->page->theme->init_page($this->page); $this->page->set_state(moodle_page::STATE_PRINTING_HEADER); // Find the appropriate page layout file, based on $this->page->pagelayout. $layoutfile = $this->page->theme->layout_file($this->page->pagelayout); // Render the layout using the layout file. $rendered = $this->render_page_layout($layoutfile); // Slice the rendered output into header and footer. $cutpos = strpos($rendered, $this->unique_main_content_token); if ($cutpos === false) { $cutpos = strpos($rendered, self::MAIN_CONTENT_TOKEN); $token = self::MAIN_CONTENT_TOKEN; } else { $token = $this->unique_main_content_token; } if ($cutpos === false) { throw new coding_exception('page layout file ' . $layoutfile . ' does not contain the main content placeholder, please include "<?php echo $OUTPUT->main_content() ?>" in theme layout file.'); } $header = substr($rendered, 0, $cutpos); $footer = substr($rendered, $cutpos + strlen($token)); if (empty($this->contenttype)) { debugging('The page layout file did not call $OUTPUT->doctype()'); $header = $this->doctype() . $header; } // If this theme version is below 2.4 release and this is a course view page if ((!isset($this->page->theme->settings->version) || $this->page->theme->settings->version < 2012101500) && $this->page->pagelayout === 'course' && $this->page->url->compare(new moodle_url('/course/view.php'), URL_MATCH_BASE)) { // check if course content header/footer have not been output during render of theme layout $coursecontentheader = $this->course_content_header(true); $coursecontentfooter = $this->course_content_footer(true); if (!empty($coursecontentheader)) { // display debug message and add header and footer right above and below main content // Please note that course header and footer (to be displayed above and below the whole page) // are not displayed in this case at all. // Besides the content header and footer are not displayed on any other course page debugging('The current theme is not optimised for 2.4, the course-specific header and footer defined in course format will not be output', DEBUG_DEVELOPER); $header .= $coursecontentheader; $footer = $coursecontentfooter . $footer; } } send_headers($this->contenttype, $this->page->cacheable); $this->opencontainers->push('header/footer', $footer); $this->page->set_state(moodle_page::STATE_IN_BODY); return $header . $this->skip_link_target('maincontent'); }
/** * Test function user_count_login_failures(). */ public function test_user_count_login_failures() { $this->resetAfterTest(); $user = $this->getDataGenerator()->create_user(); $this->assertEquals(0, get_user_preferences('login_failed_count_since_success', 0, $user)); for ($i = 0; $i < 10; $i++) { login_attempt_failed($user); } $this->assertEquals(10, get_user_preferences('login_failed_count_since_success', 0, $user)); $count = user_count_login_failures($user); // Reset count. $this->assertEquals(10, $count); $this->assertEquals(0, get_user_preferences('login_failed_count_since_success', 0, $user)); for ($i = 0; $i < 10; $i++) { login_attempt_failed($user); } $this->assertEquals(10, get_user_preferences('login_failed_count_since_success', 0, $user)); $count = user_count_login_failures($user, false); // Do not reset count. $this->assertEquals(10, $count); $this->assertEquals(10, get_user_preferences('login_failed_count_since_success', 0, $user)); }
/** * Return the standard string that says whether you are logged in (and switched * roles/logged in as another user). * @param bool $withlinks if false, then don't include any links in the HTML produced. * If not set, the default is the nologinlinks option from the theme config.php file, * and if that is not set, then links are included. * @return string HTML fragment. */ public function login_info($withlinks = null) { global $USER, $CFG, $DB, $SESSION; if (during_initial_install()) { return ''; } if (is_null($withlinks)) { $withlinks = empty($this->page->layout_options['nologinlinks']); } $loginpage = (string) $this->page->url === get_login_url(); $course = $this->page->course; if (\core\session\manager::is_loggedinas()) { $realuser = session_get_realuser(); $fullname = fullname($realuser, true); if ($withlinks) { $realuserinfo = " [<a href=\"{$CFG->wwwroot}/course/loginas.php?id={$course->id}&sesskey=" . sesskey() . "\">{$fullname}</a>] "; } else { $realuserinfo = " [{$fullname}] "; } } else { $realuserinfo = ''; } $loginurl = get_login_url(); if (empty($course->id)) { // $course->id is not defined during installation return ''; } else { if (isloggedin()) { $context = context_course::instance($course->id); $fullname = fullname($USER, true); // Since Moodle 2.0 this link always goes to the public profile page (not the course profile page) if ($withlinks) { $username = "******"{$CFG->wwwroot}/user/profile.php?id={$USER->id}\">{$fullname}</a>"; } else { $username = $fullname; } if (is_mnet_remote_user($USER) and $idprovider = $DB->get_record('mnet_host', array('id' => $USER->mnethostid))) { if ($withlinks) { $username .= " from <a href=\"{$idprovider->wwwroot}\">{$idprovider->name}</a>"; } else { $username .= " from {$idprovider->name}"; } } if (isguestuser()) { $loggedinas = $realuserinfo . get_string('loggedinasguest'); if (!$loginpage && $withlinks) { $loggedinas .= '<a class="btn btn-small btn-default" href="' . $loginurl . '"><i class="fa fa-sign-in"></i> ' . get_string('login') . '</a>'; } } else { if (is_role_switched($course->id)) { // Has switched roles $rolename = ''; if ($role = $DB->get_record('role', array('id' => $USER->access['rsw'][$context->path]))) { $rolename = ': ' . format_string($role->name); } $loggedinas = get_string('loggedinas', 'moodle', $username) . $rolename; if ($withlinks) { $loggedinas .= ' (<a href="$CFG->wwwroot/course/view.php?id=$course->id&switchrole=0&sesskey=' . sesskey() . '">' . get_string('switchrolereturn') . '</a>)'; } } else { $loggedinas = $realuserinfo . get_string('loggedinas', 'moodle', $username); if ($withlinks) { $loggedinas .= ' <a class="btn btn-small" href="' . $CFG->wwwroot . '/login/logout.php?sesskey=' . sesskey() . '"><i class="fa fa-sign-out"></i> ' . get_string('logout') . '</a>'; } } } } else { $loggedinas = get_string('loggedinnot', 'moodle'); if (!$loginpage && $withlinks) { $loggedinas .= ' <a class="btn btn-small btn-default" href="' . $loginurl . '"><i class="fa fa-sign-in"></i> ' . get_string('login') . '</a>'; } } } $loggedinas = '<div class="logininfo">' . $loggedinas . '</div>'; if (isset($SESSION->justloggedin)) { unset($SESSION->justloggedin); if (!empty($CFG->displayloginfailures)) { if (!isguestuser()) { // Include this file only when required. require_once $CFG->dirroot . '/user/lib.php'; if ($count = user_count_login_failures($USER)) { $loggedinas .= '<div class="loginfailures">'; $a = new stdClass(); $a->attempts = $count; $loggedinas .= get_string('failedloginattempts', '', $a); if (file_exists("{$CFG->dirroot}/report/log/index.php") and has_capability('report/log:view', context_system::instance())) { $loggedinas .= ' (' . html_writer::link(new moodle_url('/report/log/index.php', array('chooselog' => 1, 'id' => 0, 'modid' => 'site_errors')), get_string('logs')) . ')'; } $loggedinas .= '</div>'; } } } } return $loggedinas; }