Commit | Line | Data |
---|---|---|
f3f7610c ML |
1 | <?php |
2 | /** | |
ddff2fa8 | 3 | * Extra library for groups and groupings. |
f3f7610c ML |
4 | * |
5 | * @copyright © 2006 The Open University | |
2942a5cd | 6 | * @author J.White AT open.ac.uk, Petr Skoda (skodak) |
f3f7610c ML |
7 | * @license http://www.gnu.org/copyleft/gpl.html GNU Public License |
8 | * @package groups | |
9 | */ | |
10 | ||
ddff2fa8 | 11 | /* |
12 | * INTERNAL FUNCTIONS - to be used by moodle core only | |
13 | * require_once $CFG->dirroot.'/group/lib.php' must be used | |
14 | */ | |
15 | ||
778918fd | 16 | /** |
17 | * Adds a specified user to a group | |
9a0df45a | 18 | * @param mixed $groupid The group id or group object |
19 | * @param mixed $userid The user id or user object | |
f16fa0a3 | 20 | * @return boolean True if user added successfully or the user is already a |
21 | * member of the group, false otherwise. | |
778918fd | 22 | */ |
9a0df45a | 23 | function groups_add_member($grouporid, $userorid) { |
dfdaabd6 | 24 | global $DB; |
25 | ||
9a0df45a | 26 | if (is_object($userorid)) { |
27 | $userid = $userorid->id; | |
28 | $user = $userorid; | |
29 | } else { | |
30 | $userid = $userorid; | |
b18e25d5 | 31 | $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST); |
2061e59c | 32 | } |
33 | ||
9a0df45a | 34 | if (is_object($grouporid)) { |
35 | $groupid = $grouporid->id; | |
36 | $group = $grouporid; | |
37 | } else { | |
38 | $groupid = $grouporid; | |
39 | $group = $DB->get_record('groups', array('id'=>$groupid), '*', MUST_EXIST); | |
778918fd | 40 | } |
41 | ||
0d4723ee | 42 | //check if the user a participant of the group course |
4f0c2d00 | 43 | if (!is_enrolled(get_context_instance(CONTEXT_COURSE, $group->courseid), $userid)) { |
9a0df45a | 44 | return false; |
0d4723ee | 45 | } |
46 | ||
778918fd | 47 | if (groups_is_member($groupid, $userid)) { |
48 | return true; | |
49 | } | |
50 | ||
ace9051c | 51 | $member = new stdClass(); |
778918fd | 52 | $member->groupid = $groupid; |
53 | $member->userid = $userid; | |
54 | $member->timeadded = time(); | |
55 | ||
b25263ff | 56 | $DB->insert_record('groups_members', $member); |
778918fd | 57 | |
58 | //update group info | |
dfdaabd6 | 59 | $DB->set_field('groups', 'timemodified', $member->timeadded, array('id'=>$groupid)); |
778918fd | 60 | |
2942a5cd | 61 | //trigger groups events |
ace9051c | 62 | $eventdata = new stdClass(); |
778918fd | 63 | $eventdata->groupid = $groupid; |
2942a5cd | 64 | $eventdata->userid = $userid; |
65 | events_trigger('groups_member_added', $eventdata); | |
778918fd | 66 | |
67 | return true; | |
68 | } | |
69 | ||
70 | /** | |
71 | * Deletes the link between the specified user and group. | |
9a0df45a | 72 | * @param mixed $groupid The group id or group object |
73 | * @param mixed $userid The user id or user object | |
778918fd | 74 | * @return boolean True if deletion was successful, false otherwise |
75 | */ | |
9a0df45a | 76 | function groups_remove_member($grouporid, $userorid) { |
dfdaabd6 | 77 | global $DB; |
78 | ||
9a0df45a | 79 | if (is_object($userorid)) { |
80 | $userid = $userorid->id; | |
81 | $user = $userorid; | |
82 | } else { | |
83 | $userid = $userorid; | |
b18e25d5 | 84 | $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST); |
2061e59c | 85 | } |
86 | ||
9a0df45a | 87 | if (is_object($grouporid)) { |
88 | $groupid = $grouporid->id; | |
89 | $group = $grouporid; | |
90 | } else { | |
91 | $groupid = $grouporid; | |
92 | $group = $DB->get_record('groups', array('id'=>$groupid), '*', MUST_EXIST); | |
778918fd | 93 | } |
94 | ||
95 | if (!groups_is_member($groupid, $userid)) { | |
96 | return true; | |
97 | } | |
98 | ||
b25263ff | 99 | $DB->delete_records('groups_members', array('groupid'=>$groupid, 'userid'=>$userid)); |
100 | ||
778918fd | 101 | //update group info |
dfdaabd6 | 102 | $DB->set_field('groups', 'timemodified', time(), array('id'=>$groupid)); |
778918fd | 103 | |
2942a5cd | 104 | //trigger groups events |
ace9051c | 105 | $eventdata = new stdClass(); |
2942a5cd | 106 | $eventdata->groupid = $groupid; |
107 | $eventdata->userid = $userid; | |
108 | events_trigger('groups_member_removed', $eventdata); | |
109 | ||
778918fd | 110 | return true; |
111 | } | |
112 | ||
ddff2fa8 | 113 | /** |
114 | * Add a new group | |
e88dd876 | 115 | * @param object $data group properties |
ddff2fa8 | 116 | * @param object $um upload manager with group picture |
117 | * @return id of group or false if error | |
118 | */ | |
e88dd876 | 119 | function groups_create_group($data, $editform = false, $editoroptions = false) { |
dfdaabd6 | 120 | global $CFG, $DB; |
6f5e0852 | 121 | |
2061e59c | 122 | //check that courseid exists |
9a0df45a | 123 | $course = $DB->get_record('course', array('id' => $data->courseid), '*', MUST_EXIST); |
e88dd876 | 124 | $context = get_context_instance(CONTEXT_COURSE, $course->id); |
ddff2fa8 | 125 | |
dfdaabd6 | 126 | $data->timecreated = time(); |
ddff2fa8 | 127 | $data->timemodified = $data->timecreated; |
dfdaabd6 | 128 | $data->name = trim($data->name); |
8bdc9cac | 129 | |
e88dd876 | 130 | if ($editform and $editoroptions) { |
8bdc9cac SH |
131 | $data->description = $data->description_editor['text']; |
132 | $data->descriptionformat = $data->description_editor['format']; | |
133 | } | |
134 | ||
e88dd876 PS |
135 | $data->id = $DB->insert_record('groups', $data); |
136 | ||
137 | if ($editform and $editoroptions) { | |
138 | // Update description from editor with fixed files | |
139 | $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $context, 'group', 'description', $data->id); | |
ace9051c | 140 | $upd = new stdClass(); |
e88dd876 PS |
141 | $upd->id = $data->id; |
142 | $upd->description = $data->description; | |
143 | $upd->descriptionformat = $data->descriptionformat; | |
144 | $DB->update_record('groups', $upd); | |
145 | } | |
146 | ||
147 | $group = $DB->get_record('groups', array('id'=>$data->id)); | |
ddff2fa8 | 148 | |
b25263ff | 149 | if ($editform) { |
e88dd876 | 150 | groups_update_group_icon($group, $data, $editform); |
ddff2fa8 | 151 | } |
152 | ||
b25263ff | 153 | //trigger groups events |
e88dd876 | 154 | events_trigger('groups_group_created', $group); |
b25263ff | 155 | |
e88dd876 | 156 | return $group->id; |
ddff2fa8 | 157 | } |
158 | ||
159 | /** | |
f16fa0a3 | 160 | * Add a new grouping |
e88dd876 | 161 | * @param object $data grouping properties |
f16fa0a3 | 162 | * @return id of grouping or false if error |
163 | */ | |
8bdc9cac | 164 | function groups_create_grouping($data, $editoroptions=null) { |
dfdaabd6 | 165 | global $DB; |
f16fa0a3 | 166 | |
dfdaabd6 | 167 | $data->timecreated = time(); |
f16fa0a3 | 168 | $data->timemodified = $data->timecreated; |
dfdaabd6 | 169 | $data->name = trim($data->name); |
8bdc9cac SH |
170 | |
171 | if ($editoroptions !== null) { | |
172 | $data->description = $data->description_editor['text']; | |
173 | $data->descriptionformat = $data->description_editor['format']; | |
174 | } | |
175 | ||
2942a5cd | 176 | $id = $DB->insert_record('groupings', $data); |
177 | ||
b25263ff | 178 | //trigger groups events |
179 | $data->id = $id; | |
8bdc9cac SH |
180 | |
181 | if ($editoroptions !== null) { | |
182 | $description = new stdClass; | |
183 | $description->id = $data->id; | |
184 | $description->description_editor = $data->description_editor; | |
64f93798 | 185 | $description = file_postupdate_standard_editor($description, 'description', $editoroptions, $editoroptions['context'], 'grouping', 'description', $description->id); |
8bdc9cac SH |
186 | $DB->update_record('groupings', $description); |
187 | } | |
188 | ||
b25263ff | 189 | events_trigger('groups_grouping_created', $data); |
2942a5cd | 190 | |
191 | return $id; | |
f16fa0a3 | 192 | } |
193 | ||
e88dd876 PS |
194 | /** |
195 | * Update the group icon from form data | |
196 | * @param $group | |
197 | * @param $data | |
198 | * @param $editform | |
199 | */ | |
200 | function groups_update_group_icon($group, $data, $editform) { | |
201 | global $CFG, $DB; | |
202 | require_once("$CFG->libdir/gdlib.php"); | |
203 | ||
204 | $fs = get_file_storage(); | |
205 | $context = get_context_instance(CONTEXT_COURSE, $group->courseid, MUST_EXIST); | |
206 | ||
207 | //TODO: it would make sense to allow picture deleting too (skodak) | |
208 | ||
209 | if ($iconfile = $editform->save_temp_file('imagefile')) { | |
210 | if (process_new_icon($context, 'group', 'icon', $group->id, $iconfile)) { | |
211 | $DB->set_field('groups', 'picture', 1, array('id'=>$group->id)); | |
212 | $group->picture = 1; | |
213 | } else { | |
214 | $fs->delete_area_files($context->id, 'group', 'icon', $group->id); | |
215 | $DB->set_field('groups', 'picture', 0, array('id'=>$group->id)); | |
216 | $group->picture = 0; | |
217 | } | |
218 | @unlink($iconfile); | |
219 | } | |
220 | } | |
221 | ||
f16fa0a3 | 222 | /** |
223 | * Update group | |
224 | * @param object $data group properties (with magic quotes) | |
e88dd876 PS |
225 | * @param object $editform |
226 | * @param array $editoroptions | |
b25263ff | 227 | * @return boolean true or exception |
ddff2fa8 | 228 | */ |
e88dd876 | 229 | function groups_update_group($data, $editform = false, $editoroptions = false) { |
dfdaabd6 | 230 | global $CFG, $DB; |
e88dd876 PS |
231 | |
232 | $context = get_context_instance(CONTEXT_COURSE, $data->courseid); | |
ddff2fa8 | 233 | |
234 | $data->timemodified = time(); | |
dfdaabd6 | 235 | $data->name = trim($data->name); |
8bdc9cac | 236 | |
e88dd876 PS |
237 | if ($editform and $editoroptions) { |
238 | $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $context, 'group', 'description', $data->id); | |
8bdc9cac SH |
239 | } |
240 | ||
b25263ff | 241 | $DB->update_record('groups', $data); |
2942a5cd | 242 | |
e88dd876 PS |
243 | $group = $DB->get_record('groups', array('id'=>$data->id)); |
244 | ||
b25263ff | 245 | if ($editform) { |
e88dd876 | 246 | groups_update_group_icon($group, $data, $editform); |
ddff2fa8 | 247 | } |
248 | ||
b25263ff | 249 | //trigger groups events |
e88dd876 PS |
250 | events_trigger('groups_group_updated', $group); |
251 | ||
b25263ff | 252 | |
253 | return true; | |
ddff2fa8 | 254 | } |
255 | ||
f16fa0a3 | 256 | /** |
257 | * Update grouping | |
258 | * @param object $data grouping properties (with magic quotes) | |
b25263ff | 259 | * @return boolean true or exception |
f16fa0a3 | 260 | */ |
8bdc9cac | 261 | function groups_update_grouping($data, $editoroptions=null) { |
dfdaabd6 | 262 | global $DB; |
f16fa0a3 | 263 | $data->timemodified = time(); |
dfdaabd6 | 264 | $data->name = trim($data->name); |
8bdc9cac | 265 | if ($editoroptions !== null) { |
64f93798 | 266 | $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $editoroptions['context'], 'grouping', 'description', $data->id); |
8bdc9cac | 267 | } |
b25263ff | 268 | $DB->update_record('groupings', $data); |
269 | //trigger groups events | |
270 | events_trigger('groups_grouping_updated', $data); | |
271 | ||
272 | return true; | |
f16fa0a3 | 273 | } |
274 | ||
ddff2fa8 | 275 | /** |
276 | * Delete a group best effort, first removing members and links with courses and groupings. | |
277 | * Removes group avatar too. | |
2942a5cd | 278 | * @param mixed $grouporid The id of group to delete or full group object |
ddff2fa8 | 279 | * @return boolean True if deletion was successful, false otherwise |
280 | */ | |
2942a5cd | 281 | function groups_delete_group($grouporid) { |
b7e8cfb6 | 282 | global $CFG, $DB; |
283 | require_once("$CFG->libdir/gdlib.php"); | |
ddff2fa8 | 284 | |
2942a5cd | 285 | if (is_object($grouporid)) { |
286 | $groupid = $grouporid->id; | |
287 | $group = $grouporid; | |
288 | } else { | |
289 | $groupid = $grouporid; | |
290 | if (!$group = $DB->get_record('groups', array('id'=>$groupid))) { | |
9a0df45a | 291 | //silently ignore attempts to delete missing already deleted groups ;-) |
292 | return true; | |
2942a5cd | 293 | } |
ddff2fa8 | 294 | } |
295 | ||
0b5a80a1 | 296 | // delete group calendar events |
dfdaabd6 | 297 | $DB->delete_records('event', array('groupid'=>$groupid)); |
ddff2fa8 | 298 | //first delete usage in groupings_groups |
dfdaabd6 | 299 | $DB->delete_records('groupings_groups', array('groupid'=>$groupid)); |
ddff2fa8 | 300 | //delete members |
dfdaabd6 | 301 | $DB->delete_records('groups_members', array('groupid'=>$groupid)); |
ddff2fa8 | 302 | //group itself last |
b25263ff | 303 | $DB->delete_records('groups', array('id'=>$groupid)); |
8bdc9cac SH |
304 | |
305 | // Delete all files associated with this group | |
70e0f41e | 306 | $context = get_context_instance(CONTEXT_COURSE, $group->courseid); |
8bdc9cac | 307 | $fs = get_file_storage(); |
e88dd876 PS |
308 | $fs->delete_area_files($context->id, 'group', 'description', $groupid); |
309 | $fs->delete_area_files($context->id, 'group', 'icon', $groupid); | |
8bdc9cac | 310 | |
b25263ff | 311 | //trigger groups events |
312 | events_trigger('groups_group_deleted', $group); | |
2942a5cd | 313 | |
b25263ff | 314 | return true; |
ddff2fa8 | 315 | } |
316 | ||
f16fa0a3 | 317 | /** |
318 | * Delete grouping | |
319 | * @param int $groupingid | |
320 | * @return bool success | |
321 | */ | |
2942a5cd | 322 | function groups_delete_grouping($groupingorid) { |
dfdaabd6 | 323 | global $DB; |
324 | ||
2942a5cd | 325 | if (is_object($groupingorid)) { |
326 | $groupingid = $groupingorid->id; | |
327 | $grouping = $groupingorid; | |
328 | } else { | |
329 | $groupingid = $groupingorid; | |
330 | if (!$grouping = $DB->get_record('groupings', array('id'=>$groupingorid))) { | |
9a0df45a | 331 | //silently ignore attempts to delete missing already deleted groupings ;-) |
332 | return true; | |
2942a5cd | 333 | } |
ddff2fa8 | 334 | } |
335 | ||
336 | //first delete usage in groupings_groups | |
dfdaabd6 | 337 | $DB->delete_records('groupings_groups', array('groupingid'=>$groupingid)); |
ddff2fa8 | 338 | // remove the default groupingid from course |
dfdaabd6 | 339 | $DB->set_field('course', 'defaultgroupingid', 0, array('defaultgroupingid'=>$groupingid)); |
ddff2fa8 | 340 | // remove the groupingid from all course modules |
dfdaabd6 | 341 | $DB->set_field('course_modules', 'groupingid', 0, array('groupingid'=>$groupingid)); |
ddff2fa8 | 342 | //group itself last |
b25263ff | 343 | $DB->delete_records('groupings', array('id'=>$groupingid)); |
8bdc9cac | 344 | |
70e0f41e | 345 | $context = get_context_instance(CONTEXT_COURSE, $grouping->courseid); |
8bdc9cac | 346 | $fs = get_file_storage(); |
64f93798 | 347 | $files = $fs->get_area_files($context->id, 'grouping', 'description', $groupingid); |
8bdc9cac SH |
348 | foreach ($files as $file) { |
349 | $file->delete(); | |
350 | } | |
351 | ||
b25263ff | 352 | //trigger groups events |
353 | events_trigger('groups_grouping_deleted', $grouping); | |
2942a5cd | 354 | |
b25263ff | 355 | return true; |
ddff2fa8 | 356 | } |
357 | ||
f16fa0a3 | 358 | /** |
ffc670d9 | 359 | * Remove all users (or one user) from all groups in course |
f16fa0a3 | 360 | * @param int $courseid |
ffc670d9 | 361 | * @param int $userid 0 means all users |
f16fa0a3 | 362 | * @param bool $showfeedback |
363 | * @return bool success | |
364 | */ | |
ffc670d9 | 365 | function groups_delete_group_members($courseid, $userid=0, $showfeedback=false) { |
a1c54f7a | 366 | global $DB, $OUTPUT; |
ddff2fa8 | 367 | |
ffc670d9 | 368 | if (is_bool($userid)) { |
369 | debugging('Incorrect userid function parameter'); | |
370 | return false; | |
371 | } | |
372 | ||
373 | $params = array('courseid'=>$courseid); | |
374 | ||
375 | if ($userid) { | |
376 | $usersql = "AND userid = :userid"; | |
377 | $params['userid'] = $userid; | |
378 | } else { | |
379 | $usersql = ""; | |
380 | } | |
381 | ||
382 | $groupssql = "SELECT id FROM {groups} g WHERE g.courseid = :courseid"; | |
383 | $DB->delete_records_select('groups_members', "groupid IN ($groupssql) $usersql", $params); | |
ddff2fa8 | 384 | |
2942a5cd | 385 | //trigger groups events |
ace9051c | 386 | $eventdata = new stdClass(); |
ffc670d9 | 387 | $eventdata->courseid = $courseid; |
388 | $eventdata->userid = $userid; | |
389 | events_trigger('groups_members_removed', $eventdata); | |
2942a5cd | 390 | |
ddff2fa8 | 391 | if ($showfeedback) { |
a1c54f7a | 392 | echo $OUTPUT->notification(get_string('deleted').' groups_members'); |
ddff2fa8 | 393 | } |
394 | ||
395 | return true; | |
396 | } | |
397 | ||
0b5a80a1 | 398 | /** |
399 | * Remove all groups from all groupings in course | |
400 | * @param int $courseid | |
401 | * @param bool $showfeedback | |
402 | * @return bool success | |
403 | */ | |
404 | function groups_delete_groupings_groups($courseid, $showfeedback=false) { | |
a1c54f7a | 405 | global $DB, $OUTPUT; |
0b5a80a1 | 406 | |
dfdaabd6 | 407 | $groupssql = "SELECT id FROM {groups} g WHERE g.courseid = ?"; |
408 | $DB->delete_records_select('groupings_groups', "groupid IN ($groupssql)", array($courseid)); | |
0b5a80a1 | 409 | |
8bdc9cac | 410 | // Delete all files associated with groupings for this course |
70e0f41e | 411 | $context = get_context_instance(CONTEXT_COURSE, $courseid); |
8bdc9cac | 412 | |
2942a5cd | 413 | //trigger groups events |
414 | events_trigger('groups_groupings_groups_removed', $courseid); | |
415 | ||
0b5a80a1 | 416 | if ($showfeedback) { |
a1c54f7a | 417 | echo $OUTPUT->notification(get_string('deleted').' groupings_groups'); |
0b5a80a1 | 418 | } |
419 | ||
420 | return true; | |
421 | } | |
422 | ||
f16fa0a3 | 423 | /** |
424 | * Delete all groups from course | |
425 | * @param int $courseid | |
426 | * @param bool $showfeedback | |
427 | * @return bool success | |
428 | */ | |
ddff2fa8 | 429 | function groups_delete_groups($courseid, $showfeedback=false) { |
a1c54f7a | 430 | global $CFG, $DB, $OUTPUT; |
ddff2fa8 | 431 | |
0b5a80a1 | 432 | // delete any uses of groups |
8bdc9cac | 433 | // Any associated files are deleted as part of groups_delete_groupings_groups |
0b5a80a1 | 434 | groups_delete_groupings_groups($courseid, $showfeedback); |
ffc670d9 | 435 | groups_delete_group_members($courseid, 0, $showfeedback); |
ddff2fa8 | 436 | |
d08787af PS |
437 | // delete group pictures and descriptions |
438 | $context = get_context_instance(CONTEXT_COURSE, $courseid); | |
439 | $fs = get_file_storage(); | |
440 | $fs->delete_area_files($context->id, 'group'); | |
ddff2fa8 | 441 | |
0b5a80a1 | 442 | // delete group calendar events |
dfdaabd6 | 443 | $groupssql = "SELECT id FROM {groups} g WHERE g.courseid = ?"; |
444 | $DB->delete_records_select('event', "groupid IN ($groupssql)", array($courseid)); | |
0b5a80a1 | 445 | |
64f93798 PS |
446 | $context = get_context_instance(CONTEXT_COURSE, $courseid); |
447 | $fs = get_file_storage(); | |
448 | $fs->delete_area_files($context->id, 'group'); | |
449 | ||
dfdaabd6 | 450 | $DB->delete_records('groups', array('courseid'=>$courseid)); |
2942a5cd | 451 | |
452 | //trigger groups events | |
453 | events_trigger('groups_groups_deleted', $courseid); | |
454 | ||
ddff2fa8 | 455 | if ($showfeedback) { |
a1c54f7a | 456 | echo $OUTPUT->notification(get_string('deleted').' groups'); |
ddff2fa8 | 457 | } |
458 | ||
459 | return true; | |
460 | } | |
461 | ||
f16fa0a3 | 462 | /** |
463 | * Delete all groupings from course | |
464 | * @param int $courseid | |
465 | * @param bool $showfeedback | |
466 | * @return bool success | |
467 | */ | |
ddff2fa8 | 468 | function groups_delete_groupings($courseid, $showfeedback=false) { |
a1c54f7a | 469 | global $DB, $OUTPUT; |
ddff2fa8 | 470 | |
d08787af PS |
471 | $context = get_context_instance(CONTEXT_COURSE, $courseid); |
472 | $fs = get_file_storage(); | |
473 | ||
ddff2fa8 | 474 | // delete any uses of groupings |
dfdaabd6 | 475 | $sql = "DELETE FROM {groupings_groups} |
476 | WHERE groupingid in (SELECT id FROM {groupings} g WHERE g.courseid = ?)"; | |
477 | $DB->execute($sql, array($courseid)); | |
ddff2fa8 | 478 | |
479 | // remove the default groupingid from course | |
dfdaabd6 | 480 | $DB->set_field('course', 'defaultgroupingid', 0, array('id'=>$courseid)); |
ddff2fa8 | 481 | // remove the groupingid from all course modules |
dfdaabd6 | 482 | $DB->set_field('course_modules', 'groupingid', 0, array('course'=>$courseid)); |
ddff2fa8 | 483 | |
8bdc9cac | 484 | // Delete all files associated with groupings for this course |
70e0f41e | 485 | $context = get_context_instance(CONTEXT_COURSE, $courseid); |
8bdc9cac | 486 | $fs = get_file_storage(); |
64f93798 PS |
487 | $fs->delete_area_files($context->id, 'grouping'); |
488 | ||
489 | $DB->delete_records('groupings', array('courseid'=>$courseid)); | |
8bdc9cac | 490 | |
2942a5cd | 491 | //trigger groups events |
492 | events_trigger('groups_groupings_deleted', $courseid); | |
493 | ||
ddff2fa8 | 494 | if ($showfeedback) { |
a1c54f7a | 495 | echo $OUTPUT->notification(get_string('deleted').' groupings'); |
ddff2fa8 | 496 | } |
497 | ||
498 | return true; | |
499 | } | |
500 | ||
501 | /* =================================== */ | |
502 | /* various functions used by groups UI */ | |
503 | /* =================================== */ | |
504 | ||
e254aa34 | 505 | /** |
506 | * Obtains a list of the possible roles that group members might come from, | |
df997f84 | 507 | * on a course. Generally this includes only profile roles. |
e254aa34 | 508 | * @param object $context Context of course |
509 | * @return Array of role ID integers, or false if error/none. | |
510 | */ | |
511 | function groups_get_possible_roles($context) { | |
df997f84 PS |
512 | $roles = get_profile_roles($context); |
513 | return array_keys($roles); | |
acf000b0 | 514 | } |
515 | ||
516 | ||
517 | /** | |
518 | * Gets potential group members for grouping | |
519 | * @param int $courseid The id of the course | |
520 | * @param int $roleid The role to select users from | |
92343cd2 | 521 | * @param int $cohortid restrict to cohort id |
64fa9aa7 | 522 | * @param string $orderby The column to sort users by |
acf000b0 | 523 | * @return array An array of the users |
524 | */ | |
92343cd2 | 525 | function groups_get_potential_members($courseid, $roleid = null, $cohortid = null, $orderby = 'lastname ASC, firstname ASC') { |
4454447d | 526 | global $DB; |
f16fa0a3 | 527 | |
acf000b0 | 528 | $context = get_context_instance(CONTEXT_COURSE, $courseid); |
acf000b0 | 529 | |
530 | // we are looking for all users with this role assigned in this context or higher | |
4f0c2d00 | 531 | $listofcontexts = get_related_contexts_string($context); |
f16fa0a3 | 532 | |
4f0c2d00 | 533 | list($esql, $params) = get_enrolled_sql($context); |
64f93798 | 534 | |
acf000b0 | 535 | if ($roleid) { |
dfdaabd6 | 536 | $params['roleid'] = $roleid; |
4f0c2d00 PS |
537 | $where = "WHERE u.id IN (SELECT userid |
538 | FROM {role_assignments} | |
539 | WHERE roleid = :roleid AND contextid $listofcontexts)"; | |
acf000b0 | 540 | } else { |
4f0c2d00 | 541 | $where = ""; |
acf000b0 | 542 | } |
f16fa0a3 | 543 | |
92343cd2 | 544 | if ($cohortid) { |
d490ca81 PS |
545 | $cohortjoin = "JOIN {cohort_members} cm ON (cm.userid = u.id AND cm.cohortid = :cohortid)"; |
546 | $params['cohortid'] = $cohortid; | |
92343cd2 PS |
547 | } else { |
548 | $cohortjoin = ""; | |
549 | } | |
550 | ||
dfdaabd6 | 551 | $sql = "SELECT u.id, u.username, u.firstname, u.lastname, u.idnumber |
552 | FROM {user} u | |
4f0c2d00 | 553 | JOIN ($esql) e ON e.id = u.id |
92343cd2 | 554 | $cohortjoin |
4f0c2d00 | 555 | $where |
dfdaabd6 | 556 | ORDER BY $orderby"; |
f16fa0a3 | 557 | |
dfdaabd6 | 558 | return $DB->get_records_sql($sql, $params); |
f16fa0a3 | 559 | |
acf000b0 | 560 | } |
f3f7610c | 561 | |
acf000b0 | 562 | /** |
563 | * Parse a group name for characters to replace | |
564 | * @param string $format The format a group name will follow | |
565 | * @param int $groupnumber The number of the group to be used in the parsed format string | |
566 | * @return string the parsed format string | |
567 | */ | |
568 | function groups_parse_name($format, $groupnumber) { | |
acf000b0 | 569 | if (strstr($format, '@') !== false) { // Convert $groupnumber to a character series |
f16fa0a3 | 570 | $letter = 'A'; |
571 | for($i=0; $i<$groupnumber; $i++) { | |
572 | $letter++; | |
acf000b0 | 573 | } |
f16fa0a3 | 574 | $str = str_replace('@', $letter, $format); |
acf000b0 | 575 | } else { |
4454447d | 576 | $str = str_replace('#', $groupnumber+1, $format); |
acf000b0 | 577 | } |
578 | return($str); | |
ddff2fa8 | 579 | } |
f3f7610c | 580 | |
f16fa0a3 | 581 | /** |
582 | * Assigns group into grouping | |
583 | * @param int groupingid | |
584 | * @param int groupid | |
b25263ff | 585 | * @return bool true or exception |
f16fa0a3 | 586 | */ |
587 | function groups_assign_grouping($groupingid, $groupid) { | |
dfdaabd6 | 588 | global $DB; |
589 | ||
590 | if ($DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) { | |
f16fa0a3 | 591 | return true; |
592 | } | |
ace9051c | 593 | $assign = new stdClass(); |
f16fa0a3 | 594 | $assign->groupingid = $groupingid; |
dfdaabd6 | 595 | $assign->groupid = $groupid; |
596 | $assign->timeadded = time(); | |
b25263ff | 597 | $DB->insert_record('groupings_groups', $assign); |
598 | ||
599 | return true; | |
f16fa0a3 | 600 | } |
601 | ||
602 | /** | |
603 | * Unassigns group grom grouping | |
604 | * @param int groupingid | |
605 | * @param int groupid | |
606 | * @return bool success | |
607 | */ | |
608 | function groups_unassign_grouping($groupingid, $groupid) { | |
dfdaabd6 | 609 | global $DB; |
b25263ff | 610 | $DB->delete_records('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid)); |
dfdaabd6 | 611 | |
b25263ff | 612 | return true; |
f16fa0a3 | 613 | } |
614 | ||
e254aa34 | 615 | /** |
616 | * Lists users in a group based on their role on the course. | |
6f5e0852 | 617 | * Returns false if there's an error or there are no users in the group. |
e254aa34 | 618 | * Otherwise returns an array of role ID => role data, where role data includes: |
619 | * (role) $id, $shortname, $name | |
620 | * $users: array of objects for each user which include the specified fields | |
621 | * Users who do not have a role are stored in the returned array with key '-' | |
622 | * and pseudo-role details (including a name, 'No role'). Users with multiple | |
623 | * roles, same deal with key '*' and name 'Multiple roles'. You can find out | |
624 | * which roles each has by looking in the $roles array of the user object. | |
625 | * @param int $groupid | |
626 | * @param int $courseid Course ID (should match the group's course) | |
627 | * @param string $fields List of fields from user table prefixed with u, default 'u.*' | |
628 | * @param string $sort SQL ORDER BY clause, default 'u.lastname ASC' | |
97873016 | 629 | * @param string $extrawheretest extra SQL conditions ANDed with the existing where clause. |
4f0c2d00 | 630 | * @param array $whereparams any parameters required by $extrawheretest (named parameters). |
e254aa34 | 631 | * @return array Complex array as described above |
632 | */ | |
97873016 | 633 | function groups_get_members_by_role($groupid, $courseid, $fields='u.*', |
634 | $sort='u.lastname ASC', $extrawheretest='', $whereparams=array()) { | |
dfdaabd6 | 635 | global $CFG, $DB; |
e254aa34 | 636 | |
637 | // Retrieve information about all users and their roles on the course or | |
6f5e0852 | 638 | // parent ('related') contexts |
dfdaabd6 | 639 | $context = get_context_instance(CONTEXT_COURSE, $courseid); |
640 | ||
97873016 | 641 | if ($extrawheretest) { |
642 | $extrawheretest = ' AND ' . $extrawheretest; | |
643 | } | |
644 | ||
dfdaabd6 | 645 | $sql = "SELECT r.id AS roleid, r.shortname AS roleshortname, r.name AS rolename, |
646 | u.id AS userid, $fields | |
647 | FROM {groups_members} gm | |
648 | JOIN {user} u ON u.id = gm.userid | |
6f5e0852 | 649 | JOIN {role_assignments} ra ON ra.userid = u.id |
dfdaabd6 | 650 | JOIN {role} r ON r.id = ra.roleid |
4f0c2d00 | 651 | WHERE gm.groupid=:mgroupid |
97873016 | 652 | AND ra.contextid ".get_related_contexts_string($context). |
653 | $extrawheretest." | |
dfdaabd6 | 654 | ORDER BY r.sortorder, $sort"; |
4f0c2d00 | 655 | $whereparams['mgroupid'] = $groupid; |
97873016 | 656 | $rs = $DB->get_recordset_sql($sql, $whereparams); |
dfdaabd6 | 657 | |
658 | return groups_calculate_role_people($rs, $context); | |
e254aa34 | 659 | } |
660 | ||
661 | /** | |
662 | * Internal function used by groups_get_members_by_role to handle the | |
663 | * results of a database query that includes a list of users and possible | |
664 | * roles on a course. | |
665 | * | |
666 | * @param object $rs The record set (may be false) | |
3540f2b3 | 667 | * @param int $contextid ID of course context |
6f5e0852 | 668 | * @return array As described in groups_get_members_by_role |
e254aa34 | 669 | */ |
dfdaabd6 | 670 | function groups_calculate_role_people($rs, $context) { |
671 | global $CFG, $DB; | |
672 | ||
673 | if (!$rs) { | |
674 | return array(); | |
3540f2b3 | 675 | } |
e254aa34 | 676 | |
dfdaabd6 | 677 | $roles = $DB->get_records_menu('role', null, 'name', 'id, name'); |
678 | $aliasnames = role_fix_names($roles, $context); | |
679 | ||
e254aa34 | 680 | // Array of all involved roles |
dfdaabd6 | 681 | $roles = array(); |
e254aa34 | 682 | // Array of all retrieved users |
dfdaabd6 | 683 | $users = array(); |
e254aa34 | 684 | // Fill arrays |
dfdaabd6 | 685 | foreach ($rs as $rec) { |
e254aa34 | 686 | // Create information about user if this is a new one |
dfdaabd6 | 687 | if (!array_key_exists($rec->userid, $users)) { |
e254aa34 | 688 | // User data includes all the optional fields, but not any of the |
689 | // stuff we added to get the role details | |
690 | $userdata=clone($rec); | |
691 | unset($userdata->roleid); | |
692 | unset($userdata->roleshortname); | |
693 | unset($userdata->rolename); | |
694 | unset($userdata->userid); | |
dfdaabd6 | 695 | $userdata->id = $rec->userid; |
e254aa34 | 696 | |
697 | // Make an array to hold the list of roles for this user | |
dfdaabd6 | 698 | $userdata->roles = array(); |
699 | $users[$rec->userid] = $userdata; | |
e254aa34 | 700 | } |
701 | // If user has a role... | |
dfdaabd6 | 702 | if (!is_null($rec->roleid)) { |
e254aa34 | 703 | // Create information about role if this is a new one |
dfdaabd6 | 704 | if (!array_key_exists($rec->roleid,$roles)) { |
ace9051c | 705 | $roledata = new stdClass(); |
dfdaabd6 | 706 | $roledata->id = $rec->roleid; |
707 | $roledata->shortname = $rec->roleshortname; | |
708 | if (array_key_exists($rec->roleid, $aliasnames)) { | |
709 | $roledata->name = $aliasnames[$rec->roleid]; | |
3540f2b3 | 710 | } else { |
dfdaabd6 | 711 | $roledata->name = $rec->rolename; |
3540f2b3 | 712 | } |
dfdaabd6 | 713 | $roledata->users = array(); |
714 | $roles[$roledata->id] = $roledata; | |
e254aa34 | 715 | } |
716 | // Record that user has role | |
717 | $users[$rec->userid]->roles[] = $roles[$rec->roleid]; | |
718 | } | |
719 | } | |
dfdaabd6 | 720 | $rs->close(); |
e254aa34 | 721 | |
722 | // Return false if there weren't any users | |
dfdaabd6 | 723 | if (count($users)==0) { |
e254aa34 | 724 | return false; |
725 | } | |
726 | ||
727 | // Add pseudo-role for multiple roles | |
ace9051c | 728 | $roledata = new stdClass(); |
dfdaabd6 | 729 | $roledata->name = get_string('multipleroles','role'); |
730 | $roledata->users = array(); | |
731 | $roles['*'] = $roledata; | |
e254aa34 | 732 | |
733 | // Now we rearrange the data to store users by role | |
dfdaabd6 | 734 | foreach ($users as $userid=>$userdata) { |
735 | $rolecount = count($userdata->roles); | |
736 | if ($rolecount==0) { | |
e254aa34 | 737 | debugging("Unexpected: user $userid is missing roles"); |
738 | } else if($rolecount>1) { | |
dfdaabd6 | 739 | $roleid = '*'; |
e254aa34 | 740 | } else { |
dfdaabd6 | 741 | $roleid = $userdata->roles[0]->id; |
e254aa34 | 742 | } |
dfdaabd6 | 743 | $roles[$roleid]->users[$userid] = $userdata; |
e254aa34 | 744 | } |
745 | ||
746 | // Delete roles not used | |
dfdaabd6 | 747 | foreach ($roles as $key=>$roledata) { |
748 | if (count($roledata->users)===0) { | |
e254aa34 | 749 | unset($roles[$key]); |
750 | } | |
751 | } | |
752 | ||
753 | // Return list of roles containing their users | |
754 | return $roles; | |
755 | } |