/** * Reset contents of all database tables to initial values, reset caches, etc. * * Note: this is relatively slow (cca 2 seconds for pg and 7 for mysql) - please use with care! * * @static * @param bool $detectchanges * true - changes in global state and database are reported as errors * false - no errors reported * null - only critical problems are reported as errors * @return void */ public static function reset_all_data($detectchanges = false) { global $DB, $CFG, $USER, $SITE, $COURSE, $PAGE, $OUTPUT, $SESSION; // Stop any message redirection. phpunit_util::stop_message_redirection(); // Stop any message redirection. phpunit_util::stop_phpmailer_redirection(); // Stop any message redirection. phpunit_util::stop_event_redirection(); // We used to call gc_collect_cycles here to ensure desctructors were called between tests. // This accounted for 25% of the total time running phpunit - so we removed it. // Show any unhandled debugging messages, the runbare() could already reset it. self::display_debugging_messages(); self::reset_debugging(); // reset global $DB in case somebody mocked it $DB = self::get_global_backup('DB'); if ($DB->is_transaction_started()) { // we can not reset inside transaction $DB->force_transaction_rollback(); } $resetdb = self::reset_database(); $warnings = array(); if ($detectchanges === true) { if ($resetdb) { $warnings[] = 'Warning: unexpected database modification, resetting DB state'; } $oldcfg = self::get_global_backup('CFG'); $oldsite = self::get_global_backup('SITE'); foreach ($CFG as $k => $v) { if (!property_exists($oldcfg, $k)) { $warnings[] = 'Warning: unexpected new $CFG->' . $k . ' value'; } else { if ($oldcfg->{$k} !== $CFG->{$k}) { $warnings[] = 'Warning: unexpected change of $CFG->' . $k . ' value'; } } unset($oldcfg->{$k}); } if ($oldcfg) { foreach ($oldcfg as $k => $v) { $warnings[] = 'Warning: unexpected removal of $CFG->' . $k; } } if ($USER->id != 0) { $warnings[] = 'Warning: unexpected change of $USER'; } if ($COURSE->id != $oldsite->id) { $warnings[] = 'Warning: unexpected change of $COURSE'; } } if (ini_get('max_execution_time') != 0) { // This is special warning for all resets because we do not want any // libraries to mess with timeouts unintentionally. // Our PHPUnit integration is not supposed to change it either. if ($detectchanges !== false) { $warnings[] = 'Warning: max_execution_time was changed to ' . ini_get('max_execution_time'); } set_time_limit(0); } // restore original globals $_SERVER = self::get_global_backup('_SERVER'); $CFG = self::get_global_backup('CFG'); $SITE = self::get_global_backup('SITE'); $_GET = array(); $_POST = array(); $_FILES = array(); $_REQUEST = array(); $COURSE = $SITE; // reinitialise following globals $OUTPUT = new bootstrap_renderer(); $PAGE = new moodle_page(); $FULLME = null; $ME = null; $SCRIPT = null; // Empty sessison and set fresh new not-logged-in user. \core\session\manager::init_empty_session(); // reset all static caches \core\event\manager::phpunit_reset(); accesslib_clear_all_caches(true); get_string_manager()->reset_caches(true); reset_text_filters_cache(true); events_get_handlers('reset'); core_text::reset_caches(); get_message_processors(false, true); filter_manager::reset_caches(); // Reset internal users. core_user::reset_internal_users(); //TODO MDL-25290: add more resets here and probably refactor them to new core function // Reset course and module caches. if (class_exists('format_base')) { // If file containing class is not loaded, there is no cache there anyway. format_base::reset_course_cache(0); } get_fast_modinfo(0, 0, true); // Reset other singletons. if (class_exists('core_plugin_manager')) { core_plugin_manager::reset_caches(true); } if (class_exists('\\core\\update\\checker')) { \core\update\checker::reset_caches(true); } if (class_exists('\\core\\update\\deployer')) { \core\update\deployer::reset_caches(true); } // purge dataroot directory self::reset_dataroot(); // restore original config once more in case resetting of caches changed CFG $CFG = self::get_global_backup('CFG'); // inform data generator self::get_data_generator()->reset(); // fix PHP settings error_reporting($CFG->debug); // verify db writes just in case something goes wrong in reset if (self::$lastdbwrites != $DB->perf_get_writes()) { error_log('Unexpected DB writes in phpunit_util::reset_all_data()'); self::$lastdbwrites = $DB->perf_get_writes(); } if ($warnings) { $warnings = implode("\n", $warnings); trigger_error($warnings, E_USER_WARNING); } }
/** * Adds module specific settings to the settings block. * * @param settings_navigation $settings The settings navigation object * @param stdClass $context The node context */ function local_loginas_extends_settings_navigation(settings_navigation $settings, $context) { global $DB, $CFG, $PAGE, $USER; // Course id and context. $courseid = !empty($PAGE->course->id) ? $PAGE->course->id : SITEID; $coursecontext = context_course::instance($courseid); // Must have the loginas capability. if (!has_capability('moodle/user:loginas', $coursecontext)) { return; } // Set the settings category. $loginas = $settings->add(get_string('loginas')); // Login as list by admin setting. if (is_siteadmin($USER)) { // Admin settings page. $url = new moodle_url('/admin/settings.php', array('section' => 'localsettingloginas')); $loginas->add(get_string('settings'), $url, $settings::TYPE_SETTING); // Users list. $loginasusers = array(); // Since 2.6, use all the required fields. $ufields = 'id, ' . get_all_user_name_fields(true); // Get users by id. if ($configuserids = get_config('local_loginas', 'loginasusers')) { $userids = explode(',', $configuserids); if ($users = $DB->get_records_list('user', 'id', $userids, '', $ufields)) { $loginasusers = $users; } } // Get users by username. if ($configusernames = get_config('local_loginas', 'loginasusernames')) { $usernames = explode(',', $configusernames); if ($users = $DB->get_records_list('user', 'username', $usernames, '', $ufields)) { $loginasusers = $loginasusers + $users; } } // Add action links for specified users. if ($loginasusers) { $params = array('id' => $courseid, 'sesskey' => sesskey()); foreach ($loginasusers as $userid => $lauser) { $url = new moodle_url('/course/loginas.php', $params); $url->param('user', $userid); $loginas->add(fullname($lauser, true), $url, $settings::TYPE_SETTING); } } } // Course users login as. if (!($configcourseusers = get_config('local_loginas', 'courseusers'))) { return; } $loggedinas = \core\session\manager::is_loggedinas(); if (!$loggedinas) { // Ajax link. $node = $loginas->add(get_string('courseusers', 'local_loginas'), 'javascript:void();', $settings::TYPE_SETTING); $node->add_class('local_loginas_setting_link'); local_loginas_require_js($PAGE); } }
/** * Sends a formated data file to the browser * * @package core * @subpackage dataformat * * @param string $filename The base filename without an extension * @param string $dataformat A dataformat name * @param array $columns An ordered map of column keys and labels * @param Iterator $iterator An iterator over the records, usually a RecordSet * @param function $callback An option function applied to each record before writing * @param mixed $extra An optional value which is passed into the callback function */ function download_as_dataformat($filename, $dataformat, $columns, $iterator, $callback = null) { if (ob_get_length()) { throw new coding_exception("Output can not be buffered before calling download_as_dataformat"); } $classname = 'dataformat_' . $dataformat . '\\writer'; if (!class_exists($classname)) { throw new coding_exception("Unable to locate dataformat/{$type}/classes/writer.php"); } $format = new $classname(); // The data format export could take a while to generate... set_time_limit(0); // Close the session so that the users other tabs in the same session are not blocked. \core\session\manager::write_close(); $format->set_filename($filename); $format->send_http_headers(); $format->write_header($columns); $c = 0; foreach ($iterator as $row) { if ($callback) { $row = $callback($row); } if ($row === null) { continue; } $format->write_record($row, $c++); } $format->write_footer($columns); }
public function test_set_user() { global $USER, $DB; $this->assertEquals(0, $USER->id); $this->assertSame($_SESSION['USER'], $USER); $user = $DB->get_record('user', array('id' => 2)); $this->assertNotEmpty($user); $this->setUser($user); $this->assertEquals(2, $USER->id); $this->assertEquals(2, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $USER->id = 3; $this->assertEquals(3, $USER->id); $this->assertEquals(3, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); \core\session\manager::set_user($user); $this->assertEquals(2, $USER->id); $this->assertEquals(2, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $USER = $DB->get_record('user', array('id' => 1)); $this->assertNotEmpty($USER); $this->assertEquals(1, $USER->id); $this->assertEquals(1, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $this->setUser(null); $this->assertEquals(0, $USER->id); $this->assertSame($_SESSION['USER'], $USER); }
/** * Initiate database transfer. * @param moodle_database $sourcedb * @param moodle_database $targetdb * @param progress_trace $feedback * @return void */ function tool_dbtransfer_transfer_database(moodle_database $sourcedb, moodle_database $targetdb, progress_trace $feedback = null) { core_php_time_limit::raise(); \core\session\manager::write_close(); // Release session. $var = new database_mover($sourcedb, $targetdb, true, $feedback); $var->export_database(null); tool_dbtransfer_rebuild_target_log_actions($targetdb, $feedback); }
/** * Do the job. * Throw exceptions on errors (the job will be retried). */ public function execute() { global $DB; $timenow = time(); \core\session\manager::gc(); // Cleanup old session linked tokens. // Deletes the session linked tokens that are over a day old. $DB->delete_records_select('external_tokens', 'lastaccess < :onedayago AND tokentype = :tokentype', array('onedayago' => $timenow - DAYSECS, 'tokentype' => EXTERNAL_TOKEN_EMBEDDED)); }
/** * Kill user session. * * @param int $id * @return void */ function report_usersessions_kill_session($id) { global $DB, $USER; $session = $DB->get_record('sessions', array('id' => $id, 'userid' => $USER->id), 'id, sid'); if (!$session or $session->sid === session_id()) { // Do not delete the current session! return; } \core\session\manager::kill_session($session->sid); }
/** * Form for editing Information Spot block instances. * * @copyright 2014 Roberto Pinna * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @package block_informationspot * @category files * @param stdClass $course course object * @param stdClass $birecord_or_cm block instance record * @param stdClass $context context object * @param string $filearea file area * @param array $args extra arguments * @param bool $forcedownload whether or not force download * @param array $options additional options affecting the file serving * @return bool */ function block_informationspot_pluginfile($course, $birecord_or_cm, $context, $filearea, $args, $forcedownload, array $options = array()) { global $DB, $CFG, $USER; if ($context->contextlevel != CONTEXT_BLOCK) { send_file_not_found(); } // If block is in course context, then check if user has capability to access course. if ($context->get_course_context(false)) { require_course_login($course); } else { if ($CFG->forcelogin) { require_login(); } else { // Get parent context and see if user have proper permission. $parentcontext = $context->get_parent_context(); if ($parentcontext->contextlevel === CONTEXT_COURSECAT) { // Check if category is visible and user can view this category. $category = $DB->get_record('course_categories', array('id' => $parentcontext->instanceid), '*', MUST_EXIST); if (!$category->visible) { require_capability('moodle/category:viewhiddencategories', $parentcontext); } } else { if ($parentcontext->contextlevel === CONTEXT_USER && $parentcontext->instanceid != $USER->id) { // The block is in the context of a user, it is only visible to the user who it belongs to. send_file_not_found(); } } // At this point there is no way to check SYSTEM context, so ignoring it. } } if ($filearea != 'image') { send_file_not_found(); } $fs = get_file_storage(); $imageid = array_shift($args); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'block_informationspot', $filearea, $imageid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } if ($parentcontext = context::instance_by_id($birecord_or_cm->parentcontextid, IGNORE_MISSING)) { if ($parentcontext->contextlevel == CONTEXT_USER) { // force download on all personal pages including /my/ //because we do not have reliable way to find out from where this is used $forcedownload = true; } } else { // weird, there should be parent context, better force dowload then $forcedownload = true; } // NOTE: it woudl be nice to have file revisions here, for now rely on standard file lifetime, // do not lower it because the files are dispalyed very often. \core\session\manager::write_close(); send_stored_file($file, null, 0, $forcedownload, $options); }
public function execute() { global $CFG, $DB; require_once $CFG->dirroot . "/mod/turnitintooltwo/lib.php"; require_once $CFG->dirroot . "/mod/turnitintooltwo/turnitintooltwo_view.class.php"; $data = (array) $this->get_custom_data(); // Make sure we are still wanted. $submission = $DB->get_record('turnitintooltwo_submissions', array('id' => $data['submissionid'])); if (!$submission) { return true; } cli_writeln("Processing Turnitintooltwo submission: " . $data['submissionid']); $user = $DB->get_record('user', array('id' => $data['userid'])); \core\session\manager::set_user($user); $turnitintooltwo = $DB->get_record('turnitintooltwo', array('id' => $data['tiiid'])); list($course, $cm) = get_course_and_cm_from_instance($turnitintooltwo, 'turnitintooltwo'); try { $turnitintooltwoassignment = new \turnitintooltwo_assignment($turnitintooltwo->id, $turnitintooltwo); $turnitintooltwosubmission = new \turnitintooltwo_submission($data['submissionid'], "moodle", $turnitintooltwoassignment); $parts = $turnitintooltwoassignment->get_parts(); $tiisubmission = $turnitintooltwosubmission->do_tii_submission($cm, $turnitintooltwoassignment); // Update submission. $DB->update_record('turnitintooltwo_submissions', array('id' => $data['submissionid'], 'submission_modified' => $data['subtime'])); } catch (\Exception $e) { $tiisubmission = array('success' => false, 'message' => $e->getMessage()); cli_writeln($e->getMessage()); } $digitalreceipt = $tiisubmission; $digitalreceipt['is_manual'] = 0; $digitalreceipt = json_encode($digitalreceipt); $this->update_sub_status($data['submissionid'], $tiisubmission['success'], $digitalreceipt); if ($tiisubmission['success'] === true) { $lockedassignment = new \stdClass(); $lockedassignment->id = $turnitintooltwoassignment->turnitintooltwo->id; $lockedassignment->submitted = 1; $DB->update_record('turnitintooltwo', $lockedassignment); $lockedpart = new \stdClass(); $lockedpart->id = $data['submissionpart']; $lockedpart->submitted = 1; // Disable anonymous marking if post date has passed. if ($parts[$data['submissionpart']]->dtpost <= time()) { $lockedpart->unanon = 1; } $DB->update_record('turnitintooltwo_parts', $lockedpart); cli_writeln("Finished processing successful submission: " . $data['submissionid']); } else { turnitintooltwo_add_to_log($course->id, "errored submission", 'view.php?id=' . $cm->id, "Failed to submit '" . $turnitintooltwosubmission->submission_title . "'", $cm->id, $user->id, array('submissionid' => $data['submissionid'])); cli_writeln("Finished processing unsuccessful submission: " . $data['submissionid']); } \core\session\manager::set_user(get_admin()); return $tiisubmission['success']; }
/** * Test set up. * * This is executed before running any tests in this file. */ public function setUp() { global $SESSION; $this->resetAfterTest(); manager::init_empty_session(); // Set this user as the admin. $this->setAdminUser(); $data = new stdClass(); $data->enrolstartdate = time(); $data->secret = 'secret'; $toolrecord = $this->getDataGenerator()->create_lti_tool($data); $this->tool = helper::get_lti_tool($toolrecord->id); $SESSION->notifications = []; }
/** * This function extends the course navigation with the report items * * @param navigation_node $navigation The navigation node to extend * @param stdClass $user * @param stdClass $course The course to object for the report */ function report_usersessions_extend_navigation_user($navigation, $user, $course) { global $USER; if (isguestuser() or !isloggedin()) { return; } if (\core\session\manager::is_loggedinas() or $USER->id != $user->id) { // No peeking at somebody else's sessions! return; } $context = context_user::instance($USER->id); if (has_capability('report/usersessions:manageownsessions', $context)) { $navigation->add(get_string('navigationlink', 'report_usersessions'), new moodle_url('/report/usersessions/user.php'), $navigation::TYPE_SETTING); } }
/** * Files support. * * Exits if the required permissions are not satisfied. * * @param stdClass $course course object * @param stdClass $cm * @param stdClass $context context object * @param string $filearea file area * @param array $args extra arguments * @param bool $forcedownload whether or not force download * @param array $options additional options affecting the file serving * @return void The file is sent along with it's headers */ function tool_generator_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { // Only for admins or CLI. if (!defined('CLI_SCRIPT') && !is_siteadmin()) { die; } if ($context->contextlevel != CONTEXT_SYSTEM) { send_file_not_found(); } $fs = get_file_storage(); $file = $fs->get_file($context->id, 'tool_generator', $filearea, $args[0], '/', $args[1]); // Send the file, always forcing download, we don't want options. \core\session\manager::write_close(); send_stored_file($file, 0, 0, true); }
/** * Slideshow block * * This is a simple block that allows a user to embed a slideshow just below the * header of either the frontpage of a site or a coursepage. The slideshow is based * on jquery cycle. * * @package block_slideshow * @category blocks * @copyright 2013 Paul Prenis * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ function block_slideshow_pluginfile($course, $birecord_or_cm, $context, $filearea, $args, $forcedownload, array $options = array()) { global $DB, $CFG; if ($context->contextlevel != CONTEXT_BLOCK) { send_file_not_found(); } // If block is in course context, then check if user has capability to access course. if ($context->get_course_context(false)) { require_course_login($course); } else { if ($CFG->forcelogin) { require_login(); } else { // Get parent context and see if user have proper permission. $parentcontext = $context->get_parent_context(); if ($parentcontext->contextlevel === CONTEXT_COURSECAT) { // Check if category is visible and user can view this category. $category = $DB->get_record('course_categories', array('id' => $parentcontext->instanceid), '*', MUST_EXIST); if (!$category->visible) { require_capability('moodle/category:viewhiddencategories', $parentcontext); } } // At this point there is no way to check SYSTEM or USER context, so ignoring it. } } if ($filearea !== 'content') { send_file_not_found(); } $fs = get_file_storage(); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'block_slideshow', 'content', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } if ($parentcontext = context::instance_by_id($birecord_or_cm->parentcontextid, IGNORE_MISSING)) { if ($parentcontext->contextlevel == CONTEXT_USER) { // force download on all personal pages including /my/ //because we do not have reliable way to find out from where this is used $forcedownload = true; } } else { // weird, there should be parent context, better force dowload then $forcedownload = true; } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, $options); }
/** * Add nodes to myprofile page. * * @param \core_user\output\myprofile\tree $tree Tree object * @param stdClass $user user object * @param bool $iscurrentuser * @param stdClass $course Course object * * @return bool */ function report_usersessions_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) { global $USER; if (isguestuser() or !isloggedin()) { return; } if (\core\session\manager::is_loggedinas() or $USER->id != $user->id) { // No peeking at somebody else's sessions! return; } $context = context_user::instance($USER->id); if (has_capability('report/usersessions:manageownsessions', $context)) { $node = new core_user\output\myprofile\node('reports', 'usersessions', get_string('navigationlink', 'report_usersessions'), null, new moodle_url('/report/usersessions/user.php')); $tree->add_node($node); } return true; }
/** * Run the deletion task. * * @throws \coding_exception if the module could not be removed. */ public function execute() { global $CFG; require_once $CFG->dirroot . '/course/lib.php'; // Set the proper user. if ($this->get_custom_data()->userid !== $this->get_custom_data()->realuserid) { $realuser = \core_user::get_user($this->get_custom_data()->realuserid, '*', MUST_EXIST); cron_setup_user($realuser); \core\session\manager::loginas($this->get_custom_data()->userid, \context_system::instance(), false); } else { $user = \core_user::get_user($this->get_custom_data()->userid, '*', MUST_EXIST); cron_setup_user($user); } $cms = $this->get_custom_data()->cms; foreach ($cms as $cm) { try { course_delete_module($cm->id); } catch (\Exception $e) { throw new \coding_exception("The course module {$cm->id} could not be deleted. {$e->getTraceAsString()}"); } } }
public function test_set_user() { global $USER, $DB, $SESSION; $this->resetAfterTest(); $this->assertEquals(0, $USER->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); $user = $DB->get_record('user', array('id' => 2)); $this->assertNotEmpty($user); $this->setUser($user); $this->assertEquals(2, $USER->id); $this->assertEquals(2, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); $USER->id = 3; $this->assertEquals(3, $USER->id); $this->assertEquals(3, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); \core\session\manager::set_user($user); $this->assertEquals(2, $USER->id); $this->assertEquals(2, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); $USER = $DB->get_record('user', array('id' => 1)); $this->assertNotEmpty($USER); $this->assertEquals(1, $USER->id); $this->assertEquals(1, $_SESSION['USER']->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); $this->setUser(null); $this->assertEquals(0, $USER->id); $this->assertSame($_SESSION['USER'], $USER); $this->assertSame($GLOBALS['USER'], $USER); // Ensure session is reset after setUser, as it may contain extra info. $SESSION->sometestvalue = true; $this->setUser($user); $this->assertObjectNotHasAttribute('sometestvalue', $SESSION); }
/** * Write event in the store with buffering. Method insert_event_entries() must be * defined. * * @param \core\event\base $event * * @return void */ public function write(\core\event\base $event) { global $PAGE; if ($this->is_event_ignored($event)) { return; } // We need to capture current info at this moment, // at the same time this lowers memory use because // snapshots and custom objects may be garbage collected. $entry = $event->get_data(); $entry['other'] = serialize($entry['other']); $entry['origin'] = $PAGE->requestorigin; $entry['ip'] = $PAGE->requestip; $entry['realuserid'] = \core\session\manager::is_loggedinas() ? $GLOBALS['USER']->realuser : null; $this->buffer[] = $entry; $this->count++; if (!isset($this->buffersize)) { $this->buffersize = $this->get_config('buffersize', 50); } if ($this->count >= $this->buffersize) { $this->flush(); } }
} $row->cells[1]->text .= $OUTPUT->container_end(); $row->cells[2] = new html_table_cell(); $row->cells[2]->attributes['class'] = 'links'; $row->cells[2]->text = ''; $links = array(); if ($CFG->enableblogs && ($CFG->bloglevel != BLOG_USER_LEVEL || $USER->id == $user->id)) { $links[] = html_writer::link(new moodle_url('/blog/index.php?userid=' . $user->id), get_string('blogs', 'blog')); } if (!empty($CFG->enablenotes) and has_capability('moodle/notes:manage', $context) || has_capability('moodle/notes:view', $context)) { $links[] = html_writer::link(new moodle_url('/notes/index.php?course=' . $course->id . '&user='******'notes', 'notes')); } if (has_capability('moodle/site:viewreports', $context) or has_capability('moodle/user:viewuseractivitiesreport', $usercontext)) { $links[] = html_writer::link(new moodle_url('/course/user.php?id=' . $course->id . '&user='******'activity')); } if ($USER->id != $user->id && !\core\session\manager::is_loggedinas() && has_capability('moodle/user:loginas', $context) && !is_siteadmin($user->id)) { $links[] = html_writer::link(new moodle_url('/course/loginas.php?id=' . $course->id . '&user='******'&sesskey=' . sesskey()), get_string('loginas')); } $links[] = html_writer::link(new moodle_url('/user/view.php?id=' . $user->id . '&course=' . $course->id), get_string('fullprofile') . '...'); $row->cells[2]->text .= implode('', $links); if ($bulkoperations) { $row->cells[2]->text .= '<br /><input type="checkbox" class="usercheckbox" name="user' . $user->id . '" /> '; } $table->data = array($row); echo html_writer::table($table); } } else { echo $OUTPUT->heading(get_string('nothingtodisplay')); } } } else {
/** * 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 = \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 = ''; } $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) { echo "<i class='fa fa-user hide979 mywhite'></i> "; //****************$loggedinas .= " (<a href=\"$CFG->wwwroot/login/logout.php?sesskey=".sesskey()."\">".get_string('logout').'</a>)'; $loggedinas .= " <span class=\"line-trans\">|</span><a class=\"logtop\" href=\"{$CFG->wwwroot}/login/logout.php?sesskey=" . sesskey() . "\"> " . get_string('logout') . '</a><span class="line-trans"> |</span>'; } } } } else { $loggedinas = get_string('loggedinnot', 'moodle'); if (!$loginpage && $withlinks) { //****************$loggedinas $loggedinas .= " (<a href=\"$loginurl\">".get_string('login').'</a>)'; echo "<i class='fa fa-lock hide979 mywhite'></i> "; $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()) { if ($count = count_login_failures($CFG->displayloginfailures, $USER->username, $USER->lastlogin)) { $loggedinas .= ' <div class="loginfailures">'; if (empty($count->accounts)) { $loggedinas .= get_string('failedloginattempts', '', $count); } else { $loggedinas .= get_string('failedloginattemptsall', '', $count); } if (file_exists("{$CFG->dirroot}/report/log/index.php") and has_capability('report/log:view', context_system::instance())) { $loggedinas .= ' (<a href="' . $CFG->wwwroot . '/report/log/index.php' . '?chooselog=1&id=1&modid=site_errors">' . get_string('logs') . '</a>)'; } $loggedinas .= '</div>'; } } } } return $loggedinas; }
/** * Execute cron tasks */ function cron_run() { global $DB, $CFG, $OUTPUT; if (CLI_MAINTENANCE) { echo "CLI maintenance mode active, cron execution suspended.\n"; exit(1); } if (moodle_needs_upgrading()) { echo "Moodle upgrade pending, cron execution suspended.\n"; exit(1); } require_once $CFG->libdir . '/adminlib.php'; require_once $CFG->libdir . '/gradelib.php'; if (!empty($CFG->showcronsql)) { $DB->set_debug(true); } if (!empty($CFG->showcrondebugging)) { set_debugging(DEBUG_DEVELOPER, true); } set_time_limit(0); $starttime = microtime(); // Increase memory limit raise_memory_limit(MEMORY_EXTRA); // Emulate normal session - we use admin accoutn by default cron_setup_user(); // Start output log $timenow = time(); mtrace("Server Time: " . date('r', $timenow) . "\n\n"); // Run cleanup core cron jobs, but not every time since they aren't too important. // These don't have a timer to reduce load, so we'll use a random number // to randomly choose the percentage of times we should run these jobs. $random100 = rand(0, 100); if ($random100 < 20) { // Approximately 20% of the time. mtrace("Running clean-up tasks..."); cron_trace_time_and_memory(); // Delete users who haven't confirmed within required period if (!empty($CFG->deleteunconfirmed)) { $cuttime = $timenow - $CFG->deleteunconfirmed * 3600; $rs = $DB->get_recordset_sql("SELECT *\n FROM {user}\n WHERE confirmed = 0 AND firstaccess > 0\n AND firstaccess < ?", array($cuttime)); foreach ($rs as $user) { delete_user($user); // we MUST delete user properly first $DB->delete_records('user', array('id' => $user->id)); // this is a bloody hack, but it might work mtrace(" Deleted unconfirmed user for " . fullname($user, true) . " ({$user->id})"); } $rs->close(); } // Delete users who haven't completed profile within required period if (!empty($CFG->deleteincompleteusers)) { $cuttime = $timenow - $CFG->deleteincompleteusers * 3600; $rs = $DB->get_recordset_sql("SELECT *\n FROM {user}\n WHERE confirmed = 1 AND lastaccess > 0\n AND lastaccess < ? AND deleted = 0\n AND (lastname = '' OR firstname = '' OR email = '')", array($cuttime)); foreach ($rs as $user) { if (isguestuser($user) or is_siteadmin($user)) { continue; } delete_user($user); mtrace(" Deleted not fully setup user {$user->username} ({$user->id})"); } $rs->close(); } // Delete old logs to save space (this might need a timer to slow it down...) if (!empty($CFG->loglifetime)) { // value in days $loglifetime = $timenow - $CFG->loglifetime * 3600 * 24; $DB->delete_records_select("log", "time < ?", array($loglifetime)); mtrace(" Deleted old log records"); } // Delete old backup_controllers and logs. $loglifetime = get_config('backup', 'loglifetime'); if (!empty($loglifetime)) { // Value in days. $loglifetime = $timenow - $loglifetime * 3600 * 24; // Delete child records from backup_logs. $DB->execute("DELETE FROM {backup_logs}\n WHERE EXISTS (\n SELECT 'x'\n FROM {backup_controllers} bc\n WHERE bc.backupid = {backup_logs}.backupid\n AND bc.timecreated < ?)", array($loglifetime)); // Delete records from backup_controllers. $DB->execute("DELETE FROM {backup_controllers}\n WHERE timecreated < ?", array($loglifetime)); mtrace(" Deleted old backup records"); } // Delete old cached texts if (!empty($CFG->cachetext)) { // Defined in config.php $cachelifetime = time() - $CFG->cachetext - 60; // Add an extra minute to allow for really heavy sites $DB->delete_records_select('cache_text', "timemodified < ?", array($cachelifetime)); mtrace(" Deleted old cache_text records"); } if (!empty($CFG->usetags)) { require_once $CFG->dirroot . '/tag/lib.php'; tag_cron(); mtrace(' Executed tag cron'); } // Context maintenance stuff context_helper::cleanup_instances(); mtrace(' Cleaned up context instances'); context_helper::build_all_paths(false); // If you suspect that the context paths are somehow corrupt // replace the line below with: context_helper::build_all_paths(true); mtrace(' Built context paths'); // Remove expired cache flags gc_cache_flags(); mtrace(' Cleaned cache flags'); // Cleanup messaging if (!empty($CFG->messagingdeletereadnotificationsdelay)) { $notificationdeletetime = time() - $CFG->messagingdeletereadnotificationsdelay; $DB->delete_records_select('message_read', 'notification=1 AND timeread<:notificationdeletetime', array('notificationdeletetime' => $notificationdeletetime)); mtrace(' Cleaned up read notifications'); } mtrace(' Deleting temporary files...'); cron_delete_from_temp(); // Cleanup user password reset records // Delete any reset request records which are expired by more than a day. // (We keep recently expired requests around so we can give a different error msg to users who // are trying to user a recently expired reset attempt). $pwresettime = isset($CFG->pwresettime) ? $CFG->pwresettime : 1800; $earliestvalid = time() - $pwresettime - DAYSECS; $DB->delete_records_select('user_password_resets', "timerequested < ?", array($earliestvalid)); mtrace(' Cleaned up old password reset records'); mtrace("...finished clean-up tasks"); } // End of occasional clean-up tasks // Send login failures notification - brute force protection in moodle is weak, // we should at least send notices early in each cron execution if (notify_login_failures()) { mtrace(' Notified login failures'); } // Make sure all context instances are properly created - they may be required in auth, enrol, etc. context_helper::create_instances(); mtrace(' Created missing context instances'); // Session gc. mtrace("Running session gc tasks..."); \core\session\manager::gc(); mtrace("...finished stale session cleanup"); // Run the auth cron, if any before enrolments // because it might add users that will be needed in enrol plugins $auths = get_enabled_auth_plugins(); mtrace("Running auth crons if required..."); cron_trace_time_and_memory(); foreach ($auths as $auth) { $authplugin = get_auth_plugin($auth); if (method_exists($authplugin, 'cron')) { mtrace("Running cron for auth/{$auth}..."); $authplugin->cron(); if (!empty($authplugin->log)) { mtrace($authplugin->log); } } unset($authplugin); } // Generate new password emails for users - ppl expect these generated asap if ($DB->count_records('user_preferences', array('name' => 'create_password', 'value' => '1'))) { mtrace('Creating passwords for new users...'); $usernamefields = get_all_user_name_fields(true, 'u'); $newusers = $DB->get_recordset_sql("SELECT u.id as id, u.email,\n {$usernamefields}, u.username, u.lang,\n p.id as prefid\n FROM {user} u\n JOIN {user_preferences} p ON u.id=p.userid\n WHERE p.name='create_password' AND p.value='1' AND u.email !='' AND u.suspended = 0 AND u.auth != 'nologin' AND u.deleted = 0"); // note: we can not send emails to suspended accounts foreach ($newusers as $newuser) { // Use a low cost factor when generating bcrypt hash otherwise // hashing would be slow when emailing lots of users. Hashes // will be automatically updated to a higher cost factor the first // time the user logs in. if (setnew_password_and_mail($newuser, true)) { unset_user_preference('create_password', $newuser); set_user_preference('auth_forcepasswordchange', 1, $newuser); } else { trigger_error("Could not create and mail new user password!"); } } $newusers->close(); } // It is very important to run enrol early // because other plugins depend on correct enrolment info. mtrace("Running enrol crons if required..."); $enrols = enrol_get_plugins(true); foreach ($enrols as $ename => $enrol) { // do this for all plugins, disabled plugins might want to cleanup stuff such as roles if (!$enrol->is_cron_required()) { continue; } mtrace("Running cron for enrol_{$ename}..."); cron_trace_time_and_memory(); $enrol->cron(); $enrol->set_config('lastcron', time()); } // Run all cron jobs for each module mtrace("Starting activity modules"); get_mailer('buffer'); if ($mods = $DB->get_records_select("modules", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) { foreach ($mods as $mod) { $libfile = "{$CFG->dirroot}/mod/{$mod->name}/lib.php"; if (file_exists($libfile)) { include_once $libfile; $cron_function = $mod->name . "_cron"; if (function_exists($cron_function)) { mtrace("Processing module function {$cron_function} ...", ''); cron_trace_time_and_memory(); $pre_dbqueries = null; $pre_dbqueries = $DB->perf_get_queries(); $pre_time = microtime(1); if ($cron_function()) { $DB->set_field("modules", "lastcron", $timenow, array("id" => $mod->id)); } if (isset($pre_dbqueries)) { mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries"); mtrace("... used " . (microtime(1) - $pre_time) . " seconds"); } // Reset possible changes by modules to time_limit. MDL-11597 @set_time_limit(0); mtrace("done."); } } } } get_mailer('close'); mtrace("Finished activity modules"); mtrace("Starting blocks"); if ($blocks = $DB->get_records_select("block", "cron > 0 AND ((? - lastcron) > cron) AND visible = 1", array($timenow))) { // We will need the base class. require_once $CFG->dirroot . '/blocks/moodleblock.class.php'; foreach ($blocks as $block) { $blockfile = $CFG->dirroot . '/blocks/' . $block->name . '/block_' . $block->name . '.php'; if (file_exists($blockfile)) { require_once $blockfile; $classname = 'block_' . $block->name; $blockobj = new $classname(); if (method_exists($blockobj, 'cron')) { mtrace("Processing cron function for " . $block->name . '....', ''); cron_trace_time_and_memory(); if ($blockobj->cron()) { $DB->set_field('block', 'lastcron', $timenow, array('id' => $block->id)); } // Reset possible changes by blocks to time_limit. MDL-11597 @set_time_limit(0); mtrace('done.'); } } } } mtrace('Finished blocks'); mtrace('Starting admin reports'); cron_execute_plugin_type('report'); mtrace('Finished admin reports'); mtrace('Starting main gradebook job...'); cron_trace_time_and_memory(); grade_cron(); mtrace('done.'); mtrace('Starting processing the event queue...'); cron_trace_time_and_memory(); events_cron(); mtrace('done.'); if ($CFG->enablecompletion) { // Completion cron mtrace('Starting the completion cron...'); cron_trace_time_and_memory(); require_once $CFG->dirroot . '/completion/cron.php'; completion_cron(); mtrace('done'); } if ($CFG->enableportfolios) { // Portfolio cron mtrace('Starting the portfolio cron...'); cron_trace_time_and_memory(); require_once $CFG->libdir . '/portfoliolib.php'; portfolio_cron(); mtrace('done'); } //now do plagiarism checks require_once $CFG->libdir . '/plagiarismlib.php'; plagiarism_cron(); mtrace('Starting course reports'); cron_execute_plugin_type('coursereport'); mtrace('Finished course reports'); // run gradebook import/export/report cron mtrace('Starting gradebook plugins'); cron_execute_plugin_type('gradeimport'); cron_execute_plugin_type('gradeexport'); cron_execute_plugin_type('gradereport'); mtrace('Finished gradebook plugins'); // run calendar cron require_once "{$CFG->dirroot}/calendar/lib.php"; calendar_cron(); // Run external blog cron if needed if (!empty($CFG->enableblogs) && $CFG->useexternalblogs) { require_once $CFG->dirroot . '/blog/lib.php'; mtrace("Fetching external blog entries...", ''); cron_trace_time_and_memory(); $sql = "timefetched < ? OR timefetched = 0"; $externalblogs = $DB->get_records_select('blog_external', $sql, array(time() - $CFG->externalblogcrontime)); foreach ($externalblogs as $eb) { blog_sync_external_entries($eb); } mtrace('done.'); } // Run blog associations cleanup if (!empty($CFG->enableblogs) && $CFG->useblogassociations) { require_once $CFG->dirroot . '/blog/lib.php'; // delete entries whose contextids no longer exists mtrace("Deleting blog associations linked to non-existent contexts...", ''); cron_trace_time_and_memory(); $DB->delete_records_select('blog_association', 'contextid NOT IN (SELECT id FROM {context})'); mtrace('done.'); } // Run question bank clean-up. mtrace("Starting the question bank cron...", ''); cron_trace_time_and_memory(); require_once $CFG->libdir . '/questionlib.php'; question_bank::cron(); mtrace('done.'); //Run registration updated cron mtrace(get_string('siteupdatesstart', 'hub')); cron_trace_time_and_memory(); require_once $CFG->dirroot . '/' . $CFG->admin . '/registration/lib.php'; $registrationmanager = new registration_manager(); $registrationmanager->cron(); mtrace(get_string('siteupdatesend', 'hub')); // If enabled, fetch information about available updates and eventually notify site admins if (empty($CFG->disableupdatenotifications)) { $updateschecker = \core\update\checker::instance(); $updateschecker->cron(); } //cleanup old session linked tokens //deletes the session linked tokens that are over a day old. mtrace("Deleting session linked tokens more than one day old...", ''); cron_trace_time_and_memory(); $DB->delete_records_select('external_tokens', 'lastaccess < :onedayago AND tokentype = :tokentype', array('onedayago' => time() - DAYSECS, 'tokentype' => EXTERNAL_TOKEN_EMBEDDED)); mtrace('done.'); // all other plugins cron_execute_plugin_type('message', 'message plugins'); cron_execute_plugin_type('filter', 'filters'); cron_execute_plugin_type('editor', 'editors'); cron_execute_plugin_type('format', 'course formats'); cron_execute_plugin_type('profilefield', 'profile fields'); cron_execute_plugin_type('webservice', 'webservices'); cron_execute_plugin_type('repository', 'repository plugins'); cron_execute_plugin_type('qbehaviour', 'question behaviours'); cron_execute_plugin_type('qformat', 'question import/export formats'); cron_execute_plugin_type('qtype', 'question types'); cron_execute_plugin_type('plagiarism', 'plagiarism plugins'); cron_execute_plugin_type('theme', 'themes'); cron_execute_plugin_type('tool', 'admin tools'); // and finally run any local cronjobs, if any if ($locals = core_component::get_plugin_list('local')) { mtrace('Processing customized cron scripts ...', ''); // new cron functions in lib.php first cron_execute_plugin_type('local'); // legacy cron files are executed directly foreach ($locals as $local => $localdir) { if (file_exists("{$localdir}/cron.php")) { include "{$localdir}/cron.php"; } } mtrace('done.'); } mtrace('Running cache cron routines'); cache_helper::cron(); mtrace('done.'); // Run automated backups if required - these may take a long time to execute require_once $CFG->dirroot . '/backup/util/includes/backup_includes.php'; require_once $CFG->dirroot . '/backup/util/helper/backup_cron_helper.class.php'; backup_cron_automated_helper::run_automated_backup(); // Run stats as at the end because they are known to take very long time on large sites if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) { require_once $CFG->dirroot . '/lib/statslib.php'; // check we're not before our runtime $timetocheck = stats_get_base_daily() + $CFG->statsruntimestarthour * 60 * 60 + $CFG->statsruntimestartminute * 60; if (time() > $timetocheck) { // process configured number of days as max (defaulting to 31) $maxdays = empty($CFG->statsruntimedays) ? 31 : abs($CFG->statsruntimedays); if (stats_cron_daily($maxdays)) { if (stats_cron_weekly()) { if (stats_cron_monthly()) { stats_clean_old(); } } } @set_time_limit(0); } else { mtrace('Next stats run after:' . userdate($timetocheck)); } } // Run badges review cron. mtrace("Starting badges cron..."); require_once $CFG->dirroot . '/badges/cron.php'; badge_cron(); mtrace('done.'); // cleanup file trash - not very important $fs = get_file_storage(); $fs->cron(); mtrace("Cron script completed correctly"); gc_collect_cycles(); mtrace('Cron completed at ' . date('H:i:s') . '. Memory used ' . display_size(memory_get_usage()) . '.'); $difftime = microtime_diff($starttime, microtime()); mtrace("Execution took " . $difftime . " seconds"); }
/** * Check whether a major upgrade is needed. That is defined as an upgrade that * changes something really fundamental in the database, so nothing can possibly * work until the database has been updated, and that is defined by the hard-coded * version number in this function. */ function redirect_if_major_upgrade_required() { global $CFG; $lastmajordbchanges = 2014040800.0; if (empty($CFG->version) or (double) $CFG->version < $lastmajordbchanges or during_initial_install() or !empty($CFG->adminsetuppending)) { try { @\core\session\manager::terminate_current(); } catch (Exception $e) { // Ignore any errors, redirect to upgrade anyway. } $url = $CFG->wwwroot . '/' . $CFG->admin . '/index.php'; @header($_SERVER['SERVER_PROTOCOL'] . ' 303 See Other'); @header('Location: ' . $url); echo bootstrap_renderer::plain_redirect_message(htmlspecialchars($url)); exit; } }
/** * 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; }
// always at least user id print_error('invalidarguments'); } $contextid = (int) array_shift($args); $component = array_shift($args); $filearea = array_shift($args); $draftid = (int) array_shift($args); if ($component !== 'user' or $filearea !== 'draft') { send_file_not_found(); } $context = context::instance_by_id($contextid); if ($context->contextlevel != CONTEXT_USER) { send_file_not_found(); } $userid = $context->instanceid; if ($USER->id != $userid) { print_error('invaliduserid'); } $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/{$context->id}/user/draft/{$draftid}/{$relativepath}"; if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->get_filename() == '.') { send_file_not_found(); } // ======================================== // finally send the file // ======================================== \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, false, true, array('preview' => $preview)); // force download - security first!
/** * Checks if user has a capability to view the current repository. * * @return bool true when the user can, otherwise throws an exception. * @throws repository_exception when the user does not meet the requirements. */ public final function check_capability() { global $USER; // The context we are on. $currentcontext = $this->context; // Ensure that the user can view the repository in the current context. $can = has_capability('repository/' . $this->get_typename() . ':view', $currentcontext); // Context in which the repository has been created. $repocontext = context::instance_by_id($this->instance->contextid); // Prevent access to private repositories when logged in as. if ($can && \core\session\manager::is_loggedinas()) { if ($this->contains_private_data() || $repocontext->contextlevel == CONTEXT_USER) { $can = false; } } // We are going to ensure that the current context was legit, and reliable to check // the capability against. (No need to do that if we already cannot). if ($can) { if ($repocontext->contextlevel == CONTEXT_USER) { // The repository is a user instance, ensure we're the right user to access it! if ($repocontext->instanceid != $USER->id) { $can = false; } } else { if ($repocontext->contextlevel == CONTEXT_COURSE) { // The repository is a course one. Let's check that we are on the right course. if (in_array($currentcontext->contextlevel, array(CONTEXT_COURSE, CONTEXT_MODULE, CONTEXT_BLOCK))) { $coursecontext = $currentcontext->get_course_context(); if ($coursecontext->instanceid != $repocontext->instanceid) { $can = false; } } else { // We are on a parent context, therefore it's legit to check the permissions // in the current context. } } else { // Nothing to check here, system instances can have different permissions on different // levels. We do not want to prevent URL hack here, because it does not make sense to // prevent a user to access a repository in a context if it's accessible in another one. } } } if ($can) { return true; } throw new repository_exception('nopermissiontoaccess', 'repository'); }
} $PAGE->set_url($url); if (!($chatuser = $DB->get_record('chat_users', array('sid' => $chatsid)))) { print_error('notlogged', 'chat'); } // Get the minimal course. if (!($course = $DB->get_record('course', array('id' => $chatuser->course)))) { print_error('invalidcourseid'); } // Get the user theme and enough info to be used in chat_format_message() which passes it along to // chat_format_message_manually() -- and only id and timezone are used. // No optimisation here, it would break again in future! if (!($user = $DB->get_record('user', array('id' => $chatuser->userid, 'deleted' => 0, 'suspended' => 0)))) { print_error('invaliduser'); } \core\session\manager::set_user($user); // Setup course, lang and theme. $PAGE->set_course($course); // Force deleting of timed out users if there is a silence in room or just entering. if (time() - $chatlasttime > $CFG->chat_old_ping) { // Must be done before chat_get_latest_message! chat_delete_old_users(); } // Time to send headers, and lay out the basic JS updater page. header('Expires: Sun, 28 Dec 1997 09:32:45 GMT'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); header('Cache-Control: no-cache, must-revalidate'); header('Pragma: no-cache'); header('Content-Type: text/html; charset=utf-8'); $refreshurl = "{$CFG->wwwroot}/mod/chat/gui_header_js/jsupdated.php?" . "chat_sid={$chatsid}&chat_lasttime={$chatlasttime}&chat_lastrow={$chatnewrow}&chat_lastid={$chatlastid}"; ?>
/** * Legacy add_to_log() code. * * @param int $courseid The course id * @param string $module The module name e.g. forum, journal, resource, course, user etc * @param string $action 'view', 'update', 'add' or 'delete', possibly followed by another word to clarify. * @param string $url The file and parameters used to see the results of the action * @param string $info Additional description information * @param int $cm The course_module->id if there is one * @param int|\stdClass $user If log regards $user other than $USER */ public function legacy_add_to_log($courseid, $module, $action, $url, $info, $cm, $user) { // Note that this function intentionally does not follow the normal Moodle DB access idioms. // This is for a good reason: it is the most frequently used DB update function, // so it has been optimised for speed. global $DB, $CFG, $USER; if (!$this->is_logging()) { return; } if ($cm === '' || is_null($cm)) { // Postgres won't translate empty string to its default. $cm = 0; } if ($user) { $userid = $user; } else { if (\core\session\manager::is_loggedinas()) { // Don't log. return; } $userid = empty($USER->id) ? '0' : $USER->id; } if (isset($CFG->logguests) and !$CFG->logguests) { if (!$userid or isguestuser($userid)) { return; } } $remoteaddr = getremoteaddr(); $timenow = time(); if (!empty($url)) { // Could break doing html_entity_decode on an empty var. $url = html_entity_decode($url, ENT_QUOTES, 'UTF-8'); } else { $url = ''; } // Restrict length of log lines to the space actually available in the // database so that it doesn't cause a DB error. Log a warning so that // developers can avoid doing things which are likely to cause this on a // routine basis. if (\core_text::strlen($action) > 40) { $action = \core_text::substr($action, 0, 37) . '...'; debugging('Warning: logged very long action', DEBUG_DEVELOPER); } if (!empty($info) && \core_text::strlen($info) > 255) { $info = \core_text::substr($info, 0, 252) . '...'; debugging('Warning: logged very long info', DEBUG_DEVELOPER); } // If the 100 field size is changed, also need to alter print_log in course/lib.php. if (!empty($url) && \core_text::strlen($url) > 100) { $url = \core_text::substr($url, 0, 97) . '...'; debugging('Warning: logged very long URL', DEBUG_DEVELOPER); } if (defined('MDL_PERFDB')) { global $PERF; $PERF->logwrites++; } $log = array('time' => $timenow, 'userid' => $userid, 'course' => $courseid, 'ip' => $remoteaddr, 'module' => $module, 'cmid' => $cm, 'action' => $action, 'url' => $url, 'info' => $info); try { $DB->insert_record_raw('log', $log, false); } catch (\dml_exception $e) { debugging('Error: Could not insert a new entry to the Moodle log. ' . $e->errorcode, DEBUG_ALL); // MDL-11893, alert $CFG->supportemail if insert into log failed. if ($CFG->supportemail and empty($CFG->noemailever)) { // Function email_to_user is not usable because email_to_user tries to write to the logs table, // and this will get caught in an infinite loop, if disk is full. $site = get_site(); $subject = 'Insert into log failed at your moodle site ' . $site->fullname; $message = "Insert into log table failed at " . date('l dS \\of F Y h:i:s A') . ".\n It is possible that your disk is full.\n\n"; $message .= "The failed query parameters are:\n\n" . var_export($log, true); $lasttime = get_config('admin', 'lastloginserterrormail'); if (empty($lasttime) || time() - $lasttime > 60 * 60 * 24) { // Limit to 1 email per day. // Using email directly rather than messaging as they may not be able to log in to access a message. mail($CFG->supportemail, $subject, $message); set_config('lastloginserterrormail', time(), 'admin'); } } } }
unset($SESSION->lang); } } if (empty($user->confirmed)) { // This account was never confirmed $PAGE->set_title(get_string("mustconfirm")); $PAGE->set_heading($site->fullname); echo $OUTPUT->header(); echo $OUTPUT->heading(get_string("mustconfirm")); echo $OUTPUT->box(get_string("emailconfirmsent", "", $user->email), "generalbox boxaligncenter"); echo $OUTPUT->footer(); die; } /// Let's get them all set up. complete_user_login($user); \core\session\manager::apply_concurrent_login_limit($user->id, session_id()); // sets the username cookie if (!empty($CFG->nolastloggedin)) { // do not store last logged in user in cookie // auth plugins can temporarily override this from loginpage_hook() // do not save $CFG->nolastloggedin in database! } else { if (empty($CFG->rememberusername) or $CFG->rememberusername == 2 and empty($frm->rememberusername)) { // no permanent cookies, delete old one if exists set_moodle_cookie(''); } else { set_moodle_cookie($USER->username); } } $urltogo = core_login_get_return_url(); /// check if user password has expired
/** * Set the calendar type for this user. * * @param string $type the calendar type we want to set */ private function set_calendar_type($type) { $this->user->calendartype = $type; \core\session\manager::set_user($this->user); }
/** * 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; }
redirect("{$CFG->wwwroot}/{$CFG->admin}/"); } else { if ($returnto === 'profile') { if ($course->id != SITEID) { $returnurl = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id)); } else { $returnurl = new moodle_url('/user/profile.php', array('id' => $user->id)); } } else { $returnurl = new moodle_url('/user/preferences.php', array('userid' => $user->id)); } redirect($returnurl); } } } else { \core\session\manager::gc(); // Remove stale sessions. redirect("{$CFG->wwwroot}/{$CFG->admin}/user.php"); } // Never reached.. } // Make sure we really are on the https page when https login required. $PAGE->verify_https_required(); // Display page header. if ($user->id == -1 or $user->id != $USER->id) { if ($user->id == -1) { echo $OUTPUT->header(); } else { $streditmyprofile = get_string('editmyprofile'); $userfullname = fullname($user, true); $PAGE->set_heading($userfullname);