See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
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 * Auxiliary manual user enrolment lib, the main purpose is to lower memory requirements... 19 * 20 * @package enrol_manual 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 require_once($CFG->dirroot . '/user/selector/lib.php'); 28 require_once($CFG->dirroot . '/enrol/locallib.php'); 29 30 31 /** 32 * Enrol candidates. 33 */ 34 class enrol_manual_potential_participant extends user_selector_base { 35 protected $enrolid; 36 37 public function __construct($name, $options) { 38 $this->enrolid = $options['enrolid']; 39 parent::__construct($name, $options); 40 } 41 42 /** 43 * Candidate users 44 * @param string $search 45 * @return array 46 */ 47 public function find_users($search) { 48 global $DB; 49 // By default wherecondition retrieves all users except the deleted, not confirmed and guest. 50 list($wherecondition, $params) = $this->search_sql($search, 'u'); 51 $params['enrolid'] = $this->enrolid; 52 53 $fields = 'SELECT ' . $this->required_fields_sql('u'); 54 $countfields = 'SELECT COUNT(1)'; 55 56 $sql = " FROM {user} u 57 LEFT JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid = :enrolid) 58 WHERE $wherecondition 59 AND ue.id IS NULL"; 60 61 list($sort, $sortparams) = users_order_by_sql('u', $search, $this->accesscontext); 62 $order = ' ORDER BY ' . $sort; 63 64 if (!$this->is_validating()) { 65 $potentialmemberscount = $DB->count_records_sql($countfields . $sql, $params); 66 if ($potentialmemberscount > $this->maxusersperpage) { 67 return $this->too_many_results($search, $potentialmemberscount); 68 } 69 } 70 71 $availableusers = $DB->get_records_sql($fields . $sql . $order, array_merge($params, $sortparams)); 72 73 if (empty($availableusers)) { 74 return array(); 75 } 76 77 78 if ($search) { 79 $groupname = get_string('enrolcandidatesmatching', 'enrol', $search); 80 } else { 81 $groupname = get_string('enrolcandidates', 'enrol'); 82 } 83 84 return array($groupname => $availableusers); 85 } 86 87 protected function get_options() { 88 $options = parent::get_options(); 89 $options['enrolid'] = $this->enrolid; 90 $options['file'] = 'enrol/manual/locallib.php'; 91 return $options; 92 } 93 } 94 95 /** 96 * Enrolled users. 97 */ 98 class enrol_manual_current_participant extends user_selector_base { 99 protected $courseid; 100 protected $enrolid; 101 102 public function __construct($name, $options) { 103 $this->enrolid = $options['enrolid']; 104 parent::__construct($name, $options); 105 } 106 107 /** 108 * Candidate users 109 * @param string $search 110 * @return array 111 */ 112 public function find_users($search) { 113 global $DB; 114 // By default wherecondition retrieves all users except the deleted, not confirmed and guest. 115 list($wherecondition, $params) = $this->search_sql($search, 'u'); 116 $params['enrolid'] = $this->enrolid; 117 118 $fields = 'SELECT ' . $this->required_fields_sql('u'); 119 $countfields = 'SELECT COUNT(1)'; 120 121 $sql = " FROM {user} u 122 JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid = :enrolid) 123 WHERE $wherecondition"; 124 125 list($sort, $sortparams) = users_order_by_sql('u', $search, $this->accesscontext); 126 $order = ' ORDER BY ' . $sort; 127 128 if (!$this->is_validating()) { 129 $potentialmemberscount = $DB->count_records_sql($countfields . $sql, $params); 130 if ($potentialmemberscount > $this->maxusersperpage) { 131 return $this->too_many_results($search, $potentialmemberscount); 132 } 133 } 134 135 $availableusers = $DB->get_records_sql($fields . $sql . $order, array_merge($params, $sortparams)); 136 137 if (empty($availableusers)) { 138 return array(); 139 } 140 141 142 if ($search) { 143 $groupname = get_string('enrolledusersmatching', 'enrol', $search); 144 } else { 145 $groupname = get_string('enrolledusers', 'enrol'); 146 } 147 148 return array($groupname => $availableusers); 149 } 150 151 protected function get_options() { 152 $options = parent::get_options(); 153 $options['enrolid'] = $this->enrolid; 154 $options['file'] = 'enrol/manual/locallib.php'; 155 return $options; 156 } 157 } 158 159 /** 160 * A bulk operation for the manual enrolment plugin to edit selected users. 161 * 162 * @copyright 2011 Sam Hemelryk 163 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 164 */ 165 class enrol_manual_editselectedusers_operation extends enrol_bulk_enrolment_operation { 166 167 /** 168 * Returns the title to display for this bulk operation. 169 * 170 * @return string 171 */ 172 public function get_title() { 173 return get_string('editselectedusers', 'enrol_manual'); 174 } 175 176 /** 177 * Returns the identifier for this bulk operation. This is the key used when the plugin 178 * returns an array containing all of the bulk operations it supports. 179 */ 180 public function get_identifier() { 181 return 'editselectedusers'; 182 } 183 184 /** 185 * Processes the bulk operation request for the given userids with the provided properties. 186 * 187 * @param course_enrolment_manager $manager 188 * @param array $userids 189 * @param stdClass $properties The data returned by the form. 190 */ 191 public function process(course_enrolment_manager $manager, array $users, stdClass $properties) { 192 global $DB, $USER; 193 194 if (!has_capability("enrol/manual:manage", $manager->get_context())) { 195 return false; 196 } 197 198 // Get all of the user enrolment id's. 199 $ueids = array(); 200 $instances = array(); 201 foreach ($users as $user) { 202 foreach ($user->enrolments as $enrolment) { 203 $ueids[] = $enrolment->id; 204 if (!array_key_exists($enrolment->id, $instances)) { 205 $instances[$enrolment->id] = $enrolment; 206 } 207 } 208 } 209 210 // Check that each instance is manageable by the current user. 211 foreach ($instances as $instance) { 212 if (!$this->plugin->allow_manage($instance)) { 213 return false; 214 } 215 } 216 217 // Collect the known properties. 218 $status = $properties->status; 219 $timestart = $properties->timestart; 220 $timeend = $properties->timeend; 221 222 list($ueidsql, $params) = $DB->get_in_or_equal($ueids, SQL_PARAMS_NAMED); 223 224 $updatesql = array(); 225 if ($status == ENROL_USER_ACTIVE || $status == ENROL_USER_SUSPENDED) { 226 $updatesql[] = 'status = :status'; 227 $params['status'] = (int)$status; 228 } 229 if (!empty($timestart)) { 230 $updatesql[] = 'timestart = :timestart'; 231 $params['timestart'] = (int)$timestart; 232 } 233 if (!empty($timeend)) { 234 $updatesql[] = 'timeend = :timeend'; 235 $params['timeend'] = (int)$timeend; 236 } 237 if (empty($updatesql)) { 238 return true; 239 } 240 241 // Update the modifierid. 242 $updatesql[] = 'modifierid = :modifierid'; 243 $params['modifierid'] = (int)$USER->id; 244 245 // Update the time modified. 246 $updatesql[] = 'timemodified = :timemodified'; 247 $params['timemodified'] = time(); 248 249 // Build the SQL statement. 250 $updatesql = join(', ', $updatesql); 251 $sql = "UPDATE {user_enrolments} 252 SET $updatesql 253 WHERE id $ueidsql"; 254 255 if ($DB->execute($sql, $params)) { 256 foreach ($users as $user) { 257 foreach ($user->enrolments as $enrolment) { 258 $enrolment->courseid = $enrolment->enrolmentinstance->courseid; 259 $enrolment->enrol = 'manual'; 260 // Trigger event. 261 $event = \core\event\user_enrolment_updated::create( 262 array( 263 'objectid' => $enrolment->id, 264 'courseid' => $enrolment->courseid, 265 'context' => context_course::instance($enrolment->courseid), 266 'relateduserid' => $user->id, 267 'other' => array('enrol' => 'manual') 268 ) 269 ); 270 $event->trigger(); 271 } 272 } 273 // Delete cached course contacts for this course because they may be affected. 274 cache::make('core', 'coursecontacts')->delete($manager->get_context()->instanceid); 275 return true; 276 } 277 278 return false; 279 } 280 281 /** 282 * Returns a enrol_bulk_enrolment_operation extension form to be used 283 * in collecting required information for this operation to be processed. 284 * 285 * @param string|moodle_url|null $defaultaction 286 * @param mixed $defaultcustomdata 287 * @return enrol_manual_editselectedusers_form 288 */ 289 public function get_form($defaultaction = null, $defaultcustomdata = null) { 290 global $CFG; 291 require_once($CFG->dirroot.'/enrol/manual/bulkchangeforms.php'); 292 return new enrol_manual_editselectedusers_form($defaultaction, $defaultcustomdata); 293 } 294 } 295 296 297 /** 298 * A bulk operation for the manual enrolment plugin to delete selected users enrolments. 299 * 300 * @copyright 2011 Sam Hemelryk 301 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 302 */ 303 class enrol_manual_deleteselectedusers_operation extends enrol_bulk_enrolment_operation { 304 305 /** 306 * Returns the title to display for this bulk operation. 307 * 308 * @return string 309 */ 310 public function get_identifier() { 311 return 'deleteselectedusers'; 312 } 313 314 /** 315 * Returns the identifier for this bulk operation. This is the key used when the plugin 316 * returns an array containing all of the bulk operations it supports. 317 * 318 * @return string 319 */ 320 public function get_title() { 321 return get_string('deleteselectedusers', 'enrol_manual'); 322 } 323 324 /** 325 * Returns a enrol_bulk_enrolment_operation extension form to be used 326 * in collecting required information for this operation to be processed. 327 * 328 * @param string|moodle_url|null $defaultaction 329 * @param mixed $defaultcustomdata 330 * @return enrol_manual_editselectedusers_form 331 */ 332 public function get_form($defaultaction = null, $defaultcustomdata = null) { 333 global $CFG; 334 require_once($CFG->dirroot.'/enrol/manual/bulkchangeforms.php'); 335 if (!array($defaultcustomdata)) { 336 $defaultcustomdata = array(); 337 } 338 $defaultcustomdata['title'] = $this->get_title(); 339 $defaultcustomdata['message'] = get_string('confirmbulkdeleteenrolment', 'enrol_manual'); 340 $defaultcustomdata['button'] = get_string('unenrolusers', 'enrol_manual'); 341 return new enrol_manual_deleteselectedusers_form($defaultaction, $defaultcustomdata); 342 } 343 344 /** 345 * Processes the bulk operation request for the given userids with the provided properties. 346 * 347 * @global moodle_database $DB 348 * @param course_enrolment_manager $manager 349 * @param array $userids 350 * @param stdClass $properties The data returned by the form. 351 */ 352 public function process(course_enrolment_manager $manager, array $users, stdClass $properties) { 353 if (!has_capability("enrol/manual:unenrol", $manager->get_context())) { 354 return false; 355 } 356 $counter = 0; 357 foreach ($users as $user) { 358 foreach ($user->enrolments as $enrolment) { 359 $plugin = $enrolment->enrolmentplugin; 360 $instance = $enrolment->enrolmentinstance; 361 if ($plugin->allow_unenrol_user($instance, $enrolment)) { 362 $plugin->unenrol_user($instance, $user->id); 363 $counter++; 364 } 365 } 366 } 367 // Display a notification message after the bulk user unenrollment. 368 if ($counter > 0) { 369 \core\notification::info(get_string('totalunenrolledusers', 'enrol', $counter)); 370 } 371 return true; 372 } 373 } 374 375 /** 376 * Migrates all enrolments of the given plugin to enrol_manual plugin, 377 * this is used for example during plugin uninstallation. 378 * 379 * NOTE: this function does not trigger role and enrolment related events. 380 * 381 * @param string $enrol The enrolment method. 382 */ 383 function enrol_manual_migrate_plugin_enrolments($enrol) { 384 global $DB; 385 386 if ($enrol === 'manual') { 387 // We can not migrate to self. 388 return; 389 } 390 391 $manualplugin = enrol_get_plugin('manual'); 392 393 $params = array('enrol'=>$enrol); 394 $sql = "SELECT e.id, e.courseid, e.status, MIN(me.id) AS mid, COUNT(ue.id) AS cu 395 FROM {enrol} e 396 JOIN {user_enrolments} ue ON (ue.enrolid = e.id) 397 JOIN {course} c ON (c.id = e.courseid) 398 LEFT JOIN {enrol} me ON (me.courseid = e.courseid AND me.enrol='manual') 399 WHERE e.enrol = :enrol 400 GROUP BY e.id, e.courseid, e.status 401 ORDER BY e.id"; 402 $rs = $DB->get_recordset_sql($sql, $params); 403 404 foreach($rs as $e) { 405 $minstance = false; 406 if (!$e->mid) { 407 // Manual instance does not exist yet, add a new one. 408 $course = $DB->get_record('course', array('id'=>$e->courseid), '*', MUST_EXIST); 409 if ($minstance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'manual'))) { 410 // Already created by previous iteration. 411 $e->mid = $minstance->id; 412 } else if ($e->mid = $manualplugin->add_default_instance($course)) { 413 $minstance = $DB->get_record('enrol', array('id'=>$e->mid)); 414 if ($e->status != ENROL_INSTANCE_ENABLED) { 415 $DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$e->mid)); 416 $minstance->status = ENROL_INSTANCE_DISABLED; 417 } 418 } 419 } else { 420 $minstance = $DB->get_record('enrol', array('id'=>$e->mid)); 421 } 422 423 if (!$minstance) { 424 // This should never happen unless adding of default instance fails unexpectedly. 425 debugging('Failed to find manual enrolment instance', DEBUG_DEVELOPER); 426 continue; 427 } 428 429 // First delete potential role duplicates. 430 $params = array('id'=>$e->id, 'component'=>'enrol_'.$enrol, 'empty'=>''); 431 $sql = "SELECT ra.id 432 FROM {role_assignments} ra 433 JOIN {role_assignments} mra ON (mra.contextid = ra.contextid AND mra.userid = ra.userid AND mra.roleid = ra.roleid AND mra.component = :empty AND mra.itemid = 0) 434 WHERE ra.component = :component AND ra.itemid = :id"; 435 $ras = $DB->get_records_sql($sql, $params); 436 $ras = array_keys($ras); 437 $DB->delete_records_list('role_assignments', 'id', $ras); 438 unset($ras); 439 440 // Migrate roles. 441 $sql = "UPDATE {role_assignments} 442 SET itemid = 0, component = :empty 443 WHERE itemid = :id AND component = :component"; 444 $params = array('empty'=>'', 'id'=>$e->id, 'component'=>'enrol_'.$enrol); 445 $DB->execute($sql, $params); 446 447 // Delete potential enrol duplicates. 448 $params = array('id'=>$e->id, 'mid'=>$e->mid); 449 $sql = "SELECT ue.id 450 FROM {user_enrolments} ue 451 JOIN {user_enrolments} mue ON (mue.userid = ue.userid AND mue.enrolid = :mid) 452 WHERE ue.enrolid = :id"; 453 $ues = $DB->get_records_sql($sql, $params); 454 $ues = array_keys($ues); 455 $DB->delete_records_list('user_enrolments', 'id', $ues); 456 unset($ues); 457 458 // Migrate to manual enrol instance. 459 $params = array('id'=>$e->id, 'mid'=>$e->mid); 460 if ($e->status != ENROL_INSTANCE_ENABLED and $minstance->status == ENROL_INSTANCE_ENABLED) { 461 $status = ", status = :disabled"; 462 $params['disabled'] = ENROL_USER_SUSPENDED; 463 } else { 464 $status = ""; 465 } 466 $sql = "UPDATE {user_enrolments} 467 SET enrolid = :mid $status 468 WHERE enrolid = :id"; 469 $DB->execute($sql, $params); 470 } 471 $rs->close(); 472 } 473 474 /** 475 * Gets an array of the cohorts that can be enrolled in this course. 476 * 477 * @param int $enrolid 478 * @param string $search 479 * @param int $page Defaults to 0 480 * @param int $perpage Defaults to 25 481 * @param int $addedenrollment 482 * @return array Array(totalcohorts => int, cohorts => array) 483 */ 484 function enrol_manual_get_potential_cohorts($context, $enrolid, $search = '', $page = 0, $perpage = 25, $addedenrollment = 0) { 485 global $CFG; 486 require_once($CFG->dirroot . '/cohort/lib.php'); 487 488 $allcohorts = cohort_get_available_cohorts($context, COHORT_WITH_NOTENROLLED_MEMBERS_ONLY, 0, 0, $search); 489 $totalcohorts = count($allcohorts); 490 $cohorts = array(); 491 $cnt = 0; 492 foreach ($allcohorts as $c) { 493 if ($cnt >= $page * $perpage && (!$perpage || $cnt < ($page+1)*$perpage)) { 494 $cohorts[] = (object)array( 495 'id' => $c->id, 496 'name' => format_string($c->name, true, array('context' => $c->contextid)), 497 'cnt' => $c->memberscnt - $c->enrolledcnt 498 ); 499 } 500 $cnt++; 501 } 502 return array('totalcohorts' => $totalcohorts, 'cohorts' => $cohorts); 503 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body