Commit df997f84 authored by Petr Skoda's avatar Petr Skoda
Browse files

MDL-21782 reworked enrolment framework, the core infrastructure is in place,...

MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week

AMOS START
    MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
    MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
    MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
    MOV [enrolenddate,core],[enrolenddate,enrol_self]
    CPY [welcometocourse,core],[welcometocourse,enrol_self]
    CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
    MOV [notenrollable,core],[notenrollable,core_enrol]
    MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
    MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
    MOV [coursemanager,core_admin],[coursecontact,core_admin]
    MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
    MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
    MOV [enrolme,core],[enrolme,core_enrol]
    MOV [unenrol,core],[unenrol,core_enrol]
    MOV [unenrolme,core],[unenrolme,core_enrol]
    MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
    MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
    MOV [enrolments,core],[enrolments,core_enrol]
    MOV [enrolperiod,core],[enrolperiod,core_enrol]
    MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
parent 2c9bb9c3
......@@ -48,7 +48,7 @@ if ($CFG->bloglevel == BLOG_COURSE_LEVEL || $CFG->bloglevel == BLOG_GROUP_LEVEL)
$a->blogcount = 0;
foreach ($bloggers as $blogger) {
$courses = get_my_courses($blogger->userid);
$courses = enrol_get_users_courses($blogger->userid, true, 'groupmode,groupmodeforce');
$blogentries = $DB->get_records('post', array('module' => 'blog', 'userid' => $blogger->userid));
foreach ($courses as $course) {
......
......@@ -205,34 +205,6 @@
}
mtrace('Finished admin reports');
mtrace('Removing expired enrolments ...', ''); // See MDL-8785
$timenow = time();
$somefound = false;
// The preferred way saves memory, datablib
// find courses where limited enrolment is enabled
$sql = "SELECT ra.roleid, ra.userid, ra.contextid
FROM {course} c
JOIN {context} cx ON cx.instanceid = c.id
JOIN {role_assignments} ra ON ra.contextid = cx.id
WHERE cx.contextlevel = '".CONTEXT_COURSE."'
AND ra.timeend > 0
AND ra.timeend < ?
AND c.enrolperiod > 0";
if ($rs = $DB->get_recordset_sql($sql, array($timenow))) {
foreach ($rs as $oldenrolment) {
role_unassign($oldenrolment->roleid, $oldenrolment->userid, 0, $oldenrolment->contextid);
$somefound = true;
}
$rs->close();
}
if ($somefound) {
mtrace('Done');
} else {
mtrace('none found');
}
mtrace('Starting main gradebook job ...');
grade_cron();
mtrace('done.');
......@@ -270,41 +242,6 @@
if ($random100 < 20) { // Approximately 20% of the time.
mtrace("Running clean-up tasks...");
/// Unenrol users who haven't logged in for $CFG->longtimenosee
if ($CFG->longtimenosee) { // value in days
$cuttime = $timenow - ($CFG->longtimenosee * 3600 * 24);
$rs = $DB->get_recordset_sql ("SELECT id, userid, courseid
FROM {user_lastaccess}
WHERE courseid != ".SITEID."
AND timeaccess < ?", array($cuttime));
foreach ($rs as $assign) {
if ($context = get_context_instance(CONTEXT_COURSE, $assign->courseid)) {
if (role_unassign(0, $assign->userid, 0, $context->id)) {
mtrace("removing user $assign->userid from course $assign->courseid as they have not accessed the course for over $CFG->longtimenosee days");
}
}
}
$rs->close();
/// Execute the same query again, looking for remaining records and deleting them
/// if the user hasn't moodle/course:participate in the CONTEXT_COURSE context (orphan records)
$rs = $DB->get_recordset_sql ("SELECT id, userid, courseid
FROM {user_lastaccess}
WHERE courseid != ".SITEID."
AND timeaccess < ?", array($cuttime));
foreach ($rs as $assign) {
if ($context = get_context_instance(CONTEXT_COURSE, $assign->courseid)) {
if (!is_enrolled($context, $assign->userid) and !is_viewing($context, $assign->userid)) {
$DB->delete_records('user_lastaccess', array('userid'=>$assign->userid, 'courseid'=>$assign->courseid));
mtrace("Deleted orphan user_lastaccess for user $assign->userid from course $assign->courseid");
}
}
}
$rs->close();
}
flush();
/// Delete users who haven't confirmed within required period
if (!empty($CFG->deleteunconfirmed)) {
......@@ -370,9 +307,6 @@
}
flush();
sync_metacourses();
mtrace('Synchronised metacourses');
//
// generate new password emails for users
//
......@@ -464,20 +398,16 @@
unset($authplugin);
}
/// Run the enrolment cron, if any
if (!($plugins = explode(',', $CFG->enrol_plugins_enabled))) {
$plugins = array($CFG->enrol);
}
require_once($CFG->dirroot .'/enrol/enrol.class.php');
foreach ($plugins as $p) {
$enrol = enrolment_factory::factory($p);
if (method_exists($enrol, 'cron')) {
$enrol->cron();
}
if (!empty($enrol->log)) {
mtrace($enrol->log);
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;
}
unset($enrol);
mtrace("Running cron for enrol_$ename...");
$enrol->cron();
$enrol->set_config('lastcron', time());
}
if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) {
......
<?php
// enrol.php - allows admin to edit all enrollment variables
// Yes, enrol is correct English spelling.
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
$enrol = optional_param('enrol', $CFG->enrol, PARAM_SAFEDIR);
$savesettings = optional_param('savesettings', 0, PARAM_BOOL);
admin_externalpage_setup('enrolment');
if (!isset($CFG->sendcoursewelcomemessage)) {
set_config('sendcoursewelcomemessage', 1);
}
require_once("$CFG->dirroot/enrol/enrol.class.php"); /// Open the factory class
/// Save settings
if ($frm = data_submitted() and !$savesettings) {
if (!confirm_sesskey()) {
print_error('confirmsesskeybad', 'error');
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Enrol config manipulation script.
*
* @package core
* @subpackage enrol
* @copyright 2010 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
$action = required_param('action', PARAM_ACTION);
$enrol = required_param('enrol', PARAM_SAFEDIR);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$PAGE->set_url('/admin/enrol.php');
require_login();
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
require_sesskey();
$enabled = enrol_get_plugins(true);
$all = enrol_get_plugins(false);
$return = new moodle_url('/admin/settings.php', array('section'=>'manageenrols'));
switch ($action) {
case 'disable':
unset($enabled[$enrol]);
set_config('enrol_plugins_enabled', implode(',', array_keys($enabled)));
break;
case 'enable':
if (!isset($all[$enrol])) {
break;
}
if (empty($frm->enable)) {
$frm->enable = array();
$enabled = array_keys($enabled);
$enabled[] = $enrol;
set_config('enrol_plugins_enabled', implode(',', $enabled));
break;
case 'up':
if (!isset($enabled[$enrol])) {
break;
}
if (empty($frm->default)) {
$frm->default = '';
}
if ($frm->default && $frm->default != 'manual' && !in_array($frm->default, $frm->enable)) {
$frm->enable[] = $frm->default;
}
asort($frm->enable);
$frm->enable = array_merge(array('manual'), $frm->enable); // make sure manual plugin is called first
set_config('enrol_plugins_enabled', implode(',', $frm->enable));
set_config('enrol', $frm->default);
redirect("enrol.php", get_string("changessaved"), 1);
} else if ($frm = data_submitted() and $savesettings) {
if (!confirm_sesskey()) {
print_error('confirmsesskeybad', 'error');
}
set_config('sendcoursewelcomemessage', required_param('sendcoursewelcomemessage', PARAM_BOOL));
}
/// Print the form
$str = get_strings(array('enrolmentplugins', 'users', 'administration', 'settings', 'edit'));
echo $OUTPUT->header();
$modules = get_plugin_list('enrol');
$options = array();
foreach ($modules as $module => $moduledir) {
$options[$module] = get_string("enrolname", "enrol_$module");
}
asort($options);
echo $OUTPUT->box(get_string('configenrolmentplugins', 'admin'));
echo "<form id=\"enrolmenu\" method=\"post\" action=\"enrol.php\">";
echo "<div>";
echo "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />";
$table = new html_table();
$table->head = array(get_string('name'), get_string('enable'), get_string('default'), $str->settings);
$table->align = array('left', 'center', 'center', 'center');
$table->size = array('60%', '', '', '15%');
$table->attributes['class'] = 'generaltable enrolplugintable';
$table->data = array();
$enabledplugins = explode(',', $CFG->enrol_plugins_enabled);
foreach ($modules as $module => $moduledir) {
// skip if directory is empty
if (!file_exists("$moduledir/enrol.php")) {
continue;
$enabled = array_keys($enabled);
$enabled = array_flip($enabled);
$current = $enabled[$enrol];
if ($current == 0) {
break; //already at the top
}
$name = get_string("enrolname", "enrol_$module");
$plugin = enrolment_factory::factory($module);
$enable = '<input type="checkbox" name="enable[]" value="'.$module.'"';
if (in_array($module, $enabledplugins)) {
$enable .= ' checked="checked"';
$enabled = array_flip($enabled);
$enabled[$current] = $enabled[$current - 1];
$enabled[$current - 1] = $enrol;
set_config('enrol_plugins_enabled', implode(',', $enabled));
break;
case 'down':
if (!isset($enabled[$enrol])) {
break;
}
if ($module == 'manual') {
$enable .= ' disabled="disabled"';
$enabled = array_keys($enabled);
$enabled = array_flip($enabled);
$current = $enabled[$enrol];
if ($current == count($enabled) - 1) {
break; //already at the end
}
$enable .= ' />';
if (method_exists($plugin, 'print_entry')) {
$default = '<input type="radio" name="default" value="'.$module.'"';
if ($CFG->enrol == $module) {
$default .= ' checked="checked"';
}
$default .= ' />';
$enabled = array_flip($enabled);
$enabled[$current] = $enabled[$current + 1];
$enabled[$current + 1] = $enrol;
set_config('enrol_plugins_enabled', implode(',', $enabled));
break;
case 'uninstall':
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('enrolments', 'enrol'));
if (get_string_manager()->string_exists('pluginname', 'enrol_'.$enrol)) {
$strplugin = get_string('pluginname', 'enrol_'.$enrol);
} else {
$default = '';
$strplugin = $enrol;
}
$table->data[$name] = array($name, $enable, $default,
'<a href="enrol_config.php?enrol='.$module.'">'.$str->edit.'</a>');
}
asort($table->data);
echo html_writer::table($table);
echo "<div style=\"text-align:center\"><input type=\"submit\" value=\"".get_string("savechanges")."\" /></div>\n";
echo "</div>";
echo "</form>";
echo '<hr />';
$yesnooptions = array(0=>get_string('no'), 1=>get_string('yes'));
echo '<form id="adminsettings" method="post" action="enrol.php">';
echo '<div class="settingsform clearfix">';
echo $OUTPUT->heading(get_string('commonsettings', 'admin'));
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
echo '<input type="hidden" name="savesettings" value="1" />';
echo '<fieldset>';
echo '<div class="form-item clearfix" id="admin-sendcoursewelcomemessage">';
echo '<div class="form-label"><label for = "menusendcoursewelcomemessage">' . get_string('sendcoursewelcomemessage', 'admin');
echo '<span class="form-shortname">sendcoursewelcomemessage</span>';
echo '</label></div>';
echo '<div class="form-setting"><div class="form-checkbox defaultsnext">';
echo html_writer::select($yesnooptions, 'sendcoursewelcomemessage', $CFG->sendcoursewelcomemessage, false);
echo '</div><div class="form-defaultinfo">'.get_string('defaultsettinginfo', 'admin', get_string('yes')).'</div></div>';
echo '<div class="form-description">' . get_string('configsendcoursewelcomemessage', 'admin') . '</div>';
echo '</div>';
echo '</fieldset>';
echo '<div class="form-buttons"><input class="form-submit" type="submit" value="'.get_string('savechanges', 'admin').'" /></div>';
echo '</div>';
echo '</form>';
echo $OUTPUT->footer();
if (!$confirm) {
$uurl = new moodle_url('/admin/enrol.php', array('action'=>'uninstall', 'enrol'=>$enrol, 'sesskey'=>sesskey(), 'confirm'=>1));
echo $OUTPUT->confirm(get_string('uninstallconfirm', 'enrol', $strplugin), $uurl, $return);
echo $OUTPUT->footer();
exit;
} else { // Delete everything!!
uninstall_plugin('enrol', $enrol);
$a->plugin = $strplugin;
$a->directory = "$CFG->dirroot/enrol/$enrol";
echo $OUTPUT->notification(get_string('uninstalldeletefiles', 'enrol', $a), 'notifysuccess');
echo $OUTPUT->continue_button($return);
echo $OUTPUT->footer();
exit;
}
}
redirect($return);
\ No newline at end of file
<?php
// enrol_config.php - allows admin to edit all enrollment variables
// Yes, enrol is correct English spelling.
require_once("../config.php");
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('enrolment');
$enrol = required_param('enrol', PARAM_ALPHA);
$PAGE->set_pagetype('admin-enrol-' . $enrol);
require_once("$CFG->dirroot/enrol/enrol.class.php"); /// Open the factory class
$enrolment = enrolment_factory::factory($enrol);
/// If data submitted, then process and store.
if ($frm = data_submitted()) {
if (!confirm_sesskey()) {
print_error('confirmsesskeybad', 'error');
}
if ($enrolment->process_config($frm)) {
redirect("enrol.php?sesskey=".sesskey(), get_string("changessaved"), 1);
}
} else {
$frm = $CFG;
}
/// Otherwise fill and print the form.
/// get language strings
$str = get_strings(array('enrolmentplugins', 'configuration', 'users', 'administration'));
unset($options);
$modules = get_plugin_list('enrol');
foreach ($modules as $module => $enroldir) {
$options[$module] = get_string("enrolname", "enrol_$module");
}
asort($options);
echo $OUTPUT->header();
echo "<form id=\"enrolmenu\" method=\"post\" action=\"enrol_config.php\">";
echo "<div>";
echo "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />";
echo "<input type=\"hidden\" name=\"enrol\" value=\"".$enrol."\" />";
/// Print current enrolment type description
echo $OUTPUT->box_start();
echo $OUTPUT->heading($options[$enrol]);
echo $OUTPUT->box_start('informationbox');
print_string("description", "enrol_$enrol");
echo $OUTPUT->box_end();
echo "<hr />";
$enrolment->config_form($frm);
echo "<p class=\"centerpara\"><input type=\"submit\" value=\"".get_string("savechanges")."\" /></p>\n";
echo $OUTPUT->box_end();
echo "</div>";
echo "</form>";
echo $OUTPUT->footer();
exit;
......@@ -709,23 +709,16 @@ class generator {
$context = get_context_instance(CONTEXT_COURSE, $courseid);
foreach ($users_to_assign as $random_user) {
$success = role_assign(5, $random_user, 0, $context->id);
role_assign(5, $random_user, $context->id);
if ($success) {
$assigned_count++;
$course_users[$courseid][] = $random_user;
if (!isset($assigned_users[$random_user])) {
$assigned_users[$random_user] = 1;
} else {
$assigned_users[$random_user]++;
}
$this->verbose("Student $random_user was assigned to course $courseid.");
$assigned_count++;
$course_users[$courseid][] = $random_user;
if (!isset($assigned_users[$random_user])) {
$assigned_users[$random_user] = 1;
} else {
$this->verbose("Could not assign student $random_user to course $courseid!");
if (!$this->get('ignore_errors')) {
die();
}
$assigned_users[$random_user]++;
}
$this->verbose("Student $random_user was assigned to course $courseid.");
}
}
......
<?PHP
// enrol_config.php - allows admin to edit all enrollment variables
// enrol_config.php - allows admin to edit all enrolment variables
// Yes, enrol is correct English spelling.
die('TODO: MDL-22787 mnet enrolments are not reimplemented yet, sorry.');
require_once(dirname(__FILE__) . "/../../config.php");
require_once($CFG->libdir.'/adminlib.php');
include_once($CFG->dirroot.'/mnet/xmlrpc/client.php');
......@@ -12,8 +14,7 @@
admin_externalpage_setup('mnetenrol');
require_once("$CFG->dirroot/enrol/enrol.class.php"); /// Open the factory class
$enrolment = enrolment_factory::factory('mnet');
$enrolment = enrol_get_plugin('mnet');
$mnethostid = required_param('host', PARAM_INT);
$courseid = required_param('courseid', PARAM_INT);
......@@ -278,7 +279,7 @@
/// Print the page
/// get language strings
$str = get_strings(array('enrolmentplugins', 'configuration', 'users', 'administration'));
$str = get_strings(array('configuration', 'users', 'administration'));
/// Get some language strings
$strpotentialusers = get_string('potentialusers', 'role');
......
<?PHP
// enrol_config.php - allows admin to edit all enrollment variables
// enrol_config.php - allows admin to edit all enrolment variables
// Yes, enrol is correct English spelling.
die('TODO: ment enrolments are not reimplemented yet, sorry.');
require_once(dirname(__FILE__) . "/../../config.php");
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->dirroot.'/mnet/lib.php');
......@@ -13,8 +15,7 @@
admin_externalpage_setup('mnetenrol');
require_once("$CFG->dirroot/enrol/enrol.class.php"); /// Open the factory class
$enrolment = enrolment_factory::factory('mnet');
$enrolment = enrol_get_plugin('mnet');
$mnethost = required_param('host', PARAM_INT);
$host = $DB->get_record('mnet_host', array('id'=>$mnethost));
......
......@@ -6,11 +6,11 @@
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->dirroot.'/mnet/lib.php');
admin_externalpage_setup('mnetenrol');
die('TODO: MDL-22787 mnet enrolments are not reimplemented yet, sorry.');
require_once("$CFG->dirroot/enrol/enrol.class.php"); /// Open the factory class
admin_externalpage_setup('mnetenrol');
$enrolment = enrolment_factory::factory('mnet');
$enrolment = enrol_get_plugin('mnet');
/// Otherwise fill and print the form.
......
......@@ -35,24 +35,6 @@ $string['check_cookiesecure_details'] = '<p>If you enable https communication it
$string['check_cookiesecure_error'] = 'Please enable secure cookies';
$string['check_cookiesecure_name'] = 'Secure cookies';
$string['check_cookiesecure_ok'] = 'Secure cookies enabled.';
$string['check_courserole_anything'] = 'The "doanything" capability must not be allowed in this <a href="{$a}">context</a>.';
$string['check_courserole_details'] = '<p>Each course has one default enrolment role specified. Please make sure no risky capabilities are allowed for this role.</p>
<p>The only supported legacy type for the default course role is <em>Student</em>.</p>';
$string['check_courserole_error'] = 'Incorrectly defined default course roles detected!';
$string['check_courserole_name'] = 'Default roles (courses)';
$string['check_courserole_notyet'] = 'Used only default course role.';
$string['check_courserole_ok'] = 'Default course role definitions is OK.';
$string['check_courserole_risky'] = 'Risky capabilities detected in <a href="{$a}">context</a>.';
$string['check_courserole_riskylegacy'] = 'Risky legacy type detected in <a href="{$a->url}">{$a->shortname}</a>.';
$string['check_defaultcourserole_anything'] = 'The "doanything" capability must not be allowed in this <a href="{$a}">context</a>.';
$string['check_defaultcourserole_details'] = '<p>The default student role for course enrolment specifies the default role for courses. Please make sure no risky capabilities are allowed in this role.</p>
<p>The only supported legacy type for default role is <em>Student</em>.</p>';
$string['check_defaultcourserole_error'] = 'Incorrectly defined default course role "{$a}" detected!';
$string['check_defaultcourserole_legacy'] = 'Risky legacy type detected.';
$string['check_defaultcourserole_name'] = 'Default course role (global)';
$string['check_defaultcourserole_notset'] = 'Default role is not set.';
$string['check_defaultcourserole_ok'] = 'Site default role definition is OK.';
$string['check_defaultcourserole_risky'] = 'Risky capabilities detected in <a href="{$a}">context</a>.';
$string['check_defaultuserrole_details'] = '<p>All logged in users are given capabilities of the default user role. Please make sure no risky capabilities are allowed in this role.</p>
<p>The only supported legacy type for the default user role is <em>Authenticated user</em>. The course view capability must not be enabled.</p>';
$string['check_defaultuserrole_error'] = 'The default user role "{$a}" is incorrectly defined!';
......
......@@ -58,8 +58,6 @@ function report_security_get_issue_list() {
'report_security_check_defaultuserrole',
'report_security_check_guestrole',
'report_security_check_frontpagerole',
'report_security_check_defaultcourserole',
'report_security_check_courserole',
);
}
......@@ -587,9 +585,6 @@ function report_security_check_defaultuserrole($detailed=false) {
$riskycount = $DB->count_records_sql($sql, $params);
// default role can not have view cap in all courses - this would break moodle badly
$viewcap = $DB->record_exists('role_capabilities', array('roleid'=>$default_role->id, 'permission'=>CAP_ALLOW, 'capability'=>'moodle/course:participate'));
// it may have either none or 'user' archetype - nothing else, or else it would break during upgrades badly
if ($default_role->archetype === '' or $default_role->archetype === 'user') {
$legacyok = true;
......@@ -597,7 +592,7 @@ function report_security_check_defaultuserrole($detailed=false) {
$legacyok = false;
}
if ($riskycount or $viewcap or !$legacyok) {
if ($riskycount or !$legacyok) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_defaultuserrole_error', 'report_security', format_string($default_role->name));
......@@ -730,190 +725,6 @@ function report_security_check_frontpagerole($detailed=false) {
return $result;
}
/**
* Verifies sanity of site default course role.
* @param bool $detailed
* @return object result
*/
function report_security_check_defaultcourserole($detailed=false) {
global $DB, $CFG;
$problems = array();