Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Local stuff for category enrolment plugin.
19
 *
20
 * @package    enrol_category
21
 * @copyright  2010 Petr Skoda {@link http://skodak.org}
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
defined('MOODLE_INTERNAL') || die();
26
 
27
 
28
/**
29
 * Event handler for category enrolment plugin.
30
 *
31
 * We try to keep everything in sync via listening to events,
32
 * it may fail sometimes, so we always do a full sync in cron too.
33
 */
34
class enrol_category_observer {
35
    /**
36
     * Triggered when user is assigned a new role.
37
     *
38
     * @param \core\event\role_assigned $event
39
     */
40
    public static function role_assigned(\core\event\role_assigned $event) {
41
        global $DB;
42
 
43
        if (!enrol_is_enabled('category')) {
44
            return;
45
        }
46
 
47
        $ra = new stdClass();
48
        $ra->roleid = $event->objectid;
49
        $ra->userid = $event->relateduserid;
50
        $ra->contextid = $event->contextid;
51
 
52
        //only category level roles are interesting
53
        $parentcontext = context::instance_by_id($ra->contextid);
54
        if ($parentcontext->contextlevel != CONTEXT_COURSECAT) {
55
            return;
56
        }
57
 
58
        // Make sure the role is to be actually synchronised,
59
        // please note we are ignoring overrides of the synchronised capability (for performance reasons in full sync).
60
        $syscontext = context_system::instance();
61
        if (!$DB->record_exists('role_capabilities', array('contextid'=>$syscontext->id, 'roleid'=>$ra->roleid, 'capability'=>'enrol/category:synchronised', 'permission'=>CAP_ALLOW))) {
62
            return;
63
        }
64
 
65
        // Add necessary enrol instances.
66
        $plugin = enrol_get_plugin('category');
67
        $sql = "SELECT c.*
68
                  FROM {course} c
69
                  JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :courselevel AND ctx.path LIKE :match)
70
             LEFT JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'category')
71
                 WHERE e.id IS NULL";
72
        $params = array('courselevel'=>CONTEXT_COURSE, 'match'=>$parentcontext->path.'/%');
73
        $rs = $DB->get_recordset_sql($sql, $params);
74
        foreach ($rs as $course) {
75
            $plugin->add_instance($course);
76
        }
77
        $rs->close();
78
 
79
        // Now look for missing enrolments.
80
        $sql = "SELECT e.*
81
                  FROM {course} c
82
                  JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :courselevel AND ctx.path LIKE :match)
83
                  JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'category')
84
             LEFT JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid)
85
                 WHERE ue.id IS NULL";
86
        $params = array('courselevel'=>CONTEXT_COURSE, 'match'=>$parentcontext->path.'/%', 'userid'=>$ra->userid);
87
        $rs = $DB->get_recordset_sql($sql, $params);
88
        foreach ($rs as $instance) {
89
            $plugin->enrol_user($instance, $ra->userid, null, time());
90
        }
91
        $rs->close();
92
    }
93
 
94
    /**
95
     * Triggered when user role is unassigned.
96
     *
97
     * @param \core\event\role_unassigned $event
98
     */
99
    public static function role_unassigned(\core\event\role_unassigned $event) {
100
        global $DB;
101
 
102
        if (!enrol_is_enabled('category')) {
103
            return;
104
        }
105
 
106
        $ra = new stdClass();
107
        $ra->userid = $event->relateduserid;
108
        $ra->contextid = $event->contextid;
109
 
110
        // only category level roles are interesting
111
        $parentcontext = context::instance_by_id($ra->contextid);
112
        if ($parentcontext->contextlevel != CONTEXT_COURSECAT) {
113
            return;
114
        }
115
 
116
        // Now this is going to be a bit slow, take all enrolments in child courses and verify each separately.
117
        $syscontext = context_system::instance();
118
        if (!$roles = get_roles_with_capability('enrol/category:synchronised', CAP_ALLOW, $syscontext)) {
119
            return;
120
        }
121
 
122
        $plugin = enrol_get_plugin('category');
123
 
124
        $sql = "SELECT e.*
125
                  FROM {course} c
126
                  JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :courselevel AND ctx.path LIKE :match)
127
                  JOIN {enrol} e ON (e.courseid = c.id AND e.enrol = 'category')
128
                  JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = :userid)";
129
        $params = array('courselevel'=>CONTEXT_COURSE, 'match'=>$parentcontext->path.'/%', 'userid'=>$ra->userid);
130
        $rs = $DB->get_recordset_sql($sql, $params);
131
 
132
        list($roleids, $params) = $DB->get_in_or_equal(array_keys($roles), SQL_PARAMS_NAMED, 'r');
133
        $params['userid'] = $ra->userid;
134
 
135
        foreach ($rs as $instance) {
136
            $coursecontext = context_course::instance($instance->courseid);
137
            $contextids = $coursecontext->get_parent_context_ids();
138
            array_pop($contextids); // Remove system context, we are interested in categories only.
139
 
140
            list($contextids, $contextparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED, 'c');
141
            $params = array_merge($params, $contextparams);
142
 
143
            $sql = "SELECT ra.id
144
                      FROM {role_assignments} ra
145
                     WHERE ra.userid = :userid AND ra.contextid $contextids AND ra.roleid $roleids";
146
            if (!$DB->record_exists_sql($sql, $params)) {
147
                // User does not have any interesting role in any parent context, let's unenrol.
148
                $plugin->unenrol_user($instance, $ra->userid);
149
            }
150
        }
151
        $rs->close();
152
    }
153
}