/** * @param int $oldversion the version we are upgrading from * @return bool result */ function xmldb_auth_manual_upgrade($oldversion) { global $CFG, $DB, $OUTPUT; if ($oldversion < 2011022700) { // force creation of missing passwords $createpassword = hash_internal_user_password(''); $rs = $DB->get_recordset('user', array('password' => $createpassword, 'auth' => 'manual')); foreach ($rs as $user) { if (validate_email($user->email)) { $DB->set_field('user', 'password', 'to be created', array('id' => $user->id)); unset_user_preference('auth_forcepasswordchange', $user); set_user_preference('create_password', 1, $user); } } $rs->close(); upgrade_plugin_savepoint(true, 2011022700, 'auth', 'manual'); } return true; }
public function __getPassword($username, $email, $old_password, $new_password) { global $CFG, $DB; $systemcontext = context_system::instance(); $response = new CliniqueServiceResponce(); if (!empty($username) && !empty($old_password) && !empty($new_password)) { $user = $DB->get_record('user', array('username' => $username, 'mnethostid' => $CFG->mnet_localhost_id, 'deleted' => 0, 'suspended' => 0)); if (!empty($user)) { if (is_mnet_remote_user($user)) { add_to_log(-1, 'custom_webservice', 'mnet_user', null, 'Change password - mnet user trying to access.', 0, $user->id); $response->response(true, 'cp_mnet_user'); die; } if (isguestuser($user)) { add_to_log(-1, 'custom_webservice', 'mnet_user', null, 'Change password - guest user credential supplied.', 0, $user->id); $response->response(true, 'cp_guest'); die; } // make sure user is allowed to change password require_capability('moodle/user:changeownpassword', $systemcontext, $user->id); // $generatePasswordResult = generatePassword::app_validate_internal_user_password($user, $old_password); if (!ChangePassword::__app_validate_internal_user_password($user, $old_password)) { $response->response(true, 'cp_wrong_oldpwd'); } else { $userauth = get_auth_plugin($user->auth); if ($userauth->user_update_password($user, $new_password)) { unset_user_preference('auth_forcepasswordchange', $user); unset_user_preference('create_password', $user); $response->response(false, 'cp_success'); } else { add_to_log(-1, 'custom_webservice', 'trigger_mail', null, 'Change password - password change updation failure.', 0, $user->id); $response->response(true, 'cp_failure'); } } } else { $response->response(false, 'cp_no_mail_record'); } } else { add_to_log(-1, 'custom_webservice', 'input_parameters', null, 'Change password - input parameters missing.', 0, $user->id); } }
private function __app_reset_password_and_mail($user) { global $CFG; $site = get_site(); $supportuser = generate_email_supportuser(); $userauth = get_auth_plugin($user->auth); if (!$userauth->can_reset_password() or !is_enabled_auth($user->auth)) { trigger_error("Attempt to reset user password for user {$user->username} with Auth {$user->auth}."); return false; } $newpassword = generate_password(); if (!$userauth->user_update_password($user, $newpassword)) { $error->error = true; $error->msg = 'fp_passwordgen_failure'; echo json_encode($error); die; } $a = new stdClass(); $a->firstname = $user->firstname; $a->lastname = $user->lastname; $a->sitename = format_string($site->fullname); $a->username = $user->username; $a->newpassword = $newpassword; //$a->signoff = generate_email_signoff(); $message = 'Hi ' . $a->firstname . ', Your account password at \'' . $a->sitename . '\' has been reset and you have been issued with a new temporary password. Your current login information is now: username: '******' password: '******' Cheers from the \'' . $a->sitename . '\' administrator.'; //$message = get_string('newpasswordtext', '', $a); $subject = format_string($site->fullname) . ': ' . get_string('changedpassword'); unset_user_preference('create_password', $user); // prevent cron from generating the password //directly email rather than using the messaging system to ensure its not routed to a popup or jabber return email_to_user($user, $supportuser, $subject, $message); }
/** * Do the job. * Throw exceptions on errors (the job will be retried). */ public function execute() { global $DB; // 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, u.auth, u.deleted,\n u.suspended, u.emailstop, u.mnethostid, u.mailformat,\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\n u.email !='' AND u.suspended = 0 AND\n 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(); } }
unset_user_preference('auth_forcepasswordchange', $existinguser); } else { if (!empty($user->password)) { if ($updatepasswords) { $errmsg = null; $weak = !check_password_policy($user->password, $errmsg); if ($resetpasswords == UU_PWRESET_ALL or $resetpasswords == UU_PWRESET_WEAK and $weak) { if ($weak) { $weakpasswords++; $upt->track('password', $strinvalidpasswordpolicy, 'warning'); } set_user_preference('auth_forcepasswordchange', 1, $existinguser); } else { unset_user_preference('auth_forcepasswordchange', $existinguser); } unset_user_preference('create_password', $existinguser); // no need to create password any more $existinguser->password = hash_internal_user_password($user->password); $upt->track('password', $user->password, 'normal', false); } else { // do not print password when not changed $upt->track('password', '', 'normal', false); } } } if ($doupdate or $existinguser->password !== $oldpw) { // we want only users that were really updated $DB->update_record('user', $existinguser); $upt->track('status', $struserupdated); $usersupdated++; // save custom profile fields data from csv file
public function test_set_user_preference() { global $DB, $USER; $this->resetAfterTest(); $this->setAdminUser(); $otheruser = $this->getDataGenerator()->create_user(); $otheruserid = $otheruser->id; $DB->delete_records('user_preferences', array('userid' => $otheruserid)); set_cache_flag('userpreferenceschanged', $otheruserid, null); $user = new stdClass(); $user->id = $otheruserid; set_user_preference('aaa', 'bbb', $otheruserid); $this->assertSame('bbb', $DB->get_field('user_preferences', 'value', array('userid' => $otheruserid, 'name' => 'aaa'))); $this->assertSame('bbb', get_user_preferences('aaa', null, $otheruserid)); set_user_preference('xxx', 'yyy', $user); $this->assertSame('yyy', $DB->get_field('user_preferences', 'value', array('userid' => $otheruserid, 'name' => 'xxx'))); $this->assertSame('yyy', get_user_preferences('xxx', null, $otheruserid)); $this->assertTrue(is_array($user->preference)); $this->assertSame('bbb', $user->preference['aaa']); $this->assertSame('yyy', $user->preference['xxx']); set_user_preference('xxx', null, $user); $this->assertFalse($DB->get_field('user_preferences', 'value', array('userid' => $otheruserid, 'name' => 'xxx'))); $this->assertNull(get_user_preferences('xxx', null, $otheruserid)); set_user_preference('ooo', true, $user); $prefs = get_user_preferences(null, null, $otheruserid); $this->assertSame($user->preference['aaa'], $prefs['aaa']); $this->assertSame($user->preference['ooo'], $prefs['ooo']); $this->assertSame('1', $prefs['ooo']); set_user_preference('null', 0, $user); $this->assertSame('0', get_user_preferences('null', null, $otheruserid)); $this->assertSame('lala', get_user_preferences('undefined', 'lala', $otheruserid)); $DB->delete_records('user_preferences', array('userid' => $otheruserid)); set_cache_flag('userpreferenceschanged', $otheruserid, null); // Test $USER default. set_user_preference('_test_user_preferences_pref', 'ok'); $this->assertSame('ok', $USER->preference['_test_user_preferences_pref']); unset_user_preference('_test_user_preferences_pref'); $this->assertTrue(!isset($USER->preference['_test_user_preferences_pref'])); // Test 1333 char values (no need for unicode, there are already tests for that in DB tests). $longvalue = str_repeat('a', 1333); set_user_preference('_test_long_user_preference', $longvalue); $this->assertEquals($longvalue, get_user_preferences('_test_long_user_preference')); $this->assertEquals($longvalue, $DB->get_field('user_preferences', 'value', array('userid' => $USER->id, 'name' => '_test_long_user_preference'))); // Test > 1333 char values, coding_exception expected. $longvalue = str_repeat('a', 1334); try { set_user_preference('_test_long_user_preference', $longvalue); $this->fail('Exception expected - longer than 1333 chars not allowed as preference value'); } catch (moodle_exception $ex) { $this->assertInstanceOf('coding_exception', $ex); } // Test invalid params. try { set_user_preference('_test_user_preferences_pref', array()); $this->fail('Exception expected - array not valid preference value'); } catch (moodle_exception $ex) { $this->assertInstanceOf('coding_exception', $ex); } try { set_user_preference('_test_user_preferences_pref', new stdClass()); $this->fail('Exception expected - class not valid preference value'); } catch (moodle_exception $ex) { $this->assertInstanceOf('coding_exception', $ex); } try { set_user_preference('_test_user_preferences_pref', 1, array('xx' => 1)); $this->fail('Exception expected - user instance expected'); } catch (moodle_exception $ex) { $this->assertInstanceOf('coding_exception', $ex); } try { set_user_preference('_test_user_preferences_pref', 1, 'abc'); $this->fail('Exception expected - user instance expected'); } catch (moodle_exception $ex) { $this->assertInstanceOf('coding_exception', $ex); } try { set_user_preference('', 1); $this->fail('Exception expected - invalid name accepted'); } catch (moodle_exception $ex) { $this->assertInstanceOf('coding_exception', $ex); } try { set_user_preference('1', 1); $this->fail('Exception expected - invalid name accepted'); } catch (moodle_exception $ex) { $this->assertInstanceOf('coding_exception', $ex); } }
/** * Gets the content for this block by grabbing it from $this->page * * @return object $this->content */ function get_content() { global $CFG, $OUTPUT; // First check if we have already generated, don't waste cycles if ($this->contentgenerated === true) { return $this->content; } // JS for navigation moved to the standard theme, the code will probably have to depend on the actual page structure // $this->page->requires->js('/lib/javascript-navigation.js'); // Navcount is used to allow us to have multiple trees although I dont' know why // you would want two trees the same block_navigation::$navcount++; // Check if this block has been docked if ($this->docked === null) { $this->docked = get_user_preferences('nav_in_tab_panel_globalnav' . block_navigation::$navcount, 0); } // Check if there is a param to change the docked state if ($this->docked && optional_param('undock', null, PARAM_INT) == $this->instance->id) { unset_user_preference('nav_in_tab_panel_globalnav' . block_navigation::$navcount); $url = $this->page->url; $url->remove_params(array('undock')); redirect($url); } else { if (!$this->docked && optional_param('dock', null, PARAM_INT) == $this->instance->id) { set_user_preferences(array('nav_in_tab_panel_globalnav' . block_navigation::$navcount => 1)); $url = $this->page->url; $url->remove_params(array('dock')); redirect($url); } } $trimmode = self::TRIM_LEFT; $trimlength = 50; if (!empty($this->config->trimmode)) { $trimmode = (int) $this->config->trimmode; } if (!empty($this->config->trimlength)) { $trimlength = (int) $this->config->trimlength; } // Initialise (only actually happens if it hasn't already been done yet $this->page->navigation->initialise(); $navigation = clone $this->page->navigation; $expansionlimit = null; if (!empty($this->config->expansionlimit)) { $expansionlimit = $this->config->expansionlimit; $navigation->set_expansion_limit($this->config->expansionlimit); } $this->trim($navigation, $trimmode, $trimlength, ceil($trimlength / 2)); // Get the expandable items so we can pass them to JS $expandable = array(); $navigation->find_expandable($expandable); if ($expansionlimit) { foreach ($expandable as $key => $node) { if ($node['type'] > $expansionlimit && !($expansionlimit == navigation_node::TYPE_COURSE && $node['type'] == $expansionlimit && $node['branchid'] == SITEID)) { unset($expandable[$key]); } } } $this->page->requires->data_for_js('navtreeexpansions' . $this->instance->id, $expandable); $options = array(); $options['linkcategories'] = !empty($this->config->linkcategories) && $this->config->linkcategories == 'yes'; // Grab the items to display $renderer = $this->page->get_renderer('block_navigation'); $this->content = new stdClass(); $this->content->text = $renderer->navigation_tree($navigation, $expansionlimit, $options); // Set content generated to true so that we know it has been done $this->contentgenerated = true; return $this->content; }
/** * Resets specified user's password and send the new password to the user via email. * * @param stdClass $user A {@link $USER} object * @return bool Returns true if mail was sent OK and false if there was an error. */ function reset_password_and_mail($user) { global $CFG; $site = get_site(); $supportuser = core_user::get_support_user(); $userauth = get_auth_plugin($user->auth); if (!$userauth->can_reset_password() or !is_enabled_auth($user->auth)) { trigger_error("Attempt to reset user password for user {$user->username} with Auth {$user->auth}."); return false; } $newpassword = generate_password(); if (!$userauth->user_update_password($user, $newpassword)) { print_error("cannotsetpassword"); } $a = new stdClass(); $a->firstname = $user->firstname; $a->lastname = $user->lastname; $a->sitename = format_string($site->fullname); $a->username = $user->username; $a->newpassword = $newpassword; $a->link = $CFG->httpswwwroot . '/login/change_password.php'; $a->signoff = generate_email_signoff(); $message = get_string('newpasswordtext', '', $a); $subject = format_string($site->fullname) . ': ' . get_string('changedpassword'); unset_user_preference('create_password', $user); // Prevent cron from generating the password. // Directly email rather than using the messaging system to ensure its not routed to a popup or jabber. return email_to_user($user, $supportuser, $subject, $message); }
print_error('nocourseid'); } require_login($course->id); $context = get_context_instance(CONTEXT_COURSE, $course->id); $systemcontext = get_context_instance(CONTEXT_SYSTEM); require_capability('gradereport/grader:view', $context); require 'preferences_form.php'; $mform = new grader_report_preferences_form('preferences.php', compact('course')); // If data submitted, then process and store. if (!$mform->is_cancelled() && ($data = $mform->get_data())) { foreach ($data as $preference => $value) { if (substr($preference, 0, 6) !== 'grade_') { continue; } if ($value == GRADE_REPORT_PREFERENCE_DEFAULT || strlen($value) == 0) { unset_user_preference($preference); } else { set_user_preference($preference, $value); } } redirect($CFG->wwwroot . '/grade/report/grader/index.php?id=' . $courseid); // message here breaks accessability and is sloooowww exit; } if ($mform->is_cancelled()) { redirect($CFG->wwwroot . '/grade/report/grader/index.php?id=' . $courseid); } print_grade_page_head($courseid, 'preferences', 'grader', get_string('preferences', 'gradereport_grader')); // If USER has admin capability, print a link to the site config page for this report if (has_capability('moodle/site:config', $systemcontext)) { echo '<div id="siteconfiglink"><a href="' . $CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=gradereportgrader">';
public function test_set_user_preference() { global $DB, $USER; if (!($otheruserid = $this->get_fake_preference_test_userid())) { $this->fail('Can not find unused user id for the preferences test'); return; } $DB->delete_records('user_preferences', array('userid' => $otheruserid)); set_cache_flag('userpreferenceschanged', $otheruserid, null); $user = new stdClass(); $user->id = $otheruserid; set_user_preference('aaa', 'bbb', $otheruserid); $this->assertEqual('bbb', $DB->get_field('user_preferences', 'value', array('userid' => $otheruserid, 'name' => 'aaa'))); $this->assertEqual('bbb', get_user_preferences('aaa', null, $otheruserid)); set_user_preference('xxx', 'yyy', $user); $this->assertEqual('yyy', $DB->get_field('user_preferences', 'value', array('userid' => $otheruserid, 'name' => 'xxx'))); $this->assertEqual('yyy', get_user_preferences('xxx', null, $otheruserid)); $this->assertTrue(is_array($user->preference)); $this->assertEqual($user->preference['aaa'], 'bbb'); $this->assertEqual($user->preference['xxx'], 'yyy'); set_user_preference('xxx', NULL, $user); $this->assertIdentical(false, $DB->get_field('user_preferences', 'value', array('userid' => $otheruserid, 'name' => 'xxx'))); $this->assertIdentical(null, get_user_preferences('xxx', null, $otheruserid)); set_user_preference('ooo', true, $user); $prefs = get_user_preferences(null, null, $otheruserid); $this->assertIdentical($prefs['aaa'], $user->preference['aaa']); $this->assertIdentical($prefs['ooo'], $user->preference['ooo']); $this->assertIdentical($prefs['ooo'], '1'); set_user_preference('null', 0, $user); $this->assertIdentical('0', get_user_preferences('null', null, $otheruserid)); $this->assertIdentical('lala', get_user_preferences('undefined', 'lala', $otheruserid)); $DB->delete_records('user_preferences', array('userid' => $otheruserid)); set_cache_flag('userpreferenceschanged', $otheruserid, null); // test $USER default set_user_preference('_test_user_preferences_pref', 'ok'); $this->assertIdentical('ok', $USER->preference['_test_user_preferences_pref']); unset_user_preference('_test_user_preferences_pref'); $this->assertTrue(!isset($USER->preference['_test_user_preferences_pref'])); //test invalid params try { set_user_preference('_test_user_preferences_pref', array()); $this->assertFail('Exception expected - array not valid preference value'); } catch (Exception $ex) { $this->assertTrue(true); } try { set_user_preference('_test_user_preferences_pref', new stdClass()); $this->assertFail('Exception expected - class not valid preference value'); } catch (Exception $ex) { $this->assertTrue(true); } try { set_user_preference('_test_user_preferences_pref', 1, array('xx' => 1)); $this->assertFail('Exception expected - user instance expected'); } catch (Exception $ex) { $this->assertTrue(true); } try { set_user_preference('_test_user_preferences_pref', 1, 'abc'); $this->assertFail('Exception expected - user instance expected'); } catch (Exception $ex) { $this->assertTrue(true); } try { set_user_preference('', 1); $this->assertFail('Exception expected - invalid name accepted'); } catch (Exception $ex) { $this->assertTrue(true); } try { set_user_preference('1', 1); $this->assertFail('Exception expected - invalid name accepted'); } catch (Exception $ex) { $this->assertTrue(true); } }
/** * Gets the content for this block by grabbing it from $this->page * * @return object $this->content */ function get_content() { // First check if we have already generated, don't waste cycles if ($this->contentgenerated === true) { return $this->content; } // JS for navigation moved to the standard theme, the code will probably have to depend on the actual page structure // $this->page->requires->js('/lib/javascript-navigation.js'); // Navcount is used to allow us to have multiple trees although I dont' know why // you would want two trees the same block_navigation::$navcount++; // Check if this block has been docked if ($this->docked === null) { $this->docked = get_user_preferences('nav_in_tab_panel_globalnav' . block_navigation::$navcount, 0); } // Check if there is a param to change the docked state if ($this->docked && optional_param('undock', null, PARAM_INT) == $this->instance->id) { unset_user_preference('nav_in_tab_panel_globalnav' . block_navigation::$navcount); $url = $this->page->url; $url->remove_params(array('undock')); redirect($url); } else { if (!$this->docked && optional_param('dock', null, PARAM_INT) == $this->instance->id) { set_user_preferences(array('nav_in_tab_panel_globalnav' . block_navigation::$navcount => 1)); $url = $this->page->url; $url->remove_params(array('dock')); redirect($url); } } $trimmode = self::TRIM_LEFT; $trimlength = 50; if (!empty($this->config->trimmode)) { $trimmode = (int) $this->config->trimmode; } if (!empty($this->config->trimlength)) { $trimlength = (int) $this->config->trimlength; } // Get the navigation object or don't display the block if none provided. if (!($navigation = $this->get_navigation())) { return null; } $expansionlimit = null; if (!empty($this->config->expansionlimit)) { $expansionlimit = $this->config->expansionlimit; $navigation->set_expansion_limit($this->config->expansionlimit); } $this->trim($navigation, $trimmode, $trimlength, ceil($trimlength / 2)); // Get the expandable items so we can pass them to JS $expandable = array(); $navigation->find_expandable($expandable); if ($expansionlimit) { foreach ($expandable as $key => $node) { if ($node['type'] > $expansionlimit && !($expansionlimit == navigation_node::TYPE_COURSE && $node['type'] == $expansionlimit && $node['branchid'] == SITEID)) { unset($expandable[$key]); } } } $this->page->requires->data_for_js('navtreeexpansions' . $this->instance->id, $expandable); $options = array(); $options['linkcategories'] = !empty($this->config->linkcategories) && $this->config->linkcategories == 'yes'; // Grab the items to display $renderer = $this->page->get_renderer($this->blockname); $this->content = new stdClass(); $this->content->text = $renderer->navigation_tree($navigation, $expansionlimit, $options); // Set content generated to true so that we know it has been done $this->contentgenerated = true; global $PAGE, $CFG; //sujets link if (has_capability('moodle/course:create', $PAGE->context)) { $this->content->text .= '<ul class="block_tree list><li class=" type_setting="" depth_1="" item_with_icon"="">'; $this->content->text .= '<a href="' . $CFG->wwwroot . '/local/template_course/index.php">'; $this->content->text .= '<img alt="" class="smallicon navicon" title="" src="' . $CFG->wwwroot . '/theme/image.php/formfactor/core/1404983571/i/navigationitem"/>'; $this->content->text .= 'Matières</a></li></ul>'; } return $this->content; }
/** * Test are_notification_preferences_configured */ public function test_are_notification_preferences_configured() { $this->resetAfterTest(true); $user1 = self::getDataGenerator()->create_user(); $user2 = self::getDataGenerator()->create_user(); $user3 = self::getDataGenerator()->create_user(); self::setUser($user1); set_user_preference('message_provider_moodle_instantmessage_loggedin', 'airnotifier', $user1); set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'airnotifier', $user1); set_user_preference('message_provider_moodle_instantmessage_loggedin', 'airnotifier', $user2); set_user_preference('message_provider_moodle_instantmessage_loggedin', 'airnotifier', $user3); $params = array($user1->id, $user2->id, $user3->id); $preferences = message_airnotifier_external::are_notification_preferences_configured($params); $expected = array(array('userid' => $user1->id, 'configured' => 1)); $this->assertEquals(1, count($preferences['users'])); $this->assertEquals($expected, $preferences['users']); $this->assertEquals(2, count($preferences['warnings'])); // Now, remove one user. delete_user($user2); $preferences = message_airnotifier_external::are_notification_preferences_configured($params); $this->assertEquals(1, count($preferences['users'])); $this->assertEquals($expected, $preferences['users']); $this->assertEquals(2, count($preferences['warnings'])); // Now, remove one user1 preference (the user still has one prefernce for airnotifier). unset_user_preference('message_provider_moodle_instantmessage_loggedin', $user1); $preferences = message_airnotifier_external::are_notification_preferences_configured($params); $this->assertEquals($expected, $preferences['users']); // Delete the last user1 preference. unset_user_preference('message_provider_moodle_instantmessage_loggedoff', $user1); $preferences = message_airnotifier_external::are_notification_preferences_configured($params); $expected = array(array('userid' => $user1->id, 'configured' => 0)); $this->assertEquals($expected, $preferences['users']); }
$mform->set_data(array('id'=>$course->id)); $navlinks = array(); $navlinks[] = array('name' => $strparticipants, 'link' => "$CFG->wwwroot/user/index.php?id=$course->id", 'type' => 'misc'); if ($mform->is_cancelled()) { redirect($CFG->wwwroot.'/user/view.php?id='.$USER->id.'&course='.$course->id); } else if ($data = $mform->get_data()) { if (!$userauth->user_update_password($USER, $data->newpassword1)) { print_error('errorpasswordupdate', 'auth'); } // register success changing password unset_user_preference('auth_forcepasswordchange', $USER); unset_user_preference('create_password', $USER); $strpasswordchanged = get_string('passwordchanged'); add_to_log($course->id, 'user', 'change password', "view.php?id=$USER->id&course=$course->id", "$USER->id"); $fullname = fullname($USER, true); $PAGE->navbar->add($fullname, new moodle_url('/user/view.php', array('id'=>$USER->id, 'course'=>$course->id))); $PAGE->navbar->add($strpasswordchanged); $PAGE->set_title($strpasswordchanged); $PAGE->set_heading($COURSE->fullname); echo $OUTPUT->header(); notice($strpasswordchanged, new moodle_url($PAGE->url, array('return'=>1)));
$forcechangepassword = false; } else if ($updatepasswords){ $existinguser->password = hash_internal_user_password($existinguser->password); } else { $existinguser->password = $temppasswordhandler; } $DB->update_record('user', $existinguser); //remove user preference if (get_user_preferences('create_password', false, $existinguser)) { unset_user_preference('create_password', $existinguser); } if (get_user_preferences('auth_forcepasswordchange', false, $existinguser)) { unset_user_preference('auth_forcepasswordchange', $existinguser); } if ($isinternalauth && $updatepasswords) { if (empty($existinguser->password)) { set_user_preference('create_password', 1, $existinguser->id); set_user_preference('auth_forcepasswordchange', 1, $existinguser->id); $upt->track('password', get_string('new')); } else if ($forcechangepassword) { set_user_preference('auth_forcepasswordchange', 1, $existinguser->id); } } $upt->track('status', $struserupdated); $usersupdated++; // save custom profile fields data from csv file profile_save_data($existinguser);
public function test_set_user_preference() { global $DB, $USER; $this->resetAfterTest(true); $olduser = $USER; $USER = $DB->get_record('user', array('id'=>2)); //admin if (!$otheruserid = $this->get_fake_preference_test_userid()) { $this->fail('Can not find unused user id for the preferences test'); return; } $DB->delete_records('user_preferences', array('userid'=>$otheruserid)); set_cache_flag('userpreferenceschanged', $otheruserid, null); $user = new stdClass(); $user->id = $otheruserid; set_user_preference('aaa', 'bbb', $otheruserid); $this->assertEquals('bbb', $DB->get_field('user_preferences', 'value', array('userid'=>$otheruserid, 'name'=>'aaa'))); $this->assertEquals('bbb', get_user_preferences('aaa', null, $otheruserid)); set_user_preference('xxx', 'yyy', $user); $this->assertEquals('yyy', $DB->get_field('user_preferences', 'value', array('userid'=>$otheruserid, 'name'=>'xxx'))); $this->assertEquals('yyy', get_user_preferences('xxx', null, $otheruserid)); $this->assertTrue(is_array($user->preference)); $this->assertEquals($user->preference['aaa'], 'bbb'); $this->assertEquals($user->preference['xxx'], 'yyy'); set_user_preference('xxx', NULL, $user); $this->assertSame(false, $DB->get_field('user_preferences', 'value', array('userid'=>$otheruserid, 'name'=>'xxx'))); $this->assertSame(null, get_user_preferences('xxx', null, $otheruserid)); set_user_preference('ooo', true, $user); $prefs = get_user_preferences(null, null, $otheruserid); $this->assertSame($prefs['aaa'], $user->preference['aaa']); $this->assertSame($prefs['ooo'], $user->preference['ooo']); $this->assertSame($prefs['ooo'], '1'); set_user_preference('null', 0, $user); $this->assertSame('0', get_user_preferences('null', null, $otheruserid)); $this->assertSame('lala', get_user_preferences('undefined', 'lala', $otheruserid)); $DB->delete_records('user_preferences', array('userid'=>$otheruserid)); set_cache_flag('userpreferenceschanged', $otheruserid, null); // test $USER default set_user_preference('_test_user_preferences_pref', 'ok'); $this->assertSame('ok', $USER->preference['_test_user_preferences_pref']); unset_user_preference('_test_user_preferences_pref'); $this->assertTrue(!isset($USER->preference['_test_user_preferences_pref'])); // Test 1333 char values (no need for unicode, there are already tests for that in DB tests) $longvalue = str_repeat('a', 1333); set_user_preference('_test_long_user_preference', $longvalue); $this->assertEquals($longvalue, get_user_preferences('_test_long_user_preference')); $this->assertEquals($longvalue, $DB->get_field('user_preferences', 'value', array('userid' => $USER->id, 'name' => '_test_long_user_preference'))); // Test > 1333 char values, coding_exception expected $longvalue = str_repeat('a', 1334); try { set_user_preference('_test_long_user_preference', $longvalue); $this->assertFail('Exception expected - longer than 1333 chars not allowed as preference value'); } catch (Exception $e) { $this->assertTrue($e instanceof coding_exception); } //test invalid params try { set_user_preference('_test_user_preferences_pref', array()); $this->assertFail('Exception expected - array not valid preference value'); } catch (Exception $ex) { $this->assertTrue(true); } try { set_user_preference('_test_user_preferences_pref', new stdClass); $this->assertFail('Exception expected - class not valid preference value'); } catch (Exception $ex) { $this->assertTrue(true); } try { set_user_preference('_test_user_preferences_pref', 1, array('xx'=>1)); $this->assertFail('Exception expected - user instance expected'); } catch (Exception $ex) { $this->assertTrue(true); } try { set_user_preference('_test_user_preferences_pref', 1, 'abc'); $this->assertFail('Exception expected - user instance expected'); } catch (Exception $ex) { $this->assertTrue(true); } try { set_user_preference('', 1); $this->assertFail('Exception expected - invalid name accepted'); } catch (Exception $ex) { $this->assertTrue(true); } try { set_user_preference('1', 1); $this->assertFail('Exception expected - invalid name accepted'); } catch (Exception $ex) { $this->assertTrue(true); } $USER = $olduser; }
/** * Uses set_user_preferences() to update the value of a user preference. If 'default' is given as the value, * the preference will be removed in favour of a higher-level preference. * @static * @param string $pref_name The name of the preference. * @param mixed $pref_value The value of the preference. * @param int $itemid An optional itemid to which the preference will be assigned * @return bool Success or failure. */ public function set_pref($pref, $pref_value = 'default', $itemid = null) { $fullprefname = 'grade_report_' . $pref; if ($pref_value == 'default') { return unset_user_preference($fullprefname . $itemid); } else { return set_user_preference($fullprefname . $itemid, $pref_value); } }
/** * Display the report. */ public function display($quiz, $cm, $course) { global $CFG, $DB, $OUTPUT, $PAGE; $this->context = context_module::instance($cm->id); // Work out the display options. $download = optional_param('download', '', PARAM_ALPHA); $everything = optional_param('everything', 0, PARAM_BOOL); $recalculate = optional_param('recalculate', 0, PARAM_BOOL); // A qid paramter indicates we should display the detailed analysis of a question. $qid = optional_param('qid', 0, PARAM_INT); $slot = optional_param('slot', 0, PARAM_INT); $pageoptions = array(); $pageoptions['id'] = $cm->id; $pageoptions['mode'] = 'statistics'; $reporturl = new moodle_url('/mod/quiz/report.php', $pageoptions); $mform = new quiz_statistics_settings_form($reporturl); if ($fromform = $mform->get_data()) { $useallattempts = $fromform->useallattempts; if ($fromform->useallattempts) { set_user_preference('quiz_report_statistics_useallattempts', $fromform->useallattempts); } else { unset_user_preference('quiz_report_statistics_useallattempts'); } } else { $useallattempts = get_user_preferences('quiz_report_statistics_useallattempts', 0); } // Find out current groups mode. $currentgroup = $this->get_current_group($cm, $course, $this->context); $nostudentsingroup = false; // True if a group is selected and there is no one in it. if (empty($currentgroup)) { $currentgroup = 0; $groupstudents = array(); } else if ($currentgroup == self::NO_GROUPS_ALLOWED) { $groupstudents = array(); $nostudentsingroup = true; } else { // All users who can attempt quizzes and who are in the currently selected group. $groupstudents = get_users_by_capability($this->context, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), '', '', '', '', $currentgroup, '', false); if (!$groupstudents) { $nostudentsingroup = true; } } // If recalculate was requested, handle that. if ($recalculate && confirm_sesskey()) { $this->clear_cached_data($quiz->id, $currentgroup, $useallattempts); redirect($reporturl); } // Set up the main table. $this->table = new quiz_statistics_table(); if ($everything) { $report = get_string('completestatsfilename', 'quiz_statistics'); } else { $report = get_string('questionstatsfilename', 'quiz_statistics'); } $courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id))); $filename = quiz_report_download_filename($report, $courseshortname, $quiz->name); $this->table->is_downloading($download, $filename, get_string('quizstructureanalysis', 'quiz_statistics')); // Load the questions. $questions = quiz_report_get_significant_questions($quiz); $questionids = array(); foreach ($questions as $question) { $questionids[] = $question->id; } $fullquestions = question_load_questions($questionids); foreach ($questions as $qno => $question) { $q = $fullquestions[$question->id]; $q->maxmark = $question->maxmark; $q->slot = $qno; $q->number = $question->number; $questions[$qno] = $q; } // Get the data to be displayed. list($quizstats, $questions, $subquestions, $s) = $this->get_quiz_and_questions_stats($quiz, $currentgroup, $nostudentsingroup, $useallattempts, $groupstudents, $questions); $quizinfo = $this->get_formatted_quiz_info_data($course, $cm, $quiz, $quizstats); // Set up the table, if there is data. if ($s) { $this->table->statistics_setup($quiz, $cm->id, $reporturl, $s); } // Print the page header stuff (if not downloading. if (!$this->table->is_downloading()) { $this->print_header_and_tabs($cm, $course, $quiz, 'statistics'); if (groups_get_activity_groupmode($cm)) { groups_print_activity_menu($cm, $reporturl->out()); if ($currentgroup && !$groupstudents) { $OUTPUT->notification(get_string('nostudentsingroup', 'quiz_statistics')); } } if (!quiz_questions_in_quiz($quiz->questions)) { echo quiz_no_questions_message($quiz, $cm, $this->context); } else if (!$this->table->is_downloading() && $s == 0) { echo $OUTPUT->notification(get_string('noattempts', 'quiz')); } // Print display options form. $mform->set_data(array('useallattempts' => $useallattempts)); $mform->display(); } if ($everything) { // Implies is downloading. // Overall report, then the analysis of each question. $this->download_quiz_info_table($quizinfo); if ($s) { $this->output_quiz_structure_analysis_table($s, $questions, $subquestions); if ($this->table->is_downloading() == 'xhtml') { $this->output_statistics_graph($quizstats->id, $s); } foreach ($questions as $question) { if (question_bank::get_qtype( $question->qtype, false)->can_analyse_responses()) { $this->output_individual_question_response_analysis( $question, $reporturl, $quizstats); } else if (!empty($question->_stats->subquestions)) { $subitemstodisplay = explode(',', $question->_stats->subquestions); foreach ($subitemstodisplay as $subitemid) { $this->output_individual_question_response_analysis( $subquestions[$subitemid], $reporturl, $quizstats); } } } } $this->table->export_class_instance()->finish_document(); } else if ($slot) { // Report on an individual question indexed by position. if (!isset($questions[$slot])) { print_error('questiondoesnotexist', 'question'); } $this->output_individual_question_data($quiz, $questions[$slot]); $this->output_individual_question_response_analysis( $questions[$slot], $reporturl, $quizstats); // Back to overview link. echo $OUTPUT->box('<a href="' . $reporturl->out() . '">' . get_string('backtoquizreport', 'quiz_statistics') . '</a>', 'backtomainstats boxaligncenter generalbox boxwidthnormal mdl-align'); } else if ($qid) { // Report on an individual sub-question indexed questionid. if (!isset($subquestions[$qid])) { print_error('questiondoesnotexist', 'question'); } $this->output_individual_question_data($quiz, $subquestions[$qid]); $this->output_individual_question_response_analysis( $subquestions[$qid], $reporturl, $quizstats); // Back to overview link. echo $OUTPUT->box('<a href="' . $reporturl->out() . '">' . get_string('backtoquizreport', 'quiz_statistics') . '</a>', 'boxaligncenter generalbox boxwidthnormal mdl-align'); } else if ($this->table->is_downloading()) { // Downloading overview report. $this->download_quiz_info_table($quizinfo); $this->output_quiz_structure_analysis_table($s, $questions, $subquestions); $this->table->finish_output(); } else { // On-screen display of overview report. echo $OUTPUT->heading(get_string('quizinformation', 'quiz_statistics')); echo $this->output_caching_info($quizstats, $quiz->id, $currentgroup, $groupstudents, $useallattempts, $reporturl); echo $this->everything_download_options(); echo $this->output_quiz_info_table($quizinfo); if ($s) { echo $OUTPUT->heading(get_string('quizstructureanalysis', 'quiz_statistics')); $this->output_quiz_structure_analysis_table($s, $questions, $subquestions); $this->output_statistics_graph($quizstats->id, $s); } } return true; }
/** * Create one or more users. * * @throws invalid_parameter_exception * @param array $users An array of users to create. * @return array An array of arrays * @since Moodle 2.2 */ public static function create_users($users) { global $CFG, $DB; require_once $CFG->dirroot . "/lib/weblib.php"; require_once $CFG->dirroot . "/user/lib.php"; require_once $CFG->dirroot . "/user/profile/lib.php"; // Required for customfields related function. // Ensure the current user is allowed to run this function. $context = context_system::instance(); self::validate_context($context); require_capability('moodle/user:create', $context); // Do basic automatic PARAM checks on incoming data, using params description. // If any problems are found then exceptions are thrown with helpful error messages. $params = self::validate_parameters(self::create_users_parameters(), array('users' => $users)); $availableauths = core_component::get_plugin_list('auth'); unset($availableauths['mnet']); // These would need mnethostid too. unset($availableauths['webservice']); // We do not want new webservice users for now. $availablethemes = core_component::get_plugin_list('theme'); $availablelangs = get_string_manager()->get_list_of_translations(); $transaction = $DB->start_delegated_transaction(); $userids = array(); $createpassword = false; foreach ($params['users'] as $user) { // Make sure that the username doesn't already exist. if ($DB->record_exists('user', array('username' => $user['username'], 'mnethostid' => $CFG->mnet_localhost_id))) { throw new invalid_parameter_exception('Username already exists: ' . $user['username']); } // Make sure auth is valid. if (empty($availableauths[$user['auth']])) { throw new invalid_parameter_exception('Invalid authentication type: ' . $user['auth']); } // Make sure lang is valid. if (empty($availablelangs[$user['lang']])) { throw new invalid_parameter_exception('Invalid language code: ' . $user['lang']); } // Make sure lang is valid. if (!empty($user['theme']) && empty($availablethemes[$user['theme']])) { // Theme is VALUE_OPTIONAL, // so no default value // We need to test if the client sent it // => !empty($user['theme']). throw new invalid_parameter_exception('Invalid theme: ' . $user['theme']); } // Make sure we have a password or have to create one. if (empty($user['password']) && empty($user['createpassword'])) { throw new invalid_parameter_exception('Invalid password: you must provide a password, or set createpassword.'); } $user['confirmed'] = true; $user['mnethostid'] = $CFG->mnet_localhost_id; // Start of user info validation. // Make sure we validate current user info as handled by current GUI. See user/editadvanced_form.php func validation(). if (!validate_email($user['email'])) { throw new invalid_parameter_exception('Email address is invalid: ' . $user['email']); } else { if (empty($CFG->allowaccountssameemail) && $DB->record_exists('user', array('email' => $user['email'], 'mnethostid' => $CFG->mnet_localhost_id))) { throw new invalid_parameter_exception('Email address already exists: ' . $user['email']); } } // End of user info validation. $createpassword = !empty($user['createpassword']); unset($user['createpassword']); if ($createpassword) { $user['password'] = ''; $updatepassword = false; } else { $updatepassword = true; } // Create the user data now! $user['id'] = user_create_user($user, $updatepassword, false); // Custom fields. if (!empty($user['customfields'])) { foreach ($user['customfields'] as $customfield) { // Profile_save_data() saves profile file it's expecting a user with the correct id, // and custom field to be named profile_field_"shortname". $user["profile_field_" . $customfield['type']] = $customfield['value']; } profile_save_data((object) $user); } if ($createpassword) { $userobject = (object) $user; setnew_password_and_mail($userobject); unset_user_preference('create_password', $userobject); set_user_preference('auth_forcepasswordchange', 1, $userobject); } // Trigger event. \core\event\user_created::create_from_userid($user['id'])->trigger(); // Preferences. if (!empty($user['preferences'])) { foreach ($user['preferences'] as $preference) { set_user_preference($preference['type'], $preference['value'], $user['id']); } } $userids[] = array('id' => $user['id'], 'username' => $user['username']); } $transaction->allow_commit(); return $userids; }
/** * Switches the device type we think the user is using to what ever was given. * @param string $newdevice * @return bool * @throws coding_exception */ public static function set_user_device_type($newdevice) { $devicetype = self::get_device_type(); if ($newdevice == $devicetype) { unset_user_preference('switchdevice' . $devicetype); return true; } else { $devicetypes = self::get_device_type_list(); if (in_array($newdevice, $devicetypes)) { set_user_preference('switchdevice' . $devicetype, $newdevice); return true; } } throw new coding_exception('Invalid device type provided to set_user_device_type'); }
$usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, $usercontext, 'user', 'profile', 0); $DB->update_record('user', $usernew); // pass a true $userold here if (! $authplugin->user_update($user, $userform->get_data())) { // auth update failed, rollback for moodle $DB->update_record('user', $user); print_error('cannotupdateuseronexauth', '', '', $user->auth); } //set new password if specified if (!empty($usernew->newpassword)) { if ($authplugin->can_change_password()) { if (!$authplugin->user_update_password($usernew, $usernew->newpassword)){ print_error('cannotupdatepasswordonextauth', '', '', $usernew->auth); } unset_user_preference('create_password', $usernew); // prevent cron from generating the password } } $usercreated = false; } $usercontext = get_context_instance(CONTEXT_USER, $usernew->id); //update preferences useredit_update_user_preference($usernew); // update tags if (!empty($CFG->usetags) and empty($USER->newadminuser)) { useredit_update_interests($usernew, $usernew->interests); }
/** * Sets the display of the event type given $display. * * If $display = true the event type will be shown. * If $display = false the event type will NOT be shown. * If $display = null the current value will be toggled and saved. * * @param CALENDAR_EVENT_GLOBAL|CALENDAR_EVENT_COURSE|CALENDAR_EVENT_GROUP|CALENDAR_EVENT_USER $type object of CALENDAR_EVENT_XXX * @param bool $display option to display event type * @param stdClass|int $user moodle user object or id, null means current user */ function calendar_set_event_type_display($type, $display = null, $user = null) { $persist = get_user_preferences('calendar_persistflt', 0, $user); $default = CALENDAR_EVENT_GLOBAL + CALENDAR_EVENT_COURSE + CALENDAR_EVENT_GROUP + CALENDAR_EVENT_USER; if ($persist === 0) { global $SESSION; if (!isset($SESSION->calendarshoweventtype)) { $SESSION->calendarshoweventtype = $default; } $preference = $SESSION->calendarshoweventtype; } else { $preference = get_user_preferences('calendar_savedflt', $default, $user); } $current = $preference & $type; if ($display === null) { $display = !$current; } if ($display && !$current) { $preference += $type; } else { if (!$display && $current) { $preference -= $type; } } if ($persist === 0) { $SESSION->calendarshoweventtype = $preference; } else { if ($preference == $default) { unset_user_preference('calendar_savedflt', $user); } else { set_user_preference('calendar_savedflt', $preference, $user); } } }
/** * Sets the list of categories that user wants to see collapsed in user preferences * * This method may filter or even trim the list if it does not fit in DB field. * * @param int $courseid * @param array $collapsed */ protected static function set_collapsed_preferences($courseid, $collapsed) { global $DB; // In an unlikely case that the list of collapsed categories for one course is too big for the user preference size, // try to filter the list of categories since array may contain categories that were deleted. if (strlen(json_encode($collapsed)) >= 1333) { $collapsed = static::filter_collapsed_categories($courseid, $collapsed); } // If this did not help, "forget" about some of the collapsed categories. Still better than to loose all information. while (strlen(json_encode($collapsed)) >= 1333) { if (count($collapsed['aggregatesonly'])) { array_pop($collapsed['aggregatesonly']); } if (count($collapsed['gradesonly'])) { array_pop($collapsed['gradesonly']); } } if (!empty($collapsed['aggregatesonly']) || !empty($collapsed['gradesonly'])) { set_user_preference('grade_report_grader_collapsed_categories' . $courseid, json_encode($collapsed)); } else { unset_user_preference('grade_report_grader_collapsed_categories' . $courseid); } }
function cancel_email_update($userid) { unset_user_preference('newemail', $userid); unset_user_preference('newemailkey', $userid); unset_user_preference('newemailattemptsleft', $userid); }
/** * Allows the user to switch the device they are seeing the theme for. * This allows mobile users to switch back to the default theme, or theme for any other device. * * @param string $newdevice The device the user is currently using. * @return string The device the user has switched to */ function set_user_device_type($newdevice) { global $USER; $devicetype = get_device_type(); $devicetypes = get_device_type_list(); if ($newdevice == $devicetype) { unset_user_preference('switchdevice'.$devicetype); } else if (in_array($newdevice, $devicetypes)) { set_user_preference('switchdevice'.$devicetype, $newdevice); } }
} // Update user picture. if (empty($USER->newadminuser)) { useredit_update_picture($usernew, $userform, $filemanageroptions); } // Update mail bounces. useredit_update_bounces($user, $usernew); // Update forum track preference. useredit_update_trackforums($user, $usernew); // Save custom profile fields data. profile_save_data($usernew); // Reload from db. $usernew = $DB->get_record('user', array('id' => $usernew->id)); if ($createpassword) { setnew_password_and_mail($usernew); unset_user_preference('create_password', $usernew); set_user_preference('auth_forcepasswordchange', 1, $usernew); } // Trigger update/create event, after all fields are stored. if ($usercreated) { \core\event\user_created::create_from_userid($usernew->id)->trigger(); } else { \core\event\user_updated::create_from_userid($usernew->id)->trigger(); } if ($user->id == $USER->id) { // Override old $USER session variable. foreach ((array) $usernew as $variable => $value) { if ($variable === 'description' or $variable === 'password') { // These are not set for security nad perf reasons. continue; }
/** * Display the report. */ function display($quiz, $cm, $course) { global $CFG, $DB, $QTYPES, $OUTPUT; $context = get_context_instance(CONTEXT_MODULE, $cm->id); $download = optional_param('download', '', PARAM_ALPHA); $everything = optional_param('everything', 0, PARAM_BOOL); $recalculate = optional_param('recalculate', 0, PARAM_BOOL); //pass the question id for detailed analysis question $qid = optional_param('qid', 0, PARAM_INT); $pageoptions = array(); $pageoptions['id'] = $cm->id; $pageoptions['q'] = $quiz->id; $pageoptions['mode'] = 'statistics'; $questions = quiz_report_load_questions($quiz); // Load the question type specific information if (!get_question_options($questions)) { print_error('cannotloadquestion', 'question'); } $reporturl = new moodle_url($CFG->wwwroot . '/mod/quiz/report.php', $pageoptions); $mform = new mod_quiz_report_statistics($reporturl); if ($fromform = $mform->get_data()) { $useallattempts = $fromform->useallattempts; if ($fromform->useallattempts) { set_user_preference('quiz_report_statistics_useallattempts', $fromform->useallattempts); } else { unset_user_preference('quiz_report_statistics_useallattempts'); } } else { $useallattempts = get_user_preferences('quiz_report_statistics_useallattempts', 0); } /// find out current groups mode $currentgroup = groups_get_activity_group($cm, true); $nostudentsingroup = false; //true if a group is selected and their is noeone in it. if (!empty($currentgroup)) { // all users who can attempt quizzes and who are in the currently selected group $groupstudents = get_users_by_capability($context, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), '', '', '', '', $currentgroup, '', false); if (!$groupstudents) { $nostudentsingroup = true; } } else { $groupstudents = array(); } if ($recalculate) { if ($todelete = $DB->get_records_menu('quiz_statistics', array('quizid' => $quiz->id, 'groupid' => (int) $currentgroup, 'allattempts' => $useallattempts))) { list($todeletesql, $todeleteparams) = $DB->get_in_or_equal(array_keys($todelete)); if (!$DB->delete_records_select('quiz_statistics', "id {$todeletesql}", $todeleteparams)) { print_error('errordeleting', 'quiz_statistics', '', 'quiz_statistics'); } if (!$DB->delete_records_select('quiz_question_statistics', "quizstatisticsid {$todeletesql}", $todeleteparams)) { print_error('errordeleting', 'quiz_statistics', '', 'quiz_question_statistics'); } if (!$DB->delete_records_select('quiz_question_response_stats', "quizstatisticsid {$todeletesql}", $todeleteparams)) { print_error('errordeleting', 'quiz_statistics', '', 'quiz_question_response_stats'); } } redirect($reporturl); } $this->table = new quiz_report_statistics_table(); $filename = "{$course->shortname}-" . format_string($quiz->name, true); $this->table->is_downloading($download, $filename, get_string('quizstructureanalysis', 'quiz_statistics')); if (!$this->table->is_downloading()) { // Only print headers if not asked to download data $this->print_header_and_tabs($cm, $course, $quiz, "statistics"); } if ($groupmode = groups_get_activity_groupmode($cm)) { // Groups are being used if (!$this->table->is_downloading()) { groups_print_activity_menu($cm, $reporturl->out()); echo '<br />'; if ($currentgroup && !$groupstudents) { echo $OUTPUT->notification(get_string('nostudentsingroup', 'quiz_statistics')); } } } if (!$this->table->is_downloading()) { // Print display options $mform->set_data(array('useallattempts' => $useallattempts)); $mform->display(); } list($quizstats, $questions, $subquestions, $s, $usingattemptsstring) = $this->quiz_questions_stats($quiz, $currentgroup, $nostudentsingroup, $useallattempts, $groupstudents, $questions); if (!$this->table->is_downloading()) { if ($s == 0) { echo $OUTPUT->heading(get_string('noattempts', 'quiz')); } } if ($s) { $this->table->setup($quiz, $cm->id, $reporturl, $s); } if (!$qid) { //main page $this->output_quiz_info_table($course, $cm, $quiz, $quizstats, $usingattemptsstring, $currentgroup, $groupstudents, $useallattempts, $download, $reporturl, $everything); $this->output_quiz_structure_analysis_table($s, $questions, $subquestions); if (!$this->table->is_downloading() || $everything && $this->table->is_downloading() == 'xhtml') { if ($s > 1) { $imageurl = $CFG->wwwroot . '/mod/quiz/report/statistics/statistics_graph.php?id=' . $quizstats->id; echo $OUTPUT->heading(get_string('statisticsreportgraph', 'quiz_statistics')); echo '<div class="mdl-align"><img src="' . $imageurl . '" alt="' . get_string('statisticsreportgraph', 'quiz_statistics') . '" /></div>'; } } if ($this->table->is_downloading()) { if ($everything) { foreach ($questions as $question) { if ($question->qtype != 'random' && $QTYPES[$question->qtype]->show_analysis_of_responses()) { $this->output_individual_question_data($quiz, $question, $reporturl, $quizstats); } elseif (!empty($question->_stats->subquestions)) { $subitemstodisplay = explode(',', $question->_stats->subquestions); foreach ($subitemstodisplay as $subitemid) { $this->output_individual_question_data($quiz, $subquestions[$subitemid], $reporturl, $quizstats); } } } $exportclassinstance =& $this->table->export_class_instance(); } else { $this->table->finish_output(); } } if ($this->table->is_downloading() && $everything) { $exportclassinstance->finish_document(); } } else { //individual question page $thisquestion = false; if (isset($questions[$qid])) { $thisquestion = $questions[$qid]; } else { if (isset($subquestions[$qid])) { $thisquestion = $subquestions[$qid]; } else { print_error('questiondoesnotexist', 'question'); } } $this->output_individual_question_data($quiz, $thisquestion, $reporturl, $quizstats); } return true; }
/** * 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"); }
/** * This function processes a user's submitted token to validate the request to set a new password. * If the user's token is validated, they are prompted to set a new password. * @param string $token the one-use identifier which should verify the password reset request as being valid. * @return void */ function core_login_process_password_set($token) { global $DB, $CFG, $OUTPUT, $PAGE, $SESSION; $pwresettime = isset($CFG->pwresettime) ? $CFG->pwresettime : 1800; $sql = "SELECT u.*, upr.token, upr.timerequested, upr.id as tokenid\n FROM {user} u\n JOIN {user_password_resets} upr ON upr.userid = u.id\n WHERE upr.token = ?"; $user = $DB->get_record_sql($sql, array($token)); $forgotpasswordurl = "{$CFG->httpswwwroot}/login/forgot_password.php"; if (empty($user) or $user->timerequested < time() - $pwresettime - DAYSECS) { // There is no valid reset request record - not even a recently expired one. // (suspicious) // Direct the user to the forgot password page to request a password reset. echo $OUTPUT->header(); notice(get_string('noresetrecord'), $forgotpasswordurl); die; // Never reached. } if ($user->timerequested < time() - $pwresettime) { // There is a reset record, but it's expired. // Direct the user to the forgot password page to request a password reset. $pwresetmins = floor($pwresettime / MINSECS); echo $OUTPUT->header(); notice(get_string('resetrecordexpired', '', $pwresetmins), $forgotpasswordurl); die; // Never reached. } if ($user->auth === 'nologin' or !is_enabled_auth($user->auth)) { // Bad luck - user is not able to login, do not let them set password. echo $OUTPUT->header(); print_error('forgotteninvalidurl'); die; // Never reached. } // Check this isn't guest user. if (isguestuser($user)) { print_error('cannotresetguestpwd'); } // Token is correct, and unexpired. $mform = new login_set_password_form(null, null, 'post', '', 'autocomplete="yes"'); $data = $mform->get_data(); if (empty($data)) { // User hasn't submitted form, they got here directly from email link. // Next, display the form. $setdata = new stdClass(); $setdata->username = $user->username; $setdata->username2 = $user->username; $setdata->token = $user->token; $mform->set_data($setdata); $PAGE->verify_https_required(); echo $OUTPUT->header(); echo $OUTPUT->box(get_string('setpasswordinstructions'), 'generalbox boxwidthnormal boxaligncenter'); $mform->display(); echo $OUTPUT->footer(); return; } else { // User has submitted form. // Delete this token so it can't be used again. $DB->delete_records('user_password_resets', array('id' => $user->tokenid)); $userauth = get_auth_plugin($user->auth); if (!$userauth->user_update_password($user, $data->password)) { print_error('errorpasswordupdate', 'auth'); } // Reset login lockout (if present) before a new password is set. login_unlock_account($user); // Clear any requirement to change passwords. unset_user_preference('auth_forcepasswordchange', $user); unset_user_preference('create_password', $user); if (!empty($user->lang)) { // Unset previous session language - use user preference instead. unset($SESSION->lang); } complete_user_login($user); // Triggers the login event. $urltogo = core_login_get_return_url(); unset($SESSION->wantsurl); redirect($urltogo, get_string('passwordset'), 1); } }
/** * Unlock user account and reset timers. * * @param stdClass $user */ function login_unlock_account($user) { unset_user_preference('login_lockout', $user); unset_user_preference('login_failed_count', $user); unset_user_preference('login_failed_last', $user); // Note: do not clear the lockout secret because user might click on the link repeatedly. }
// this internal scrip not used redirect($changeurl); } $mform = new login_change_password_form(); $mform->set_data(array('id' => $course->id)); $navlinks = array(); $navlinks[] = array('name' => $strparticipants, 'link' => "{$CFG->wwwroot}/user/index.php?id={$course->id}", 'type' => 'misc'); if ($mform->is_cancelled()) { redirect($CFG->wwwroot . '/user/view.php?id=' . $USER->id . '&course=' . $course->id); } else { if ($data = $mform->get_data()) { if (!$userauth->user_update_password($USER, $data->newpassword1)) { print_error('errorpasswordupdate', 'auth'); } // register success changing password unset_user_preference('auth_forcepasswordchange', $USER->id); $strpasswordchanged = get_string('passwordchanged'); add_to_log($course->id, 'user', 'change password', "view.php?id={$USER->id}&course={$course->id}", "{$USER->id}"); $fullname = fullname($USER, true); $PAGE->navbar->add($fullname, new moodle_url('/user/view.php', array('id' => $USER->id, 'course' => $course->id))); $PAGE->navbar->add($strpasswordchanged); $PAGE->set_title($strpasswordchanged); $PAGE->set_heading($COURSE->fullname); echo $OUTPUT->header(); if (empty($SESSION->wantsurl) or $SESSION->wantsurl == $CFG->httpswwwroot . '/login/change_password.php') { $returnto = "{$CFG->wwwroot}/user/view.php?id={$USER->id}&course={$id}"; } else { $returnto = $SESSION->wantsurl; } unset($SESSION->wantsurl); notice($strpasswordchanged, $returnto);