Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/enrol/meta/locallib.php
Go to the documentation of this file.
00001 <?php
00002 // This file is part of Moodle - http://moodle.org/
00003 //
00004 // Moodle is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // Moodle is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00016 
00026 defined('MOODLE_INTERNAL') || die();
00027 
00028 
00035 class enrol_meta_handler {
00036 
00044     protected static function sync_course_instances($courseid, $userid) {
00045         global $DB;
00046 
00047         static $preventrecursion = false;
00048 
00049         // does anything want to sync with this parent?
00050         if (!$enrols = $DB->get_records('enrol', array('customint1'=>$courseid, 'enrol'=>'meta'), 'id ASC')) {
00051             return;
00052         }
00053 
00054         if ($preventrecursion) {
00055             return;
00056         }
00057 
00058         $preventrecursion = true;
00059 
00060         try {
00061             foreach ($enrols as $enrol) {
00062                 self::sync_with_parent_course($enrol, $userid);
00063             }
00064         } catch (Exception $e) {
00065             $preventrecursion = false;
00066             throw $e;
00067         }
00068 
00069         $preventrecursion = false;
00070     }
00071 
00082     protected static function sync_with_parent_course(stdClass $instance, $userid) {
00083         global $DB, $CFG;
00084 
00085         $plugin = enrol_get_plugin('meta');
00086 
00087         if ($instance->customint1 == $instance->courseid) {
00088             // can not sync with self!!!
00089             return;
00090         }
00091 
00092         $context = context_course::instance($instance->courseid);
00093 
00094         if (!$parentcontext = context_course::instance($instance->customint1, IGNORE_MISSING)) {
00095             // linking to missing course is not possible
00096             role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta'));
00097             return;
00098         }
00099 
00100         // list of enrolments in parent course (we ignore meta enrols in parents completely)
00101         list($enabled, $params) = $DB->get_in_or_equal(explode(',', $CFG->enrol_plugins_enabled), SQL_PARAMS_NAMED, 'e');
00102         $params['userid'] = $userid;
00103         $params['parentcourse'] = $instance->customint1;
00104         $sql = "SELECT ue.*
00105                   FROM {user_enrolments} ue
00106                   JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol <> 'meta' AND e.courseid = :parentcourse AND e.enrol $enabled)
00107                  WHERE ue.userid = :userid";
00108         $parentues = $DB->get_records_sql($sql, $params);
00109         // current enrolments for this instance
00110         $ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid));
00111 
00112         // first deal with users that are not enrolled in parent
00113         if (empty($parentues)) {
00114             self::user_not_supposed_to_be_here($instance, $ue, $context, $plugin);
00115             return;
00116         }
00117 
00118         if (!enrol_is_enabled('meta')) {
00119             if ($ue) {
00120                 role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta'));
00121             }
00122             return;
00123         }
00124 
00125         $skiproles = $plugin->get_config('nosyncroleids', '');
00126         $skiproles = empty($skiproles) ? array() : explode(',', $skiproles);
00127         $syncall   = $plugin->get_config('syncall', 1);
00128 
00129         // roles in parent course (meta enrols must be ignored!)
00130         $parentroles = array();
00131         list($ignoreroles, $params) = $DB->get_in_or_equal($skiproles, SQL_PARAMS_NAMED, 'ri', false, -1);
00132         $params['contextid'] = $parentcontext->id;
00133         $params['userid'] = $userid;
00134         $select = "contextid = :contextid AND userid = :userid AND component <> 'enrol_meta' AND roleid $ignoreroles";
00135         foreach($DB->get_records_select('role_assignments', $select, $params) as $ra) {
00136             $parentroles[$ra->roleid] = $ra->roleid;
00137         }
00138 
00139         // roles from this instance
00140         $roles = array();
00141         $ras = $DB->get_records('role_assignments', array('contextid'=>$context->id, 'userid'=>$userid, 'component'=>'enrol_meta', 'itemid'=>$instance->id));
00142         foreach($ras as $ra) {
00143             $roles[$ra->roleid] = $ra->roleid;
00144         }
00145         unset($ras);
00146 
00147         // do we want users without roles?
00148         if (!$syncall and empty($parentroles)) {
00149             self::user_not_supposed_to_be_here($instance, $ue, $context, $plugin);
00150             return;
00151         }
00152 
00153         // is parent enrol active? (we ignore enrol starts and ends, sorry it would be too complex)
00154         $parentstatus = ENROL_USER_SUSPENDED;
00155         foreach ($parentues as $pue) {
00156             if ($pue->status == ENROL_USER_ACTIVE) {
00157                 $parentstatus = ENROL_USER_ACTIVE;
00158                 break;
00159             }
00160         }
00161 
00162         // enrol user if not enrolled yet or fix status
00163         if ($ue) {
00164             if ($parentstatus != $ue->status) {
00165                 $plugin->update_user_enrol($instance, $userid, $parentstatus);
00166                 $ue->status = $parentstatus;
00167             }
00168         } else {
00169             $plugin->enrol_user($instance, $userid, NULL, 0, 0, $parentstatus);
00170             $ue = new stdClass();
00171             $ue->userid = $userid;
00172             $ue->enrolid = $instance->id;
00173             $ue->status = $parentstatus;
00174         }
00175 
00176         // only active users in enabled instances are supposed to have roles (we can reassign the roles any time later)
00177         if ($ue->status != ENROL_USER_ACTIVE or $instance->status != ENROL_INSTANCE_ENABLED) {
00178             if ($roles) {
00179                 role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$instance->id));
00180             }
00181             return;
00182         }
00183 
00184         // add new roles
00185         foreach ($parentroles as $rid) {
00186             if (!isset($roles[$rid])) {
00187                 role_assign($rid, $userid, $context->id, 'enrol_meta', $instance->id);
00188             }
00189         }
00190 
00191         // remove roles
00192         foreach ($roles as $rid) {
00193             if (!isset($parentroles[$rid])) {
00194                 role_unassign($rid, $userid, $context->id, 'enrol_meta', $instance->id);
00195             }
00196         }
00197     }
00198 
00208     protected static function user_not_supposed_to_be_here($instance, $ue, context_course $context, $plugin) {
00209         if (!$ue) {
00210             // not enrolled yet - simple!
00211             return;
00212         }
00213 
00214         $userid = $ue->userid;
00215         $unenrolaction = $plugin->get_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
00216 
00217         if ($unenrolaction == ENROL_EXT_REMOVED_UNENROL) {
00218             // purges grades, group membership, preferences, etc. - admins were warned!
00219             $plugin->unenrol_user($instance, $userid);
00220             return;
00221 
00222         } else { // ENROL_EXT_REMOVED_SUSPENDNOROLES
00223             // just suspend users and remove all roles (we can reassign the roles any time later)
00224             if ($ue->status != ENROL_USER_SUSPENDED) {
00225                 $plugin->update_user_enrol($instance, $userid, ENROL_USER_SUSPENDED);
00226                 role_unassign_all(array('userid'=>$userid, 'contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$instance->id));
00227             }
00228             return;
00229         }
00230     }
00231 
00238     public static function role_assigned($ra) {
00239         if (!enrol_is_enabled('meta')) {
00240             return true;
00241         }
00242 
00243         // prevent circular dependencies - we can not sync meta roles recursively
00244         if ($ra->component === 'enrol_meta') {
00245             return true;
00246         }
00247 
00248         // only course level roles are interesting
00249         if (!$parentcontext = context::instance_by_id($ra->contextid, IGNORE_MISSING)) {
00250             return true;
00251         }
00252         if ($parentcontext->contextlevel != CONTEXT_COURSE) {
00253             return true;
00254         }
00255 
00256         self::sync_course_instances($parentcontext->instanceid, $ra->userid);
00257 
00258         return true;
00259     }
00260 
00267     public static function role_unassigned($ra) {
00268         if (!enrol_is_enabled('meta')) {
00269             // all roles are removed via cron automatically
00270             return true;
00271         }
00272 
00273         // prevent circular dependencies - we can not sync meta roles recursively
00274         if ($ra->component === 'enrol_meta') {
00275             return true;
00276         }
00277 
00278         // only course level roles are interesting
00279         if (!$parentcontext = context::instance_by_id($ra->contextid, IGNORE_MISSING)) {
00280             return true;
00281         }
00282         if ($parentcontext->contextlevel != CONTEXT_COURSE) {
00283             return true;
00284         }
00285 
00286         self::sync_course_instances($parentcontext->instanceid, $ra->userid);
00287 
00288         return true;
00289     }
00290 
00297     public static function user_enrolled($ue) {
00298         if (!enrol_is_enabled('meta')) {
00299             // no more enrolments for disabled plugins
00300             return true;
00301         }
00302 
00303         if ($ue->enrol === 'meta') {
00304             // prevent circular dependencies - we can not sync meta enrolments recursively
00305             return true;
00306         }
00307 
00308         self::sync_course_instances($ue->courseid, $ue->userid);
00309 
00310         return true;
00311     }
00312 
00319     public static function user_unenrolled($ue) {
00320 
00321         // keep unenrolling even if plugin disabled
00322 
00323         if ($ue->enrol === 'meta') {
00324             // prevent circular dependencies - we can not sync meta enrolments recursively
00325             return true;
00326         }
00327 
00328         self::sync_course_instances($ue->courseid, $ue->userid);
00329 
00330         return true;
00331     }
00332 
00339     public static function user_enrol_modified($ue) {
00340         if (!enrol_is_enabled('meta')) {
00341             // no modifications if plugin disabled
00342             return true;
00343         }
00344 
00345         if ($ue->enrol === 'meta') {
00346             // prevent circular dependencies - we can not sync meta enrolments recursively
00347             return true;
00348         }
00349 
00350         self::sync_course_instances($ue->courseid, $ue->userid);
00351 
00352         return true;
00353     }
00354 
00361     public static function course_deleted($course) {
00362         global $DB;
00363 
00364         // NOTE: do not test if plugin enabled, we want to keep disabling instances with invalid course links
00365 
00366         // does anything want to sync with this parent?
00367         if (!$enrols = $DB->get_records('enrol', array('customint1'=>$course->id, 'enrol'=>'meta'), 'courseid ASC, id ASC')) {
00368             return true;
00369         }
00370 
00371         $plugin = enrol_get_plugin('meta');
00372 
00373         // hack the DB info for all courses first
00374         foreach ($enrols as $enrol) {
00375             $enrol->customint1 = 0;
00376             $enrol->status = ENROL_INSTANCE_DISABLED;
00377             $DB->update_record('enrol', $enrol);
00378             $context = context_course::instance($enrol->courseid);
00379             role_unassign_all(array('contextid'=>$context->id, 'component'=>'enrol_meta', 'itemid'=>$enrol->id));
00380         }
00381 
00382         // now trigger sync for each instance and purge caches
00383         foreach ($enrols as $enrol) {
00384             $plugin->update_status($enrol, ENROL_INSTANCE_DISABLED);
00385         }
00386 
00387         return true;
00388     }
00389 }
00390 
00391 
00399 function enrol_meta_sync($courseid = NULL, $verbose = false) {
00400     global $CFG, $DB;
00401 
00402     // purge all roles if meta sync disabled, those can be recreated later here in cron
00403     if (!enrol_is_enabled('meta')) {
00404         if ($verbose) {
00405             mtrace('Meta sync plugin is disabled, unassigning all plugin roles and stopping.');
00406         }
00407         role_unassign_all(array('component'=>'enrol_meta'));
00408         return 2;
00409     }
00410 
00411     // unfortunately this may take a long time, execution can be interrupted safely
00412     @set_time_limit(0);
00413     raise_memory_limit(MEMORY_HUGE);
00414 
00415     if ($verbose) {
00416         mtrace('Starting user enrolment synchronisation...');
00417     }
00418 
00419     $instances = array(); // cache instances
00420 
00421     $meta = enrol_get_plugin('meta');
00422 
00423     $unenrolaction = $meta->get_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
00424     $skiproles     = $meta->get_config('nosyncroleids', '');
00425     $skiproles     = empty($skiproles) ? array() : explode(',', $skiproles);
00426     $syncall       = $meta->get_config('syncall', 1);
00427 
00428     $allroles = get_all_roles();
00429 
00430 
00431     // iterate through all not enrolled yet users
00432     $onecourse = $courseid ? "AND e.courseid = :courseid" : "";
00433     list($enabled, $params) = $DB->get_in_or_equal(explode(',', $CFG->enrol_plugins_enabled), SQL_PARAMS_NAMED, 'e');
00434     $params['courseid'] = $courseid;
00435     $sql = "SELECT pue.userid, e.id AS enrolid, pue.status
00436               FROM {user_enrolments} pue
00437               JOIN {enrol} pe ON (pe.id = pue.enrolid AND pe.enrol <> 'meta' AND pe.enrol $enabled)
00438               JOIN {enrol} e ON (e.customint1 = pe.courseid AND e.enrol = 'meta' $onecourse)
00439          LEFT JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = pue.userid)
00440              WHERE ue.id IS NULL";
00441 
00442     $rs = $DB->get_recordset_sql($sql, $params);
00443     foreach($rs as $ue) {
00444         if (!isset($instances[$ue->enrolid])) {
00445             $instances[$ue->enrolid] = $DB->get_record('enrol', array('id'=>$ue->enrolid));
00446         }
00447         $instance = $instances[$ue->enrolid];
00448 
00449         if (!$syncall) {
00450             // this may be slow if very many users are ignored in sync
00451             $parentcontext = context_course::instance($instance->customint1);
00452             list($ignoreroles, $params) = $DB->get_in_or_equal($skiproles, SQL_PARAMS_NAMED, 'ri', false, -1);
00453             $params['contextid'] = $parentcontext->id;
00454             $params['userid'] = $ue->userid;
00455             $select = "contextid = :contextid AND userid = :userid AND component <> 'enrol_meta' AND roleid $ignoreroles";
00456             if (!$DB->record_exists_select('role_assignments', $select, $params)) {
00457                 // bad luck, this user does not have any role we want in parent course
00458                 if ($verbose) {
00459                     mtrace("  skipping enrolling: $ue->userid ==> $instance->courseid (user without role)");
00460                 }
00461                 continue;
00462             }
00463         }
00464 
00465         $meta->enrol_user($instance, $ue->userid, $ue->status);
00466         if ($verbose) {
00467             mtrace("  enrolling: $ue->userid ==> $instance->courseid");
00468         }
00469     }
00470     $rs->close();
00471 
00472 
00473     // unenrol as necessary - ignore enabled flag, we want to get rid of existing enrols in any case
00474     $onecourse = $courseid ? "AND e.courseid = :courseid" : "";
00475     list($enabled, $params) = $DB->get_in_or_equal(explode(',', $CFG->enrol_plugins_enabled), SQL_PARAMS_NAMED, 'e');
00476     $params['courseid'] = $courseid;
00477     $sql = "SELECT ue.*
00478               FROM {user_enrolments} ue
00479               JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = 'meta' $onecourse)
00480          LEFT JOIN (SELECT xpue.userid, xpe.courseid
00481                       FROM {user_enrolments} xpue
00482                       JOIN {enrol} xpe ON (xpe.id = xpue.enrolid AND xpe.enrol <> 'meta' AND xpe.enrol $enabled)
00483                    ) pue ON (pue.courseid = e.customint1 AND pue.userid = ue.userid)
00484              WHERE pue.userid IS NULL";
00485     $rs = $DB->get_recordset_sql($sql, $params);
00486     foreach($rs as $ue) {
00487         if (!isset($instances[$ue->enrolid])) {
00488             $instances[$ue->enrolid] = $DB->get_record('enrol', array('id'=>$ue->enrolid));
00489         }
00490         $instance = $instances[$ue->enrolid];
00491 
00492         if ($unenrolaction == ENROL_EXT_REMOVED_UNENROL) {
00493             $meta->unenrol_user($instance, $ue->userid);
00494             if ($verbose) {
00495                 mtrace("  unenrolling: $ue->userid ==> $instance->courseid");
00496             }
00497             continue;
00498 
00499         } else { // ENROL_EXT_REMOVED_SUSPENDNOROLES
00500             // just disable and ignore any changes
00501             if ($ue->status != ENROL_USER_SUSPENDED) {
00502                 $meta->update_user_enrol($instance, $ue->userid, ENROL_USER_SUSPENDED);
00503                 $context = context_course::instance($instance->courseid);
00504                 role_unassign_all(array('userid'=>$ue->userid, 'contextid'=>$context->id, 'component'=>'enrol_meta'));
00505                 if ($verbose) {
00506                     mtrace("  suspending and removing all roles: $ue->userid ==> $instance->courseid");
00507                 }
00508             }
00509             continue;
00510         }
00511     }
00512     $rs->close();
00513 
00514 
00515     // update status - meta enrols + start and end dates are ignored, sorry
00516     // note the trick here is that the active enrolment and instance constants have value 0
00517     $onecourse = $courseid ? "AND e.courseid = :courseid" : "";
00518     list($enabled, $params) = $DB->get_in_or_equal(explode(',', $CFG->enrol_plugins_enabled), SQL_PARAMS_NAMED, 'e');
00519     $params['courseid'] = $courseid;
00520     $sql = "SELECT ue.userid, ue.enrolid, pue.pstatus
00521               FROM {user_enrolments} ue
00522               JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = 'meta' $onecourse)
00523               JOIN (SELECT xpue.userid, xpe.courseid, MIN(xpue.status + xpe.status) AS pstatus
00524                       FROM {user_enrolments} xpue
00525                       JOIN {enrol} xpe ON (xpe.id = xpue.enrolid AND xpe.enrol <> 'meta' AND xpe.enrol $enabled)
00526                   GROUP BY xpue.userid, xpe.courseid
00527                    ) pue ON (pue.courseid = e.customint1 AND pue.userid = ue.userid)
00528              WHERE (pue.pstatus = 0 AND ue.status > 0) OR (pue.pstatus > 0 and ue.status = 0)";
00529     $rs = $DB->get_recordset_sql($sql, $params);
00530     foreach($rs as $ue) {
00531         if (!isset($instances[$ue->enrolid])) {
00532             $instances[$ue->enrolid] = $DB->get_record('enrol', array('id'=>$ue->enrolid));
00533         }
00534         $instance = $instances[$ue->enrolid];
00535         $ue->pstatus = ($ue->pstatus == ENROL_USER_ACTIVE) ? ENROL_USER_ACTIVE : ENROL_USER_SUSPENDED;
00536 
00537         if ($ue->pstatus == ENROL_USER_ACTIVE and !$syncall and $unenrolaction != ENROL_EXT_REMOVED_UNENROL) {
00538             // this may be slow if very many users are ignored in sync
00539             $parentcontext = context_course::instance($instance->customint1);
00540             list($ignoreroles, $params) = $DB->get_in_or_equal($skiproles, SQL_PARAMS_NAMED, 'ri', false, -1);
00541             $params['contextid'] = $parentcontext->id;
00542             $params['userid'] = $ue->userid;
00543             $select = "contextid = :contextid AND userid = :userid AND component <> 'enrol_meta' AND roleid $ignoreroles";
00544             if (!$DB->record_exists_select('role_assignments', $select, $params)) {
00545                 // bad luck, this user does not have any role we want in parent course
00546                 if ($verbose) {
00547                     mtrace("  skipping unsuspending: $ue->userid ==> $instance->courseid (user without role)");
00548                 }
00549                 continue;
00550             }
00551         }
00552 
00553         $meta->update_user_enrol($instance, $ue->userid, $ue->pstatus);
00554         if ($verbose) {
00555             if ($ue->pstatus == ENROL_USER_ACTIVE) {
00556                 mtrace("  unsuspending: $ue->userid ==> $instance->courseid");
00557             } else {
00558                 mtrace("  suspending: $ue->userid ==> $instance->courseid");
00559             }
00560         }
00561     }
00562     $rs->close();
00563 
00564 
00565     // now assign all necessary roles
00566     $enabled = explode(',', $CFG->enrol_plugins_enabled);
00567     foreach($enabled as $k=>$v) {
00568         if ($v === 'meta') {
00569             continue; // no meta sync of meta roles
00570         }
00571         $enabled[$k] = 'enrol_'.$v;
00572     }
00573     $enabled[] = $DB->sql_empty(); // manual assignments are replicated too
00574 
00575     $onecourse = $courseid ? "AND e.courseid = :courseid" : "";
00576     list($enabled, $params) = $DB->get_in_or_equal($enabled, SQL_PARAMS_NAMED, 'e');
00577     $params['coursecontext'] = CONTEXT_COURSE;
00578     $params['courseid'] = $courseid;
00579     $params['activeuser'] = ENROL_USER_ACTIVE;
00580     $params['enabledinstance'] = ENROL_INSTANCE_ENABLED;
00581     $sql = "SELECT DISTINCT pra.roleid, pra.userid, c.id AS contextid, e.id AS enrolid, e.courseid
00582               FROM {role_assignments} pra
00583               JOIN {user} u ON (u.id = pra.userid AND u.deleted = 0)
00584               JOIN {context} pc ON (pc.id = pra.contextid AND pc.contextlevel = :coursecontext AND pra.component $enabled)
00585               JOIN {enrol} e ON (e.customint1 = pc.instanceid AND e.enrol = 'meta' $onecourse AND e.status = :enabledinstance)
00586               JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = u.id AND ue.status = :activeuser)
00587               JOIN {context} c ON (c.contextlevel = pc.contextlevel AND c.instanceid = e.courseid)
00588          LEFT JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.userid = pra.userid AND ra.roleid = pra.roleid AND ra.itemid = e.id AND ra.component = 'enrol_meta')
00589              WHERE ra.id IS NULL";
00590 
00591     if ($ignored = $meta->get_config('nosyncroleids')) {
00592         list($notignored, $xparams) = $DB->get_in_or_equal(explode(',', $ignored), SQL_PARAMS_NAMED, 'ig', false);
00593         $params = array_merge($params, $xparams);
00594         $sql = "$sql AND pra.roleid $notignored";
00595     }
00596 
00597     $rs = $DB->get_recordset_sql($sql, $params);
00598     foreach($rs as $ra) {
00599         role_assign($ra->roleid, $ra->userid, $ra->contextid, 'enrol_meta', $ra->enrolid);
00600         if ($verbose) {
00601             mtrace("  assigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname);
00602         }
00603     }
00604     $rs->close();
00605 
00606 
00607     // remove unwanted roles - include ignored roles and disabled plugins too
00608     $onecourse = $courseid ? "AND e.courseid = :courseid" : "";
00609     $params = array();
00610     $params['coursecontext'] = CONTEXT_COURSE;
00611     $params['courseid'] = $courseid;
00612     $params['activeuser'] = ENROL_USER_ACTIVE;
00613     $params['enabledinstance'] = ENROL_INSTANCE_ENABLED;
00614     if ($ignored = $meta->get_config('nosyncroleids')) {
00615         list($notignored, $xparams) = $DB->get_in_or_equal(explode(',', $ignored), SQL_PARAMS_NAMED, 'ig', false);
00616         $params = array_merge($params, $xparams);
00617         $notignored = "AND pra.roleid $notignored";
00618     } else {
00619         $notignored = "";
00620     }
00621     $sql = "SELECT ra.roleid, ra.userid, ra.contextid, ra.itemid, e.courseid
00622               FROM {role_assignments} ra
00623               JOIN {enrol} e ON (e.id = ra.itemid AND ra.component = 'enrol_meta' AND e.enrol = 'meta' $onecourse)
00624               JOIN {context} pc ON (pc.instanceid = e.customint1 AND pc.contextlevel = :coursecontext)
00625          LEFT JOIN {role_assignments} pra ON (pra.contextid = pc.id AND pra.userid = ra.userid AND pra.roleid = ra.roleid AND pra.component <> 'enrol_meta' $notignored)
00626          LEFT JOIN {user_enrolments} ue ON (ue.enrolid = e.id AND ue.userid = ra.userid AND ue.status = :activeuser)
00627              WHERE pra.id IS NULL OR ue.id IS NULL OR e.status <> :enabledinstance";
00628 
00629     $rs = $DB->get_recordset_sql($sql, $params);
00630     foreach($rs as $ra) {
00631         role_unassign($ra->roleid, $ra->userid, $ra->contextid, 'enrol_meta', $ra->itemid);
00632         if ($verbose) {
00633             mtrace("  unassigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname);
00634         }
00635     }
00636     $rs->close();
00637 
00638 
00639     // kick out or suspend users without synced roles if syncall disabled
00640     if (!$syncall) {
00641         if ($unenrolaction == ENROL_EXT_REMOVED_UNENROL) {
00642             $onecourse = $courseid ? "AND e.courseid = :courseid" : "";
00643             $params = array();
00644             $params['coursecontext'] = CONTEXT_COURSE;
00645             $params['courseid'] = $courseid;
00646             $sql = "SELECT ue.userid, ue.enrolid
00647                       FROM {user_enrolments} ue
00648                       JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = 'meta' $onecourse)
00649                       JOIN {context} c ON (e.courseid = c.instanceid AND c.contextlevel = :coursecontext)
00650                  LEFT JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.itemid = e.id AND ra.userid = ue.userid)
00651                      WHERE ra.id IS NULL";
00652             $ues = $DB->get_recordset_sql($sql, $params);
00653             foreach($ues as $ue) {
00654                 if (!isset($instances[$ue->enrolid])) {
00655                     $instances[$ue->enrolid] = $DB->get_record('enrol', array('id'=>$ue->enrolid));
00656                 }
00657                 $instance = $instances[$ue->enrolid];
00658                 $meta->unenrol_user($instance, $ue->userid);
00659                 if ($verbose) {
00660                     mtrace("  unenrolling: $ue->userid ==> $instance->courseid (user without role)");
00661                 }
00662             }
00663             $ues->close();
00664 
00665         } else {
00666             // just suspend the users
00667             $onecourse = $courseid ? "AND e.courseid = :courseid" : "";
00668             $params = array();
00669             $params['coursecontext'] = CONTEXT_COURSE;
00670             $params['courseid'] = $courseid;
00671             $params['active'] = ENROL_USER_ACTIVE;
00672             $sql = "SELECT ue.userid, ue.enrolid
00673                       FROM {user_enrolments} ue
00674                       JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = 'meta' $onecourse)
00675                       JOIN {context} c ON (e.courseid = c.instanceid AND c.contextlevel = :coursecontext)
00676                  LEFT JOIN {role_assignments} ra ON (ra.contextid = c.id AND ra.itemid = e.id AND ra.userid = ue.userid)
00677                      WHERE ra.id IS NULL AND ue.status = :active";
00678             $ues = $DB->get_recordset_sql($sql, $params);
00679             foreach($ues as $ue) {
00680                 if (!isset($instances[$ue->enrolid])) {
00681                     $instances[$ue->enrolid] = $DB->get_record('enrol', array('id'=>$ue->enrolid));
00682                 }
00683                 $instance = $instances[$ue->enrolid];
00684                 $meta->update_user_enrol($instance, $ue->userid, ENROL_USER_SUSPENDED);
00685                 if ($verbose) {
00686                     mtrace("  suspending: $ue->userid ==> $instance->courseid (user without role)");
00687                 }
00688             }
00689             $ues->close();
00690         }
00691     }
00692 
00693     if ($verbose) {
00694         mtrace('...user enrolment synchronisation finished.');
00695     }
00696 
00697     return 0;
00698 }
 All Data Structures Namespaces Files Functions Variables Enumerations