|
Moodle
2.2.1
http://www.collinsharper.com
|
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 }