���ѧۧݧ�ӧ�� �ާ֧ߧ֧էا֧� - ���֧էѧܧ�ڧ��ӧѧ�� - /home3/cpr76684/public_html/category.tar
���ѧ٧ѧ�
db/install.php 0000644 00000001762 15151236446 0007325 0 ustar 00 <?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/>. /** * category enrolment plugin installation. * * @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(); function xmldb_enrol_category_install() { global $CFG, $DB; } db/tasks.php 0000644 00000002320 15151236446 0006773 0 ustar 00 <?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/>. /** * Task definition for enrol_category. * @author Farhan Karmali <farhan6318@gmail.com> * @copyright Farhan Karmali * @package enrol_category * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $tasks = array( array( 'classname' => '\enrol_category\task\enrol_category_sync', 'blocking' => 0, 'minute' => '*', 'hour' => '*', 'day' => '*', 'month' => '*', 'dayofweek' => '*', 'disabled' => 0 ) ); db/events.php 0000644 00000002372 15151236446 0007161 0 ustar 00 <?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/>. /** * Category enrolment plugin event handler definition. * * @package enrol_category * @category event * @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(); $observers = array ( array ( 'eventname' => '\core\event\role_assigned', 'callback' => 'enrol_category_observer::role_assigned', ), array ( 'eventname' => '\core\event\role_unassigned', 'callback' => 'enrol_category_observer::role_unassigned', ), ); db/access.php 0000644 00000003155 15151236446 0007116 0 ustar 00 <?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/>. /** * Capabilities for category access 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(); $capabilities = array( // Marks roles that have category role assignments synchronised to course enrolments // overrides below system context are ignored (for performance reasons). // By default his is not allowed in new installs, admins have to explicitly allow category enrolments. 'enrol/category:synchronised' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_SYSTEM, 'archetypes' => array( ) ), 'enrol/category:config' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, 'archetypes' => array( 'manager' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, ) ), ); locallib.php 0000644 00000025041 15151236446 0007047 0 ustar 00 <?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(); /** * Sync all category enrolments in one course * @param stdClass $course * @return void */ function enrol_category_sync_course($course) { global $DB; if (!enrol_is_enabled('category')) { return; } $plugin = enrol_get_plugin('category'); $syscontext = context_system::instance(); $roles = get_roles_with_capability('enrol/category:synchronised', CAP_ALLOW, $syscontext); if (!$roles) { // Nothing to sync, so remove the instance completely if exists. if ($instances = $DB->get_records('enrol', array('courseid'=>$course->id, 'enrol'=>'category'))) { foreach ($instances as $instance) { $plugin->delete_instance($instance); } } return; } // First find out if any parent category context contains interesting role assignments. $coursecontext = context_course::instance($course->id); $contextids = $coursecontext->get_parent_context_ids(); array_pop($contextids); // Remove system context, we are interested in categories only. list($roleids, $params) = $DB->get_in_or_equal(array_keys($roles), SQL_PARAMS_NAMED, 'r'); list($contextids, $contextparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED, 'c'); $params = array_merge($params, $contextparams); $params['courseid'] = $course->id; $sql = "SELECT 'x' FROM {role_assignments} WHERE roleid $roleids AND contextid $contextids"; if (!$DB->record_exists_sql($sql, $params)) { if ($instances = $DB->get_records('enrol', array('courseid'=>$course->id, 'enrol'=>'category'))) { // Should be max one instance, but anyway. foreach ($instances as $instance) { $plugin->delete_instance($instance); } } return; } // Make sure the enrol instance exists - there should be always only one instance. $delinstances = array(); if ($instances = $DB->get_records('enrol', array('courseid'=>$course->id, 'enrol'=>'category'))) { $instance = array_shift($instances); $delinstances = $instances; } else { $i = $plugin->add_instance($course); $instance = $DB->get_record('enrol', array('id'=>$i)); } // Add new enrolments. $sql = "SELECT ra.userid, ra.estart FROM (SELECT xra.userid, MIN(xra.timemodified) AS estart FROM {role_assignments} xra JOIN {user} xu ON (xu.id = xra.userid AND xu.deleted = 0) WHERE xra.roleid $roleids AND xra.contextid $contextids GROUP BY xra.userid ) ra LEFT JOIN {user_enrolments} ue ON (ue.enrolid = :instanceid AND ue.userid = ra.userid) WHERE ue.id IS NULL"; $params['instanceid'] = $instance->id; $rs = $DB->get_recordset_sql($sql, $params); foreach ($rs as $ra) { $plugin->enrol_user($instance, $ra->userid, null, $ra->estart); } $rs->close(); // Remove unwanted enrolments. $sql = "SELECT DISTINCT ue.userid FROM {user_enrolments} ue LEFT JOIN {role_assignments} ra ON (ra.roleid $roleids AND ra.contextid $contextids AND ra.userid = ue.userid) WHERE ue.enrolid = :instanceid AND ra.id IS NULL"; $rs = $DB->get_recordset_sql($sql, $params); foreach ($rs as $ra) { $plugin->unenrol_user($instance, $ra->userid); } $rs->close(); if ($delinstances) { // We have to do this as the last step in order to prevent temporary unenrolment. foreach ($delinstances as $delinstance) { $plugin->delete_instance($delinstance); } } } /** * Synchronise courses in all categories. * * It gets out-of-sync if: * - you move course to different category * - reorder categories * - disable enrol_category and enable it again * * @param progress_trace $trace * @return int exit code - 0 is ok, 1 means error, 2 if plugin disabled */ function enrol_category_sync_full(progress_trace $trace) { global $DB; if (!enrol_is_enabled('category')) { $trace->finished(); return 2; } // We may need a lot of time here. core_php_time_limit::raise(); $plugin = enrol_get_plugin('category'); $syscontext = context_system::instance(); // Any interesting roles worth synchronising? if (!$roles = get_roles_with_capability('enrol/category:synchronised', CAP_ALLOW, $syscontext)) { // yay, nothing to do, so let's remove all leftovers $trace->output("No roles with 'enrol/category:synchronised' capability found."); if ($instances = $DB->get_records('enrol', array('enrol'=>'category'))) { $trace->output("Deleting all category enrol instances..."); foreach ($instances as $instance) { $trace->output("deleting category enrol instance from course {$instance->courseid}", 1); $plugin->delete_instance($instance); } $trace->output("...all instances deleted."); } $trace->finished(); return 0; } $rolenames = role_fix_names($roles, null, ROLENAME_SHORT, true); $trace->output('Synchronising category enrolments for roles: '.implode(', ', $rolenames).'...'); list($roleids, $params) = $DB->get_in_or_equal(array_keys($roles), SQL_PARAMS_NAMED, 'r'); $params['courselevel'] = CONTEXT_COURSE; $params['catlevel'] = CONTEXT_COURSECAT; // First of all add necessary enrol instances to all courses. $parentcat = $DB->sql_concat("cat.path", "'/%'"); $parentcctx = $DB->sql_concat("cctx.path", "'/%'"); // Need whole course records to be used by add_instance(), use inner view (ci) to // get distinct records only. // TODO: Moodle 2.1. Improve enrol API to accept courseid / courserec $sql = "SELECT c.* FROM {course} c JOIN ( SELECT DISTINCT c.id FROM {course} c JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :courselevel) JOIN (SELECT DISTINCT cctx.path FROM {course_categories} cc JOIN {context} cctx ON (cctx.instanceid = cc.id AND cctx.contextlevel = :catlevel) JOIN {role_assignments} ra ON (ra.contextid = cctx.id AND ra.roleid $roleids) ) cat ON (ctx.path LIKE $parentcat) LEFT JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'category') WHERE e.id IS NULL) ci ON (c.id = ci.id)"; $rs = $DB->get_recordset_sql($sql, $params); foreach($rs as $course) { $plugin->add_instance($course); } $rs->close(); // Now look for courses that do not have any interesting roles in parent contexts, // but still have the instance and delete them. $sql = "SELECT e.* FROM {enrol} e JOIN {context} ctx ON (ctx.instanceid = e.courseid AND ctx.contextlevel = :courselevel) LEFT JOIN ({course_categories} cc JOIN {context} cctx ON (cctx.instanceid = cc.id AND cctx.contextlevel = :catlevel) JOIN {role_assignments} ra ON (ra.contextid = cctx.id AND ra.roleid $roleids) ) ON (ctx.path LIKE $parentcctx) WHERE e.enrol = 'category' AND cc.id IS NULL"; $rs = $DB->get_recordset_sql($sql, $params); foreach($rs as $instance) { $plugin->delete_instance($instance); } $rs->close(); // Add missing enrolments. $sql = "SELECT e.*, cat.userid, cat.estart FROM {enrol} e JOIN {context} ctx ON (ctx.instanceid = e.courseid AND ctx.contextlevel = :courselevel) JOIN (SELECT cctx.path, ra.userid, MIN(ra.timemodified) AS estart FROM {course_categories} cc JOIN {context} cctx ON (cctx.instanceid = cc.id AND cctx.contextlevel = :catlevel) JOIN {role_assignments} ra ON (ra.contextid = cctx.id AND ra.roleid $roleids) GROUP BY cctx.path, ra.userid ) cat ON (ctx.path LIKE $parentcat) LEFT JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = cat.userid) WHERE e.enrol = 'category' AND ue.id IS NULL"; $rs = $DB->get_recordset_sql($sql, $params); foreach($rs as $instance) { $userid = $instance->userid; $estart = $instance->estart; unset($instance->userid); unset($instance->estart); $plugin->enrol_user($instance, $userid, null, $estart); $trace->output("enrolling: user $userid ==> course $instance->courseid", 1); } $rs->close(); // Remove stale enrolments. $sql = "SELECT e.*, ue.userid FROM {enrol} e JOIN {context} ctx ON (ctx.instanceid = e.courseid AND ctx.contextlevel = :courselevel) JOIN {user_enrolments} ue ON (ue.enrolid = e.id) LEFT JOIN ({course_categories} cc JOIN {context} cctx ON (cctx.instanceid = cc.id AND cctx.contextlevel = :catlevel) JOIN {role_assignments} ra ON (ra.contextid = cctx.id AND ra.roleid $roleids) ) ON (ctx.path LIKE $parentcctx AND ra.userid = ue.userid) WHERE e.enrol = 'category' AND cc.id IS NULL"; $rs = $DB->get_recordset_sql($sql, $params); foreach($rs as $instance) { $userid = $instance->userid; unset($instance->userid); $plugin->unenrol_user($instance, $userid); $trace->output("unenrolling: user $userid ==> course $instance->courseid", 1); } $rs->close(); $trace->output('...user enrolment synchronisation finished.'); $trace->finished(); return 0; } cli/sync.php 0000644 00000004370 15151236446 0007013 0 ustar 00 <?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/>. /** * CLI sync for full category enrol synchronisation. * * Sample execution: * $ sudo -u www-data /usr/bin/php /var/www/moodle/enrol/category/cli/sync.php * * Notes: * - it is required to use the web server account when executing PHP CLI scripts * - you need to change the "www-data" to match the apache user account * - use "su" if "sudo" not available * * @package enrol_category * @copyright 2010 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define('CLI_SCRIPT', true); require(__DIR__.'/../../../config.php'); require_once("$CFG->dirroot/enrol/category/locallib.php"); require_once("$CFG->libdir/clilib.php"); // Now get cli options. list($options, $unrecognized) = cli_get_params(array('verbose'=>false, 'help'=>false), array('v'=>'verbose', 'h'=>'help')); if ($unrecognized) { $unrecognized = implode("\n ", $unrecognized); cli_error(get_string('cliunknowoption', 'admin', $unrecognized)); } if ($options['help']) { $help = "Execute course category enrolment sync. Options: -v, --verbose Print verbose progress information -h, --help Print out this help Example: \$ sudo -u www-data /usr/bin/php enrol/category/cli/sync.php "; echo $help; die; } if (!enrol_is_enabled('category')) { cli_error('enrol_category plugin is disabled, synchronisation stopped', 2); } if (empty($options['verbose'])) { $trace = new null_progress_trace(); } else { $trace = new text_progress_trace(); } $result = enrol_category_sync_full($trace); exit($result); tests/plugin_test.php 0000644 00000041520 15151236446 0010765 0 ustar 00 <?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/>. namespace enrol_category; /** * Category enrolment sync functional test. * * @package enrol_category * @category phpunit * @copyright 2012 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class plugin_test extends \advanced_testcase { protected function enable_plugin() { $enabled = enrol_get_plugins(true); $enabled['category'] = true; $enabled = array_keys($enabled); set_config('enrol_plugins_enabled', implode(',', $enabled)); } protected function disable_plugin() { $enabled = enrol_get_plugins(true); unset($enabled['category']); $enabled = array_keys($enabled); set_config('enrol_plugins_enabled', implode(',', $enabled)); } protected function enable_role_sync($roleid) { $syscontext = \context_system::instance(); assign_capability('enrol/category:synchronised', CAP_ALLOW, $roleid, $syscontext, true); } protected function disable_role_sync($roleid) { $syscontext = \context_system::instance(); unassign_capability('enrol/category:synchronised', $roleid, $syscontext); } /** * Test utility methods used in syn test, fail here means something * in core accesslib was changed, but it is possible that only this test * is affected, nto the plugin itself... */ public function test_utils() { global $DB; $this->resetAfterTest(); $syscontext = \context_system::instance(); $this->assertFalse(enrol_is_enabled('category')); $this->enable_plugin(); $this->assertTrue(enrol_is_enabled('category')); $roles = get_roles_with_capability('enrol/category:synchronised', CAP_ALLOW, $syscontext); $this->assertEmpty($roles); $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->assertNotEmpty($studentrole); $this->enable_role_sync($studentrole->id); $roles = get_roles_with_capability('enrol/category:synchronised', CAP_ALLOW, $syscontext); $this->assertEquals(1, count($roles)); $this->assertEquals($studentrole, reset($roles)); $this->disable_role_sync($studentrole->id); $roles = get_roles_with_capability('enrol/category:synchronised', CAP_ALLOW, $syscontext); $this->assertEmpty($roles); } public function test_handler_sync() { global $DB, $CFG; require_once($CFG->dirroot.'/enrol/category/locallib.php'); $this->resetAfterTest(); // Setup a few courses and categories. $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->assertNotEmpty($studentrole); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->assertNotEmpty($teacherrole); $managerrole = $DB->get_record('role', array('shortname'=>'manager')); $this->assertNotEmpty($managerrole); $cat1 = $this->getDataGenerator()->create_category(); $cat2 = $this->getDataGenerator()->create_category(); $cat3 = $this->getDataGenerator()->create_category(array('parent'=>$cat2->id)); $course1 = $this->getDataGenerator()->create_course(array('category'=>$cat1->id)); $course2 = $this->getDataGenerator()->create_course(array('category'=>$cat2->id)); $course3 = $this->getDataGenerator()->create_course(array('category'=>$cat3->id)); $course4 = $this->getDataGenerator()->create_course(array('category'=>$cat3->id)); $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $user3 = $this->getDataGenerator()->create_user(); $user4 = $this->getDataGenerator()->create_user(); $this->enable_role_sync($studentrole->id); $this->enable_role_sync($teacherrole->id); $this->enable_plugin(); $this->assertEquals(0, $DB->count_records('role_assignments', array())); $this->assertEquals(0, $DB->count_records('user_enrolments', array())); // Test assign event. role_assign($managerrole->id, $user1->id, \context_coursecat::instance($cat1->id)); role_assign($managerrole->id, $user3->id, \context_course::instance($course1->id)); role_assign($managerrole->id, $user3->id, \context_course::instance($course2->id)); $this->assertEquals(0, $DB->count_records('user_enrolments', array())); role_assign($studentrole->id, $user1->id, \context_coursecat::instance($cat2->id)); $this->assertTrue(is_enrolled(\context_course::instance($course2->id), $user1->id)); $this->assertTrue(is_enrolled(\context_course::instance($course3->id), $user1->id)); $this->assertTrue(is_enrolled(\context_course::instance($course4->id), $user1->id)); $this->assertEquals(3, $DB->count_records('user_enrolments', array())); role_assign($managerrole->id, $user2->id, \context_coursecat::instance($cat3->id)); $this->assertEquals(3, $DB->count_records('user_enrolments', array())); role_assign($teacherrole->id, $user4->id, \context_coursecat::instance($cat1->id)); $this->assertTrue(is_enrolled(\context_course::instance($course1->id), $user4->id)); $this->assertEquals(4, $DB->count_records('user_enrolments', array())); // Test role unassigned event. role_unassign($teacherrole->id, $user4->id, \context_coursecat::instance($cat1->id)->id); $this->assertFalse(is_enrolled(\context_course::instance($course1->id), $user4->id)); $this->assertEquals(3, $DB->count_records('user_enrolments', array())); // Make sure handlers are disabled when plugin disabled. $this->disable_plugin(); role_unassign($studentrole->id, $user1->id, \context_coursecat::instance($cat2->id)->id); $this->assertEquals(3, $DB->count_records('user_enrolments', array())); role_assign($studentrole->id, $user3->id, \context_coursecat::instance($cat1->id)); $this->assertEquals(3, $DB->count_records('user_enrolments', array())); } public function test_sync_course() { global $DB, $CFG; require_once($CFG->dirroot.'/enrol/category/locallib.php'); $this->resetAfterTest(); // Setup a few courses and categories. $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->assertNotEmpty($studentrole); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->assertNotEmpty($teacherrole); $managerrole = $DB->get_record('role', array('shortname'=>'manager')); $this->assertNotEmpty($managerrole); $cat1 = $this->getDataGenerator()->create_category(); $cat2 = $this->getDataGenerator()->create_category(); $cat3 = $this->getDataGenerator()->create_category(array('parent'=>$cat2->id)); $course1 = $this->getDataGenerator()->create_course(array('category'=>$cat1->id)); $course2 = $this->getDataGenerator()->create_course(array('category'=>$cat2->id)); $course3 = $this->getDataGenerator()->create_course(array('category'=>$cat3->id)); $course4 = $this->getDataGenerator()->create_course(array('category'=>$cat3->id)); $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $user3 = $this->getDataGenerator()->create_user(); $user4 = $this->getDataGenerator()->create_user(); $this->enable_role_sync($studentrole->id); $this->enable_role_sync($teacherrole->id); $this->enable_plugin(); $this->assertEquals(0, $DB->count_records('role_assignments', array())); role_assign($managerrole->id, $user1->id, \context_coursecat::instance($cat1->id)); role_assign($managerrole->id, $user3->id, \context_course::instance($course1->id)); role_assign($managerrole->id, $user3->id, \context_course::instance($course2->id)); $this->assertEquals(0, $DB->count_records('user_enrolments', array())); $this->disable_plugin(); // Stops the event handlers. role_assign($studentrole->id, $user1->id, \context_coursecat::instance($cat2->id)); $this->assertEquals(0, $DB->count_records('user_enrolments', array())); $this->enable_plugin(); enrol_category_sync_course($course2); $this->assertTrue(is_enrolled(\context_course::instance($course2->id), $user1->id)); $this->assertFalse(is_enrolled(\context_course::instance($course3->id), $user1->id)); $this->assertFalse(is_enrolled(\context_course::instance($course4->id), $user1->id)); $this->assertEquals(1, $DB->count_records('user_enrolments', array())); enrol_category_sync_course($course2); enrol_category_sync_course($course3); enrol_category_sync_course($course4); $this->assertFalse(is_enrolled(\context_course::instance($course1->id), $user1->id)); $this->assertTrue(is_enrolled(\context_course::instance($course2->id), $user1->id)); $this->assertTrue(is_enrolled(\context_course::instance($course3->id), $user1->id)); $this->assertTrue(is_enrolled(\context_course::instance($course4->id), $user1->id)); $this->assertEquals(3, $DB->count_records('user_enrolments', array())); $this->disable_plugin(); // Stops the event handlers. role_assign($studentrole->id, $user2->id, \context_coursecat::instance($cat1->id)); role_assign($teacherrole->id, $user4->id, \context_coursecat::instance($cat1->id)); role_unassign($studentrole->id, $user1->id, \context_coursecat::instance($cat2->id)->id); $this->assertEquals(3, $DB->count_records('user_enrolments', array())); $this->enable_plugin(); enrol_category_sync_course($course2); $this->assertFalse(is_enrolled(\context_course::instance($course2->id), $user1->id)); $this->assertFalse(is_enrolled(\context_course::instance($course2->id), $user2->id)); $this->assertFalse(is_enrolled(\context_course::instance($course2->id), $user4->id)); enrol_category_sync_course($course1); enrol_category_sync_course($course3); enrol_category_sync_course($course4); $this->assertEquals(2, $DB->count_records('user_enrolments', array())); $this->assertTrue(is_enrolled(\context_course::instance($course1->id), $user2->id)); $this->assertTrue(is_enrolled(\context_course::instance($course1->id), $user4->id)); $this->disable_role_sync($studentrole->id); enrol_category_sync_course($course1); enrol_category_sync_course($course2); enrol_category_sync_course($course3); enrol_category_sync_course($course4); $this->assertEquals(1, $DB->count_records('user_enrolments', array())); $this->assertTrue(is_enrolled(\context_course::instance($course1->id), $user4->id)); $this->assertEquals(1, $DB->count_records('enrol', array('enrol'=>'category'))); $this->disable_role_sync($teacherrole->id); enrol_category_sync_course($course1); enrol_category_sync_course($course2); enrol_category_sync_course($course3); enrol_category_sync_course($course4); $this->assertEquals(0, $DB->count_records('user_enrolments', array())); $this->assertEquals(0, $DB->count_records('enrol', array('enrol'=>'category'))); } public function test_sync_full() { global $DB, $CFG; require_once($CFG->dirroot.'/enrol/category/locallib.php'); $this->resetAfterTest(); $trace = new \null_progress_trace(); // Setup a few courses and categories. $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->assertNotEmpty($studentrole); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->assertNotEmpty($teacherrole); $managerrole = $DB->get_record('role', array('shortname'=>'manager')); $this->assertNotEmpty($managerrole); $cat1 = $this->getDataGenerator()->create_category(); $cat2 = $this->getDataGenerator()->create_category(); $cat3 = $this->getDataGenerator()->create_category(array('parent'=>$cat2->id)); $course1 = $this->getDataGenerator()->create_course(array('category'=>$cat1->id)); $course2 = $this->getDataGenerator()->create_course(array('category'=>$cat2->id)); $course3 = $this->getDataGenerator()->create_course(array('category'=>$cat3->id)); $course4 = $this->getDataGenerator()->create_course(array('category'=>$cat3->id)); $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $user3 = $this->getDataGenerator()->create_user(); $user4 = $this->getDataGenerator()->create_user(); $this->enable_role_sync($studentrole->id); $this->enable_role_sync($teacherrole->id); $this->enable_plugin(); $this->assertEquals(0, $DB->count_records('role_assignments', array())); role_assign($managerrole->id, $user1->id, \context_coursecat::instance($cat1->id)); role_assign($managerrole->id, $user3->id, \context_course::instance($course1->id)); role_assign($managerrole->id, $user3->id, \context_course::instance($course2->id)); $this->assertEquals(0, $DB->count_records('user_enrolments', array())); $result = enrol_category_sync_full($trace); $this->assertSame(0, $result); $this->disable_plugin(); role_assign($studentrole->id, $user1->id, \context_coursecat::instance($cat2->id)); $this->enable_plugin(); $result = enrol_category_sync_full($trace); $this->assertSame(0, $result); $this->assertEquals(3, $DB->count_records('user_enrolments', array())); $this->assertTrue(is_enrolled(\context_course::instance($course2->id), $user1->id)); $this->assertTrue(is_enrolled(\context_course::instance($course3->id), $user1->id)); $this->assertTrue(is_enrolled(\context_course::instance($course4->id), $user1->id)); $this->disable_plugin(); role_unassign($studentrole->id, $user1->id, \context_coursecat::instance($cat2->id)->id); role_assign($studentrole->id, $user2->id, \context_coursecat::instance($cat1->id)); role_assign($teacherrole->id, $user4->id, \context_coursecat::instance($cat1->id)); role_assign($teacherrole->id, $user3->id, \context_coursecat::instance($cat2->id)); role_assign($managerrole->id, $user3->id, \context_course::instance($course3->id)); $this->enable_plugin(); $result = enrol_category_sync_full($trace); $this->assertSame(0, $result); $this->assertEquals(5, $DB->count_records('user_enrolments', array())); $this->assertTrue(is_enrolled(\context_course::instance($course1->id), $user2->id)); $this->assertTrue(is_enrolled(\context_course::instance($course1->id), $user4->id)); $this->assertTrue(is_enrolled(\context_course::instance($course2->id), $user3->id)); $this->assertTrue(is_enrolled(\context_course::instance($course3->id), $user3->id)); $this->assertTrue(is_enrolled(\context_course::instance($course4->id), $user3->id)); // Cleanup everything. $this->assertNotEmpty($DB->count_records('role_assignments', array())); $this->assertNotEmpty($DB->count_records('user_enrolments', array())); $this->disable_plugin(); role_unassign_all(array('roleid'=>$studentrole->id)); role_unassign_all(array('roleid'=>$managerrole->id)); role_unassign_all(array('roleid'=>$teacherrole->id)); $result = enrol_category_sync_full($trace); $this->assertSame(2, $result); $this->assertEquals(0, $DB->count_records('role_assignments', array())); $this->assertNotEmpty($DB->count_records('user_enrolments', array())); $this->disable_role_sync($studentrole->id); $this->disable_role_sync($teacherrole->id); $this->enable_plugin(); $result = enrol_category_sync_full($trace); $this->assertSame(0, $result); $this->assertEquals(0, $DB->count_records('role_assignments', array())); $this->assertEquals(0, $DB->count_records('user_enrolments', array())); $this->assertEquals(0, $DB->count_records('enrol', array('enrol'=>'category'))); } } settings.php 0000644 00000002461 15151236446 0007127 0 ustar 00 <?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/>. /** * Category enrolment plugin settings and presets. * * @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(); if ($ADMIN->fulltree) { //--- general settings ----------------------------------------------------------------------------------- $settings->add(new admin_setting_heading('enrol_category_settings', '', get_string('pluginname_desc', 'enrol_category'))); //--- enrol instance defaults ---------------------------------------------------------------------------- } lib.php 0000644 00000006352 15151236446 0006040 0 ustar 00 <?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/>. /** * 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(); /** * category enrolment plugin implementation. * @author Petr Skoda * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class enrol_category_plugin extends enrol_plugin { /** * Is it possible to delete enrol instance via standard UI? * * @param stdClass $instance * @return bool */ public function can_delete_instance($instance) { global $DB; $context = context_course::instance($instance->courseid); if (!has_capability('enrol/category:config', $context)) { return false; } if (!enrol_is_enabled('category')) { return true; } // Allow delete only when no synced users here. return !$DB->record_exists('user_enrolments', array('enrolid'=>$instance->id)); } /** * Is it possible to hide/show enrol instance via standard UI? * * @param stdClass $instance * @return bool */ public function can_hide_show_instance($instance) { $context = context_course::instance($instance->courseid); return has_capability('enrol/category:config', $context); } /** * Returns link to page which may be used to add new instance of enrolment plugin in course. * @param int $courseid * @return moodle_url page url */ public function get_newinstance_link($courseid) { // Instances are added automatically as necessary. return null; } /** * Called after updating/inserting course. * * @param bool $inserted true if course just inserted * @param stdClass $course * @param stdClass $data form data * @return void */ public function course_updated($inserted, $course, $data) { global $CFG; if (!enrol_is_enabled('category')) { return; } // Sync category enrols. require_once("$CFG->dirroot/enrol/category/locallib.php"); enrol_category_sync_course($course); } /** * Automatic enrol sync executed during restore. * Useful for automatic sync by course->idnumber or course category. * @param stdClass $course course record */ public function restore_sync_course($course) { global $CFG; require_once("$CFG->dirroot/enrol/category/locallib.php"); enrol_category_sync_course($course); } } version.php 0000644 00000002264 15151236446 0006755 0 ustar 00 <?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/>. /** * Category enrolment plugin version specification. * * @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(); $plugin->version = 2022112800; // The current plugin version (Date: YYYYMMDDXX). $plugin->requires = 2022111800; // Requires this Moodle version. $plugin->component = 'enrol_category'; // Full name of the plugin (used for diagnostics) classes/privacy/provider.php 0000644 00000002771 15151236446 0012237 0 ustar 00 <?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/>. /** * Privacy Subsystem implementation for enrol_category. * * @package enrol_category * @copyright 2018 Carlos Escobedo <carlos@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace enrol_category\privacy; defined('MOODLE_INTERNAL') || die(); /** * Privacy Subsystem for enrol_category implementing null_provider. * * @copyright 2018 Carlos Escobedo <carlos@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class provider implements \core_privacy\local\metadata\null_provider { /** * Get the language string identifier with the component's language * file to explain why this plugin stores no data. * * @return string */ public static function get_reason() : string { return 'privacy:metadata'; } } classes/task/enrol_category_sync.php 0000644 00000003413 15151236446 0013734 0 ustar 00 <?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/>. /** * Syncing enrolments task. * * @package enrol_category * @author Farhan Karmali <farhan6318@gmail.com> * @copyright Farhan Karmali * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace enrol_category\task; defined('MOODLE_INTERNAL') || die(); /** * Syncing enrolments task. * * @package enrol_category * @author Farhan Karmali <farhan6318@gmail.com> * @copyright Farhan Karmali * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class enrol_category_sync extends \core\task\scheduled_task { /** * Name for this task. * * @return string */ public function get_name() { return get_string('enrolcategorysynctask', 'enrol_category'); } /** * Run task for syncing category enrolments. */ public function execute() { global $CFG; if (!enrol_is_enabled('category')) { return; } require_once("$CFG->dirroot/enrol/category/locallib.php"); $trace = new \null_progress_trace(); enrol_category_sync_full($trace); } } classes/observer.php 0000644 00000014146 15151236446 0010556 0 ustar 00 <?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 = new stdClass(); $ra->roleid = $event->objectid; $ra->userid = $event->relateduserid; $ra->contextid = $event->contextid; //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, time()); } $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 = new stdClass(); $ra->userid = $event->relateduserid; $ra->contextid = $event->contextid; // 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(); } } lang/en/enrol_category.php 0000644 00000002703 15151236446 0011625 0 ustar 00 <?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/>. /** * Strings for component 'enrol_category', language 'en'. * * @package enrol_category * @copyright 2010 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ $string['category:config'] = 'Configure category enrol instances'; $string['category:synchronised'] = 'Role assignments synchronised to course enrolment'; $string['enrolcategorysynctask'] = 'Category enrolment sync task'; $string['pluginname'] = 'Category enrolments'; $string['pluginname_desc'] = 'The category enrolments plugin synchronises any role assignments in the category context for roles with the capability enrol/category:synchronised allowed.'; $string['privacy:metadata'] = 'The Category enrolments plugin does not store any personal data.';
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | ���֧ߧ֧�ѧ�ڧ� ����ѧߧڧ��: 0 |
proxy
|
phpinfo
|
���ѧ����ۧܧ�