Index: group/assign.php =================================================================== --- group/assign.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ group/assign.php (revision ) @@ -86,9 +86,9 @@ } // Get course managers so they can be hilited in the list - if ($managerroles = get_config('', 'coursemanager')) { - $coursemanagerroles = split(',', $managerroles); - foreach ($coursemanagerroles as $roleid) { + if ($managerroles = get_config('', 'coursecontact')) { + $coursecontactroles = split(',', $managerroles); + foreach ($coursecontactroles as $roleid) { $role = $DB->get_record('role', array('id'=>$roleid)); $managers = get_role_users($roleid, $context, true, 'u.id', 'u.id ASC'); } Index: admin/mnet/enr_hosts.php =================================================================== --- admin/mnet/enr_hosts.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/mnet/enr_hosts.php (revision ) @@ -8,10 +8,8 @@ admin_externalpage_setup('mnetenrol'); - require_once("$CFG->dirroot/enrol/enrol.class.php"); /// Open the factory class + $enrolment = enrol_get_plugin('mnet'); - $enrolment = enrolment_factory::factory('mnet'); - /// Otherwise fill and print the form. /// get language strings Index: enrol/authorize/db/upgrade.php =================================================================== --- enrol/authorize/db/upgrade.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/authorize/db/upgrade.php (revision ) @@ -28,7 +28,7 @@ //===== 1.9.0 upgrade line ======// - if ($result && $oldversion < 2008020500 && is_enabled_enrol('authorize')) { + if ($result && $oldversion < 2008020500 && enrol_is_enabled('authorize')) { require_once($CFG->dirroot.'/enrol/authorize/localfuncs.php'); if (!check_curl_available()) { echo $OUTPUT->notification("You are using the authorize.net enrolment plugin for payment handling but cUrl is not available. Index: enrol/manual/lang/en/enrol_manual.php =================================================================== --- enrol/manual/lang/en/enrol_manual.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/manual/lang/en/enrol_manual.php (revision ) @@ -23,16 +23,12 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -$string['description'] = 'This is the default form of enrolment. There are two main ways a student can be enrolled in a particular course. -'; -$string['enrol_manual_requirekey'] = 'Require course enrolment keys in new courses and prevent removing of existing keys.'; -$string['enrol_manual_showhint'] = 'Enable this setting to reveal the first character of the enrolment key as a hint if one enters an incorrect key.'; -$string['enrol_manual_usepasswordpolicy'] = 'Use current user password policy for course enrolment keys.'; -$string['enrolmentkeyerror'] = 'That enrolment key was incorrect, please try again.'; -$string['enrolname'] = 'Internal Enrolment'; -$string['keyholderrole'] = 'The role of the user that holds the enrolment key for a course. Displayed to students attempting to enrol on the course.'; +$string['assignrole'] = 'Assignrole'; +$string['defaultperiod'] = 'Default enrolment period'; +$string['defaultperiod_desc'] = 'Default length of the default enrolment period setting (in seconds).'; //TODO: fixme +$string['pluginname'] = 'Internal enrolments'; +$string['pluginname_desc'] = 'Internal enrolments is a basic enrolment plugin which allows simple user enrolments. It should be kept enabled in most cases. Some other plugins such as self enrolment may use this pugin internally.'; +$string['status'] = 'Enable internal enrolments'; +$string['status_desc'] = 'Allow course access of internally enrolled users. This should be kept enabled in most cases.'; +$string['statusenabled'] = 'Enabled'; +$string['statusdisabled'] = 'Disabled'; Index: enrol/database/enrol.php =================================================================== --- enrol/database/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/database/enrol.php (revision ) @@ -1,7 +1,6 @@ libdir.'/adodb/adodb.inc.php'); -require_once($CFG->dirroot.'/enrol/enrol.class.php'); class enrolment_plugin_database { @@ -146,7 +145,8 @@ } //error_log('[ENROL_DB] Enrolling user in course '.$course->idnumber); - role_assign($role->id, $user->id, 0, $context->id, 0, 0, 0, 'database'); + //TODO: do some real enrolment here + role_assign($role->id, $user->id, $context->id, 'enrol_database'); } } // We've processed all external courses found @@ -157,7 +157,7 @@ foreach ($existing as $role_assignment) { if ($role_assignment->enrol == 'database') { //error_log('[ENROL_DB] Removing user from context '.$role_assignment->contextid); - role_unassign($role_assignment->roleid, $user->id, '', $role_assignment->contextid); + role_unassign($role_assignment->roleid, $user->id, $role_assignment->contextid); } } } @@ -318,14 +318,11 @@ if ($to_prune) { foreach ($to_prune as $role_assignment) { - if (role_unassign($role->id, $role_assignment->userid, 0, $role_assignment->contextid)){ + role_unassign($role->id, $role_assignment->userid, $role_assignment->contextid); - error_log( "Unassigned {$role->shortname} assignment #{$role_assignment->id} for course {$course->id} (" . format_string($course->shortname) . "); user {$role_assignment->userid}"); + error_log( "Unassigned {$role->shortname} assignment #{$role_assignment->id} for course {$course->id} (" . format_string($course->shortname) . "); user {$role_assignment->userid}"); - } else { - error_log( "Failed to unassign {$role->shortname} assignment #{$role_assignment->id} for course {$course->id} (" . format_string($course->shortname) . "); user {$role_assignment->userid}"); - } - } - } + } + } + } - } // // insert current enrolments @@ -359,7 +356,8 @@ continue; } - if (role_assign($role->id, $userid, 0, $context->id, 0, 0, 0, 'database')){ + //TODO: real enrolment here + if (role_assign($role->id, $userid, $context->id, 'enrol_database')){ error_log( "Assigned role {$role->shortname} to user {$userid} in course {$course->id} (" . format_string($course->shortname) . ")"); } else { error_log( "Failed to assign role {$role->shortname} to user {$userid} in course {$course->id} (" . format_string($course->shortname) . ")"); @@ -409,12 +407,9 @@ $roleid = $user_obj->roleid; $user = $user_obj->userid; $contextid = $user_obj->contextid; - if (role_unassign($roleid, $user, 0, $contextid)){ + role_unassign($roleid, $user, $contextid); - error_log( "Unassigned role {$roleid} from user $user in context $contextid"); + error_log( "Unassigned role {$roleid} from user $user in context $contextid"); - } else { - error_log( "Failed unassign role {$roleid} from user $user in context $contextid"); - } + } - } $ers->close(); // release the handle } Index: enrol/self/locallib.php =================================================================== --- enrol/self/locallib.php (revision ) +++ enrol/self/locallib.php (revision ) @@ -0,0 +1,81 @@ +. + +/** + * Selfenrol plugin implementation. + * + * @package enrol_self + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once("$CFG->libdir/formslib.php"); + +class enrol_self_enrol_form extends moodleform { + protected $instance; + + public function definition() { + $mform = $this->_form; + $instance = $this->_customdata; + $this->instance = $instance; + + if ($instance->password) { + $heading = empty($instance->name) ? get_string('pluginname', 'enrol_self') : format_string($instance->name); + $mform->addElement('header', 'selfheader', $heading); + $mform->addElement('passwordunmask', 'enrolpassword', get_string('password', 'enrol_self')); + } else { + // nothing? + } + + $this->add_action_buttons(false, get_string('enrolme', 'enrol_self')); + + $mform->addElement('hidden', 'id'); + $mform->setType('id', PARAM_INT); + $mform->setDefault('id', $instance->courseid); + + $mform->addElement('hidden', 'instance'); + $mform->setType('instance', PARAM_INT); + $mform->setDefault('instance', $instance->id); + } + + public function validation($data, $files) { + global $DB, $CFG; + + $errors = parent::validation($data, $files); + $instance = $this->instance; + + if ($instance->password) { + if ($data['enrolpassword'] !== $instance->password) { + if ($instance->customint1) { + //TODO: check groups + + } else { + $plugin = enrol_get_plugin('self'); + if ($plugin->get_config('showhint')) { + $textlib = textlib_get_instance(); + $hint = $textlib->substr($instance->password, 0, 1); + $errors['enrolpassword'] = get_string('passwordinvalidhint', 'enrol_self', $hint); + } else { + $errors['enrolpassword'] = get_string('passwordinvalid', 'enrol_self'); + } + } + } + } + + return $errors; + } +} \ No newline at end of file Index: enrol/authorize/locallib.php =================================================================== --- enrol/authorize/locallib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/authorize/locallib.php (revision ) @@ -358,7 +358,7 @@ } else { if (!empty($unenrol)) { - role_unassign(0, $order->userid, 0, $coursecontext->id); + role_unassign_all(array('userid'=>$order->userid, 'contextid'=>$coursecontext->id, 'component'=>'enrol_authorize'), true, true); } redirect("$CFG->wwwroot/enrol/authorize/index.php?order=$orderid"); } @@ -383,7 +383,7 @@ elseif (ORDER_DELETE == $do && in_array(ORDER_DELETE, $statusandactions->actions)) { if ($confirm && confirm_sesskey()) { if (!empty($unenrol)) { - role_unassign(0, $order->userid, 0, $coursecontext->id); + role_unassign_all(array('userid'=>$order->userid, 'contextid'=>$coursecontext->id, 'component'=>'enrol_authorize'), true, true); } $DB->delete_records('enrol_authorize', array('id'=>$orderid)); redirect("$CFG->wwwroot/enrol/authorize/index.php"); @@ -436,7 +436,7 @@ if (AN_APPROVED == AuthorizeNet::process($suborder, $message, $extra, AN_ACTION_VOID)) { if (empty($CFG->an_test)) { if (!empty($unenrol)) { - role_unassign(0, $order->userid, 0, $coursecontext->id); + role_unassign_all(array('userid'=>$order->userid, 'contextid'=>$coursecontext->id, 'component'=>'enrol_authorize'), true, true); } redirect("$CFG->wwwroot/enrol/authorize/index.php?order=$orderid"); } Index: lib/moodlelib.php =================================================================== --- lib/moodlelib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/moodlelib.php (revision ) @@ -2106,86 +2106,91 @@ * case they are automatically logged in as guests. * If $courseid is given and the user is not enrolled in that course then the * user is redirected to the course enrolment page. - * If $cm is given and the coursemodule is hidden and the user is not a teacher + * If $cm is given and the course module is hidden and the user is not a teacher * in the course then the user is redirected to the course home page. * * When $cm parameter specified, this function sets page layout to 'module'. * You need to change it manually later if some other layout needed. * - * @global object - * @global object - * @global object - * @global object - * @global string - * @global object - * @global object - * @global object - * @uses SITEID Define * @param mixed $courseorid id of the course or course object * @param bool $autologinguest default true * @param object $cm course module object * @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to * true. Used to avoid (=false) some scripts (file.php...) to set that variable, * in order to keep redirects working properly. MDL-14495 + * @param bool $preventredirect set to true in scripts that can not redirect (CLI, rss feeds, etc.), throws exceptions * @return mixed Void, exit, and die depending on path */ -function require_login($courseorid=0, $autologinguest=true, $cm=null, $setwantsurltome=true) { - global $CFG, $SESSION, $USER, $COURSE, $FULLME, $PAGE, $SITE, $DB, $OUTPUT; +function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false) { + global $CFG, $SESSION, $USER, $FULLME, $PAGE, $SITE, $DB, $OUTPUT; -/// setup global $COURSE, themes, language and locale + // 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)); - if (!$course) { - throw new moodle_exception('invalidcourseid'); + $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!!'); + } $PAGE->set_cm($cm, $course); // set's up global $COURSE $PAGE->set_pagelayout('incourse'); } else { $PAGE->set_course($course); // set's up global $COURSE } } else { - // do not touch global $COURSE via $PAGE->set_course() !! + // 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 the user is not even logged in yet then make sure they are if (!isloggedin()) { //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) { $SESSION->wantsurl = $FULLME; } if (!empty($_SERVER['HTTP_REFERER'])) { $SESSION->fromurl = $_SERVER['HTTP_REFERER']; } - if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests) and ($COURSE->id == SITEID or $COURSE->guest) ) { + if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests)) { + if ($course->id == SITEID) { - $loginguest = true; - } else { - $loginguest = false; - } + $loginguest = true; + } else { + $loginguest = false; + } + } else { + $loginguest = false; + } redirect(get_login_url($loginguest)); exit; // never reached } -/// loginas as redirection if needed - if ($COURSE->id != SITEID and session_is_loggedinas()) { + // 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) { + 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) + // 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()) { + if ($userauth->can_change_password() and !$preventredirect) { $SESSION->wantsurl = $FULLME; if ($changeurl = $userauth->change_password_url()) { //use plugin custom url @@ -2204,154 +2209,235 @@ } } -/// Check that the user account is properly set up + // 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 checking script parameters. + // Make sure the USER has a sesskey set up. Used for CSRF protection. sesskey(); + // Do not bother admins with any formalities, no last access updates either + if (is_siteadmin()) { + return; + } + // Check that the user has agreed to a site policy if there is one if (!empty($CFG->sitepolicy)) { + if ($preventredirect) { + throw new require_login_exception('Policy not agreed'); + } if (!$USER->policyagreed) { $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot .'/user/policy.php'); } } - // Fetch the system context, we are going to use it a lot. + // 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; + } -/// If the site is currently under maintenance, then print a message + // If the site is currently under maintenance, then print a message if (!empty($CFG->maintenance_enabled) and !has_capability('moodle/site:config', $sysctx)) { + if ($preventredirect) { + throw new require_login_exception('Maintenance in progress'); + } + print_maintenance_message(); } -/// groupmembersonly access control - if (!empty($CFG->enablegroupmembersonly) and $cm and $cm->groupmembersonly and !has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id))) { - if (isguestuser() or !groups_has_membership($cm)) { - print_error('groupmembersonlyerror', 'group', $CFG->wwwroot.'/course/view.php?id='.$cm->course); + // make sure the course itself is not hidden + if ($course->id == SITEID) { + // frontpage can not be hidden + } else { + if (!empty($USER->access['rsw'][$coursecontext->path])) { + // 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 .'/'); - } + } - - // Fetch the course context, and prefetch its child contexts - $coursecontext = get_context_instance(CONTEXT_COURSE, $COURSE->id, MUST_EXIST); - if ($cm) { - $cmcontext = get_context_instance(CONTEXT_MODULE, $cm->id, MUST_EXIST); - } + } - - // Conditional activity access control - if (!empty($CFG->enableavailability) and $cm) { - // We cache conditional access in session - if (!isset($SESSION->conditionaccessok)) { - $SESSION->conditionaccessok = array(); - } + } - // If you have been allowed into the module once then you are allowed - // in for rest of session, no need to do conditional checks - if (!array_key_exists($cm->id, $SESSION->conditionaccessok)) { - // Get condition info (does a query for the availability table) - require_once($CFG->libdir.'/conditionlib.php'); - $ci = new condition_info($cm, CONDITION_MISSING_EXTRATABLE); - // Check condition for user (this will do a query if the availability - // information depends on grade or completion information) - if ($ci->is_available($junk) || has_capability('moodle/course:viewhiddenactivities', $cmcontext)) { - $SESSION->conditionaccessok[$cm->id] = true; + + // is the user enrolled? + if ($course->id == SITEID) { + // everybody is enrolled on the frontpage + - } else { + } else { - print_error('activityiscurrentlyhidden'); + 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 .'/'); - } - } + } + } - if ($COURSE->id == SITEID) { - /// Eliminate hidden site activities straight away - if ($cm && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $cmcontext)) { - redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden')); + // 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(); } - user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times - return; - } else { + $access = false; - /// Check if the user can be in a particular course - if (empty($USER->access['rsw'][$coursecontext->path])) { - // - // MDL-13900 - If the course or the parent category are hidden - // and the user hasn't the 'course:viewhiddencourses' capability, prevent access - // - if ( !($COURSE->visible && course_parent_visible($COURSE)) && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { - echo $OUTPUT->header(); - notice(get_string('coursehidden'), $CFG->wwwroot .'/'); + 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 (is_enrolled($coursecontext) or is_viewing($coursecontext)) { - // Enrolled user or allowed to visit course (managers, inspectors, etc.) - if (session_is_loggedinas()) { // Make sure the REAL person can also access this course - $realuser = session_get_realuser(); - if (!is_enrolled($coursecontext, $realuser->id) and !is_viewing($coursecontext, $realuser->id) and !is_siteadmin($realuser->id)) { - echo $OUTPUT->header(); - notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot .'/'); + 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); } } - // Make sure they can read this activity too, if specified - if ($cm && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $cmcontext)) { - redirect($CFG->wwwroot.'/course/view.php?id='.$cm->course, get_string('activityiscurrentlyhidden')); + 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(cp.timeend) + FROM {course_participants} cp + JOIN {enrol} e ON (e.id = cp.enrolid AND e.courseid = :courseid) + JOIN {user} u ON u.id = cp.userid + WHERE cp.userid = :userid AND cp.status = :active AND e.status = :enabled AND u.deleted = 0 + AND cp.timestart < :now1 AND (cp.timeend = 0 OR cp.timeend > :now2)"; + $params = array('enabled'=>ENROL_STATUS_ENABLED, 'active'=>ENROL_PARTICIPATION_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_accesstime_log($COURSE->id); /// Access granted, update lastaccess times - return; // User is allowed to see this course + $USER->enrol['enrolled'][$course->id] = $until; + $access = true; + + // remove traces of previous temp guest access + $USER->access = remove_temp_roles($coursecontext, $USER->access); + - } else { + } else { - // guest access - switch ($COURSE->guest) { /// Check course policy about guest access + $instances = $DB->get_records('enrol', array('courseid'=>$course->id, 'status'=>ENROL_STATUS_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; + } + $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; + } + $until = $enrols[$instance->enrol]->try_guestaccess($instance); + if ($until !== false) { + $USER->enrol['tempguest'][$course->id] = $until; + $access = true; + break; + } + } + } + } + } - case 1: /// Guests always allowed - if ($cm and !$cm->visible) { // Not allowed to see module, send to course page - redirect($CFG->wwwroot.'/course/view.php?id='.$cm->course, - get_string('activityiscurrentlyhidden')); + if (!$access) { + if ($preventredirect) { + throw new require_login_exception('Not enrolled'); - } + } + $SESSION->wantsurl = $FULLME; + redirect($CFG->wwwroot .'/enrol/index.php?id='. $course->id); + } + } - if ($USER->username != 'guest' and !empty($CFG->guestroleid)) { - // Non-guests who don't currently have access, check if they can be allowed in as a guest - // Temporarily assign them guest role for this context, if it fails later user is asked to enrol - $USER->access = load_temp_role($coursecontext, $CFG->guestroleid, $USER->access); + // test visibility + if ($cm && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $cmcontext)) { + if ($preventredirect) { + throw new require_login_exception('Activity is hidden'); - } + } + redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden')); + } - user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times - return; // User is allowed to see this course - - case 2: /// Guests allowed with key - if (!empty($USER->enrolkey[$COURSE->id])) { // Set by enrol/manual/enrol.php - user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times - return true; + // groupmembersonly access control + if (!empty($CFG->enablegroupmembersonly) and $cm and $cm->groupmembersonly and !has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id))) { + if (isguestuser() or !groups_has_membership($cm)) { + if ($preventredirect) { + throw new require_login_exception('Not member of a group'); - } + } - // otherwise drop through to logic below (--> enrol.php) - break; + print_error('groupmembersonlyerror', 'group', $CFG->wwwroot.'/course/view.php?id='.$cm->course); + } + } - default: /// Guests not allowed - $strloggedinasguest = get_string('loggedinasguest'); - $PAGE->navbar->add($strloggedinasguest); - echo $OUTPUT->header(); - if (empty($USER->access['rsw'][$coursecontext->path])) { // Normal guest - notice(get_string('guestsnotallowed', '', format_string($COURSE->fullname)), get_login_url()); + // Conditional activity access control + if (!empty($CFG->enableavailability) and $cm) { + // TODO: this is going to work with login-as-user, sorry! + // We cache conditional access in session + if (!isset($SESSION->conditionaccessok)) { + $SESSION->conditionaccessok = array(); + } + // If you have been allowed into the module once then you are allowed + // in for rest of session, no need to do conditional checks + if (!array_key_exists($cm->id, $SESSION->conditionaccessok)) { + // Get condition info (does a query for the availability table) + require_once($CFG->libdir.'/conditionlib.php'); + $ci = new condition_info($cm, CONDITION_MISSING_EXTRATABLE); + // Check condition for user (this will do a query if the availability + // information depends on grade or completion information) + if ($ci->is_available($junk) || has_capability('moodle/course:viewhiddenactivities', $cmcontext)) { + $SESSION->conditionaccessok[$cm->id] = true; - } else { + } else { - echo $OUTPUT->notification(get_string('guestsnotallowed', '', format_string($COURSE->fullname))); - echo '
'.switchroles_form($COURSE->id).'
'; - echo $OUTPUT->footer(); - exit; + print_error('activityiscurrentlyhidden'); - } + } - break; - } - } + } + } - // Currently not enrolled in the course, so see if they want to enrol - $SESSION->wantsurl = $FULLME; - redirect($CFG->wwwroot .'/course/enrol.php?id='. $COURSE->id); - die; + // Finally access granted, update lastaccess times + user_accesstime_log($course->id); - } +} -} /** @@ -2390,26 +2476,28 @@ * @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to * true. Used to avoid (=false) some scripts (file.php...) to set that variable, * in order to keep redirects working properly. MDL-14495 + * @param bool $preventredirect set to true in scripts that can not redirect (CLI, rss feeds, etc.), throws exceptions + * @return void */ -function require_course_login($courseorid, $autologinguest=true, $cm=null, $setwantsurltome=true) { +function require_course_login($courseorid, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false) { global $CFG, $PAGE, $SITE; if (!empty($CFG->forcelogin)) { // login required for both SITE and courses - require_login($courseorid, $autologinguest, $cm, $setwantsurltome); + require_login($courseorid, $autologinguest, $cm, $setwantsurltome, $preventredirect); } else if (!empty($cm) and !$cm->visible) { // always login for hidden activities - require_login($courseorid, $autologinguest, $cm, $setwantsurltome); + require_login($courseorid, $autologinguest, $cm, $setwantsurltome, $preventredirect); } else if ((is_object($courseorid) and $courseorid->id == SITEID) or (!is_object($courseorid) and $courseorid == SITEID)) { //login for SITE not required if ($cm and empty($cm->visible)) { // hidden activities are not accessible without login - require_login($courseorid, $autologinguest, $cm, $setwantsurltome); + require_login($courseorid, $autologinguest, $cm, $setwantsurltome, $preventredirect); } else if ($cm and !empty($CFG->enablegroupmembersonly) and $cm->groupmembersonly) { // not-logged-in users do not have any group membership - require_login($courseorid, $autologinguest, $cm, $setwantsurltome); + require_login($courseorid, $autologinguest, $cm, $setwantsurltome, $preventredirect); } else { // We still need to instatiate PAGE vars properly so that things // that rely on it like navigation function correctly. @@ -2420,6 +2508,9 @@ $course = clone($SITE); } if ($cm) { + if ($cm->course != $course->id) { + throw new coding_exception('course and cm parameters in require_course_login() call do not match!!'); + } $PAGE->set_cm($cm, $course); $PAGE->set_pagelayout('incourse'); } else { @@ -2437,7 +2528,7 @@ } else { // course login always required - require_login($courseorid, $autologinguest, $cm, $setwantsurltome); + require_login($courseorid, $autologinguest, $cm, $setwantsurltome, $preventredirect); } } @@ -2707,25 +2798,6 @@ } /** - * Sync all meta courses - * Goes through all enrolment records for the courses inside all metacourses and syncs with them. - * @see sync_metacourse() - * - * @global object - */ -function sync_metacourses() { - global $DB; - - if (!$courses = $DB->get_records('course', array('metacourse'=>1))) { - return; - } - - foreach ($courses as $course) { - sync_metacourse($course); - } -} - -/** * Returns reference to full info about modules in course (including visibility). * Cached and as fast as possible (0 or 1 db query). * @@ -2922,157 +2994,6 @@ } /** - * Goes through all enrolment records for the courses inside the metacourse and sync with them. - * - * @todo finish timeend and timestart maybe we could rely on cron - * job to do the cleaning from time to time - * - * @global object - * @global object - * @uses CONTEXT_COURSE - * @param mixed $course the metacourse to synch. Either the course object itself, or the courseid. - * @return bool Success - */ -function sync_metacourse($course) { - global $CFG, $DB; - - // Check the course is valid. - if (!is_object($course)) { - if (!$course = $DB->get_record('course', array('id'=>$course))) { - return false; // invalid course id - } - } - - // Check that we actually have a metacourse. - if (empty($course->metacourse)) { - return false; - } - - // Get a list of roles that should not be synced. - if (!empty($CFG->nonmetacoursesyncroleids)) { - $roleexclusions = 'ra.roleid NOT IN (' . $CFG->nonmetacoursesyncroleids . ') AND'; - } else { - $roleexclusions = ''; - } - - // Get the context of the metacourse. - $context = get_context_instance(CONTEXT_COURSE, $course->id); // SITEID can not be a metacourse - - // We do not ever want to unassign the list of metacourse manager, so get a list of them. - if ($users = get_users_by_capability($context, 'moodle/course:managemetacourse')) { - $managers = array_keys($users); - } else { - $managers = array(); - } - - // Get assignments of a user to a role that exist in a child course, but - // not in the meta coure. That is, get a list of the assignments that need to be made. - if (!$assignments = $DB->get_records_sql(" - SELECT ra.id, ra.roleid, ra.userid - FROM {role_assignments} ra, {context} con, {course_meta} cm - WHERE ra.contextid = con.id AND - con.contextlevel = ".CONTEXT_COURSE." AND - con.instanceid = cm.child_course AND - cm.parent_course = ? AND - $roleexclusions - NOT EXISTS ( - SELECT 1 - FROM {role_assignments} ra2 - WHERE ra2.userid = ra.userid AND - ra2.roleid = ra.roleid AND - ra2.contextid = ? - )", array($course->id, $context->id))) { - $assignments = array(); - } - - // Get assignments of a user to a role that exist in the meta course, but - // not in any child courses. That is, get a list of the unassignments that need to be made. - if (!$unassignments = $DB->get_records_sql(" - SELECT ra.id, ra.roleid, ra.userid - FROM {role_assignments} ra - WHERE ra.contextid = ? AND - $roleexclusions - NOT EXISTS ( - SELECT 1 - FROM {role_assignments} ra2, {context} con2, {course_meta} cm - WHERE ra2.userid = ra.userid AND - ra2.roleid = ra.roleid AND - ra2.contextid = con2.id AND - con2.contextlevel = " . CONTEXT_COURSE . " AND - con2.instanceid = cm.child_course AND - cm.parent_course = ? - )", array($context->id, $course->id))) { - $unassignments = array(); - } - - $success = true; - - // Make the unassignments, if they are not managers. - foreach ($unassignments as $unassignment) { - if (!in_array($unassignment->userid, $managers)) { - $success = role_unassign($unassignment->roleid, $unassignment->userid, 0, $context->id) && $success; - } - } - - // Make the assignments. - foreach ($assignments as $assignment) { - $success = role_assign($assignment->roleid, $assignment->userid, 0, $context->id, 0, 0) && $success; - } - - return $success; - -// TODO: finish timeend and timestart -// maybe we could rely on cron job to do the cleaning from time to time -} - -/** - * Adds a record to the metacourse table and calls sync_metacoures - * - * @global object - * @param int $metacourseid The Metacourse ID for the metacourse to add to - * @param int $courseid The Course ID of the course to add - * @return bool Success - */ -function add_to_metacourse ($metacourseid, $courseid) { - global $DB; - - if (!$metacourse = $DB->get_record("course", array("id"=>$metacourseid))) { - return false; - } - - if (!$course = $DB->get_record("course", array("id"=>$courseid))) { - return false; - } - - if (!$record = $DB->get_record("course_meta", array("parent_course"=>$metacourseid, "child_course"=>$courseid))) { - $rec = new object(); - $rec->parent_course = $metacourseid; - $rec->child_course = $courseid; - $DB->insert_record('course_meta', $rec); - return sync_metacourse($metacourseid); - } - return true; - -} - -/** - * Removes the record from the metacourse table and calls sync_metacourse - * - * @global object - * @param int $metacourseid The Metacourse ID for the metacourse to remove from - * @param int $courseid The Course ID of the course to remove - * @return bool Success - */ -function remove_from_metacourse($metacourseid, $courseid) { - global $DB; - - if ($DB->delete_records('course_meta', array('parent_course'=>$metacourseid, 'child_course'=>$courseid))) { - return sync_metacourse($metacourseid); - } - return false; -} - -/** * Determines if the currently logged in user is in editing mode. * Note: originally this function had $userid parameter - it was not usable anyway * @@ -3450,13 +3371,13 @@ require_once($CFG->libdir.'/grouplib.php'); require_once($CFG->libdir.'/gradelib.php'); require_once($CFG->dirroot.'/message/lib.php'); - - // delete all grades - backup is kept in grade_grades_history table - if ($grades = grade_grade::fetch_all(array('userid'=>$user->id))) { - foreach ($grades as $grade) { - $grade->delete('userdelete'); - } - } + + // delete all grades - backup is kept in grade_grades_history table + if ($grades = grade_grade::fetch_all(array('userid'=>$user->id))) { + foreach ($grades as $grade) { + $grade->delete('userdelete'); + } + } //move unread messages from this user to read message_move_userfrom_unread2read($user->id); @@ -3468,9 +3389,9 @@ $DB->delete_records('groups_members', array('userid'=>$user->id)); // unenrol from all roles in all contexts - role_unassign(0, $user->id); // this might be slow but it is really needed - modules might do some extra cleanup! + role_unassign_all(array('userid'=>$user->id)); // this might be slow but it is really needed - modules might do some extra cleanup! - // now do a final accesslib cleanup - removes all role assingments in user context and context itself + // now do a final accesslib cleanup - removes all role assignments in user context and context itself delete_context(CONTEXT_USER, $user->id); require_once($CFG->dirroot.'/tag/lib.php'); @@ -4125,26 +4046,6 @@ } } - -/// Clean up metacourse stuff - - if ($course->metacourse) { - $DB->delete_records("course_meta", array("parent_course"=>$course->id)); - sync_metacourse($course->id); // have to do it here so the enrolments get nuked. sync_metacourses won't find it without the id. - if ($showfeedback) { - echo $OUTPUT->notification("$strdeleted course_meta"); - } - } else { - if ($parents = $DB->get_records("course_meta", array("child_course"=>$course->id))) { - foreach ($parents as $parent) { - remove_from_metacourse($parent->parent_course,$parent->child_course); // this will do the unenrolments as well. - } - if ($showfeedback) { - echo $OUTPUT->notification("$strdeleted course_meta"); - } - } - } - /// Delete questions and question categories question_delete_course($course, $showfeedback); @@ -4270,7 +4171,7 @@ if (!empty($data->reset_roles_local)) { $children = get_child_contexts($context); foreach ($children as $child) { - role_unassign(0, 0, 0, $child->id); + role_unassign_all(array('contextid'=>$child->id)); } //force refresh for logged in users mark_context_dirty($context->path); @@ -4283,7 +4184,7 @@ foreach($data->reset_roles as $roleid) { if ($users = get_role_users($roleid, $context, false, 'u.id', 'u.id ASC')) { foreach ($users as $user) { - role_unassign($roleid, $user->id, 0, $context->id); + role_unassign($roleid, $user->id, $context->id); if (!is_enrolled($context, $user->id)) { $data->unenrolled[$user->id] = $user->id; } @@ -5038,54 +4939,6 @@ return false; } -/** - * Send welcome email to specified user - * - * @global object - * @global object - * @param object $course - * @param user $user A {@link $USER} object - * @return bool - */ -function email_welcome_message_to_user($course, $user=NULL) { - global $CFG, $USER; - - if (isset($CFG->sendcoursewelcomemessage) and !$CFG->sendcoursewelcomemessage) { - return; - } - - if (empty($user)) { - if (!isloggedin()) { - return false; - } - $user = $USER; - } - - if (!empty($course->welcomemessage)) { - $message = $course->welcomemessage; - } else { - $a = new object(); - $a->coursename = $course->fullname; - $a->profileurl = "$CFG->wwwroot/user/view.php?id=$user->id&course=$course->id"; - $message = get_string("welcometocoursetext", "", $a); - } - - /// If you don't want a welcome message sent, then make the message string blank. - if (!empty($message)) { - $subject = get_string('welcometocourse', '', format_string($course->fullname)); - - $context = get_context_instance(CONTEXT_COURSE, $course->id); - // TODO: replace with $CFG->coursemanager test, 'moodle/course:update' is very wrong!! - if ($users = get_users_by_capability($context, 'moodle/course:update', 'u.*', 'u.id ASC','', '', '', '', false, true)) { - $users = sort_by_roleassignment_authority($users, $context); - $teacher = array_shift($users); - } else { - $teacher = get_admin(); - } - email_to_user($user, $teacher, $subject, $message); - } -} - /// FILE HANDLING ///////////////////////////////////////////// /** @@ -6916,6 +6769,7 @@ 'dock' => NULL, 'editor' => 'lib/editor', 'edufields' => NULL, + 'enrol' => 'enrol', 'error' => NULL, 'filepicker' => NULL, 'filters' => NULL, @@ -9223,23 +9077,6 @@ } /** - * Checks if a given plugin is in the list of enabled enrolment plugins. - * - * @global object - * @param string $auth Enrolment plugin. - * @return boolean Whether the plugin is enabled. - */ -function is_enabled_enrol($enrol='') { - global $CFG; - - // use the global default if not specified - if ($enrol == '') { - $enrol = $CFG->enrol; - } - return in_array($enrol, explode(',', $CFG->enrol_plugins_enabled)); -} - -/** * This function will search for browser prefereed languages, setting Moodle * to use the best one available if $SESSION->lang is undefined * @@ -9454,7 +9291,7 @@ } } - /** +/** * Returns the site identifier * * @global object Index: admin/settings/appearance.php =================================================================== --- admin/settings/appearance.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/settings/appearance.php (revision ) @@ -128,9 +128,9 @@ $temp->add(new admin_setting_configtext('mycoursesperpage', get_string('mycoursesperpage', 'admin'), get_string('configmycoursesperpage', 'admin'), 21, PARAM_INT)); $ADMIN->add('appearance', $temp); - // coursemanager is the person responsible for course - usually manages enrolments, receives notification, etc. - $temp = new admin_settingpage('coursemanager', get_string('coursemanager', 'admin')); - $temp->add(new admin_setting_special_coursemanager()); + // coursecontact is the person responsible for course - usually manages enrolments, receives notification, etc. + $temp = new admin_settingpage('coursecontact', get_string('coursecontact', 'admin')); + $temp->add(new admin_setting_special_coursecontact()); $ADMIN->add('appearance', $temp); $temp = new admin_settingpage('ajax', get_string('ajaxuse')); Index: course/unenrol.php =================================================================== --- course/unenrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/unenrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,123 +0,0 @@ -. - -/** - * Remove oneself or someone else from a course, unassigning all roles one might have - * - * This will not delete any of their data from the course, but will remove them - * from the participant list and prevent any course email being sent to them. - * - * @copyright 1999 Martin Dougiamas http://dougiamas.com - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @package course - */ - -require_once("../config.php"); -require_once("lib.php"); - -$id = required_param('id', PARAM_INT); //course -$userid = optional_param('user', 0, PARAM_INT); //course -$confirm = optional_param('confirm', 0, PARAM_BOOL); - -$PAGE->set_url('/course/unenrol.php', array('id'=>$id)); - -if($userid == $USER->id){ - // the rest of this code assumes $userid=0 means - // you are unassigning yourself, so set this for the - // correct capabiliy checks & language later - $userid = 0; -} - -if (!$course = $DB->get_record('course', array('id'=>$id))) { - print_error('invalidcourseid'); -} - -if (! $context = get_context_instance(CONTEXT_COURSE, $course->id)) { - print_error('invalidcontext'); -} - -require_login($course->id); - -if ($course->metacourse) { - print_error('cantunenrollfrommetacourse', '', $CFG->wwwroot.'/course/view.php?id='.$course->id); -} - -if ($userid) { // Unenrolling someone else - require_capability('moodle/role:assign', $context, NULL, false); - - $roles = get_user_roles($context, $userid, false); - - // verify user may unassign all roles at course context - foreach($roles as $role) { - if (!user_can_assign($context, $role->roleid)) { - print_error('cannotunassignrolefrom', '', '', - $role->roleid); - } - } - -} else { // Unenrol yourself - require_capability('moodle/role:unassignself', $context, NULL, false); -} - -if (!empty($USER->access['rsw'][$context->path])) { - print_error('cantunenrollinthisrole', '', - $CFG->wwwroot.'/course/view.php?id='.$course->id); -} - -if ($confirm and confirm_sesskey()) { - if ($userid) { - if (! role_unassign(0, $userid, 0, $context->id)) { - print_error("unenrolerror"); - } - - add_to_log($course->id, 'course', 'unenrol', - "view.php?id=$course->id", $course->id); - redirect($CFG->wwwroot.'/user/index.php?id='.$course->id); - - } else { - if (! role_unassign(0, $USER->id, 0, $context->id)) { - print_error("unenrolerror"); - } - - // force a refresh of mycourses - unset($USER->mycourses); - add_to_log($course->id, 'course', 'unenrol', - "view.php?id=$course->id", $course->id); - - redirect($CFG->wwwroot); - } -} - - -$strunenrol = get_string('unenrol'); -$PAGE->navbar->add($strunenrol); -$PAGE->set_title("$course->shortname: $strunenrol"); -$PAGE->set_heading($course->fullname); -echo $OUTPUT->header(); -if ($userid) { - if (!$user = $DB->get_record('user', array('id'=>$userid))) { - print_error('nousers'); - } - $strunenrolsure = get_string('unenrolsure', '', fullname($user, true)); - echo $OUTPUT->confirm($strunenrolsure, "unenrol.php?id=$id&user=$user->id&confirm=yes", $PAGE->url); -} else { - $strunenrolsure = get_string('unenrolsure', '', get_string("yourself")); - echo $OUTPUT->confirm($strunenrolsure, "unenrol.php?id=$id&confirm=yes", $PAGE->url); -} - -echo $OUTPUT->footer(); - Index: tag/coursetagslib.php =================================================================== --- tag/coursetagslib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ tag/coursetagslib.php (revision ) @@ -399,7 +399,8 @@ //view, but arguably it is best that when clicking on a tag, the tagged course summary should //be seen and then if the student clicks on that they will be given the opportunity to join //note courses not visible should not have their tagid sent to this function - //if (has_capability('moodle/course:participate', get_context_instance(CONTEXT_COURSE, $c->itemid))) { + // $context = get_context_instance(CONTEXT_COURSE, $c->itemid); + //if (is_enrolled($context) oe is_viewing($context)) { $course = $DB->get_record('course', array('id'=>$c->itemid)); $courses[$c->itemid] = $course; //} Index: admin/roles/assign.php =================================================================== --- admin/roles/assign.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/roles/assign.php (revision ) @@ -31,8 +31,6 @@ $contextid = required_param('contextid',PARAM_INT); $roleid = optional_param('roleid', 0, PARAM_INT); -$extendperiod = optional_param('extendperiod', 0, PARAM_INT); -$extendbase = optional_param('extendbase', 3, PARAM_INT); list($context, $course, $cm) = get_context_info_array($contextid); @@ -58,7 +56,6 @@ $contextname = print_context_name($context); $courseid = $course->id; -$inmeta = $course->metacourse; $isfrontpage = ($course->id == SITEID); // These are needed early because of tabs.php @@ -87,40 +84,6 @@ } } -// Build the list of options for the enrolment period dropdown. -$unlimitedperiod = get_string('unlimited'); -for ($i=1; $i<=365; $i++) { - $seconds = $i * 86400; - $periodmenu[$seconds] = get_string('numdays', '', $i); -} -// Work out the apropriate default setting. -if ($extendperiod) { - $defaultperiod = $extendperiod; -} else { - $defaultperiod = $course->enrolperiod; -} - -// Build the list of options for the starting from dropdown. -$timeformat = get_string('strftimedatefullshort'); -$today = time(); -$today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0); - -// MDL-12420, preventing course start date showing up as an option at system context and front page roles. -if ($course->startdate > 0) { - $basemenu[2] = get_string('coursestart') . ' (' . userdate($course->startdate, $timeformat) . ')'; -} -if ($course->enrollable != 2 || ($course->enrolstartdate == 0 || $course->enrolstartdate <= $today) && ($course->enrolenddate == 0 || $course->enrolenddate > $today)) { - $basemenu[3] = get_string('today') . ' (' . userdate($today, $timeformat) . ')' ; -} -if ($course->enrollable == 2) { - if($course->enrolstartdate > 0) { - $basemenu[4] = get_string('courseenrolstart') . ' (' . userdate($course->enrolstartdate, $timeformat) . ')'; - } - if($course->enrolenddate > 0) { - $basemenu[5] = get_string('courseenrolend') . ' (' . userdate($course->enrolenddate, $timeformat) . ')'; - } -} - // Process any incoming role assignments before printing the header. if ($roleid) { @@ -138,48 +101,11 @@ foreach ($userstoassign as $adduser) { $allow = true; - if ($inmeta) { - if (has_capability('moodle/course:managemetacourse', $context, $adduser->id)) { - //ok - } else { - $managerroles = get_roles_with_capability('moodle/course:managemetacourse', CAP_ALLOW, $context); - if (!empty($managerroles) and !array_key_exists($roleid, $managerroles)) { - $erruser = $DB->get_record('user', array('id'=>$adduser->id), 'id, firstname, lastname'); - $errors[] = get_string('metaassignerror', 'role', fullname($erruser)); - $allow = false; - } - } - } if ($allow) { - switch($extendbase) { - case 2: - $timestart = $course->startdate; - break; - case 3: - $timestart = $today; - break; - case 4: - $timestart = $course->enrolstartdate; - break; - case 5: - $timestart = $course->enrolenddate; - break; + role_assign($roleid, $adduser->id, $context->id); - } + } - - if($extendperiod > 0) { - $timeend = $timestart + $extendperiod; - } else { - $timeend = 0; - } + } - if (! role_assign($roleid, $adduser->id, 0, $context->id, $timestart, $timeend)) { - $a = new stdClass; - $a->role = $assignableroles[$roleid]; - $a->user = fullname($adduser); - $errors[] = get_string('assignerror', 'role', $a); - } - } - } $potentialuserselector->invalidate_selected_users(); $currentuserselector->invalidate_selected_users(); @@ -197,19 +123,9 @@ if (!empty($userstounassign)) { foreach ($userstounassign as $removeuser) { - if (! role_unassign($roleid, $removeuser->id, 0, $context->id)) { - $a = new stdClass; - $a->role = $assignableroles[$roleid]; - $a->user = fullname($removeuser); - $errors[] = get_string('unassignerror', 'role', $a); - } else if ($inmeta) { - sync_metacourse($courseid); - $newroles = get_user_roles($context, $removeuser->id, false); - if (empty($newroles) || array_key_exists($roleid, $newroles)) { - $errors[] = get_string('metaunassignerror', 'role', fullname($removeuser)); + //TODO: add some protection for role unsasignment from some enrol/auth plugins + role_unassign_all(array('roleid'=>$roleid, 'userid'=>$removeuser->id, 'contextid'=>$context->id)); - } + } - } - } $potentialuserselector->invalidate_selected_users(); $currentuserselector->invalidate_selected_users(); @@ -288,16 +204,6 @@

- - - -


-

- -


-

-
@@ -350,11 +256,6 @@ // Print instruction echo $OUTPUT->heading(get_string('chooseroletoassign', 'role'), 3); - // sync metacourse enrolments if needed - if ($inmeta) { - sync_metacourse($course); - } - // Get the names of role holders for roles with between 1 and MAX_USERS_TO_LIST_PER_ROLE users, // and so determine whether to show the extra column. $roleholdernames = array(); Index: admin/generator.php =================================================================== --- admin/generator.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/generator.php (revision ) @@ -710,25 +710,18 @@ $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 { + $assigned_users[$random_user]++; + } + $this->verbose("Student $random_user was assigned to course $courseid."); - } else { - $this->verbose("Could not assign student $random_user to course $courseid!"); - if (!$this->get('ignore_errors')) { - die(); - } - } + } + } - } - } if (!$this->get('quiet')) { echo "$assigned_count user => course role assignments have been correctly performed.{$this->eolchar}"; Index: enrol/manual/manage.php =================================================================== --- enrol/manual/manage.php (revision ) +++ enrol/manual/manage.php (revision ) @@ -0,0 +1,184 @@ +. + +/** + * Manual user enrolment UI. + * + * @package enrol_manual + * @copyright 2009 Tim Hunt, 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require('../../config.php'); +require_once($CFG->dirroot.'/enrol/manual/locallib.php'); + +$id = required_param('id', PARAM_INT); // course id +$enrolid = required_param('enrolid', PARAM_INT); +$roleid = optional_param('roleid', -1, PARAM_INT); +$extendperiod = optional_param('extendperiod', 0, PARAM_INT); +$extendbase = optional_param('extendbase', 3, PARAM_INT); + +$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST); +$context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); + +require_login($course); +require_capability('enrol/manual:manage', $context); + +$instance = $DB->get_record('enrol', array('id'=>$enrolid, 'enrol'=>'manual'), '*', MUST_EXIST); +if ($roleid < 0) { + $roleid = $instance->defaultrole; +} +$roles = get_assignable_roles($context); +$roles = array('0'=>get_string('none')) + $roles; + +if (!isset($roles[$roleid])) { + // weird - security always first! + $roleid = 0; +} + +if (!$enrol_manual = enrol_get_plugin('manual')) { + throw coding_error('Can not instantiate enrol_manual'); +} + +$PAGE->set_url('/enrol/manual/manage.php', array('id'=>$course->id, 'enrolid'=>$instance->id)); + +// Create the user selector objects. +$options = array('enrolid' => $enrolid); + +$potentialuserselector = new enrol_manual_potential_participant('addselect', $options); +$currentuserselector = new enrol_manual_current_participant('removeselect', $options); + +// Build the list of options for the enrolment period dropdown. +$unlimitedperiod = get_string('unlimited'); +$periodmenu = array(); +for ($i=1; $i<=365; $i++) { + $seconds = $i * 86400; + $periodmenu[$seconds] = get_string('numdays', '', $i); +} +// Work out the apropriate default setting. +if ($extendperiod) { + $defaultperiod = $extendperiod; +} else { + $defaultperiod = $instance->enrolperiod; +} + +// Build the list of options for the starting from dropdown. +$timeformat = get_string('strftimedatefullshort'); +$today = time(); +$today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0); + +// enrolment start +$basemenu = array(); +if ($course->startdate > 0) { + $basemenu[2] = get_string('coursestart') . ' (' . userdate($course->startdate, $timeformat) . ')'; +} +$basemenu[3] = get_string('today') . ' (' . userdate($today, $timeformat) . ')' ; + +// process add and removes +if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) { + $userstoassign = $potentialuserselector->get_selected_users(); + if (!empty($userstoassign)) { + foreach($userstoassign as $adduser) { + switch($extendbase) { + case 2: + $timestart = $course->startdate; + break; + case 3: + default: + $timestart = $today; + break; + } + + if($extendperiod > 0) { + $timeend = $timestart + $extendperiod; + } else { + $timeend = 0; + } + $enrol_manual->enrol_user($instance, $adduser->id, $timestart, $timeend, $roleid); + } + + $potentialuserselector->invalidate_selected_users(); + $currentuserselector->invalidate_selected_users(); + + //TODO: log + } +} + +// Process incoming role unassignments +if (optional_param('remove', false, PARAM_BOOL) && confirm_sesskey()) { + $userstounassign = $currentuserselector->get_selected_users(); + if (!empty($userstounassign)) { + foreach($userstounassign as $removeuser) { + $enrol_manual->unenrol_user($instance, $removeuser->id); + } + + $potentialuserselector->invalidate_selected_users(); + $currentuserselector->invalidate_selected_users(); + + //TODO: log + } +} + + +echo $OUTPUT->header(); + +$currenttab = 'manual'; +require("$CFG->dirroot/enrol/tabs.php"); + + +?> +
+ + + + + + + + +
+

+ display() ?> +
+
+
+ +
+ +


+

+ +


+

+ +


+

+ +
+
+ +
+ +
+
+

+ display() ?> +
+
+footer(); \ No newline at end of file Index: backup/moodle2/backup_stepslib.php =================================================================== --- backup/moodle2/backup_stepslib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ backup/moodle2/backup_stepslib.php (revision ) @@ -202,7 +202,7 @@ /** * structure step that will generate the course.xml file for the course, including - * course category reference, tags, metacourse, modules restriction information + * course category reference, tags, modules restriction information * and some annotations (files & groupings) */ class backup_course_structure_step extends backup_structure_step { @@ -219,7 +219,7 @@ 'numsections', 'marker', 'maxbytes', 'showreports', 'visible', 'hiddensections', 'groupmode', 'groupmodeforce', 'defaultgroupingid', 'lang', 'theme', 'cost', - 'currency', 'timecreated', 'timemodified', 'metacourse', + 'currency', 'timecreated', 'timemodified', 'requested', 'restrictmodules', 'expirynotify', 'expirythreshold', 'notifystudents', 'enrollable', 'enrolstartdate', 'enrolenddate', 'enrol', 'defaultrole', 'enablecompletion')); @@ -307,8 +307,7 @@ $assignments = new backup_nested_element('role_assignments'); $assignment = new backup_nested_element('assignment', array('id'), array( - 'roleid', 'userid', 'hidden', 'timestart', - 'timeend', 'timemodified', 'modifierid', 'enrol', + 'roleid', 'userid', 'timemodified', 'modifierid', 'enrol', 'sortorder')); // Build the tree @@ -714,8 +713,7 @@ $assignments = new backup_nested_element('role_assignments'); $assignment = new backup_nested_element('assignment', array('id'), array( - 'roleid', 'userid', 'hidden', 'timestart', - 'timeend', 'timemodified', 'modifierid', 'enrol', + 'roleid', 'userid', 'timemodified', 'modifierid', 'enrol', 'sortorder')); // Build the tree Index: auth/mnet/auth.php =================================================================== --- auth/mnet/auth.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ auth/mnet/auth.php (revision ) @@ -87,7 +87,7 @@ } $userdata['myhosts'] = array(); - if($courses = get_my_courses($user->id, 'id', 'id, visible')) { + if ($courses = enrol_get_users_courses($user->id, false)) { $userdata['myhosts'][] = array('name'=> $SITE->shortname, 'url' => $CFG->wwwroot, 'count' => count($courses)); } @@ -352,10 +352,10 @@ $mnetrequest->add_param($remoteuser->username); $fields = 'id, category, sortorder, fullname, shortname, idnumber, summary, startdate, cost, currency, defaultrole, visible'; - $courses = get_my_courses($localuser->id, 'visible DESC,sortorder ASC', $fields); + $courses = enrol_get_users_courses($localuser->id, false, $fields, 'visible DESC,sortorder ASC'); if (is_array($courses) && !empty($courses)) { // Second request to do the JOINs that we'd have done - // inside get_my_courses() if we had been allowed + // inside enrol_get_users_courses() if we had been allowed $sql = "SELECT c.id, cc.name AS cat_name, cc.description AS cat_description, r.shortname as defaultrolename Index: enrol/self/lib.php =================================================================== --- enrol/self/lib.php (revision ) +++ enrol/self/lib.php (revision ) @@ -0,0 +1,411 @@ +. + +/** + * Self enrolment plugin. + * + * This plugin does not add entries to the course_participants table, + * instead it is relying on the manual enrolment plugin to do the actual + * work. + * + * @package enrol_self + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +class enrol_self_plugin extends enrol_plugin { + + public function enrol_user(stdClass $instance, $userid, $timestart = 0, $timeend = 0, $roleid = null) { + // nothing to do, we abuse the first instance of manual enrolment plugin + return; + } + + public function unenrol_user(stdClass $instance, $userid) { + // nothing to do, we enrolled via some manual plugin + return; + } + + /** + * Creates course enrol form, checks if form submitted + * and enrols user if necessary. It can also redirect. + * + * @param stdClass $instance + * @return string html text, usually a form in a text box + */ + public function enrol_page_hook(stdClass $instance) { + global $CFG, $OUTPUT, $SESSION, $USER, $DB; + + if (isguestuser()) { + // can not enrol guest!! + return null; + } + + if (!$manuals = $DB->get_records('enrol', array('enrol'=>'manual', 'courseid'=>$instance->courseid), 'sortorder,id ASC')) { + // we can not self enrol if no manual enrol plugin present, sorry + return null; + } + $manual = reset($manuals); + if (!$manualplugin = enrol_get_plugin('manual')) { + // weird, somebody deleted manual plugin + return null; + } + + if ($DB->record_exists('course_participants', array('userid'=>$USER->id, 'enrolid'=>$manual->id))) { + // user is already enrolled - does not matter if active, bad luck! + //TODO: maybe we should tell them they rea already enrolled, but can not access the course + return null; + } + + if ($instance->enrolstartdate != 0 and $instance->enrolstartdate < time) { + //TODO: inform that we can not enrol yet + return null; + } + + if ($instance->enrolenddate != 0 and $instance->enrolenddate > time) { + //TODO: inform that enrolment is not possible any more + return null; + } + + require_once("$CFG->dirroot/enrol/self/locallib.php"); + $form = new enrol_self_enrol_form(NULL, $instance); + $instanceid = optional_param('instance', 0, PARAM_INT); + + if ($instance->id == $instanceid) { + if ($data = $form->get_data()) { + // clean caches + unset($USER->enrol['enrolled'][$instance->courseid]); + unset($USER->enrol['tempguest'][$instance->courseid]); + + // remove any guest role + $context = get_context_instance(CONTEXT_COURSE, $instance->courseid); + $USER->access = remove_temp_roles($context, $USER->access); + + $enrol = enrol_get_plugin('self'); + if ($instance->enrolperiod) { + $timestart = time(); + $tineend = $timestart + $instance->enrolperiod; + } else { + $timestart = 0; + $tineend = 0; + } + + // abuse the manual enrol plugin so that teachers may manually tweak the roles and enrolments later + $manualplugin->enrol_user($manual, $USER->id, $timestart, $tineend, $instance->defaultrole); + // send welcome + if ($this->get_config('sendcoursewelcomemessage')) { + $this->email_welcome_message($instance, $USER); + } + } + } + + ob_start(); + $form->display(); + $output = ob_get_clean(); + + return $OUTPUT->box($output); + } + + /** + * Adds enrol instance UI to course edit form + * + * @param object $instance enrol instance or null if does not exist yet + * @param MoodleQuickForm $mform + * @param object $data + * @param object $context context of existing course or parent category if course does not exist + * @return void + */ + public function course_edit_form($instance, MoodleQuickForm $mform, $data, $context) { + + $i = isset($instance->id) ? $instance->id : 0; + $header = empty($instance->name) ? get_string('pluginname', 'enrol_self') : $instance->name; + $config = has_capability('enrol/self:config', $context); + + $mform->addElement('header', 'enrol_self_header_'.$i, $header); + + + $options = array(ENROL_STATUS_ENABLED => get_string('yes'), + ENROL_STATUS_DISABLED => get_string('no')); + $mform->addElement('select', 'enrol_self_status_'.$i, get_string('status', 'enrol_self'), $options); + $mform->setDefault('enrol_self_status_'.$i, $this->get_config('status')); + $mform->setAdvanced('enrol_self_status_'.$i, $this->get_config('status_adv')); + if (!$config) { + $mform->hardFreeze('enrol_self_status_'.$i); + } + + + $mform->addElement('passwordunmask', 'enrol_self_password_'.$i, get_string('password', 'enrol_self')); + if (!$config) { + $mform->hardFreeze('enrol_self_password_'.$i); + } else { + $mform->disabledIf('enrol_self_password_'.$i, 'enrol_self_status_'.$i, 'noteq', ENROL_STATUS_ENABLED); + } + + + $options = array(1 => get_string('yes'), + 0 => get_string('no')); + $mform->addElement('select', 'enrol_self_customint1_'.$i, get_string('groupkey', 'enrol_self'), $options); + $mform->setDefault('enrol_self_customint1_'.$i, $this->get_config('groupkey')); + $mform->setAdvanced('enrol_self_customint1_'.$i, $this->get_config('groupkey_adv')); + if (!$config) { + $mform->hardFreeze('enrol_self_customint1_'.$i); + } else { + $mform->disabledIf('enrol_self_customint1_'.$i, 'enrol_self_status_'.$i, 'noteq', ENROL_STATUS_ENABLED); + } + + + if ($instance) { + $roles = get_default_enrol_roles($context, $instance->defaultrole); + } else { + $roles = get_default_enrol_roles($context, $this->get_config('defaultrole')); + } + $mform->addElement('select', 'enrol_self_defaultrole_'.$i, get_string('role', 'enrol_self'), $roles); + $mform->setDefault('enrol_self_defaultrole_'.$i, $this->get_config('role')); + $mform->setAdvanced('enrol_self_defaultrole_'.$i, $this->get_config('role_adv')); + if (!$config) { + $mform->hardFreeze('enrol_self_defaultrole_'.$i); + } else { + $mform->disabledIf('enrol_self_defaultrole_'.$i, 'enrol_self_status_'.$i, 'noteq', ENROL_STATUS_ENABLED); + } + + + $mform->addElement('duration', 'enrol_self_enrolperiod_'.$i, get_string('enrolperiod', 'enrol_self'), array('optional' => true, 'defaultunit' => 86400)); + $mform->setDefault('enrol_self_enrolperiod_'.$i, $this->get_config('enrolperiod')); + $mform->setAdvanced('enrol_self_enrolperiod_'.$i, $this->get_config('enrolperiod_adv')); + if (!$config) { + $mform->hardFreeze('enrol_self_enrolperiod_'.$i); + } else { + $mform->disabledIf('enrol_self_enrolperiod_'.$i, 'enrol_self_status_'.$i, 'noteq', ENROL_STATUS_ENABLED); + } + + + $mform->addElement('date_selector', 'enrol_self_enrolstartdate_'.$i, get_string('enrolstartdate', 'enrol_self'), array('optional' => true)); + $mform->setDefault('enrol_self_enrolstartdate_'.$i, 0); + $mform->setAdvanced('enrol_self_enrolstartdate_'.$i, 1); + if (!$config) { + $mform->hardFreeze('enrol_self_enrolstartdate_'.$i); + } else { + $mform->disabledIf('enrol_self_enrolstartdate_'.$i, 'enrol_self_status_'.$i, 'noteq', ENROL_STATUS_ENABLED); + } + + + $mform->addElement('date_selector', 'enrol_self_enrolenddate_'.$i, get_string('enrolenddate', 'enrol_self'), array('optional' => true)); + $mform->setDefault('enrol_self_enrolenddate_'.$i, 0); + $mform->setAdvanced('enrol_self_enrolenddate_'.$i, 1); + if (!$config) { + $mform->hardFreeze('enrol_self_enrolenddate_'.$i); + } else { + $mform->disabledIf('enrol_self_enrolenddate_'.$i, 'enrol_self_status_'.$i, 'noteq', ENROL_STATUS_ENABLED); + } + + + // now add all values from enrol table + if ($instance) { + foreach($instance as $key=>$val) { + $data->{'enrol_self_'.$key.'_'.$i} = $val; + } + } + } + + + /** + * Validates course edit form data + * + * @param object $instance enrol instance or null if does not exist yet + * @param array $data + * @param object $context context of existing course or parent category if course does not exist + * @return array errors array + */ + public function course_edit_validation($instance, array $data, $context) { + $errors = array(); + + if (!has_capability('enrol/self:config', $context)) { + // we are going to ignore the data later anyway, they would nto be able to fix the form anyway + return $errors; + } + + $i = isset($instance->id) ? $instance->id : 0; + + $password = empty($data['enrol_self_password_'.$i]) ? '' : $data['enrol_self_password_'.$i]; + $checkpassword = false; + + if ($instance) { + if ($data['enrol_self_status_'.$i] == ENROL_STATUS_ENABLED) { + if ($instance->password !== $password) { + $checkpassword = true; + } + } + } else { + if ($data['enrol_self_status_'.$i] == ENROL_STATUS_ENABLED) { + $checkpassword = true; + } + } + + if ($checkpassword) { + $require = $this->get_config('requirepassword'); + $policy = $this->get_config('usepasswordpolicy'); + if ($require and empty($password)) { + $errors['enrol_self_password_'.$i] = get_string('required'); + } else if ($policy) { + $errmsg = '';//prevent eclipse warning + if (!check_password_policy($password, $errmsg)) { + $errors['enrol_self_password_'.$i] = $errmsg; + } + } + } + + if ($data['enrol_self_status_'.$i] == ENROL_STATUS_ENABLED) { + if (!empty($data['enrol_self_enrolenddate_'.$i]) and $data['enrol_self_enrolenddate_'.$i] < $data['enrol_self_enrolstartdate_'.$i]) { + $errors['enrol_self_enrolenddate_'.$i] = get_string('enrolenddaterror', 'enrol_self'); + } + } + + return $errors; + } + + + /** + * Called after updating/inserting course. + * + * @param object $instance enrol instance, null if does not exist yet + * @param object $course + * @param object $data form data + * @return void + */ + public function course_updated($instance, $course, $data) { + global $DB; + + $context = get_context_instance(CONTEXT_COURSE, $course->id); + + if (has_capability('enrol/self:config', $context)) { + if ($instance) { + $i = $instance->id; + } else { + $i = 0; + $instance = new object(); + $instance->enrol = 'self'; + $instance->courseid = $course->id; + } + + $instance->status = $data->{'enrol_self_status_'.$i}; + $instance->timemodified = time(); + + if ($instance->status == ENROL_STATUS_ENABLED) { + $instance->password = $data->{'enrol_self_password_'.$i}; + $instance->customint1 = $data->{'enrol_self_customint1_'.$i}; + $instance->defaultrole = $data->{'enrol_self_defaultrole_'.$i}; + $instance->enrolperiod = $data->{'enrol_self_enrolperiod_'.$i}; + $instance->enrolstartdate = $data->{'enrol_self_enrolstartdate_'.$i}; + $instance->enrolenddate = $data->{'enrol_self_enrolenddate_'.$i}; + + } else if (empty($instance->id)) { + if ($this->get_config('requirepassword')) { + // make sure some password is set after enabling this plugin + $instance->password = generate_password(20); + } + $instance->customint1 = $this->get_config('groupkey'); + $instance->defaultrole = $this->get_config('role'); + $instance->enrolperiod = $this->get_config('enrolperiod'); + $instance->enrolstartdate = 0; + $instance->enrolenddate = 0; + } + + if (empty($instance->id)) { + $instance->timecreated = $instance->timemodified; + $instance->sortorder = $DB->get_field('enrol', 'COALESCE(MAX(sortorder), -1) + 1', array('courseid'=>$course->id)); + $DB->insert_record('enrol', $instance); + } else { + $DB->update_record('enrol', $instance); + } + + } else { + if ($instance) { + // bad luck, user can not change anything + } else { + $this->add_default_instance($course); + } + } + } + + /** + * Add new instance of enrol plugin with default settings. + * @param object $course + * @return int id of new instance + */ + public function add_default_instance($course) { + global $DB; + + $instance = new object(); + $instance->enrol = 'self'; + $instance->status = $this->get_config('status'); + $instance->courseid = $course->id; + $instance->customint1 = $this->get_config('groupkey'); + $instance->defaultrole = $this->get_config('role'); + $instance->enrolperiod = $this->get_config('enrolperiod'); + $instance->enrolstartdate = 0; + $instance->enrolenddate = 0; + $instance->timemodified = time(); + $instance->timecreated = $instance->timemodified; + $instance->sortorder = $DB->get_field('enrol', 'COALESCE(MAX(sortorder), -1) + 1', array('courseid'=>$course->id)); + + if ($this->get_config('requirepassword')) { + $instance->password = generate_password(20); + } + + return $DB->insert_record('enrol', $instance); + } + + /** + * Send welcome email to specified user + * + * @param object $instance + * @param object $user user record + * @return void + */ + protected function email_welcome_message($instance, $user) { + global $CFG, $DB; + + $course = $DB->get_record('course', array('id'=>$instance->courseid), '*', MUST_EXIST); + + if (!empty($instance->customtext1)) { + //note: there is no gui for this yet, do we really need it? + $message = formaat_string($instance->customtext1); + } else { + $a = new object(); + $a->coursename = format_string($course->fullname); + $a->profileurl = "$CFG->wwwroot/user/view.php?id=$user->id&course=$course->id"; + $message = get_string("welcometocoursetext", 'enrol_self', $a); + } + + $subject = get_string('welcometocourse', 'enrol_self', format_string($course->fullname)); + + $context = get_context_instance(CONTEXT_COURSE, $course->id); + $rusers = null; + if (!empty($CFG->coursecontact)) { + $croles = explode(',', $CFG->coursecontact); + $rusers = get_role_users($croles, $context, true, '', 'r.sortorder ASC, u.lastname ASC'); + } + if ($rusers) { + $contact = reset($rusers); + } else { + $contact = get_admin(); + } + + email_to_user($user, $contact, $subject, $message); + } +} + + Index: lib/simpletest/testaccesslib.php =================================================================== --- lib/simpletest/testaccesslib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/simpletest/testaccesslib.php (revision ) @@ -261,10 +261,6 @@ $context = $contexts['cou']; $context->id = SYSCONTEXTID + 2; - $this->load_test_data('capabilities', - array('name'), array( - array('moodle/course:participate'))); - $roles = $this->load_test_data('role', array( 'name', 'shortname', 'description', 'sortorder'), array( 'admin' => array('admin', 'admin', 'not null', 1), @@ -274,14 +270,8 @@ $adminid = $roles['admin']->id; $r1id = $roles['r1']->id; $r2id = $roles['r2']->id; - $funnyid = $roles['funny']->id; // strange role to test that roles with 'moodle/course:participate' are not returned. + $funnyid = $roles['funny']->id; // strange role - $this->load_test_data('role_capabilities', - array('roleid', 'capability', 'contextid', 'permission'), array( - array( $r1id, 'moodle/course:participate', SYSCONTEXTID + 1, CAP_ALLOW), - array( $r2id, 'moodle/course:participate', SYSCONTEXTID, CAP_ALLOW), - array($funnyid, 'moodle/course:participate', SYSCONTEXTID, CAP_ALLOW))); - $this->load_test_data('role_assignments', array('userid', 'contextid', 'roleid'), array( array( 1, SYSCONTEXTID, $adminid), @@ -295,13 +285,6 @@ array( $r2id , $r2id), array( $r2id , $funnyid))); - // Admin should be able to switch to any role with 'moodle/course:participate' in any context. - $this->switch_global_user_id(1); - accesslib_clear_all_caches_for_unit_testing(); - $this->assert(new ArraysHaveSameValuesExpectation(array($r2id)), array_keys(get_switchable_roles($syscontext))); - $this->assert(new ArraysHaveSameValuesExpectation(array($r2id)), array_keys(get_switchable_roles($context))); - $this->revert_global_user_id(); - // r1 should be able to switch to r2, but this user only has r1 in $context, not $syscontext. $this->switch_global_user_id(2); accesslib_clear_all_caches_for_unit_testing(); @@ -316,21 +299,5 @@ $this->assert(new ArraysHaveSameValuesExpectation(array($r2id)), array_keys(get_switchable_roles($context))); } - function test_get_allowed_switchable_roles() { - $this->create_test_table('role_capabilities', 'lib'); - - $this->load_test_data('role_capabilities', - array('roleid', 'capability', 'contextid', 'permission'), array( - array( 1, 'moodle/forum:replypost', SYSCONTEXTID, CAP_ALLOW), - array( 2, 'moodle/course:participate', SYSCONTEXTID, CAP_ALLOW), - array( 4, 'moodle/course:participate', SYSCONTEXTID, CAP_ALLOW), - array( 5, 'moodle/course:participate', SYSCONTEXTID, CAP_ALLOW), - array( 6, 'moodle/course:participate', SYSCONTEXTID, CAP_PREVENT), - )); - - $this->switch_to_test_db(); - - $this->assert(new ArraysHaveSameValuesExpectation(array(2, 5)), array_keys(get_allowed_switchable_roles())); - } +} -} Index: admin/settings/plugins.php =================================================================== --- admin/settings/plugins.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/settings/plugins.php (revision ) @@ -51,6 +51,47 @@ } + // Enrolment plugins + $ADMIN->add('modules', new admin_category('enrolments', get_string('enrolments'))); + $temp = new admin_settingpage('manageenrols', get_string('manageenrols', 'enrol')); + $temp->add(new admin_setting_manageenrols()); + if (empty($CFG->enrol_plugins_enabled)) { + $enabled = array(); + } else { + $enabled = explode(',', $CFG->enrol_plugins_enabled); + } + $enrols = get_plugin_list('enrol'); + $options = array(); + foreach($enrols as $enrol=>$enrolpath) { + if (!file_exists("$enrolpath/lib.php")) { + continue; + } + if (!in_array($enrol, $enabled)) { + continue; + } + $options[$enrol] = get_string('pluginname', 'enrol_'.$enrol); + } + if ($options) { + $temp->add(new admin_setting_configmultiselect('enrol_plugins_default', get_string('defaultenrols', 'enrol'), get_string('defaultenrols_desc', 'enrol'), array('manual', 'self', 'guest'), $options)); + } + $ADMIN->add('enrolments', $temp); + foreach($enrols as $enrol=>$enrolpath) { + if (!file_exists("$enrolpath/settings.php")) { + continue; + } + + $settings = new admin_settingpage('enrolsettings'.$enrol, get_string('pluginname', 'enrol_'.$enrol), 'moodle/site:config', !in_array($enrol, $enabled)); + // settings.php may create a subcategory or unset the settings completely + include("$enrolpath/settings.php"); + if ($settings) { + $ADMIN->add('enrolments', $settings); + } + + } + unset($enabled); + unset($enrols); + + /// Editor plugins $ADMIN->add('modules', new admin_category('editorsettings', get_string('editors', 'editor'))); $temp = new admin_settingpage('manageeditors', get_string('editorsettings', 'editor')); Index: enrol/self/version.php =================================================================== --- enrol/self/version.php (revision ) +++ enrol/self/version.php (revision ) @@ -0,0 +1,25 @@ +. + +/** + * Self enrolment plugin. + * + * @package enrol_self + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$plugin->version = 2010042302; Index: backup/restore_check.html =================================================================== --- backup/restore_check.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ backup/restore_check.html (revision ) @@ -92,8 +92,6 @@ } //restoreto $restore_restoreto = required_param('restore_restoreto', PARAM_INT); - //restore_metacourse - $restore_metacourse = required_param('restore_metacourse', PARAM_INT); //restore_users $restore_users = required_param('restore_users', PARAM_INT); @@ -140,7 +138,6 @@ } } $restore->restoreto=$restore_restoreto; - $restore->metacourse=$restore_metacourse; $restore->users=$restore_users; $restore->groups=$restore_groups; $restore->logs=$restore_logs; @@ -220,15 +217,9 @@ //Check site $site = get_site(); - // Non-cached - get accessinfo - if (isset($USER->access)) { - $accessinfo = $USER->access; - } else { - $accessinfo = get_user_access_sitewide($USER->id); - } - // Get all the courses the user is able to restore to - $mycourses = get_user_courses_bycap($USER->id, 'moodle/restore:restorecourse', $accessinfo, true, 'c.sortorder ASC', array('id', 'fullname', 'shortname', 'visible')); + //TODO: use better function which includes all courses for admins + $mycourses = get_user_courses_bycap($USER->id, 'moodle/restore:restorecourse'); // Calculate if the user can create courses $cancreatecourses = user_can_create_courses(); Index: admin/mnet/enr_course_enrol.php =================================================================== --- admin/mnet/enr_course_enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/mnet/enr_course_enrol.php (revision ) @@ -12,8 +12,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 +277,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'); Index: enrol/flatfile/enrol.php =================================================================== --- enrol/flatfile/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/flatfile/enrol.php (revision ) @@ -187,9 +187,10 @@ $context = get_context_instance(CONTEXT_COURSE, $course->id); if ($fields[0] == 'add') { - role_assign($roleid, $user->id, null, $context->id, $fields[4], $fields[5], 0, 'flatfile'); + // TODO: real enrol, and maybe manual + role_assign($roleid, $user->id, $context->id, 'enrol_flatfile'); } else { - role_unassign($roleid, $user->id, null, $context->id); + role_unassign($roleid, $user->id, $context->id); } Index: enrol/guest/lib.php =================================================================== --- enrol/guest/lib.php (revision ) +++ enrol/guest/lib.php (revision ) @@ -0,0 +1,276 @@ +. + +/** + * Guest access plugin. + * + * This plugin does not add any entries into the course_participants table, + * the access control is granted on the fly via the tricks in require_login(). + * + * @package enrol_guest + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +class enrol_guest_plugin extends enrol_plugin { + + public function enrol_user(stdClass $instance, $userid, $timestart = 0, $timeend = 0, $roleid = null) { + // no real enrolments here + return; + } + + public function unenrol_user(stdClass $instance, $userid) { + // nothing to do, we never enrol here + return; + } + + /** + * Attempt to automatically gain temporary guest access to course, + * calling code has to make sure the plugin and instance are active. + * + * @param stdClass $instance course enrol instance + * @param stdClass $user record + * @return bool|int false means no guest access, integer means end of cached time + */ + public function try_guestaccess(stdClass $instance) { + global $USER, $CFG; + + if (empty($instance->password)) { + // Temporarily assign them some guest role for this context + $context = get_context_instance(CONTEXT_COURSE, $instance->courseid); + $USER->access = load_temp_role($context, $CFG->guestroleid, $USER->access); + return ENROL_REQUIRE_LOGIN_CACHE_PERIOD; + } + + return false; + } + + /** + * Creates course enrol form, checks if form submitted + * and enrols user if necessary. It can also redirect. + * + * @param stdClass $instance + * @return string html text, usually a form in a text box + */ + public function enrol_page_hook(stdClass $instance) { + global $CFG, $OUTPUT, $SESSION, $USER; + + if (empty($instance->password)) { + return null; + } + + require_once("$CFG->dirroot/enrol/guest/locallib.php"); + $form = new enrol_guest_enrol_form(NULL, $instance); + $instanceid = optional_param('instance', 0, PARAM_INT); + + if ($instance->id == $instanceid) { + if ($data = $form->get_data()) { + // set up caching + unset($USER->enrol['enrolled'][$instance->courseid]); + $USER->enrol['tempguest'][$instance->courseid] = time() + 60*60*8; // 8 hours access before asking for pw again + + // add guest role + $context = get_context_instance(CONTEXT_COURSE, $instance->courseid); + $USER->access = load_temp_role($context, $CFG->guestroleid, $USER->access); + + // go to the originally requested page + if (!empty($SESSION->wantsurl)) { + $destination = $SESSION->wantsurl; + unset($SESSION->wantsurl); + } else { + $destination = "$CFG->wwwroot/course/view.php?id=$instance->courseid"; + } + redirect($destination); + } + } + + ob_start(); + $form->display(); + $output = ob_get_clean(); + + return $OUTPUT->box($output, 'generalbox'); + } + + /** + * Adds enrol instance UI to course edit form + * + * @param object $instance enrol instance or null if does not exist yet + * @param MoodleQuickForm $mform + * @param object $data + * @param object $context context of existing course or parent category if course does not exist + * @return void + */ + public function course_edit_form($instance, MoodleQuickForm $mform, $data, $context) { + + $i = isset($instance->id) ? $instance->id : 0; + $header = empty($instance->name) ? get_string('pluginname', 'enrol_guest') : $instance->name; + $config = has_capability('enrol/guest:config', $context); + + $mform->addElement('header', 'enrol_guest_header_'.$i, $header); + + + $options = array(ENROL_STATUS_ENABLED => get_string('yes'), + ENROL_STATUS_DISABLED => get_string('no')); + $mform->addElement('select', 'enrol_guest_status_'.$i, get_string('status', 'enrol_guest'), $options); + $mform->setDefault('enrol_guest_status_'.$i, $this->get_config('status')); + $mform->setAdvanced('enrol_guest_status_'.$i, $this->get_config('status_adv')); + if (!$config) { + $mform->hardFreeze('enrol_guest_status_'.$i); + } + + $mform->addElement('passwordunmask', 'enrol_guest_password_'.$i, get_string('password', 'enrol_guest')); + if (!$config) { + $mform->hardFreeze('enrol_guest_password_'.$i); + } else { + $mform->disabledIf('enrol_guest_password_'.$i, 'enrol_guest_status_'.$i, 'noteq', ENROL_STATUS_ENABLED); + } + + + // now add all values from enrol table + if ($instance) { + foreach($instance as $key=>$val) { + $data->{'enrol_guest_'.$key.'_'.$i} = $val; + } + } + } + + /** + * Validates course edit form data + * + * @param object $instance enrol instance or null if does not exist yet + * @param array $data + * @param object $context context of existing course or parent category if course does not exist + * @return array errors array + */ + public function course_edit_validation($instance, array $data, $context) { + $errors = array(); + + if (!has_capability('enrol/guest:config', $context)) { + // we are going to ignore the data later anyway, they would nto be able to fix the form anyway + return $errors; + } + + $i = isset($instance->id) ? $instance->id : 0; + + $password = empty($data['enrol_guest_password_'.$i]) ? '' : $data['enrol_guest_password_'.$i]; + $checkpassword = false; + + if ($instance) { + if ($data['enrol_guest_status_'.$i] == ENROL_STATUS_ENABLED) { + if ($instance->password !== $password) { + $checkpassword = true; + } + } + } else { + if ($data['enrol_guest_status_'.$i] == ENROL_STATUS_ENABLED) { + $checkpassword = true; + } + } + + if ($checkpassword) { + $require = $this->get_config('requirepassword'); + $policy = $this->get_config('usepasswordpolicy'); + if ($require and empty($password)) { + $errors['enrol_guest_password_'.$i] = get_string('required'); + } else if ($policy) { + $errmsg = '';//prevent eclipse warning + if (!check_password_policy($password, $errmsg)) { + $errors['enrol_guest_password_'.$i] = $errmsg; + } + } + } + + return $errors; + } + + /** + * Called after updating/inserting course. + * + * @param object $instance enrol instance, null if does not exist yet + * @param object $course + * @param object $data form data + * @return void + */ + public function course_updated($instance, $course, $data) { + global $DB; + + $context = get_context_instance(CONTEXT_COURSE, $course->id); + + if (has_capability('enrol/guest:config', $context)) { + if ($instance) { + $i = $instance->id; + } else { + $i = 0; + $instance = new object(); + $instance->enrol = 'guest'; + $instance->courseid = $course->id; + } + + $instance->status = $data->{'enrol_guest_status_'.$i}; + $instance->timemodified = time(); + + if ($instance->status == ENROL_STATUS_ENABLED) { + $instance->password = $data->{'enrol_guest_password_'.$i}; + } else if (empty($instance->id)) { + if ($this->get_config('requirepassword')) { + // make sure some password is set after enabling this plugin + $instance->password = generate_password(20); + } + } + + if (empty($instance->id)) { + $instance->timecreated = $instance->timemodified; + $instance->sortorder = $DB->get_field('enrol', 'COALESCE(MAX(sortorder), -1) + 1', array('courseid'=>$course->id)); + $DB->insert_record('enrol', $instance); + } else { + $DB->update_record('enrol', $instance); + } + + } else { + if ($instance) { + // bad luck, user can not change anything + } else { + $this->add_default_instance($course); + } + } + } + + /** + * Add new instance of enrol plugin with default settings. + * @param object $course + * @return int id of new instance + */ + public function add_default_instance($course) { + global $DB; + + $instance = new object(); + $instance->enrol = 'guest'; + $instance->status = $this->get_config('status'); + $instance->courseid = $course->id; + $instance->timemodified = time(); + $instance->timecreated = $instance->timemodified; + $instance->sortorder = $DB->get_field('enrol', 'COALESCE(MAX(sortorder), -1) + 1', array('courseid'=>$course->id)); + + if ($this->get_config('requirepassword')) { + $instance->password = generate_password(20); + } + + return $DB->insert_record('enrol', $instance); + } + +} + Index: enrol/paypal/return.php =================================================================== --- enrol/paypal/return.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/paypal/return.php (revision ) @@ -25,7 +25,7 @@ $destination = "$CFG->wwwroot/course/view.php?id=$course->id"; } - if (has_capability('moodle/course:participate', $context)) { + if (is_enrolled($context, NULL, '', true)) { // TODO: use real paypal check redirect($destination, get_string('paymentthanks', '', $course->fullname)); } else { /// Somehow they aren't enrolled yet! :-( Index: admin/bloglevelupgrade.php =================================================================== --- admin/bloglevelupgrade.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/bloglevelupgrade.php (revision ) @@ -48,7 +48,7 @@ $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) { Index: enrol/guest/version.php =================================================================== --- enrol/guest/version.php (revision ) +++ enrol/guest/version.php (revision ) @@ -0,0 +1,25 @@ +. + +/** + * Guest access plugin. + * + * @package enrol_guest + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$plugin->version = 2010042302; Index: enrol/cohort/lib.php =================================================================== --- enrol/cohort/lib.php (revision ) +++ enrol/cohort/lib.php (revision ) @@ -0,0 +1,30 @@ +. + +/** + * Cohort enrolment plugin. + * + * @package enrol_cohort + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +class enrol_cohort_plugin extends enrol_plugin { + +} + Index: lib/navigationlib.php =================================================================== --- lib/navigationlib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/navigationlib.php (revision ) @@ -829,7 +829,7 @@ $this->rootnodes['users'] = $this->add(get_string('users'), null, self::TYPE_ROOTNODE, null, 'users'); // Fetch all of the users courses. - $this->mycourses = get_my_courses($USER->id); + $this->mycourses = enrol_get_my_courses(); // Check if any courses were returned. if (count($this->mycourses) > 0) { // Add all of the users courses to the navigation @@ -1401,7 +1401,7 @@ } $canviewhidden = has_capability('moodle/course:viewhiddencourses', $this->page->context); - if ($course->id !== SITEID && !$canviewhidden && (!$course->visible || !course_parent_visible($course))) { + if ($course->id !== SITEID && !$canviewhidden && !$course->visible) { return false; } @@ -2307,6 +2307,11 @@ } } + if (has_capability('moodle/course:enrolreview', $coursecontext)) { + $url = new moodle_url('/enrol/review.php', array('id'=>$course->id)); + $coursenode->add(get_string('enrolments'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/roles', '')); + } + if (has_capability('moodle/role:assign', $coursecontext)) { // Add assign or override roles if allowed $url = new moodle_url('/'.$CFG->admin.'/roles/assign.php', array('contextid'=>$coursecontext->id)); @@ -2356,17 +2361,6 @@ $coursenode->add(get_string('outcomes', 'grades'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/outcomes', '')); } - // Add meta course links - if ($course->metacourse) { - if (has_capability('moodle/course:managemetacourse', $coursecontext)) { - $url = new moodle_url('/course/importstudents.php', array('id'=>$course->id)); - $coursenode->add(get_string('childcourses'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/course', '')); - } else if (has_capability('moodle/role:assign', $coursecontext)) { - $roleassign = $coursenode->add(get_string('childcourses'), null, self::TYPE_SETTING, null, null, new pix_icon('i/course', '')); - $roleassign->hidden = true; - } - } - // Manage groups in this course if (($course->groupmode || !$course->groupmodeforce) && has_capability('moodle/course:managegroups', $coursecontext)) { $url = new moodle_url('/group/index.php', array('id'=>$course->id)); @@ -2437,7 +2431,8 @@ $coursenode->add(get_string('files'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/files', '')); } - // Authorize hooks + // TODO: rework enrol hooks!!!! + /* if ($course->enrol == 'authorize' || (empty($course->enrol) && $CFG->enrol == 'authorize')) { require_once($CFG->dirroot.'/enrol/authorize/const.php'); $url = new moodle_url('/enrol/authorize/index.php', array('course'=>$course->id)); @@ -2449,21 +2444,21 @@ $coursenode->add(get_string('paymentpending', 'moodle', $cnt), $url, self::TYPE_SETTING, null, null, new pix_icon('i/payment', '')); } } - } + }*/ // Unenrol link - if (empty($course->metacourse) && ($course->id!==SITEID)) { + if ($course->id!==SITEID) { if (is_enrolled(get_context_instance(CONTEXT_COURSE, $course->id))) { - if (has_capability('moodle/role:unassignself', $this->page->context, NULL, false) and get_user_roles($this->page->context, $USER->id, false)) { // Have some role + /*if (..detect if can unenrol somehow and probably cache it..) { $this->content->items[]=''.get_string('unenrolme', '', format_string($course->shortname)).''; $this->content->icons[]=''; - } + }*/ } else if (is_viewing(get_context_instance(CONTEXT_COURSE, $course->id))) { // inspector, manager, etc. - do not show anything } else { // access because otherwise they would not get into this course at all - $this->content->items[]=''.get_string('enrolme', '', format_string($course->shortname)).''; + $this->content->items[]=''.get_string('enrolme', '', format_string($course->shortname)).''; $this->content->icons[]=''; } } @@ -2650,7 +2645,7 @@ // Check that the user can view the profile $usercontext = get_context_instance(CONTEXT_USER, $user->id); // User context if ($course->id==SITEID) { - if ($CFG->forceloginforprofiles && !!has_coursemanager_role($user->id) && !has_capability('moodle/user:viewdetails', $usercontext)) { // Reduce possibility of "browsing" userbase at site level + if ($CFG->forceloginforprofiles && !!has_coursecontact_role($user->id) && !has_capability('moodle/user:viewdetails', $usercontext)) { // Reduce possibility of "browsing" userbase at site level // Teachers can browse and be browsed at site level. If not forceloginforprofiles, allow access (bug #4366) return false; } Index: course/lib.php =================================================================== --- course/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/lib.php (revision ) @@ -1950,7 +1950,7 @@ echo "\n\n".''; - $courses = get_courses($category->id, 'c.sortorder ASC', 'c.id,c.sortorder,c.visible,c.fullname,c.shortname,c.password,c.summary,c.guest,c.cost,c.currency'); + $courses = get_courses($category->id, 'c.sortorder ASC', 'c.id,c.sortorder,c.visible,c.fullname,c.shortname,c.summary'); if ($showcourses and $coursecount) { echo ''; @@ -2108,17 +2108,17 @@ $category = array_shift($categories); $courses = get_courses_wmanagers($category->id, 'c.sortorder ASC', - array('password','summary','summaryformat','currency')); + array('summary','summaryformat')); } else { $courses = get_courses_wmanagers('all', 'c.sortorder ASC', - array('password','summary','summaryformat','currency')); + array('summary','summaryformat')); } unset($categories); } else { $courses = get_courses_wmanagers($category->id, 'c.sortorder ASC', - array('password','summary','summaryformat','currency')); + array('summary','summaryformat')); } if ($courses) { @@ -2169,8 +2169,8 @@ /// first find all roles that are supposed to be displayed - if (!empty($CFG->coursemanager)) { - $managerroles = split(',', $CFG->coursemanager); + if (!empty($CFG->coursecontact)) { + $managerroles = split(',', $CFG->coursecontact); $namesarray = array(); if (isset($course->managers)) { if (count($course->managers)) { @@ -2236,9 +2236,7 @@ } } - require_once("$CFG->dirroot/enrol/enrol.class.php"); - $enrol = enrolment_factory::factory($course->enrol); - echo $enrol->get_access_icons($course); + // TODO: print some enrol icons echo '
'; $options = NULL; @@ -2263,7 +2261,7 @@ print_error('nopermissions', '', '', 'See My Moodle'); } - $courses = get_my_courses($USER->id, 'visible DESC,sortorder ASC', array('summary')); + $courses = enrol_get_my_courses('summary', 'visible DESC,sortorder ASC'); $rhosts = array(); $rcourses = array(); if (!empty($CFG->mnet_dispatcher_mode) && $CFG->mnet_dispatcher_mode==='strict') { @@ -2952,15 +2950,6 @@ } } -/** - * This function will return true if the given course is a child course at all - */ -function course_in_meta ($course) { - global $DB; - return $DB->record_exists("course_meta", array("child_course"=>$course->id)); -} - - function update_restricted_mods($course, $mods) { global $DB; @@ -3220,7 +3209,7 @@ $context = get_context_instance(CONTEXT_COURSE, $courseid); foreach ($data as $fieldname => $value) { - if (!strstr($fieldname, 'role_')) { + if (strpos($fieldname, 'role_') !== 0) { continue; } list($ignored, $roleid) = explode('_', $fieldname); @@ -3247,35 +3236,32 @@ * Create a course and either return a $course object or false * * @param object $data - all the data needed for an entry in the 'course' table + * @param array $editoroptions course description editor options + * @param bool $fixcreator add default enrolment for creator role + * @return object new course record */ -function create_course($data) { - global $CFG, $USER, $DB; +function create_course($data, $editoroptions=null, $fixcreator=false) { + global $CFG, $DB, $USER; //check the categoryid if (!empty($data->category) && !$data->category==0) { - $category = $DB->get_record('course_categories', array('id'=>$data->category)); - if (empty($category)) { - throw new moodle_exception('noexistingcategory'); + $category = $DB->get_record('course_categories', array('id'=>$data->category), '*', MUST_EXIST); - } + } - } //check if the shortname already exist - if(!empty($data->shortname)) { + if (!empty($data->shortname)) { - $course = $DB->get_record('course', array('shortname' => $data->shortname)); - if (!empty($course)) { + if ($DB->record_exists('course', array('shortname' => $data->shortname))) { throw new moodle_exception('shortnametaken'); } } //check if the id number already exist - if(!empty($data->idnumber)) { + if (!empty($data->idnumber)) { - $course = $DB->get_record('course', array('idnumber' => $data->idnumber)); - if (!empty($course)) { + if ($DB->record_exists('course', array('idnumber' => $data->idnumber))) { throw new moodle_exception('idnumbertaken'); } } - // preprocess allowed mods $allowedmods = empty($data->allowedmods) ? array() : $data->allowedmods; unset($data->allowedmods); @@ -3298,43 +3284,68 @@ // place at beginning of any category $data->sortorder = 0; - if ($newcourseid = $DB->insert_record('course', $data)) { // Set up new course + // Set up new course + $course->id = $DB->insert_record('course', $data); + $context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); - $course = $DB->get_record('course', array('id'=>$newcourseid)); + if ($editoroptions) { + // Save the files used in the summary editor + $editordata = new stdClass; + $editordata->id = $course->id; + $editordata->summary_editor = $data->summary_editor; + $editordata = file_postupdate_standard_editor($editordata, 'summary', $editoroptions, $context, 'course_summary', $course->id); + $DB->update_record('course', $editordata); + } + $course = $DB->get_record('course', array('id'=>$course->id)); + + // new context created - btter mark it as dirty + mark_context_dirty($context->path); + + // this is a chicken-egg problem - we need to set up enrolment instances first, + // only then we can enrol course creator who may not have right to manage course :-( + enrol_course_updated(true, $course, $data); + + // in case this is executed by creator enrol him/her into course using manual enrol with default role + if ($fixcreator) { + if (!is_viewing($context, NULL, 'moodle/role:assign') and !is_enrolled($context, NULL, 'moodle/role:assign')) { + //TODO: do some real enrolment here + role_assign($CFG->creatornewroleid, $USER->id, $context->id); + } + } + - // Setup the blocks - blocks_add_default_course_blocks($course); + // Setup the blocks + blocks_add_default_course_blocks($course); - update_restricted_mods($course, $allowedmods); + update_restricted_mods($course, $allowedmods); - $section = new object(); - $section->course = $course->id; // Create a default section. - $section->section = 0; + $section = new object(); + $section->course = $course->id; // Create a default section. + $section->section = 0; - $section->id = $DB->insert_record('course_sections', $section); + $section->id = $DB->insert_record('course_sections', $section); - fix_course_sortorder(); + fix_course_sortorder(); - add_to_log(SITEID, 'course', 'new', 'view.php?id='.$course->id, $data->fullname.' (ID '.$course->id.')'); + add_to_log(SITEID, 'course', 'new', 'view.php?id='.$course->id, $data->fullname.' (ID '.$course->id.')'); - // Save any custom role names. - save_local_role_names($course->id, $data); + // Save any custom role names. + save_local_role_names($course->id, $data); - // Trigger events - events_trigger('course_created', $course); + // Trigger events + events_trigger('course_created', $course); - return $course; - } + return $course; +} - return false; // error -} - /** * Update a course and return true or false * * @param object $data - all the data needed for an entry in the 'course' table + * @param array $editoroptions course description editor options + * @return void */ -function update_course($data) { - global $USER, $CFG, $DB; +function update_course($data, $editoroptions) { + global $CFG, $DB; // Preprocess allowed mods $allowedmods = empty($data->allowedmods) ? array() : $data->allowedmods; @@ -3346,11 +3357,7 @@ } $movecat = false; - $oldcourse = $DB->get_record('course', array('id'=>$data->id)); // should not fail, already tested above - // check that course id exist - if (empty($oldcourse)) { - throw new moodle_exception('courseidnotfound'); - } + $oldcourse = $DB->get_record('course', array('id'=>$data->id), '*', MUST_EXIST); if (!has_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $oldcourse->category)) or !has_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $data->category))) { @@ -3361,42 +3368,40 @@ $movecat = true; } + $context = get_context_instance(CONTEXT_COURSE, $data->id, MUST_EXIST); + $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course_summary', $data->id); + // Update with the new data - if ($DB->update_record('course', $data)) { + $DB->update_record('course', $data); - $course = $DB->get_record('course', array('id'=>$data->id)); + $course = $DB->get_record('course', array('id'=>$data->id)); + enrol_course_updated(false, $course, $data); + - add_to_log($course->id, "course", "update", "edit.php?id=$course->id", $course->id); + add_to_log($course->id, "course", "update", "edit.php?id=$course->id", $course->id); - // "Admins" can change allowed mods for a course - if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) { - update_restricted_mods($course, $allowedmods); - } + // "Admins" can change allowed mods for a course + if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) { + update_restricted_mods($course, $allowedmods); + } - if ($movecat) { + if ($movecat) { - $context = get_context_instance(CONTEXT_COURSE, $course->id); - $newparent = get_context_instance(CONTEXT_COURSECAT, $course->category); - context_moved($context, $newparent); - } + $newparent = get_context_instance(CONTEXT_COURSECAT, $course->category); + context_moved($context, $newparent); + } - fix_course_sortorder(); + fix_course_sortorder(); - // Test for and remove blocks which aren't appropriate anymore - blocks_remove_inappropriate($course); + // Test for and remove blocks which aren't appropriate anymore + blocks_remove_inappropriate($course); - // Save any custom role names. - save_local_role_names($course->id, $data); + // Save any custom role names. + save_local_role_names($course->id, $data); - // Trigger events - events_trigger('course_updated', $course); + // Trigger events + events_trigger('course_updated', $course); - - return true; - - } +} - return false; -} - function get_course_by_id ($id) { global $DB; return $DB->get_record('course', array('id' => $id)); @@ -3738,7 +3743,8 @@ $course = $DB->get_record('course', array('id' => $course->id)); blocks_add_default_course_blocks($course); $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); - role_assign($CFG->creatornewroleid, $this->properties->requester, 0, $coursecontext->id); // assing teacher role + // TODO: do some real enrolment here + role_assign($CFG->creatornewroleid, $this->properties->requester, $coursecontext->id); // assing teacher role if (!empty($CFG->restrictmodulesfor) && $CFG->restrictmodulesfor != 'none' && !empty($CFG->restrictbydefault)) { // if we're all or requested we're ok. $allowedmods = explode(',',$CFG->defaultallowedmodules); Index: admin/report/security/lib.php =================================================================== --- admin/report/security/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/report/security/lib.php (revision ) @@ -587,9 +587,6 @@ $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 +594,7 @@ $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)); Index: backup/moodle2/backup_course_task.class.php =================================================================== --- backup/moodle2/backup_course_task.class.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ backup/moodle2/backup_course_task.class.php (revision ) @@ -69,7 +69,7 @@ $this->add_step(new create_taskbasepath_directory('create_course_directory')); // Create the course.xml file with course & category information - // annotating some bits, metacourse info, tags and module restrictions + // annotating some bits, tags and module restrictions $this->add_step(new backup_course_structure_step('course_info', 'course.xml')); // Annotate the groups used in already annotated groupings Index: enrol/manual/enrol.php =================================================================== --- enrol/manual/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/manual/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,455 +0,0 @@ -dirroot.'/group/lib.php'); -require_once($CFG->libdir.'/eventslib.php'); - -/** -* enrolment_plugin_manual is the default enrolment plugin -* -* This class provides all the functionality for an enrolment plugin -* In fact it includes all the code for the default, "manual" method -* so that other plugins can override these as necessary. -*/ - -class enrolment_plugin_manual { - -var $errormsg; - -/** -* Prints the entry form/page for this enrolment -* -* This is only called from course/enrol.php -* Most plugins will probably override this to print payment -* forms etc, or even just a notice to say that manual enrolment -* is disabled -* -* @param course current course object -*/ -function print_entry($course) { - global $CFG, $USER, $SESSION, $OUTPUT, $PAGE; - - $strloginto = get_string('loginto', '', $course->shortname); - $strcourses = get_string('courses'); - -/// Automatically enrol into courses without password - - $context = get_context_instance(CONTEXT_SYSTEM); - - $PAGE->navbar->add($strcourses); - $PAGE->navbar->add($strloginto); - - if ($course->password == '') { // no password, so enrol - - if (isguestuser()) { - add_to_log($course->id, 'course', 'guest', 'view.php?id='.$course->id, getremoteaddr()); - - } else if (empty($_GET['confirm']) && empty($_GET['cancel'])) { - $PAGE->set_title($strloginto); - $PAGE->set_heading($course->fullname); - echo $OUTPUT->header(); - echo '
'; - echo $OUTPUT->confirm(get_string('enrolmentconfirmation'), "enrol.php?id=$course->id&confirm=1&sesskey=".sesskey(), "enrol.php?id=$course->id&cancel=1"); - echo $OUTPUT->footer(); - exit; - - } else if (!empty($_GET['confirm']) and confirm_sesskey()) { - - if (!enrol_into_course($course, $USER, 'manual')) { - print_error('couldnotassignrole'); - } - // force a refresh of mycourses - unset($USER->mycourses); - - if (!empty($SESSION->wantsurl)) { - $destination = $SESSION->wantsurl; - unset($SESSION->wantsurl); - } else { - $destination = "$CFG->wwwroot/course/view.php?id=$course->id"; - } - - redirect($destination); - - } else if (!empty($_GET['cancel'])) { - unset($SESSION->wantsurl); - if (!empty($SESSION->enrolcancel)) { - $destination = $SESSION->enrolcancel; - unset($SESSION->enrolcancel); - } else { - $destination = $CFG->wwwroot; - } - redirect($destination); - } - } - - // if we get here we are going to display the form asking for the enrolment key - // and (hopefully) provide information about who to ask for it. - if (!isset($password)) { - $password = ''; - } - - $PAGE->set_title($strloginto); - $PAGE->set_heading($course->fullname); - $PAGE->set_focuscontrol('form.password'); - echo $OUTPUT->header(); - - print_course($course, "80%"); - - include("$CFG->dirroot/enrol/manual/enrol.html"); - - echo $OUTPUT->footer(); - -} - - - -/** -* The other half to print_entry, this checks the form data -* -* This function checks that the user has completed the task on the -* enrolment entry page and then enrolls them. -* -* @param form the form data submitted, as an object -* @param course the current course, as an object -*/ -function check_entry($form, $course) { - global $CFG, $USER, $SESSION; - - if (empty($form->password)) { - $form->password = ''; - } - - if (empty($course->password) or !confirm_sesskey()) { - // do not allow entry when no course password set - // automatic login when manual primary, no login when secondary at all!! - print_error('invalidenrol'); - } - - $groupid = $this->check_group_entry($course->id, $form->password); - - if (($form->password == $course->password) or ($groupid !== false) ) { - - if (isguestuser()) { // only real user guest, do not use this for users with guest role - $USER->enrolkey[$course->id] = true; - add_to_log($course->id, 'course', 'guest', 'view.php?id='.$course->id, getremoteaddr()); - - } else { /// Update or add new enrolment - if (enrol_into_course($course, $USER, 'manual')) { - // force a refresh of mycourses - unset($USER->mycourses); - if ($groupid !== false) { - if (!groups_add_member($groupid, $USER->id)) { - print_error('couldnotassigngroup'); - } - } - } else { - print_error('couldnotassignrole'); - } - } - - if ($SESSION->wantsurl) { - $destination = $SESSION->wantsurl; - unset($SESSION->wantsurl); - } else { - $destination = "$CFG->wwwroot/course/view.php?id=$course->id"; - } - - redirect($destination); - - } else if (!isset($CFG->enrol_manual_showhint) or $CFG->enrol_manual_showhint) { - $this->errormsg = get_string('enrolmentkeyhint', '', substr($course->password, 0, 1)); - - } else { - $this->errormsg = get_string('enrolmentkeyerror', 'enrol_manual'); - } -} - - -/** -* Check if the given enrolment key matches a group enrolment key for the given course -* -* @param courseid the current course id -* @param password the submitted enrolment key -*/ -function check_group_entry ($courseid, $password) { - - if ($groups = groups_get_all_groups($courseid)) { - foreach ($groups as $group) { - if ( !empty($group->enrolmentkey) and ($password == $group->enrolmentkey) ) { - return $group->id; - } - } - } - - return false; -} - - -/** -* Prints a form for configuring the current enrolment plugin -* -* This function is called from admin/enrol.php, and outputs a -* full page with a form for defining the current enrolment plugin. -* -* @param frm an object containing all the data for this page -*/ -function config_form($frm) { - global $CFG, $OUTPUT; - - if (!isset( $frm->enrol_manual_keyholderrole )) { - $frm->enrol_manual_keyholderrole = ''; - } - - if (!isset($frm->enrol_manual_showhint)) { - $frm->enrol_manual_showhint = 1; - } - - if (!isset($frm->enrol_manual_usepasswordpolicy)) { - $frm->enrol_manual_usepasswordpolicy = 0; - } - - if (!isset($frm->enrol_manual_requirekey)) { - $frm->enrol_manual_requirekey = 0; - } - - include ("$CFG->dirroot/enrol/manual/config.html"); -} - - -/** -* Processes and stored configuration data for the enrolment plugin -* -* @param config all the configuration data as entered by the admin -*/ -function process_config($config) { - foreach ($config as $name => $value) { - set_config($name, $value); - } - - return true; -} - - -/** -* Notify users about enrolments that are going to expire soon! -* This function is run by admin/cron.php -* @return void -*/ -function cron() { - global $CFG, $USER, $SITE, $DB; - - if (!isset($CFG->lastexpirynotify)) { - set_config('lastexpirynotify', 0); - } - - // notify once a day only - TODO: add some tz handling here, maybe use timestamps - if ($CFG->lastexpirynotify == date('Ymd')) { - return; - } - - if ($rs = $DB->get_recordset_select('course', 'enrolperiod > 0 AND expirynotify > 0 AND expirythreshold > 0')) { - $admin = get_admin(); - - foreach ($rs as $course) { - $a = new object(); - $a->coursename = $course->shortname .'/'. $course->fullname; // must be processed by format_string later - $a->threshold = $course->expirythreshold / 86400; - $a->extendurl = $CFG->wwwroot . '/user/index.php?id=' . $course->id; - $a->current = array(); - $a->past = array(); - - $expiry = time() + $course->expirythreshold; - $cname = $course->fullname; - - /// Get all the manual role assignments for this course that have expired. - - if (!$context = get_context_instance(CONTEXT_COURSE, $course->id)) { - continue; - } - - if ($oldenrolments = $DB->get_records_sql(" - SELECT u.*, ra.timeend - FROM {user} u - JOIN {role_assignments} ra ON (ra.userid = u.id) - WHERE ra.contextid = $context->id - AND ra.timeend > 0 AND ra.timeend <= $expiry - AND ra.enrol = 'manual'")) { - - // inform user who can assign roles or admin - if ($teachers = get_users_by_capability($context, 'moodle/role:assign', '', '', '', '', '', '', false)) { - $teachers = sort_by_roleassignment_authority($teachers, $context); - $teacher = reset($teachers); - } else { - $teachers = array($admin); - $teacher = $admin; - } - - $a->teacherstr = fullname($teacher, true); - - foreach ($oldenrolments as $user) { /// Email all users about to expire - $a->studentstr = fullname($user, true); - if ($user->timeend < ($expiry - 86400)) { - $a->past[] = fullname($user) . " <$user->email>"; - } else { - $a->current[] = fullname($user) . " <$user->email>"; - if ($course->notifystudents) { // Send this guy notice - // setup global $COURSE properly - needed for languages - cron_setup_user($user, $course); - $a->coursename = format_string($cname); - $a->course = $a->coursename; - $strexpirynotifystudentsemail = get_string('expirynotifystudentsemail', '', $a); - $strexpirynotify = get_string('expirynotify'); - - $eventdata = new object(); - $eventdata->modulename = 'moodle'; - $eventdata->userfrom = $teacher; - $eventdata->userto = $user; - $eventdata->subject = format_string($SITE->fullname) .' '. $strexpirynotify; - $eventdata->fullmessage = $strexpirynotifystudentsemail; - $eventdata->fullmessageformat = FORMAT_PLAIN; - $eventdata->fullmessagehtml = ''; - $eventdata->smallmessage = ''; - message_send($eventdata); - } - } - } - - $a->current = implode("\n", $a->current); - $a->past = implode("\n", $a->past); - - if ($a->current || $a->past) { - foreach ($teachers as $teacher) { - // setup global $COURSE properly - needed for languages - cron_setup_user($teacher, $course); - $a->coursename = format_string($cname); - $strexpirynotifyemail = get_string('expirynotifyemail', '', $a); - $strexpirynotify = get_string('expirynotify'); - - $eventdata = new object(); - $eventdata->modulename = 'moodle'; - $eventdata->userfrom = $admin; - $eventdata->userto = $teacher; - $eventdata->subject = $a->coursename .' '. $strexpirynotify; - $eventdata->fullmessage = $strexpirynotifyemail; - $eventdata->fullmessageformat = FORMAT_PLAIN; - $eventdata->fullmessagehtml = ''; - $eventdata->smallmessage = ''; - message_send($eventdata); - } - } - } - } - $rs->close(); - cron_setup_user(); - } - - set_config('lastexpirynotify', date('Ymd')); -} - - -/** -* Returns the relevant icons for a course -* -* @param course the current course, as an object -*/ -function get_access_icons($course) { - global $CFG, $OUTPUT; - - global $strallowguests; - global $strrequireskey; - - if (empty($strallowguests)) { - $strallowguests = get_string('allowguests'); - $strrequireskey = get_string('requireskey'); - } - - $str = ''; - - if (!empty($course->guest)) { - $str .= ''; - $str .= ''.$strallowguests.'  '; - } - if (!empty($course->password)) { - $str .= ''; - $str .= ''.$strrequireskey.''; - } - - return $str; -} - -/** - * Prints the message telling you were to get the enrolment key - * appropriate for the prevailing circumstances - * A bit clunky because I didn't want to change the standard strings - */ -function print_enrolmentkeyfrom($course) { - global $CFG, $USER; - - $context = get_context_instance(CONTEXT_SYSTEM); - - // if a keyholder role is defined we list teachers in that role (if any exist) - $contactslisted = false; - if (!empty($CFG->enrol_manual_keyholderrole)) { - if ($contacts = get_role_users($CFG->enrol_manual_keyholderrole, get_context_instance(CONTEXT_COURSE, $course->id),true,'','u.lastname ASC')) { - // guest user has a slightly different message - if (isguestuser()) { - print_string('enrolmentkeyfromguest', '', ':
' ); - } - else { - print_string('enrolmentkeyfrom', '', ':
'); - } - foreach ($contacts as $contact) { - $contactname = "id&course=".SITEID."\">".fullname($contact)."."; - echo "$contactname
"; - } - $contactslisted = true; - } - } - - // if no keyholder role is defined OR nobody is in that role we do this the 'old' way - // (show the first person with update rights) - if (!$contactslisted) { - if ($teachers = get_users_by_capability(get_context_instance(CONTEXT_COURSE, $course->id), 'moodle/course:update', - 'u.*', 'u.id ASC', 0, 1, '', '', false, true)) { - $teacher = array_shift($teachers); - } - if (!empty($teacher)) { - $teachername = "id&course=".SITEID."\">".fullname($teacher)."."; - } else { - $teachername = strtolower( get_string('defaultcourseteacher') ); - } - - // guest user has a slightly different message - if (isguestuser()) { - print_string('enrolmentkeyfromguest', '', $teachername ); - } - else { - print_string('enrolmentkeyfrom', '', $teachername); - } - } -} - -} /// end of class - - Index: calendar/view.php =================================================================== --- calendar/view.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ calendar/view.php (revision ) @@ -636,7 +636,7 @@ if (has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_SYSTEM)) && !empty($CFG->calendar_adminseesall)) { $courses = get_courses('all', 'c.shortname','c.id,c.shortname'); } else { - $courses = get_my_courses($USER->id, 'shortname'); + $courses = enrol_get_my_courses(); } unset($courses[SITEID]); Index: enrol/authorize/enrol.php =================================================================== --- enrol/authorize/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/authorize/enrol.php (revision ) @@ -1,6 +1,5 @@ dirroot.'/enrol/enrol.class.php'); require_once($CFG->dirroot.'/enrol/authorize/const.php'); require_once($CFG->dirroot.'/enrol/authorize/localfuncs.php'); require_once($CFG->dirroot.'/enrol/authorize/authorizenet.class.php'); @@ -49,7 +48,7 @@ print_error('httpsrequired', 'enrol_authorize'); } else { $wwwsroot = str_replace('http:','https:', $CFG->wwwroot); - redirect("$wwwsroot/course/enrol.php?id=$course->id"); + redirect("$wwwsroot/enrol/index.php?id=$course->id"); exit; } } @@ -685,7 +684,8 @@ $timeend = $order->settletime + $course->enrolperiod; } $user = $DB->get_record('user', array('id'=>$order->userid)); - if (role_assign($role->id, $user->id, 0, $context->id, $timestart, $timeend, 0, 'authorize')) { + // TODO: do some real enrolment here + if (role_assign($role->id, $user->id, $context->id, 'enrol_authorize')) { $this->log .= "User($user->id) has been enrolled to course($course->id).\n"; if (!empty($CFG->enrol_mailstudents)) { $sendem[] = $order->id; Index: user/view.php =================================================================== --- user/view.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ user/view.php (revision ) @@ -121,7 +121,7 @@ if ($isfrontpage) { // Reduce possibility of "browsing" userbase at site level - if (!empty($CFG->forceloginforprofiles) and !has_capability('moodle/user:viewdetails', $usercontext) and !has_coursemanager_role($user->id)) { + if (!empty($CFG->forceloginforprofiles) and !has_capability('moodle/user:viewdetails', $usercontext) and !has_coursecontact_role($user->id)) { // Course managers can be browsed at site level. If not forceloginforprofiles, allow access (bug #4366) $PAGE->navbar->add($struser); echo $OUTPUT->header(); @@ -364,24 +364,26 @@ if (!isset($hiddenfields['mycourses'])) { - if ($mycourses = get_my_courses($user->id, 'visible DESC,sortorder ASC', null, false, 21)) { + if ($hiscourses = enrol_get_users_courses($user->id, true, NULL, 'visible DESC,sortorder ASC')) { $shown=0; $courselisting = ''; - foreach ($mycourses as $mycourse) { - if ($mycourse->category) { - if ($mycourse->id != $course->id){ + foreach ($hiscourses as $hiscourse) { + if ($hiscourse->category) { + if ($hiscourse->id != $course->id){ $class = ''; - if ($mycourse->visible == 0) { - // get_my_courses will filter courses $USER cannot see - // if we get one with visible 0 it just means it's hidden - // ... but not from $USER + if ($hiscourse->visible == 0) { + $ccontext = get_context_instance(CONTEXT_COURSE, $hiscourse->id, MUST_EXIST); + if (!has_capability('moodle/course:viewhiddencourses', $ccontext)) { + // filter our courses I am not allowed to see + continue; + } $class = 'class="dimmed"'; } - $courselisting .= "wwwroot}/user/view.php?id={$user->id}&course={$mycourse->id}\" $class >" - . format_string($mycourse->fullname) . ", "; + $courselisting .= "wwwroot}/user/view.php?id={$user->id}&course={$hiscourse->id}\" $class >" + . format_string($hiscourse->fullname) . ", "; } else { - $courselisting .= format_string($mycourse->fullname) . ", "; + $courselisting .= format_string($hiscourse->fullname) . ", "; } } $shown++; @@ -488,11 +490,12 @@ echo ""; } -if (!$isfrontpage && empty($course->metacourse)) { // Mostly only useful at course level +if (!$isfrontpage) { // Mostly only useful at course level if ($currentuser) { - if (is_enrolled($coursecontext, NULL, 'moodle/role:unassignself')) { - echo '
'; + /* + if (..detect if can unenrol somehow and probably cache it..) { + echo ''; echo '
'; echo ''; echo ''; @@ -500,6 +503,7 @@ echo '
'; echo ''; } + */ } else { if (is_enrolled($coursecontext, $user->id, 'moodle/role:assign')) { // I can unassign roles // add some button to unenroll user Index: enrol/manual/db/install.php =================================================================== --- enrol/manual/db/install.php (revision ) +++ enrol/manual/db/install.php (revision ) @@ -0,0 +1,24 @@ +enrol_manual_usepasswordpolicy)) { + set_config('usepasswordpolicy', $CFG->enrol_manual_usepasswordpolicy, 'enrol_guest'); + set_config('usepasswordpolicy', $CFG->enrol_manual_usepasswordpolicy, 'enrol_self'); + unset_config('enrol_manual_usepasswordpolicy'); + } + if (isset($CFG->enrol_manual_requirekey)) { + set_config('requirepassword', $CFG->enrol_manual_requirekey, 'enrol_guest'); + set_config('requirepassword', $CFG->enrol_manual_requirekey, 'enrol_self'); + unset_config('enrol_manual_requirekey'); + } + if (isset($CFG->enrol_manual_showhint)) { + set_config('showhint', $CFG->enrol_manual_showhint, 'enrol_guest'); + set_config('showhint', $CFG->enrol_manual_showhint, 'enrol_self'); + unset_config('enrol_manual_showhint'); + } +} + Index: enrol/paypal/enrol.php =================================================================== --- enrol/paypal/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/paypal/enrol.php (revision ) @@ -1,9 +1,6 @@ dirroot/enrol/enrol.class.php"); - - class enrolment_plugin_paypal { Index: enrol/meta/lib.php =================================================================== --- enrol/meta/lib.php (revision ) +++ enrol/meta/lib.php (revision ) @@ -0,0 +1,34 @@ +. + +/** + * Meta course enrolment plugin. + * + * @package enrol_meta + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +//TODO: +// * sync in cron or upon request + + +class enrol_meta_plugin extends enrol_plugin { + +} + Index: enrol/ldap/enrol_ldap_sync.php =================================================================== --- enrol/ldap/enrol_ldap_sync.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/ldap/enrol_ldap_sync.php (revision ) @@ -27,9 +27,4 @@ $enrol->sync_enrolments($role->shortname, true); } - // sync metacourses - if (function_exists('sync_metacourses')) { - sync_metacourses(); - } - Index: course/external.php =================================================================== --- course/external.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/external.php (revision ) @@ -51,16 +51,7 @@ * @subreturn integer $return:course->showgrades * @subreturn string $return:course->modinfo * @subreturn string $return:course->newsitems - * @subreturn string $return:course->guest - * @subreturn integer $return:course->metacourse - * @subreturn string $return:course->password - * @subreturn integer $return:course->enrolperiod - * @subreturn integer $return:course->defaultrole - * @subreturn integer $return:course->enrollable * @subreturn integer $return:course->numsections - * @subreturn integer $return:course->expirynotify - * @subreturn integer $return:course->notifystudents - * @subreturn integer $return:course->expirythreshold * @subreturn integer $return:course->marker * @subreturn integer $return:course->maxbytes * @subreturn integer $return:course->showreports @@ -71,20 +62,15 @@ * @subreturn integer $return:course->defaultgroupingid * @subreturn string $return:course->lang * @subreturn string $return:course->theme - * @subreturn string $return:course->cost - * @subreturn string $return:course->currency * @subreturn integer $return:course->timecreated * @subreturn integer $return:course->timemodified * @subreturn integer $return:course->requested * @subreturn integer $return:course->restrictmodules - * @subreturn integer $return:course->enrolstartdate - * @subreturn integer $return:course->enrolenddate - * @subreturn string $return:course->enrol * @subreturn integer $return:course->enablecompletion */ static function get_courses($params) { global $USER; - if (has_capability('moodle/course:participate', get_context_instance(CONTEXT_SYSTEM))) { + if (has_capability('moodle/course:view', get_context_instance(CONTEXT_SYSTEM))) { $courses = array(); foreach ($params as $param) { $course = new stdClass(); @@ -111,12 +97,9 @@ $returnedcourse->startdate = $course->startdate; $returnedcourse->category = $course->category; $returnedcourse->sortorder = $course->sortorder; - $returnedcourse->password = $course->password ; $returnedcourse->showgrades = $course->showgrades; $returnedcourse->modinfo = $course->modinfo; $returnedcourse->newsitems = $course->newsitems; - $returnedcourse->guest = $course->guest; - $returnedcourse->enrolperiod = $course->enrolperiod; $returnedcourse->marker = $course->marker; $returnedcourse->maxbytes = $course->maxbytes; $returnedcourse->showreports = $course->showreports; @@ -127,21 +110,10 @@ $returnedcourse->defaultgroupingid = $course->defaultgroupingid; $returnedcourse->lang = $course->lang; $returnedcourse->theme = $course->theme; - $returnedcourse->cost = $course->cost; - $returnedcourse->currency = $course->currency; $returnedcourse->timecreated = $course->timecreated; $returnedcourse->timemodified = $course->timemodified; - $returnedcourse->metacourse = $course->metacourse; $returnedcourse->requested = $course->requested; $returnedcourse->restrictmodules = $course->restrictmodules; - $returnedcourse->expirynotify = $course->expirynotify; - $returnedcourse->expirythreshold = $course->expirythreshold; - $returnedcourse->notifystudents = $course->notifystudents; - $returnedcourse->enrollable = $course->enrollable; - $returnedcourse->enrolstartdate = $course->enrolstartdate; - $returnedcourse->enrolenddate = $course->enrolenddate; - $returnedcourse->enrol = $course->enrol; - $returnedcourse->defaultrole = $course->defaultrole; $returnedcourse->enablecompletion = $course->enablecompletion; $courses[] = $returnedcourse; @@ -168,16 +140,7 @@ * @subparam integer $params:course->showgrades * @subparam string $params:course->modinfo * @subparam string $params:course->newsitems - * @subparam string $params:course->guest - * @subparam integer $params:course->metacourse - * @subparam string $params:course->password - * @subparam integer $params:course->enrolperiod - * @subparam integer $params:course->defaultrole - * @subparam integer $params:course->enrollable * @subparam integer $params:course->numsections - * @subparam integer $params:course->expirynotify - * @subparam integer $params:course->notifystudents - * @subparam integer $params:course->expirythreshold * @subparam integer $params:course->marker * @subparam integer $params:course->maxbytes * @subparam integer $params:course->showreports @@ -188,15 +151,10 @@ * @subparam integer $params:course->defaultgroupingid * @subparam string $params:course->lang * @subparam string $params:course->theme - * @subparam string $params:course->cost - * @subparam string $params:course->currency * @subparam integer $params:course->timecreated * @subparam integer $params:course->timemodified * @subparam integer $params:course->requested * @subparam integer $params:course->restrictmodules - * @subparam integer $params:course->enrolstartdate - * @subparam integer $params:course->enrolenddate - * @subparam string $params:course->enrol * @subparam integer $params:course->enablecompletion * @return array $return ids of new courses * @subreturn integer $return:id course id @@ -236,7 +194,6 @@ $course->startdate = clean_param($courseparams['startdate'], PARAM_INT); } - if (array_key_exists('sortorder', $courseparams)) { $course->sortorder = clean_param($courseparams['sortorder'], PARAM_INT); } @@ -253,46 +210,10 @@ $course->newsitems = clean_param($courseparams['newsitems'], PARAM_ALPHANUMEXT); } - if (array_key_exists('guest', $courseparams)) { - $course->guest = clean_param($courseparams['guest'], PARAM_ALPHANUMEXT); - } - - if (array_key_exists('metacourse', $courseparams)) { - $course->metacourse = clean_param($courseparams['metacourse'], PARAM_INT); - } - - if (array_key_exists('password', $courseparams)) { - $course->password = clean_param($courseparams['password'], PARAM_ALPHANUMEXT); - } - - if (array_key_exists('enrolperiod', $courseparams)) { - $course->enrolperiod = clean_param($courseparams['enrolperiod'], PARAM_INT); - } - - if (array_key_exists('defaultrole', $courseparams)) { - $course->defaultrole = clean_param($courseparams['defaultrole'], PARAM_INT); - } - - if (array_key_exists('enrollable', $courseparams)) { - $course->enrollable = clean_param($courseparams['enrollable'], PARAM_INT); - } - if (array_key_exists('numsections', $courseparams)) { $course->numsections = clean_param($courseparams['numsections'], PARAM_INT); } - if (array_key_exists('expirynotify', $courseparams)) { - $course->expirynotify = clean_param($courseparams['expirynotify'], PARAM_INT); - } - - if (array_key_exists('notifystudents', $courseparams)) { - $course->notifystudents = clean_param($courseparams['notifystudents'], PARAM_INT); - } - - if (array_key_exists('expirythreshold', $courseparams)) { - $course->expirythreshold = clean_param($courseparams['expirythreshold'], PARAM_INT); - } - if (array_key_exists('marker', $courseparams)) { $course->marker = clean_param($courseparams['marker'], PARAM_INT); } @@ -313,7 +234,6 @@ $course->hiddensections = clean_param($courseparams['hiddensections'], PARAM_INT); } - if (array_key_exists('groupmode', $courseparams)) { $course->groupmode = clean_param($courseparams['groupmode'], PARAM_INT); } @@ -334,14 +254,6 @@ $course->theme = clean_param($courseparams['theme'], PARAM_ALPHANUMEXT); } - if (array_key_exists('cost', $courseparams)) { - $course->cost = clean_param($courseparams['cost'], PARAM_ALPHANUMEXT); - } - - if (array_key_exists('currency', $courseparams)) { - $course->currency = clean_param($courseparams['currency'], PARAM_ALPHANUMEXT); - } - if (array_key_exists('timecreated', $courseparams)) { $course->timecreated = clean_param($courseparams['timecreated'], PARAM_INT); } @@ -358,18 +270,6 @@ $course->restrictmodules = clean_param($courseparams['restrictmodules'], PARAM_INT); } - if (array_key_exists('enrolstartdate', $courseparams)) { - $course->enrolstartdate = clean_param($courseparams['enrolstartdate'], PARAM_INT); - } - - if (array_key_exists('enrolenddate', $courseparams)) { - $course->enrolenddate = clean_param($courseparams['enrolenddate'], PARAM_INT); - } - - if (array_key_exists('enrol', $courseparams)) { - $course->enrol = clean_param($courseparams['enrol'], PARAM_ALPHANUMEXT); - } - if (array_key_exists('enablecompletion', $courseparams)) { $course->enablecompletion = clean_param($courseparams['enablecompletion'], PARAM_INT); } @@ -445,16 +345,7 @@ * @subparam integer $params:course->showgrades * @subparam string $params:course->modinfo * @subparam string $params:course->newsitems - * @subparam string $params:course->guest - * @subparam integer $params:course->metacourse - * @subparam string $params:course->password - * @subparam integer $params:course->enrolperiod - * @subparam integer $params:course->defaultrole - * @subparam integer $params:course->enrollable * @subparam integer $params:course->numsections - * @subparam integer $params:course->expirynotify - * @subparam integer $params:course->notifystudents - * @subparam integer $params:course->expirythreshold * @subparam integer $params:course->marker * @subparam integer $params:course->maxbytes * @subparam integer $params:course->showreports @@ -465,15 +356,10 @@ * @subparam integer $params:course->defaultgroupingid * @subparam string $params:course->lang * @subparam string $params:course->theme - * @subparam string $params:course->cost - * @subparam string $params:course->currency * @subparam integer $params:course->timecreated * @subparam integer $params:course->timemodified * @subparam integer $params:course->requested * @subparam integer $params:course->restrictmodules - * @subparam integer $params:course->enrolstartdate - * @subparam integer $params:course->enrolenddate - * @subparam string $params:course->enrol * @subparam integer $params:course->enablecompletion * @return boolean result true if success */ @@ -515,7 +401,6 @@ $course->startdate = clean_param($courseparams['startdate'], PARAM_INT); } - if (array_key_exists('sortorder', $courseparams)) { $course->sortorder = clean_param($courseparams['sortorder'], PARAM_INT); } @@ -532,46 +417,10 @@ $course->newsitems = clean_param($courseparams['newsitems'], PARAM_ALPHANUMEXT); } - if (array_key_exists('guest', $courseparams)) { - $course->guest = clean_param($courseparams['guest'], PARAM_ALPHANUMEXT); - } - - if (array_key_exists('metacourse', $courseparams)) { - $course->metacourse = clean_param($courseparams['metacourse'], PARAM_INT); - } - - if (array_key_exists('password', $courseparams)) { - $course->password = clean_param($courseparams['password'], PARAM_ALPHANUMEXT); - } - - if (array_key_exists('enrolperiod', $courseparams)) { - $course->enrolperiod = clean_param($courseparams['enrolperiod'], PARAM_INT); - } - - if (array_key_exists('defaultrole', $courseparams)) { - $course->defaultrole = clean_param($courseparams['defaultrole'], PARAM_INT); - } - - if (array_key_exists('enrollable', $courseparams)) { - $course->enrollable = clean_param($courseparams['enrollable'], PARAM_INT); - } - if (array_key_exists('numsections', $courseparams)) { $course->numsections = clean_param($courseparams['numsections'], PARAM_INT); } - if (array_key_exists('expirynotify', $courseparams)) { - $course->expirynotify = clean_param($courseparams['expirynotify'], PARAM_INT); - } - - if (array_key_exists('notifystudents', $courseparams)) { - $course->notifystudents = clean_param($courseparams['notifystudents'], PARAM_INT); - } - - if (array_key_exists('expirythreshold', $courseparams)) { - $course->expirythreshold = clean_param($courseparams['expirythreshold'], PARAM_INT); - } - if (array_key_exists('marker', $courseparams)) { $course->marker = clean_param($courseparams['marker'], PARAM_INT); } @@ -612,14 +461,6 @@ $course->theme = clean_param($courseparams['theme'], PARAM_ALPHANUMEXT); } - if (array_key_exists('cost', $courseparams)) { - $course->cost = clean_param($courseparams['cost'], PARAM_ALPHANUMEXT); - } - - if (array_key_exists('currency', $courseparams)) { - $course->currency = clean_param($courseparams['currency'], PARAM_ALPHANUMEXT); - } - if (array_key_exists('timecreated', $courseparams)) { $course->timecreated = clean_param($courseparams['timecreated'], PARAM_INT); } @@ -636,18 +477,6 @@ $course->restrictmodules = clean_param($courseparams['restrictmodules'], PARAM_INT); } - if (array_key_exists('enrolstartdate', $courseparams)) { - $course->enrolstartdate = clean_param($courseparams['enrolstartdate'], PARAM_INT); - } - - if (array_key_exists('enrolenddate', $courseparams)) { - $course->enrolenddate = clean_param($courseparams['enrolenddate'], PARAM_INT); - } - - if (array_key_exists('enrol', $courseparams)) { - $course->enrol = clean_param($courseparams['enrol'], PARAM_ALPHANUMEXT); - } - if (array_key_exists('enablecompletion', $courseparams)) { $course->enablecompletion = clean_param($courseparams['enablecompletion'], PARAM_INT); } @@ -681,7 +510,7 @@ */ static function get_course_modules($params, $type=null) { global $DB; - if (has_capability('moodle/course:participate', get_context_instance(CONTEXT_SYSTEM))) { + if (has_capability('moodle/course:view', get_context_instance(CONTEXT_SYSTEM))) { $modules = array(); foreach ($params as $courseparams) { if (array_key_exists('id', $courseparams)) { Index: message/lib.php =================================================================== --- message/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ message/lib.php (revision ) @@ -319,7 +319,7 @@ if (optional_param('mycourses', 0, PARAM_BOOL)) { $users = array(); - $mycourses = get_my_courses($USER->id); + $mycourses = enrol_get_my_courses(); foreach ($mycourses as $mycourse) { if (is_array($susers = message_search_users($mycourse->id, $frm->name))) { foreach ($susers as $suser) $users[$suser->id] = $suser; Index: grade/querylib.php =================================================================== --- grade/querylib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ grade/querylib.php (revision ) @@ -128,7 +128,7 @@ if (!is_array($courseid_or_ids)) { if (empty($courseid_or_ids)) { - if (!$courses = get_my_courses($userid, $sort='visible DESC,sortorder ASC', 'id')) { + if (!$courses = enrol_get_users_courses($userid)) { return false; } $courseids = array_keys($courses); Index: auth/cas/auth.php =================================================================== --- auth/cas/auth.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ auth/cas/auth.php (revision ) @@ -824,9 +824,9 @@ // update course creators if needed if ($creatorrole !== false) { if ($this->iscreator($user->username)) { - role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'cas'); + role_assign($creatorrole->id, $user->id, $sitecontext->id, 'auth_cas'); } else { - role_unassign($creatorrole->id, $user->id, 0, $sitecontext->id, 'cas'); + role_unassign($creatorrole->id, $user->id, $sitecontext->id, 'auth_cas'); } } } @@ -884,7 +884,7 @@ // add course creators if needed if ($creatorrole !== false and $this->iscreator($user->username)) { - role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'cas'); + role_assign($creatorrole->id, $user->id, $sitecontext->id, 'auth_cas'); } } $transaction->allow_commit(); @@ -1128,10 +1128,10 @@ $creatorrole = array_shift($roles); // We can only use one, let's use the first one $systemcontext = get_context_instance(CONTEXT_SYSTEM); if ($iscreator) { // Following calls will not create duplicates - role_assign($creatorrole->id, $user->id, 0, $systemcontext->id, 0, 0, 0, 'cas'); + role_assign($creatorrole->id, $user->id, $systemcontext->id, 'auth_cas'); } else { //unassign only if previously assigned by this plugin! - role_unassign($creatorrole->id, $user->id, 0, $systemcontext->id, 'cas'); + role_unassign($creatorrole->id, $user->id, $systemcontext->id, 'auth_cas'); } } } Index: repository/lib.php =================================================================== --- repository/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ repository/lib.php (revision ) @@ -549,7 +549,7 @@ $level = $context->contextlevel; if ($level == CONTEXT_COURSE) { - if (!has_capability('moodle/course:participate', $context)) { + if (!is_enrolled($context)) { //TODO: this looks a bit too simple, verify! return false; } else { return true; Index: lib/db/install.php =================================================================== --- lib/db/install.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/db/install.php (revision ) @@ -46,7 +46,7 @@ 'auth' => 'email', 'auth_pop3mailbox' => 'INBOX', 'enrol' => 'manual', - 'enrol_plugins_enabled' => 'manual', + 'enrol_plugins_enabled' => 'manual,guest,self,cohort', 'style' => 'default', 'template' => 'default', 'theme' => theme_config::DEFAULT_THEME, Index: lang/en/help/courseenrollable2.html =================================================================== --- lang/en/help/courseenrollable2.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lang/en/help/courseenrollable2.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,2 +0,0 @@ -

This setting determines whether students are able to enrol themselves using the default interactive enrolment plugin (e.g. Internal enrolment) for the course, or whether they obtain the message "This course is not enrollable at the moment."

-

This setting has no effect on non-interactive enrolment plugins (e.g. External database enrolment). Also, users can always be assigned the role of student via the Assign roles link in the course administration block.

\ No newline at end of file Index: enrol/self/db/access.php =================================================================== --- enrol/self/db/access.php (revision ) +++ enrol/self/db/access.php (revision ) @@ -0,0 +1,25 @@ + array( + + 'captype' => 'write', + 'contextlevel' => CONTEXT_COURSE, + 'legacy' => array( + 'editingteacher' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + ) + ), + +); + + Index: admin/uploaduser.php =================================================================== --- admin/uploaduser.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/uploaduser.php (revision ) @@ -658,12 +658,10 @@ $a = new object(); $a->course = $shortname; $a->role = $rolecache[$rid]->name; - if (role_assign($rid, $user->id, 0, $coursecontext->id, $timestart, $timeend)) { + //TODO: use real manual enrolments here! + role_assign($rid, $user->id, $coursecontext->id); - $upt->track('enrolments', get_string('enrolledincourserole', '', $a)); + $upt->track('enrolments', get_string('enrolledincourserole', '', $a)); - } else { - $upt->track('enrolments', get_string('enrolledincoursenotrole', '', $a), 'error'); - } + } - } // find group to add to if (!empty($user->{'group'.$i})) { Index: enrol/index.php =================================================================== --- enrol/index.php (revision ) +++ enrol/index.php (revision ) @@ -0,0 +1,99 @@ +. + +/** + * This page shows all course enrolment options for current user. + * + * @package core + * @subpackage course + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require('../config.php'); +require_once("$CFG->libdir/formslib.php"); + +$id = required_param('id', PARAM_INT); + +if (!isloggedin()) { + // do not use require_login here because we are usually coming from it, + // it would also mess up the SESSION->wantsurl + redirect(get_login_url()); +} + +$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST); +$context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); + +// Everybody is enrolled on the frontpage +if ($course->id == SITEID) { + redirect("$CFG->wwwroot/"); +} + +$PAGE->set_url('/enrol/index.php', array('id'=>$course->id)); + +// do not allow enrols when in login-as session +if (session_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; + unset($SESSION->wantsurl); + } else { + $destination = "$CFG->wwwroot/course/view.php?id=$course->id"; + } + redirect($destination); // Bye! +} + +$PAGE->set_title($course->shortname); +$PAGE->set_heading($course->fullname); +$PAGE->navbar->add($course->fullname); + + +echo $OUTPUT->header(); + +//TODO: find if future enrolments present and display some info + +foreach ($forms as $form) { + echo $form; +} + +if (!$forms) { + notice(get_string('notenrollable'), "$CFG->wwwroot/index.php"); +} + +if (isguestuser()) { + //TODO: print login link + some info +} + +echo $OUTPUT->footer(); Index: course/info.php =================================================================== --- course/info.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/info.php (revision ) @@ -29,7 +29,7 @@ } $context = get_context_instance(CONTEXT_COURSE, $course->id); - if ((!course_parent_visible($course) || (! $course->visible)) && !has_capability('moodle/course:viewhiddencourses', $context)) { + if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) { print_error('coursehidden', '', $CFG->wwwroot .'/'); } @@ -61,9 +61,9 @@ $course->summary = file_rewrite_pluginfile_urls($course->summary, 'pluginfile.php', $context->id, 'course_summary', $course->id); echo format_text($course->summary, $course->summaryformat, NULL, $course->id); - if (!empty($CFG->coursemanager)) { - $coursemanagerroles = explode(',', $CFG->coursemanager); - foreach ($coursemanagerroles as $roleid) { + if (!empty($CFG->coursecontact)) { + $coursecontactroles = explode(',', $CFG->coursecontact); + foreach ($coursecontactroles as $roleid) { $role = $DB->get_record('role', array('id'=>$roleid)); $roleid = (int) $roleid; if ($users = get_role_users($roleid, $context, true)) { @@ -82,9 +82,7 @@ } } - require_once("$CFG->dirroot/enrol/enrol.class.php"); - $enrol = enrolment_factory::factory($course->enrol); - echo $enrol->get_access_icons($course); +// TODO: print some enrol icons echo $OUTPUT->box_end(); Index: enrol/imsenterprise/enrol.php =================================================================== --- enrol/imsenterprise/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/imsenterprise/enrol.php (revision ) @@ -761,7 +761,8 @@ // Enrol unsing the generic role_assign() function - if ((!role_assign($moodleroleid, $memberstoreobj->userid, 0, $rolecontext, $timeframe->begin, $timeframe->end, 0, 'imsenterprise')) && (trim($memberstoreobj->userid)!='')) { + //TODO: some real enrolment here + if ((!role_assign($moodleroleid, $memberstoreobj->userid, $rolecontext, 'enrol_imsenterprise')) && (trim($memberstoreobj->userid)!='')) { $this->log_line("Error enrolling user #$memberstoreobj->userid ($member->idnumber) to role $member->roletype in course $memberstoreobj->course"); }else{ $this->log_line("Enrolled user #$memberstoreobj->userid ($member->idnumber) to role $member->roletype in course $memberstoreobj->course"); @@ -798,13 +799,10 @@ }elseif($CFG->enrol_imsunenrol){ // Unenrol - if (! role_unassign($moodleroleid, $memberstoreobj->userid, 0, $rolecontext, 'imsenterprise')) { - $this->log_line("Error unenrolling $memberstoreobj->userid from role $moodleroleid in course"); - }else{ + role_unassign($moodleroleid, $memberstoreobj->userid, 0, $rolecontext, 'imsenterprise'); - $membersuntally++; - $this->log_line("Unenrolled $member->idnumber from role $moodleroleid in course"); - } + $membersuntally++; + $this->log_line("Unenrolled $member->idnumber from role $moodleroleid in course"); + } - } } } Index: lib/sessionlib.php =================================================================== --- lib/sessionlib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/sessionlib.php (revision ) @@ -74,7 +74,7 @@ * @return void */ public function write_close(); - + /** * Check for existing session with id $sid * @param unknown_type $sid @@ -159,7 +159,7 @@ } catch (Exception $ignored) { // probably install/upgrade - ignore this problem } - + if (NO_MOODLE_COOKIES) { return; } @@ -372,7 +372,7 @@ $sessionfile = clean_param("$CFG->dataroot/sessions/sess_$sid", PARAM_FILE); return file_exists($sessionfile); } - + } @@ -401,20 +401,20 @@ } } } - + public function session_exists($sid){ global $CFG; try { $sql = "SELECT * FROM {sessions} WHERE timemodified < ? AND sid=? AND state=?"; $params = array(time() + $CFG->sessiontimeout, $sid, 0); - + return $this->database->record_exists_sql($sql, $params); } catch (dml_exception $ex) { error_log('Error checking existance of database session'); return false; } } - + protected function init_session_storage() { global $CFG; @@ -878,7 +878,7 @@ unset($_SESSION['USER']->description); // conserve memory if (!isset($_SESSION['USER']->access)) { // check enrolments and load caps only once - check_enrolment_plugins($_SESSION['USER']); + enrol_check_plugins($_SESSION['USER']); load_all_capabilities(); } sesskey(); // init session key Index: lib/setup.php =================================================================== --- lib/setup.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/setup.php (revision ) @@ -289,6 +289,7 @@ require_once($CFG->libdir .'/accesslib.php'); // Access control functions require_once($CFG->libdir .'/deprecatedlib.php'); // Deprecated functions included for backward compatibility require_once($CFG->libdir .'/moodlelib.php'); // Other general-purpose functions +require_once($CFG->libdir .'/enrollib.php'); // Enrolment related functions require_once($CFG->libdir .'/pagelib.php'); // Library that defines the moodle_page class, used for $PAGE require_once($CFG->libdir .'/blocklib.php'); // Library for controlling blocks require_once($CFG->libdir .'/eventslib.php'); // Events functions Index: lib/simpletest/broken_testfilelib.php =================================================================== --- lib/simpletest/broken_testfilelib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/simpletest/broken_testfilelib.php (revision ) @@ -135,7 +135,7 @@ $this->user->id = create_user($this->user); // Assign user to course - // role_assign(5, $this->user->id, 0, get_context_instance(CONTEXT_COURSE, $this->course->id)->id); + // role_assign(5, $this->user->id, get_context_instance(CONTEXT_COURSE, $this->course->id)->id); // Create a module $module = new stdClass(); Index: admin/settings/users.php =================================================================== --- admin/settings/users.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/settings/users.php (revision ) @@ -155,6 +155,7 @@ $temp->add(new admin_setting_configcheckbox('nodefaultuserrolelists', get_string('nodefaultuserrolelists', 'admin'), get_string('confignodefaultuserrolelists', 'admin'), 0)); if (!during_initial_install()) { + //TODO? remove defaultcourseroleid because it was replaced by default roles in each enrol plugin $temp->add(new admin_setting_configselect('defaultcourseroleid', get_string('defaultcourseroleid', 'admin'), get_string('configdefaultcourseroleid', 'admin'), $defaultstudentid, $allroles)); $temp->add(new admin_setting_configselect('creatornewroleid', get_string('creatornewroleid', 'admin'), @@ -163,11 +164,6 @@ $temp->add(new admin_setting_configcheckbox('autologinguests', get_string('autologinguests', 'admin'), get_string('configautologinguests', 'admin'), 0)); - if (!during_initial_install()) { - $temp->add(new admin_setting_configmultiselect('nonmetacoursesyncroleids', get_string('nonmetacoursesyncroleids', 'admin'), - get_string('confignonmetacoursesyncroleids', 'admin'), array(), $allroles)); - } - $temp->add(new admin_setting_configmultiselect('hiddenuserfields', get_string('hiddenuserfields', 'admin'), get_string('confighiddenuserfields', 'admin'), array(), array('description' => get_string('description'), Index: admin/settings/courses.php =================================================================== --- admin/settings/courses.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/settings/courses.php (revision ) @@ -11,8 +11,6 @@ $ADMIN->add('courses', new admin_externalpage('coursemgmt', get_string('coursemgmt', 'admin'), $CFG->wwwroot . '/course/index.php?categoryedit=on', array('moodle/category:manage', 'moodle/course:create'))); - $ADMIN->add('courses', new admin_enrolment_page()); - /// Course Default Settings Page /// NOTE: these settings must be applied after all other settings because they depend on them ///main course settings @@ -41,46 +39,7 @@ $choices = get_max_upload_sizes(); } $temp->add(new admin_setting_configselect('moodlecourse/maxbytes', get_string('maximumupload'), get_string('coursehelpmaximumupload'), key($choices), $choices)); - $temp->add(new admin_setting_configselect('moodlecourse/metacourse', get_string('metacourse'), get_string('coursehelpmetacourse'), 0,array(0 => get_string('no'), 1 => get_string('yes')))); - ///enrolement course settings - $temp->add(new admin_setting_heading('enrolhdr', get_string('enrolments'), '')); - require_once($CFG->dirroot.'/enrol/enrol.class.php'); - $choices = array(); - $modules = explode(',', $CFG->enrol_plugins_enabled); - foreach ($modules as $module) { - $name = get_string('enrolname', "enrol_$module"); - $plugin = enrolment_factory::factory($module); - if (method_exists($plugin, 'print_entry')) { - $choices[$name] = $module; - } - } - asort($choices); - $choices = array_flip($choices); - $choices = array_merge(array('' => get_string('sitedefault').' ('.get_string('enrolname', "enrol_$CFG->enrol").')'), $choices); - $temp->add(new admin_setting_configselect('moodlecourse/enrol', get_string('enrolmentplugins'), get_string('coursehelpenrolmentplugins'), key($choices),$choices)); - $choices = array(0 => get_string('no'), 1 => get_string('yes'), 2 => get_string('enroldate')); - $temp->add(new admin_setting_configselect('moodlecourse/enrollable', get_string('enrollable'), get_string('coursehelpenrollable'), 1,$choices)); - $periodmenu=array(); - $periodmenu[0] = get_string('unlimited'); - for ($i=1; $i<=365; $i++) { - $seconds = $i * 86400; - $periodmenu[$seconds] = get_string('numdays', '', $i); - } - $temp->add(new admin_setting_configselect('moodlecourse/enrolperiod', get_string('enrolperiod'), '', 0,$periodmenu)); - - /// - $temp->add(new admin_setting_heading('expirynotifyhdr', get_string('expirynotify'), '')); - $temp->add(new admin_setting_configselect('moodlecourse/expirynotify', get_string('notify'), get_string('coursehelpnotify'), 0,array(0 => get_string('no'), 1 => get_string('yes')))); - $temp->add(new admin_setting_configselect('moodlecourse/notifystudents', get_string('expirynotifystudents'), get_string('coursehelpexpirynotifystudents'), 0,array(0 => get_string('no'), 1 => get_string('yes')))); - $thresholdmenu=array(); - for ($i=1; $i<=30; $i++) { - $seconds = $i * 86400; - $thresholdmenu[$seconds] = get_string('numdays', '', $i); - } - $temp->add(new admin_setting_configselect('moodlecourse/expirythreshold', get_string('expirythreshold'), get_string('coursehelpexpirythreshold'), 10 * 86400,$thresholdmenu)); - - $temp->add(new admin_setting_heading('groups', get_string('groups', 'group'), '')); $choices = array(); $choices[NOGROUPS] = get_string('groupsnone', 'group'); @@ -95,12 +54,6 @@ $choices['0'] = get_string('courseavailablenot'); $choices['1'] = get_string('courseavailable'); $temp->add(new admin_setting_configselect('moodlecourse/visible', get_string('visible'), '', 1,$choices)); - $temp->add(new admin_setting_configpasswordunmask('moodlecourse/enrolpassword', get_string('enrolmentkey'), get_string('coursehelpenrolmentkey'),'')); - $choices = array(); - $choices['0'] = get_string('guestsno'); - $choices['1'] = get_string('guestsyes'); - $choices['2'] = get_string('guestskey'); - $temp->add(new admin_setting_configselect('moodlecourse/guest', get_string('opentoguests'), '', 0,$choices)); $temp->add(new admin_setting_heading('language', get_string('language'), '')); @@ -133,7 +86,6 @@ $temp = new admin_settingpage('backups', get_string('backups','admin'), 'moodle/backup:backupcourse'); $temp->add(new admin_setting_configcheckbox('backup/backup_sche_modules', get_string('includemodules'), get_string('backupincludemoduleshelp'), 0)); $temp->add(new admin_setting_configcheckbox('backup/backup_sche_withuserdata', get_string('includemoduleuserdata'), get_string('backupincludemoduleuserdatahelp'), 0)); - $temp->add(new admin_setting_configcheckbox('backup/backup_sche_metacourse', get_string('metacourse'), get_string('backupmetacoursehelp'), 0)); $temp->add(new admin_setting_configselect('backup/backup_sche_users', get_string('users'), get_string('backupusershelp'), 0, array(0 => get_string('all'), 1 => get_string('course')))); $temp->add(new admin_setting_configcheckbox('backup/backup_sche_logs', get_string('logs'), get_string('backuplogshelp'), 0)); Index: pluginfile.php =================================================================== --- pluginfile.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ pluginfile.php (revision ) @@ -220,7 +220,7 @@ if ($USER->id !== $userid) { $usercontext = get_context_instance(CONTEXT_USER, $userid); // The browsing user is not the current user - if (!has_coursemanager_role($userid) && !has_capability('moodle/user:viewdetails', $usercontext)) { + if (!has_coursecontact_role($userid) && !has_capability('moodle/user:viewdetails', $usercontext)) { send_file_not_found(); } @@ -228,7 +228,7 @@ if (has_capability('moodle/user:viewdetails', $usercontext)) { $canview = true; } else { - $courses = get_my_courses($USER->id); + $courses = enrol_get_my_courses(); } while (!$canview && count($courses) > 0) { @@ -423,7 +423,7 @@ print_error('noguest'); } - if (!has_coursemanager_role($userid) and !has_capability('moodle/user:viewdetails', $usercontext)) { + if (!has_coursecontact_role($userid) and !has_capability('moodle/user:viewdetails', $usercontext)) { print_error('usernotavailable'); } if (!has_capability('moodle/user:viewdetails', $context) && Index: enrol/cohort/lang/en/enrol_cohort.php =================================================================== --- enrol/cohort/lang/en/enrol_cohort.php (revision ) +++ enrol/cohort/lang/en/enrol_cohort.php (revision ) @@ -0,0 +1,26 @@ +. + +/** + * Strings for component 'enrol_cohort', language 'en', branch 'MOODLE_20_STABLE' + * + * @package enrol_cohort + * @copyright 2010 onwards Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$string['pluginname'] = 'Cohort synchronisation'; Index: search/querylib.php =================================================================== --- search/querylib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ search/querylib.php (revision ) @@ -398,7 +398,7 @@ } // first check course compatibility against user : enrolled users to that course can see. - $myCourses = get_my_courses($user->id); + $myCourses = enrol_get_users_courses($user->id, true); $unenroled = !in_array($course_id, array_keys($myCourses)); // if guests are allowed, logged guest can see Index: admin/cron.php =================================================================== --- admin/cron.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/cron.php (revision ) @@ -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,9 @@ if ($random100 < 20) { // Approximately 20% of the time. mtrace("Running clean-up tasks..."); - /// Unenrol users who haven't logged in for $CFG->longtimenosee + /// TODO: 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 +310,6 @@ } flush(); - sync_metacourses(); - mtrace('Synchronised metacourses'); - // // generate new password emails for users // @@ -464,21 +401,16 @@ unset($authplugin); } -/// Run the enrolment cron, if any - if (!($plugins = explode(',', $CFG->enrol_plugins_enabled))) { - $plugins = array($CFG->enrol); + mtrace("Running enrol crons if required..."); + $enrols = enrol_get_plugins(true); + foreach($enrols as $ename=>$enrol) { + if (!$enrol->is_cron_required()) { + continue; - } + } - require_once($CFG->dirroot .'/enrol/enrol.class.php'); - foreach ($plugins as $p) { - $enrol = enrolment_factory::factory($p); - if (method_exists($enrol, 'cron')) { + mtrace("Running cron for enrol_$ename..."); - $enrol->cron(); + $enrol->cron(); + $enrol->set_config('lastcron', time()); - } + } - if (!empty($enrol->log)) { - mtrace($enrol->log); - } - unset($enrol); - } if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) { require_once($CFG->dirroot.'/lib/statslib.php'); Index: enrol/manual/db/access.php =================================================================== --- enrol/manual/db/access.php (revision ) +++ enrol/manual/db/access.php (revision ) @@ -0,0 +1,58 @@ +. + +/** + * Capabilities for manual enrolment plugin. + * + * @package enrol_manual + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +$capabilities = array( + + 'enrol/manual:config' => array( + + 'captype' => 'write', + 'contextlevel' => CONTEXT_COURSE, + 'legacy' => array( + 'manager' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + ) + ), + + 'enrol/manual:manage' => array( + + 'captype' => 'write', + 'contextlevel' => CONTEXT_COURSE, + 'legacy' => array( + 'manager' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + ) + ), + + 'enrol/manual:unenrolself' => array( + + 'captype' => 'write', + 'contextlevel' => CONTEXT_COURSE, + 'legacy' => array( + ) + ), + +); + Index: search/documents/resource_document.php =================================================================== --- search/documents/resource_document.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ search/documents/resource_document.php (revision ) @@ -326,7 +326,7 @@ } //check if user is registered in course or course is open to guests - if (!$course->guest && !has_capability('moodle/course:participate', $course_context)) { + if (!is_enrolled($course_context) and !is_viewing($course_context)) { //TODO: guest course access is gone, this needs a different solution return false; } Index: enrol/review.php =================================================================== --- enrol/review.php (revision ) +++ enrol/review.php (revision ) @@ -0,0 +1,239 @@ +. + +/** + * Main course enrolment management UI. + * + * @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('../config.php'); + +$id = required_param('id', PARAM_INT); // course id +$action = optional_param('action', '', PARAM_ACTION); +$instanceid = optional_param('instance', 0, PARAM_INT); +$confirm = optional_param('confirm', 0, PARAM_BOOL); +$add = optional_param('add', '', PARAM_SAFEDIR); // name of enrol plugin to be added to course + +$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST); +$context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); + +require_login($course); +require_capability('moodle/course:enrolreview', $context); + +$canconfig = has_capability('moodle/course:enrolconfig', $context); + +$PAGE->set_url('/enrol/review.php', array('id'=>$course->id)); + +$instances = enrol_get_instances($course->id, false); +$plugins = enrol_get_plugins(false); + +if ($canconfig and $action and confirm_sesskey()) { + if (isset($instances[$instanceid]) and isset($plugins[$instances[$instanceid]->enrol])) { + if ($action === 'up') { + $order = array_keys($instances); + $order = array_flip($order); + $pos = $order[$instanceid]; + if ($pos > 0) { + $switch = $pos - 1; + $resorted = array_values($instances); + $temp = $resorted[$pos]; + $resorted[$pos] = $resorted[$switch]; + $resorted[$switch] = $temp; + // now update db sortorder + foreach ($resorted as $sortorder=>$instance) { + if ($instance->sortorder != $sortorder) { + $instance->sortorder = $sortorder; + $DB->update_record('enrol', $instance); + } + } + } + redirect($PAGE->url); + + } else if ($action === 'down') { + $order = array_keys($instances); + $order = array_flip($order); + $pos = $order[$instanceid]; + if ($pos < count($instances) - 1) { + $switch = $pos + 1; + $resorted = array_values($instances); + $temp = $resorted[$pos]; + $resorted[$pos] = $resorted[$switch]; + $resorted[$switch] = $temp; + // now update db sortorder + foreach ($resorted as $sortorder=>$instance) { + if ($instance->sortorder != $sortorder) { + $instance->sortorder = $sortorder; + $DB->update_record('enrol', $instance); + } + } + } + redirect($PAGE->url); + + } else if ($action === 'delete') { + $instance = $instances[$instanceid]; + $plugin = $plugins[$instance->enrol]; + + if ($confirm) { + $plugin->delete_instance($instance); + redirect($PAGE->url); + } + + echo $OUTPUT->header(); + $yesurl = new moodle_url('/enrol/review.php', array('id'=>$course->id, 'action'=>'delete', 'instance'=>$instance->id, 'confirm'=>1,'sesskey'=>sesskey())); + $displayname = empty($instance->name) ? get_string('pluginname', 'enrol_'.$instance->enrol) : format_string($instance->name); + $users = $DB->count_records('course_participants', array('enrolid'=>$instance->id)); + $message = get_string('deleteinstanceconfirm', 'enrol', array('name'=>$displayname, 'users'=>$users)); + echo $OUTPUT->confirm($message, $yesurl, $PAGE->url); + echo $OUTPUT->footer(); + die(); + + } else if ($action === 'disable') { + $instance = $instances[$instanceid]; + if ($instance->status == ENROL_STATUS_ENABLED) { + $instance->status = ENROL_STATUS_DISABLED; + $DB->update_record('enrol', $instance); + redirect($PAGE->url); + } + + } else if ($action === 'enable') { + $instance = $instances[$instanceid]; + if ($instance->status == ENROL_STATUS_DISABLED) { + $instance->status = ENROL_STATUS_ENABLED; + $DB->update_record('enrol', $instance); + redirect($PAGE->url); + } + } + } + if ($action === 'add') { + $candidates = enrol_get_instance_candidates($course->id); + + if (isset($plugins[$add]) and isset($candidates[$add])) { + $plugins[$add]->add_default_instance($course); + redirect($PAGE->url); + } + } + +} + + +echo $OUTPUT->header(); + +$currenttab = 'review'; +require('tabs.php'); + +echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthnormal'); + +// display strings +$strup = get_string('up'); +$strdown = get_string('down'); +$strdelete = get_string('delete'); +$strenable = get_string('enable'); +$strdisable = get_string('disable'); + +$table = new html_table(); +if ($canconfig) { + $table->head = array(get_string('name'), get_string('users'), $strup.'/'.$strdown, get_string('edit')); + $table->align = array('left', 'center', 'center', 'center'); +} else { + $table->head = array(get_string('name'), get_string('users')); + $table->align = array('left', 'center'); +} +$table->width = '100%'; +$table->data = array(); + +// iterate through enrol plugins and add to the display table +$updowncount = 1; +$icount = count($instances); +$url = new moodle_url('/enrol/review.php', array('sesskey'=>sesskey(), 'id'=>$course->id)); +foreach ($instances as $instance) { + if (!isset($plugins[$instance->enrol])) { + continue; + } + $plugin = $plugins[$instance->enrol]; + + $displayname = empty($instance->name) ? get_string('pluginname', 'enrol_'.$instance->enrol) : format_string($instance->name); + if (enrol_is_enabled($instance->enrol)) { + //TODO: why is dimmed_text not dimming text??? + $displayname = html_writer::tag('span', $displayname, array('class'=>'dimmed_text')); + } else if ($instance->status != ENROL_STATUS_ENABLED) { + //TODO: why is dimmed_text not dimming text??? + $displayname = html_writer::tag('span', $displayname, array('class'=>'dimmed_text')); + } + + $users = $DB->count_records('course_participants', array('enrolid'=>$instance->id)); + + if ($canconfig) { + // up/down link + $updown = ''; + if ($updowncount > 1) { + $aurl = new moodle_url($url, array('action'=>'up', 'instance'=>$instance->id)); + $updown .= "pix_url('t/up') . "\" alt=\"$strup\" /> "; + } else { + $updown .= "pix_url('spacer.gif') . "\" class=\"icon\" alt=\"\" /> "; + } + if ($updowncount < $icount) { + $aurl = new moodle_url($url, array('action'=>'down', 'instance'=>$instance->id)); + $updown .= "pix_url('t/down') . "\" alt=\"$strdown\" />"; + } else { + $updown .= "pix_url('spacer.gif') . "\" class=\"icon\" alt=\"\" />"; + } + ++$updowncount; + + // edit links + $aurl = new moodle_url($url, array('action'=>'delete', 'instance'=>$instance->id)); + $edit = "pix_url('t/delete') . "\" alt=\"$strdelete\" /> "; + + if (enrol_is_enabled($instance->enrol)) { + if ($instance->status == ENROL_STATUS_ENABLED) { + $aurl = new moodle_url($url, array('action'=>'disable', 'instance'=>$instance->id)); + $edit .= "pix_url('t/show') . "\" alt=\"$strdisable\" /> "; + } else if ($instance->status == ENROL_STATUS_DISABLED) { + $aurl = new moodle_url($url, array('action'=>'enable', 'instance'=>$instance->id)); + $edit .= "pix_url('t/hide') . "\" alt=\"$strenable\" /> "; + } else { + // plugin specific state - do not mess with it! + $edit .= "pix_url('t/hide') . "\" alt=\"\" />"; + } + + } + + // add a row to the table + $table->data[] = array($displayname, $users, $updown, $edit); + + } else { + // add a row to the table + $table->data[] = array($displayname, $users); + } + +} +echo html_writer::table($table); + +if ($canconfig) { + if ($candidates = enrol_get_instance_candidates($course->id)) { + $addurl = new moodle_url('/enrol/review.php', array('id'=>$course->id, 'action'=>'add', 'sesskey'=>sesskey())); + $select = new single_select($addurl, 'add', $candidates); + $select->set_label(get_string('addinstance', 'enrol')); + echo $OUTPUT->render($select); + } +} + +echo $OUTPUT->box_end(); + +echo $OUTPUT->footer(); Index: lib/externallib.php =================================================================== --- lib/externallib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/externallib.php (revision ) @@ -307,28 +307,10 @@ if ($context->contextlevel >= CONTEXT_COURSE) { list($context, $course, $cm) = get_context_info_array($context->id); - // must be enrolled or viewing - if (!is_enrolled($context) and !is_viewing($context)) { - throw new invalid_parameter_exception('Must be enrolled in course or be allowed to inspect it.'); + require_login($course, false, $cm, false, true); - } + } - // make sure the course is actually visible - if (!($course->visible && course_parent_visible($COURSE)) && !has_capability('moodle/course:viewhiddencourses', get_context_instance(CONTEXT_COURSE, $course->id))) { - throw new invalid_parameter_exception('Invalid course.'); - } + } - // make sure the activity is actually visible - if ($cm && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_MODULE, $cm->id))) { - throw new invalid_parameter_exception('Invalid activity.'); - } +} - // verify group memebers - if (!empty($CFG->enablegroupmembersonly) and $cm and $cm->groupmembersonly and !has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id))) { - if (!groups_has_membership($cm)) { - throw new invalid_parameter_exception('Must be member of at least one group.'); - } - } - //TODO: verify course completion - } - } -} /** * Common ancestor of all parameter description classes @@ -468,7 +450,7 @@ return $newtoken->token; } /** - * Create and return a session linked token. Token to be used for html embedded client apps that want to communicate + * Create and return a session linked token. Token to be used for html embedded client apps that want to communicate * with the Moodle server through web services. The token is linked to the current session for the current page request. * It is expected this will be called in the script generating the html page that is embedding the client app and that the * returned token will be somehow passed into the client app being embedded in the page. Index: enrol/manual/enrol.html =================================================================== --- enrol/manual/enrol.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/manual/enrol.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,47 +0,0 @@ -password != '' and !(isguestuser() and !empty($USER->enrolkey[$course->id]))) { // password - echo $OUTPUT->box_start('generalbox centerpara'); - echo '

'; - - $this->print_enrolmentkeyfrom( $course ); - ?> -

- -

errormsg)) {echo $OUTPUT->error_text($this->errormsg);} ?>

- - -
-
- - - - -
: - - - - - " /> -
- -
- -
-
- " /> -
-
- -box_end(); - } - - - if (isguestuser()) { - echo $OUTPUT->box_start('centerpara'); - $loginurl = get_login_url(); - echo $OUTPUT->single_button($loginurl, get_string('login')); - echo $OUTPUT->box_end(); - } -?> Index: admin/user/user_bulk_enrol.php =================================================================== --- admin/user/user_bulk_enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/user/user_bulk_enrol.php (revision ) @@ -84,19 +84,15 @@ $ids = explode(',', $info); if(!empty($ids[2])) { $context = get_context_instance(CONTEXT_COURSE, $ids[1]); - if( role_assign(5, $ids[0], 0, $context->id) ) { - continue; - } + role_assign(5, $ids[0], $context->id); } else { if( empty($ids[1] ) ) { continue; } $context = get_context_instance(CONTEXT_COURSE, $ids[1]); - if( role_unassign(5, $ids[0], 0, $context->id) ) { - continue; + role_unassign(5, $ids[0], $context->id); - } - } + } + } - } redirect($return, get_string('changessaved')); } @@ -104,14 +100,12 @@ echo '
'; echo ''; $count = 0; -foreach($users as $user) -{ +foreach($users as $user) { $temparray = array ( ''.$user->fullname.'' ); - $mycourses = get_my_courses($user->id); - foreach($courses as $acourse) - { + $mycourses = enrol_get_users_courses($user->id, false); + foreach($courses as $acourse) { $state = ''; if (isset($mycourses[$acourse->id])) { $state = 'checked="checked"'; Index: enrol/externallib.php =================================================================== --- enrol/externallib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/externallib.php (revision ) @@ -25,134 +25,3 @@ */ require_once("$CFG->libdir/externallib.php"); - -class moodle_enrol_external extends external_api { - - /** - * Returns description of method parameters - * @return external_function_parameters - */ - public static function role_assign_parameters() { - global $CFG; - - return new external_function_parameters( - array( - 'enrolments' => new external_multiple_structure( - new external_single_structure( - array( - 'roleid' => new external_value(PARAM_RAW, 'Role to assign to the user'), - 'userid' => new external_value(PARAM_RAW, 'The user that is going to be assigned'), - 'contextid' => new external_value(PARAM_NOTAGS, 'The context to assign the user into '), - 'timestart' => new external_value(PARAM_EMAIL, 'A valid and unique email address', VALUE_DEFAULT, 0, NULL_NOT_ALLOWED), - 'timeend' => new external_value(PARAM_SAFEDIR, 'Auth plugins include manual, ldap, imap, etc', VALUE_DEFAULT, 0, NULL_NOT_ALLOWED) - ) - ) - ) - ) - ); - } - - /** - * Assign roles to users - * - * @param array $enrolment An array of enrolment - * @return null - */ - public static function role_assign($enrolments) { - global $CFG, $DB; - - // Do basic automatic PARAM checks on incoming data, using params description - // If any problems are found then exceptions are thrown with helpful error messages - $params = self::validate_parameters(self::role_assign_parameters(), array('enrolments'=>$enrolments)); - - $transaction = $DB->start_delegated_transaction(); - - $success = true; - - foreach ($params['enrolments'] as $enrolment) { - // Ensure the current user is allowed to run this function in the enrolment context - $context = get_context_instance_by_id($enrolment['contextid']); - self::validate_context($context); - require_capability('moodle/role:assign', $context); - - if(!role_assign($enrolment['roleid'], $enrolment['userid'], null, $enrolment['contextid'], $enrolment['timestart'], $enrolment['timeend'])) { - $success = false; - } - } - - $transaction->allow_commit(); - - return $success; - } - - /** - * Returns description of method result value - * @return external_description - */ - public static function role_assign_returns() { - return new external_value(PARAM_BOOL, 'If all assignement succeed returns true'); - } - - - /** - * Returns description of method parameters - * @return external_function_parameters - */ - public static function role_unassign_parameters() { - return new external_function_parameters( - array( - 'unenrolments' => new external_multiple_structure( - new external_single_structure( - array( - 'roleid' => new external_value(PARAM_RAW, 'Role to assign to the user'), - 'userid' => new external_value(PARAM_RAW, 'The user that is going to be assigned'), - 'contextid' => new external_value(PARAM_NOTAGS, 'The context to assign the user into '), - ) - ) - ) - ) - ); - } - - /** - * Unassign roles to users - * - * @param array $unenrolment An array of unenrolment - * @return null - */ - public static function role_unassign($unenrolments) { - global $CFG, $DB; - - // Do basic automatic PARAM checks on incoming data, using params description - // If any problems are found then exceptions are thrown with helpful error messages - $params = self::validate_parameters(self::role_unassign_parameters(), array('unenrolments'=>$unenrolments)); - - $transaction = $DB->start_delegated_transaction(); - - $success = true; - - foreach ($params['unenrolments'] as $unenrolment) { - // Ensure the current user is allowed to run this function in the unenrolment context - $context = get_context_instance_by_id($unenrolment['contextid']); - self::validate_context($context); - require_capability('moodle/role:assign', $context); - - if (!role_unassign($unenrolment['roleid'], $unenrolment['userid'], null, $unenrolment['contextid'])) { - $success = false; - } - } - - $transaction->allow_commit(); - - return $success; - } - - /** - * Returns description of method result value - * @return external_description - */ - public static function role_unassign_returns() { - return new external_value(PARAM_BOOL, 'If all unassignement succeed returns true'); - } - -} Index: enrol/paypal/ipn.php =================================================================== --- enrol/paypal/ipn.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/paypal/ipn.php (revision ) @@ -93,7 +93,7 @@ // and notify admin if ($data->payment_status != "Completed" and $data->payment_status != "Pending") { - role_unassign(0, $data->userid, 0, $context->id); + role_unassign_all(array('userid'=>$data->userid, 'contextid'=>$context->id, 'component'=>'enrol_paypal'), true, true); message_paypal_error_to_admin("Status not completed or pending. User unenrolled from course", $data); die; } Index: admin/roles/lib.php =================================================================== --- admin/roles/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/roles/lib.php (revision ) @@ -1020,56 +1020,27 @@ * when we are assigning in a context below the course level. (CONTEXT_MODULE and * some CONTEXT_BLOCK). * - * In this case we replicate part of get_users_by_capability() get the users - * with moodle/course:participate. We can't use - * get_users_by_capability() becuase - * 1) get_users_by_capability() does not deal with searching by name - * 2) exceptions array can be potentially large for large courses + * This returns only enrolled users in this context. */ class potential_assignees_below_course extends role_assign_user_selector_base { public function find_users($search) { global $DB; - // Get roles with some assignement to the 'moodle/course:participate' capability. - $possibleroles = get_roles_with_capability('moodle/course:participate', CAP_ALLOW, $this->context); - if (empty($possibleroles)) { - // If there aren't any, we are done. - return array(); - } + list($enrolsql, $eparams) = get_enrolled_sql($this->context); - // Now exclude the admin roles, and check the actual permission on - // 'moodle/course:participate' to make sure it is allow. - $validroleids = array(); - - foreach ($possibleroles as $possiblerole) { - if ($caps = role_context_capabilities($possiblerole->id, $this->context, 'moodle/course:participate')) { // resolved list - if (isset($caps['moodle/course:participate']) && $caps['moodle/course:participate'] > 0) { // resolved capability > 0 - $validroleids[] = $possiblerole->id; - } - } - } - - // If there are no valid roles, we are done. - if (!$validroleids) { - return array(); - } - // Now we have to go to the database. list($wherecondition, $params) = $this->search_sql($search, 'u'); + $params = array_merge($params, $eparams); + if ($wherecondition) { $wherecondition = ' AND ' . $wherecondition; } - $roleids = '('.implode(',', $validroleids).')'; - $fields = 'SELECT DISTINCT ' . $this->required_fields_sql('u'); - $countfields = 'SELECT COUNT(DISTINCT u.id)'; + $fields = 'SELECT ' . $this->required_fields_sql('u'); + $countfields = 'SELECT COUNT(u.id)'; $sql = " FROM {user} u - JOIN {role_assignments} ra ON ra.userid = u.id - JOIN {role} r ON r.id = ra.roleid - WHERE ra.contextid " . get_related_contexts_string($this->context)." - $wherecondition - AND ra.roleid IN $roleids + WHERE u.id IN ($enrolsql) $wherecondition AND u.id NOT IN ( SELECT u.id FROM {role_assignments} r, {user} u @@ -1465,8 +1436,9 @@ } protected function load_required_roles() { + global $DB; parent::load_required_roles(); - $this->allowedtargetroles = get_allowed_switchable_roles(); + $this->allowedtargetroles = $DB->get_records_menu('roles', NULL, 'id', 'roleid, 1'); } protected function set_allow($fromroleid, $targetroleid) { Index: lib/db/upgrade.php =================================================================== --- lib/db/upgrade.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/db/upgrade.php (revision ) @@ -2984,7 +2984,7 @@ upgrade_main_savepoint($result, 2010031900); } - + if ($result && $oldversion < 2010032400) { // Upgrade all of those using the standardold theme to the use the standard // theme instead @@ -3386,7 +3386,7 @@ } } // remove all roles of the guest account - the only way to change it is to override the guest role, sorry - // the guest account gets all the role assignemnts on the fly whcih works fine in has_capability(), + // the guest account gets all the role assignments on the fly whcih works fine in has_capability(), $DB->delete_records_select('role_assignments', "userid IN (SELECT id FROM {user} WHERE username = 'guest')"); upgrade_main_savepoint($result, 2010033102.08); @@ -3644,7 +3644,6 @@ upgrade_main_savepoint($result, 2010042800); } - if ($result && $oldversion < 2010042801) { // migrating old comments block content $DB->execute(" @@ -3697,7 +3696,6 @@ upgrade_main_savepoint($result, 2010042802); } - if ($result && $oldversion < 2010043000) { // Adding new course completion feature /// Add course completion tables @@ -3927,7 +3925,537 @@ upgrade_main_savepoint($result, 2010050200); } + if ($result && $oldversion < 2010050300.03) { + // Define table enrol to be created + $table = new xmldb_table('enrol'); + // Adding fields to table enrol + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); + $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null); + $table->add_field('enrol', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null); + $table->add_field('status', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); + $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('enrolperiod', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, '0'); + $table->add_field('enrolstartdate', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, '0'); + $table->add_field('enrolenddate', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, '0'); + $table->add_field('expirynotify', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, '0'); + $table->add_field('expirythreshold', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, '0'); + $table->add_field('notifyall', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, '0'); + $table->add_field('password', XMLDB_TYPE_CHAR, '50', null, null, null, null); + $table->add_field('cost', XMLDB_TYPE_CHAR, '20', null, null, null, null); + $table->add_field('currency', XMLDB_TYPE_CHAR, '3', null, null, null, null); + $table->add_field('defaultrole', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, '0'); + $table->add_field('customint1', XMLDB_TYPE_INTEGER, '10', null, null, null, null); + $table->add_field('customint2', XMLDB_TYPE_INTEGER, '10', null, null, null, null); + $table->add_field('customint3', XMLDB_TYPE_INTEGER, '10', null, null, null, null); + $table->add_field('customint4', XMLDB_TYPE_INTEGER, '10', null, null, null, null); + $table->add_field('customchar1', XMLDB_TYPE_CHAR, '255', null, null, null, null); + $table->add_field('customchar2', XMLDB_TYPE_CHAR, '255', null, null, null, null); + $table->add_field('customdec1', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null); + $table->add_field('customdec2', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null); + $table->add_field('customtext1', XMLDB_TYPE_TEXT, 'big', null, null, null, null); + $table->add_field('customtext2', XMLDB_TYPE_TEXT, 'big', null, null, null, null); + $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + + // Adding keys to table enrol + $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); + $table->add_key('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id')); + + // Adding indexes to table enrol + $table->add_index('enrol', XMLDB_INDEX_NOTUNIQUE, array('enrol')); + + // Conditionally launch create table for enrol + if (!$dbman->table_exists($table)) { + $dbman->create_table($table); + } + + // Main savepoint reached + upgrade_main_savepoint($result, 2010050300.03); + } + + if ($result && $oldversion < 2010050300.04) { + // Define table course_participant to be created + $table = new xmldb_table('course_participants'); + + // Adding fields to table course_participant + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); + $table->add_field('status', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('enrolid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); + $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); + $table->add_field('timestart', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('timeend', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2147483647'); + $table->add_field('modifierid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + + // Adding keys to table course_participant + $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); + $table->add_key('enrolid', XMLDB_KEY_FOREIGN, array('enrolid'), 'enrol', array('id')); + $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id')); + $table->add_key('modifierid', XMLDB_KEY_FOREIGN, array('modifierid'), 'user', array('id')); + + // Conditionally launch create table for course_participant + if (!$dbman->table_exists($table)) { + $dbman->create_table($table); + } + + // Main savepoint reached + upgrade_main_savepoint($result, 2010050300.04); + } + + if ($result && $oldversion < 2010050300.05) { + // Define field enrolid to be added to role_assignments + $table = new xmldb_table('role_assignments'); + $field = new xmldb_field('enrolid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, 'enrol'); + + // Conditionally launch add field enrolid + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // The new enrol plugins may assign one role several times in one context, + // if we did not allow it we would have big problems with roles when unenrolling + $table = new xmldb_table('role_assignments'); + $index = new xmldb_index('contextid-roleid-userid', XMLDB_INDEX_UNIQUE, array('contextid', 'roleid', 'userid')); + + // Conditionally launch drop index contextid-roleid-userid + if ($dbman->index_exists($table, $index)) { + $dbman->drop_index($table, $index); + } + + // Define key enrolid (foreign) to be added to role_assignments + $table = new xmldb_table('role_assignments'); + $key = new xmldb_key('enrolid', XMLDB_KEY_FOREIGN, array('enrolid'), 'enrol', array('id')); + + // Launch add key enrolid + $dbman->add_key($table, $key); + + // Main savepoint reached + upgrade_main_savepoint($result, 2010050300.05); + } + + if ($result && $oldversion < 2010050300.06) { + $sqlempty = $DB->sql_empty(); + + // first of all set course->enrol to default value so that other ugprade code is simpler + $defaultenrol = empty($CFG->enrol) ? 'manual' : $CFG->enrol; + $sql = "UPDATE {course} SET enrol = ? WHERE enrol = '$sqlempty'"; + $DB->execute($sql, array($defaultenrol)); + + $params = array('siteid'=>SITEID); + // enable manual in all courses + $sql = "INSERT INTO {enrol} (enrol, status, courseid, sortorder, enrolperiod, expirynotify, expirythreshold, notifyall, defaultrole, timecreated, timemodified) + SELECT 'manual', 0, id, 0, enrolperiod, expirynotify, expirythreshold, notifystudents, defaultrole, timecreated, timemodified + FROM {course} + WHERE id <> :siteid"; + $DB->execute($sql, $params); + + // enable self enrol only when course enrollable + $sql = "INSERT INTO {enrol} (enrol, status, courseid, sortorder, enrolperiod, enrolstartdate, enrolenddate, expirynotify, expirythreshold, + notifyall, password, defaultrole, timecreated, timemodified) + SELECT 'self', 0, id, 1, enrolperiod, enrolstartdate, enrolenddate, expirynotify, expirythreshold, + notifystudents, password, defaultrole, timecreated, timemodified + FROM {course} + WHERE enrollable = 1 AND id <> :siteid"; + $DB->execute($sql, $params); + + // enable guest access if previously allowed - either with or without password + $sql = "INSERT INTO {enrol} (enrol, status, courseid, sortorder, timecreated, timemodified) + SELECT 'guest', 0, id, 2, timecreated, timemodified + FROM {course} + WHERE guest = 1 AND id <> :siteid"; + $DB->execute($sql, $params); + $sql = "INSERT INTO {enrol} (enrol, status, courseid, sortorder, password, timecreated, timemodified) + SELECT 'guest', 0, id, 2, password, timecreated, timemodified + FROM {course} + WHERE guest = 2 and password <> '$sqlempty' AND id <> :siteid"; + $DB->execute($sql, $params); + + upgrade_main_savepoint($result, 2010050300.06); + } + + if ($result && $oldversion < 2010050300.07) { + // now migrate old style "interactive" enrol plugins + $params = array('siteid'=>SITEID); + $enabledplugins = explode(',', $CFG->enrol_plugins_enabled); + $usedplugins = $DB->get_fieldset_sql("SELECT DISTINCT enrol FROM {course}"); + foreach ($usedplugins as $plugin) { + if ($plugin === 'manual') { + continue; + } + $enabled = in_array($plugin, $enabledplugins) ? 0 : 1; // 0 means active, 1 disabled + $sql = "INSERT INTO {enrol} (enrol, status, courseid, sortorder, enrolperiod, enrolstartdate, enrolenddate, expirynotify, expirythreshold, + notifyall, password, cost, currency, defaultrole, timecreated, timemodified) + SELECT enrol, $enabled, id, 3, enrolperiod, enrolstartdate, enrolenddate, expirynotify, expirythreshold, + notifystudents, password, cost, currency, defaultrole, timecreated, timemodified + FROM {course} + WHERE enrol = :plugin AND id <> :siteid"; + $params['plugin'] = $plugin; + $DB->execute($sql, $params); + } + upgrade_main_savepoint($result, 2010050300.07); + } + + if ($result && $oldversion < 2010050300.08) { + // now migrate the rest + + // enabled + $processed = $DB->get_fieldset_sql("SELECT DISTINCT enrol FROM {enrol}"); + $enabledplugins = explode(',', $CFG->enrol_plugins_enabled); + list($sqlnotprocessed, $params) = $DB->get_in_or_equal($processed, SQL_PARAMS_NAMED, 'np00', false); + list($sqlenabled, $params2) = $DB->get_in_or_equal($enabledplugins, SQL_PARAMS_NAMED, 'ena00'); + $params = array_merge($params, $params2); + $params['siteid'] = SITEID; + $sql = "INSERT INTO {enrol} (enrol, status, courseid, sortorder, enrolperiod, enrolstartdate, enrolenddate, expirynotify, expirythreshold, + notifyall, password, cost, currency, defaultrole, timecreated, timemodified) + SELECT DISTINCT ra.enrol, 0, c.id, 4, c.enrolperiod, c.enrolstartdate, c.enrolenddate, c.expirynotify, c.expirythreshold, + c.notifystudents, c.password, c.cost, c.currency, c.defaultrole, c.timecreated, c.timemodified + FROM {course} c + JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = 50) + JOIN {role_assignments} ra ON (ra.contextid = ctx.id) + WHERE c.id <> :siteid AND ra.enrol $sqlnotprocessed AND ra.enrol $sqlenabled"; + $DB->execute($sql, $params); + + // disabled + $processed = $DB->get_fieldset_sql("SELECT DISTINCT enrol FROM {enrol}"); + list($sqlnotprocessed, $params) = $DB->get_in_or_equal($processed, SQL_PARAMS_NAMED, 'np00', false); + $params = array_merge($params, $params2); + $params['siteid'] = SITEID; + $sql = "INSERT INTO {enrol} (enrol, status, courseid, sortorder, enrolperiod, enrolstartdate, enrolenddate, expirynotify, expirythreshold, + notifyall, password, cost, currency, defaultrole, timecreated, timemodified) + SELECT DISTINCT ra.enrol, 1, c.id, 4, c.enrolperiod, c.enrolstartdate, c.enrolenddate, c.expirynotify, c.expirythreshold, + c.notifystudents, c.password, c.cost, c.currency, c.defaultrole, c.timecreated, c.timemodified + FROM {course} c + JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = 50) + JOIN {role_assignments} ra ON (ra.contextid = ctx.id) + WHERE c.id <> :siteid AND ra.enrol $sqlnotprocessed"; + $DB->execute($sql, $params); + + + upgrade_main_savepoint($result, 2010050300.08); + } + + if ($result && $oldversion < 2010050300.09) { + // unfortunately there may be still some leftovers + // after reconfigured, uninstalled or borked enrol plugins, + // unfortunately this may be a bit slow - but there should not be many of these + $sql = "SELECT DISTINCT c.id AS courseid, ra.enrol, e.timecreated, c.timemodified + FROM {course} c + JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = 50) + JOIN {role_assignments} ra ON (ra.contextid = ctx.id) + LEFT JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = ra.enrol) + WHERE c.id <> :siteid AND e.id IS NULL"; + $params = array('siteid'=>SITEID); + $enrols = $DB->get_recordset_sql($sql, $params); + foreach ($enrols as $enrol) { + $enrol->status = 1; // better disable them + $DB->inert_record('enrol', $enrol); + } + $enrols->close(); + upgrade_main_savepoint($result, 2010050300.09); + } + + if ($result && $oldversion < 2010050300.10) { + // migrate existing setup of meta courses + $sql = "INSERT INTO {enrol} (enrol, status, courseid, sortorder, customint1) + SELECT 'meta', 0, child_course, 5, parent_course + FROM {course_meta}"; + $DB->execute($sql); + + upgrade_main_savepoint($result, 2010050300.10); + } + + if ($result && $oldversion < 2010050300.11) { + // course_meta to be dropped - we use enrol_meta plugin instead now + $table = new xmldb_table('course_meta'); + + // Conditionally launch drop table for course_meta + if ($dbman->table_exists($table)) { + $dbman->drop_table($table); + } + + // Main savepoint reached + upgrade_main_savepoint($result, 2010050300.11); + } + + if ($result && $oldversion < 2010050300.12) { + // finally remove all obsolete fields from the course table - yay! + // all the information was migrated to the enrol table + + // Define field guest to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('guest'); + + // Conditionally launch drop field guest + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field enrolperiod to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('enrolperiod'); + + // Conditionally launch drop field enrolperiod + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field cost to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('cost'); + + // Conditionally launch drop field cost + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field currency to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('currency'); + + // Conditionally launch drop field currency + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field metacourse to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('metacourse'); + + // Conditionally launch drop field metacourse + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field expirynotify to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('expirynotify'); + + // Conditionally launch drop field expirynotify + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field expirythreshold to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('expirythreshold'); + + // Conditionally launch drop field expirythreshold + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field notifystudents to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('notifystudents'); + + // Conditionally launch drop field notifystudents + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field enrollable to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('enrollable'); + + // Conditionally launch drop field enrollable + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field enrolstartdate to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('enrolstartdate'); + + // Conditionally launch drop field enrolstartdate + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field enrolenddate to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('enrolenddate'); + + // Conditionally launch drop field enrolenddate + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field enrol to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('enrol'); + + // Conditionally launch drop field enrol + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field defaultrole to be dropped from course + $table = new xmldb_table('course'); + $field = new xmldb_field('defaultrole'); + + // Conditionally launch drop field defaultrole + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + upgrade_main_savepoint($result, 2010050300.12); + } + + if ($result && $oldversion < 2010050300.20) { + // now set up the enrolments - look for roles with course:participate only at course context - the category enrolments will be converted by cohort plugin later + + $syscontext = get_context_instance(CONTEXT_SYSTEM); + $params = array('syscontext'=>$syscontext->id, 'participate'=>'moodle/course:participate'); + $roles = $DB->get_fieldset_sql("SELECT DISTINCT roleid FROM {role_capabilities} WHERE contextid = :syscontext AND capability = :participate AND permission = 1", $params); + list($sqlroles, $params) = $DB->get_in_or_equal($roles, SQL_PARAMS_NAMED, 'r00'); + + $sql = "INSERT INTO {course_participants} (status, enrolid, userid, timestart, timeend, modifierid, timemodified) + SELECT 0, e.id, ra.userid, ra.timestart, ra.timeend, ra.modifierid, ra.timemodified + FROM {role_assignments} ra + JOIN {context} c ON (c.id = ra.contextid AND c.contextlevel = 50) + JOIN {enrol} e ON (e.enrol = ra.enrol AND e.courseid = c.instanceid) + JOIN {user} u ON u.id = ra.userid + WHERE u.deleted = 0 AND ra.roleid $sqlroles"; + $DB->execute($sql, $params); + + upgrade_main_savepoint($result, 2010050300.20); + } + + if ($result && $oldversion < 2010050300.21) { + // hidden is completely removed, timestart+timeend are now in the course_participants table + + // Define field hidden to be dropped from role_assignments + $table = new xmldb_table('role_assignments'); + $field = new xmldb_field('hidden'); + + // Conditionally launch drop field hidden + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field timestart to be dropped from role_assignments + $table = new xmldb_table('role_assignments'); + $field = new xmldb_field('timestart'); + + // Conditionally launch drop field timestart + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Define field timeend to be dropped from role_assignments + $table = new xmldb_table('role_assignments'); + $field = new xmldb_field('timeend'); + + // Conditionally launch drop field timeend + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Main savepoint reached + upgrade_main_savepoint($result, 2010050300.21); + } + + if ($result && $oldversion < 2010050300.22) { + // Rename field enrol on table role_assignments to component and update content + + $table = new xmldb_table('role_assignments'); + $field = new xmldb_field('enrol', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, 'modifierid'); + + // Launch rename field enrol + $dbman->rename_field($table, $field, 'component'); + + // Changing precision of field component on table role_assignments to (100) + $table = new xmldb_table('role_assignments'); + $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'modifierid'); + + // Launch change of precision for field component + $dbman->change_field_precision($table, $field); + + // Manual is a special case - we use empty string instead now + $params = array('empty'=>$DB->sql_empty(), 'manual'=>'manual'); + $sql = "UPDATE {role_assignments} + SET component = :empty + WHERE component = :manual"; + $DB->execute($sql, $params); + + // Now migrate to real enrol component names + $params = array('empty'=>$DB->sql_empty()); + $concat = $DB->sql_concat("'enrol_'", 'component'); + $sql = "UPDATE {role_assignments} + SET component = $concat + WHERE component <> :empty + AND contextid IN ( + SELECT id + FROM {context} + WHERE contextlevel >= 50)"; + $DB->execute($sql, $params); + + // Now migrate to real auth component names + $params = array('empty'=>$DB->sql_empty()); + $concat = $DB->sql_concat("'auth_'", 'component'); + $sql = "UPDATE {role_assignments} + SET component = $concat + WHERE component <> :empty + AND contextid IN ( + SELECT id + FROM {context} + WHERE contextlevel < 50)"; + $DB->execute($sql, $params); + + // Main savepoint reached + upgrade_main_savepoint($result, 2010050300.22); + } + + if ($result && $oldversion < 2010050300.31) { + // finalize all new enrol settings and cleanup old settings + + // legacy allowunenrol was deprecated in 1.9 already + unset_config('allwunenroll'); + + // make new list of active enrol plugins - order is important, meta should be always last, manual first + $enabledplugins = explode(',', $CFG->enrol_plugins_enabled); + $enabledplugins = array_merge(array('manual', 'guest', 'self', 'cohort'), $enabledplugins); + if ($DB->record_exists('enrol', array('enrol'=>'meta'))) { + $enabledplugins[] = 'meta'; + } + set_config('enrol_plugins_enabled', implode(',', $enabledplugins)); + + // add new $CFG->enrol_plugins_default + $default = 'manual,guest,self,cohort'; // order is not important + if (!empty($CFG->enrol) and $CFG->enrol !== 'manual') { + $default .= ','.$CFG->enrol; + } + set_config('enrol_plugins_default', $default); + + // obsolete course presets + unset_config('metacourse', 'moodlecourse'); + unset_config('enrol', 'moodlecourse'); + unset_config('enrollable', 'moodlecourse'); + unset_config('enrolperiod', 'moodlecourse'); + unset_config('expirynotify', 'moodlecourse'); + unset_config('notifystudents', 'moodlecourse'); + unset_config('expirythreshold', 'moodlecourse'); + unset_config('enrolpassword', 'moodlecourse'); + unset_config('guest', 'moodlecourse'); + + unset_config('backup_sche_metacourse', 'backup'); + + unset_config('lastexpirynotify'); + + // hidden course categories now prevetn only browsing + unset_config('allowvisiblecoursesinhiddencategories'); + + if (isset($CFG->coursemanager)) { + set_config('coursecontact', $CFG->coursemanager); + unset_config('coursemanager'); + } + + upgrade_main_savepoint($result, 2010050300.31); + } + + return $result; } Index: backup/restore_form.html =================================================================== --- backup/restore_form.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ backup/restore_form.html (revision ) @@ -77,11 +77,6 @@ } } - //Check other parameters - if (!isset($restore_metacourse)) { - $restore_metacourse = 1; - } - if (!isset($restore_users)) { $restore_users = 1; } @@ -201,15 +196,9 @@ // permission should have been checked already - // Non-cached - get accessinfo - if (isset($USER->access)) { - $accessinfo = $USER->access; - } else { - $accessinfo = get_user_access_sitewide($USER->id); - } + //TODO: use better function which includes all courses for admins + $mycourses = get_user_courses_bycap($USER->id, 'moodle/restore:restorecourse'); - $mycourses = get_user_courses_bycap($USER->id, 'moodle/restore:restorecourse', $accessinfo, true); - // if the user can restore to current course, grant the "current" options if (has_capability('moodle/restore:restorecourse', get_context_instance(CONTEXT_COURSE, $id))){ $restore_restoreto_options[RESTORETO_CURRENT_DELETING] = get_string("currentcoursedeleting"); @@ -418,22 +407,6 @@ //Line echo "$nonrestmod
"; - //Now print the Metacourse tr - echo ""; - echo ""; - echo ''; - echo ""; - //If metacourse are in the backup file, show menu, else fixed to no - if ($info->backup_metacourse == "true") { - $metacourse_options = array(); - $metacourse_options[0] = get_string("no"); - $metacourse_options[1] = get_string("yes"); - echo html_writer::select($metacourse_options, "restore_metacourse", $restore_metacourse, false); - } else { - echo get_string("no"); - echo ""; - } - echo ""; //Now print the Users tr echo ""; echo ""; Index: course/enrol.php =================================================================== --- course/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/enrol.php (revision ) @@ -16,118 +16,15 @@ // along with Moodle. If not, see . /** - * Depending on the current enrolment method, this page - * presents the user with whatever they need to know when - * they try to enrol in a course. + * Redirection of old enrol entry point. * * @copyright 1999 Martin Dougiamas http://dougiamas.com * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @package course */ -require_once("../config.php"); -require_once("lib.php"); -require_once("$CFG->dirroot/enrol/enrol.class.php"); +require('../config.php'); -$id = required_param('id', PARAM_INT); +$id = required_param('id', PARAM_INT); -$loginasguest = optional_param('loginasguest', 0, PARAM_BOOL); // hmm, is this still needed? -$url = new moodle_url('/course/enrol.php', array('id'=>$id)); -if ($loginasguest !== 0) { - $url->param('loginasguest', $loginasguest); -} -$PAGE->set_url($url); - -if (!isloggedin() or isguestuser()) { - // do not use require_login here because we are usually comming from it - redirect(get_login_url()); -} - -if (!$course = $DB->get_record('course', array('id'=>$id))) { - print_error("That's an invalid course id"); -} - -if (! $context = get_context_instance(CONTEXT_COURSE, $course->id) ) { - print_error("That's an invalid course id"); -} - -/// do not use when in course login as -if (session_is_loggedinas() and $USER->loginascontext->contextlevel == CONTEXT_COURSE) { - print_error('loginasnoenrol', '', $CFG->wwwroot.'/course/view.php?id='.$USER->loginascontext->instanceid); -} - -$enrol = enrolment_factory::factory($course->enrol); // do not use if (!$enrol... here, it can not work in PHP4 - see MDL-7529 - -/// Refreshing all current role assignments for the current user - -load_all_capabilities(); - -/// Double check just in case they are actually enrolled already and -/// thus got to this script by mistake. This might occur if enrolments -/// changed during this session or something - -if (has_capability('moodle/course:participate', $context)) { - if (!empty($SESSION->wantsurl)) { - $destination = $SESSION->wantsurl; - unset($SESSION->wantsurl); - } else { - $destination = "$CFG->wwwroot/course/view.php?id=$course->id"; - } - redirect($destination); // Bye! -} - -/// Check if the course is a meta course (bug 5734) -if ($course->metacourse) { - echo $OUTPUT->header(); - notice(get_string('coursenotaccessible'), "$CFG->wwwroot/index.php"); -} - -/// Users can't enroll to site course -if ($course->id == SITEID) { - echo $OUTPUT->header(); - notice(get_string('enrollfirst'), "$CFG->wwwroot/index.php"); -} - -/// Double check just in case they are enrolled to start in the future - -if ($course->enrolperiod) { // Only active if the course has an enrolment period in effect - if ($roles = get_user_roles($context, $USER->id)) { - foreach ($roles as $role) { - if ($role->timestart and ($role->timestart >= time())) { - $message = get_string('enrolmentnotyet', '', userdate($student->timestart)); - echo $OUTPUT->header(); - notice($message, "$CFG->wwwroot/index.php"); - } - } - } -} - -/// Check if the course is enrollable -if (!method_exists($enrol, 'print_entry')) { - echo $OUTPUT->header(); - notice(get_string('enrolmentnointernal'), "$CFG->wwwroot/index.php"); -} - -if (!$course->enrollable || - ($course->enrollable == 2 && $course->enrolstartdate > 0 && $course->enrolstartdate > time()) || - ($course->enrollable == 2 && $course->enrolenddate > 0 && $course->enrolenddate <= time()) - ) { - $PAGE->set_title($course->shortname); - $PAGE->set_heading($course->fullname); - $PAGE->navbar->add($course->shortname); - echo $OUTPUT->header(); - notice(get_string('notenrollable'), "$CFG->wwwroot/index.php"); -} - -/// Check the submitted enrolment information if there is any (eg could be enrolment key) - -if ($form = data_submitted()) { - $enrol->check_entry($form, $course); // Should terminate/redirect in here if it's all OK -} - -/// Otherwise, we print the entry form. - -$enrol->print_entry($course); - -/// Easy! - +redirect(new moodle_url('/enrol/index.php', array('id'=>$id))); Index: group/lib.php =================================================================== --- group/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ group/lib.php (revision ) @@ -481,32 +481,14 @@ /** * Obtains a list of the possible roles that group members might come from, - * on a course. Generally this includes all the roles who would have - * course:view on that course, except the doanything roles. + * on a course. Generally this includes only profile roles. * @param object $context Context of course * @return Array of role ID integers, or false if error/none. */ function groups_get_possible_roles($context) { - $capability = 'moodle/course:participate'; - - // find all possible "student" roles - if ($possibleroles = get_roles_with_capability($capability, CAP_ALLOW, $context)) { - $validroleids = array(); - foreach ($possibleroles as $possiblerole) { - if ($caps = role_context_capabilities($possiblerole->id, $context, $capability)) { // resolved list - if (isset($caps[$capability]) && $caps[$capability] > 0) { // resolved capability > 0 - $validroleids[] = $possiblerole->id; + $roles = get_profile_roles($context); + return array_keys($roles); - } +} - } - } - if (empty($validroleids)) { - return false; - } - return $validroleids; - } else { - return false; // No need to continue, since no roles have this capability set - } -} /** Index: lang/en/help/courseenrolmentplugins.html =================================================================== --- lang/en/help/courseenrolmentplugins.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lang/en/help/courseenrolmentplugins.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,1 +0,0 @@ -

Choose default interactive enrolment plugin used in this course

Index: admin/mnet/enr_courses.php =================================================================== --- admin/mnet/enr_courses.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/mnet/enr_courses.php (revision ) @@ -13,8 +13,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)); Index: version.php =================================================================== --- version.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ version.php (revision ) @@ -6,7 +6,7 @@ // This is compared against the values stored in the database to determine // whether upgrades should be performed (see lib/db/*.php) - $version = 2010050200; // YYYYMMDD = date of the last version bump + $version = 2010050301; // YYYYMMDD = date of the last version bump // XX = daily increments $release = '2.0 dev (Build: 20100502)'; // Human-friendly version name Index: enrol/meta/version.php =================================================================== --- enrol/meta/version.php (revision ) +++ enrol/meta/version.php (revision ) @@ -0,0 +1,3 @@ +version = 2010042301; Index: enrol/enrol.class.php =================================================================== --- enrol/enrol.class.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/enrol.class.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,22 +0,0 @@ -enrol; - } - if (file_exists("$CFG->dirroot/enrol/$enrol/enrol.php")) { - require_once("$CFG->dirroot/enrol/$enrol/enrol.php"); - $class = "enrolment_plugin_$enrol"; - return new $class; - } else { - error_log("$CFG->dirroot/enrol/$enrol/enrol.php does not exist"); - echo $OUTPUT->notification("Enrolment file $enrol/enrol.php does not exist"); - } - } -} Index: rss/file.php =================================================================== --- rss/file.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ rss/file.php (revision ) @@ -86,29 +86,21 @@ if (!in_array(strtolower($modulename), $mods)) { rss_not_found(); } - //Get course_module to check it's visible - if (!$cm = get_coursemodule_from_instance($modulename,$instance)) { + try { + $cm = get_coursemodule_from_instance($modulename, $instance, 0, false, MUST_EXIST); + require_login($course, false, $cm, false, true); + } catch (Exception $e) { rss_not_found(); } - $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); - //will $modcontext always be the same object as $context? - $isuser = has_capability('moodle/course:participate', $modcontext); -} else { - $isuser = has_capability('moodle/course:participate', $coursecontext); -} -//Check if course allows guests -if ($course->id != SITEID) { - if ((!$course->guest || $course->password) && (!$isuser)) { +} else { + try { + require_login($course, false, NULL, false, true); + } catch (Exception $e) { rss_not_found(); } } -//Check for "security" if the course is hidden or the activity is hidden -if (!$isblog and (!$course->visible || !$cm->visible) && (!has_capability('moodle/course:viewhiddenactivities', $context))) { - rss_not_found(); -} - $pathname = null; //Work out the filename of the cached RSS file if ($isblog) { Index: enrol/guest/db/access.php =================================================================== --- enrol/guest/db/access.php (revision ) +++ enrol/guest/db/access.php (revision ) @@ -0,0 +1,41 @@ +. + +/** + * Capabilities for guest access plugin. + * + * @package enrol_guest + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +$capabilities = array( + + 'enrol/guest:config' => array( + + 'captype' => 'write', + 'contextlevel' => CONTEXT_COURSE, + 'legacy' => array( + 'manager' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + ) + ), + +); + + Index: lib/adminlib.php =================================================================== --- lib/adminlib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/adminlib.php (revision ) @@ -139,11 +139,21 @@ if ($type === 'mod') { $pluginname = $name; // eg. 'forum' - $strpluginname = get_string('modulename', $pluginname); + if (get_string_manager()->string_exists('modulename', $component)) { + $strpluginname = get_string('modulename', $component); - } else { + } else { + $strpluginname = $component; + } + + } else { $pluginname = $component; - $strpluginname = get_string('pluginname', $pluginname); // replaces string 'modulename' + if (get_string_manager()->string_exists('pluginname', $component)) { + $strpluginname = get_string('pluginname', $component); + } else { + $strpluginname = $component; - } + } + } + echo $OUTPUT->heading($pluginname); $plugindirectory = get_plugin_directory($type, $name); @@ -158,7 +168,7 @@ } } - if ('mod' === $type) { + if ($type === 'mod') { // perform cleanup tasks specific for activity modules if (!$module = $DB->get_record('modules', array('name' => $name))) { @@ -212,7 +222,26 @@ } } } + + } else if ($type === 'enrol') { + // NOTE: this is a bit brute force way - it will not trigger events and hooks properly + // nuke all role assignments + role_unassign_all(array('component'=>$component)); + // purge participants + $DB->delete_records_select('course_participants', "enrolid IN (SELECT id FROM {enrol} WHERE enrol = ?)", array($name)); + // purge enrol instances + $DB->delete_records('enrol', array('enrol'=>$name)); + // tweak enrol settings + if (!empty($CFG->enrol_plugins_enabled)) { + $enabledenrols = explode(',', $CFG->enrol_plugins_enabled); + $enabledenrols = array_flip($enabledenrols); + unset($enabledenrols[$name]); + $enabledenrols = array_flip($enabledenrols); + if (is_array($enabledenrols)) { + set_config('enrol_plugins_enabled', implode(',', $enabledenrols)); - } + } + } + } // perform clean-up taks common for all the plugin/subplugin types @@ -4114,13 +4143,13 @@ * * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class admin_setting_special_coursemanager extends admin_setting_pickroles { +class admin_setting_special_coursecontact extends admin_setting_pickroles { /** * Calls parent::__construct with specific arguments */ public function __construct() { - parent::__construct('coursemanager', get_string('coursemanager', 'admin'), - get_string('configcoursemanager', 'admin'), + parent::__construct('coursecontact', get_string('coursecontact', 'admin'), + get_string('coursecontact_desc', 'admin'), array('editingteacher')); } } @@ -4489,66 +4518,204 @@ } } + /** - * Enrolment manage page + * Special class for enrol plugins management. * + * @copyright 2010 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class admin_enrolment_page extends admin_externalpage { +class admin_setting_manageenrols extends admin_setting { /** * Calls parent::__construct with specific arguments */ public function __construct() { - global $CFG; - parent::__construct('enrolment', get_string('enrolments'), $CFG->wwwroot . '/'.$CFG->admin.'/enrol.php'); + $this->nosave = true; + parent::__construct('enrolsui', get_string('manageenrols', 'enrol'), '', ''); } /** - * @param string The string to search for - * @return array + * Always returns true, does nothing + * + * @return true */ - public function search($query) { - if ($result = parent::search($query)) { - return $result; + public function get_setting() { + return true; - } + } - $found = false; + /** + * Always returns true, does nothing + * + * @return true + */ + public function get_defaultsetting() { + return true; + } - if ($modules = get_plugin_list('enrol')) { + /** + * Always returns '', does not write anything + * + * @return string Always returns '' + */ + public function write_setting($data) { + // do not write any setting + return ''; + } + + /** + * Checks if $query is one of the available enrol plugins + * + * @param string $query The string to search for + * @return bool Returns true if found, false if not + */ + public function is_related($query) { + if (parent::is_related($query)) { + return true; + } + - $textlib = textlib_get_instance(); + $textlib = textlib_get_instance(); - foreach ($modules as $plugin => $dir) { - if (strpos($plugin, $query) !== false) { - $found = true; - break; + $query = $textlib->strtolower($query); + $enrols = enrol_get_plugins(false); + foreach ($enrols as $name=>$enrol) { + $localised = get_string('pluginname', 'enrol_'.$name); + if (strpos($textlib->strtolower($name), $query) !== false) { + return true; - } + } - $strmodulename = get_string('enrolname', "enrol_$plugin"); - if (strpos($textlib->strtolower($strmodulename), $query) !== false) { - $found = true; - break; + if (strpos($textlib->strtolower($localised), $query) !== false) { + return true; - } - } + } + } + return false; - } + } - //ugly harcoded hacks - if (strpos('sendcoursewelcomemessage', $query) !== false) { - $found = true; - } else if (strpos($textlib->strtolower(get_string('sendcoursewelcomemessage', 'admin')), $query) !== false) { - $found = true; - } else if (strpos($textlib->strtolower(get_string('configsendcoursewelcomemessage', 'admin')), $query) !== false) { - $found = true; - } else if (strpos($textlib->strtolower(get_string('configenrolmentplugins', 'admin')), $query) !== false) { - $found = true; + + /** + * 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; - } + } - if ($found) { - $result = new object(); - $result->page = $this; - $result->settings = array(); - return array($this->name => $result); + 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 { + } else { - return array(); + $name = $enrol; - } + } + //usage + $ci = $DB->count_records('enrol', array('enrol'=>$enrol)); + $cp = $DB->count_records_select('course_participants', "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 = ""; + $hideshow .= "pix_url('i/hide') . "\" class=\"icon\" alt=\"$strdisable\" />"; + $enabled = true; + $displayname = "$name"; + } else if (isset($enrols_available[$enrol])) { + $aurl = new moodle_url($url, array('action'=>'enable', 'enrol'=>$enrol)); + $hideshow = ""; + $hideshow .= "pix_url('i/show') . "\" class=\"icon\" alt=\"$strenable\" />"; + $enabled = false; + $displayname = "$name"; + } else { + $hideshow = ''; + $enabled = false; + $displayname = ''.$name.''; - } + } + + // 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 .= ""; + $updown .= "pix_url('t/up') . "\" alt=\"$strup\" /> "; + } else { + $updown .= "pix_url('spacer.gif') . "\" class=\"icon\" alt=\"\" /> "; -} + } + if ($updowncount < $enrolcount) { + $aurl = new moodle_url($url, array('action'=>'down', 'enrol'=>$enrol)); + $updown .= ""; + $updown .= "pix_url('t/down') . "\" alt=\"$strdown\" />"; + } else { + $updown .= "pix_url('spacer.gif') . "\" 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 = "$strsettings"; + } else { + $settings = ''; + } + + // uninstall + $aurl = new moodle_url($url, array('action'=>'uninstall', 'enrol'=>$enrol)); + $uninstall = "$struninstall"; + + // 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').'
'.get_string('tablenosave', 'admin'); + $return .= $OUTPUT->box_end(); + return highlight($query, $return); + } +} + + /** * Blocks manage page * @@ -5437,7 +5604,7 @@ $ADMIN->loaded = true; } - + return $ADMIN; } @@ -6087,7 +6254,7 @@ * Helper function that generates a moodle_url object * relevant to the repository */ - + function repository_action_url($repository) { return new moodle_url('/admin/repository.php', array('sesskey'=>sesskey(), 'repos'=>$repository)); } @@ -6120,7 +6287,7 @@ // Set strings that are used multiple times $settingsstr = get_string('settings'); $disablestr = get_string('disable'); - + // Table to list plug-ins $table = new html_table(); $table->head = array(get_string('name'), get_string('isactive', 'repository'), get_string('order'), $settingsstr); @@ -6166,7 +6333,7 @@ } else { $currentaction = 'hide'; } - + $select = new single_select($this->repository_action_url($typename, 'repos'), 'action', $actionchoicesforexisting, $currentaction, null, 'applyto' . basename($typename)); // Display up/down link Index: auth/fc/auth.php =================================================================== --- auth/fc/auth.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ auth/fc/auth.php (revision ) @@ -183,10 +183,10 @@ $systemcontext = get_context_instance(CONTEXT_SYSTEM); if ($iscreator) { // Following calls will not create duplicates - role_assign($creatorrole->id, $user->id, 0, $systemcontext->id, 0, 0, 0, 'fc'); + role_assign($creatorrole->id, $user->id, $systemcontext->id, 'auth_fc'); } else { //unassign only if previously assigned by this plugin! - role_unassign($creatorrole->id, $user->id, 0, $systemcontext->id, 'fc'); + role_unassign($creatorrole->id, $user->id, $systemcontext->id, 'auth_fc'); } } } Index: my/index.php =================================================================== --- my/index.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ my/index.php (revision ) @@ -60,9 +60,8 @@ $courses_limit = $courses_limit + 1; } - $courses = get_my_courses($USER->id, 'visible DESC,sortorder ASC', '*', false, $courses_limit); + $courses = enrol_get_my_courses('*', 'visible DESC,sortorder ASC', $courses_limit); $site = get_site(); - $course = $site; //just in case we need the old global $course hack if (($courses_limit > 0) && (count($courses) >= $courses_limit)) { //remove the 'marker' course that we retrieve just to see if we have more than $courses_limit Index: notes/index.php =================================================================== --- notes/index.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ notes/index.php (revision ) @@ -118,7 +118,7 @@ echo ''; if (!empty($userid)) { - $courses = get_my_courses($userid); + $courses = enrol_get_users_courses($userid); foreach($courses as $c) { $header = '' . $c->fullname . ''; if (has_capability('moodle/notes:manage', get_context_instance(CONTEXT_COURSE, $c->id))) { Index: enrol/guest/locallib.php =================================================================== --- enrol/guest/locallib.php (revision ) +++ enrol/guest/locallib.php (revision ) @@ -0,0 +1,73 @@ +. + +/** + * Guest access plugin implementation. + * + * @package enrol_guest + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once("$CFG->libdir/formslib.php"); + +class enrol_guest_enrol_form extends moodleform { + protected $instance; + + public function definition() { + $mform = $this->_form; + $instance = $this->_customdata; + $this->instance = $instance; + + $heading = empty($instance->name) ? get_string('pluginname', 'enrol_guest') : format_string($instance->name); + $mform->addElement('header', 'guestheader', $heading); + + $mform->addElement('passwordunmask', 'guestpassword', get_string('password', 'enrol_guest')); + + $this->add_action_buttons(false, get_string('submit')); + + $mform->addElement('hidden', 'id'); + $mform->setType('id', PARAM_INT); + $mform->setDefault('id', $instance->courseid); + + $mform->addElement('hidden', 'instance'); + $mform->setType('instance', PARAM_INT); + $mform->setDefault('instance', $instance->id); + } + + public function validation($data, $files) { + global $DB, $CFG; + + $errors = parent::validation($data, $files); + $instance = $this->instance; + + if ($instance->password) { + if ($data['guestpassword'] !== $instance->password) { + $plugin = enrol_get_plugin('guest'); + if ($plugin->get_config('showhint')) { + $textlib = textlib_get_instance(); + $hint = $textlib->substr($instance->password, 0, 1); + $errors['guestpassword'] = get_string('passwordinvalidhint', 'enrol_guest', $hint); + } else { + $errors['guestpassword'] = get_string('passwordinvalid', 'enrol_guest'); + } + } + } + + return $errors; + } +} \ No newline at end of file Index: enrol/manual/lib.php =================================================================== --- enrol/manual/lib.php (revision ) +++ enrol/manual/lib.php (revision ) @@ -0,0 +1,172 @@ +. + +/** + * Manual enrolment plugin main library file. + * + * @package enrol_manual + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +class enrol_manual_plugin extends enrol_plugin { + + /** + * Adds enrol instance UI to course edit form + * + * @param object $instance enrol instance or null if does not exist yet + * @param MoodleQuickForm $mform + * @param object $data + * @param object $context context of existing course or parent category if course does not exist + * @return void + */ + public function course_edit_form($instance, MoodleQuickForm $mform, $data, $context) { + + $i = isset($instance->id) ? $instance->id : 0; + $header = empty($instance->name) ? get_string('pluginname', 'enrol_manual') : $instance->name; + $config = has_capability('enrol/manual:config', $context); + + $mform->addElement('header', 'enrol_manual_header_'.$i, $header); + + + $options = array(ENROL_STATUS_ENABLED => get_string('yes'), + ENROL_STATUS_DISABLED => get_string('no')); + $mform->addElement('select', 'enrol_manual_status_'.$i, get_string('status', 'enrol_manual'), $options); + $mform->setDefault('enrol_manual_status_'.$i, $this->get_config('status')); + $mform->setAdvanced('enrol_manual_status_'.$i, $this->get_config('status_adv')); + if (!$config) { + $mform->hardFreeze('enrol_manual_status_'.$i); + } + + + $mform->addElement('duration', 'enrol_manual_enrolperiod_'.$i, get_string('defaultperiod', 'enrol_manual'), array('optional' => true, 'defaultunit' => 86400)); + $mform->setDefault('enrol_manual_enrolperiod_'.$i, $this->get_config('enrolperiod')); + $mform->setAdvanced('enrol_manual_enrolperiod_'.$i, $this->get_config('enrolperiod_adv')); + if (!$config) { + $mform->hardFreeze('enrol_manual_enrolperiod_'.$i); + } else { + $mform->disabledIf('enrol_manual_enrolperiod_'.$i, 'enrol_manual_status_'.$i, 'noteq', ENROL_STATUS_ENABLED); + } + + + if ($instance) { + $roles = get_default_enrol_roles($context, $instance->defaultrole); + } else { + $roles = get_default_enrol_roles($context, $this->get_config('defaultrole')); + } + $mform->addElement('select', 'enrol_manual_defaultrole_'.$i, get_string('defaultrole', 'role'), $roles); + $mform->setDefault('enrol_manual_defaultrole_'.$i, $this->get_config('defaultrole')); + $mform->setAdvanced('enrol_manual_defaultrole_'.$i, $this->get_config('defaultrole_adv')); + if (!$config) { + $mform->hardFreeze('enrol_manual_defaultrole_'.$i); + } else { + $mform->disabledIf('enrol_manual_defaultrole_'.$i, 'enrol_manual_status_'.$i, 'noteq', ENROL_STATUS_ENABLED); + } + + + // now add all values from enrol table + if ($instance) { + foreach($instance as $key=>$val) { + $data->{'enrol_manual_'.$key.'_'.$i} = $val; + } + } + } + + /** + * Called after updating/inserting course. + * + * @param object $instance enrol instance, null if does not exist yet + * @param object $course + * @param object $data form data + * @return void + */ + public function course_updated($instance, $course, $data) { + global $DB; + + $context = get_context_instance(CONTEXT_COURSE, $course->id); + if (has_capability('enrol/manual:config', $context)) { + if ($instance) { + $i = $instance->id; + } else { + $i = 0; + $instance = new object(); + $instance->enrol = 'manual'; + $instance->courseid = $course->id; + } + + $instance->status = $data->{'enrol_manual_status_'.$i}; + $instance->timemodified = time(); + + if ($instance->status == ENROL_STATUS_ENABLED) { + $instance->enrolperiod = $data->{'enrol_manual_enrolperiod_'.$i}; + $instance->defaultrole = $data->{'enrol_manual_defaultrole_'.$i}; + + } else if (empty($instance->id)) { + $instance->enrolperiod = $this->get_config('enrolperiod'); + $instance->defaultrole = $this->get_config('defaultrole'); + } + + if (empty($instance->id)) { + $instance->timecreated = $instance->timemodified; + $instance->sortorder = $DB->get_field('enrol', 'COALESCE(MAX(sortorder), -1) + 1', array('courseid'=>$course->id)); + $DB->insert_record('enrol', $instance); + } else { + $DB->update_record('enrol', $instance); + } + + } else { + if ($instance) { + // bad luck, user can not change anything + } else { + $this->add_default_instance($course); + } + } + } + + /** + * Add new instance of enrol plugin with default settings. + * @param object $course + * @return int id of new instance + */ + public function add_default_instance($course) { + global $DB; + + $instance = new object(); + $instance->enrol = 'manual'; + $instance->status = $this->get_config('status'); + $instance->courseid = $course->id; + $instance->enrolperiod = $this->get_config('enrolperiod', 0); + $instance->defaultrole = $this->get_config('defalutrole', 0); + $instance->timemodified = time(); + $instance->timecreated = $instance->timemodified; + $instance->sortorder = $DB->get_field('enrol', 'COALESCE(MAX(sortorder), -1) + 1', array('courseid'=>$course->id)); + + return $DB->insert_record('enrol', $instance); + } + + public function setup_manage_tabs($instance, &$currenttab, &$toprow, &$inactive, &$activetwo, &$secondrow) { + $context = get_context_instance(CONTEXT_COURSE, $instance->courseid); + if (!has_capability('enrol/manual:manage', $context)) { + return; + } + $url = new moodle_url('/enrol/manual/manage.php', array('id'=>$instance->courseid, 'enrolid'=>$instance->id)); + $name = empty($instance->name) ? get_string('pluginname', 'enrol_'.$instance->enrol) : format_string($instance->name); + $toprow[] = new tabobject($instance->enrol, $url, $name); + } +} + Index: calendar/lib.php =================================================================== --- calendar/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ calendar/lib.php (revision ) @@ -1429,12 +1429,7 @@ } } - if (isset($CFG->adminseesall)) { - $courses = get_my_courses($USER->id, null, null, $CFG->adminseesall); - } - else { - $courses = get_my_courses($USER->id, null, null, false); - } + $courses = enrol_get_my_courses(); return $courses; } Index: lib/db/services.php =================================================================== --- lib/db/services.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/db/services.php (revision ) @@ -131,19 +131,4 @@ 'type' => 'write', ), - 'moodle_enrol_role_assign' => array( - 'classname' => 'moodle_enrol_external', - 'methodname' => 'role_assign', - 'classpath' => 'enrol/externallib.php', - 'description' => 'Enrol users.', - 'type' => 'write', - ), - - 'moodle_enrol_role_unassign' => array( - 'classname' => 'moodle_enrol_external', - 'methodname' => 'role_unassign', - 'classpath' => 'enrol/externallib.php', - 'description' => 'Unenrol users.', - 'type' => 'write', - ), ); Index: enrol/mnet/enrol.php =================================================================== --- enrol/mnet/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/mnet/enrol.php (revision ) @@ -353,9 +353,7 @@ // Are we a *real* user or the shady MNET Daemon? // require_capability('moodle/role:assign', $context, NULL, false); - if (!role_unassign(0, $userrecord->id, 0, $context->id)) { - throw new mnet_exception(5015, 'couldnotunenrol', 'enrol_mnet'); - } + role_unassign_all(array('userid'=>$userrecord->id, 'contextiod'=>$context->id, 'component'=>'enrol_mnet'), true, true); return true; } Index: backup/restorelib.php =================================================================== --- backup/restorelib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ backup/restorelib.php (revision ) @@ -9699,13 +9699,7 @@ return true; } - // Non-cached - get accessinfo - if (isset($USER->access)) { - $accessinfo = $USER->access; - } else { - $accessinfo = get_user_access_sitewide($USER->id); - } - $courses = get_user_courses_bycap($USER->id, 'moodle/restore:rolldates', $accessinfo, true); + $courses = get_user_courses_bycap($USER->id, 'moodle/restore:rolldates'); return !empty($courses); } Index: enrol/manual/version.php =================================================================== --- enrol/manual/version.php (revision ) +++ enrol/manual/version.php (revision ) @@ -0,0 +1,26 @@ +. + +/** + * Manual enrolment plugin. + * + * @package enrol_manual + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$plugin->version = 2010042303; Index: mod/choice/view.php =================================================================== --- mod/choice/view.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ mod/choice/view.php (revision ) @@ -142,7 +142,7 @@ echo $OUTPUT->box_start('generalbox', 'notice'); echo '

'. get_string('noguestchoose', 'choice') .'

'; echo $OUTPUT->container_start('continuebutton'); - echo $OUTPUT->single_button(new moodle_url('/course/enrol.php?', array('id'=>$course->id)), get_string('enrolme', '', format_string($course->shortname))); + echo $OUTPUT->single_button(new moodle_url('/enrol/index.php?', array('id'=>$course->id)), get_string('enrolme', '', format_string($course->shortname))); echo $OUTPUT->container_end(); echo $OUTPUT->box_end(); Index: auth/ldap/auth.php =================================================================== --- auth/ldap/auth.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ auth/ldap/auth.php (revision ) @@ -745,9 +745,9 @@ // update course creators if needed if ($creatorrole !== false) { if ($this->iscreator($user->username)) { - role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'ldap'); + role_assign($creatorrole->id, $user->id, $sitecontext->id, 'auth_ldap'); } else { - role_unassign($creatorrole->id, $user->id, 0, $sitecontext->id, 'ldap'); + role_unassign($creatorrole->id, $user->id, $sitecontext->id, 'auth_ldap'); } } } @@ -809,7 +809,7 @@ // add course creators if needed if ($creatorrole !== false and $this->iscreator($user->username)) { - role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'ldap'); + role_assign($creatorrole->id, $user->id, $sitecontext->id, 'auth_ldap'); } } $transaction->allow_commit(); @@ -1950,10 +1950,10 @@ $systemcontext = get_context_instance(CONTEXT_SYSTEM); if ($iscreator) { // Following calls will not create duplicates - role_assign($creatorrole->id, $user->id, 0, $systemcontext->id, 0, 0, 0, 'ldap'); + role_assign($creatorrole->id, $user->id, $systemcontext->id, 'auth_ldap'); } else { //unassign only if previously assigned by this plugin! - role_unassign($creatorrole->id, $user->id, 0, $systemcontext->id, 'ldap'); + role_unassign($creatorrole->id, $user->id, $systemcontext->id, 'auth_ldap'); } } } Index: lang/en/admin.php =================================================================== --- lang/en/admin.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lang/en/admin.php (revision ) @@ -45,7 +45,6 @@ $string['allowusermailcharset'] = 'Allow user to select character set'; $string['allowuserswitchrolestheycantassign'] = 'Allow users without the assign roles capability to switch roles'; $string['allowuserthemes'] = 'Allow user themes'; -$string['allowvisiblecoursesinhiddencategories'] = 'Allow visible courses in hidden categories'; $string['antivirus'] = 'Anti-Virus'; $string['appearance'] = 'Appearance'; $string['aspellpath'] = 'Path to aspell'; @@ -122,7 +121,6 @@ $string['configallowoverride2'] = 'Select which role(s) can be overridden by each role in the left column.
Note that these settings only apply to users who have either the capability moodle/role:override or the capability moodle/role:safeoverride allowed.'; $string['configallowswitch'] = 'Select which roles a user may switch to, based on which roles they already have. In addition to an entry in this table, a user must also have the moodle/role:switchroles capability to be able to switch.
Note that it is only possible to switch to roles that have the moodle/course:view capability, and that do not have the moodle/site:doanything capability, so some columns in this table are disabled.'; $string['configallowthemechangeonurl'] = 'If enabled, the theme can be changed by adding theme={themename} to any Moodle URL.'; -$string['configallowunenroll'] = 'If this is set \'Yes\', then students are allowed to unenrol themselves from courses whenever they like. Otherwise they are not allowed, and this process will be solely controlled by the teachers and administrators.'; $string['configallowuserblockhiding'] = 'Do you want to allow users to hide/show side blocks throughout this site? This feature uses Javascript and cookies to remember the state of each collapsible block, and only affects the user\'s own view.'; $string['configallowusermailcharset'] = 'Enabling this, every user in the site will be able to specify his own charset for email.'; $string['configallowuserswitchrolestheycantassign'] = 'By default, moodle/role:assign is required for users to switch roles. Enabling this setting removes this requirement, and results in the roles available in the "Switch role to" dropdown menu being determined by settings in the "Allow role assignments" table only. @@ -143,7 +141,6 @@ $string['configcookiehttponly'] = 'Enables new PHP 5.2.0 feature - browsers are instructed to send cookie with real http requests only, cookies should not be accessible by scripting languages. This is not supported in all browsers and it may not be fully compatible with current code. It helps to prevent some types of XSS attacks.'; $string['configcookiesecure'] = 'If server is accepting only https connections it is recommended to enable sending of secure cookies. If enabled please make sure that web server is not accepting http:// or set up permanent redirection to https:// address. When wwwroot address does not start with https:// this setting is turned off automatically.'; $string['configcountry'] = 'If you set a country here, then this country will be selected by default on new user accounts. To force users to choose a country, just leave this unset.'; -$string['configcoursemanager'] = 'This setting allows you to control who appears on the course description. Users need to have at least one of these roles in a course to be shown on the course description for that course.'; $string['configcourserequestnotify'] = 'Type username of user to be notified when new course requested.'; $string['configcourserequestnotify2'] = 'Users who will be notified when a course is requested. Only users who can approve course requests are listed here.'; $string['configcoursesperpage'] = 'Enter the number of courses to be display per page in a course listing.'; @@ -193,7 +190,6 @@ $string['configenabletrusttext'] = 'By default Moodle will always thoroughly clean text that comes from users to remove any possible bad scripts, media etc that could be a security risk. The Trusted Content system is a way of giving particular users that you trust the ability to include these advanced features in their content without interference. To enable this system, you need to first enable this setting, and then grant the Trusted Content permission to a specific Moodle role. Texts created or uploaded by such users will be marked as trusted and will not be cleaned before display.'; $string['configenablewebservices'] = 'Web services enable other systems to log in to this Moodle and perform operations. For extra security this feature should be disabled unless you are really using it.'; $string['configenablewsdocumentation'] = 'Enable auto-generation of web services documentation. A web service user can access to his own {$a} without login into Moodle. It display the documentation for the enabled protocols only.'; -$string['configenrolmentplugins'] = 'Please choose the enrolment plugins you wish to use. Don\'t forget to configure the settings properly.

You have to indicate which plugins are enabled, and one plugin can be set as the default plugin for interactive enrolment. To disable interactive enrolment, set "enrollable" to "No" in required courses.'; $string['configerrorlevel'] = 'Choose the amount of PHP warnings that you want to be displayed. Normal is usually the best choice.'; $string['configexcludeoldflashclients'] = 'Some versions of the Adobe Flash plugin are known to be vulnerable to attacks from malicious Flash content. You can specify a minimum supported version here, and Moodle will not show Flash files to users with lower versions. Instead they will see an alternate Flash file telling them how to upgrade. Leave this empty to disable all checks.'; $string['configexperimentalsplitrestore'] = 'If enabled, course backup files will be checked for XML errors and split into smaller parts for use in the restore process. This will result in improvements to restore robustness and execution times, particularly for medium to large course backups.'; @@ -257,7 +253,6 @@ $string['confignavshowallcourses'] = 'Setting this ensures that all courses a user is registered in are shown on the navigation at all times. By default once a user browses to a course only that course is shown on the navigation.'; $string['confignavshowcategories'] = 'Show course categories in the navigation bar and navigation blocks'; $string['confignodefaultuserrolelists'] = 'This setting prevents all users from being returned from the database from deprecated calls of get_course_user, etc., for the site course if the default role provides that access. Check this, if you suffer a performance hit.'; -$string['confignonmetacoursesyncroleids'] = 'By default all role assignments from child courses are synchronised to metacourses. Roles that are selected here will not be included in the synchronisation process.'; $string['confignoreplyaddress'] = 'Emails are sometimes sent out on behalf of a user (eg forum posts). The email address you specify here will be used as the "From" address in those cases when the recipients should not be able to reply directly to the user (eg when a user chooses to keep their address private).'; $string['confignotifyloginfailures'] = 'If login failures have been recorded, email notifications can be sent out. Who should see these notifications?'; $string['confignotifyloginthreshold'] = 'If notifications about failed logins are active, how many failed login attempts by one user or one IP address is it worth notifying about?'; @@ -302,7 +297,6 @@ $string['configsectionstats'] = 'Statistics'; $string['configsectionuser'] = 'User'; $string['configsecureforms'] = 'Moodle can use an additional level of security when accepting data from web forms. If this is enabled, then the browser\'s HTTP_REFERER variable is checked against the current form address. In a very few cases this can cause problems if the user is using a firewall (eg Zonealarm) configured to strip HTTP_REFERER from their web traffic. Symptoms are getting \'stuck\' on a form. If your users are having problems with the login page (for example) you might want to disable this setting, although it might leave your site more open to brute-force password attacks. If in doubt, leave this set to \'Yes\'.'; -$string['configsendcoursewelcomemessage'] = 'If enabled, users receive a welcome message via email when they self-enrol in a course.'; $string['configsessioncookie'] = 'This setting customises the name of the cookie used for Moodle sessions. This is optional, and only useful to avoid cookies being confused when there is more than one copy of Moodle running within the same web site.'; $string['configsessioncookiedomain'] = 'This allows you to change the domain that the Moodle cookies are available from. This is useful for Moodle customisations (e.g. authentication or enrolment plugins) that need to share Moodle session information with a web application on another subdomain. WARNING: it is strongly recommended to leave this setting at the default (empty) - an incorrect value will prevent all logins to the site.'; $string['configsessioncookiepath'] = 'If you need to change where browsers send the Moodle cookies, you can change this setting to specify a subdirectory of your web site. Otherwise the default \'/\' should be fine.'; @@ -357,7 +351,8 @@ $string['cookiehttponly'] = 'Only http cookies'; $string['cookiesecure'] = 'Secure cookies only'; $string['country'] = 'Default country'; -$string['coursemanager'] = 'Course managers'; +$string['coursecontact'] = 'Course contacts'; +$string['coursecontact_desc'] = 'This setting allows you to control who appears on the course description. Users need to have at least one of these roles in a course to be shown on the course description for that course.'; $string['coursemgmt'] = 'Add/edit courses'; $string['courseoverview'] = 'Course overview'; $string['courserequestnotify'] = 'Course request notification'; @@ -465,6 +460,8 @@ $string['enablewebservices'] = 'Enable web services'; $string['enablewsdocumentation'] = 'Web services documentation'; $string['encoding'] = 'Encoding'; +$string['enrolinstancedefaults'] = 'Enrolment instance defaults'; +$string['enrolinstancedefaults_desc'] = 'Default enrolment settings in new courses.'; $string['enrolmultipleusers'] = 'Enrol the users'; $string['environment'] = 'Environment'; $string['environmenterrortodo'] = 'You must solve all the environmental problems (errors) found above before proceeding to install this Moodle version!'; @@ -683,7 +680,6 @@ $string['nomissingstrings'] = 'No missing strings'; $string['nonewsettings'] = 'No new settings were added during this upgrade.'; $string['nonexistentbookmark'] = 'The bookmark you requested does not exist.'; -$string['nonmetacoursesyncroleids'] = 'Roles that are not synchronised to metacourses'; $string['noreplyaddress'] = 'No-reply address'; $string['noresults'] = 'No results found.'; $string['noroles'] = 'No roles'; @@ -829,7 +825,6 @@ $string['sectionerror'] = 'Section Error!'; $string['secureforms'] = 'Use additional form security'; $string['security'] = 'Security'; -$string['sendcoursewelcomemessage'] = 'Send course welcome message'; $string['server'] = 'Server'; $string['serverchecks'] = 'Server Checks'; $string['serverlimit'] = 'Server Limit'; Index: lib/datalib.php =================================================================== --- lib/datalib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/datalib.php (revision ) @@ -82,82 +82,6 @@ } /** - * Get all of the courses in a given meta course - * - * @global object - * @param int $metacourseid The metacourse id - * @return array - */ -function get_courses_in_metacourse($metacourseid) { - global $DB; - - $sql = "SELECT c.id, c.shortname, c.fullname - FROM {course} c, {course_meta} mc - WHERE mc.parent_course = ? AND mc.child_course = c.id - ORDER BY c.shortname"; - $params = array($metacourseid); - - return $DB->get_records_sql($sql, $params); -} - -/** - * @todo Document this function - * - * @global object - * @uses SITEID - * @param int $metacourseid - * @return array - */ -function get_courses_notin_metacourse($metacourseid) { - global $DB; - - if ($alreadycourses = get_courses_in_metacourse($metacourseid)) { - $alreadycourses = implode(',',array_keys($alreadycourses)); - $alreadycourses = "AND c.id NOT IN ($alreadycourses)"; - } else { - $alreadycourses = ""; - } - - $sql = "SELECT c.id,c.shortname,c.fullname - FROM {course} c - WHERE c.id != ? and c.id != ".SITEID." and c.metacourse != 1 - $alreadycourses - ORDER BY c.shortname"; - $params = array($metacourseid); - - return $DB->get_records_sql($sql, $params); -} - -/** - * @todo Document this function - * - * This function is nearly identical to {@link get_courses_notin_metacourse()} - * - * @global object - * @uses SITEID - * @param int $metacourseid - * @return int The count - */ -function count_courses_notin_metacourse($metacourseid) { - global $DB; - - if ($alreadycourses = get_courses_in_metacourse($metacourseid)) { - $alreadycourses = implode(',',array_keys($alreadycourses)); - $alreadycourses = "AND c.id NOT IN ($alreadycourses)"; - } else { - $alreadycourses = ""; - } - - $sql = "SELECT COUNT(c.id) - FROM {course} c - WHERE c.id != ? and c.id != ".SITEID." and c.metacourse != 1 - $alreadycourses"; - $params = array($metacourseid); - - return $DB->count_records_sql($sql, $params); -} - -/** * Search through course users * * If $coursid specifies the site course then this function searches @@ -602,9 +526,8 @@ $basefields = array('id', 'category', 'sortorder', 'shortname', 'fullname', 'idnumber', - 'guest', 'startdate', 'visible', - 'newsitems', 'cost', 'enrol', - 'groupmode', 'groupmodeforce'); + 'startdate', 'visible', + 'newsitems', 'groupmode', 'groupmodeforce'); if (!is_null($fields) && is_string($fields)) { if (empty($fields)) { @@ -666,12 +589,12 @@ return array(); // no courses! } - $CFG->coursemanager = trim($CFG->coursemanager); - if (empty($CFG->coursemanager)) { + $CFG->coursecontact = trim($CFG->coursecontact); + if (empty($CFG->coursecontact)) { return $courses; } - $managerroles = split(',', $CFG->coursemanager); + $managerroles = split(',', $CFG->coursecontact); $catctxids = ''; if (count($managerroles)) { if ($allcats === true) { @@ -720,7 +643,7 @@ $sql .= " OR ra.contextid IN ($catctxids) )"; } - $sql .= "AND ra.roleid IN ({$CFG->coursemanager}) + $sql .= "AND ra.roleid IN ({$CFG->coursecontact}) $categoryclause ORDER BY r.sortorder ASC, ctx.contextlevel ASC, ra.sortorder ASC"; $rs = $DB->get_recordset_sql($sql, $params); @@ -768,293 +691,6 @@ } /** - * Convenience function - lists courses that a user has access to view. - * - * For admins and others with access to "every" course in the system, we should - * try to get courses with explicit RAs. - * - * NOTE: this function is heavily geared towards the perspective of the user - * passed in $userid. So it will hide courses that the user cannot see - * (for any reason) even if called from cron or from another $USER's - * perspective. - * - * If you really want to know what courses are assigned to the user, - * without any hiding or scheming, call the lower-level - * get_user_courses_bycap(). - * - * - * Notes inherited from get_user_courses_bycap(): - * - * - $fields is an array of fieldnames to ADD - * so name the fields you really need, which will - * be added and uniq'd - * - * - the course records have $c->context which is a fully - * valid context object. Saves you a query per course! - * - * @global object - * @global object - * @global object - * @uses CONTEXT_SYSTEM - * @uses CONTEXT_COURSE - * @uses CONTEXT_COURSECAT - * @param int $userid The user of interest - * @param string $sort the sortorder in the course table - * @param array $fields names of _additional_ fields to return (also accepts a string) - * @param bool $doanything True if using the doanything flag - * @param int $limit Maximum number of records to return, or 0 for unlimited - * @return array Array of {@link $COURSE} of course objects - */ -function get_my_courses($userid, $sort='visible DESC,sortorder ASC', $fields=NULL, $doanything=false,$limit=0) { - global $CFG, $USER, $DB; - - // Guest account does not have any courses - if (isguestuser()) { - return(array()); - } - - $basefields = array('id', 'category', 'sortorder', - 'shortname', 'fullname', 'idnumber', - 'guest', 'startdate', 'visible', - 'newsitems', 'cost', 'enrol', - 'groupmode', 'groupmodeforce'); - - if (!is_null($fields) && is_string($fields)) { - if (empty($fields)) { - $fields = $basefields; - } else { - // turn the fields from a string to an array that - // get_user_courses_bycap() will like... - $fields = explode(',',$fields); - $fields = array_map('trim', $fields); - $fields = array_unique(array_merge($basefields, $fields)); - } - } elseif (is_array($fields)) { - $fields = array_unique(array_merge($basefields, $fields)); - } else { - $fields = $basefields; - } - - $orderby = ''; - $sort = trim($sort); - if (!empty($sort)) { - $rawsorts = explode(',', $sort); - $sorts = array(); - foreach ($rawsorts as $rawsort) { - $rawsort = trim($rawsort); - if (strpos($rawsort, 'c.') === 0) { - $rawsort = substr($rawsort, 2); - } - $sorts[] = trim($rawsort); - } - $sort = 'c.'.implode(',c.', $sorts); - $orderby = "ORDER BY $sort"; - } - - // - // Logged-in user - Check cached courses - // - // NOTE! it's a _string_ because - // - it's all we'll ever use - // - it serialises much more compact than an array - // this a big concern here - cost of serialise - // and unserialise gets huge as the session grows - // - // If the courses are too many - it won't be set - // for large numbers of courses, caching in the session - // has marginal benefits (costs too much, not - // worthwhile...) and we may hit SQL parser limits - // because we use IN() - // - if ($userid === $USER->id) { - if (isset($USER->loginascontext) - && $USER->loginascontext->contextlevel == CONTEXT_COURSE) { - // list _only_ this course - // anything else is asking for trouble... - $courseids = $USER->loginascontext->instanceid; - } elseif (isset($USER->mycourses) - && is_string($USER->mycourses)) { - if ($USER->mycourses === '') { - // empty str means: user has no courses - // ... so do the easy thing... - return array(); - } else { - $courseids = $USER->mycourses; - } - } - if (isset($courseids)) { - // The data massaging here MUST be kept in sync with - // get_user_courses_bycap() so we return - // the same... - // (but here we don't need to check has_cap) - $coursefields = 'c.' .join(',c.', $fields); - list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx'); - $sql = "SELECT $coursefields $ccselect, cc.path AS categorypath - FROM {course} c - JOIN {course_categories} cc ON c.category=cc.id - $ccjoin - WHERE c.id IN ($courseids) - $orderby"; - $rs = $DB->get_recordset_sql($sql); - $courses = array(); - $cc = 0; // keep count - foreach ($rs as $c) { - // build the context obj - context_instance_preload($c); - - if ($limit > 0 && $cc >= $limit) { - break; - } - - $courses[$c->id] = $c; - $cc++; - } - $rs->close(); - return $courses; - } - } - - // Non-cached - get accessinfo - if ($userid === $USER->id && isset($USER->access)) { - $accessinfo = $USER->access; - } else { - $accessinfo = get_user_access_sitewide($userid); - } - - - $courses = get_user_courses_bycap($userid, 'moodle/course:participate', $accessinfo, - $doanything, $sort, $fields, - $limit); - - $cats = NULL; - // If we have to walk category visibility - // to eval course visibility, get the categories - if (empty($CFG->allowvisiblecoursesinhiddencategories)) { - list($ccselect, $ccjoin) = context_instance_preload_sql('cc.id', CONTEXT_COURSECAT, 'ctx'); - $sql = "SELECT cc.id, cc.path, cc.visible $ccselect - FROM {course_categories} cc - $ccjoin - ORDER BY cc.id"; - $rs = $DB->get_recordset_sql($sql); - - // Using a temporary array instead of $cats here, to avoid a "true" result when isnull($cats) further down - $categories = array(); - foreach($rs as $course_cat) { - // build the context obj - context_instance_preload($course_cat); - $categories[$course_cat->id] = $course_cat; - } - $rs->close(); - - if (!empty($categories)) { - $cats = $categories; - } - - unset($course_cat); - } - // - // Strangely, get_my_courses() is expected to return the - // array keyed on id, which messes up the sorting - // So do that, and also cache the ids in the session if appropriate - // - $kcourses = array(); - $courses_count = count($courses); - $cacheids = NULL; - $vcatpaths = array(); - if ($userid === $USER->id && $courses_count < 500) { - $cacheids = array(); - } - for ($n=0; $n<$courses_count; $n++) { - - // - // Check whether $USER (not $userid) can _actually_ see them - // Easy if $CFG->allowvisiblecoursesinhiddencategories - // is set, and we don't have to care about categories. - // Lots of work otherwise... (all in mem though!) - // - $cansee = false; - if (is_null($cats)) { // easy rules! - if ($courses[$n]->visible == true) { - $cansee = true; - } elseif (has_capability('moodle/course:viewhiddencourses', - $courses[$n]->context, $USER->id)) { - $cansee = true; - } - } else { - // - // Is the cat visible? - // we have to assume it _is_ visible - // so we can shortcut when we find a hidden one - // - $viscat = true; - $cpath = $courses[$n]->categorypath; - if (isset($vcatpaths[$cpath])) { - $viscat = $vcatpaths[$cpath]; - } else { - $cpath = substr($cpath,1); // kill leading slash - $cpath = explode('/',$cpath); - $ccct = count($cpath); - for ($m=0;$m<$ccct;$m++) { - $ccid = $cpath[$m]; - if ($cats[$ccid]->visible==false) { - $viscat = false; - break; - } - } - $vcatpaths[$courses[$n]->categorypath] = $viscat; - } - - // - // Perhaps it's actually visible to $USER - // check moodle/category:viewhiddencategories - // - // The name isn't obvious, but the description says - // "See hidden categories" so the user shall see... - // But also check if the allowvisiblecoursesinhiddencategories setting is true, and check for course visibility - if ($viscat === false) { - $catctx = $cats[$courses[$n]->category]->context; - if (has_capability('moodle/category:viewhiddencategories', $catctx, $USER->id)) { - $vcatpaths[$courses[$n]->categorypath] = true; - $viscat = true; - } elseif ($CFG->allowvisiblecoursesinhiddencategories && $courses[$n]->visible == true) { - $viscat = true; - } - } - - // - // Decision matrix - // - if ($viscat === true) { - if ($courses[$n]->visible == true) { - $cansee = true; - } elseif (has_capability('moodle/course:viewhiddencourses', - $courses[$n]->context, $USER->id)) { - $cansee = true; - } - } - } - if ($cansee === true) { - $kcourses[$courses[$n]->id] = $courses[$n]; - if (is_array($cacheids)) { - $cacheids[] = $courses[$n]->id; - } - } - } - if (is_array($cacheids)) { - // Only happens - // - for the logged in user - // - below the threshold (500) - // empty string is _valid_ - $USER->mycourses = join(',',$cacheids); - } elseif ($userid === $USER->id && isset($USER->mycourses)) { - // cheap sanity check - unset($USER->mycourses); - } - - return $kcourses; -} - -/** * A list of courses that match a search * * @global object @@ -2283,75 +1919,6 @@ } /** - * Check whether a course is visible through its parents - * path. - * - * Notes: - * - * - All we need from the course is ->category. _However_ - * if the course object has a categorypath property, - * we'll save a dbquery - * - * - If we return false, you'll still need to check if - * the user can has the 'moodle/category:viewhiddencategories' - * capability... - * - * - Will generate 2 DB calls. - * - * - It does have a small local cache, however... - * - * - Do NOT call this over many courses as it'll generate - * DB traffic. Instead, see what get_my_courses() does. - * - * @global object - * @global object - * @staticvar array $mycache - * @param object $course A course object - * @return bool - */ -function course_parent_visible($course = null) { - global $CFG, $DB; - //return true; - static $mycache; - - if (!is_object($course)) { - return true; - } - if (!empty($CFG->allowvisiblecoursesinhiddencategories)) { - return true; - } - - if (!isset($mycache)) { - $mycache = array(); - } else { - // cast to force assoc array - $k = (string)$course->category; - if (isset($mycache[$k])) { - return $mycache[$k]; - } - } - - if (isset($course->categorypath)) { - $path = $course->categorypath; - } else { - $path = $DB->get_field('course_categories', 'path', array('id'=>$course->category)); - } - $catids = substr($path,1); // strip leading slash - $catids = str_replace('/',',',$catids); - - $sql = "SELECT MIN(visible) - FROM {course_categories} - WHERE id IN ($catids)"; - $vis = $DB->get_field_sql($sql); - - // cast to force assoc array - $k = (string)$course->category; - $mycache[$k] = $vis; - - return $vis; -} - -/** * This function is the official hook inside XMLDB stuff to delegate its debug to one * external function. * Index: question/type/randomsamatch/questiontype.php =================================================================== --- question/type/randomsamatch/questiontype.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ question/type/randomsamatch/questiontype.php (revision ) @@ -97,7 +97,7 @@ $count = count($saquestions); $wanted = $question->options->choose; $errorstr = ''; - if ($count < $wanted && has_coursemanager_role()) { //TODO: this teacher test is far from optimal + if ($count < $wanted && has_coursecontact_role()) { //TODO: this teacher test is far from optimal if ($count >= 2) { $errorstr = "Error: could not get enough Short-Answer questions! Got $count Short-Answer questions, but wanted $wanted. Index: enrol/self/settings.php =================================================================== --- enrol/self/settings.php (revision ) +++ enrol/self/settings.php (revision ) @@ -0,0 +1,74 @@ +. + +/** + * Self enrolment plugin settings and presets. + * + * @package enrol_self + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +if ($ADMIN->fulltree) { + + //--- general settings ----------------------------------------------------------------------------------- + $settings->add(new admin_setting_heading('enrol_manual_settings', '', get_string('pluginname_desc', 'enrol_self'))); + + $settings->add(new admin_setting_configcheckbox('enrol_self/requirepassword', + get_string('requirepassword', 'enrol_self'), get_string('requirepassword_desc', 'enrol_self'), 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_self/usepasswordpolicy', + get_string('usepasswordpolicy', 'enrol_self'), get_string('usepasswordpolicy_desc', 'enrol_self'), 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_self/showhint', + get_string('showhint', 'enrol_self'), get_string('showhint_desc', 'enrol_self'), 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_self/sendcoursewelcomemessage', + get_string('sendcoursewelcomemessage', 'enrol_self'), get_string('sendcoursewelcomemessage_desc', 'enrol_self'), 1)); + + + //--- enrol instance defaults ---------------------------------------------------------------------------- + $settings->add(new admin_setting_heading('enrol_self_defaults', + get_string('enrolinstancedefaults', 'admin'), get_string('enrolinstancedefaults_desc', 'admin'))); + + $options = array(ENROL_STATUS_ENABLED => get_string('yes'), + ENROL_STATUS_DISABLED => get_string('no')); + $settings->add(new admin_setting_configselect_with_advanced('enrol_self/status', + get_string('status', 'enrol_self'), get_string('status_desc', 'enrol_self'), + array('value'=>ENROL_STATUS_ENABLED, 'adv'=>false), $options)); + + $options = array(1 => get_string('yes'), + 0 => get_string('no')); + $settings->add(new admin_setting_configselect_with_advanced('enrol_self/groupkey', + get_string('groupkey', 'enrol_self'), get_string('groupkey_desc', 'enrol_self'), + array('value'=>0, 'adv'=>true), $options)); + + if (!during_initial_install()) { + $options = get_default_enrol_roles(get_context_instance(CONTEXT_SYSTEM)); + $student = get_archetype_roles('student'); + $student = reset($student); + $settings->add(new admin_setting_configselect_with_advanced('enrol_self/role', + get_string('role', 'enrol_self'), get_string('role_desc', 'enrol_self'), + array('value'=>$student->id, 'adv'=>false), $options)); + } + + $settings->add(new admin_setting_configtext_with_advanced('enrol_self/enrolperiod', + get_string('enrolperiod', 'enrol_self'), get_string('enrolperiod_desc', 'enrol_self'), + array('value'=>0, 'adv'=>true), PARAM_INT)); + + +} Index: enrol/meta/db/access.php =================================================================== --- enrol/meta/db/access.php (revision ) +++ enrol/meta/db/access.php (revision ) @@ -0,0 +1,23 @@ + array( + + 'captype' => 'write', + 'contextlevel' => CONTEXT_COURSE, + 'legacy' => array( + 'manager' => CAP_ALLOW, + ) + ), + +); + + Index: mod/forum/lib.php =================================================================== --- mod/forum/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ mod/forum/lib.php (revision ) @@ -1793,9 +1793,8 @@ $courses = $DB->get_records('course', array('id' => $courseid)); } else { // If no course is specified, then the user can see SITE + his courses. - // And admins can see all courses, so pass the $doanything flag enabled $courses1 = $DB->get_records('course', array('id' => SITEID)); - $courses2 = get_my_courses($userid, null, null, true); + $courses2 = enrol_get_users_courses($userid, true); $courses = array_merge($courses1, $courses2); } if (!$courses) { @@ -5635,34 +5634,29 @@ } /** - * This function gets run whenever a role is assigned to a user in a context + * This function gets run whenever user is enrolled into course * - * @param integer $userid - * @param object $context - * @param itn $roleid - * @return bool + * @param int $userid + * @param int $courseid + * @return void */ -function forum_role_assign($userid, $context, $roleid) { - return forum_add_user_default_subscriptions($userid, $context); +function forum_user_enrolled($userid, $courseid) { + $context = get_context_instance(CONTEXT_COURSE, $courseid); + forum_add_user_default_subscriptions($userid, $context); } /** - * This function gets run whenever a role is assigned to a user in a context + * This function gets run whenever user is unenrolled from course * - * @param integer $userid - * @param object $context - * @return bool + * @param int $userid + * @param int $courseid + * @return void */ -function forum_role_unassign($userid, $context) { - if (empty($context->contextlevel)) { - return false; - } - +function forum_user_unenrolled($userid, $courseid) { + $context = get_context_instance(CONTEXT_COURSE, $courseid); forum_remove_user_subscriptions($userid, $context); forum_remove_user_tracking($userid, $context); - - return true; } @@ -5774,7 +5768,6 @@ switch ($context->contextlevel) { case CONTEXT_SYSTEM: // For the whole site - //if ($courses = get_my_courses($userid)) { // find all courses in which this user has a forum subscription if ($courses = $DB->get_records_sql("SELECT c.id FROM {course} c, Index: lang/en/moodle.php =================================================================== --- lang/en/moodle.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lang/en/moodle.php (revision ) @@ -185,7 +185,6 @@ $string['backuplogdetailed'] = 'Detailed execution log'; $string['backuploglaststatus'] = 'Last execution log'; $string['backuplogshelp'] = 'If enabled, then course logs will be included in automated backups'; -$string['backupmetacoursehelp'] = 'If enabled, then metacourse info (inherited enrolments) will be included in automated backups'; $string['backupmissinguserinfoperms'] = 'Note: This backup contains no user data. Exercise and Workshop activities will not be included in the backup, since these modules are not compatible with this type of backup.'; $string['backupnext'] = 'Next backup'; $string['backupnoneusersinfo'] = 'Note: This backup contains no users and so all activities have been switched to "without user data" mode. Exercise and Workshop activities will not be included in the backup, since these modules are not compatible with this type of backup.'; @@ -292,27 +291,16 @@ $string['coursecreators'] = 'Course creator'; $string['coursecreatorsdescription'] = 'Course creators can create new courses.'; $string['coursedeleted'] = 'Deleted course {$a}'; -$string['courseenrolend'] = 'Course enrolment end'; -$string['courseenrolenddate'] = 'Course enrolment end date'; -$string['courseenrolstart'] = 'Course enrolment start'; -$string['courseenrolstartdate'] = 'Course enrolment start'; $string['coursefiles'] = 'Course files'; $string['courseformatdata'] = 'Course format data'; $string['courseformats'] = 'Course formats'; $string['coursegrades'] = 'Course grades'; $string['coursehelpcategory'] = 'Position the course on the course listing and may make it easier for students to find it.'; -$string['coursehelpenrollable'] = 'Are students able to enrol themselves using the default interactive enrolment plugin'; -$string['coursehelpenrolmentkey'] = 'If set, users will need this key to be enrolled into the course.'; -$string['coursehelpenrolmentplugins'] = 'Default interactive enrolment plugin.'; -$string['coursehelpexpirynotifystudents'] = 'If an enrolment duration has been specified, then this setting determines whether students receive email notification when they are about to be unenrolled from the course.'; -$string['coursehelpexpirythreshold'] = 'If an enrolment duration has been specified, then this setting detemines the number of days notice given before students are unenrolled from the course.'; $string['coursehelpforce'] = 'Force the course group mode to every activity in the course.'; $string['coursehelpformat'] = 'The course main page will be displayed in this format.'; $string['coursehelphiddensections'] = 'How the hidden sections in the course are displayed to students.'; $string['coursehelpmaximumupload'] = 'Define the largest size of file that can be uploaded in this course, limited by the site-wide setting.'; -$string['coursehelpmetacourse'] = 'Set the course a metacourse. A meta course takes enrolments (and other role assignments) from a "child" course or courses.'; $string['coursehelpnewsitemsnumber'] = 'Number of recent items appearing on the course home page, in a news box down the right-hand side
(0 means the news box won\'t appear).'; -$string['coursehelpnotify'] = 'If an enrolment duration has been specified, then this setting determines whether teachers receive email notification when a student is about to be unenrolled from the course.'; $string['coursehelpnumberweeks'] = 'Number of weeks/topics displayed on the course main page.'; $string['coursehelpshowgrades'] = 'Enable the display of the gradebook. It does not prevent grades from being displayed within the individual activities.'; $string['coursehidden'] = 'This course is currently unavailable to students'; @@ -370,7 +358,6 @@ $string['creatinggroups'] = 'Creating groups'; $string['creatinglogentries'] = 'Creating log entries'; $string['creatingmessagesinfo'] = 'Creating messages info'; -$string['creatingmetacoursedata'] = 'Creating metacourse info'; $string['creatingmodroles'] = 'Creating module level role assignments and overrides'; $string['creatingnewcourse'] = 'Creating new course'; $string['creatingrolesdefinitions'] = 'Creating roles definitions'; @@ -612,10 +599,7 @@ $string['enable'] = 'Enable'; $string['encryptedcode'] = 'Encrypted code'; $string['english'] = 'English'; -$string['enroldate'] = 'Date range'; $string['enroldetails'] = 'Enrolment details'; -$string['enrolenddate'] = 'End date'; -$string['enrolenddaterror'] = 'Enrolment end date cannot be earlier than start date'; $string['enrollable'] = 'Course enrollable'; $string['enrolledincourse'] = 'Enrolled in course "{$a}"'; $string['enrolledincoursenot'] = 'Not enrolled in course "{$a}"'; @@ -630,17 +614,11 @@ password that you should have received from {$a}'; $string['enrolmentkeyfromguest'] = 'This course requires an \'enrolment key\' - as a guest
you must enter it each time you enter the course. You should have received it from {$a}'; -$string['enrolmentkeyhint'] = 'That enrolment key was incorrect, please try again
-(Here\'s a hint - it starts with \'{$a}\')'; $string['enrolmentnew'] = 'New enrolment in {$a}'; $string['enrolmentnewuser'] = '{$a->user} has enrolled in course "{$a->course}"'; -$string['enrolmentnointernal'] = 'Manual enrolments are currently not enabled'; $string['enrolmentnotyet'] = 'Sorry, you can not access this course until
{$a}'; -$string['enrolmentplugins'] = 'Enrolment Plugins'; $string['enrolments'] = 'Enrolments'; -$string['enrolmentstart'] = 'Enrolment Started'; $string['enrolperiod'] = 'Enrolment duration'; -$string['enrolstartdate'] = 'Start date'; $string['entercourse'] = 'Click to enter this course'; $string['enteremail'] = 'Enter your email address'; $string['enteremailaddress'] = 'Enter in your email address to reset your @@ -882,7 +860,6 @@ $string['chooseauthmethod'] = 'Choose authentication plugin'; $string['choosecourse'] = 'Choose a course'; $string['choosedots'] = 'Choose...'; -$string['chooseenrolmethod'] = 'Choose enrolment plugin'; $string['chooselivelogs'] = 'Or watch current activity'; $string['chooselogs'] = 'Choose which logs you want to see'; $string['choosereportfilter'] = 'Choose a filter for the report'; @@ -901,7 +878,6 @@ $string['importdatafinished'] = 'Import complete! Continue to your course'; $string['importdatafrom'] = 'Find a course to import data from:'; $string['importgroups'] = 'Import groups'; -$string['importmetacoursenote'] = 'Use this form to add courses to your meta course (this will import the enrolments)'; $string['inactive'] = 'Inactive'; $string['include'] = 'Include'; $string['includeallusers'] = 'Include All Users'; @@ -1007,9 +983,6 @@ $string['managedatabase'] = 'Database'; $string['manageeditorfiles'] = 'Manage files used by editor'; $string['managefilters'] = 'Filters'; -$string['managemeta'] = 'Is this a meta course?'; -$string['managemetadisabled'] = 'This is disabled because this course is already in a meta course'; -$string['managemetaexplan'] = '(This means that enrolments are inherited from other courses)'; $string['managemodules'] = 'Modules'; $string['manageroles'] = 'Roles and permissions'; $string['markedthistopic'] = 'This topic is highlighted as the current topic'; @@ -1029,17 +1002,6 @@ $string['messageprovider:notices'] = 'Notices about minor problems'; $string['messageselect'] = 'Select this user as an email recipient'; $string['messageselectadd'] = 'Add / send message'; -$string['metaaddcourse'] = 'Add this course'; -$string['metaalreadycourses'] = 'Courses already assigned'; -$string['metaalreadyhascourses'] = 'This meta course already has child courses.'; -$string['metaalreadyhasenrolments'] = 'This course already has normal enrolments.'; -$string['metaalreadyinmeta'] = 'This course is already part of a meta course.'; -$string['metaassigncourses'] = 'Assign courses'; -$string['metacourse'] = 'Metacourse'; -$string['metanoalreadycourses'] = 'No courses already assigned'; -$string['metanopotentialcourses'] = 'No courses available'; -$string['metapotentialcourses'] = 'Courses available'; -$string['metaremovecourse'] = 'Remove this course'; $string['migratinggrades'] = 'Migrating grades'; $string['min'] = 'min'; $string['mins'] = 'mins'; @@ -1211,7 +1173,6 @@ $string['nosuchemail'] = 'No such email address'; $string['notavailable'] = 'Not available'; $string['noteachersyet'] = 'No teachers in this course yet'; -$string['notenrollable'] = 'This course is not enrollable at the moment.'; $string['notenrolled'] = '{$a} is not enrolled in this course.'; $string['notenrolledprofile'] = 'This profile is not available because this user is not enrolled in this course.'; $string['noteusercannotrolldatesoncontext'] = 'Note: The ability to roll dates when restoring this backup has been disabled because you lack the required permissions.'; @@ -1260,7 +1221,6 @@ $string['pageshouldredirect'] = 'This page should automatically redirect. If nothing is happening please use the continue link below.'; $string['parentcategory'] = 'Parent category'; $string['parentcoursenotfound'] = 'Parent course not found!'; -$string['parentcoursenotmetacourse'] = 'Parent course not metacourse!'; $string['parentfolder'] = 'Parent folder'; $string['participants'] = 'Participants'; $string['participantslist'] = 'Participants list'; Index: user/lib.php =================================================================== --- user/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ user/lib.php (revision ) @@ -99,7 +99,7 @@ $DB->delete_records('groups_members', array('userid'=>$user->id)); // unenrol from all roles in all contexts - role_unassign(0, $user->id); // this might be slow but it is really needed - modules might do some extra cleanup! + role_unassign_all(array('userid'=>$user->id)); // this might be slow but it is really needed - modules might do some extra cleanup! // now do a final accesslib cleanup - removes all role assingments in user context and context itself delete_context(CONTEXT_USER, $user->id); Index: mod/forum/post.php =================================================================== --- mod/forum/post.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ mod/forum/post.php (revision ) @@ -111,7 +111,7 @@ if (!is_enrolled($coursecontext)) { $SESSION->wantsurl = $FULLME; $SESSION->enrolcancel = $_SERVER['HTTP_REFERER']; - redirect($CFG->wwwroot.'/course/enrol.php?id='.$course->id, get_string('youneedtoenrol')); + redirect($CFG->wwwroot.'/enrol/index.php?id='.$course->id, get_string('youneedtoenrol')); } } print_error('nopostforum', 'forum'); @@ -178,7 +178,7 @@ if (!is_enrolled($coursecontext)) { // User is a guest here! $SESSION->wantsurl = $FULLME; $SESSION->enrolcancel = $_SERVER['HTTP_REFERER']; - redirect($CFG->wwwroot.'/course/enrol.php?id='.$course->id, get_string('youneedtoenrol')); + redirect($CFG->wwwroot.'/enrol/index.php?id='.$course->id, get_string('youneedtoenrol')); } } print_error('nopostforum', 'forum'); Index: enrol/self/confirm.php =================================================================== --- enrol/self/confirm.php (revision ) +++ enrol/self/confirm.php (revision ) @@ -0,0 +1,0 @@ Index: enrol/authorize/uploadcsv.php =================================================================== --- enrol/authorize/uploadcsv.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/authorize/uploadcsv.php (revision ) @@ -210,7 +210,8 @@ $timestart = time(); $timeend = $timestart + $course->enrolperiod; } - if (role_assign($role->id, $user->id, 0, $coursecontext->id, $timestart, $timeend, 0, 'authorize')) { + //TODO: do some real enrolment here + if (role_assign($role->id, $user->id, $coursecontext->id, 'enrol_authorize')) { $imported++; if (!empty($CFG->enrol_mailstudents)) { $sendem[] = $order->id; Index: admin/enrol_config.php =================================================================== --- admin/enrol_config.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/enrol_config.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,70 +0,0 @@ -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 ""; - echo "
"; - echo ""; - echo ""; - -/// 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 "
"; - - $enrolment->config_form($frm); - - echo "

\n"; - echo $OUTPUT->box_end(); - echo "
"; - echo ""; - - echo $OUTPUT->footer(); - - exit; - Index: admin/enrol.php =================================================================== --- admin/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/enrol.php (revision ) @@ -1,141 +1,120 @@ . +/** + * 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'); +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); +$action = required_param('action', PARAM_ACTION); +$enrol = required_param('enrol', PARAM_SAFEDIR); +$confirm = optional_param('confirm', 0, PARAM_BOOL); - admin_externalpage_setup('enrolment'); +$PAGE->set_url('/admin/enrol.php'); - if (!isset($CFG->sendcoursewelcomemessage)) { - set_config('sendcoursewelcomemessage', 1); - } +require_login(); +require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)); +require_sesskey(); +$enabled = enrol_get_plugins(true); +$all = enrol_get_plugins(false); - require_once("$CFG->dirroot/enrol/enrol.class.php"); /// Open the factory class +$return = new moodle_url('/admin/settings.php', array('section'=>'manageenrols')); -/// Save settings +switch ($action) { + case 'disable': + unset($enabled[$enrol]); + set_config('enrol_plugins_enabled', implode(',', array_keys($enabled))); + break; - if ($frm = data_submitted() and !$savesettings) { - if (!confirm_sesskey()) { - print_error('confirmsesskeybad', 'error'); + 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 = ''; + $enabled = array_keys($enabled); + $enabled = array_flip($enabled); + $current = $enabled[$enrol]; + if ($current == 0) { + break; //already at the top } - 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); + $enabled = array_flip($enabled); + $enabled[$current] = $enabled[$current - 1]; + $enabled[$current - 1] = $enrol; + set_config('enrol_plugins_enabled', implode(',', $enabled)); + break; - } else if ($frm = data_submitted() and $savesettings) { - if (!confirm_sesskey()) { - print_error('confirmsesskeybad', 'error'); + case 'down': + if (!isset($enabled[$enrol])) { + break; } - set_config('sendcoursewelcomemessage', required_param('sendcoursewelcomemessage', PARAM_BOOL)); + $enabled = array_keys($enabled); + $enabled = array_flip($enabled); + $current = $enabled[$enrol]; + if ($current == count($enabled) - 1) { + break; //already at the end - } + } + $enabled = array_flip($enabled); + $enabled[$current] = $enabled[$current + 1]; + $enabled[$current + 1] = $enrol; + set_config('enrol_plugins_enabled', implode(',', $enabled)); + break; -/// Print the form - - $str = get_strings(array('enrolmentplugins', 'users', 'administration', 'settings', 'edit')); - + case 'uninstall': - echo $OUTPUT->header(); + echo $OUTPUT->header(); + echo $OUTPUT->heading(get_string('enrolments')); - $modules = get_plugin_list('enrol'); - $options = array(); - foreach ($modules as $module => $moduledir) { - $options[$module] = get_string("enrolname", "enrol_$module"); + if (get_string_manager()->string_exists('pluginname', 'enrol_'.$enrol)) { + $strplugin = get_string('pluginname', 'enrol_'.$enrol); + } else { + $strplugin = $enrol; - } + } - asort($options); - echo $OUTPUT->box(get_string('configenrolmentplugins', 'admin')); + 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; - echo "
"; - echo "
"; - echo ""; + } else { // Delete everything!! + uninstall_plugin('enrol', $enrol); - $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; + $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; } - - $name = get_string("enrolname", "enrol_$module"); - $plugin = enrolment_factory::factory($module); - $enable = 'enrol == $module) { - $default .= ' checked="checked"'; - } - $default .= ' />'; - } else { - $default = ''; - } - $table->data[$name] = array($name, $enable, $default, - ''.$str->edit.''); - } - asort($table->data); - echo html_writer::table($table); - echo "
\n"; - echo "
"; - echo "
"; - - echo '
'; - - $yesnooptions = array(0=>get_string('no'), 1=>get_string('yes')); - - echo '
'; - echo '
'; - echo $OUTPUT->heading(get_string('commonsettings', 'admin')); - echo ''; - echo ''; - echo '
'; - echo '
'; - - echo '
'; - echo '
'; - echo html_writer::select($yesnooptions, 'sendcoursewelcomemessage', $CFG->sendcoursewelcomemessage, false); - echo '
'.get_string('defaultsettinginfo', 'admin', get_string('yes')).'
'; - echo '
' . get_string('configsendcoursewelcomemessage', 'admin') . '
'; - echo '
'; - - echo '
'; - - echo '
'; - echo '
'; - echo '
'; - - echo $OUTPUT->footer(); - - +redirect($return); \ No newline at end of file Index: lib/setuplib.php =================================================================== --- lib/setuplib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/setuplib.php (revision ) @@ -92,6 +92,17 @@ } /** + * Course/activity access exception. + * + * This exception is thrown from require_login() + */ +class require_login_exception extends moodle_exception { + function __construct($debuginfo) { + parent::__construct('requireloginerror', 'error', '', NULL, $debuginfo); + } +} + +/** * Web service parameter exception class * * This exception must be thrown to the web service client when a web service parameter is invalid Index: enrol/unenrol.php =================================================================== --- enrol/unenrol.php (revision ) +++ enrol/unenrol.php (revision ) @@ -0,0 +1,49 @@ +. + +/** + * This page shows unenrolment options for current user. + * + * @package core + * @subpackage course + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require('../config.php'); + +$id = required_param('id', PARAM_INT); +$unrol = optional_param('instance', 0, PARAM_INT); + +$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST); +$context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); + +require_login($course); + +$PAGE->set_url('/enrol/unenrol.php', array('id'=>$course->id)); + +// Everybody is enrolled on the frontpage +if ($course->id == SITEID) { + redirect("$CFG->wwwroot/"); +} + +// do not use when in course level login-as, but still allow enrols in full login-as +if (session_is_loggedinas() and $USER->loginascontext->contextlevel == CONTEXT_COURSE) { + redirect($CFG->wwwroot.'/course/view.php?id='.$id); +} + +die('TODO: reimplement unenrol support'); \ No newline at end of file Index: enrol/manual/config.html =================================================================== --- enrol/manual/config.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/manual/config.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
enrol_manual_keyholderrole: - $role) { - $rolenames[$id]=$role->name; - } - echo html_writer::select($rolenames, 'enrol_manual_keyholderrole', $frm->enrol_manual_keyholderrole); - ?> - - -
enrol_manual_showhint: -enrol_manual_showhint, false); -?> - - -
enrol_manual_usepasswordpolicy: -enrol_manual_usepasswordpolicy, false); -?> - - -
enrol_manual_requirekey: -enrol_manual_requirekey, false); -?> - - -
Index: course/importstudents.html =================================================================== --- course/importstudents.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/importstudents.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,80 +0,0 @@ - -
- - - - - - - - - -
- -
-
-

- -
- -

-
- -
- -
- - - - '."\n"; - } - ?> -
-
- - Index: lib/db/install.xml =================================================================== --- lib/db/install.xml (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/db/install.xml (revision ) @@ -80,11 +80,9 @@ - - - - - + + + @@ -94,23 +92,12 @@ - - - - - - - - - - - - - - - - - + + + + + + @@ -236,7 +223,7 @@ - +
@@ -250,22 +237,65 @@
- +
- - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - - +
- +
+ + + + + + + + + + + + + + + +
+ + @@ -1049,29 +1079,27 @@
- +
- - - - - - - - + + + + + + - + + - - +
@@ -2273,7 +2301,7 @@
- +
@@ -2284,8 +2312,36 @@
- +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + Index: lib/accesslib.php =================================================================== --- lib/accesslib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/accesslib.php (revision ) @@ -700,19 +700,19 @@ /** * Returns true if user has at least one role assign - * of 'coursemanager' role (is potentially listed in some course descriptions). + * of 'coursecontact' role (is potentially listed in some course descriptions). * @param $userid * @return unknown_type */ -function has_coursemanager_role($userid) { +function has_coursecontact_role($userid) { global $DB; - if (empty($CFG->coursemanager)) { + if (empty($CFG->coursecontact)) { return false; } $sql = "SELECT 1 FROM {role_assignments} - WHERE userid = :userid AND roleid IN ($CFG->coursemanager)"; + WHERE userid = :userid AND roleid IN ($CFG->coursecontact)"; return $DB->record_exists($sql, array('userid'=>$userid)); } @@ -920,213 +920,28 @@ /** * Get an array of courses where cap requested is available + * and user is enrolled, this can be relatively slow. * - * Get an array of courses (with magic extra bits) - * where the accessdata and in DB enrolments show - * that the cap requested is available. - * - * The main use is for get_my_courses(). - * - * Notes - * - * - $fields is an array of fieldnames to ADD - * so name the fields you really need, which will - * be added and uniq'd - * - * - the course records have $c->context which is a fully - * valid context object. Saves you a query per course! - * - * - the course records have $c->categorypath to make - * category lookups cheap - * - * - current implementation is split in - - * - * - if the user has the cap systemwide, stupidly - * grab *every* course for a capcheck. This eats - * a TON of bandwidth, specially on large sites - * with separate DBs... - * - * - otherwise, fetch "likely" courses with a wide net - * that should get us _cheaply_ at least the courses we need, and some - * we won't - we get courses that... - * - are in a category where user has the cap - * - or where use has a role-assignment (any kind) - * - or where the course has an override on for this cap - * - * - walk the courses recordset checking the caps oneach one - * the checks are all in memory and quite fast - * (though we could implement a specialised variant of the - * has_capability_in_accessdata() code to speed it up) - * - * @global object - * @global object * @param string $capability - name of the capability - * @param array $accessdata - accessdata session array - * @param bool $doanything_ignored - admin roles are completely ignored here + * @param array $accessdata_ignored + * @param bool $doanything_ignored * @param string $sort - sorting fields - prefix each fieldname with "c." * @param array $fields - additional fields you are interested in... - * @param int $limit - set if you want to limit the number of courses + * @param int $limit_ignored * @return array $courses - ordered array of course objects - see notes above */ -function get_user_courses_bycap($userid, $cap, $accessdata, $doanything_ignored, $sort='c.sortorder ASC', $fields=NULL, $limit=0) { +function get_user_courses_bycap($userid, $cap, $accessdata_ignored, $doanything_ignored, $sort='c.sortorder ASC', $fields=NULL, $limit_ignored=0) { - global $CFG, $DB; + //TODO: this shoudl be most probably deprecated - // Slim base fields, let callers ask for what they need... - $basefields = array('id', 'sortorder', 'shortname', 'idnumber'); - - if (!is_null($fields)) { - $fields = array_merge($basefields, $fields); - $fields = array_unique($fields); - } else { - $fields = $basefields; + $courses = enrol_get_users_courses($userid, true, $fields, $sort); + foreach ($courses as $id=>$course) { + $context = get_context_instance(CONTEXT_COURSE, $id); + if (!has_capability($cap, $context, $userid)) { + unset($courses[$id]); - } + } - // If any of the fields is '*', leave it alone, discarding the rest - // to avoid ambiguous columns under some silly DBs. See MDL-18746 :-D - if (in_array('*', $fields)) { - $fields = array('*'); } - $coursefields = 'c.' .implode(',c.', $fields); - $sort = trim($sort); - if ($sort !== '') { - $sort = "ORDER BY $sort"; - } - - $sysctx = get_context_instance(CONTEXT_SYSTEM); - if (has_capability_in_accessdata($cap, $sysctx, $accessdata)) { - // - // Apparently the user has the cap sitewide, so walk *every* course - // (the cap checks are moderately fast, but this moves massive bandwidth w the db) - // Yuck. - // - $sql = "SELECT $coursefields, - ctx.id AS ctxid, ctx.path AS ctxpath, - ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel, - cc.path AS categorypath - FROM {course} c - JOIN {course_categories} cc - ON c.category=cc.id - JOIN {context} ctx - ON (c.id=ctx.instanceid AND ctx.contextlevel=".CONTEXT_COURSE.") - $sort "; - $rs = $DB->get_recordset_sql($sql); - } else { - // - // narrow down where we have the caps to a few contexts - // this will be a combination of - // - courses where user has an explicit enrolment - // - courses that have an override (any status) on that capability - // - categories where user has the rights (granted status) on that capability - // - $sql = "SELECT ctx.* - FROM {context} ctx - WHERE ctx.contextlevel=".CONTEXT_COURSECAT." - ORDER BY ctx.depth"; - $rs = $DB->get_recordset_sql($sql); - $catpaths = array(); - foreach ($rs as $catctx) { - if ($catctx->path != '' - && has_capability_in_accessdata($cap, $catctx, $accessdata)) { - $catpaths[] = $catctx->path; - } - } - $rs->close(); - $catclause = ''; - $params = array(); - if (count($catpaths)) { - $cc = count($catpaths); - for ($n=0;$n<$cc;$n++) { - $catpaths[$n] = "ctx.path LIKE '{$catpaths[$n]}/%'"; - } - $catclause = 'WHERE (' . implode(' OR ', $catpaths) .')'; - } - unset($catpaths); - - /// UNION 3 queries: - /// - user role assignments in courses - /// - user capability (override - any status) in courses - /// - user right (granted status) in categories (optionally executed) - /// Enclosing the 3-UNION into an inline_view to avoid column names conflict and making the ORDER BY cross-db - /// and to allow selection of TEXT columns in the query (MSSQL and Oracle limitation). MDL-16209 - $sql = " - SELECT $coursefields, ctxid, ctxpath, ctxdepth, ctxlevel, ctxinstance, categorypath - FROM ( - SELECT c.id, - ctx.id AS ctxid, ctx.path AS ctxpath, - ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel, ctx.instanceid AS ctxinstance, - cc.path AS categorypath - FROM {course} c - JOIN {course_categories} cc - ON c.category=cc.id - JOIN {context} ctx - ON (c.id=ctx.instanceid AND ctx.contextlevel=".CONTEXT_COURSE.") - JOIN {role_assignments} ra - ON (ra.contextid=ctx.id AND ra.userid=:userid) - UNION - SELECT c.id, - ctx.id AS ctxid, ctx.path AS ctxpath, - ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel, ctx.instanceid AS ctxinstance, - cc.path AS categorypath - FROM {course} c - JOIN {course_categories} cc - ON c.category=cc.id - JOIN {context} ctx - ON (c.id=ctx.instanceid AND ctx.contextlevel=".CONTEXT_COURSE.") - JOIN {role_capabilities} rc - ON (rc.contextid=ctx.id AND (rc.capability=:cap)) "; - - if (!empty($catclause)) { /// If we have found the right in categories, add child courses here too - $sql .= " - UNION - SELECT c.id, - ctx.id AS ctxid, ctx.path AS ctxpath, - ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel, ctx.instanceid AS ctxinstance, - cc.path AS categorypath - FROM {course} c - JOIN {course_categories} cc - ON c.category=cc.id - JOIN {context} ctx - ON (c.id=ctx.instanceid AND ctx.contextlevel=".CONTEXT_COURSE.") - $catclause"; - } - - /// Close the inline_view and join with courses table to get requested $coursefields - $sql .= " - ) inline_view - INNER JOIN {course} c - ON inline_view.id = c.id"; - - /// To keep cross-db we need to strip any prefix in the ORDER BY clause for queries using UNION - $sql .= " - " . preg_replace('/[a-z]+\./i', '', $sort); /// Add ORDER BY clause - - $params['userid'] = $userid; - $params['cap'] = $cap; - $rs = $DB->get_recordset_sql($sql, $params); - } - -/// Confirm rights (granted capability) for each course returned - $courses = array(); - $cc = 0; // keep count - if ($rs) { - foreach ($rs as $c) { - // build the context obj - context_instance_preload($c); - $context = get_context_instance(CONTEXT_COURSE, $c->id); - - if (has_capability_in_accessdata($cap, $context, $accessdata)) { - if ($limit > 0 && $cc >= $limit) { - break; - } - - $courses[] = $c; - $cc++; - } - } - $rs->close(); - } - return $courses; } @@ -1134,7 +949,7 @@ /** * Return a nested array showing role assignments * all relevant role capabilities for the user at - * site/metacourse/course_category/course levels + * site/course_category/course levels * * We do _not_ delve deeper than courses because the number of * overrides at the module/block levels is HUGE. @@ -1679,15 +1494,12 @@ * * Note - assumes a course context! * - * @global object - * @global object * @param object $content * @param int $roleid * @param array $accessdata * @return array Returns access data */ -function load_temp_role($context, $roleid, $accessdata) { - +function load_temp_role($context, $roleid, array $accessdata) { global $CFG, $DB; // @@ -1738,59 +1550,23 @@ return $accessdata; } - /** - * Check all the login enrolment information for the given user object - * by querying the enrolment plugins - * - * @global object - * @param object $user - * @return void + * Removes any extra guest roels from accessdata + * @param object $context + * @param array $accessdata + * @return array access data */ -function check_enrolment_plugins(&$user) { - global $CFG; +function remove_temp_roles($context, array $accessdata) { + global $DB, $USER; + $sql = "SELECT DISTINCT ra.roleid AS id + FROM {role_assignments} ra + WHERE ra.contextid = :contextid AND ra.userid = :userid"; + $ras = $DB->get_records_sql($sql, array('contextid'=>$context->id, 'userid'=>$USER->id)); - if (empty($user->id) or isguestuser($user)) { - // shortcut - there is no enrolment work for guests and not-logged-in users - return; + $accessdata['ra'][$context->path] = array_keys($ras); + return $accessdata; - } +} - static $inprogress = array(); // To prevent this function being called more than once in an invocation - - if (!empty($inprogress[$user->id])) { - return; - } - - $inprogress[$user->id] = true; // Set the flag - - require_once($CFG->dirroot .'/enrol/enrol.class.php'); - - if (!($plugins = explode(',', $CFG->enrol_plugins_enabled))) { - $plugins = array($CFG->enrol); - } - - foreach ($plugins as $plugin) { - $enrol = enrolment_factory::factory($plugin); - if (method_exists($enrol, 'setup_enrolments')) { /// Plugin supports Roles (Moodle 1.7 and later) - $enrol->setup_enrolments($user); - } else { /// Run legacy enrolment methods - if (method_exists($enrol, 'get_student_courses')) { - $enrol->get_student_courses($user); - } - if (method_exists($enrol, 'get_teacher_courses')) { - $enrol->get_teacher_courses($user); - } - - /// deal with $user->students and $user->teachers stuff - unset($user->student); - unset($user->teacher); - } - unset($enrol); - } - - unset($inprogress[$user->id]); // Unset the flag -} - /** * Returns array of all role archetypes. * @@ -2536,7 +2312,7 @@ global $CFG, $DB; // first unssign all users - role_unassign($roleid); + role_unassign_all(array('roleid'=>$roleid)); // cleanup all references to this role, ignore errors $DB->delete_records('role_capabilities', array('roleid'=>$roleid)); @@ -2672,260 +2448,217 @@ /** - * This function makes a role-assignment (a role for a user or group in a particular context) + * This function makes a role-assignment (a role for a user in a particular context) * * @param int $roleid the role of the id * @param int $userid userid - * @param int $groupid_ignored - never implemented! * @param int $contextid id of the context - * @param int $timestart time this assignment becomes effective defaults to 0 - * @param int $timeend time this assignemnt ceases to be effective defaults to 0 - * @param int $hidden_ignored - use roels with moodle/course:view capability or enrolemnt instead - * @param string $enrol defaults to 'manual' - * @param string $timemodified defaults to '' - * @return int new id of the assigment + * @param string $component example 'enrol_ldap', defaults to '' which means manual assignment, + * @prama int $enrolid id of enrolment plugin + * @param string $timemodified defaults to current time + * @return int new/existing id of the assignment */ -function role_assign($roleid, $userid, $groupid_ignored, $contextid, $timestart=0, $timeend=0, $hidden_ignored=0, $enrol='manual',$timemodified='') { +function role_assign($roleid, $userid, $contextid, $component = '', $enrolid = NULL, $timemodified = '') { global $USER, $CFG, $DB; -/// Do some data validation + // first of all detect if somebody is using old style parameters + if ($contextid === 0 or is_numeric($component)) { + throw new coding_exception('Invalid call to role_assign(), code needs to be updated to use new order of parameters'); + } + // now validate all parameters if (empty($roleid)) { - debugging('Role ID not provided'); - return false; + throw new coding_exception('Invalid call to role_assign(), roleid can not be empty'); } if (empty($userid)) { - debugging('Userid or groupid must be provided'); - return false; + throw new coding_exception('Invalid call to role_assign(), userid can not be empty'); } - if ($userid && !$DB->record_exists('user', array('id'=>$userid))) { - debugging('User ID '.intval($userid).' does not exist!'); - return false; + if ($enrolid) { + if (strpos($component, 'enrol_') !== 0) { + throw new coding_exception('Invalid call to role_assign(), component must start with "enrol_" when enrolid specified', 'component:'.$component); - } + } + } else { + $enrolid = NULL; + } - if (!$context = get_context_instance_by_id($contextid)) { - debugging('Context ID '.intval($contextid).' does not exist!'); - return false; + if ($component !== '' and strpos($component, '_') === false) { + throw new coding_exception('Invalid call to role_assign(), invalid component string', 'component:'.$component); } - if (($timestart and $timeend) and ($timestart > $timeend)) { - debugging('The end time can not be earlier than the start time'); + if (!$DB->record_exists('user', array('id'=>$userid, 'deleted'=>0))) { + throw new coding_exception('User ID does not exist or is deleted!', 'userid:'.$userid); return false; } + $context = get_context_instance_by_id($contextid, MUST_EXIST); + if (!$timemodified) { $timemodified = time(); } /// Check for existing entry - $ra = $DB->get_record('role_assignments', array('roleid'=>$roleid, 'contextid'=>$context->id, 'userid'=>$userid)); + $ras = $DB->get_records('role_assignments', array('roleid'=>$roleid, 'contextid'=>$context->id, 'userid'=>$userid, 'component'=>$component, 'enrolid'=>$enrolid), 'id'); - if (empty($ra)) { // Create a new entry + if ($ras) { + // role already assigned - this should not happen + if (count($ras) > 1) { + //very weird - remove all duplicates! + $ra = array_shift($ras); + foreach ($ras as $r) { + $DB->delete_records('role_assignments', array('id'=>$r->id)); + } + } else { + $ra = reset($ras); + } + + // actually there is no need to update, reset anything or trigger any event, so just return + return $ra->id; + } + + // Create a new entry - $ra = new object(); + $ra = new object(); - $ra->roleid = $roleid; + $ra->roleid = $roleid; - $ra->contextid = $context->id; + $ra->contextid = $context->id; - $ra->userid = $userid; + $ra->userid = $userid; - $ra->enrol = $enrol; - /// Always round timestart downto 100 secs to help DBs to use their own caching algorithms - /// by repeating queries with the same exact parameters in a 100 secs time window - $ra->timestart = round($timestart, -2); - $ra->timeend = $timeend; + $ra->component = $component; + $ra->enrolid = $enrolid; - $ra->timemodified = $timemodified; + $ra->timemodified = $timemodified; - $ra->modifierid = empty($USER->id) ? 0 : $USER->id; + $ra->modifierid = empty($USER->id) ? 0 : $USER->id; - $ra->id = $DB->insert_record('role_assignments', $ra); + $ra->id = $DB->insert_record('role_assignments', $ra); - } else { // We already have one, just update it - $ra->id = $ra->id; - $ra->enrol = $enrol; - /// Always round timestart downto 100 secs to help DBs to use their own caching algorithms - /// by repeating queries with the same exact parameters in a 100 secs time window - $ra->timestart = round($timestart, -2); - $ra->timeend = $timeend; - $ra->timemodified = $timemodified; - $ra->modifierid = empty($USER->id) ? 0 : $USER->id; - - $DB->update_record('role_assignments', $ra); - } - -/// mark context as dirty - modules might use has_capability() in xxx_role_assing() -/// again expensive, but needed + // mark context as dirty - again expensive, but needed mark_context_dirty($context->path); if (!empty($USER->id) && $USER->id == $userid) { -/// If the user is the current user, then do full reload of capabilities too. + // If the user is the current user, then do full reload of capabilities too. load_all_capabilities(); } -/// Ask all the modules if anything needs to be done for this user - $mods = get_plugin_list('mod'); - foreach ($mods as $mod => $moddir) { - include_once($moddir.'/lib.php'); - $functionname = $mod.'_role_assign'; - if (function_exists($functionname)) { - $functionname($userid, $context, $roleid); - } - } - - /// now handle metacourse role assignments if in course context - if ($context->contextlevel == CONTEXT_COURSE) { - if ($parents = $DB->get_records('course_meta', array('child_course'=>$context->instanceid))) { - foreach ($parents as $parent) { - sync_metacourse($parent->parent_course); - } - } - } - events_trigger('role_assigned', $ra); return $ra->id; } - /** - * Deletes one or more role assignments. You must specify at least one parameter. + * Removes one role assignment * - * @global object - * @global object - * @global object - * @param int $roleid defaults to 0 - * @param int $userid defaults to 0 - * @param int $groupid_ignored never implemented - * @param int $contextid defaults to 0 - * @param mixed $enrol unassign only if enrolment type matches, NULL means anything. Defaults to NULL - * @return boolean success or failure + * @param int $roleid + * @param int $userid + * @param int $contextid + * @param string $component + * @param int $enrolid + * @return void */ -function role_unassign($roleid=0, $userid=0, $groupid_ignored=0, $contextid=0, $enrol=NULL) { - +function role_unassign($roleid, $userid, $contextid, $component = '', $enrolid = NULL) { global $USER, $CFG, $DB; - require_once($CFG->dirroot.'/group/lib.php'); - $args = array('roleid', 'userid', 'groupid', 'contextid'); - $select = array(); - $params = array(); + // first make sure the params make sense + if ($roleid == 0 or $userid == 0 or $contextid == 0) { + throw new coding_exception('Invalid call to role_unassign(), please use role_unassign_all() when removing multiple role assignments'); + } - foreach ($args as $arg) { - if ($$arg) { - $select[] = "$arg = ?"; - $params[] = $$arg; + if ($enrolid) { + if (strpos($component, 'enrol_') !== 0) { + throw new coding_exception('Invalid call to role_assign(), component must start with "enrol_" when enrolid specified', 'component:'.$component); } + } else { + $enrolid = NULL; } - if (!empty($enrol)) { - $select[] = "enrol=?"; - $params[] = $enrol; - } - if ($select) { - if ($ras = $DB->get_records_select('role_assignments', implode(' AND ', $select), $params)) { - $mods = get_plugin_list('mod'); - foreach($ras as $ra) { - /// infinite loop protection when deleting recursively - if (!$ra = $DB->get_record('role_assignments', array('id'=>$ra->id))) { - continue; + if ($component !== '' and strpos($component, '_') === false) { + throw new coding_exception('Invalid call to role_assign(), invalid component string', 'component:'.$component); - } + } - $DB->delete_records('role_assignments', array('id'=>$ra->id)); - if (!$context = get_context_instance_by_id($ra->contextid)) { - // strange error, not much to do - continue; + role_unassign_all(array('roleid'=>$roleid, 'userid'=>$userid, 'contextid'=>$contextid, 'component'=>$component, 'enrolid'=>$enrolid), false, false); - } +} - /* mark contexts as dirty here, because we need the refreshed - * caps bellow to delete group membership and user_lastaccess! - * and yes, this is very expensive for bulk operations :-( +/** + * Removes multiple role assignments, parameters may contain: + * 'roleid', 'userid', 'contextid', 'component', 'enrolid'. + * + * @param array $params role assignment parameters + * @param bool $subcontexts unassign in subcontexts too + * @param bool $includemanual include manual role assignments too + * @return void - */ + */ - mark_context_dirty($context->path); +function role_unassign_all(array $params, $subcontexts = false, $includemanual=false) { + global $USER, $CFG, $DB; - /// If the user is the current user, then do full reload of capabilities too. - if (!empty($USER->id) && $USER->id == $ra->userid) { - load_all_capabilities(); + if (!$params) { + throw new coding_exception('Missing parameters in role_unsassign_all() call'); - } + } - /// Ask all the modules if anything needs to be done for this user - foreach ($mods as $mod=>$moddir) { - include_once($moddir.'/lib.php'); - $functionname = $mod.'_role_unassign'; - if (function_exists($functionname)) { - $functionname($ra->userid, $context); // watch out, $context might be NULL if something goes wrong + $allowed = array('roleid', 'userid', 'contextid', 'component', 'enrolid'); + foreach ($params as $key=>$value) { + if (!in_array($key, $allowed)) { + throw new coding_exception('Unknown role_unsassign_all() parameter key', 'key:'.$key); - } - } + } + } - /// now handle metacourse role unassigment and removing from goups if in course context - if ($context->contextlevel == CONTEXT_COURSE) { - - // cleanup leftover course groups/subscriptions etc when user has - // no capability to view course - // this may be slow, but this is the proper way of doing it - if (!has_capability('moodle/course:participate', $context, $ra->userid)) { - // remove from groups - groups_delete_group_members($context->instanceid, $ra->userid); - - // delete lastaccess records - $DB->delete_records('user_lastaccess', array('userid'=>$ra->userid, 'courseid'=>$context->instanceid)); + if (isset($params['component']) and $params['component'] !== '' and strpos($params['component'], '_') === false) { + throw new coding_exception('Invalid component paramter in role_unsassign_all() call', 'component:'.$params['component']); - } + } - //unassign roles in metacourses if needed - if ($parents = $DB->get_records('course_meta', array('child_course'=>$context->instanceid))) { - foreach ($parents as $parent) { - sync_metacourse($parent->parent_course); + if ($includemanual) { + if (!isset($params['component']) or $params['component'] === '') { + throw new coding_exception('include manual parameter requires component parameter in role_unsassign_all() call'); - } - } + } + } - } - events_trigger('role_unassigned', $ra); + if ($subcontexts) { + if (empty($params['contextid'])) { + throw new coding_exception('subcontexts paramtere requires component parameter in role_unsassign_all() call'); - } - } + } + } - } - return true; -} + $context = -/** - * Enrol someone without using the default role in a course - * - * A convenience function to take care of the common case where you - * just want to enrol someone using the default role into a course - * - * @param object $course - * @param object $user - * @param string $enrol the plugin used to do this enrolment - * @return bool - */ -function enrol_into_course($course, $user, $enrol) { - - $timestart = time(); - // remove time part from the timestamp and keep only the date part - $timestart = make_timestamp(date('Y', $timestart), date('m', $timestart), date('d', $timestart), 0, 0, 0); - if ($course->enrolperiod) { - $timeend = $timestart + $course->enrolperiod; - } else { - $timeend = 0; + $ras = $DB->get_records('role_assignments', $params); + foreach($ras as $ra) { + $DB->delete_records('role_assignments', array('id'=>$ra->id)); + if ($context = get_context_instance_by_id($ra->contextid)) { + // this is a bit expensive but necessary + mark_context_dirty($context->path); + /// If the user is the current user, then do full reload of capabilities too. + if (!empty($USER->id) && $USER->id == $ra->userid) { + load_all_capabilities(); - } + } - - if ($role = get_default_course_role($course)) { - - $context = get_context_instance(CONTEXT_COURSE, $course->id); - - if (!role_assign($role->id, $user->id, 0, $context->id, $timestart, $timeend, 0, $enrol)) { - return false; } + events_trigger('role_unassigned', $ra); + } + unset($ras); - // force accessdata refresh for users visiting this context... + // process subcontexts + if ($subcontexts and $context = get_context_instance_by_id($params['contextid'])) { + $contexts = get_child_contexts($context); + $mparams = $params; + foreach($contexts as $context) { + $mparams['contextid'] = $context->id; + $ras = $DB->get_records('role_assignments', $mparams); + foreach($ras as $ra) { + $DB->delete_records('role_assignments', array('id'=>$ra->id)); + // this is a bit expensive but necessary - mark_context_dirty($context->path); + mark_context_dirty($context->path); - - email_welcome_message_to_user($course, $user); - - add_to_log($course->id, 'course', 'enrol', - 'view.php?id='.$course->id, $course->id); - - return true; + /// If the user is the current user, then do full reload of capabilities too. + if (!empty($USER->id) && $USER->id == $ra->userid) { + load_all_capabilities(); - } + } + events_trigger('role_unassigned', $ra); + } + } + } - return false; + // do this once more for all manual role assignments + if ($includemanual) { + $params['component'] = ''; + role_unassign_all($params, $subcontexts, false); -} + } +} + /** * Determines if a user is currently logged in * @@ -2940,7 +2673,7 @@ /** * Determines if a user is logged in as real guest user with username 'guest'. * - * @param int $user mixed user object or id, $USER if not specified + * @param int|object $user mixed user object or id, $USER if not specified * @return bool true if user is the real guest user, false if not logged in or other user */ function isguestuser($user = NULL) { @@ -3005,7 +2738,8 @@ return false; } - if (has_capability('moodle/course:participate', $coursecontext, $userid, false)) { + // consider only real active enrolments here + if (is_enrolled($coursecontext, $user, '', true)) { return false; } @@ -3051,12 +2785,13 @@ * this is intended for students and teachers. * * @param object $context - * @param int|object $user, if NULL $USER is used, oherwise user object or id expected + * @param int|object $user, if NULL $USER is used, otherwise user object or id expected * @param string $withcapability extra capability name + * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @return bool */ -function is_enrolled($context, $user = NULL, $withcapability = '') { - global $USER; +function is_enrolled($context, $user = NULL, $withcapability = '', $onlyactive = false) { + global $USER, $DB; // first find the course context $coursecontext = get_course_context($context); @@ -3076,11 +2811,49 @@ return false; } - if ($coursecontext->instanceid != SITEID and !has_capability('moodle/course:participate', $coursecontext, $userid, false)) { - // admins are not enrolled, everybody is "enrolled" in the frontpage course + if ($coursecontext->instanceid == SITEID) { + // everybody participates on frontpage + } else { + if ($onlyactive) { + $sql = "SELECT cp.* + FROM {course_participants} cp + JOIN {enrol} e ON (e.id = cp.enrolid AND e.courseid = :courseid) + JOIN {user} u ON u.id = cp.userid + WHERE cp.userid = :userid AND cp.status = :active AND e.status = :enabled AND u.deleted = 0"; + $params = array('enabled'=>ENROL_STATUS_ENABLED, 'active'=>ENROL_PARTICIPATION_ACTIVE, 'userid'=>$userid, 'courseid'=>$coursecontext->instanceid); + // this result should be very small, better not do the complex time checks in sql for now ;-) + $enrolments = $DB->get_records_sql($sql, $params); + $now = time(); + // make sure the enrol period is ok + $result = false; + foreach ($enrolments as $e) { + if ($e->timestart > $now) { + continue; + } + if ($e->timeend and $e->timeend < $now) { + continue; + } + $result = true; + break; + } + if (!$result) { - return false; - } + return false; + } + } else { + // any enrolment is good for us here, even outdated, disabled or inactive + $sql = "SELECT 'x' + FROM {course_participants} cp + JOIN {enrol} e ON (e.id = cp.enrolid AND e.courseid = :courseid) + JOIN {user} u ON u.id = cp.userid + WHERE cp.userid = :userid AND u.deleted = 0"; + $params = array('userid'=>$userid, 'courseid'=>$coursecontext->instanceid); + if (!$DB->record_exists_sql($sql, $params)) { + return false; + } + } + } + if ($withcapability and !has_capability($withcapability, $context, $userid)) { return false; } @@ -3091,145 +2864,89 @@ /** * Returns array with sql code and parameters returning all ids * of users enrolled into course. + * + * This function is using 'eu[0-9]+_' prefix for table names and parameters. + * * @param object $context * @param string $withcapability * @param int $groupid 0 means ignore groups, any other value limits the result by group id - * @param string $prefix used for alias of user table, parameter names and in aliases of other used tables + * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @return array list($sql, $params) */ -function get_enrolled_sql($context, $withcapability = '', $groupid = 0, $prefix = 'eu') { +function get_enrolled_sql($context, $withcapability = '', $groupid = 0, $onlyactive = false) { global $DB; - if ($context->contextlevel < CONTEXT_COURSE) { - throw new coding_exception('get_enrolled_sql() expects course context and bellow!'); - } + // use unique prefix just in case somebody makes some SQL magic with the result + static $i = 0; + $i++; + $prefix = 'eu'.$i.'_'; // first find the course context - if ($context->contextlevel == CONTEXT_COURSE) { - $coursecontext = $context; + $coursecontext = get_course_context($context); - } else if ($context->contextlevel == CONTEXT_MODULE) { - $coursecontext = get_context_instance_by_id(get_parent_contextid($context, MUST_EXIST)); + $isfrontpage = ($coursecontext->instanceid == SITEID); - } else if ($context->contextlevel == CONTEXT_BLOCK) { - $parentcontext = get_context_instance_by_id(get_parent_contextid($context, MUST_EXIST)); - if ($parentcontext->contextlevel == CONTEXT_COURSE) { - $coursecontext = $parentcontext; - } else if ($parentcontext->contextlevel == CONTEXT_MODULE) { - $coursecontext = get_context_instance_by_id(get_parent_contextid($parentcontext, MUST_EXIST)); - } else { - throw new coding_exception('Invalid context supplied to get_enrolled_sql()!'); - } + $joins = array(); + $wheres = array(); + $params = array(); - } else { - throw new coding_exception('Invalid context supplied to get_enrolled_sql()!'); - } - list($contextids, $contextpaths) = get_context_info_list($context); - list($coursecontextids, $coursecontextpaths) = get_context_info_list($coursecontext); // get all relevant capability info for all roles if ($withcapability) { - list($incontexts, $params) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED, 'con00'); - $incaps = "IN (:participate, :withcap)"; - $params['participate'] = 'moodle/course:participate'; - $params['withcap'] = $withcapability; - } else { - list($incontexts, $params) = $DB->get_in_or_equal($coursecontextids, SQL_PARAMS_NAMED, 'con00'); - $incaps = "= :participate"; - $params['participate'] = 'moodle/course:participate'; - } + list($incontexts, $cparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED, 'ctx00'); + $cparams['cap'] = $withcapability; + - $defs = array(); + $defs = array(); - $sql = "SELECT rc.id, rc.roleid, rc.permission, rc.capability, ctx.path + $sql = "SELECT rc.id, rc.roleid, rc.permission, ctx.path - FROM {role_capabilities} rc - JOIN {context} ctx on rc.contextid = ctx.id + FROM {role_capabilities} rc + JOIN {context} ctx on rc.contextid = ctx.id - WHERE rc.contextid $incontexts AND rc.capability $incaps"; - $rcs = $DB->get_records_sql($sql, $params); + WHERE rc.contextid $incontexts AND rc.capability = :cap"; + $rcs = $DB->get_records_sql($sql, $cparams); - foreach ($rcs as $rc) { + foreach ($rcs as $rc) { - $defs[$rc->capability][$rc->path][$rc->roleid] = $rc->permission; + $defs[$rc->path][$rc->roleid] = $rc->permission; - } + } - $courseaccess = array(); - if (!empty($defs['moodle/course:participate'])) { - foreach ($coursecontextpaths as $path) { - if (empty($defs['moodle/course:participate'][$path])) { - continue; - } - - foreach($defs['moodle/course:participate'][$path] as $roleid => $perm) { - if ($perm == CAP_PROHIBIT) { - $courseaccess[$roleid] = CAP_PROHIBIT; - continue; - } - if (!isset($courseaccess[$roleid])) { - $courseaccess[$roleid] = (int)$perm; - } - } - } - } - - $access = array(); + $access = array(); - if (!empty($defs[$withcapability])) { + if (!empty($defs)) { - foreach ($contextpaths as $path) { + foreach ($contextpaths as $path) { - if (empty($defs[$withcapability][$path])) { + if (empty($defs[$path])) { - continue; - } + continue; + } - foreach($defs[$withcapability][$path] as $roleid => $perm) { + foreach($defs[$path] as $roleid => $perm) { - if ($perm == CAP_PROHIBIT) { - $access[$roleid] = CAP_PROHIBIT; - continue; - } - if (!isset($access[$roleid])) { - $access[$roleid] = (int)$perm; - } - } - } - } + if ($perm == CAP_PROHIBIT) { + $access[$roleid] = CAP_PROHIBIT; + continue; + } + if (!isset($access[$roleid])) { + $access[$roleid] = (int)$perm; + } + } + } + } - unset($defs); + unset($defs); - // make lists of roles that are needed and prohibited + // make lists of roles that are needed and prohibited - $courseneeded = array(); // one of these is enough - $courseprohibited = array(); // must not have any of these - foreach ($courseaccess as $roleid => $perm) { - if ($perm == CAP_PROHIBIT) { - unset($courseneeded[$roleid]); - $courseprohibited[$roleid] = true; - } else if ($perm == CAP_ALLOW and empty($courseprohibited[$roleid])) { - $courseneeded[$roleid] = true; - } - } - $needed = array(); // one of these is enough - $prohibited = array(); // must not have any of these - if ($withcapability) { - foreach ($access as $roleid => $perm) { - if ($perm == CAP_PROHIBIT) { - unset($needed[$roleid]); - $prohibited[$roleid] = true; - } else if ($perm == CAP_ALLOW and empty($prohibited[$roleid])) { - $needed[$roleid] = true; - } - } - } + $needed = array(); // one of these is enough + $prohibited = array(); // must not have any of these + if ($withcapability) { + foreach ($access as $roleid => $perm) { + if ($perm == CAP_PROHIBIT) { + unset($needed[$roleid]); + $prohibited[$roleid] = true; + } else if ($perm == CAP_ALLOW and empty($prohibited[$roleid])) { + $needed[$roleid] = true; + } + } + } - $isfrontpage = ($coursecontext->instanceid == SITEID); - - $defaultuserroleid = isset($CFG->defaultuserroleid) ? $CFG->defaultuserroleid : NULL; - $defaultfrontpageroleid = isset($CFG->defaultfrontpageroleid) ? $CFG->defaultfrontpageroleid : NULL; + $defaultuserroleid = isset($CFG->defaultuserroleid) ? $CFG->defaultuserroleid : NULL; + $defaultfrontpageroleid = isset($CFG->defaultfrontpageroleid) ? $CFG->defaultfrontpageroleid : NULL; - $nobody = false; + $nobody = false; - if ($isfrontpage) { + if ($isfrontpage) { - // on the frontpage all users are kind of enrolled, we have to respect only the prohibits - $courseneeded = array(); - } else { - if (empty($courseneeded)) { - $nobody = true; - } - } - - if ($withcapability and !$nobody) { - if ($isfrontpage) { if (!empty($prohibited[$defaultuserroleid]) or !empty($prohibited[$defaultfrontpageroleid])) { $nobody = true; } else if (!empty($neded[$defaultuserroleid]) or !empty($neded[$defaultfrontpageroleid])) { @@ -3248,53 +2965,58 @@ $nobody = true; } } - } - if ($nobody) { - // nobody can match so return some SQL that does not return any results + if ($nobody) { + // nobody can match so return some SQL that does not return any results - return array("SELECT {$prefix}.id FROM {user} {$prefix} WHERE 1=2", array()); - } + $wheres[] = "1 = 2"; - $joins = array(); - $params = array(); - $wheres = array("{$prefix}.deleted = 0 AND {$prefix}.username <> 'guest'"); + } else { - if ($courseneeded) { - $ctxids = implode(',', $coursecontextids); - $roleids = implode(',', array_keys($courseneeded)); - $joins[] = "JOIN {role_assignments} {$prefix}_ra1 ON ({$prefix}_ra1.userid = {$prefix}.id AND {$prefix}_ra1.roleid IN ($roleids) AND {$prefix}_ra1.contextid IN ($ctxids))"; - } - - if ($courseprohibited) { - $ctxids = implode(',', $coursecontextids); - $roleids = implode(',', array_keys($courseprohibited)); - $joins[] = "LEFT JOIN {role_assignments} {$prefix}_ra2 ON ({$prefix}_ra2.userid = {$prefix}.id AND {$prefix}_ra2.roleid IN ($roleids) AND {$prefix}_ra2.contextid IN ($ctxids))"; - $wheres[] = "{$prefix}_ra2 IS NULL"; - } - - if ($needed) { - $ctxids = implode(',', $contextids); - $roleids = implode(',', array_keys($needed)); + if ($needed) { + $ctxids = implode(',', $contextids); + $roleids = implode(',', array_keys($needed)); - $joins[] = "JOIN {role_assignments} {$prefix}_ra3 ON ({$prefix}_ra3.userid = {$prefix}.id AND {$prefix}_ra3.roleid IN ($roleids) AND {$prefix}_ra3.contextid IN ($ctxids))"; + $joins[] = "JOIN {role_assignments} {$prefix}ra3 ON ({$prefix}ra3.userid = {$prefix}u.id AND {$prefix}ra3.roleid IN ($roleids) AND {$prefix}ra3.contextid IN ($ctxids))"; - } + } - if ($prohibited) { - $ctxids = implode(',', $contextids); - $roleids = implode(',', array_keys($prohibited)); + if ($prohibited) { + $ctxids = implode(',', $contextids); + $roleids = implode(',', array_keys($prohibited)); - $joins[] = "LEFT JOIN {role_assignments} {$prefix}_ra4 ON ({$prefix}_ra4.userid = {$prefix}.id AND {$prefix}_ra4.roleid IN ($roleids) AND {$prefix}_ra4.contextid IN ($ctxids))"; - $wheres[] = "{$prefix}_ra4 IS NULL"; + $joins[] = "LEFT JOIN {role_assignments} {$prefix}ra4 ON ({$prefix}ra4.userid = {$prefix}u.id AND {$prefix}ra4.roleid IN ($roleids) AND {$prefix}ra4.contextid IN ($ctxids))"; + $wheres[] = "{$prefix}ra4 IS NULL"; - } + } - if ($groupid) { + if ($groupid) { - $joins[] = "JOIN {groups_members} {$prefix}gm ON ({$prefix}gm.userid = {$prefix}.id AND {$prefix}.roleid = :{$prefix}gmid)"; + $joins[] = "JOIN {groups_members} {$prefix}gm ON ({$prefix}gm.userid = {$prefix}u.id AND {$prefix}u.roleid = :{$prefix}gmid)"; - $params["{$prefix}gmid"] = $groupid; - } + $params["{$prefix}gmid"] = $groupid; + } + } + } + + $wheres[] = "{$prefix}u.deleted = 0 AND {$prefix}u.username <> 'guest'"; + + if ($isfrontpage) { + // all users are "enrolled" on the frontpage + } else { + $joins[] = "JOIN {course_participants} {$prefix}cp ON {$prefix}cp.userid = {$prefix}u.id"; + $joins[] = "JOIN {enrol} {$prefix}e ON ({$prefix}e.id = {$prefix}cp.enrolid AND {$prefix}e.courseid = :{$prefix}courseid)"; + $params[$prefix.'courseid'] = $coursecontext->instanceid; + + if ($onlyactive) { + $wheres[] = "{$prefix}cp.status = :{$prefix}active AND {$prefix}e.status = :{$prefix}enabled"; + $wheres[] = "{$prefix}cp.timestart < :{$prefix}now1 AND ({$prefix}cp.timeend = 0 OR {$prefix}cp.timeend > :{$prefix}now2)"; + $now = round(time(), -2); // rounding helps caching in DB + $params = array_merge($params, array($prefix.'enabled'=>ENROL_STATUS_ENABLED, + $prefix.'active'=>ENROL_PARTICIPATION_ACTIVE, + $prefix.'now1'=>$now, $prefix.'now2'=>$now)); + } + } + $joins = implode("\n", $joins); $wheres = "WHERE ".implode(" AND ", $wheres); - $sql = "SELECT DISTINCT {$prefix}.id - FROM {user} {$prefix} + $sql = "SELECT DISTINCT {$prefix}u.id + FROM {user} {$prefix}u $joins $wheres"; @@ -4323,7 +4045,7 @@ case CONTEXT_SYSTEM: if (preg_match('|^enrol|', $component)) { $langname = str_replace('/', '_', $component); - $string = get_string('enrolname', $langname); + $string = get_string('pluginname', $langname); } else if (preg_match('|^block|', $component)) { $langname = str_replace('/', '_', $component); $string = get_string('pluginname', $langname); @@ -4748,8 +4470,7 @@ $extrajoins = ''; $extrawhere = ''; if (!is_siteadmin()) { - // Admins are allowed to switch to any role with 'moodle/course:participate' in the - // role definition. + // Admins are allowed to switch to any role with. // Others are subject to the additional constraint that the switch-to role must be allowed by // 'role_allow_switch' for some role they have assigned in this context or any parent. $parents = get_parent_contexts($context); @@ -4758,7 +4479,7 @@ $extrajoins = "JOIN {role_allow_switch} ras ON ras.allowswitch = rc.roleid JOIN {role_assignments} ra ON ra.roleid = ras.roleid"; - $extrawhere = "AND ra.userid = :userid AND ra.contextid IN ($contexts)"; + $extrawhere = "WHERE ra.userid = :userid AND ra.contextid IN ($contexts)"; $params['userid'] = $USER->id; } @@ -4768,47 +4489,16 @@ SELECT DISTINCT rc.roleid FROM {role_capabilities} rc $extrajoins - WHERE rc.capability = :viewcap - AND rc.permission = " . CAP_ALLOW . " - AND rc.contextid = :syscontextid - $extrawhere + $extrawhere ) idlist JOIN {role} r ON r.id = idlist.roleid ORDER BY r.sortorder"; - $params['syscontextid'] = $systemcontext->id; - $params['viewcap'] = 'moodle/course:participate'; $rolenames = $DB->get_records_sql_menu($query, $params); return role_fix_names($rolenames, $context, ROLENAME_ALIAS); } /** - * Get an array of role ids that might possibly be the target of a switchrole. - * Our policy is that you cannot switch to admin role - * and you can only switch to a role with moodle/course:participate. This method returns - * a list of those role ids. - * - * @global object - * @return array an array whose keys are the allowed role ids. - */ -function get_allowed_switchable_roles() { - global $CFG, $DB; - - $systemcontext = get_context_instance(CONTEXT_SYSTEM); - - $query = " - SELECT DISTINCT rc.roleid, 1 - FROM {role_capabilities} rc - JOIN {role} r ON r.id = rc.roleid - WHERE rc.capability = :participate - AND rc.permission = " . CAP_ALLOW . " - AND rc.contextid = :syscontextid"; - $params = array('syscontextid' => $systemcontext->id, 'participate' => 'moodle/course:participate'); - - return $DB->get_records_sql_menu($query, $params); -} - -/** * Gets a list of roles that this user can override in this context. * * @global object @@ -4894,6 +4584,34 @@ } /** + * Create a role menu suitable for default role selection in enrol plugins. + * @param object $context + * @param int $addroleid current or default role - always added to list + * @return array roleid=>localised role name + */ +function get_default_enrol_roles($context, $addroleid = null) { + global $DB; + + $params = array('level'=>CONTEXT_COURSE); + if ($addroleid) { + $addrole = "OR r.id = :addroleid"; + $params['addroleid'] = $addroleid; + } else { + $addrole = ""; + } + $sql = "SELECT r.id, r.name + FROM {role} r + LEFT JOIN {role_context_levels} rcl ON (rcl.roleid = r.id AND rcl.contextlevel = :level) + WHERE rcl.id IS NOT NULL $addrole + ORDER BY sortorder DESC"; + + $roles = $DB->get_records_sql_menu($sql, $params); + $roles = role_fix_names($roles, $context, ROLENAME_BOTH); + + return $roles; +} + +/** * @global object * @param integer $roleid the id of a role. * @return array list of the context levels at which this role may be assigned. @@ -4967,6 +4685,7 @@ * @return object returns a role or NULL if none set */ function get_default_course_role($course) { + //TODO: remove, use enrol plugin settings instead global $DB, $CFG; /// First let's take the default role the course may have @@ -5291,7 +5010,7 @@ * a good idea to see what roles have the capabilities you want * (array_diff() them against roiles that have 'can-do-anything' * to weed out admin-ish roles. Or fetch a list of roles from - * variables like $CFG->coursemanager . + * variables like $CFG->coursecontact . * * @global object * @param array $users Users array, keyed on userid Index: enrol/manual/settings.php =================================================================== --- enrol/manual/settings.php (revision ) +++ enrol/manual/settings.php (revision ) @@ -0,0 +1,55 @@ +. + +/** + * Manual enrolment plugin settings and presets. + * + * @package enrol_manual + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +if ($ADMIN->fulltree) { + + //--- general settings ----------------------------------------------------------------------------------- + $settings->add(new admin_setting_heading('enrol_manual_settings', '', get_string('pluginname_desc', 'enrol_manual'))); + + + //--- enrol instance defaults ---------------------------------------------------------------------------- + $settings->add(new admin_setting_heading('enrol_manual_defaults', + get_string('enrolinstancedefaults', 'admin'), get_string('enrolinstancedefaults_desc', 'admin'))); + + $options = array(ENROL_STATUS_ENABLED => get_string('yes'), + ENROL_STATUS_DISABLED => get_string('no')); + $settings->add(new admin_setting_configselect_with_advanced('enrol_manual/status', + get_string('status', 'enrol_manual'), get_string('status_desc', 'enrol_manual'), + array('value'=>ENROL_STATUS_ENABLED, 'adv'=>false), $options)); + + $settings->add(new admin_setting_configtext_with_advanced('enrol_manual/enrolperiod', + get_string('defaultperiod', 'enrol_manual'), get_string('defaultperiod_desc', 'enrol_manual'), + array('value'=>0, 'adv'=>true), PARAM_INT)); + + if (!during_initial_install()) { + $options = get_default_enrol_roles(get_context_instance(CONTEXT_SYSTEM)); + $student = get_archetype_roles('student'); + $student = reset($student); + $settings->add(new admin_setting_configselect_with_advanced('enrol_manual/defaultrole', + get_string('defaultrole', 'role'), '', + array('value'=>$student->id, 'adv'=>true), $options)); + } +} + Index: enrol/self/db/install.php =================================================================== --- enrol/self/db/install.php (revision ) +++ enrol/self/db/install.php (revision ) @@ -0,0 +1,10 @@ +sendcoursewelcomemessage)) { + set_config('sendcoursewelcomemessage', $CFG->sendcoursewelcomemessage, 'enrol_self'); + unset_config('sendcoursewelcomemessage'); + } +} Index: mod/forum/db/upgrade.php =================================================================== --- mod/forum/db/upgrade.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ mod/forum/db/upgrade.php (revision ) @@ -56,34 +56,6 @@ upgrade_mod_savepoint($result, 2007101511, 'forum'); } - if ($result && $oldversion < 2007101512) { - - /// Cleanup the forum subscriptions - echo $OUTPUT->notification('Removing stale forum subscriptions', 'notifysuccess'); - - $roles = get_roles_with_capability('moodle/course:participate', CAP_ALLOW); - $roles = array_keys($roles); - - list($usql, $params) = $DB->get_in_or_equal($roles); - $sql = "SELECT fs.userid, f.id AS forumid - FROM {forum} f - JOIN {course} c ON c.id = f.course - JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = ".CONTEXT_COURSE.") - JOIN {forum_subscriptions} fs ON fs.forum = f.id - LEFT JOIN {role_assignments} ra ON (ra.contextid = ctx.id AND ra.userid = fs.userid AND ra.roleid $usql) - WHERE ra.id IS NULL"; - - if ($rs = $DB->get_recordset_sql($sql, $params)) { - foreach ($rs as $remove) { - $DB->delete_records('forum_subscriptions', array('userid'=>$remove->userid, 'forum'=>$remove->forumid)); - echo '.'; - } - $rs->close(); - } - - upgrade_mod_savepoint($result, 2007101512, 'forum'); - } - if ($result && $oldversion < 2008072800) { /// Define field completiondiscussions to be added to forum $table = new xmldb_table('forum'); Index: lang/en/role.php =================================================================== --- lang/en/role.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lang/en/role.php (revision ) @@ -121,7 +121,6 @@ $string['course:managefiles'] = 'Manage files'; $string['course:managegrades'] = 'Manage grades'; $string['course:managegroups'] = 'Manage groups'; -$string['course:managemetacourse'] = 'Manage metacourse'; $string['course:managescales'] = 'Manage scales'; $string['course:markcomplete'] = 'Mark users as complete in course completion'; $string['course:participate'] = 'Participate in courses'; @@ -157,7 +156,6 @@ $string['editingrolex'] = 'Editing role \'{$a}\''; $string['editrole'] = 'Edit role'; $string['editxrole'] = 'Edit {$a} role'; -$string['enrolmentoptions'] = 'Enrolment options'; $string['errorbadrolename'] = 'Incorrect role name'; $string['errorbadroleshortname'] = 'Incorrect role short name'; $string['errorexistsrolename'] = 'Role name already exists'; @@ -216,8 +214,6 @@ $string['managerdescription'] = 'Managers can access course and modify them, they usually do not participate in courses.'; $string['manageroles'] = 'Manage roles'; $string['maybeassignedin'] = 'Context types where this role may be assigned'; -$string['metaassignerror'] = 'Can not assign this role to user "{$a}" because Manage metacourse capability is needed.'; -$string['metaunassignerror'] = 'Role of user "{$a}" was automatically reassigned, please unassign the role in child courses instead.'; $string['morethan'] = 'More than {$a}'; $string['multipleroles'] = 'Multiple roles'; $string['my:manageblocks'] = 'Manage myMoodle page blocks'; @@ -300,7 +296,6 @@ $string['role:switchroles'] = 'Switch to other roles'; $string['roletoassign'] = 'Role to assign'; $string['roletooverride'] = 'Role to override'; -$string['role:unassignself'] = 'Unassign own roles'; $string['role:viewhiddenassigns'] = 'View hidden role assignments'; $string['safeoverridenotice'] = 'Note: Capabilities with higher risks are locked because you are only allowed to override safe capabilities.'; $string['selectanotheruser'] = 'Select another user'; Index: enrol/ldap/enrol.php =================================================================== --- enrol/ldap/enrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/ldap/enrol.php (revision ) @@ -1,7 +1,5 @@ dirroot/enrol/enrol.class.php"); - class enrolment_plugin_ldap { var $log; @@ -81,7 +79,8 @@ if (!$DB->get_record('role_assignments', array('roleid'=>$role->id, 'userid'=>$user->id, 'contextid'=>$context->id))) { //error_log("[ENROL_LDAP] Assigning role '{$role->name}' to {$user->id} ({$user->username}) in course {$course_obj->id} ({$course_obj->shortname})"); - if (!role_assign($role->id, $user->id, 0, $context->id, 0, 0, 0, 'ldap')){ + //TODO: some real enrolment here + if (!role_assign($role->id, $user->id, $context->id, 'enrol_ldap')){ error_log("[ENROL_LDAP] Failed to assign role '{$role->name}' to $user->id ($user->username) into course $course_obj->id ($course_obj->shortname)"); } } else { @@ -106,7 +105,7 @@ foreach ($ldap_assignments as $ra) { if($ra->enrol === 'ldap') { error_log("Unassigning role_assignment with id '{$ra->id}' from user {$user->id} ({$user->username})"); - role_unassign($ra->roleid, $user->id, 0, $ra->contextid, 'ldap'); + role_unassign($ra->roleid, $user->id, $ra->contextid, 'enrol_ldap'); } } @@ -265,13 +264,10 @@ foreach ($todelete as $member) { $member = $member->user; - if (role_unassign($role->id, $member, 0, $context->id, 'ldap')) { + role_unassign($role->id, $member, $context->id, 'enrol_ldap'); - print "Unassigned $type from $member for course $course_obj->id ($course_obj->shortname)\n"; + print "Unassigned $type from $member for course $course_obj->id ($course_obj->shortname)\n"; - } else { - print "Failed to unassign $type from $member for course $course_obj->id ($course_obj->shortname)\n"; - } - } + } + } - } // insert current enrolments // bad we can't do INSERT IGNORE with postgres... @@ -287,7 +283,7 @@ $member = $member->id; if (!$DB->get_record('role_assignments', array('roleid'=>$role->id, 'contextid'=>$context->id, 'userid'=>$member, 'enrol'=>'ldap'))){ - if (role_assign($role->id, $member, 0, $context->id, 0, 0, 0, 'ldap')){ + if (role_assign($role->id, $member, $context->id, 'enrol_ldap')){ print "Assigned role $type to $member ($ldapmember) for course $course_obj->id ($course_obj->shortname)\n"; } else { print "Failed to assign role $type to $member ($ldapmember) for course $course_obj->id ($course_obj->shortname)\n"; Index: calendar/export_execute.php =================================================================== --- calendar/export_execute.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ calendar/export_execute.php (revision ) @@ -33,7 +33,7 @@ if(!empty($what) && !empty($time)) { if(in_array($what, $allowed_what) && in_array($time, $allowed_time)) { - $courses = get_my_courses($user->id, NULL, 'id, visible, shortname'); + $courses = enrol_get_users_courses($user->id, true, 'id, visible, shortname'); if ($what == 'all') { $users = $user->id; Index: enrol/index.html =================================================================== --- enrol/index.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/index.html (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,1 +0,0 @@ - Index: enrol/guest/lang/en/enrol_guest.php =================================================================== --- enrol/guest/lang/en/enrol_guest.php (revision ) +++ enrol/guest/lang/en/enrol_guest.php (revision ) @@ -0,0 +1,39 @@ +. + +/** + * Strings for component 'enrol_guest', language 'en', branch 'MOODLE_20_STABLE' + * + * @package enrol_guest + * @copyright 2010 onwards Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$string['password'] = 'Password'; +$string['passwordinvalid'] = 'Incorrect access password, please try again'; +$string['passwordinvalidhint'] = 'That access password was incorrect, please try again
+(Here\'s a hint - it starts with \'{$a}\')'; +$string['pluginname'] = 'Guest access'; +$string['pluginname_desc'] = 'Guest access plugin is only granting temporary access to courses, it is not actually enrolling users.'; +$string['requirepassword'] = 'Require guest access passsword'; +$string['requirepassword_desc'] = 'Require access password in new courses and prevent prevent removing of access key from existing courses.'; +$string['showhint'] = 'Show hint'; +$string['showhint_desc'] = 'Show first letter of the guest access password.'; +$string['status'] = 'Allow guest access'; +$string['status_desc'] = 'Allow temporary guest access by default.'; +$string['usepasswordpolicy'] = 'Use password policy'; +$string['usepasswordpolicy_desc'] = 'Use standard password policy for guest access passwords.'; Index: tag/locallib.php =================================================================== --- tag/locallib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ tag/locallib.php (revision ) @@ -322,7 +322,7 @@ $usercontext = get_context_instance(CONTEXT_USER, $user->id); $profilelink = ''; - if ( has_capability('moodle/user:viewdetails', $usercontext) || has_coursemanager_role($user->id) ) { + if ( has_capability('moodle/user:viewdetails', $usercontext) || has_coursecontact_role($user->id) ) { $profilelink = $CFG->wwwroot .'/user/view.php?id='. $user->id; } Index: course/edit_form.php =================================================================== --- course/edit_form.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/edit_form.php (revision ) @@ -3,56 +3,34 @@ require_once($CFG->libdir.'/formslib.php'); class course_edit_form extends moodleform { + protected $course; + protected $context; function definition() { global $USER, $CFG, $DB; - $courseconfig = get_config('moodlecourse'); - $mform =& $this->_form; + $mform = $this->_form; - $course = $this->_customdata['course']; + $course = $this->_customdata['course']; // this contains the data of this form $category = $this->_customdata['category']; $editoroptions = $this->_customdata['editoroptions']; $systemcontext = get_context_instance(CONTEXT_SYSTEM); $categorycontext = get_context_instance(CONTEXT_COURSECAT, $category->id); - $disable_meta = false; // basic meta course state protection; server-side security checks not needed if (!empty($course->id)) { $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); $context = $coursecontext; - - if (course_in_meta($course)) { - $disable_meta = get_string('metaalreadyinmeta'); - - } else if ($course->metacourse) { - if ($DB->count_records('course_meta', array('parent_course'=>$course->id)) > 0) { - $disable_meta = get_string('metaalreadyhascourses'); - } - - } else { + } else { - // if users already enrolled directly into coures, do not allow switching to meta, - // users with metacourse manage permission are exception - // please note that we do not need exact results - anything unexpected here prevents metacourse - $managers = get_users_by_capability($coursecontext, 'moodle/course:managemetacourse', 'u.id'); - $enrolroles = get_roles_with_capability('moodle/course:participate', CAP_ALLOW, $coursecontext); - if ($users = get_role_users(array_keys($enrolroles), $coursecontext, false, 'u.id', 'u.id ASC')) { - foreach($users as $user) { - if (!isset($managers[$user->id])) { - $disable_meta = get_string('metaalreadyhasenrolments'); - break; - } - } - } - unset($managers); - unset($users); - unset($enrolroles); - } - } else { $coursecontext = null; $context = $categorycontext; } + $courseconfig = get_config('moodlecourse'); + + $this->course = $course; + $this->context = $context; + /// form definition with new course defaults //-------------------------------------------------------------------------------- $mform->addElement('header','general', get_string('general', 'form')); @@ -177,108 +155,10 @@ $mform->addElement('select', 'theme', get_string('forcetheme'), $themes); } - $meta=array(); - $meta[0] = get_string('no'); - $meta[1] = get_string('yes'); - if ($disable_meta === false) { - $mform->addElement('select', 'metacourse', get_string('managemeta'), $meta); - $mform->setHelpButton('metacourse', array('metacourse', get_string('metacourse')), true); - $mform->setDefault('metacourse', $courseconfig->metacourse); - } else { - // no metacourse element - we do not want to change it anyway! - $mform->addElement('static', 'nometacourse', get_string('managemeta'), - ((empty($course->metacourse)) ? $meta[0] : $meta[1]) . " - $disable_meta "); - $mform->setHelpButton('nometacourse', array('metacourse', get_string('metacourse')), true); - } - //-------------------------------------------------------------------------------- - $mform->addElement('header','enrolhdr', get_string('enrolments')); + enrol_course_edit_form($mform, $course, $context); - $choices = array(); - $modules = explode(',', $CFG->enrol_plugins_enabled); - foreach ($modules as $module) { - $name = get_string('enrolname', "enrol_$module"); - $plugin = enrolment_factory::factory($module); - if (method_exists($plugin, 'print_entry')) { - $choices[$name] = $module; - } - } - asort($choices); - $choices = array_flip($choices); - $choices = array_merge(array('' => get_string('sitedefault').' ('.get_string('enrolname', "enrol_$CFG->enrol").')'), $choices); - $mform->addElement('select', 'enrol', get_string('enrolmentplugins'), $choices); - $mform->setHelpButton('enrol', array('courseenrolmentplugins', get_string('enrolmentplugins')), true); - $mform->setDefault('enrol', $courseconfig->enrol); - - - $roles = get_assignable_roles($context); - if (!empty($course->id)) { - // add current default role, so that it is selectable even when user can not assign it - if ($current_role = $DB->get_record('role', array('id'=>$course->defaultrole))) { - $roles[$current_role->id] = strip_tags(format_string($current_role->name, true)); - } - } - $choices = array(); - if ($sitedefaultrole = $DB->get_record('role', array('id'=>$CFG->defaultcourseroleid))) { - $choices[0] = get_string('sitedefault').' ('.$sitedefaultrole->name.')'; - } else { - $choices[0] = get_string('sitedefault'); - } - $choices = $choices + $roles; - - // fix for MDL-9197 - foreach ($choices as $choiceid => $choice) { - $choices[$choiceid] = format_string($choice); - } - - $mform->addElement('select', 'defaultrole', get_string('defaultrole', 'role'), $choices); - $mform->setDefault('defaultrole', 0); - - - $radio = array(); - $radio[] = &MoodleQuickForm::createElement('radio', 'enrollable', null, get_string('no'), 0); - $radio[] = &MoodleQuickForm::createElement('radio', 'enrollable', null, get_string('yes'), 1); - $radio[] = &MoodleQuickForm::createElement('radio', 'enrollable', null, get_string('enroldate'), 2); - $mform->addGroup($radio, 'enrollable', get_string('enrollable'), ' ', false); - $mform->setHelpButton('enrollable', array('courseenrollable2', get_string('enrollable')), true); - $mform->setDefault('enrollable', $courseconfig->enrollable); - - $mform->addElement('date_selector', 'enrolstartdate', get_string('enrolstartdate'), array('optional' => true)); - $mform->setDefault('enrolstartdate', 0); - $mform->disabledIf('enrolstartdate', 'enrollable', 'neq', 2); - - $mform->addElement('date_selector', 'enrolenddate', get_string('enrolenddate'), array('optional' => true)); - $mform->setDefault('enrolenddate', 0); - $mform->disabledIf('enrolenddate', 'enrollable', 'neq', 2); - - $mform->addElement('duration', 'enrolperiod', get_string('enrolperiod'), array('optional' => true, 'defaultunit' => 86400)); - $mform->setDefault('enrolperiod', $courseconfig->enrolperiod); - - //-------------------------------------------------------------------------------- - $mform->addElement('header','expirynotifyhdr', get_string('expirynotify')); - - $choices = array(); - $choices['0'] = get_string('no'); - $choices['1'] = get_string('yes'); - $mform->addElement('select', 'expirynotify', get_string('notify'), $choices); - $mform->setHelpButton('expirynotify', array('expirynotify', get_string('expirynotify')), true); - $mform->setDefault('expirynotify', $courseconfig->expirynotify); - - $mform->addElement('select', 'notifystudents', get_string('expirynotifystudents'), $choices); - $mform->setHelpButton('notifystudents', array('expirynotifystudents', get_string('expirynotifystudents')), true); - $mform->setDefault('notifystudents', $courseconfig->notifystudents); - - $thresholdmenu=array(); - for ($i=1; $i<=30; $i++) { - $seconds = $i * 86400; - $thresholdmenu[$seconds] = get_string('numdays', '', $i); - } - $mform->addElement('select', 'expirythreshold', get_string('expirythreshold'), $thresholdmenu); - $mform->setHelpButton('expirythreshold', array('expirythreshold', get_string('expirythreshold')), true); - $mform->setDefault('expirythreshold', $courseconfig->expirythreshold); - -//-------------------------------------------------------------------------------- $mform->addElement('header','', get_string('groups', 'group')); $choices = array(); @@ -315,51 +195,6 @@ $mform->setConstant('visible', $course->visible); } - $mform->addElement('passwordunmask', 'enrolpassword', get_string('enrolmentkey'), 'size="25"'); - $mform->setHelpButton('enrolpassword', array('enrolmentkey', get_string('enrolmentkey')), true); - $mform->setDefault('enrolpassword', ''); - $mform->setDefault('enrolpassword', $courseconfig->enrolpassword); - $mform->setType('enrolpassword', PARAM_RAW); - - if (empty($course->id) or ($course->password !== '' and $course->id != SITEID)) { - // do not require password in existing courses that do not have password yet - backwards compatibility ;-) - if (!empty($CFG->enrol_manual_requirekey)) { - $mform->addRule('enrolpassword', get_string('required'), 'required', null, 'client'); - } - } - - $choices = array(); - $choices['0'] = get_string('guestsno'); - $choices['1'] = get_string('guestsyes'); - $choices['2'] = get_string('guestskey'); - $mform->addElement('select', 'guest', get_string('opentoguests'), $choices); - $mform->setHelpButton('guest', array('guestaccess', get_string('opentoguests')), true); - $mform->setDefault('guest', $courseconfig->guest); - - // If we are creating a course, its enrol method isn't yet chosen, BUT the site has a default enrol method which we can use here - $enrol_object = $CFG; - if (!empty($course->id)) { - $enrol_object = $course; - } - // If the print_entry method exists and the course enrol method isn't manual (both set or inherited from site), show cost - if (method_exists(enrolment_factory::factory($enrol_object->enrol), 'print_entry') && !($enrol_object->enrol == 'manual' || (empty($enrol_object->enrol) && $CFG->enrol == 'manual'))) { - $costgroup=array(); - $currencies = get_string_manager()->get_list_of_currencies(); - $costgroup[]= &MoodleQuickForm::createElement('text','cost', '', 'maxlength="6" size="6"'); - $costgroup[]= &MoodleQuickForm::createElement('select', 'currency', '', $currencies); - $mform->addGroup($costgroup, 'costgrp', get_string('cost'), ' ', false); - //defining a rule for a form element within a group : - $costgrprules=array(); - //set the message to null to tell Moodle to use a default message - //available for most rules, fetched from language pack (err_{rulename}). - $costgrprules['cost'][]=array(null, 'numeric', null, 'client'); - $mform->addGroupRule('costgrp',$costgrprules); - $mform->setHelpButton('costgrp', array('cost', get_string('cost')), true); - $mform->setDefault('cost', ''); - $mform->setDefault('currency', empty($CFG->enrol_currency) ? 'USD' : $CFG->enrol_currency); - - } - //-------------------------------------------------------------------------------- $mform->addElement('header','', get_string('language')); @@ -444,6 +279,10 @@ //-------------------------------------------------------------------------------- $mform->addElement('hidden', 'id', null); $mform->setType('id', PARAM_INT); + +/// finally set the current form data +//-------------------------------------------------------------------------------- + $this->set_data($course); } function definition_after_data() { @@ -451,7 +290,7 @@ $mform =& $this->_form; - // add availabe groupings + // add available groupings if ($courseid = $mform->getElementValue('id') and $mform->elementExists('defaultgroupingid')) { $options = array(); if ($groupings = $DB->get_records('groupings', array('courseid'=>$courseid))) { @@ -483,22 +322,8 @@ } } - if (!empty($data['enrolstartdate']) && !empty($data['enrolenddate']) && - $data['enrolenddate'] <= $data['enrolstartdate']){ - $errors['enrolenddate'] = get_string('enrolenddaterror'); - } + $errors = array_merge($errors, enrol_course_edit_validation($data, $this->context)); - if (!empty($CFG->enrol_manual_usepasswordpolicy) and isset($data['enrolpassword']) and $data['enrolpassword'] != '') { - $course = $this->_customdata['course']; - if ($course->password !== $data['enrolpassword']) { - // enforce password policy only if changing password - backwards compatibility - $errmsg = ''; - if (!check_password_policy($data['enrolpassword'], $errmsg)) { - $errors['enrolpassword'] = $errmsg; - } - } - } - return $errors; } } Index: enrol/guest/settings.php =================================================================== --- enrol/guest/settings.php (revision ) +++ enrol/guest/settings.php (revision ) @@ -0,0 +1,51 @@ +. + +/** + * Guest access plugin settings and presets. + * + * @package enrol_guest + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +if ($ADMIN->fulltree) { + + //--- general settings ----------------------------------------------------------------------------------- + $settings->add(new admin_setting_heading('enrol_manual_settings', '', get_string('pluginname_desc', 'enrol_guest'))); + + $settings->add(new admin_setting_configcheckbox('enrol_guest/requirepassword', + get_string('requirepassword', 'enrol_guest'), get_string('requirepassword_desc', 'enrol_guest'), 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_guest/usepasswordpolicy', + get_string('usepasswordpolicy', 'enrol_guest'), get_string('usepasswordpolicy_desc', 'enrol_guest'), 0)); + + $settings->add(new admin_setting_configcheckbox('enrol_guest/showhint', + get_string('showhint', 'enrol_guest'), get_string('showhint_desc', 'enrol_guest'), 0)); + + + //--- enrol instance defaults ---------------------------------------------------------------------------- + $settings->add(new admin_setting_heading('enrol_guest_defaults', + get_string('enrolinstancedefaults', 'admin'), get_string('enrolinstancedefaults_desc', 'admin'))); + + $options = array(ENROL_STATUS_ENABLED => get_string('yes'), + ENROL_STATUS_DISABLED => get_string('no')); + $settings->add(new admin_setting_configselect_with_advanced('enrol_guest/status', + get_string('status', 'enrol_guest'), get_string('status_desc', 'enrol_guest'), + array('value'=>ENROL_STATUS_ENABLED, 'adv'=>false), $options)); +} + Index: lib/deprecatedlib.php =================================================================== --- lib/deprecatedlib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/deprecatedlib.php (revision ) @@ -39,7 +39,24 @@ return get_string('pluginname', "auth_{$authtype}"); } + /** + * Enrol someone without using the default role in a course + * @deprecated + */ +function enrol_into_course($course, $user, $enrol) { + error('Function enrol_into_course() was removed, please use new enrol plugins instead!'); +} + +/** + * Extremely slow enrolled courses query. + * @deprecated + */ +function get_my_courses($userid, $sort='visible DESC,sortorder ASC', $fields=NULL, $doanything=false,$limit=0) { + error('Function get_my_courses() was removed, please use new enrol_get_my_courses() or enrol_get_users_courses()!'); +} + +/** * Was returning list of translations, use new string_manager instead * * @deprecated Index: enrol/manual/locallib.php =================================================================== --- enrol/manual/locallib.php (revision ) +++ enrol/manual/locallib.php (revision ) @@ -0,0 +1,152 @@ +. + +/** + * Auxiliary manual user enrolment lib, the main purpose is to lower memory requirements... + * + * @package enrol_manual + * @copyright 2010 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once($CFG->dirroot . '/user/selector/lib.php'); + +/** + * Enrol candidates + */ +class enrol_manual_potential_participant extends user_selector_base { + protected $enrolid; + + public function __construct($name, $options) { + $this->enrolid = $options['enrolid']; + parent::__construct($name, $options); + } + + /** + * Candidate users + * @param $search + * @return array + */ + public function find_users($search) { + global $DB; + //by default wherecondition retrieves all users except the deleted, not confirmed and guest + list($wherecondition, $params) = $this->search_sql($search, 'u'); + $params['enrolid'] = $this->enrolid; + + $fields = 'SELECT ' . $this->required_fields_sql('u'); + $countfields = 'SELECT COUNT(1)'; + + $sql = " FROM {user} u + WHERE $wherecondition + AND u.id NOT IN (SELECT cp.userid + FROM {course_participants} cp + JOIN {enrol} e ON (e.id = cp.enrolid AND e.id = :enrolid))"; + + $order = ' ORDER BY u.lastname ASC, u.firstname ASC'; + + if (!$this->is_validating()) { + $potentialmemberscount = $DB->count_records_sql($countfields . $sql, $params); + if ($potentialmemberscount > 100) { + return $this->too_many_results($search, $potentialmemberscount); + } + } + + $availableusers = $DB->get_records_sql($fields . $sql . $order, $params); + + if (empty($availableusers)) { + return array(); + } + + + if ($search) { + $groupname = get_string('enrolcandidatesmatching', 'enrol', $search); + } else { + $groupname = get_string('enrolcandidates', 'enrol'); + } + + return array($groupname => $availableusers); + } + + protected function get_options() { + $options = parent::get_options(); + $options['enrolid'] = $this->enrolid; + $options['file'] = 'enrol/manual/locallib.php'; + return $options; + } +} + +/** + * Enroled users + */ +class enrol_manual_current_participant extends user_selector_base { + protected $courseid; + protected $enrolid; + + public function __construct($name, $options) { + $this->enrolid = $options['enrolid']; + parent::__construct($name, $options); + } + + /** + * Candidate users + * @param $search + * @return array + */ + public function find_users($search) { + global $DB; + //by default wherecondition retrieves all users except the deleted, not confirmed and guest + list($wherecondition, $params) = $this->search_sql($search, 'u'); + $params['enrolid'] = $this->enrolid; + + $fields = 'SELECT ' . $this->required_fields_sql('u'); + $countfields = 'SELECT COUNT(1)'; + + $sql = " FROM {user} u + JOIN {course_participants} cp ON (cp.userid = u.id AND cp.enrolid = :enrolid) + WHERE $wherecondition"; + + $order = ' ORDER BY u.lastname ASC, u.firstname ASC'; + + if (!$this->is_validating()) { + $potentialmemberscount = $DB->count_records_sql($countfields . $sql, $params); + if ($potentialmemberscount > 100) { + return $this->too_many_results($search, $potentialmemberscount); + } + } + + $availableusers = $DB->get_records_sql($fields . $sql . $order, $params); + + if (empty($availableusers)) { + return array(); + } + + + if ($search) { + $groupname = get_string('enrolledusersmatching', 'enrol', $search); + } else { + $groupname = get_string('enrolledusers', 'enrol'); + } + + return array($groupname => $availableusers); + } + + protected function get_options() { + $options = parent::get_options(); + $options['enrolid'] = $this->enrolid; + $options['file'] = 'enrol/manual/locallib.php'; + return $options; + } +} Index: user/action_redir.php =================================================================== --- user/action_redir.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ user/action_redir.php (revision ) @@ -33,8 +33,6 @@ // Add every page will be redirected by this script $actions = array( 'messageselect.php', - 'extendenrol.php', - 'groupextendenrol.php', 'addnote.php', 'groupaddnote.php', ); Index: search/documents/label_document.php =================================================================== --- search/documents/label_document.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ search/documents/label_document.php (revision ) @@ -165,7 +165,7 @@ $course_context = get_context_instance(CONTEXT_COURSE, $r->course); //check if englobing course is visible - if (!has_capability('moodle/course:participate', $course_context)){ + if (!is_enrolled($course_context) and !is_viewing($course_context)) { return false; } Index: blocks/admin/block_admin.php =================================================================== --- blocks/admin/block_admin.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ blocks/admin/block_admin.php (revision ) @@ -86,20 +86,6 @@ } } - /// Manage metacourses - if ($course->metacourse) { - if (has_capability('moodle/course:managemetacourse', $this->page->context)) { - $strchildcourses = get_string('childcourses'); - $this->content->items[]=''.$strchildcourses.''; - $this->content->icons[]=''; - } else if (has_capability('moodle/role:assign', $this->page->context)) { - $strchildcourses = get_string('childcourses'); - $this->content->items[]=''.$strchildcourses.''; - $this->content->icons[]=''; - } - } - - /// Manage groups in this course if (($course->id!==SITEID) && ($course->groupmode || !$course->groupmodeforce) && has_capability('moodle/course:managegroups', $this->page->context)) { $strgroups = get_string('groups'); @@ -192,21 +178,21 @@ } /// Unenrol link - if (empty($course->metacourse) && ($course->id!==SITEID)) { - if ($isenrolled) { + if ($isenrolled) { - if (has_capability('moodle/role:unassignself', $this->page->context, NULL, false) and get_user_roles($this->page->context, $USER->id, false)) { // Have some role + /* + if (..detect if can unenrol somehow and probably cache it..) { - $this->content->items[]=''.get_string('unenrolme', '', format_string($course->shortname)).''; - $this->content->icons[]=''; - } + $this->content->items[]=''.get_string('unenrolme', '', format_string($course->shortname)).''; + $this->content->icons[]=''; + } + */ - - } else if ($isviewing) { - // inspector, manager, etc. - do not show anything - } else { - // access because otherwise they would not get into this course at all + + } else if ($isviewing) { + // inspector, manager, etc. - do not show anything + } else { + // access because otherwise they would not get into this course at all - $this->content->items[]=''.get_string('enrolme', '', format_string($course->shortname)).''; + $this->content->items[]=''.get_string('enrolme', '', format_string($course->shortname)).''; - $this->content->icons[]=''; - } + $this->content->icons[]=''; + } - } /// Link to the user own profile if they are enrolled if ($isenrolled) { Index: blocks/course_list/block_course_list.php =================================================================== --- blocks/course_list/block_course_list.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ blocks/course_list/block_course_list.php (revision ) @@ -36,11 +36,8 @@ if (empty($CFG->disablemycourses) and isloggedin() and !isguestuser() and !(has_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM)) and $adminseesall)) { // Just print My Courses - if ($courses = get_my_courses($USER->id, 'visible DESC, fullname ASC')) { + if ($courses = enrol_get_my_courses($USER->id, NULL, 'visible DESC, fullname ASC')) { foreach ($courses as $course) { - if ($course->id == SITEID) { - continue; - } $linkcss = $course->visible ? "" : " class=\"dimmed\" "; $this->content->items[]="shortname) . "\" ". "href=\"$CFG->wwwroot/course/view.php?id=$course->id\">" . format_string($course->fullname) . ""; Index: user/extendenrol.php =================================================================== --- user/extendenrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ user/extendenrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,188 +0,0 @@ -. - -/** - * This file is part of the User section Moodle - * - * @copyright 1999 Martin Dougiamas http://dougiamas.com - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @package user - */ - -require_once("../config.php"); - -$id = required_param('id', PARAM_INT); // course id -$users = optional_param('userid', array(), PARAM_INT); // array of user id - -$PAGE->set_url('/user/extendenrol.php', array('id'=>$id)); - -if (! $course = $DB->get_record('course', array('id'=>$id))) { - print_error('invalidcourseid'); -} - -$context = get_context_instance(CONTEXT_COURSE, $id); -require_login($course->id); - -// to extend enrolments current user needs to be able to do role assignments -require_capability('moodle/role:assign', $context); -$today = time(); -$today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0); -if ((count($users) > 0) and ($form = data_submitted()) and confirm_sesskey()) { - if (count($form->userid) != count($form->extendperiod) || count($form->userid) != count($form->extendbase)) { - print_error('invalidformdata', '', $CFG->wwwroot.'/user/index.php?id='.$id); - } - - foreach ($form->userid as $k => $v) { - // find all roles this student have in this course - if ($students = $DB->get_records_sql("SELECT ra.id, ra.roleid, ra.timestart, ra.timeend - FROM {role_assignments} ra - WHERE userid = ? - AND contextid = ?", array($v, $context->id))) { - // enrol these users again, with time extension - // not that this is not necessarily a student role - foreach ($students as $student) { - // only extend if the user can make role assignments on this role - if (user_can_assign($context, $student->roleid)) { - switch($form->extendperiod[$k]) { - case 0: // No change - break; - case -1: // unlimited - $student->timeend = 0; - break; - default: // extend - switch($form->extendbase[$k]) { - case 0: // course start date - $student->timeend = $course->startdate + $form->extendperiod[$k]; - break; - case 1: // student enrolment start date - // we check for student enrolment date because Moodle versions before 1.9 did not set this for - // unlimited enrolment courses, so it might be 0 - if($student->timestart > 0) { - $student->timeend = $student->timestart + $form->extendperiod[$k]; - } - break; - case 2: // student enrolment start date - // enrolment end equals 0 means Unlimited, so adding some time to that will still yield Unlimited - if($student->timeend > 0) { - $student->timeend = $student->timeend + $form->extendperiod[$k]; - } - break; - case 3: // current date - $student->timeend = $today + $form->extendperiod[$k]; - break; - case 4: // course enrolment start date - if($course->enrolstartdate > 0) { - $student->timeend = $course->enrolstartdate + $form->extendperiod[$k]; - } - break; - case 5: // course enrolment end date - if($course->enrolenddate > 0) { - $student->timeend = $course->enrolenddate + $form->extendperiod[$k]; - } - break; - } - } - role_assign($student->roleid, $v, 0, $context->id, $student->timestart, $student->timeend, 0); - } - } - } - } - - redirect("$CFG->wwwroot/user/index.php?id=$id", get_string('changessaved')); -} - -/// Print headers - -$PAGE->navbar->add(get_string('extendenrol')); -$PAGE->set_title("$course->shortname: ".get_string('extendenrol')); -$PAGE->set_heading( $course->fullname); - -echo $OUTPUT->header(); - -$timeformat = get_string('strftimedate'); -$unlimited = get_string('unlimited'); -$periodmenu[-1] = $unlimited; -for ($i=1; $i<=365; $i++) { - $seconds = $i * 86400; - $periodmenu[$seconds] = get_string('numdays', '', $i); -} - -// this will contain all available the based On select options, but we'll disable some on them on a per user basis -$basemenu[0] = get_string('startdate') . ' (' . userdate($course->startdate, $timeformat) . ')'; -$basemenu[1] = get_string('enrolmentstart'); -$basemenu[2] = get_string('enrolmentend'); -if($course->enrollable != 2 || ($course->enrolstartdate == 0 || $course->enrolstartdate <= $today) && ($course->enrolenddate == 0 || $course->enrolenddate > $today)) { - $basemenu[3] = get_string('today') . ' (' . userdate($today, $timeformat) . ')' ; -} -if($course->enrollable == 2) { - if($course->enrolstartdate > 0) { - $basemenu[4] = get_string('courseenrolstartdate') . ' (' . userdate($course->enrolstartdate, $timeformat) . ')'; - } - if($course->enrolenddate > 0) { - $basemenu[5] = get_string('courseenrolenddate') . ' (' . userdate($course->enrolenddate, $timeformat) . ')'; - } -} - -$title = get_string('extendenrol'); -echo $OUTPUT->heading($title . $OUTPUT->old_help_icon('extendenrol', $title)); -echo "
\n"; -echo ''; -echo ''; -$table = new html_table(); -$table->head = array (get_string('fullnameuser'), get_string('enrolmentstart'), get_string('enrolmentend'), get_string('extendperiod'), get_string('startingfrom')); -$table->align = array ('left', 'center', 'center', 'center'); -$table->width = "600"; -$nochange = get_string('nochange'); -$notavailable = get_string('notavailable'); -foreach ($_POST as $k => $v) { - if (preg_match('/^user(\d+)$/',$k,$m)) { - - if (!($user = $DB->get_record_sql("SELECT * - FROM {user} u - JOIN {role_assignments} ra ON u.id=ra.userid - WHERE u.id=? AND ra.contextid = ?", array($m[1], $context->id)))) { - continue; - } - $userbasemenu = $basemenu; - if ($user->timestart) { - $timestart = userdate($user->timestart, $timeformat); - } else { - $timestart = $notavailable; - unset($userbasemenu[1]); - } - if ($user->timeend) { - $timeend = userdate($user->timeend, $timeformat); - } else { - $timeend = $unlimited; - unset($userbasemenu[2]); - } - - $checkbox = html_writer::select($periodmenu, "extendperiod[{$m[1]}]", "0", array('0'=>$nochange)); - $checkbox2 = html_writer::select($userbasemenu, "extendbase[{$m[1]}]", "2", false); - $table->data[] = array( - fullname($user, true), - $timestart, - $timeend, - ''.$checkbox, - $checkbox2); - } -} -echo html_writer::table($table); -echo "\n
\n\n"; - -echo $OUTPUT->footer(); - Index: lib/db/access.php =================================================================== --- lib/db/access.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lib/db/access.php (revision ) @@ -551,19 +551,6 @@ ) ), - 'moodle/role:unassignself' => array( - - 'captype' => 'write', - 'contextlevel' => CONTEXT_COURSE, - 'legacy' => array( - 'student' => (empty($CFG->allowunenrol)) ? CAP_INHERIT : CAP_ALLOW, - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'coursecreator' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - 'moodle/role:switchroles' => array( 'riskbitmask' => RISK_XSS | RISK_PERSONAL, @@ -682,6 +669,7 @@ /* originally this capability was called moodle/course:view, * but since 2.0 it is used for access to course without the enrolment + * TODO: remove when enrol migration finished! */ 'moodle/course:participate' => array( @@ -703,6 +691,32 @@ ) ), + /* review course enrolments */ + 'moodle/course:enrolreview' => array( + + 'riskbitmask' => RISK_PERSONAL, + + 'captype' => 'read', + 'contextlevel' => CONTEXT_COURSE, + 'legacy' => array( + 'editingteacher' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + ) + ), + + /* config enrol instances */ + 'moodle/course:enrolconfig' => array( + + 'riskbitmask' => RISK_PERSONAL, + + 'captype' => 'write', + 'contextlevel' => CONTEXT_COURSE, + 'legacy' => array( + 'editingteacher' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + ) + ), + 'moodle/course:bulkmessaging' => array( 'riskbitmask' => RISK_SPAM, @@ -774,18 +788,6 @@ ) ), - 'moodle/course:managemetacourse' => array( - - 'riskbitmask' => RISK_XSS | RISK_PERSONAL, - - 'captype' => 'write', - 'contextlevel' => CONTEXT_COURSE, - 'legacy' => array( - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - 'moodle/course:activityvisibility' => array( 'captype' => 'write', Index: enrol/self/lang/en/enrol_self.php =================================================================== --- enrol/self/lang/en/enrol_self.php (revision ) +++ enrol/self/lang/en/enrol_self.php (revision ) @@ -0,0 +1,57 @@ +. + +/** + * Strings for component 'enrol_self', language 'en', branch 'MOODLE_20_STABLE' + * + * @package enrol_self + * @copyright 2010 onwards Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$string['enrolenddate'] = 'End date'; +$string['enrolenddaterror'] = 'Enrolment end date cannot be earlier than start date'; +$string['enrolme'] = 'Enrol me'; +$string['enrolperiod'] = 'Enrolment period'; +$string['enrolperiod_desc'] = 'Default length of the enrolment period (in seconds).'; //TODO: fixme +$string['enrolstartdate'] = 'Start date'; +$string['groupkey'] = 'Use group enrolment keys'; +$string['groupkey_desc'] = 'Use group enrolment keys by default.'; +$string['password'] = 'Enrolment key'; +$string['passwordinvalid'] = 'Incorrect enrolment key, please try again'; +$string['passwordinvalidhint'] = 'That enrolment key was incorrect, please try again
+(Here\'s a hint - it starts with \'{$a}\')'; +$string['pluginname'] = 'Self enrolment'; +$string['pluginname_desc'] = 'The self enrolment plugin allows users to choose which courses they want to participate in. The courses may be protected by an enrolment key. Internally the enrolment is done via the manual enrolmnet plugin which has to be enabled in the same course.'; +$string['requirepassword'] = 'Require enrolment key'; +$string['requirepassword_desc'] = 'Require enrolment key in new courses and prevent prevent removing of access key from existing courses.'; +$string['role'] = 'Assign role'; +$string['role_desc'] = 'Select role which should be assigned to users during self enrolment'; +$string['sendcoursewelcomemessage'] = 'Send course welcome message'; +$string['sendcoursewelcomemessage_desc'] = 'If enabled, users receive a welcome message via email when they self-enrol in a course.'; +$string['showhint'] = 'Show hint'; +$string['showhint_desc'] = 'Show first letter of the guest access key.'; +$string['status'] = 'Allow self enrolments'; +$string['status_desc'] = 'Allow users to self enrol into course by default.'; +$string['usepasswordpolicy'] = 'Use password policy'; +$string['usepasswordpolicy_desc'] = 'Use standard password policy for enrolment keys.'; +$string['welcometocourse'] = 'Welcome to {$a}'; +$string['welcometocoursetext'] = 'Welcome to {$a->coursename}! + +If you have not done so already, you should edit your profile page so that we can learn more about you: + + {$a->profileurl}'; Index: user/index.php =================================================================== --- user/index.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ user/index.php (revision ) @@ -11,7 +11,6 @@ define('SHOW_ALL_PAGE_SIZE', 5000); define('MODE_BRIEF', 0); define('MODE_USERDETAILS', 1); - define('MODE_ENROLDETAILS', 2); $page = optional_param('page', 0, PARAM_INT); // which page to show $perpage = optional_param('perpage', DEFAULT_PAGE_SIZE, PARAM_INT); // how many per page @@ -194,7 +193,7 @@ $controlstable->data[] = new html_table_row(); /// Print my course menus - if ($mycourses = get_my_courses($USER->id)) { + if ($mycourses = enrol_get_my_courses()) { $courselist = array(); $popupurl = new moodle_url('/user/index.php?roleid='.$roleid.'&sifirst=&silast='); foreach ($mycourses as $mycourse) { @@ -268,27 +267,8 @@ } } - // Decide wheteher we will fetch extra enrolment/groups data. - // - // MODE_ENROLDETAILS is expensive, and only suitable where the listing is small - // (at or below DEFAULT_PAGE_SIZE) and $USER can enrol/unenrol - // (will take 1 extra DB query - 2 on Oracle) - // - if (!$isfrontpage && ($perpage <= DEFAULT_PAGE_SIZE) && has_capability('moodle/role:assign',$context)) { - $allowenroldetails = true; - } else { - $allowenroldetails = false; - if ($mode === MODE_ENROLDETAILS) { - // conditions haven't been met - reset - $mode = MODE_BRIEF; - } - } - $formatmenu = array( '0' => get_string('brief'), '1' => get_string('userdetails')); - if ($allowenroldetails) { - $formatmenu['2']= get_string('enroldetails'); - } $select = new single_select($baseurl, 'mode', $formatmenu, $mode, null, 'formatmenu'); $select->set_label(get_string('userlist')); $userlistcell = new html_table_cell(); @@ -345,22 +325,6 @@ $tableheaders[] = get_string('lastaccess'); } - if ($course->enrolperiod and $roleid) { - $tablecolumns[] = 'timeend'; - $tableheaders[] = get_string('enrolmentend'); - } - - if ($mode === MODE_ENROLDETAILS) { - $tablecolumns[] = 'roles'; - $tableheaders[] = get_string('roles'); - if ($groupmode != 0) { - $tablecolumns[] = 'groups'; - $tableheaders[] = get_string('groups'); - $tablecolumns[] = 'groupings'; - $tableheaders[] = get_string('groupings', 'group'); - } - } - if ($bulkoperations) { $tablecolumns[] = 'select'; $tableheaders[] = get_string('select'); @@ -398,7 +362,7 @@ // we are looking for all users with this role assigned in this context or higher $contextlist = get_related_contexts_string($context); - list($esql, $params) = get_enrolled_sql($context, NULL, $currentgroup, 'eu'); + list($esql, $params) = get_enrolled_sql($context, NULL, $currentgroup); $joins = array("FROM {user} u"); $wheres = array(); @@ -423,17 +387,7 @@ if ($accesssince) { $wheres[] = get_course_lastaccess_sql($accesssince); } - - if ($course->enrolperiod) { - // note: this is extremely tricky now, we do not know which ra assignment - // is the one causing enrolment - better show it onl when filtering by roles - - if ($roleid) { - $select .= ", (SELECT MAX(rax.timeend) FROM {role_assignments} rax WHERE rax.userid = u.id AND rax.contextid $contextlist AND rax.roleid = :raxroleid) AS timeend"; - $params['raxroleid'] = $roleid; - } + } - } - } // performance hacks - we preload user contexts together with accounts list($ccselect, $ccjoin) = context_instance_preload_sql('u.id', CONTEXT_USER, 'ctx'); @@ -490,17 +444,6 @@ // list of users at the current visible page - paging makes it relatively short $userlist = $DB->get_recordset_sql("$select $from $where $sort", $params, $table->get_page_start(), $table->get_page_size()); - // - // The SELECT behind get_participants_extra() is cheaper if we pass an array - // if IDs. We could pass the SELECT we did before (with the limit bits - tricky!) - // but this is much cheaper. And in any case, it is only doable with limited numbers - // of rows anyway. On a large course it will explode badly... - // - if ($mode === MODE_ENROLDETAILS) { - $userids = $DB->get_fieldset_sql("SELECT u.id $from $where", $params, $table->get_page_start(), $table->get_page_size()); - $userlist_extra = get_participants_extra($userids, $course, $context); - } - /// If there are multiple Roles in the course, then show a drop down menu for switching if (count($rolenames) > 1) { echo '
'; @@ -705,7 +648,7 @@ } if (has_capability('moodle/role:assign', $context) and get_user_roles($context, $user->id, false)) { // I can unassign and user has some role - $links[] = html_writer::link(new moodle_url('/course/unenrol.php?id='. $course->id .'&user='. $user->id), get_string('unenrol')); + $links[] = html_writer::link(new moodle_url('/enrol/unenrol.php?id='. $course->id .'&user='. $user->id), get_string('unenrol')); } if ($USER->id != $user->id && !session_is_loggedinas() && has_capability('moodle/user:loginas', $context) && !is_siteadmin($user->id)) { @@ -735,14 +678,6 @@ if ($userlist) { - // only show the plugin if multiple enrolment plugins - // are enabled... - if (strpos($CFG->enrol_plugins_enabled, ',')=== false) { - $showenrolplugin = true; - } else { - $showenrolplugin = false; - } - $usersprinted = array(); foreach ($userlist as $user) { if (in_array($user->id, $usersprinted)) { /// Prevent duplicates by r.hidden - MDL-13935 @@ -789,13 +724,6 @@ if (!isset($hiddenfields['lastaccess'])) { $data[] = $lastaccess; } - if ($course->enrolperiod and $roleid) { - if ($user->timeend) { - $data[] = userdate($user->timeend, $timeformat); - } else { - $data[] = get_string('unlimited'); - } - } if (isset($userlist_extra) && isset($userlist_extra[$user->id])) { $ras = $userlist_extra[$user->id]['ra']; @@ -809,12 +737,7 @@ } else { $rastring .= $rolename; } - if ($showenrolplugin) { - $rastring .= '
'; - } else { - $rastring .= ' ('. $ra['enrolplugin'] .')
'; - } + } - } $data[] = $rastring; if ($groupmode != 0) { // htmlescape with s() and implode the array @@ -846,11 +769,6 @@ $displaylist['groupaddnote.php'] = get_string('groupaddnewnote', 'notes'); } - if ($context->id != $frontpagectx->id) { - $displaylist['extendenrol.php'] = get_string('extendenrol'); - $displaylist['groupextendenrol.php'] = get_string('groupextendenrol'); - } - echo $OUTPUT->old_help_icon("participantswithselectedusers", get_string("withselectedusers")); echo html_writer::tag('label', get_string("withselectedusers"), array('for'=>'formactionid')); echo html_writer::select($displaylist, 'formaction', '', array(''=>'choosedots'), array('id'=>'formactionid')); @@ -940,7 +858,6 @@ ctx.contextlevel AS ctxlevel, ctx.instanceid AS ctxinstanceid, cc.name AS ccname, ra.roleid AS roleid, - ra.enrol AS enrolplugin, g.id AS gid, g.name AS gname $gpselect FROM {role_assignments} ra @@ -974,11 +891,6 @@ // ctxname => 'name' (categories only) // ctxinstid => // roleid => $roleid - // enrol => $pluginname - // - // Might be interesting to add to RA timestart, timeend, timemodified, - // and modifierid (with an outer join to mdl_user! - // foreach ($rs as $rec) { $userid = $rec->userid; @@ -1002,8 +914,7 @@ 'ctxlevel' => $rec->ctxlevel, 'ctxinstanceid' => $rec->ctxinstanceid, 'ccname' => $rec->ccname, - 'roleid' => $rec->roleid, - 'enrolplugin' => $rec->enrolplugin); + 'roleid' => $rec->roleid); } } Index: admin/settings/frontpage.php =================================================================== --- admin/settings/frontpage.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ admin/settings/frontpage.php (revision ) @@ -50,7 +50,6 @@ $temp->add(new admin_setting_configtext('commentsperpage', get_string('commentsperpage', 'admin'), '', 15, PARAM_INT)); $temp->add(new admin_setting_configtext('coursesperpage', get_string('coursesperpage', 'admin'), get_string('configcoursesperpage', 'admin'), 20, PARAM_INT)); - $temp->add(new admin_setting_configcheckbox('allowvisiblecoursesinhiddencategories', get_string('allowvisiblecoursesinhiddencategories', 'admin'), get_string('configvisiblecourses', 'admin'), 0)); // front page default role $roleoptions = array(0=>get_string('none')); // roles to choose from Index: lang/en/error.php =================================================================== --- lang/en/error.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ lang/en/error.php (revision ) @@ -104,7 +104,6 @@ $string['cannotmanualctrack'] = 'Activity does not provide manual completion tracking'; $string['cannotmapfield'] = 'Mapping collision detected - two fields maps to the same grade item {$a}'; $string['cannotmarktopic'] = 'Could not mark that topic for this course'; -$string['cannotmetacourse'] = 'Cannot not add the selected course to this meta course!'; $string['cannotmigratedatacomments'] = 'Cannot migrate data module comments'; $string['cannotmodulename'] = 'Cannot get the module name in build navigation'; $string['cannotmoduletype'] = 'Cannot get the module type in build navigation'; @@ -160,8 +159,6 @@ $string['cannotusepage2'] = 'Sorry, you may not use this page'; $string['cannotviewprofile'] = 'You cannot view the profile of this user'; $string['cannotwritefile'] = 'Cannot write to file ({$a})'; -$string['cantunenrollfrommetacourse'] = 'You cannot unenrol from this meta course'; -$string['cantunenrollinthisrole'] = 'You cannot unenrol from this course while you are in your current role'; $string['commentmisconf'] = 'Comment ID is misconfigured'; $string['componentisuptodate'] = 'Component is up-to-date'; $string['confirmsesskeybad'] = 'Sorry, but your session key could not be confirmed to carry out this action. This security feature prevents against accidental or malicious execution of important functions in your name. Please make sure you really wanted to execute this function.'; @@ -270,7 +267,6 @@ $string['invalidcoursenameshort'] = 'Invalid short course name'; $string['invaliddata'] = 'Data submitted is invalid'; $string['invalidelementid'] = 'Incorrect element id!'; -$string['invalidenrol'] = 'Illegal enrolment attempted'; $string['invalidentry'] = 'This is not valid entry!'; $string['invalidevent'] = 'Invalid event'; $string['invalidfieldname'] = '"{$a}" is not a valid field name'; @@ -409,6 +405,7 @@ $string['remotedownloaderror'] = 'Download of component to your server failed, please verify proxy settings, PHP cURL extension is highly recommended.

You must download the {$a->url} file manually, copy it to "{$a->dest}" in your server and unzip it there.'; $string['remotedownloadnotallowed'] = 'Download of components to your server isn\'t allowed (allow_url_fopen is disabled).

You must download the {$a->url} file manually, copy it to "{$a->dest}" in your server and unzip it there.'; $string['reportnotavailable'] = 'This type of report is only available for the site course'; +$string['requireloginerror'] = 'Cource or activity not accessible.'; $string['restorechecksumfailed'] = 'Some problem happened with the restore information stored in your session. Please check your PHP memory/DB package size limits. Restore stopped.'; $string['restrictedcontextexception'] = 'Sorry, execution of external function violates context restriction.'; $string['restricteduser'] = 'Sorry, but your current account "{$a}" is restricted from doing that'; Index: course/importstudents.php =================================================================== --- course/importstudents.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/importstudents.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,170 +0,0 @@ -. - -/** - * Script to assign students to a meta course by selecting which courses the meta - * course comprises. This is basically a hack of student.php that uses courses instead. - * - * @copyright 1999 Martin Dougiamas http://dougiamas.com - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @package course - */ - - require_once("../config.php"); - require_once("lib.php"); - - define("MAX_COURSES_PER_PAGE", 1000); - - $id = required_param('id',PARAM_INT); // course id - $add = optional_param('add', 0, PARAM_BOOL); - $remove = optional_param('remove', 0, PARAM_BOOL); - $showall = optional_param('showall', 0, PARAM_BOOL); - $searchtext = optional_param('searchtext', '', PARAM_RAW); // search string - $previoussearch = optional_param('previoussearch', 0, PARAM_BOOL); - $previoussearch = ($searchtext != '') or ($previoussearch) ? 1:0; - - $url = new moodle_url('/course/importstudents.php', array('id'=>$id)); - if ($add !== 0) { - $url->param('add', $add); - } - if ($remove !== 0) { - $url->param('remove', $remove); - } - if ($showall !== 0) { - $url->param('showall', $showall); - } - if ($searchtext !== '') { - $url->param('searchtext', $searchtext); - } - if ($previoussearch !== 0) { - $url->param('previoussearch', $previoussearch); - } - $PAGE->set_url($url); - - $site = get_site(); - - if (!$course = $DB->get_record('course', array('id'=>$id))) { - print_error("invalidcourseid"); - } - - require_login($course->id); - $context = get_context_instance(CONTEXT_COURSE, $course->id); - require_capability('moodle/course:managemetacourse', $context); - - if (!$course->metacourse) { - redirect("$CFG->wwwroot/course/view.php?id=$course->id"); - } - - $strassigncourses = get_string('metaassigncourses'); - $stralreadycourses = get_string('metaalreadycourses'); - $strnoalreadycourses = get_string('metanoalreadycourses'); - $strpotentialcourses = get_string('metapotentialcourses'); - $strnopotentialcourses = get_string('metanopotentialcourses'); - $straddcourses = get_string('metaaddcourse'); - $strremovecourse = get_string('metaremovecourse'); - $strsearch = get_string("search"); - $strsearchresults = get_string("searchresults"); - $strcourses = get_string("courses"); - $strshowall = get_string("showall"); - - $PAGE->navbar->add($strassigncourses); - $PAGE->set_title("$course->shortname: $strassigncourses"); - $PAGE->set_heading($site->fullname); - $PAGE->set_focuscontrol("searchtext"); - echo $OUTPUT->header(); - -/// Print a help notice about the need to use this page - - echo $OUTPUT->heading(get_string('childcourses')); - - if (!$frm = data_submitted()) { - $note = get_string("importmetacoursenote"); - echo $OUTPUT->box($note); - -/// A form was submitted so process the input - - } else { - if ($add and !empty($frm->addselect) and confirm_sesskey()) { - $timestart = $timeend = 0; - foreach ($frm->addselect as $addcourse) { - $addcourse = clean_param($addcourse, PARAM_INT); - set_time_limit(180); - if (!add_to_metacourse($course->id,$addcourse)) { - print_error("cannotmetacourse"); - } - } - } else if ($remove and !empty($frm->removeselect) and confirm_sesskey()) { - foreach ($frm->removeselect as $removecourse) { - set_time_limit(180); - $removecourse = clean_param($removecourse, PARAM_INT); - if (! remove_from_metacourse($course->id,$removecourse)) { - print_error("cannotremovefrommeta"); - } - } - } else if ($showall and confirm_sesskey()) { - $searchtext = ''; - $previoussearch = 0; - } - } - - -/// Get all existing students and teachers for this course. - if(! $alreadycourses = get_courses_in_metacourse($course->id)) { - $alreadycourses = array(); - } - - $numcourses = 0; - - -/// Get search results excluding any users already in this course - if (($searchtext != '') and $previoussearch and confirm_sesskey()) { - if ($searchcourses = get_courses_search(explode(" ",$searchtext),'fullname ASC',0,99999,$numcourses)) { - foreach ($searchcourses as $tmp) { - if (array_key_exists($tmp->id,$alreadycourses)) { - unset($searchcourses[$tmp->id]); - } - if (!empty($tmp->metacourse)) { - unset($searchcourses[$tmp->id]); - } - } - if (array_key_exists($course->id,$searchcourses)) { - unset($searchcourses[$course->id]); - } - $numcourses = count($searchcourses); - } - } - -/// If no search results then get potential students for this course excluding users already in course - if (empty($searchcourses)) { - $numcourses = count_courses_notin_metacourse($course->id); - - if ($numcourses > 0 and $numcourses <= MAX_COURSES_PER_PAGE) { - $courses = get_courses_notin_metacourse($course->id); - } else { - $courses = array(); - } - } - - echo $OUTPUT->box_start(); - - include('importstudents.html'); - - echo $OUTPUT->box_end(); - - echo $OUTPUT->footer(); - - Index: course/user.php =================================================================== --- course/user.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/user.php (revision ) @@ -54,7 +54,7 @@ $personalcontext = get_context_instance(CONTEXT_USER, $user->id); require_login(); -if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext) and !has_capability('moodle/course:participate', $coursecontext)) { +if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext) and !is_enrolled($coursecontext)) { // do not require parents to be enrolled in courses ;-) $PAGE->set_course($course); } else { Index: course/edit.php =================================================================== --- course/edit.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/edit.php (revision ) @@ -1,165 +1,154 @@ . + +/** + * Edit course settings + * + * @package moodlecore + * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + - require_once('../config.php'); +require_once('../config.php'); - require_once($CFG->dirroot.'/enrol/enrol.class.php'); - require_once('lib.php'); - require_once('edit_form.php'); +require_once('lib.php'); +require_once('edit_form.php'); - $id = optional_param('id', 0, PARAM_INT); // course id - $categoryid = optional_param('category', 0, PARAM_INT); // course category - can be changed in edit form +$id = optional_param('id', 0, PARAM_INT); // course id +$categoryid = optional_param('category', 0, PARAM_INT); // course category - can be changed in edit form - $PAGE->set_pagelayout('admin'); +$PAGE->set_pagelayout('admin'); +$PAGE->set_url('/course/edit.php'); -/// basic access control checks +// basic access control checks - if ($id) { // editing course +if ($id) { // editing course - - if($id == SITEID){ + if ($id == SITEID){ - // don't allow editing of 'site course' using this from - print_error('cannoteditsiteform'); - } + // don't allow editing of 'site course' using this from + print_error('cannoteditsiteform'); + } - if (!$course = $DB->get_record('course', array('id'=>$id))) { - print_error('invalidcourseid'); - } + $course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST); - require_login($course->id); + require_login($course->id); - $category = $DB->get_record('course_categories', array('id'=>$course->category)); + $category = $DB->get_record('course_categories', array('id'=>$course->category), '*', MUST_EXIST); - $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); - require_capability('moodle/course:update', $coursecontext); + $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); + require_capability('moodle/course:update', $coursecontext); + $PAGE->url->param('id',$id); + - } else if ($categoryid) { // creating new course in this category - $course = null; - require_login(); +} else if ($categoryid) { // creating new course in this category + $course = null; + require_login(); - if (!$category = $DB->get_record('course_categories', array('id'=>$categoryid))) { - print_error('unknowcategory'); - } + $category = $DB->get_record('course_categories', array('id'=>$categoryid), '*', MUST_EXIST); - require_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $category->id)); + require_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $category->id)); + $PAGE->url->param('category',$categoryid); + - } else { - require_login(); - print_error('needcoursecategroyid'); - } +} else { + require_login(); + print_error('needcoursecategroyid'); +} - $PAGE->set_url('/course/edit.php'); - if ($id !== 0) { - $PAGE->url->param('id',$id); - } else { - $PAGE->url->param('category',$categoryid); - } - - /// Prepare course and the editor +// Prepare course and the editor - $editoroptions = array('maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false, 'noclean'=>true); - if (!empty($course)) { - $allowedmods = array(); +$editoroptions = array('maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false, 'noclean'=>true); +if (!empty($course)) { + $allowedmods = array(); - if (!empty($course)) { - if ($am = $DB->get_records('course_allowed_modules', array('course'=>$course->id))) { - foreach ($am as $m) { - $allowedmods[] = $m->module; - } - } else { - if (empty($course->restrictmodules)) { - $allowedmods = explode(',',$CFG->defaultallowedmodules); - } // it'll be greyed out but we want these by default anyway. - } - $course->allowedmods = $allowedmods; + if ($am = $DB->get_records('course_allowed_modules', array('course'=>$course->id))) { + foreach ($am as $m) { + $allowedmods[] = $m->module; + } + } else { + if (empty($course->restrictmodules)) { + $allowedmods = explode(',',$CFG->defaultallowedmodules); + } // it'll be greyed out but we want these by default anyway. + } + $course->allowedmods = $allowedmods; - } - $course = file_prepare_standard_editor($course, 'summary', $editoroptions, $coursecontext, 'course_summary', $course->id); + $course = file_prepare_standard_editor($course, 'summary', $editoroptions, $coursecontext, 'course_summary', $course->id); + - } else { - $course = file_prepare_standard_editor($course, 'summary', $editoroptions, null, 'course_summary', null); - } +} else { + $course = file_prepare_standard_editor($course, 'summary', $editoroptions, null, 'course_summary', null); +} -/// first create the form +// first create the form - $editform = new course_edit_form('edit.php', compact('course', 'category', 'editoroptions')); +$editform = new course_edit_form('edit.php', compact('course', 'category', 'editoroptions')); + - // now override defaults if course already exists +// now override defaults if course already exists - if (!empty($course->id)) { - $course->enrolpassword = $course->password; // we need some other name for password field MDL-9929 - $editform->set_data($course); - } - if ($editform->is_cancelled()){ - if (empty($course)) { +if ($editform->is_cancelled()){ + if (empty($course)) { - redirect($CFG->wwwroot); + redirect($CFG->wwwroot.'/'); - } else { - redirect($CFG->wwwroot.'/course/view.php?id='.$course->id); - } + } else { + redirect($CFG->wwwroot.'/course/view.php?id='.$course->id); + } - } else if ($data = $editform->get_data()) { +} else if ($data = $editform->get_data()) { + // process data if submitted - $data->password = $data->enrolpassword; // we need some other name for password field MDL-9929 -/// process data if submitted - - //preprocess data - $data->timemodified = time(); + //preprocess data + $data->timemodified = time(); - if (empty($course->id)) { - // In creating the course + if (empty($course->id)) { + // In creating the course - if (!$course = create_course($data)) { - print_error('coursenotcreated'); - } + $course = create_course($data, $editoroptions, true); - // Get the context of the newly created course + // Get the context of the newly created course - $context = get_context_instance(CONTEXT_COURSE, $course->id); + $context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); - // Save the files used in the summary editor - $editordata = new stdClass; - $editordata->id = $course->id; - $editordata->summary_editor = $data->summary_editor; - $editordata = file_postupdate_standard_editor($editordata, 'summary', $editoroptions, $context, 'course_summary', $course->id); - $DB->update_record('course', $editordata); - - // assign default role to creator if not already having permission to manage course assignments - if (!is_viewing($context, NULL, 'moodle/role:assign') and !is_enrolled($context, NULL, 'moodle/role:assign')) { - role_assign($CFG->creatornewroleid, $USER->id, 0, $context->id); + // Redirect to manual enrolment page if possible - this is a big hack, we should improve it in future + if ($manuals = $DB->get_records('enrol', array('enrol'=>'manual', 'status'=>ENROL_STATUS_ENABLED), 'sortorder,id ASC')) { + if (has_capability('enrol/manual:manage', $context)) { + $manual = reset($manuals); + redirect($CFG->wwwroot."/enrol/manual/manage.php?enrolid=$manual->id&id=$course->id"); } - - // ensure we can use the course right after creating it - // this means trigger a reload of accessinfo... - mark_context_dirty($context->path); - - if ($data->metacourse and has_capability('moodle/course:managemetacourse', $context)) { - // Redirect users with metacourse capability to student import - redirect($CFG->wwwroot."/course/importstudents.php?id=$course->id"); - } else { - // Redirect to roles assignment - redirect($CFG->wwwroot."/$CFG->admin/roles/assign.php?contextid=$context->id"); - } + } + redirect($CFG->wwwroot."/course/view.php?id=$course->id"); - } else { - // Save any changes to the files used in the editor + } else { + // Save any changes to the files used in the editor - $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $coursecontext, 'course_summary', $data->id); - if (!update_course($data)) { - print_error('coursenotupdated'); - } + update_course($data, $editoroptions); - redirect($CFG->wwwroot."/course/view.php?id=$course->id"); - } - } + redirect($CFG->wwwroot."/course/view.php?id=$course->id"); + } +} -/// Print the form +// Print the form - $site = get_site(); +$site = get_site(); - $streditcoursesettings = get_string("editcoursesettings"); - $straddnewcourse = get_string("addnewcourse"); - $stradministration = get_string("administration"); - $strcategories = get_string("categories"); +$streditcoursesettings = get_string("editcoursesettings"); +$straddnewcourse = get_string("addnewcourse"); +$stradministration = get_string("administration"); +$strcategories = get_string("categories"); - if (!empty($course->id)) { - $PAGE->navbar->add($streditcoursesettings); - $title = $streditcoursesettings; - $fullname = $course->fullname; - } else { - $PAGE->navbar->add($stradministration, new moodle_url('/admin/index.php')); - $PAGE->navbar->add($strcategories, new moodle_url('/course/index.php')); - $PAGE->navbar->add($straddnewcourse); - $title = "$site->shortname: $straddnewcourse"; - $fullname = $site->fullname; - } +if (!empty($course->id)) { + $PAGE->navbar->add($streditcoursesettings); + $title = $streditcoursesettings; + $fullname = $course->fullname; +} else { + $PAGE->navbar->add($stradministration, new moodle_url('/admin/index.php')); + $PAGE->navbar->add($strcategories, new moodle_url('/course/index.php')); + $PAGE->navbar->add($straddnewcourse); + $title = "$site->shortname: $straddnewcourse"; + $fullname = $site->fullname; +} - $PAGE->set_title($title); - $PAGE->set_heading($fullname); - $PAGE->set_focuscontrol($editform->focus()); +$PAGE->set_title($title); +$PAGE->set_heading($fullname); +$PAGE->set_focuscontrol($editform->focus()); + - echo $OUTPUT->header(); - echo $OUTPUT->heading($streditcoursesettings); +echo $OUTPUT->header(); +echo $OUTPUT->heading($streditcoursesettings); - $editform->display(); +$editform->display(); - echo $OUTPUT->footer(); +echo $OUTPUT->footer(); Index: grade/report/overview/lib.php =================================================================== --- grade/report/overview/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ grade/report/overview/lib.php (revision ) @@ -111,8 +111,8 @@ public function fill_table() { global $CFG, $DB, $OUTPUT; - // MDL-11679, only show 'mycourses' instead of all courses - if ($courses = get_my_courses($this->user->id, 'c.sortorder ASC', 'id, shortname, showgrades')) { + // MDL-11679, only show user's courses instead of all courses + if ($courses = enrol_get_users_courses($this->user->id, false, 'id, shortname, showgrades')) { $numusers = $this->get_numusers(false); foreach ($courses as $course) { Index: user/groupextendenrol.php =================================================================== --- user/groupextendenrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ user/groupextendenrol.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) @@ -1,185 +0,0 @@ -. - -/** - * This file is part of the User section Moodle - * - * @copyright 1999 Martin Dougiamas http://dougiamas.com - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @package user - */ - -require_once("../config.php"); - -$id = required_param('id', PARAM_INT); // course id -$users = optional_param('userid', array(), PARAM_INT); // array of user id - -$PAGE->set_url('/user/groupextendenrol.php', array('id'=>$id)); - -if (! $course = $DB->get_record('course', array('id'=>$id))) { - print_error('invalidcourseid'); -} - -$context = get_context_instance(CONTEXT_COURSE, $id); -require_login($course->id); - -// to extend enrolments current user needs to be able to do role assignments -require_capability('moodle/role:assign', $context); -$today = time(); -$today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0); - -if ((count($users) > 0) and ($form = data_submitted()) and confirm_sesskey()) { - - foreach ($form->userid as $k => $v) { - // find all roles this student have in this course - if ($students = $DB->get_records_sql("SELECT ra.id, ra.roleid, ra.timestart, ra.timeend - FROM {role_assignments} ra - WHERE userid = ? - AND contextid = ?", array($v, $context->id))) { - // enrol these users again, with time extension - // not that this is not necessarily a student role - foreach ($students as $student) { - // only extend if the user can make role assignments on this role - if (user_can_assign($context, $student->roleid)) { - switch($form->extendperiod) { - case 0: // No change (currently this option is not available in dropdown list, but it might be ...) - break; - case -1: // unlimited - $student->timeend = 0; - break; - default: // extend - switch($form->extendbase) { - case 0: // course start date - $student->timeend = $course->startdate + $form->extendperiod; - break; - case 1: // student enrolment start date - // we check for student enrolment date because Moodle versions before 1.9 did not set this for - // unlimited enrolment courses, so it might be 0 - if($student->timestart > 0) { - $student->timeend = $student->timestart + $form->extendperiod; - } - break; - case 2: // student enrolment start date - // enrolment end equals 0 means Unlimited, so adding some time to that will still yield Unlimited - if($student->timeend > 0) { - $student->timeend = $student->timeend + $form->extendperiod; - } - break; - case 3: // current date - $student->timeend = $today + $form->extendperiod; - break; - case 4: // course enrolment start date - if($course->enrolstartdate > 0) { - $student->timeend = $course->enrolstartdate + $form->extendperiod; - } - break; - case 5: // course enrolment end date - if($course->enrolenddate > 0) { - $student->timeend = $course->enrolenddate + $form->extendperiod; - } - break; - } - } - role_assign($student->roleid, $v, 0, $context->id, $student->timestart, $student->timeend, 0); - } - } - } - } - - redirect("$CFG->wwwroot/user/index.php?id=$id", get_string('changessaved')); -} - -$PAGE->navbar->add(get_string('extendenrol')); -$PAGE->set_title("$course->shortname: ".get_string('extendenrol')); -$PAGE->set_heading($course->fullname); - -/// Print headers -echo $OUTPUT->header(); - -$timeformat = get_string('strftimedate'); -$unlimited = get_string('unlimited'); -$periodmenu[-1] = $unlimited; -for ($i=1; $i<=365; $i++) { - $seconds = $i * 86400; - $periodmenu[$seconds] = get_string('numdays', '', $i); -} - -$basemenu[0] = get_string('startdate') . ' (' . userdate($course->startdate, $timeformat) . ')'; -$basemenu[1] = get_string('enrolmentstart'); -$basemenu[2] = get_string('enrolmentend'); -if($course->enrollable != 2 || ($course->enrolstartdate == 0 || $course->enrolstartdate <= $today) && ($course->enrolenddate == 0 || $course->enrolenddate > $today)) { - $basemenu[3] = get_string('today') . ' (' . userdate($today, $timeformat) . ')' ; -} -if($course->enrollable == 2) { - if($course->enrolstartdate > 0) { - $basemenu[4] = get_string('courseenrolstartdate') . ' (' . userdate($course->enrolstartdate, $timeformat) . ')'; - } - if($course->enrolenddate > 0) { - $basemenu[5] = get_string('courseenrolenddate') . ' (' . userdate($course->enrolenddate, $timeformat) . ')'; - } -} - -$title = get_string('groupextendenrol'); -echo $OUTPUT->heading($title . $OUTPUT->old_help_icon('groupextendenrol', $title)); -echo '
'; -echo ''; -echo ''; -$table = new html_table(); -$table->head = array (get_string('fullnameuser'), get_string('enrolmentstart'), get_string('enrolmentend')); -$table->align = array ('left', 'center', 'center', 'center'); -$table->width = "600"; -$nochange = get_string('nochange'); -$notavailable = get_string('notavailable'); - -foreach ($_POST as $k => $v) { - if (preg_match('/^user(\d+)$/',$k,$m)) { - - if (!($user = $DB->get_record_sql("SELECT * - FROM {user} u - JOIN {role_assignments} ra ON u.id=ra.userid - WHERE u.id=? AND ra.contextid = ?", array($m[1], $context->id)))) { - continue; - } - if ($user->timestart) { - $timestart = userdate($user->timestart, $timeformat); - } else { - $timestart = $notavailable; - } - if ($user->timeend) { - $timeend = userdate($user->timeend, $timeformat); - } else { - $timeend = $unlimited; - } - $table->data[] = array( - fullname($user, true), - $timestart, - $timeend . '' - ); - } -} -echo html_writer::table($table); -echo '
'; -echo get_string('extendperiod') . ' '; -echo html_writer::select($periodmenu, 'extendperiod'); -echo ' ' . get_string('startingfrom') . ' '; -echo html_writer::select($basemenu, 'extendbase', '2', false); -echo '
'; -echo ''; -echo '
'; - -echo $OUTPUT->footer(); - Index: enrol/meta/lang/en/enrol_meta.php =================================================================== --- enrol/meta/lang/en/enrol_meta.php (revision ) +++ enrol/meta/lang/en/enrol_meta.php (revision ) @@ -0,0 +1,26 @@ +. + +/** + * Strings for component 'enrol_self', language 'en', branch 'MOODLE_20_STABLE' + * + * @package enrol_self + * @copyright 2010 onwards Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$string['pluginname'] = 'Course meta link'; Index: auth/shibboleth/index.php =================================================================== --- auth/shibboleth/index.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ auth/shibboleth/index.php (revision ) @@ -76,7 +76,7 @@ } } - check_enrolment_plugins($USER); + enrol_check_plugins($USER); load_all_capabilities(); /// This is what lets the user do anything on the site :-) redirect($urltogo); Index: lib/enrollib.php =================================================================== --- lib/enrollib.php (revision ) +++ lib/enrollib.php (revision ) @@ -0,0 +1,885 @@ +. + +/** + * This library includes the basic parts of enrol api. + * It is available on each page. + * + * @package moodlecore + * @copyright 2010 Petr Skoda (info@skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +/** Course enrol instance enabled. (used in enrol->status) */ +define('ENROL_STATUS_ENABLED', 0); + +/** Course enrol instance disabled, user may enter course if other enrol instance enabled. (used in enrol->status)*/ +define('ENROL_STATUS_DISABLED', 1); + +/** User is active participant (used in course_participation->status)*/ +define('ENROL_PARTICIPATION_ACTIVE', 0); + +/** User participation in course is suspended (used in course_participants->status) */ +define('ENROL_PARTICIPATION_SUSPENDED', 1); + +/** Enrol info is cached for this number of seconds in require_login() */ +define('ENROL_REQUIRE_LOGIN_CACHE_PERIOD', 1800); + +/** + * Returns instances of enrol plugins + * @param bool $enable return enabled only + * @return array of enrol plugins name=>instance + */ +function enrol_get_plugins($enabled) { + global $CFG; + + $result = array(); + + if ($enabled) { + // sorted by enabled plugin order + $enabled = explode(',', $CFG->enrol_plugins_enabled); + $plugins = array(); + foreach ($enabled as $plugin) { + $plugins[$plugin] = "$CFG->dirroot/enrol/$plugin"; + } + } else { + // sorted alphabetically + $plugins = get_plugin_list('enrol'); + ksort($plugins); + } + + foreach ($plugins as $plugin=>$location) { + if (!file_exists("$location/lib.php")) { + continue; + } + include_once("$location/lib.php"); + $class = "enrol_{$plugin}_plugin"; + if (!class_exists($class)) { + continue; + } + + $result[$plugin] = new $class(); + } + + return $result; +} + +/** + * Returns instance of enrol plugin + * @param string $name name of enrol plugin ('manual', 'guest', ...) + * @return enrol_plugin + */ +function enrol_get_plugin($name) { + global $CFG; + + if ($name !== clean_param($name, PARAM_SAFEDIR)) { + // ignore malformed plugin names completely + return null; + } + + $location = "$CFG->dirroot/enrol/$name"; + + if (!file_exists("$location/lib.php")) { + return null; + } + include_once("$location/lib.php"); + $class = "enrol_{$name}_plugin"; + if (!class_exists($class)) { + return null; + } + + return new $class(); +} + +/** + * Returns enrolment instances in given course. + * @param int $courseid + * @param bool $enabled + * @return array of enrol instances + */ +function enrol_get_instances($courseid, $enabled) { + global $DB, $CFG; + + if (!$enabled) { + return $DB->get_records('enrol', array('courseid'=>$courseid), 'sortorder,id'); + } + + $result = $DB->get_records('enrol', array('courseid'=>$courseid, 'status'=>ENROL_STATUS_ENABLED), 'sortorder,id'); +/* + $enabled = $enabled = explode(',', $CFG->enrol_plugins_enabled); + foreach ($result as $key=>$enrol) { + if (!in_array($enrol->enrol, $enabled)) { + unset($result[$key]); + } + } +*/ + return $result; +} + +/** + * Checks if a given plugin is in the list of enabled enrolment plugins. + * + * @param string $enrol Enrolment plugin name + * @return boolean Whether the plugin is enabled + */ +function enrol_is_enabled($enrol) { + global $CFG; + + return in_array($enrol, explode(',', $CFG->enrol_plugins_enabled)); +} + +/** + * Check all the login enrolment information for the given user object + * by querying the enrolment plugins + * + * @param object $user + * @return void + */ +function enrol_check_plugins($user) { + global $CFG; + + if (empty($user->id) or isguestuser($user)) { + // shortcut - there is no enrolment work for guests and not-logged-in users + return; + } + + static $inprogress = array(); // To prevent this function being called more than once in an invocation + + if (!empty($inprogress[$user->id])) { + return; + } + + $inprogress[$user->id] = true; // Set the flag + + $enabled = enrol_get_plugins(true); + + foreach($enabled as $enrol) { + $enrol->sync_user_enrolments($user); + } + + unset($inprogress[$user->id]); // Unset the flag +} + +/** + * This function adds necessary enrol plugins UI into the course edit form. + * + * @param MoodleQuickForm $mform + * @param object $data course edit form data + * @param object $context context of existing course or parent category if course does not exist + * @return void + */ +function enrol_course_edit_form(MoodleQuickForm $mform, $data, $context) { + global $DB, $CFG; + + $enabled = explode(',', $CFG->enrol_plugins_enabled); + $default = explode(',', $CFG->enrol_plugins_default); + + if (!empty($data->id)) { + $instances = $DB->get_records('enrol', array('courseid'=>$data->id), 'sortorder,id'); + foreach ($instances as $instance) { + if (!in_array($instance->enrol, $enabled)) { + continue; + } + if (!$plugin = enrol_get_plugin($instance->enrol)) { + continue; + } + $plugin->course_edit_form($instance, $mform, $data, $context); + } + } else { + foreach ($enabled as $enrol) { + if (!in_array($enrol, $default)) { + continue; + } + if (!$plugin = enrol_get_plugin($enrol)) { + continue; + } + $plugin->course_edit_form(NULL, $mform, $data, $context); + } + } +} + +/** + * Validate course edit form data + * + * @param array $data raw form data + * @param object $context context of existing course or parent category if course does not exist + * @return array errors array + */ +function enrol_course_edit_validation(array $data, $context) { + global $DB, $CFG; + + $errors = array(); + + $enabled = explode(',', $CFG->enrol_plugins_enabled); + $default = explode(',', $CFG->enrol_plugins_default); + + if (!empty($data['id'])) { + $instances = $DB->get_records('enrol', array('courseid'=>$data['id']), 'sortorder,id'); + foreach ($instances as $instance) { + if (!in_array($instance->enrol, $enabled)) { + continue; + } + if (!$plugin = enrol_get_plugin($instance->enrol)) { + continue; + } + $errors = array_merge($errors, $plugin->course_edit_validation($instance, $data, $context)); + } + } else { + foreach ($enabled as $enrol) { + if (!in_array($enrol, $default)) { + continue; + } + if (!$plugin = enrol_get_plugin($enrol)) { + continue; + } + $errors = array_merge($errors, $plugin->course_edit_validation(NULL, $data, $context)); + } + } + + return $errors; +} + +/** + * Update enrol instances after course edit form submission + * @rapam bool $inserted true means new course added, false course already existed + * @param object $course + * @param object $data form data + * @return void + */ +function enrol_course_updated($inserted, $course, $data) { + global $DB, $CFG; + + $enabled = explode(',', $CFG->enrol_plugins_enabled); + $default = explode(',', $CFG->enrol_plugins_default); + + if (!$inserted) { + $instances = $DB->get_records('enrol', array('courseid'=>$course->id), 'sortorder,id'); + foreach ($instances as $instance) { + if (!in_array($instance->enrol, $enabled)) { + continue; + } + if (!$plugin = enrol_get_plugin($instance->enrol)) { + continue; + } + $plugin->course_updated($instance, $course, $data); + } + } else { + foreach ($enabled as $enrol) { + if (!in_array($enrol, $default)) { + continue; + } + if (!$plugin = enrol_get_plugin($enrol)) { + continue; + } + $plugin->course_updated(NULL, $course, $data); + } + } +} + +/** + * Returns list of enrol instances that can be added to a course + * @param int $courseid + * @return array of enrol plugin names + */ +function enrol_get_instance_candidates($courseid) { + $instances = enrol_get_instances($courseid, false); + $plugins = enrol_get_plugins(true); + $candidates = array(); + + //TODO: add support for mutiple instances of the same type in one course + foreach ($instances as $instance) { + unset($plugins[$instance->enrol]); + } + + foreach ($plugins as $name=>$ignored) { + $candidates[$name] = get_string('pluginname', 'enrol_'.$name); + } + + return $candidates; +} + +/** + * Returns list of courses current $USER is enrolled in and can access + * + * - $fields is an array of fieldnames to ADD + * so name the fields you really need, which will + * be added and uniq'd + * + * @param strin|array $fields + * @param string $sort + * @param int $limit max number of courses + * @return array + */ +function enrol_get_my_courses($fields = NULL, $sort = 'visible DESC,sortorder ASC', $limit = 0) { + global $DB, $USER; + + // Guest account does not have any courses + if (isguestuser() or !isloggedin()) { + return(array()); + } + + $basefields = array('id', 'category', 'sortorder', + 'shortname', 'fullname', 'idnumber', + 'startdate', 'visible', + 'groupmode', 'groupmodeforce'); + + if (empty($fields)) { + $fields = $basefields; + } else if (is_string($fields)) { + // turn the fields from a string to an array + $fields = explode(',', $fields); + $fields = array_map('trim', $fields); + $fields = array_unique(array_merge($basefields, $fields)); + } else if (is_array($fields)) { + $fields = array_unique(array_merge($basefields, $fields)); + } else { + throw new coding_exception('Invalid $fileds parameter in enrol_get_my_courses()'); + } + if (in_array('*', $fields)) { + $fields = array('*'); + } + + $orderby = ""; + $sort = trim($sort); + if (!empty($sort)) { + $rawsorts = explode(',', $sort); + $sorts = array(); + foreach ($rawsorts as $rawsort) { + $rawsort = trim($rawsort); + if (strpos($rawsort, 'c.') === 0) { + $rawsort = substr($rawsort, 2); + } + $sorts[] = trim($rawsort); + } + $sort = 'c.'.implode(',c.', $sorts); + $orderby = "ORDER BY $sort"; + } + + $wheres = array("c.id <> :siteid"); + $params = array('siteid'=>SITEID); + + if (isset($USER->loginascontext) and $USER->loginascontext->contextlevel == CONTEXT_COURSE) { + // list _only_ this course - anything else is asking for trouble... + $wheres[] = "courseid = :loginas"; + $params['loginas'] = $USER->loginascontext->instanceid; + } + + $coursefields = 'c.' .join(',c.', $fields); + list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx'); + $wheres = " AND ".implode(" AND ", $wheres); + + $sql = "SELECT DISTINCT $coursefields $ccselect + FROM {course} c + JOIN {enrol} e ON (e.courseid = c.id AND e.status = :enabled) + JOIN {course_participants} cp ON (cp.enrolid = e.id AND cp.userid = :userid AND cp.status = :active) + $ccjoin + WHERE cp.timestart < :now1 AND (cp.timeend = 0 OR cp.timeend > :now2) + $wheres + $orderby"; + $params['userid'] = $USER->id; + $params['active'] = ENROL_PARTICIPATION_ACTIVE; + $params['enabled'] = ENROL_STATUS_ENABLED; + $params['now1'] = round(time(), -2); // improves db caching + $params['now2'] = $params['now1']; + + $courses = $DB->get_records_sql($sql, $params, 0, $limit); + + // preload contexts and check visibility + foreach ($courses as $id=>$course) { + context_instance_preload($course); + if (!$course->visible) { + if (!$context = get_context_instance(CONTEXT_COURSE, $id)) { + unset($course[$id]); + continue; + } + if (!has_capability('moodle/course:viewhiddencourses', $context)) { + unset($course[$id]); + continue; + } + } + $courses[$id] = $course; + } + + //wow! Is that really all? :-D + + return $courses; +} + +/** + * Returns list of courses user is enrolled into. + * + * - $fields is an array of fieldnames to ADD + * so name the fields you really need, which will + * be added and uniq'd + * + * @param int $userid + * @param bool $onlyactive return only active enrolments in courses user may see + * @param strin|array $fields + * @param string $sort + * @return array + */ +function enrol_get_users_courses($userid, $onlyactive = false, $fields = NULL, $sort = 'visible DESC,sortorder ASC') { + global $DB; + + // Guest account does not have any courses + if (isguestuser($userid) or !empty($userid)) { + return(array()); + } + + $basefields = array('id', 'category', 'sortorder', + 'shortname', 'fullname', 'idnumber', + 'startdate', 'visible', + 'groupmode', 'groupmodeforce'); + + if (empty($fields)) { + $fields = $basefields; + } else if (is_string($fields)) { + // turn the fields from a string to an array + $fields = explode(',', $fields); + $fields = array_map('trim', $fields); + $fields = array_unique(array_merge($basefields, $fields)); + } else if (is_array($fields)) { + $fields = array_unique(array_merge($basefields, $fields)); + } else { + throw new coding_exception('Invalid $fileds parameter in enrol_get_my_courses()'); + } + if (in_array('*', $fields)) { + $fields = array('*'); + } + + $orderby = ""; + $sort = trim($sort); + if (!empty($sort)) { + $rawsorts = explode(',', $sort); + $sorts = array(); + foreach ($rawsorts as $rawsort) { + $rawsort = trim($rawsort); + if (strpos($rawsort, 'c.') === 0) { + $rawsort = substr($rawsort, 2); + } + $sorts[] = trim($rawsort); + } + $sort = 'c.'.implode(',c.', $sorts); + $orderby = "ORDER BY $sort"; + } + + $wheres = array("c.id <> :siteid"); + $params = array('siteid'=>SITEID); + + if ($onlyactive) { + $wheres[] = "cp.status = :active"; + $wheres[] = "e.status = :enabled"; + $wheres[] = "cp.timestart < :now1 AND (cp.timeend = 0 OR cp.timeend > :now2)"; + $params['now1'] = round(time(), -2); // improves db caching + $params['now2'] = $params['now1']; + $params['active'] = ENROL_PARTICIPATION_ACTIVE; + $params['enabled'] = ENROL_STATUS_ENABLED; + } + + $coursefields = 'c.' .join(',c.', $fields); + list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx'); + $wheres = "WHERE ".implode(" AND ", $wheres); + + $sql = "SELECT DISTINCT $coursefields $ccselect + FROM {course} c + JOIN {enrol} e ON (e.courseid = c.id) + JOIN {course_participants} cp ON (cp.enrolid = e.id AND cp.userid = :userid) + $ccjoin + $wheres + $orderby"; + $params['userid'] = $USER->id; + + $courses = $DB->get_records_sql($sql, $params); + + // preload contexts and check visibility + foreach ($courses as $id=>$course) { + context_instance_preload($course); + if ($onlyactive) { + if (!$course->visible) { + if (!$context = get_context_instance(CONTEXT_COURSE, $id)) { + unset($course[$id]); + continue; + } + if (!has_capability('moodle/course:viewhiddencourses', $context, $userid)) { + unset($course[$id]); + continue; + } + } + } + $courses[$id] = $course; + } + + //wow! Is that really all? :-D + + return $courses; + +} + +/** + * All enrol plugins should be based on this class, + * this is also the main source of documentation. + */ +abstract class enrol_plugin { + protected $config = null; + + /** + * Returns name of this enrol plugin + * @return string + */ + public function get_name() { + // second word in class is always enrol name + $words = explode('_', get_class($this)); + return $words[1]; + } + + /** + * Makes sure config is loaded and cached. + * @return void + */ + protected function load_config() { + if (!isset($this->config)) { + $name = $this->get_name(); + if (!$config = get_config("enrol_$name")) { + $config = new object(); + } + $this->config = $config; + } + } + + /** + * Returns plugin config value + * @param string $name + * @param string $default value if config does not exist yet + * @return string value or default + */ + public function get_config($name, $default = NULL) { + $this->load_config(); + return isset($this->config->$name) ? $this->config->$name : $default; + } + + /** + * Sets plugin config value + * @param string $name name of config + * @param string $value string config value, null means delete + * @return string value + */ + public function set_config($name, $value) { + $name = $this->get_name(); + $this->load_config(); + if ($value === NULL) { + unset($this->config->$name); + } else { + $this->config->$name = $value; + } + set_config($name, $value, "enrol_$name"); + } + + /** + * Attempt to automatically enrol current user in course without any interaction, + * calling code has to make sure the plugin and instance are active. + * + * @param stdClass $instance course enrol instance + * @param stdClass $user record + * @return bool|int false means not enrolled, integer means timeend + */ + public function try_autoenrol(stdClass $instance) { + global $USER; + + return false; + } + + /** + * Attempt to automatically gain temporary guest access to course, + * calling code has to make sure the plugin and instance are active. + * + * @param stdClass $instance course enrol instance + * @param stdClass $user record + * @return bool|int false means no guest access, integer means timeend + */ + public function try_guestaccess(stdClass $instance) { + global $USER; + + return false; + } + + /** + * Enrol user into course via enrol instance. + * + * @param stdClass $instance + * @param int $userid + * @param int $timestart + * @param int $timeend + * @param int $roleid optional role id + * @return void + */ + public function enrol_user(stdClass $instance, $userid, $timestart = 0, $timeend = 0, $roleid = null) { + global $DB, $USER, $CFG; // CFG necessary!!! + + $name = $this->get_name(); + $courseid = $instance->courseid; + + if ($instance->enrol !== $name) { + throw coding_exception('invalid enrol instance!'); + } + $context = get_context_instance(CONTEXT_COURSE, $instance->courseid, MUST_EXIST); + + if (!$DB->record_exists('course_participants', array('enrolid'=>$instance->id, 'userid'=>$userid))) { + $cp = new object(); + $cp->enrolid = $instance->id; + $cp->status = ENROL_PARTICIPATION_ACTIVE; + $cp->userid = $userid; + $cp->timestart = $timestart; + $cp->timeend = $timeend; + $cp->modifier = $USER->id; + $cp->timemodified = time(); + $DB->insert_record('course_participants', $cp); + } + + if ($roleid) { + role_assign($roleid, $userid, $context->id, 'enrol_'.$name, $instance->id); + } + + //TODO: trigger 'enrolled' event and log + + // inform all modules just in case they want to set up something + $mods = get_plugin_list('mod'); + foreach ($mods as $mod => $moddir) { + if (!file_exists($moddir.'/lib.php')) { + continue; + } + include_once($moddir.'/lib.php'); + $functionname = $mod.'_user_enrolled'; + if (function_exists($functionname)) { + $functionname($userid, $courseid); + } + } + } + + /** + * Unenrol user from course, + * the last unenrolment removes all remaining roles. + * + * @param stdClass $instance + * @param int $userid + * @return void + */ + public function unenrol_user(stdClass $instance, $userid) { + global $CFG, $DB; + + $name = $this->get_name(); + $courseid = $instance->courseid; + + if ($instance->enrol !== $name) { + throw coding_exception('invalid enrol instance!'); + } + $context = get_context_instance(CONTEXT_COURSE, $instance->courseid, MUST_EXIST); + + $DB->delete_records('course_participants', array('enrolid'=>$instance->id, 'userid'=>$userid)); + + role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_'.$name, 'enrolid'=>$instance->id)); + + $sql = "SELECT 'x' + FROM {course_participants} cp + JOIN {enrol} e ON (e.id = cp.enrolid) + WHERE cp.userid = :userid AND e.courseid = :courseid"; + if ($DB->record_exists_sql($sql, array('userid'=>$userid, 'courseid'=>$courseid))) { + // user still has some enrolments, no need to cleanup yet + return; + } + + // the big cleanup ahead! + + require_once($CFG->dirroot.'/group/lib.php'); + require_once($CFG->libdir.'/gradelib.php'); + + // remove all roles + role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id), true, false); + + //clean up ALL invisible user data from course if this is the last enrolment - groups, grades, etc. + groups_delete_group_members($courseid, $userid); + + // delete all grades - backup is kept in grade_grades_history table +/* if ($grades = .... somehow fetch the grades ...) { + foreach ($grades as $grade) { + $grade->delete('unenrol'); + } + }*/ + + $DB->delete_records('user_lastaccess', array('userid'=>$userid, 'courseid'=>$courseid)); + + //TODO: trigger 'unenrolled' event and log + + // finally inform all modules just in case they need to get rid of some data + $mods = get_plugin_list('mod'); + foreach ($mods as $mod => $moddir) { + if (!file_exists($moddir.'/lib.php')) { + continue; + } + include_once($moddir.'/lib.php'); + $functionname = $mod.'_user_unenrolled'; + if (function_exists($functionname)) { + $functionname($userid, $courseid); + } + } + } + + /** + * Forces synchronisation of user enrolments. + * + * This is important especially for external enrol plugins, + * this function is called for all enabled enrol plugins + * right after every user login. + * + * @param object $user user record + * @return void + */ + public function sync_user_enrolments($user) { + // override if necessary + } + + /** + * Adds enrol instance UI to course edit form + * + * @param object $instance enrol instance or null if does not exist yet + * @param MoodleQuickForm $mform + * @param object $data + * @param object $context context of existing course or parent category if course does not exist + * @return void + */ + public function course_edit_form($instance, MoodleQuickForm $mform, $data, $context) { + // override - usually at least enable/disable switch, has to add own form header + } + + /** + * Validates course edit form data + * + * @param object $instance enrol instance or null if does not exist yet + * @param array $data + * @param object $context context of existing course or parent category if course does not exist + * @return array errors array + */ + public function course_edit_validation($instance, array $data, $context) { + return array(); + } + + /** + * Called after updating/inserting course. + * + * @param object $instance enrol instance, null if does not exist yet + * @param object $course + * @param object $data form data + * @return void + */ + public function course_updated($instance, $course, $data) { + // override - usually at least status handling + } + + /** + * Add new instance of enrol plugin with default settings. + * @param object $course + * @return int id of new instance + */ + public function add_default_instance($course) { + global $DB; + + $instance = new object(); + $instance->enrol = $this->get_name(); + $instance->status = $this->get_config('status', ENROL_STATUS_DISABLED); + $instance->courseid = $course->id; + $instance->timemodified = time(); + $instance->timecreated = $instance->timemodified; + $instance->sortorder = $DB->get_field('enrol', 'COALESCE(MAX(sortorder), -1) + 1', array('courseid'=>$course->id)); + + return $DB->insert_record('enrol', $instance); + } + + /** + * Delete course enrol plugin instance, unenrol all users. + * @param object $instance + * @return void + */ + public function delete_instance($instance) { + global $DB; + + $name = $this->get_name(); + if ($instance->enrol !== $name) { + throw coding_exception('invalid enrol instance!'); + } + + //first unenroll all users + $participants = $DB->get_recordset('course_participants', array('enrolid'=>$instance->id)); + foreach ($participants as $participant) { + $this->unenrol_user($instance, $participant->userid); + } + $participants->close(); + + // now clean up all remainders that were not removed correctly + $DB->delete_records('role_assignments', array('enrolid'=>$instance->id)); + $DB->delete_records('course_participants', array('enrolid'=>$instance->id)); + + // finally drop the enrol row + $DB->delete_records('enrol', array('id'=>$instance->id)); + } + + /** + * Creates course enrol form, checks if form submitted + * and enrols user if necessary. It can also redirect. + * + * @param stdClass $instance + * @return string html text, usually a form in a text box + */ + public function enrol_page_hook(stdClass $instance) { + return null; + } + + public function setup_manage_tabs($instance, &$currenttab, &$toprow, &$inactive, &$activetwo, &$secondrow) { + // override when plugin supports managing of users, etc. in each instance + } + + /** + * Reads version.php and determines if it is necessary + * to execute the cron job now. + * @return bool + */ + public function is_cron_required() { + global $CFG; + + $name = $this->get_name(); + $versionfile = "$CFG->dirroot/enrol/$name/version.php"; + $plugin = new object(); + include($versionfile); + if (empty($plugin->cron)) { + return false; + } + $lastexecuted = $this->get_config('lastcron', 0); + if ($lastexecuted + $plugin->cron < time()) { + return true; + } else { + return false; + } + } + + /** + * Called for all enabled enrol plugins that returned true from is_cron_required(). + * @return void + */ + public function cron() { + } + +} + Index: lang/en/enrol.php =================================================================== --- lang/en/enrol.php (revision ) +++ lang/en/enrol.php (revision ) @@ -0,0 +1,41 @@ +. + +/** + * Strings for component 'core_enrol', language 'en', branch 'MOODLE_20_STABLE' + * + * @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 + */ + +$string['actenrolshhdr'] = 'Active course enrolment plugins'; +$string['addinstance'] = 'Add instance'; +$string['configenrolplugins'] = 'Please select all required plugins and arrange then in appropriate order.'; +$string['defaultenrols'] = 'Default enrol plugins'; +$string['defaultenrols_desc'] = 'Select all enrol plugins that should available in new courses by default.'; +$string['deleteinstanceconfirm'] = 'Do you really want to delete enrol plugin instance "{$a->name}" with {$a->users} enrolled users?'; +$string['enrolcandidates'] = 'Not enrolled users'; +$string['enrolcandidatesmatching'] = 'Matching not enrolled users'; +$string['enrolledusers'] = 'Enrolled users'; +$string['enrolledusersmatching'] = 'Matching enrolled users'; +$string['enrolusage'] = 'Instances / enrolments'; +$string['manageenrols'] = 'Manage enrol plugins'; +$string['notenrollable'] = 'This course is not enrollable at the moment.'; +$string['uninstallconfirm'] = 'You are about to completely delete the enrol plugin \'{$a}\'. This will completely delete everything in the database associated with this enrolment type. Are you SURE you want to continue?'; +$string['uninstalldeletefiles'] = 'All data associated with the enrol plugin \'{$a->plugin}\' has been deleted from the database. To complete the deletion (and prevent the plugin re-installing itself), you should now delete this directory from your server: {$a->directory}'; Index: enrol/tabs.php =================================================================== --- enrol/tabs.php (revision ) +++ enrol/tabs.php (revision ) @@ -0,0 +1,56 @@ +. + +/** + * Enrolment tabs. + * + * @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 + */ + +// expects $course, $context and $currenttab + +$toprow = array(); +$inactive = array(); +$activetwo = array(); +$secondrow = array(); + +if (has_capability('moodle/course:enrolreview', $context)) { + $url = new moodle_url('/enrol/review.php', array('id'=>$course->id)); + $toprow[] = new tabobject('review', $url, get_string('enrolments')); +} + +// give each enrol plugin a chance to add some tabs (exclude disabled plugins, but include inactive instances) +$taballplugins = enrol_get_plugins(true); +$tabinstances = $DB->get_records('enrol', array('courseid'=>$course->id), 'sortorder ASC, id ASC'); +foreach($tabinstances as $tabinstance) { + if (!isset($taballplugins[$tabinstance->enrol])) { + continue; + } + $taballplugins[$tabinstance->enrol]->setup_manage_tabs($tabinstance, $currenttab, $toprow, $inactive, $activetwo, $secondrow); +} + +$inactive[] = $currenttab; +$tabs = array($toprow); + +/// If there are any secondrow defined, let's introduce it +if (!empty($secondrow)) { + $tabs[] = $secondrow; +} + +print_tabs($tabs, $currenttab, $inactive, $activetwo); Index: enrol/database/enrol_database_sync.php =================================================================== --- enrol/database/enrol_database_sync.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ enrol/database/enrol_database_sync.php (revision ) @@ -14,7 +14,7 @@ // ensure errors are well explained $CFG->debug=E_ALL; - if (!is_enabled_enrol('database')) { + if (!enrol_is_enabled('database')) { error_log("Database enrol plugin not enabled!"); die; } @@ -33,9 +33,5 @@ $enrol->sync_enrolments($role); } - // sync metacourses - if (function_exists('sync_metacourses')) { - sync_metacourses(); - } Index: course/report/log/lib.php =================================================================== --- course/report/log/lib.php (revision de4bf1ff9d6a12d5f77c47362c2de3b6496f026a) +++ course/report/log/lib.php (revision ) @@ -88,7 +88,7 @@ // If looking at a different host, we're interested in all our site users if ($hostid == $CFG->mnet_localhost_id && $course->id != SITEID) { - $courseusers = get_users_by_capability($context, 'moodle/course:participate', 'u.id, u.firstname, u.lastname, u.idnumber', 'lastname ASC, firstname ASC', $limitfrom, $limitnum, $selectedgroup,'', false); + $courseusers = get_enrolled_users($context, '', $selectedgroup, 'u.id, u.firstname, u.lastname, u.idnumber', 'lastname ASC, firstname ASC', $limitfrom, $limitnum); } else { // this may be a lot of users :-( $courseusers = $DB->get_records('user', array('deleted'=>0), 'lastaccess DESC', 'id, firstname, lastname, idnumber', $limitfrom, $limitnum); @@ -356,12 +356,7 @@ // Get all the possible users $users = array(); - if ($course->id != SITEID) { - $courseusers = get_users_by_capability($context, 'moodle/course:participate', 'u.id, u.firstname, u.lastname, u.idnumber', 'lastname ASC, firstname ASC', '','',$selectedgroup,null, false); - } else { - // this may be a lot of users :-( - $courseusers = $DB->get_records('user', array('deleted'=>0), 'lastaccess DESC', 'id, firstname, lastname, idnumber'); - } + $courseusers = get_enrolled_users($context, $selectedgroup, 'u.id, u.firstname, u.lastname, u.idnumber', 'lastname ASC, firstname ASC'); if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$showusers) { $showusers = 1;