protected function disable_plugin() { $enabled = enrol_get_plugins(true); unset($enabled['meta']); $enabled = array_keys($enabled); set_config('enrol_plugins_enabled', implode(',', $enabled)); }
public function test_get_enrolment_plugins() { $this->resetAfterTest(true); $actual = tool_uploadcourse_helper::get_enrolment_plugins(); $this->assertSame(array_keys(enrol_get_plugins(false)), array_keys($actual)); // This should be identical as cached. $secondactual = tool_uploadcourse_helper::get_enrolment_plugins(); $this->assertEquals($actual, $secondactual); }
/** * Gets all of the enrolment plugins that are active for this course. * * @return array */ public function get_enrolment_plugins() { if ($this->_plugins === null) { $this->_plugins = enrol_get_plugins(true); } return $this->_plugins; }
/** * Test moodle_enrol_manual_enrol_users web service function * This test will: * 1- create a user (core call) * 2- enrol this user in the courses supporting enrolment * 3- unenrol this user (core call) * * @param webservice_rest_client|webservice_soap_client|webservice_xmlrpc_client $client the protocol test client */ private function moodle_enrol_manual_enrol_users($client) { global $DB, $CFG; require_once($CFG->dirroot . "/user/lib.php"); require_once($CFG->dirroot . "/user/profile/lib.php"); require_once($CFG->dirroot . "/lib/enrollib.php"); // Delete some previous test data if ($user = $DB->get_record('user', array('username' => 'veryimprobabletestusername2'))) { $DB->delete_records('user', array('id' => $user->id)); } if ($role = $DB->get_record('role', array('shortname' => 'role1thatshouldnotexist'))) { set_role_contextlevels($role->id, array(CONTEXT_COURSE)); delete_role($role->id); } // create a user $user = new stdClass(); $user->username = '******'; $user->password = '******'; $user->firstname = 'testfirstname2'; $user->lastname = 'testlastname2'; $user->email = '*****@*****.**'; $user->id = user_create_user($user); $roleid = create_role('role1thatshouldnotexist', 'role1thatshouldnotexist', ''); set_role_contextlevels($roleid, array(CONTEXT_COURSE)); $enrolments = array(); $courses = $DB->get_records('course'); foreach ($courses as $course) { if ($course->id > 1) { $enrolments[] = array('roleid' => $roleid, 'userid' => $user->id, 'courseid' => $course->id); $enrolledcourses[] = $course; } } // web service call $function = 'moodle_enrol_manual_enrol_users'; $wsparams = array('enrolments' => $enrolments); $enrolmentsresult = $client->call($function, $wsparams); // get instance that can unenrol $enrols = enrol_get_plugins(true); $enrolinstances = enrol_get_instances($course->id, true); $unenrolled = false; foreach ($enrolinstances as $instance) { if (!$unenrolled and $enrols[$instance->enrol]->allow_unenrol($instance)) { $unenrolinstance = $instance; $unenrolled = true; } } // test and unenrol the user $enrolledusercourses = enrol_get_users_courses($user->id); foreach ($enrolledcourses as $course) { // test $this->assertEqual(true, isset($enrolledusercourses[$course->id])); // unenrol the user $enrols[$unenrolinstance->enrol]->unenrol_user($unenrolinstance, $user->id, $roleid); } // delete user $DB->delete_records('user', array('id' => $user->id)); // delete the context level set_role_contextlevels($roleid, array(CONTEXT_COURSE)); // delete role delete_role($roleid); }
/** * This function will empty a course of user data. * It will retain the activities and the structure of the course. * * @param object $data an object containing all the settings including courseid (without magic quotes) * @return array status array of array component, item, error */ function reset_course_userdata($data) { global $CFG, $USER, $DB; require_once $CFG->libdir . '/gradelib.php'; require_once $CFG->libdir . '/completionlib.php'; require_once $CFG->dirroot . '/group/lib.php'; $data->courseid = $data->id; $context = get_context_instance(CONTEXT_COURSE, $data->courseid); // calculate the time shift of dates if (!empty($data->reset_start_date)) { // time part of course startdate should be zero $data->timeshift = $data->reset_start_date - usergetmidnight($data->reset_start_date_old); } else { $data->timeshift = 0; } // result array: component, item, error $status = array(); // start the resetting $componentstr = get_string('general'); // move the course start time if (!empty($data->reset_start_date) and $data->timeshift) { // change course start data $DB->set_field('course', 'startdate', $data->reset_start_date, array('id' => $data->courseid)); // update all course and group events - do not move activity events $updatesql = "UPDATE {event}\n SET timestart = timestart + ?\n WHERE courseid=? AND instance=0"; $DB->execute($updatesql, array($data->timeshift, $data->courseid)); $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false); } if (!empty($data->reset_logs)) { $DB->delete_records('log', array('course' => $data->courseid)); $status[] = array('component' => $componentstr, 'item' => get_string('deletelogs'), 'error' => false); } if (!empty($data->reset_events)) { $DB->delete_records('event', array('courseid' => $data->courseid)); $status[] = array('component' => $componentstr, 'item' => get_string('deleteevents', 'calendar'), 'error' => false); } if (!empty($data->reset_notes)) { require_once $CFG->dirroot . '/notes/lib.php'; note_delete_all($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('deletenotes', 'notes'), 'error' => false); } if (!empty($data->delete_blog_associations)) { require_once $CFG->dirroot . '/blog/lib.php'; blog_remove_associations_for_course($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('deleteblogassociations', 'blog'), 'error' => false); } if (!empty($data->reset_course_completion)) { // Delete course completion information $course = $DB->get_record('course', array('id' => $data->courseid)); $cc = new completion_info($course); $cc->delete_course_completion_data(); $status[] = array('component' => $componentstr, 'item' => get_string('deletecoursecompletiondata', 'completion'), 'error' => false); } $componentstr = get_string('roles'); if (!empty($data->reset_roles_overrides)) { $children = get_child_contexts($context); foreach ($children as $child) { $DB->delete_records('role_capabilities', array('contextid' => $child->id)); } $DB->delete_records('role_capabilities', array('contextid' => $context->id)); //force refresh for logged in users mark_context_dirty($context->path); $status[] = array('component' => $componentstr, 'item' => get_string('deletecourseoverrides', 'role'), 'error' => false); } if (!empty($data->reset_roles_local)) { $children = get_child_contexts($context); foreach ($children as $child) { role_unassign_all(array('contextid' => $child->id)); } //force refresh for logged in users mark_context_dirty($context->path); $status[] = array('component' => $componentstr, 'item' => get_string('deletelocalroles', 'role'), 'error' => false); } // First unenrol users - this cleans some of related user data too, such as forum subscriptions, tracking, etc. $data->unenrolled = array(); if (!empty($data->unenrol_users)) { $plugins = enrol_get_plugins(true); $instances = enrol_get_instances($data->courseid, true); foreach ($instances as $key => $instance) { if (!isset($plugins[$instance->enrol])) { unset($instances[$key]); continue; } if (!$plugins[$instance->enrol]->allow_unenrol($instance)) { unset($instances[$key]); } } $sqlempty = $DB->sql_empty(); foreach ($data->unenrol_users as $withroleid) { $sql = "SELECT DISTINCT ue.userid, ue.enrolid\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.roleid = :roleid AND ra.userid = ue.userid)"; $params = array('courseid' => $data->courseid, 'roleid' => $withroleid, 'courselevel' => CONTEXT_COURSE); $rs = $DB->get_recordset_sql($sql, $params); foreach ($rs as $ue) { if (!isset($instances[$ue->enrolid])) { continue; } $plugins[$instances[$ue->enrolid]->enrol]->unenrol_user($instances[$ue->enrolid], $ue->userid); $data->unenrolled[$ue->userid] = $ue->userid; } } } if (!empty($data->unenrolled)) { $status[] = array('component' => $componentstr, 'item' => get_string('unenrol', 'enrol') . ' (' . count($data->unenrolled) . ')', 'error' => false); } $componentstr = get_string('groups'); // remove all group members if (!empty($data->reset_groups_members)) { groups_delete_group_members($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('removegroupsmembers', 'group'), 'error' => false); } // remove all groups if (!empty($data->reset_groups_remove)) { groups_delete_groups($data->courseid, false); $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroups', 'group'), 'error' => false); } // remove all grouping members if (!empty($data->reset_groupings_members)) { groups_delete_groupings_groups($data->courseid, false); $status[] = array('component' => $componentstr, 'item' => get_string('removegroupingsmembers', 'group'), 'error' => false); } // remove all groupings if (!empty($data->reset_groupings_remove)) { groups_delete_groupings($data->courseid, false); $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroupings', 'group'), 'error' => false); } // Look in every instance of every module for data to delete $unsupported_mods = array(); if ($allmods = $DB->get_records('modules')) { foreach ($allmods as $mod) { $modname = $mod->name; if (!$DB->count_records($modname, array('course' => $data->courseid))) { continue; // skip mods with no instances } $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php'; $moddeleteuserdata = $modname . '_reset_userdata'; // Function to delete user data if (file_exists($modfile)) { include_once $modfile; if (function_exists($moddeleteuserdata)) { $modstatus = $moddeleteuserdata($data); if (is_array($modstatus)) { $status = array_merge($status, $modstatus); } else { debugging('Module ' . $modname . ' returned incorrect staus - must be an array!'); } } else { $unsupported_mods[] = $mod; } } else { debugging('Missing lib.php in ' . $modname . ' module!'); } } } // mention unsupported mods if (!empty($unsupported_mods)) { foreach ($unsupported_mods as $mod) { $status[] = array('component' => get_string('modulenameplural', $mod->name), 'item' => '', 'error' => get_string('resetnotimplemented')); } } $componentstr = get_string('gradebook', 'grades'); // reset gradebook if (!empty($data->reset_gradebook_items)) { remove_course_grades($data->courseid, false); grade_grab_course_grades($data->courseid); grade_regrade_final_grades($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('removeallcourseitems', 'grades'), 'error' => false); } else { if (!empty($data->reset_gradebook_grades)) { grade_course_reset($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('removeallcoursegrades', 'grades'), 'error' => false); } } // reset comments if (!empty($data->reset_comments)) { require_once $CFG->dirroot . '/comment/lib.php'; comment::reset_course_page_comments($context); } return $status; }
/** * Builds the XHTML to display the control * * @param string $data Unused * @param string $query * @return string */ public function output_html($data, $query = '') { global $CFG, $OUTPUT, $DB; // display strings $strup = get_string('up'); $strdown = get_string('down'); $strsettings = get_string('settings'); $strenable = get_string('enable'); $strdisable = get_string('disable'); $struninstall = get_string('uninstallplugin', 'admin'); $strusage = get_string('enrolusage', 'enrol'); $enrols_available = enrol_get_plugins(false); $active_enrols = enrol_get_plugins(true); $allenrols = array(); foreach ($active_enrols as $key => $enrol) { $allenrols[$key] = true; } foreach ($enrols_available as $key => $enrol) { $allenrols[$key] = true; } // now find all borked plugins and at least allow then to uninstall $borked = array(); $condidates = $DB->get_fieldset_sql("SELECT DISTINCT enrol FROM {enrol}"); foreach ($condidates as $candidate) { if (empty($allenrols[$candidate])) { $allenrols[$candidate] = true; } } $return = $OUTPUT->heading(get_string('actenrolshhdr', 'enrol'), 3, 'main', true); $return .= $OUTPUT->box_start('generalbox enrolsui'); $table = new html_table(); $table->head = array(get_string('name'), $strusage, $strenable, $strup . '/' . $strdown, $strsettings, $struninstall); $table->align = array('left', 'center', 'center', 'center', 'center', 'center'); $table->width = '90%'; $table->data = array(); // iterate through enrol plugins and add to the display table $updowncount = 1; $enrolcount = count($active_enrols); $url = new moodle_url('/admin/enrol.php', array('sesskey' => sesskey())); $printed = array(); foreach ($allenrols as $enrol => $unused) { if (get_string_manager()->string_exists('pluginname', 'enrol_' . $enrol)) { $name = get_string('pluginname', 'enrol_' . $enrol); } else { $name = $enrol; } //usage $ci = $DB->count_records('enrol', array('enrol' => $enrol)); $cp = $DB->count_records_select('user_enrolments', "enrolid IN (SELECT id FROM {enrol} WHERE enrol = ?)", array($enrol)); $usage = "{$ci} / {$cp}"; // hide/show link if (isset($active_enrols[$enrol])) { $aurl = new moodle_url($url, array('action' => 'disable', 'enrol' => $enrol)); $hideshow = "<a href=\"{$aurl}\">"; $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/hide') . "\" class=\"icon\" alt=\"{$strdisable}\" /></a>"; $enabled = true; $displayname = "<span>{$name}</span>"; } else { if (isset($enrols_available[$enrol])) { $aurl = new moodle_url($url, array('action' => 'enable', 'enrol' => $enrol)); $hideshow = "<a href=\"{$aurl}\">"; $hideshow .= "<img src=\"" . $OUTPUT->pix_url('i/show') . "\" class=\"icon\" alt=\"{$strenable}\" /></a>"; $enabled = false; $displayname = "<span class=\"dimmed_text\">{$name}</span>"; } else { $hideshow = ''; $enabled = false; $displayname = '<span class="notifyproblem">' . $name . '</span>'; } } // up/down link (only if enrol is enabled) $updown = ''; if ($enabled) { if ($updowncount > 1) { $aurl = new moodle_url($url, array('action' => 'up', 'enrol' => $enrol)); $updown .= "<a href=\"{$aurl}\">"; $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"{$strup}\" /></a> "; } else { $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" /> "; } if ($updowncount < $enrolcount) { $aurl = new moodle_url($url, array('action' => 'down', 'enrol' => $enrol)); $updown .= "<a href=\"{$aurl}\">"; $updown .= "<img src=\"" . $OUTPUT->pix_url('t/down') . "\" alt=\"{$strdown}\" /></a>"; } else { $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"icon\" alt=\"\" />"; } ++$updowncount; } // settings link if (isset($active_enrols[$enrol]) or file_exists($CFG->dirroot . '/enrol/' . $enrol . '/settings.php')) { $surl = new moodle_url('/admin/settings.php', array('section' => 'enrolsettings' . $enrol)); $settings = "<a href=\"{$surl}\">{$strsettings}</a>"; } else { $settings = ''; } // uninstall $aurl = new moodle_url($url, array('action' => 'uninstall', 'enrol' => $enrol)); $uninstall = "<a href=\"{$aurl}\">{$struninstall}</a>"; // add a row to the table $table->data[] = array($displayname, $usage, $hideshow, $updown, $settings, $uninstall); $printed[$enrol] = true; } $return .= html_writer::table($table); $return .= get_string('configenrolplugins', 'enrol') . '<br />' . get_string('tablenosave', 'admin'); $return .= $OUTPUT->box_end(); return highlight($query, $return); }
/** * 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"); }
function display_savenew() { // action_savenew() global $USER, $CFG, $DB; $clsid = cm_get_param('clsid', 0); $class = new pmclass($clsid); $now = time(); if (!$class->is_enrollable()) { print_error('notenrollable', 'enrol'); // TBD } // check if class is full if (!empty($class->maxstudents) && student::count_enroled($class->id) >= $class->maxstudents) { $form = $this->create_waitlistform($classid); $form->display(); return; } // call the Moodle enrolment plugin if attached to a Moodle course, and // it's not the elis plugin //todo: check Moodle enrolment plugins here $cuserid = cm_get_crlmuserid($USER->id); $sturecord = array(); $sturecord['classid'] = $class->id; $sturecord['userid'] = $cuserid; // Set the enrolment time from class startdate if it's in the future or just set // current time if class has an associated Moodle course that has already started $enrolmenttime = $class->startdate; if ($moodlecourseid = moodle_get_course($clsid)) { if ($startdate = $DB->get_field('course', 'startdate', array('id' => $moodlecourseid))) { $enrolmenttime = $startdate < $now ? $now : $class->startdate; } } $sturecord['enrolmenttime'] = max($now, $enrolmenttime); $sturecord['completetime'] = 0; $newstu = new student($sturecord); $courseid = $class->get_moodle_course_id(); if ($courseid) { $course = $DB->get_record('course', array('id' => $courseid)); // check that the elis plugin allows for enrolments from the course // catalog -- if not, see if there are other plugins that allow // self-enrolment. $plugin = enrol_get_plugin('elis'); $enrol = $plugin->get_or_create_instance($course); if (!$enrol->{enrol_elis_plugin::ENROL_FROM_COURSE_CATALOG_DB}) { // get course enrolment plugins, and see if any of them allow self-enrolment $enrols = enrol_get_plugins(true); $enrolinstances = enrol_get_instances($course->id, true); foreach ($enrolinstances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } $form = $enrols[$instance->enrol]->enrol_page_hook($instance); if ($form) { // at least one plugin allows self-enrolment -- send // the user to the course enrolment page, and prevent // automatic enrolment $newstu->no_moodle_enrol = true; $newstu->save(); redirect("{$CFG->wwwroot}/course/enrol.php?id={$courseid}"); return; } } } } $newstu->save(); $tmppage = new coursecatalogpage(array('action' => 'default')); redirect($tmppage->url); }
/** * Create enrolment instances. * * This has to be called after creation of roles * and before adding of role assignments. * * @param mixed $data * @return void */ public function process_enrol($data) { global $DB; $data = (object)$data; $oldid = $data->id; // We'll need this later $restoretype = plugin_supports('enrol', $data->enrol, ENROL_RESTORE_TYPE, null); if ($restoretype !== ENROL_RESTORE_EXACT and $restoretype !== ENROL_RESTORE_NOUSERS) { // TODO: add complex restore support via custom class debugging("Skipping '{$data->enrol}' enrolment plugin. Will be implemented before 2.0 release", DEBUG_DEVELOPER); $this->set_mapping('enrol', $oldid, 0); return; } // Perform various checks to decide what to do with the enrol plugin if (!array_key_exists($data->enrol, enrol_get_plugins(false))) { // TODO: decide if we want to switch to manual enrol - we need UI for this debugging("Enrol plugin data can not be restored because it is not installed"); $this->set_mapping('enrol', $oldid, 0); return; } if (!enrol_is_enabled($data->enrol)) { // TODO: decide if we want to switch to manual enrol - we need UI for this debugging("Enrol plugin data can not be restored because it is not enabled"); $this->set_mapping('enrol', $oldid, 0); return; } // map standard fields - plugin has to process custom fields from own restore class $data->roleid = $this->get_mappingid('role', $data->roleid); //TODO: should we move the enrol start and end date here? // always add instance, if the course does not support multiple instances it just returns NULL $enrol = enrol_get_plugin($data->enrol); $courserec = $DB->get_record('course', array('id' => $this->get_courseid())); // Requires object, uses only id!! if ($newitemid = $enrol->add_instance($courserec, (array)$data)) { // ok } else { if ($instances = $DB->get_records('enrol', array('courseid'=>$courserec->id, 'enrol'=>$data->enrol))) { // most probably plugin that supports only one instance $newitemid = key($instances); } else { debugging('Can not create new enrol instance or reuse existing'); $newitemid = 0; } } if ($restoretype === ENROL_RESTORE_NOUSERS) { // plugin requests to prevent restore of any users $newitemid = 0; } $this->set_mapping('enrol', $oldid, $newitemid); }
/** * Cron functions. * * @package core * @subpackage admin * @copyright 1999 onwards Martin Dougiamas http://dougiamas.com * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ 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)) { $CFG->debug = DEBUG_DEVELOPER; $CFG->debugdisplay = true; } set_time_limit(0); $starttime = microtime(); /// increase memory limit raise_memory_limit(MEMORY_EXTRA); /// emulate normal session cron_setup_user(); /// Start output log $timenow = time(); mtrace("Server Time: " . date('r', $timenow) . "\n\n"); /// Session gc mtrace("Cleaning up stale sessions"); session_gc(); /// 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} ...", ''); $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 . '....', ''); 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'); //now do plagiarism checks require_once $CFG->libdir . '/plagiarismlib.php'; plagiarism_cron(); mtrace("Starting quiz reports"); if ($reports = $DB->get_records_select('quiz_report', "cron > 0 AND ((? - lastcron) > cron)", array($timenow))) { foreach ($reports as $report) { $cronfile = "{$CFG->dirroot}/mod/quiz/report/{$report->name}/cron.php"; if (file_exists($cronfile)) { include_once $cronfile; $cron_function = 'quiz_report_' . $report->name . "_cron"; if (function_exists($cron_function)) { mtrace("Processing quiz report cron function {$cron_function} ...", ''); $pre_dbqueries = null; $pre_dbqueries = $DB->perf_get_queries(); $pre_time = microtime(1); if ($cron_function()) { $DB->set_field('quiz_report', "lastcron", $timenow, array("id" => $report->id)); } if (isset($pre_dbqueries)) { mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries"); mtrace("... used " . (microtime(1) - $pre_time) . " seconds"); } mtrace("done."); } } } } mtrace("Finished quiz reports"); mtrace('Starting admin reports'); // Admin reports do not have a database table that lists them. Instead a // report includes cron.php with function report_reportname_cron() if it wishes // to be cronned. It is up to cron.php to handle e.g. if it only needs to // actually do anything occasionally. $reports = get_plugin_list('report'); foreach ($reports as $report => $reportdir) { $cronfile = $reportdir . '/cron.php'; if (file_exists($cronfile)) { require_once $cronfile; $cronfunction = 'report_' . $report . '_cron'; mtrace('Processing cron function for ' . $report . '...', ''); $pre_dbqueries = null; $pre_dbqueries = $DB->perf_get_queries(); $pre_time = microtime(true); $cronfunction(); if (isset($pre_dbqueries)) { mtrace("... used " . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries"); mtrace("... used " . round(microtime(true) - $pre_time, 2) . " seconds"); } mtrace('done.'); } } mtrace('Finished admin reports'); mtrace('Starting main gradebook job ...'); grade_cron(); mtrace('done.'); mtrace('Starting processing the event queue...'); events_cron(); mtrace('done.'); if ($CFG->enablecompletion) { // Completion cron mtrace('Starting the completion cron...'); require_once $CFG->libdir . '/completion/cron.php'; completion_cron(); mtrace('done'); } if ($CFG->enableportfolios) { // Portfolio cron mtrace('Starting the portfolio cron...'); require_once $CFG->libdir . '/portfoliolib.php'; portfolio_cron(); mtrace('done'); } /// Run all 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. srand((double) microtime() * 10000000); $random100 = rand(0, 100); if ($random100 < 20) { // Approximately 20% of the time. mtrace("Running clean-up tasks..."); /// Delete users who haven't confirmed within required period if (!empty($CFG->deleteunconfirmed)) { $cuttime = $timenow - $CFG->deleteunconfirmed * 3600; $rs = $DB->get_recordset_sql("SELECT id, firstname, lastname\n FROM {user}\n WHERE confirmed = 0 AND firstaccess > 0\n AND firstaccess < ?", array($cuttime)); foreach ($rs as $user) { if ($DB->delete_records('user', array('id' => $user->id))) { mtrace("Deleted unconfirmed user for " . fullname($user, true) . " ({$user->id})"); } } $rs->close(); } flush(); /// 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 id, username\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 (delete_user($user)) { mtrace("Deleted not fully setup user {$user->username} ({$user->id})"); } } $rs->close(); } flush(); /// 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; if ($DB->delete_records_select("log", "time < ?", array($loglifetime))) { mtrace("Deleted old log records"); } } flush(); // Delete old backup_controllers and logs if (!empty($CFG->loglifetime)) { // value in days $loglifetime = $timenow - $CFG->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"); } flush(); /// 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 if ($DB->delete_records_select('cache_text', "timemodified < ?", array($cachelifetime))) { mtrace("Deleted old cache_text records"); } } flush(); if (!empty($CFG->notifyloginfailures)) { notify_login_failures(); mtrace('Notified login failured'); } flush(); // // generate new password emails for users // mtrace('checking for create_password'); if ($DB->count_records('user_preferences', array('name' => 'create_password', 'value' => '1'))) { mtrace('creating passwords for new users'); $newusers = $DB->get_records_sql("SELECT u.id as id, u.email, u.firstname,\n u.lastname, u.username,\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 !='' "); foreach ($newusers as $newuserid => $newuser) { // email user if (setnew_password_and_mail($newuser)) { // remove user pref $DB->delete_records('user_preferences', array('id' => $newuser->prefid)); } else { trigger_error("Could not create and mail new user password!"); } } } if (!empty($CFG->usetags)) { require_once $CFG->dirroot . '/tag/lib.php'; tag_cron(); mtrace('Executed tag cron'); } // Accesslib stuff cleanup_contexts(); mtrace('Cleaned up contexts'); gc_cache_flags(); mtrace('Cleaned cache flags'); // If you suspect that the context paths are somehow corrupt // replace the line below with: build_context_path(true); build_context_path(); mtrace('Built context paths'); 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("Finished clean-up tasks..."); } // End of occasional clean-up tasks // Run automated backups if required. 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 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..."); 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); } 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}..."); $enrol->cron(); $enrol->set_config('lastcron', time()); } 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 gradebook import/export/report cron if ($gradeimports = get_plugin_list('gradeimport')) { foreach ($gradeimports as $gradeimport => $plugindir) { if (file_exists($plugindir . '/lib.php')) { require_once $plugindir . '/lib.php'; $cron_function = 'grade_import_' . $gradeimport . '_cron'; if (function_exists($cron_function)) { mtrace("Processing gradebook import function {$cron_function} ...", ''); $cron_function(); } } } } if ($gradeexports = get_plugin_list('gradeexport')) { foreach ($gradeexports as $gradeexport => $plugindir) { if (file_exists($plugindir . '/lib.php')) { require_once $plugindir . '/lib.php'; $cron_function = 'grade_export_' . $gradeexport . '_cron'; if (function_exists($cron_function)) { mtrace("Processing gradebook export function {$cron_function} ...", ''); $cron_function(); } } } } if ($gradereports = get_plugin_list('gradereport')) { foreach ($gradereports as $gradereport => $plugindir) { if (file_exists($plugindir . '/lib.php')) { require_once $plugindir . '/lib.php'; $cron_function = 'grade_report_' . $gradereport . '_cron'; if (function_exists($cron_function)) { mtrace("Processing gradebook report function {$cron_function} ...", ''); $cron_function(); } } } } // Run external blog cron if needed if ($CFG->useexternalblogs) { require_once $CFG->dirroot . '/blog/lib.php'; mtrace("Fetching external blog entries...", ''); $sql = "timefetched < ? OR timefetched = 0"; $externalblogs = $DB->get_records_select('blog_external', $sql, array(mktime() - $CFG->externalblogcrontime)); foreach ($externalblogs as $eb) { blog_sync_external_entries($eb); } } // Run blog associations cleanup if ($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...", ''); $DB->delete_records_select('blog_association', 'contextid NOT IN (SELECT id FROM {context})'); } //Run registration updated cron mtrace(get_string('siteupdatesstart', 'hub')); require_once $CFG->dirroot . '/admin/registration/lib.php'; $registrationmanager = new registration_manager(); $registrationmanager->cron(); mtrace(get_string('siteupdatesend', 'hub')); // cleanup file trash $fs = get_file_storage(); $fs->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...", ''); $DB->delete_records_select('external_tokens', 'lastaccess < :onedayago AND tokentype = :tokentype', array('onedayago' => time() - DAYSECS, 'tokentype' => EXTERNAL_TOKEN_EMBEDDED)); mtrace('done.'); // run any customized cronjobs, if any if ($locals = get_plugin_list('local')) { mtrace('Processing customized cron scripts ...', ''); foreach ($locals as $local => $localdir) { if (file_exists("{$localdir}/cron.php")) { include "{$localdir}/cron.php"; } } mtrace('done.'); } mtrace("Cron script completed correctly"); $difftime = microtime_diff($starttime, microtime()); mtrace("Execution took " . $difftime . " seconds"); }
// Everybody is enrolled on the frontpage if ($course->id == SITEID) { redirect("{$CFG->wwwroot}/"); } if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', context_course::instance($course->id))) { print_error('coursehidden'); } $PAGE->set_course($course); $PAGE->set_pagelayout('course'); $PAGE->set_url('/enrol/index.php', array('id' => $course->id)); // do not allow enrols when in login-as session if (\core\session\manager::is_loggedinas() and $USER->loginascontext->contextlevel == CONTEXT_COURSE) { print_error('loginasnoenrol', '', $CFG->wwwroot . '/course/view.php?id=' . $USER->loginascontext->instanceid); } // get all enrol forms available in this course $enrols = enrol_get_plugins(true); $enrolinstances = enrol_get_instances($course->id, true); $forms = array(); foreach ($enrolinstances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } $form = $enrols[$instance->enrol]->enrol_page_hook($instance); if ($form) { $forms[$instance->id] = $form; } } // Check if user already enrolled if (is_enrolled($context, $USER, '', true)) { if (!empty($SESSION->wantsurl)) { $destination = $SESSION->wantsurl;
/** * Returns true if the user is able to access the course. * * This function is in no way, shape, or form a substitute for require_login. * It should only be used in circumstances where it is not possible to call require_login * such as the navigation. * * This function checks many of the methods of access to a course such as the view * capability, enrollments, and guest access. It also makes use of the cache * generated by require_login for guest access. * * The flags within the $USER object that are used here should NEVER be used outside * of this function can_access_course and require_login. Doing so WILL break future * versions. * * @global moodle_database $DB * @param stdClass $context * @param stdClass|null $user * @param string $withcapability Check for this capability as well. * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @param boolean $trustcache If set to false guest access will always be checked * against the enrolment plugins from the course, rather * than the cache generated by require_login. * @return boolean Returns true if the user is able to access the course */ function can_access_course($context, $user = null, $withcapability = '', $onlyactive = false, $trustcache = true) { global $DB, $USER; $coursecontext = get_course_context($context); $courseid = $coursecontext->instanceid; // First check the obvious, is the user viewing or is the user enrolled. if (is_viewing($coursecontext, $user, $withcapability) || is_enrolled($coursecontext, $user, $withcapability, $onlyactive)) { // How easy was that! return true; } $access = false; if (!isset($USER->enrol)) { // Cache hasn't been generated yet so we can't trust it $trustcache = false; /** * These flags within the $USER object should NEVER be used outside of this * function can_access_course and the function require_login. * Doing so WILL break future versions!!!! */ $USER->enrol = array(); $USER->enrol['enrolled'] = array(); $USER->enrol['tempguest'] = array(); } // If we don't trust the cache we need to check with the courses enrolment // plugin instances to see if the user can access the course as a guest. if (!$trustcache) { // Ok, off to the database we go! $instances = $DB->get_records('enrol', array('courseid' => $courseid, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false) { // Never use me anywhere but here and require_login $USER->enrol['tempguest'][$courseid] = $until; $access = true; break; } } } // If we don't already have access (from above) check the cache and see whether // there is record of it in there. if (!$access && isset($USER->enrol['tempguest'][$courseid])) { // Never use me anywhere but here and require_login if ($USER->enrol['tempguest'][$courseid] == 0) { $access = true; } else { if ($USER->enrol['tempguest'][$courseid] > time()) { $access = true; } else { //expired unset($USER->enrol['tempguest'][$courseid]); } } } return $access; }
/** * Do the job. * Throw exceptions on errors (the job will be retried). */ public function execute() { global $CFG, $DB; $timenow = time(); // 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..."); 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); } // 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}..."); $enrol->cron(); $enrol->set_config('lastcron', time()); } // Run all cron jobs for each module. mtrace("Starting activity modules"); 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; $cronfunction = $mod->name . "_cron"; if (function_exists($cronfunction)) { mtrace("Processing module function {$cronfunction} ...\n", ''); $predbqueries = null; $predbqueries = $DB->perf_get_queries(); $pretime = microtime(1); if ($cronfunction()) { $DB->set_field("modules", "lastcron", $timenow, array("id" => $mod->id)); } if (isset($predbqueries)) { mtrace("... used " . ($DB->perf_get_queries() - $predbqueries) . " dbqueries"); mtrace("... used " . (microtime(1) - $pretime) . " seconds"); } // Reset possible changes by modules to time_limit. MDL-11597. \core_php_time_limit::raise(); mtrace("done."); } } } } 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 . '....', ''); if ($blockobj->cron()) { $DB->set_field('block', 'lastcron', $timenow, array('id' => $block->id)); } // Reset possible changes by blocks to time_limit. MDL-11597. \core_php_time_limit::raise(); mtrace('done.'); } } } } mtrace('Finished blocks'); mtrace('Starting admin reports'); cron_execute_plugin_type('report'); mtrace('Finished admin reports'); 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'); // 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'); cron_execute_plugin_type('local', 'local plugins'); }
/** * Duplicate a course * * @param int $courseid * @param string $fullname Duplicated course fullname * @param int $newcourse Destination course * @param array $options List of backup options * @return stdClass New course info */ function local_ltiprovider_duplicate_course($courseid, $newcourse, $visible = 1, $options = array(), $useridcreating = null, $context) { global $CFG, $USER, $DB; require_once $CFG->dirroot . '/backup/util/includes/backup_includes.php'; require_once $CFG->dirroot . '/backup/util/includes/restore_includes.php'; if (empty($USER)) { // Emulate session. cron_setup_user(); } // Context validation. if (!($course = $DB->get_record('course', array('id' => $courseid)))) { throw new moodle_exception('invalidcourseid', 'error'); } $removeoptions = array(); $removeoptions['keep_roles_and_enrolments'] = true; $removeoptions['keep_groups_and_groupings'] = true; remove_course_contents($newcourse->id, false, $removeoptions); $backupdefaults = array('activities' => 1, 'blocks' => 1, 'filters' => 1, 'users' => 0, 'role_assignments' => 0, 'comments' => 0, 'userscompletion' => 0, 'logs' => 0, 'grade_histories' => 0); $backupsettings = array(); // Check for backup and restore options. if (!empty($options)) { foreach ($options as $option) { // Strict check for a correct value (allways 1 or 0, true or false). $value = clean_param($option['value'], PARAM_INT); if ($value !== 0 and $value !== 1) { throw new moodle_exception('invalidextparam', 'webservice', '', $option['name']); } if (!isset($backupdefaults[$option['name']])) { throw new moodle_exception('invalidextparam', 'webservice', '', $option['name']); } $backupsettings[$option['name']] = $value; } } // Backup the course. $admin = get_admin(); $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_SAMESITE, $admin->id); foreach ($backupsettings as $name => $value) { $bc->get_plan()->get_setting($name)->set_value($value); } $backupid = $bc->get_backupid(); $backupbasepath = $bc->get_plan()->get_basepath(); $bc->execute_plan(); $results = $bc->get_results(); $file = $results['backup_destination']; $bc->destroy(); // Restore the backup immediately. // Check if we need to unzip the file because the backup temp dir does not contains backup files. if (!file_exists($backupbasepath . "/moodle_backup.xml")) { $file->extract_to_pathname(get_file_packer(), $backupbasepath); } $rc = new restore_controller($backupid, $newcourse->id, backup::INTERACTIVE_NO, backup::MODE_SAMESITE, $admin->id, backup::TARGET_CURRENT_DELETING); foreach ($backupsettings as $name => $value) { $setting = $rc->get_plan()->get_setting($name); if ($setting->get_status() == backup_setting::NOT_LOCKED) { $setting->set_value($value); } } if (!$rc->execute_precheck()) { $precheckresults = $rc->get_precheck_results(); if (is_array($precheckresults) && !empty($precheckresults['errors'])) { if (empty($CFG->keeptempdirectoriesonbackup)) { fulldelete($backupbasepath); } $errorinfo = ''; foreach ($precheckresults['errors'] as $error) { $errorinfo .= $error; } if (array_key_exists('warnings', $precheckresults)) { foreach ($precheckresults['warnings'] as $warning) { $errorinfo .= $warning; } } throw new moodle_exception('backupprecheckerrors', 'webservice', '', $errorinfo); } } $rc->execute_plan(); $rc->destroy(); $course = $DB->get_record('course', array('id' => $newcourse->id), '*', MUST_EXIST); $course->visible = $visible; $course->fullname = $newcourse->fullname; $course->shortname = $newcourse->shortname; $course->idnumber = $newcourse->idnumber; // Set shortname and fullname back. $DB->update_record('course', $course); if (empty($CFG->keeptempdirectoriesonbackup)) { fulldelete($backupbasepath); } // Delete the course backup file created by this WebService. Originally located in the course backups area. $file->delete(); // We have to unenroll all the user except the one that create the course. if (get_config('local_ltiprovider', 'duplicatecourseswithoutusers') and $useridcreating) { require_once $CFG->dirroot . '/group/lib.php'; // Previous to unenrol users, we assign some type of activities to the user that created the course. if ($user = $DB->get_record('user', array('id' => $useridcreating))) { if ($databases = $DB->get_records('data', array('course' => $course->id))) { foreach ($databases as $data) { $DB->execute("UPDATE {data_records} SET userid = ? WHERE dataid = ?", array($user->id, $data->id)); } } if ($glossaries = $DB->get_records('glossary', array('course' => $course->id))) { foreach ($glossaries as $glossary) { $DB->execute("UPDATE {glossary_entries} SET userid = ? WHERE glossaryid = ?", array($user->id, $glossary->id)); } } // Same for questions. $newcoursecontextid = context_course::instance($course->id); if ($qcategories = $DB->get_records('question_categories', array('contextid' => $newcoursecontextid->id))) { foreach ($qcategories as $qcategory) { $DB->execute("UPDATE {question} SET createdby = ?, modifiedby = ? WHERE category = ?", array($user->id, $user->id, $qcategory->id)); } } // Enrol the user. if ($tool = $DB->get_record('local_ltiprovider', array('contextid' => $newcoursecontextid->id))) { $roles = explode(',', strtolower($context->info['roles'])); local_ltiprovider_enrol_user($tool, $user, $roles, true); } // Now, we unenrol all the users except the one who created the course. $plugins = enrol_get_plugins(true); $instances = enrol_get_instances($course->id, true); foreach ($instances as $key => $instance) { if (!isset($plugins[$instance->enrol])) { unset($instances[$key]); continue; } } $sql = "SELECT ue.*\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)"; $params = array('courseid' => $course->id, 'courselevel' => CONTEXT_COURSE); $rs = $DB->get_recordset_sql($sql, $params); foreach ($rs as $ue) { if ($ue->userid == $user->id) { continue; } if (!isset($instances[$ue->enrolid])) { continue; } $instance = $instances[$ue->enrolid]; $plugin = $plugins[$instance->enrol]; if (!$plugin->allow_unenrol($instance) and !$plugin->allow_unenrol_user($instance, $ue)) { continue; } $plugin->unenrol_user($instance, $ue->userid); } $rs->close(); groups_delete_group_members($course->id); groups_delete_groups($course->id, false); groups_delete_groupings_groups($course->id, false); groups_delete_groupings($course->id, false); } } return $course; }
/** * generate list of course tools * * @author Guy Thomas * @date 2014-04-23 * @return string */ public static function appendices() { global $CFG, $COURSE, $PAGE, $OUTPUT; $links = array(); $localplugins = core_component::get_plugin_list('local'); $coursecontext = context_course::instance($COURSE->id); // Turn editing on. $iconsrc = $OUTPUT->pix_url('icon', 'label'); $editcourseicon = '<img class="svg-icon" alt="" title="" src="' . $iconsrc . '">'; $url = new moodle_url('/course/view.php', ['id' => $COURSE->id, 'sesskey' => sesskey()]); if ($PAGE->user_is_editing()) { $url->param('edit', 'off'); $editstring = get_string('turneditingoff'); } else { $url->param('edit', 'on'); $editstring = get_string('editcoursecontent', 'theme_snap'); } $links[] = array('link' => $url, 'title' => $editcourseicon . $editstring, 'capability' => 'moodle/course:update'); // Course settings. $settingsicon = '<svg viewBox="0 0 100 100" class="svg-icon"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-settings"></use></svg>'; $links[] = array('link' => 'course/edit.php?id=' . $COURSE->id, 'title' => $settingsicon . get_string('editcoursesettings', 'theme_snap'), 'capability' => 'moodle/course:update'); // Participants. $participanticon = '<svg viewBox="0 0 100 100" class="svg-icon"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-participants"></use></svg>'; $links[] = array('link' => 'user/index.php?id=' . $COURSE->id . '&mode=1', 'title' => $participanticon . get_string('participants'), 'capability' => 'moodle/course:viewparticipants'); // Gradebook. $gradebookicon = '<svg viewBox="0 0 100 100" class="svg-icon"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-gradbook"></use></svg>'; if (self::gradebook_accessible($coursecontext)) { // Gradebook. $links[] = array('link' => 'grade/index.php?id=' . $COURSE->id, 'title' => $gradebookicon . get_string('gradebook', 'grades')); } // Only show if joule grader is installed. if (array_key_exists('joulegrader', $localplugins)) { if (has_capability('local/joulegrader:grade', $coursecontext) || has_capability('local/joulegrader:view', $coursecontext)) { $links[] = array('link' => 'local/joulegrader/view.php?courseid=' . $COURSE->id, 'title' => $gradebookicon . get_string('pluginname', 'local_joulegrader')); } } // Only show Norton grader if installed. if (array_key_exists('nortongrader', $localplugins)) { if (has_capability('local/nortongrader:grade', $coursecontext) || has_capability('local/nortongrader:view', $coursecontext)) { $links[] = array('link' => $CFG->wwwroot . '/local/nortongrader/view.php?courseid=' . $COURSE->id, 'title' => $gradebookicon . get_string('pluginname', 'local_nortongrader')); } } // Only show core outcomes if enabled. $outcomesicon = '<svg viewBox="0 0 100 100" class="svg-icon"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-outcomes"></use></svg>'; if (!empty($CFG->core_outcome_enable) && has_capability('moodle/grade:edit', $coursecontext)) { $links[] = array('link' => 'outcome/course.php?contextid=' . $coursecontext->id, 'title' => $outcomesicon . get_string('outcomes', 'outcome')); } else { if (!empty($CFG->core_outcome_enable) && !is_guest($coursecontext)) { $outcomesets = new \core_outcome\model\outcome_set_repository(); if ($outcomesets->course_has_any_outcome_sets($COURSE->id)) { $links[] = array('link' => 'outcome/course.php?contextid=' . $coursecontext->id . '&action=report_course_user_performance_table', 'title' => $participanticon . get_string('report:course_user_performance_table', 'outcome')); } } } $badgesicon = '<svg viewBox="0 0 100 100" class="svg-icon"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-badges"></use></svg>'; // Course badges. if (!empty($CFG->enablebadges) && !empty($CFG->badges_allowcoursebadges)) { // Match capabilities used by badges subsystem. $studentcaps = array('moodle/badges:earnbadge', 'moodle/badges:viewbadges'); $teachercaps = array('moodle/badges:viewawarded', 'moodle/badges:createbadge', 'moodle/badges:awardbadge', 'moodle/badges:configuremessages', 'moodle/badges:configuredetails', 'moodle/badges:deletebadge'); // Show link for students. if (!is_guest($coursecontext) && has_any_capability($studentcaps, $coursecontext)) { $links[] = array('link' => 'badges/view.php?type=' . BADGE_TYPE_COURSE . '&id=' . $COURSE->id, 'title' => $badgesicon . get_string('badgesview', 'badges'), 'capability' => '!moodle/course:update'); } // Show link for trachers / admin staff. if (!is_guest($coursecontext) && has_any_capability($teachercaps, $coursecontext)) { $links[] = array('link' => 'badges/index.php?type=' . BADGE_TYPE_COURSE . '&id=' . $COURSE->id, 'title' => $badgesicon . get_string('managebadges', 'badges')); } } // Only show Joule reports if installed. $reportsicon = '<svg viewBox="0 0 100 100" class="svg-icon"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-reports"></use></svg>'; if (array_key_exists('reports', core_component::get_plugin_list('block'))) { if (has_capability('block/reports:viewown', $coursecontext, null, false) || has_capability('block/reports:view', $coursecontext)) { $links[] = array('link' => $CFG->wwwroot . '/blocks/reports/view.php?action=dashboard&courseid=' . $COURSE->id, 'title' => $reportsicon . get_string('joulereports', 'block_reports')); } } // Personalised Learning Designer. $pldicon = '<svg viewBox="0 0 100 100" class="svg-icon"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-pld"></use></svg>'; $pldname = get_string('pld', 'theme_snap'); $links[] = array('link' => 'local/pld/view.php?courseid=' . $COURSE->id, 'title' => $pldicon . $pldname, 'capability' => 'moodle/course:update'); // Course enrolment link. $plugins = enrol_get_plugins(true); $instances = enrol_get_instances($COURSE->id, true); $selfenrol = false; foreach ($instances as $instance) { // Need to check enrolment methods for self enrol. if ($instance->enrol === 'self') { $plugin = $plugins[$instance->enrol]; if (is_enrolled($coursecontext)) { // Prepare unenrolment link. $enrolurl = $plugin->get_unenrolself_link($instance); if ($enrolurl) { $selfenrol = true; $enrolstr = get_string('unenrolme', 'theme_snap'); break; } } else { if ($plugin->show_enrolme_link($instance)) { // Prepare enrolment link. $selfenrol = true; $enrolurl = new moodle_url('/enrol/index.php', array('id' => $COURSE->id)); $enrolstr = get_string('enrolme', 'core_enrol'); break; } } } } if ($selfenrol) { $enrolicon = '<svg viewBox="0 0 100 100" class="svg-icon"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#coursetools-settings"></use></svg>'; $links[] = array('link' => $enrolurl, 'title' => $enrolicon . $enrolstr); } $toolssvg = self::inline_svg('tools.svg'); // Output course tools. $coursetools = get_string('coursetools', 'theme_snap'); $o = "<h2>{$coursetools}</h2>"; $o .= "<div class='row'><div class='col-xs-4'>{$toolssvg}</div><div class='col-xs-8'><div id='coursetools-list'>" . self::render_appendices($links) . "</div></div></div><hr>"; return $o; }
function action($action) { $enabled = enrol_get_plugins(true); $all = enrol_get_plugins(false); $syscontext = context_system::instance(); switch ($action) { case 'enable': if (!isset($all[$this->plugin])) { break; } $enabled = array_keys($enabled); $enabled[] = $this->plugin; set_config('enrol_plugins_enabled', implode(',', $enabled)); // Resets all enrol caches. $syscontext->mark_dirty(); break; case 'disable': unset($enabled[$this->plugin]); set_config('enrol_plugins_enabled', implode(',', array_keys($enabled))); $syscontext->mark_dirty(); // resets all enrol caches break; } return 0; }
/** * Function that will contain all the code to be executed. */ protected function define_execution() { global $DB; $plugins = enrol_get_plugins(true); $enrols = $DB->get_records('enrol', array('courseid' => $this->task->get_courseid())); // Allow each enrol plugin to add annotations. foreach ($enrols as $enrol) { if (isset($plugins[$enrol->enrol])) { $plugins[$enrol->enrol]->backup_annotate_custom_fields($this, $enrol); } } }
/** * Gets all of the enrolment plugins that are active for this course. * * @param bool $onlyenabled return only enabled enrol plugins * @return array */ public function get_enrolment_plugins($onlyenabled = true) { if ($this->_plugins === null) { $this->_plugins = enrol_get_plugins(true); } if ($onlyenabled) { return $this->_plugins; } if ($this->_allplugins === null) { // Make sure we have the same objects in _allplugins and _plugins. $this->_allplugins = $this->_plugins; foreach (enrol_get_plugins(false) as $name => $plugin) { if (!isset($this->_allplugins[$name])) { $this->_allplugins[$name] = $plugin; } } } return $this->_allplugins; }
/** * Returns course details in an array ready to be printed. * * @global \moodle_database $DB * @param \course_in_list $course * @return array */ public static function get_course_detail_array(\course_in_list $course) { global $DB; $canaccess = $course->can_access(); $format = \course_get_format($course->id); $modinfo = \get_fast_modinfo($course->id); $modules = $modinfo->get_used_module_names(); $sections = array(); if ($format->uses_sections()) { foreach ($modinfo->get_section_info_all() as $section) { if ($section->uservisible) { $sections[] = $format->get_section_name($section); } } } $category = \coursecat::get($course->category); $categoryurl = new \moodle_url('/course/management.php', array('categoryid' => $course->category)); $categoryname = $category->get_formatted_name(); $details = array('fullname' => array('key' => \get_string('fullname'), 'value' => $course->get_formatted_fullname()), 'shortname' => array('key' => \get_string('shortname'), 'value' => $course->get_formatted_shortname()), 'idnumber' => array('key' => \get_string('idnumber'), 'value' => s($course->idnumber)), 'category' => array('key' => \get_string('category'), 'value' => \html_writer::link($categoryurl, $categoryname))); if (has_capability('moodle/site:accessallgroups', $course->get_context())) { $groups = \groups_get_course_data($course->id); $details += array('groupings' => array('key' => \get_string('groupings', 'group'), 'value' => count($groups->groupings)), 'groups' => array('key' => \get_string('groups'), 'value' => count($groups->groups))); } if ($canaccess) { $names = \role_get_names($course->get_context()); $sql = 'SELECT ra.roleid, COUNT(ra.id) AS rolecount FROM {role_assignments} ra WHERE ra.contextid = :contextid GROUP BY ra.roleid'; $rolecounts = $DB->get_records_sql($sql, array('contextid' => $course->get_context()->id)); $roledetails = array(); foreach ($rolecounts as $result) { $a = new \stdClass(); $a->role = $names[$result->roleid]->localname; $a->count = $result->rolecount; $roledetails[] = \get_string('assignedrolecount', 'moodle', $a); } $details['roleassignments'] = array('key' => \get_string('roleassignments'), 'value' => join('<br />', $roledetails)); } if ($course->can_review_enrolments()) { $enrolmentlines = array(); $instances = \enrol_get_instances($course->id, true); $plugins = \enrol_get_plugins(true); foreach ($instances as $instance) { if (!isset($plugins[$instance->enrol])) { // Weird. continue; } $plugin = $plugins[$instance->enrol]; $enrolmentlines[] = $plugin->get_instance_name($instance); } $details['enrolmentmethods'] = array('key' => \get_string('enrolmentmethods'), 'value' => join('<br />', $enrolmentlines)); } if ($canaccess) { $details['format'] = array('key' => \get_string('format'), 'value' => \course_get_format($course)->get_format_name()); $details['sections'] = array('key' => \get_string('sections'), 'value' => join('<br />', $sections)); $details['modulesused'] = array('key' => \get_string('modulesused'), 'value' => join('<br />', $modules)); } return $details; }
/** * * @global object $CFG * @uses $CFG * @uses $OUTPUT */ public function enrol() { global $CFG; $class = new pmclass($this->classid); // enrol directly in the course $student = new student(); // TBD: new student($this); didn't work!!! $student->userid = $this->userid; $student->classid = $this->classid; $student->enrolmenttime = max(time(), $class->startdate); // Disable validation rules for prerequisites and enrolment_limits $student->validation_overrides[] = 'prerequisites'; $student->validation_overrides[] = 'enrolment_limit'; $courseid = $class->get_moodle_course_id(); if ($courseid) { $course = $this->_db->get_record('course', array('id' => $courseid)); // check that the elis plugin allows for enrolments from the course // catalog -- if not, see if there are other plugins that allow // self-enrolment. $plugin = enrol_get_plugin('elis'); $enrol = $plugin->get_or_create_instance($course); if (!$enrol->{enrol_elis_plugin::ENROL_FROM_COURSE_CATALOG_DB}) { // get course enrolment plugins, and see if any of them allow self-enrolment $enrols = enrol_get_plugins(true); $enrolinstances = enrol_get_instances($course->id, true); foreach ($enrolinstances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } $form = $enrols[$instance->enrol]->enrol_page_hook($instance); if ($form) { // at least one plugin allows self-enrolment -- send // the user to the course enrolment page, and prevent // automatic enrolment $a = new stdClass(); $a->id = $course->id; $a->idnumber = $class->idnumber; $a->wwwroot = $CFG->wwwroot; $subject = get_string('moodleenrol_subj', self::LANG_FILE, $a); $message = get_string('moodleenrol', self::LANG_FILE, $a); $student->no_moodle_enrol = true; break; } } } } $student->save(); // Send notification, if enabled. $sendnotification = !empty(elis::$config->local_elisprogram->notify_enroledfromwaitlist_user) ? true : false; if ($sendnotification === true) { if (!isset($message)) { $a = new stdClass(); $a->idnum = $class->idnumber; $subject = get_string('nowenroled', self::LANG_FILE, $a); $message = get_string('nowenroled', self::LANG_FILE, $a); } $cuser = new user($this->userid); $cuser->load(); $from = get_admin(); notification::notify($message, $cuser, $from); } $this->delete(); }
function moodlebook_require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false) { global $CFG, $SESSION, $USER, $FULLME, $DB; // setup global $COURSE, themes, language and locale if (!empty($courseorid)) { if (is_object($courseorid)) { $course = $courseorid; } else { if ($courseorid == SITEID) { $course = clone $SITE; } else { $course = $DB->get_record('course', array('id' => $courseorid), '*', MUST_EXIST); } } if ($cm) { if ($cm->course != $course->id) { throw new coding_exception('course and cm parameters in require_login() call do not match!!'); } // make sure we have a $cm from get_fast_modinfo as this contains activity access details if (!$cm instanceof cm_info) { // note: nearly all pages call get_fast_modinfo anyway and it does not make any // db queries so this is not really a performance concern, however it is obviously // better if you use get_fast_modinfo to get the cm before calling this. $modinfo = get_fast_modinfo($course); $cm = $modinfo->get_cm($cm->id); } } } else { // do not touch global $COURSE via $PAGE->set_course(), // the reasons is we need to be able to call require_login() at any time!! $course = $SITE; if ($cm) { throw new coding_exception('cm parameter in require_login() requires valid course parameter!'); } } // If the user is not even logged in yet then make sure they are if (!isloggedin()) { if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests)) { if (!($guest = get_complete_user_data('id', $CFG->siteguest))) { // misconfigured site guest, just redirect to login page redirect(get_login_url()); exit; // never reached } $lang = isset($SESSION->lang) ? $SESSION->lang : $CFG->lang; complete_user_login($guest); $USER->autologinguest = true; $SESSION->lang = $lang; } else { //NOTE: $USER->site check was obsoleted by session test cookie, // $USER->confirmed test is in login/index.php if ($preventredirect) { throw new require_login_exception('You are not logged in'); } if ($setwantsurltome) { // TODO: switch to PAGE->url $SESSION->wantsurl = $FULLME; } if (!empty($_SERVER['HTTP_REFERER'])) { $SESSION->fromurl = $_SERVER['HTTP_REFERER']; } redirect(get_login_url()); exit; // never reached } } // loginas as redirection if needed if ($course->id != SITEID and session_is_loggedinas()) { if ($USER->loginascontext->contextlevel == CONTEXT_COURSE) { if ($USER->loginascontext->instanceid != $course->id) { print_error('loginasonecourse', '', $CFG->wwwroot . '/course/view.php?id=' . $USER->loginascontext->instanceid); } } } // check whether the user should be changing password (but only if it is REALLY them) if (get_user_preferences('auth_forcepasswordchange') && !session_is_loggedinas()) { $userauth = get_auth_plugin($USER->auth); if ($userauth->can_change_password() and !$preventredirect) { $SESSION->wantsurl = $FULLME; if ($changeurl = $userauth->change_password_url()) { //use plugin custom url redirect($changeurl); } else { //use moodle internal method if (empty($CFG->loginhttps)) { redirect($CFG->wwwroot . '/login/change_password.php'); } else { $wwwroot = str_replace('http:', 'https:', $CFG->wwwroot); redirect($wwwroot . '/login/change_password.php'); } } } else { print_error('nopasswordchangeforced', 'auth'); } } // Check that the user account is properly set up if (user_not_fully_set_up($USER)) { if ($preventredirect) { throw new require_login_exception('User not fully set-up'); } $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/edit.php?id=' . $USER->id . '&course=' . SITEID); } // Make sure the USER has a sesskey set up. Used for CSRF protection. sesskey(); // Do not bother admins with any formalities if (is_siteadmin()) { return; } // Fetch the system context, the course context, and prefetch its child contexts $sysctx = get_context_instance(CONTEXT_SYSTEM); $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); if ($cm) { $cmcontext = get_context_instance(CONTEXT_MODULE, $cm->id, MUST_EXIST); } else { $cmcontext = null; } // make sure the course itself is not hidden if ($course->id == SITEID) { // frontpage can not be hidden } else { if (is_role_switched($course->id)) { // when switching roles ignore the hidden flag - user had to be in course to do the switch } else { if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { // originally there was also test of parent category visibility, // BUT is was very slow in complex queries involving "my courses" // now it is also possible to simply hide all courses user is not enrolled in :-) if ($preventredirect) { throw new require_login_exception('Course is hidden'); } notice(get_string('coursehidden'), $CFG->wwwroot . '/'); } } } // is the user enrolled? if ($course->id == SITEID) { // everybody is enrolled on the frontpage } else { if (session_is_loggedinas()) { // Make sure the REAL person can access this course first $realuser = session_get_realuser(); if (!is_enrolled($coursecontext, $realuser->id, '', true) and !is_viewing($coursecontext, $realuser->id) and !is_siteadmin($realuser->id)) { if ($preventredirect) { throw new require_login_exception('Invalid course login-as access'); } echo $OUTPUT->header(); notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot . '/'); } } // very simple enrolment caching - changes in course setting are not reflected immediately if (!isset($USER->enrol)) { $USER->enrol = array(); $USER->enrol['enrolled'] = array(); $USER->enrol['tempguest'] = array(); } $access = false; if (is_viewing($coursecontext, $USER)) { // ok, no need to mess with enrol $access = true; } else { if (isset($USER->enrol['enrolled'][$course->id])) { if ($USER->enrol['enrolled'][$course->id] == 0) { $access = true; } else { if ($USER->enrol['enrolled'][$course->id] > time()) { $access = true; } else { //expired unset($USER->enrol['enrolled'][$course->id]); } } } if (isset($USER->enrol['tempguest'][$course->id])) { if ($USER->enrol['tempguest'][$course->id] == 0) { $access = true; } else { if ($USER->enrol['tempguest'][$course->id] > time()) { $access = true; } else { //expired unset($USER->enrol['tempguest'][$course->id]); $USER->access = remove_temp_roles($coursecontext, $USER->access); } } } if ($access) { // cache ok } else { if (is_enrolled($coursecontext, $USER, '', true)) { // active participants may always access // TODO: refactor this into some new function $now = time(); $sql = "SELECT MAX(ue.timeend)\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {user} u ON u.id = ue.userid\n WHERE ue.userid = :userid AND ue.status = :active AND e.status = :enabled AND u.deleted = 0\n AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)"; $params = array('enabled' => ENROL_INSTANCE_ENABLED, 'active' => ENROL_USER_ACTIVE, 'userid' => $USER->id, 'courseid' => $coursecontext->instanceid, 'now1' => $now, 'now2' => $now); $until = $DB->get_field_sql($sql, $params); if (!$until or $until > time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD) { $until = time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD; } $USER->enrol['enrolled'][$course->id] = $until; $access = true; // remove traces of previous temp guest access if (function_exists('remove_temp_course_roles')) { if ($coursecontext->instanceid !== SITEID) { remove_temp_course_roles($coursecontext); } } else { $USER->access = remove_temp_roles($coursecontext, $USER->access); } } else { $instances = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); // first ask all enabled enrol instances in course if they want to auto enrol user foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guestaccess, a timestamp in the future or false. $until = $enrols[$instance->enrol]->try_autoenrol($instance); if ($until !== false) { $USER->enrol['enrolled'][$course->id] = $until; $USER->access = remove_temp_roles($coursecontext, $USER->access); $access = true; break; } } // if not enrolled yet try to gain temporary guest access if (!$access) { foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guestaccess, a timestamp in the future or false. $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false) { $USER->enrol['tempguest'][$course->id] = $until; $access = true; break; } } } } } } if (!$access) { if ($preventredirect) { throw new require_login_exception('Not enrolled'); } $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/enrol/index.php?id=' . $course->id); } } // Check visibility of activity to current user; includes visible flag, groupmembersonly, // conditional availability, etc if ($cm && !$cm->uservisible) { if ($preventredirect) { throw new require_login_exception('Activity is hidden'); } redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden')); } }
/** * Enable enrol_lti plugin. */ protected function enable_enrol() { $enabled = enrol_get_plugins(true); $enabled['lti'] = true; $enabled = array_keys($enabled); set_config('enrol_plugins_enabled', implode(',', $enabled)); }
/** * This function will empty a course of user data. * It will retain the activities and the structure of the course. * * @param object $data an object containing all the settings including courseid (without magic quotes) * @return array status array of array component, item, error */ function reset_course_userdata($data) { global $CFG, $DB; require_once $CFG->libdir . '/gradelib.php'; require_once $CFG->libdir . '/completionlib.php'; require_once $CFG->dirroot . '/group/lib.php'; $data->courseid = $data->id; $context = context_course::instance($data->courseid); $eventparams = array('context' => $context, 'courseid' => $data->id, 'other' => array('reset_options' => (array) $data)); $event = \core\event\course_reset_started::create($eventparams); $event->trigger(); // Calculate the time shift of dates. if (!empty($data->reset_start_date)) { // Time part of course startdate should be zero. $data->timeshift = $data->reset_start_date - usergetmidnight($data->reset_start_date_old); } else { $data->timeshift = 0; } // Result array: component, item, error. $status = array(); // Start the resetting. $componentstr = get_string('general'); // Move the course start time. if (!empty($data->reset_start_date) and $data->timeshift) { // Change course start data. $DB->set_field('course', 'startdate', $data->reset_start_date, array('id' => $data->courseid)); // Update all course and group events - do not move activity events. $updatesql = "UPDATE {event}\n SET timestart = timestart + ?\n WHERE courseid=? AND instance=0"; $DB->execute($updatesql, array($data->timeshift, $data->courseid)); // Update any date activity restrictions. if ($CFG->enableavailability) { \availability_date\condition::update_all_dates($data->courseid, $data->timeshift); } $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false); } if (!empty($data->reset_end_date)) { // If the user set a end date value respect it. $DB->set_field('course', 'enddate', $data->reset_end_date, array('id' => $data->courseid)); } else { if ($data->timeshift > 0 && $data->reset_end_date_old) { // If there is a time shift apply it to the end date as well. $enddate = $data->reset_end_date_old + $data->timeshift; $DB->set_field('course', 'enddate', $enddate, array('id' => $data->courseid)); } } if (!empty($data->reset_events)) { $DB->delete_records('event', array('courseid' => $data->courseid)); $status[] = array('component' => $componentstr, 'item' => get_string('deleteevents', 'calendar'), 'error' => false); } if (!empty($data->reset_notes)) { require_once $CFG->dirroot . '/notes/lib.php'; note_delete_all($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('deletenotes', 'notes'), 'error' => false); } if (!empty($data->delete_blog_associations)) { require_once $CFG->dirroot . '/blog/lib.php'; blog_remove_associations_for_course($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('deleteblogassociations', 'blog'), 'error' => false); } if (!empty($data->reset_completion)) { // Delete course and activity completion information. $course = $DB->get_record('course', array('id' => $data->courseid)); $cc = new completion_info($course); $cc->delete_all_completion_data(); $status[] = array('component' => $componentstr, 'item' => get_string('deletecompletiondata', 'completion'), 'error' => false); } if (!empty($data->reset_competency_ratings)) { \core_competency\api::hook_course_reset_competency_ratings($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('deletecompetencyratings', 'core_competency'), 'error' => false); } $componentstr = get_string('roles'); if (!empty($data->reset_roles_overrides)) { $children = $context->get_child_contexts(); foreach ($children as $child) { $DB->delete_records('role_capabilities', array('contextid' => $child->id)); } $DB->delete_records('role_capabilities', array('contextid' => $context->id)); // Force refresh for logged in users. $context->mark_dirty(); $status[] = array('component' => $componentstr, 'item' => get_string('deletecourseoverrides', 'role'), 'error' => false); } if (!empty($data->reset_roles_local)) { $children = $context->get_child_contexts(); foreach ($children as $child) { role_unassign_all(array('contextid' => $child->id)); } // Force refresh for logged in users. $context->mark_dirty(); $status[] = array('component' => $componentstr, 'item' => get_string('deletelocalroles', 'role'), 'error' => false); } // First unenrol users - this cleans some of related user data too, such as forum subscriptions, tracking, etc. $data->unenrolled = array(); if (!empty($data->unenrol_users)) { $plugins = enrol_get_plugins(true); $instances = enrol_get_instances($data->courseid, true); foreach ($instances as $key => $instance) { if (!isset($plugins[$instance->enrol])) { unset($instances[$key]); continue; } } foreach ($data->unenrol_users as $withroleid) { if ($withroleid) { $sql = "SELECT ue.*\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.roleid = :roleid AND ra.userid = ue.userid)"; $params = array('courseid' => $data->courseid, 'roleid' => $withroleid, 'courselevel' => CONTEXT_COURSE); } else { // Without any role assigned at course context. $sql = "SELECT ue.*\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {context} c ON (c.contextlevel = :courselevel AND c.instanceid = e.courseid)\n LEFT JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.userid = ue.userid)\n WHERE ra.id IS null"; $params = array('courseid' => $data->courseid, 'courselevel' => CONTEXT_COURSE); } $rs = $DB->get_recordset_sql($sql, $params); foreach ($rs as $ue) { if (!isset($instances[$ue->enrolid])) { continue; } $instance = $instances[$ue->enrolid]; $plugin = $plugins[$instance->enrol]; if (!$plugin->allow_unenrol($instance) and !$plugin->allow_unenrol_user($instance, $ue)) { continue; } $plugin->unenrol_user($instance, $ue->userid); $data->unenrolled[$ue->userid] = $ue->userid; } $rs->close(); } } if (!empty($data->unenrolled)) { $status[] = array('component' => $componentstr, 'item' => get_string('unenrol', 'enrol') . ' (' . count($data->unenrolled) . ')', 'error' => false); } $componentstr = get_string('groups'); // Remove all group members. if (!empty($data->reset_groups_members)) { groups_delete_group_members($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('removegroupsmembers', 'group'), 'error' => false); } // Remove all groups. if (!empty($data->reset_groups_remove)) { groups_delete_groups($data->courseid, false); $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroups', 'group'), 'error' => false); } // Remove all grouping members. if (!empty($data->reset_groupings_members)) { groups_delete_groupings_groups($data->courseid, false); $status[] = array('component' => $componentstr, 'item' => get_string('removegroupingsmembers', 'group'), 'error' => false); } // Remove all groupings. if (!empty($data->reset_groupings_remove)) { groups_delete_groupings($data->courseid, false); $status[] = array('component' => $componentstr, 'item' => get_string('deleteallgroupings', 'group'), 'error' => false); } // Look in every instance of every module for data to delete. $unsupportedmods = array(); if ($allmods = $DB->get_records('modules')) { foreach ($allmods as $mod) { $modname = $mod->name; $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php'; $moddeleteuserdata = $modname . '_reset_userdata'; // Function to delete user data. if (file_exists($modfile)) { if (!$DB->count_records($modname, array('course' => $data->courseid))) { continue; // Skip mods with no instances. } include_once $modfile; if (function_exists($moddeleteuserdata)) { $modstatus = $moddeleteuserdata($data); if (is_array($modstatus)) { $status = array_merge($status, $modstatus); } else { debugging('Module ' . $modname . ' returned incorrect staus - must be an array!'); } } else { $unsupportedmods[] = $mod; } } else { debugging('Missing lib.php in ' . $modname . ' module!'); } } } // Mention unsupported mods. if (!empty($unsupportedmods)) { foreach ($unsupportedmods as $mod) { $status[] = array('component' => get_string('modulenameplural', $mod->name), 'item' => '', 'error' => get_string('resetnotimplemented')); } } $componentstr = get_string('gradebook', 'grades'); // Reset gradebook,. if (!empty($data->reset_gradebook_items)) { remove_course_grades($data->courseid, false); grade_grab_course_grades($data->courseid); grade_regrade_final_grades($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('removeallcourseitems', 'grades'), 'error' => false); } else { if (!empty($data->reset_gradebook_grades)) { grade_course_reset($data->courseid); $status[] = array('component' => $componentstr, 'item' => get_string('removeallcoursegrades', 'grades'), 'error' => false); } } // Reset comments. if (!empty($data->reset_comments)) { require_once $CFG->dirroot . '/comment/lib.php'; comment::reset_course_page_comments($context); } $event = \core\event\course_reset_ended::create($eventparams); $event->trigger(); return $status; }
// plugin specific state - do not mess with it! $edit[] = html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/show'), 'alt' => '', 'class' => 'smallicon')); } } } } // link to instance management if (enrol_is_enabled($instance->enrol)) { if ($icons = $plugin->get_action_icons($instance)) { $edit = array_merge($edit, $icons); } } // add a row to the table $table->data[] = array($displayname, $users, implode(' ', $updown), implode(' ', $edit)); } echo html_writer::table($table); // access security is in each plugin $candidates = array(); foreach (enrol_get_plugins(true) as $name => $plugin) { if (!($link = $plugin->get_newinstance_link($course->id))) { continue; } $candidates[$link->out(false)] = get_string('pluginname', 'enrol_' . $name); } if ($candidates) { $select = new url_select($candidates); $select->set_label(get_string('addinstance', 'enrol')); echo $OUTPUT->render($select); } echo $OUTPUT->box_end(); echo $OUTPUT->footer();
/** * Builds the XHTML to display the control * * @param string $data Unused * @param string $query * @return string */ public function output_html($data, $query = '') { global $CFG, $OUTPUT, $DB, $PAGE; // Display strings. $strup = get_string('up'); $strdown = get_string('down'); $strsettings = get_string('settings'); $strenable = get_string('enable'); $strdisable = get_string('disable'); $struninstall = get_string('uninstallplugin', 'core_admin'); $strusage = get_string('enrolusage', 'enrol'); $strversion = get_string('version'); $strtest = get_string('testsettings', 'core_enrol'); $pluginmanager = core_plugin_manager::instance(); $enrols_available = enrol_get_plugins(false); $active_enrols = enrol_get_plugins(true); $allenrols = array(); foreach ($active_enrols as $key => $enrol) { $allenrols[$key] = true; } foreach ($enrols_available as $key => $enrol) { $allenrols[$key] = true; } // Now find all borked plugins and at least allow then to uninstall. $condidates = $DB->get_fieldset_sql("SELECT DISTINCT enrol FROM {enrol}"); foreach ($condidates as $candidate) { if (empty($allenrols[$candidate])) { $allenrols[$candidate] = true; } } $return = $OUTPUT->heading(get_string('actenrolshhdr', 'enrol'), 3, 'main', true); $return .= $OUTPUT->box_start('generalbox enrolsui'); $table = new html_table(); $table->head = array(get_string('name'), $strusage, $strversion, $strenable, $strup . '/' . $strdown, $strsettings, $strtest, $struninstall); $table->colclasses = array('leftalign', 'centeralign', 'centeralign', 'centeralign', 'centeralign', 'centeralign', 'centeralign', 'centeralign'); $table->id = 'courseenrolmentplugins'; $table->attributes['class'] = 'admintable generaltable'; $table->data = array(); // Iterate through enrol plugins and add to the display table. $updowncount = 1; $enrolcount = count($active_enrols); $url = new moodle_url('/admin/enrol.php', array('sesskey' => sesskey())); $printed = array(); foreach ($allenrols as $enrol => $unused) { $plugininfo = $pluginmanager->get_plugin_info('enrol_' . $enrol); $version = get_config('enrol_' . $enrol, 'version'); if ($version === false) { $version = ''; } if (get_string_manager()->string_exists('pluginname', 'enrol_' . $enrol)) { $name = get_string('pluginname', 'enrol_' . $enrol); } else { $name = $enrol; } // Usage. $ci = $DB->count_records('enrol', array('enrol' => $enrol)); $cp = $DB->count_records_select('user_enrolments', "enrolid IN (SELECT id FROM {enrol} WHERE enrol = ?)", array($enrol)); $usage = "{$ci} / {$cp}"; // Hide/show links. $class = ''; if (isset($active_enrols[$enrol])) { $aurl = new moodle_url($url, array('action' => 'disable', 'enrol' => $enrol)); $hideshow = "<a href=\"{$aurl}\">"; $hideshow .= "<img src=\"" . $OUTPUT->pix_url('t/hide') . "\" class=\"iconsmall\" alt=\"{$strdisable}\" /></a>"; $enabled = true; $displayname = $name; } else { if (isset($enrols_available[$enrol])) { $aurl = new moodle_url($url, array('action' => 'enable', 'enrol' => $enrol)); $hideshow = "<a href=\"{$aurl}\">"; $hideshow .= "<img src=\"" . $OUTPUT->pix_url('t/show') . "\" class=\"iconsmall\" alt=\"{$strenable}\" /></a>"; $enabled = false; $displayname = $name; $class = 'dimmed_text'; } else { $hideshow = ''; $enabled = false; $displayname = '<span class="notifyproblem">' . $name . '</span>'; } } if ($PAGE->theme->resolve_image_location('icon', 'enrol_' . $name, false)) { $icon = $OUTPUT->pix_icon('icon', '', 'enrol_' . $name, array('class' => 'icon pluginicon')); } else { $icon = $OUTPUT->pix_icon('spacer', '', 'moodle', array('class' => 'icon pluginicon noicon')); } // Up/down link (only if enrol is enabled). $updown = ''; if ($enabled) { if ($updowncount > 1) { $aurl = new moodle_url($url, array('action' => 'up', 'enrol' => $enrol)); $updown .= "<a href=\"{$aurl}\">"; $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"{$strup}\" class=\"iconsmall\" /></a> "; } else { $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"iconsmall\" alt=\"\" /> "; } if ($updowncount < $enrolcount) { $aurl = new moodle_url($url, array('action' => 'down', 'enrol' => $enrol)); $updown .= "<a href=\"{$aurl}\">"; $updown .= "<img src=\"" . $OUTPUT->pix_url('t/down') . "\" alt=\"{$strdown}\" class=\"iconsmall\" /></a>"; } else { $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"iconsmall\" alt=\"\" />"; } ++$updowncount; } // Add settings link. if (!$version) { $settings = ''; } else { if ($surl = $plugininfo->get_settings_url()) { $settings = html_writer::link($surl, $strsettings); } else { $settings = ''; } } // Add uninstall info. $uninstall = ''; if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('enrol_' . $enrol, 'manage')) { $uninstall = html_writer::link($uninstallurl, $struninstall); } $test = ''; if (!empty($enrols_available[$enrol]) and method_exists($enrols_available[$enrol], 'test_settings')) { $testsettingsurl = new moodle_url('/enrol/test_settings.php', array('enrol' => $enrol, 'sesskey' => sesskey())); $test = html_writer::link($testsettingsurl, $strtest); } // Add a row to the table. $row = new html_table_row(array($icon . $displayname, $usage, $version, $hideshow, $updown, $settings, $test, $uninstall)); if ($class) { $row->attributes['class'] = $class; } $table->data[] = $row; $printed[$enrol] = true; } $return .= html_writer::table($table); $return .= get_string('configenrolplugins', 'enrol') . '<br />' . get_string('tablenosave', 'admin'); $return .= $OUTPUT->box_end(); return highlight($query, $return); }
* @copyright 2010 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define('NO_OUTPUT_BUFFERING', true); require_once '../config.php'; require_once $CFG->libdir . '/adminlib.php'; $action = required_param('action', PARAM_ALPHANUMEXT); $enrol = required_param('enrol', PARAM_PLUGIN); $confirm = optional_param('confirm', 0, PARAM_BOOL); $PAGE->set_url('/admin/enrol.php'); $PAGE->set_context(context_system::instance()); require_login(); require_capability('moodle/site:config', context_system::instance()); require_sesskey(); $enabled = enrol_get_plugins(true); $all = enrol_get_plugins(false); $return = new moodle_url('/admin/settings.php', array('section' => 'manageenrols')); $syscontext = context_system::instance(); switch ($action) { case 'disable': unset($enabled[$enrol]); set_config('enrol_plugins_enabled', implode(',', array_keys($enabled))); core_plugin_manager::reset_caches(); $syscontext->mark_dirty(); // resets all enrol caches break; case 'enable': if (!isset($all[$enrol])) { break; } $enabled = array_keys($enabled);
/** * Create user enrolments. * * This has to be called after creation of enrolment instances * and before adding of role assignments. * * Roles are assigned in restore_ras_and_caps_structure_step::process_assignment() processing afterwards. * * @param mixed $data * @return void */ public function process_enrolment($data) { global $DB; if (!isset($this->plugins)) { $this->plugins = enrol_get_plugins(true); } $data = (object) $data; // Process only if parent instance have been mapped. if ($enrolid = $this->get_new_parentid('enrol')) { $oldinstancestatus = ENROL_INSTANCE_ENABLED; $oldenrolid = $this->get_old_parentid('enrol'); if (isset($this->originalstatus[$oldenrolid])) { $oldinstancestatus = $this->originalstatus[$oldenrolid]; } if ($instance = $DB->get_record('enrol', array('id' => $enrolid))) { // And only if user is a mapped one. if ($userid = $this->get_mappingid('user', $data->userid)) { if (isset($this->plugins[$instance->enrol])) { $this->plugins[$instance->enrol]->restore_user_enrolment($this, $data, $instance, $userid, $oldinstancestatus); } } } } }
/** * Is there a chance users might self enrol * @param int $courseid * @return bool */ function enrol_selfenrol_available($courseid) { $result = false; $plugins = enrol_get_plugins(true); $enrolinstances = enrol_get_instances($courseid, true); foreach ($enrolinstances as $instance) { if (!isset($plugins[$instance->enrol])) { continue; } if ($instance->enrol === 'guest') { // blacklist known temporary guest plugins continue; } if ($plugins[$instance->enrol]->show_enrolme_link($instance)) { $result = true; break; } } return $result; }
/** * Returns true if the user is able to access the course. * * This function is in no way, shape, or form a substitute for require_login. * It should only be used in circumstances where it is not possible to call require_login * such as the navigation. * * This function checks many of the methods of access to a course such as the view * capability, enrollments, and guest access. It also makes use of the cache * generated by require_login for guest access. * * The flags within the $USER object that are used here should NEVER be used outside * of this function can_access_course and require_login. Doing so WILL break future * versions. * * @param stdClass $course record * @param stdClass|int|null $user user record or id, current user if null * @param string $withcapability Check for this capability as well. * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @return boolean Returns true if the user is able to access the course */ function can_access_course(stdClass $course, $user = null, $withcapability = '', $onlyactive = false) { global $DB, $USER; // this function originally accepted $coursecontext parameter if ($course instanceof context) { if ($course instanceof context_course) { debugging('deprecated context parameter, please use $course record'); $coursecontext = $course; $course = $DB->get_record('course', array('id' => $coursecontext->instanceid)); } else { debugging('Invalid context parameter, please use $course record'); return false; } } else { $coursecontext = context_course::instance($course->id); } if (!isset($USER->id)) { // should never happen $USER->id = 0; } // make sure there is a user specified if ($user === null) { $userid = $USER->id; } else { $userid = is_object($user) ? $user->id : $user; } unset($user); if ($withcapability and !has_capability($withcapability, $coursecontext, $userid)) { return false; } if ($userid == $USER->id) { if (!empty($USER->access['rsw'][$coursecontext->path])) { // the fact that somebody switched role means they can access the course no matter to what role they switched return true; } } if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext, $userid)) { return false; } if (is_viewing($coursecontext, $userid)) { return true; } if ($userid != $USER->id) { // for performance reasons we do not verify temporary guest access for other users, sorry... return is_enrolled($coursecontext, $userid, '', $onlyactive); } // === from here we deal only with $USER === $coursecontext->reload_if_dirty(); if (isset($USER->enrol['enrolled'][$course->id])) { if ($USER->enrol['enrolled'][$course->id] > time()) { return true; } } if (isset($USER->enrol['tempguest'][$course->id])) { if ($USER->enrol['tempguest'][$course->id] > time()) { return true; } } if (is_enrolled($coursecontext, $USER, '', $onlyactive)) { return true; } // if not enrolled try to gain temporary guest access $instances = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guest access, a timestamp in the future, 0 (always) or false. $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false and $until > time()) { $USER->enrol['tempguest'][$course->id] = $until; return true; } } if (isset($USER->enrol['tempguest'][$course->id])) { unset($USER->enrol['tempguest'][$course->id]); remove_temp_course_roles($coursecontext); } return false; }
/** * Returns true if the user is able to access the course. * * This function is in no way, shape, or form a substitute for require_login. * It should only be used in circumstances where it is not possible to call require_login * such as the navigation. * * This function checks many of the methods of access to a course such as the view * capability, enrollments, and guest access. It also makes use of the cache * generated by require_login for guest access. * * The flags within the $USER object that are used here should NEVER be used outside * of this function can_access_course and require_login. Doing so WILL break future * versions. * * @param stdClass $course record * @param stdClass|int|null $user user record or id, current user if null * @param string $withcapability Check for this capability as well. * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @return boolean Returns true if the user is able to access the course */ function can_access_course(stdClass $course, $user = null, $withcapability = '', $onlyactive = false) { global $DB, $USER; // this function originally accepted $coursecontext parameter if ($course instanceof context) { if ($course instanceof context_course) { debugging('deprecated context parameter, please use $course record'); $coursecontext = $course; $course = $DB->get_record('course', array('id' => $coursecontext->instanceid)); } else { debugging('Invalid context parameter, please use $course record'); return false; } } else { $coursecontext = context_course::instance($course->id); } if (!isset($USER->id)) { // should never happen $USER->id = 0; } // make sure there is a user specified if ($user === null) { $userid = $USER->id; } else { $userid = is_object($user) ? $user->id : $user; } unset($user); if ($withcapability and !has_capability($withcapability, $coursecontext, $userid)) { return false; } if ($userid == $USER->id) { if (!empty($USER->access['rsw'][$coursecontext->path])) { // the fact that somebody switched role means they can access the course no matter to what role they switched return true; } } if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext, $userid)) { return false; } if (is_viewing($coursecontext, $userid)) { return true; } if ($userid != $USER->id) { // for performance reasons we do not verify temporary guest access for other users, sorry... return is_enrolled($coursecontext, $userid, '', $onlyactive); } // === from here we deal only with $USER === // verify our caches if (!isset($USER->enrol)) { /** * These flags within the $USER object should NEVER be used outside of this * function can_access_course and the function require_login. * Doing so WILL break future versions!!!! */ $USER->enrol = array(); $USER->enrol['enrolled'] = array(); $USER->enrol['tempguest'] = array(); } if (isset($USER->enrol['enrolled'][$course->id])) { if ($USER->enrol['enrolled'][$course->id] == 0) { return true; } else { if ($USER->enrol['enrolled'][$course->id] > time()) { return true; } } } if (isset($USER->enrol['tempguest'][$course->id])) { if ($USER->enrol['tempguest'][$course->id] == 0) { return true; } else { if ($USER->enrol['tempguest'][$course->id] > time()) { return true; } } } if (is_enrolled($coursecontext, $USER, '', true)) { // active participants may always access // TODO: refactor this into some new function $now = time(); $sql = "SELECT MAX(ue.timeend)\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {user} u ON u.id = ue.userid\n WHERE ue.userid = :userid AND ue.status = :active AND e.status = :enabled AND u.deleted = 0\n AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)"; $params = array('enabled' => ENROL_INSTANCE_ENABLED, 'active' => ENROL_USER_ACTIVE, 'userid' => $USER->id, 'courseid' => $coursecontext->instanceid, 'now1' => $now, 'now2' => $now); $until = $DB->get_field_sql($sql, $params); if (!$until or $until > time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD) { $until = time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD; } $USER->enrol['enrolled'][$course->id] = $until; // remove traces of previous temp guest access remove_temp_course_roles($coursecontext); return true; } unset($USER->enrol['enrolled'][$course->id]); // if not enrolled try to gain temporary guest access $instances = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guestaccess, a timestamp in the future or false. $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false) { $USER->enrol['tempguest'][$course->id] = $until; return true; } } unset($USER->enrol['tempguest'][$course->id]); return false; }