mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 08:56:36 +02:00
MDL-39846 convert enrol_category to new events and class loader
This commit is contained in:
parent
b474bec396
commit
e99a209094
4 changed files with 164 additions and 145 deletions
148
enrol/category/classes/observer.php
Normal file
148
enrol/category/classes/observer.php
Normal file
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Local stuff for category enrolment plugin.
|
||||
*
|
||||
* @package enrol_category
|
||||
* @copyright 2010 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Event handler for category enrolment plugin.
|
||||
*
|
||||
* We try to keep everything in sync via listening to events,
|
||||
* it may fail sometimes, so we always do a full sync in cron too.
|
||||
*/
|
||||
class enrol_category_observer {
|
||||
/**
|
||||
* Triggered when user is assigned a new role.
|
||||
*
|
||||
* @param \core\event\role_assigned $event
|
||||
*/
|
||||
public static function role_assigned(\core\event\role_assigned $event) {
|
||||
global $DB;
|
||||
|
||||
if (!enrol_is_enabled('category')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ra = $event->get_cached_record('role_assignments', $event->extra['id']);
|
||||
|
||||
//only category level roles are interesting
|
||||
$parentcontext = context::instance_by_id($ra->contextid);
|
||||
if ($parentcontext->contextlevel != CONTEXT_COURSECAT) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the role is to be actually synchronised,
|
||||
// please note we are ignoring overrides of the synchronised capability (for performance reasons in full sync).
|
||||
$syscontext = context_system::instance();
|
||||
if (!$DB->record_exists('role_capabilities', array('contextid'=>$syscontext->id, 'roleid'=>$ra->roleid, 'capability'=>'enrol/category:synchronised', 'permission'=>CAP_ALLOW))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add necessary enrol instances.
|
||||
$plugin = enrol_get_plugin('category');
|
||||
$sql = "SELECT c.*
|
||||
FROM {course} c
|
||||
JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :courselevel AND ctx.path LIKE :match)
|
||||
LEFT JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'category')
|
||||
WHERE e.id IS NULL";
|
||||
$params = array('courselevel'=>CONTEXT_COURSE, 'match'=>$parentcontext->path.'/%');
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
foreach ($rs as $course) {
|
||||
$plugin->add_instance($course);
|
||||
}
|
||||
$rs->close();
|
||||
|
||||
// Now look for missing enrolments.
|
||||
$sql = "SELECT e.*
|
||||
FROM {course} c
|
||||
JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :courselevel AND ctx.path LIKE :match)
|
||||
JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'category')
|
||||
LEFT JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid)
|
||||
WHERE ue.id IS NULL";
|
||||
$params = array('courselevel'=>CONTEXT_COURSE, 'match'=>$parentcontext->path.'/%', 'userid'=>$ra->userid);
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
foreach ($rs as $instance) {
|
||||
$plugin->enrol_user($instance, $ra->userid, null, $ra->timemodified);
|
||||
}
|
||||
$rs->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when user role is unassigned.
|
||||
*
|
||||
* @param \core\event\role_unassigned $event
|
||||
*/
|
||||
public static function role_unassigned(\core\event\role_unassigned $event) {
|
||||
global $DB;
|
||||
|
||||
if (!enrol_is_enabled('category')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ra = $event->get_cached_record('role_assignments', $event->extra['id']);
|
||||
|
||||
// only category level roles are interesting
|
||||
$parentcontext = context::instance_by_id($ra->contextid);
|
||||
if ($parentcontext->contextlevel != CONTEXT_COURSECAT) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Now this is going to be a bit slow, take all enrolments in child courses and verify each separately.
|
||||
$syscontext = context_system::instance();
|
||||
if (!$roles = get_roles_with_capability('enrol/category:synchronised', CAP_ALLOW, $syscontext)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$plugin = enrol_get_plugin('category');
|
||||
|
||||
$sql = "SELECT e.*
|
||||
FROM {course} c
|
||||
JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :courselevel AND ctx.path LIKE :match)
|
||||
JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'category')
|
||||
JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid)";
|
||||
$params = array('courselevel'=>CONTEXT_COURSE, 'match'=>$parentcontext->path.'/%', 'userid'=>$ra->userid);
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
|
||||
list($roleids, $params) = $DB->get_in_or_equal(array_keys($roles), SQL_PARAMS_NAMED, 'r');
|
||||
$params['userid'] = $ra->userid;
|
||||
|
||||
foreach ($rs as $instance) {
|
||||
$coursecontext = context_course::instance($instance->courseid);
|
||||
$contextids = $coursecontext->get_parent_context_ids();
|
||||
array_pop($contextids); // Remove system context, we are interested in categories only.
|
||||
|
||||
list($contextids, $contextparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED, 'c');
|
||||
$params = array_merge($params, $contextparams);
|
||||
|
||||
$sql = "SELECT ra.id
|
||||
FROM {role_assignments} ra
|
||||
WHERE ra.userid = :userid AND ra.contextid $contextids AND ra.roleid $roleids";
|
||||
if (!$DB->record_exists_sql($sql, $params)) {
|
||||
// User does not have any interesting role in any parent context, let's unenrol.
|
||||
$plugin->unenrol_user($instance, $ra->userid);
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
}
|
||||
}
|
|
@ -25,20 +25,16 @@
|
|||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/* List of handlers */
|
||||
$handlers = array (
|
||||
'role_assigned' => array (
|
||||
'handlerfile' => '/enrol/category/locallib.php',
|
||||
'handlerfunction' => array('enrol_category_handler', 'role_assigned'),
|
||||
'schedule' => 'instant',
|
||||
'internal' => 1,
|
||||
$observers = array (
|
||||
|
||||
array (
|
||||
'eventname' => '\core\event\role_assigned',
|
||||
'callable' => 'enrol_category_observer::role_assigned',
|
||||
),
|
||||
|
||||
'role_unassigned' => array (
|
||||
'handlerfile' => '/enrol/category/locallib.php',
|
||||
'handlerfunction' => array('enrol_category_handler', 'role_unassigned'),
|
||||
'schedule' => 'instant',
|
||||
'internal' => 1,
|
||||
array (
|
||||
'eventname' => '\core\event\role_unassigned',
|
||||
'callable' => 'enrol_category_observer::role_unassigned',
|
||||
),
|
||||
|
||||
);
|
||||
);
|
||||
|
|
|
@ -24,131 +24,6 @@
|
|||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Event handler for category enrolment plugin.
|
||||
*
|
||||
* We try to keep everything in sync via listening to events,
|
||||
* it may fail sometimes, so we always do a full sync in cron too.
|
||||
*/
|
||||
class enrol_category_handler {
|
||||
/**
|
||||
* Triggered when user is assigned a new role.
|
||||
* @static
|
||||
* @param stdClass $ra
|
||||
* @return bool
|
||||
*/
|
||||
public static function role_assigned($ra) {
|
||||
global $DB;
|
||||
|
||||
if (!enrol_is_enabled('category')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//only category level roles are interesting
|
||||
$parentcontext = context::instance_by_id($ra->contextid);
|
||||
if ($parentcontext->contextlevel != CONTEXT_COURSECAT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make sure the role is to be actually synchronised,
|
||||
// please note we are ignoring overrides of the synchronised capability (for performance reasons in full sync).
|
||||
$syscontext = context_system::instance();
|
||||
if (!$DB->record_exists('role_capabilities', array('contextid'=>$syscontext->id, 'roleid'=>$ra->roleid, 'capability'=>'enrol/category:synchronised', 'permission'=>CAP_ALLOW))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add necessary enrol instances.
|
||||
$plugin = enrol_get_plugin('category');
|
||||
$sql = "SELECT c.*
|
||||
FROM {course} c
|
||||
JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :courselevel AND ctx.path LIKE :match)
|
||||
LEFT JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'category')
|
||||
WHERE e.id IS NULL";
|
||||
$params = array('courselevel'=>CONTEXT_COURSE, 'match'=>$parentcontext->path.'/%');
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
foreach ($rs as $course) {
|
||||
$plugin->add_instance($course);
|
||||
}
|
||||
$rs->close();
|
||||
|
||||
// Now look for missing enrolments.
|
||||
$sql = "SELECT e.*
|
||||
FROM {course} c
|
||||
JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :courselevel AND ctx.path LIKE :match)
|
||||
JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'category')
|
||||
LEFT JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid)
|
||||
WHERE ue.id IS NULL";
|
||||
$params = array('courselevel'=>CONTEXT_COURSE, 'match'=>$parentcontext->path.'/%', 'userid'=>$ra->userid);
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
foreach ($rs as $instance) {
|
||||
$plugin->enrol_user($instance, $ra->userid, null, $ra->timemodified);
|
||||
}
|
||||
$rs->close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when user role is unassigned.
|
||||
* @static
|
||||
* @param stdClass $ra
|
||||
* @return bool
|
||||
*/
|
||||
public static function role_unassigned($ra) {
|
||||
global $DB;
|
||||
|
||||
if (!enrol_is_enabled('category')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// only category level roles are interesting
|
||||
$parentcontext = context::instance_by_id($ra->contextid);
|
||||
if ($parentcontext->contextlevel != CONTEXT_COURSECAT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Now this is going to be a bit slow, take all enrolments in child courses and verify each separately.
|
||||
$syscontext = context_system::instance();
|
||||
if (!$roles = get_roles_with_capability('enrol/category:synchronised', CAP_ALLOW, $syscontext)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$plugin = enrol_get_plugin('category');
|
||||
|
||||
$sql = "SELECT e.*
|
||||
FROM {course} c
|
||||
JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :courselevel AND ctx.path LIKE :match)
|
||||
JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'category')
|
||||
JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid)";
|
||||
$params = array('courselevel'=>CONTEXT_COURSE, 'match'=>$parentcontext->path.'/%', 'userid'=>$ra->userid);
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
|
||||
list($roleids, $params) = $DB->get_in_or_equal(array_keys($roles), SQL_PARAMS_NAMED, 'r');
|
||||
$params['userid'] = $ra->userid;
|
||||
|
||||
foreach ($rs as $instance) {
|
||||
$coursecontext = context_course::instance($instance->courseid);
|
||||
$contextids = $coursecontext->get_parent_context_ids();
|
||||
array_pop($contextids); // Remove system context, we are interested in categories only.
|
||||
|
||||
list($contextids, $contextparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED, 'c');
|
||||
$params = array_merge($params, $contextparams);
|
||||
|
||||
$sql = "SELECT ra.id
|
||||
FROM {role_assignments} ra
|
||||
WHERE ra.userid = :userid AND ra.contextid $contextids AND ra.roleid $roleids";
|
||||
if (!$DB->record_exists_sql($sql, $params)) {
|
||||
// User does not have any interesting role in any parent context, let's unenrol.
|
||||
$plugin->unenrol_user($instance, $ra->userid);
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync all category enrolments in one course
|
||||
* @param stdClass $course
|
||||
|
|
|
@ -25,10 +25,7 @@
|
|||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot.'/enrol/category/locallib.php');
|
||||
|
||||
class enrol_category_testcase extends advanced_testcase {
|
||||
class enrol_category_plugin_testcase extends advanced_testcase {
|
||||
|
||||
protected function enable_plugin() {
|
||||
$enabled = enrol_get_plugins(true);
|
||||
|
@ -107,7 +104,8 @@ class enrol_category_testcase extends advanced_testcase {
|
|||
}
|
||||
|
||||
public function test_handler_sync() {
|
||||
global $DB;
|
||||
global $DB, $CFG;
|
||||
require_once($CFG->dirroot.'/enrol/category/locallib.php');
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
|
@ -179,7 +177,8 @@ class enrol_category_testcase extends advanced_testcase {
|
|||
}
|
||||
|
||||
public function test_sync_course() {
|
||||
global $DB;
|
||||
global $DB, $CFG;
|
||||
require_once($CFG->dirroot.'/enrol/category/locallib.php');
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
|
@ -272,7 +271,8 @@ class enrol_category_testcase extends advanced_testcase {
|
|||
}
|
||||
|
||||
public function test_sync_full() {
|
||||
global $DB;
|
||||
global $DB, $CFG;
|
||||
require_once($CFG->dirroot.'/enrol/category/locallib.php');
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue