Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402] [Versions 402 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 use core_external\external_api; 18 use core_external\external_format_value; 19 use core_external\external_function_parameters; 20 use core_external\external_multiple_structure; 21 use core_external\external_single_structure; 22 use core_external\external_value; 23 use core_external\external_warnings; 24 use core_external\util; 25 use core_group\visibility; 26 27 /** 28 * Group external functions 29 * 30 * @package core_group 31 * @category external 32 * @copyright 2011 Jerome Mouneyrac 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 * @since Moodle 2.2 35 */ 36 class core_group_external extends external_api { 37 38 39 /** 40 * Validate visibility. 41 * 42 * @param int $visibility Visibility string, must one of the visibility class constants. 43 * @throws invalid_parameter_exception if visibility is not an allowed value. 44 */ 45 protected static function validate_visibility(int $visibility): void { 46 $allowed = [ 47 GROUPS_VISIBILITY_ALL, 48 GROUPS_VISIBILITY_MEMBERS, 49 GROUPS_VISIBILITY_OWN, 50 GROUPS_VISIBILITY_NONE, 51 ]; 52 if (!array_key_exists($visibility, $allowed)) { 53 throw new invalid_parameter_exception('Invalid group visibility provided. Must be one of ' 54 . join(',', $allowed)); 55 } 56 } 57 58 /** 59 * Returns description of method parameters 60 * 61 * @return external_function_parameters 62 * @since Moodle 2.2 63 */ 64 public static function create_groups_parameters() { 65 return new external_function_parameters( 66 array( 67 'groups' => new external_multiple_structure( 68 new external_single_structure( 69 array( 70 'courseid' => new external_value(PARAM_INT, 'id of course'), 71 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 72 'description' => new external_value(PARAM_RAW, 'group description text'), 73 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT), 74 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase', VALUE_OPTIONAL), 75 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL), 76 'visibility' => new external_value(PARAM_INT, 77 'group visibility mode. 0 = Visible to all. 1 = Visible to members. ' 78 . '2 = See own membership. 3 = Membership is hidden. default: 0', 79 VALUE_DEFAULT, 0), 80 'participation' => new external_value(PARAM_BOOL, 81 'activity participation enabled? Only for "all" and "members" visibility. Default true.', 82 VALUE_DEFAULT, true), 83 ) 84 ), 'List of group object. A group has a courseid, a name, a description and an enrolment key.' 85 ) 86 ) 87 ); 88 } 89 90 /** 91 * Create groups 92 * 93 * @param array $groups array of group description arrays (with keys groupname and courseid) 94 * @return array of newly created groups 95 * @since Moodle 2.2 96 */ 97 public static function create_groups($groups) { 98 global $CFG, $DB; 99 require_once("$CFG->dirroot/group/lib.php"); 100 101 $params = self::validate_parameters(self::create_groups_parameters(), array('groups'=>$groups)); 102 103 $transaction = $DB->start_delegated_transaction(); 104 105 $groups = array(); 106 107 foreach ($params['groups'] as $group) { 108 $group = (object)$group; 109 110 if (trim($group->name) == '') { 111 throw new invalid_parameter_exception('Invalid group name'); 112 } 113 if ($DB->get_record('groups', array('courseid'=>$group->courseid, 'name'=>$group->name))) { 114 throw new invalid_parameter_exception('Group with the same name already exists in the course'); 115 } 116 117 // now security checks 118 $context = context_course::instance($group->courseid, IGNORE_MISSING); 119 try { 120 self::validate_context($context); 121 } catch (Exception $e) { 122 $exceptionparam = new stdClass(); 123 $exceptionparam->message = $e->getMessage(); 124 $exceptionparam->courseid = $group->courseid; 125 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 126 } 127 require_capability('moodle/course:managegroups', $context); 128 129 // Validate format. 130 $group->descriptionformat = util::validate_format($group->descriptionformat); 131 132 // Validate visibility. 133 self::validate_visibility($group->visibility); 134 135 // finally create the group 136 $group->id = groups_create_group($group, false); 137 if (!isset($group->enrolmentkey)) { 138 $group->enrolmentkey = ''; 139 } 140 if (!isset($group->idnumber)) { 141 $group->idnumber = ''; 142 } 143 144 $groups[] = (array)$group; 145 } 146 147 $transaction->allow_commit(); 148 149 return $groups; 150 } 151 152 /** 153 * Returns description of method result value 154 * 155 * @return \core_external\external_description 156 * @since Moodle 2.2 157 */ 158 public static function create_groups_returns() { 159 return new external_multiple_structure( 160 new external_single_structure( 161 array( 162 'id' => new external_value(PARAM_INT, 'group record id'), 163 'courseid' => new external_value(PARAM_INT, 'id of course'), 164 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 165 'description' => new external_value(PARAM_RAW, 'group description text'), 166 'descriptionformat' => new external_format_value('description'), 167 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'), 168 'idnumber' => new external_value(PARAM_RAW, 'id number'), 169 'visibility' => new external_value(PARAM_INT, 170 'group visibility mode. 0 = Visible to all. 1 = Visible to members. 2 = See own membership. ' 171 . '3 = Membership is hidden.'), 172 'participation' => new external_value(PARAM_BOOL, 'participation mode'), 173 ) 174 ), 'List of group object. A group has an id, a courseid, a name, a description and an enrolment key.' 175 ); 176 } 177 178 /** 179 * Returns description of method parameters 180 * 181 * @return external_function_parameters 182 * @since Moodle 2.2 183 */ 184 public static function get_groups_parameters() { 185 return new external_function_parameters( 186 array( 187 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID') 188 ,'List of group id. A group id is an integer.'), 189 ) 190 ); 191 } 192 193 /** 194 * Get groups definition specified by ids 195 * 196 * @param array $groupids arrays of group ids 197 * @return array of group objects (id, courseid, name, enrolmentkey) 198 * @since Moodle 2.2 199 */ 200 public static function get_groups($groupids) { 201 $params = self::validate_parameters(self::get_groups_parameters(), array('groupids'=>$groupids)); 202 203 $groups = array(); 204 foreach ($params['groupids'] as $groupid) { 205 // validate params 206 $group = groups_get_group($groupid, 'id, courseid, name, idnumber, description, descriptionformat, enrolmentkey, ' 207 . 'visibility, participation', MUST_EXIST); 208 209 // now security checks 210 $context = context_course::instance($group->courseid, IGNORE_MISSING); 211 try { 212 self::validate_context($context); 213 } catch (Exception $e) { 214 $exceptionparam = new stdClass(); 215 $exceptionparam->message = $e->getMessage(); 216 $exceptionparam->courseid = $group->courseid; 217 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 218 } 219 require_capability('moodle/course:managegroups', $context); 220 221 $group->name = \core_external\util::format_string($group->name, $context); 222 [$group->description, $group->descriptionformat] = 223 \core_external\util::format_text($group->description, $group->descriptionformat, 224 $context, 'group', 'description', $group->id); 225 226 $groups[] = (array)$group; 227 } 228 229 return $groups; 230 } 231 232 /** 233 * Returns description of method result value 234 * 235 * @return \core_external\external_description 236 * @since Moodle 2.2 237 */ 238 public static function get_groups_returns() { 239 return new external_multiple_structure( 240 new external_single_structure( 241 array( 242 'id' => new external_value(PARAM_INT, 'group record id'), 243 'courseid' => new external_value(PARAM_INT, 'id of course'), 244 'name' => new external_value(PARAM_TEXT, 'group name'), 245 'description' => new external_value(PARAM_RAW, 'group description text'), 246 'descriptionformat' => new external_format_value('description'), 247 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'), 248 'idnumber' => new external_value(PARAM_RAW, 'id number'), 249 'visibility' => new external_value(PARAM_INT, 250 'group visibility mode. 0 = Visible to all. 1 = Visible to members. 2 = See own membership. ' 251 . '3 = Membership is hidden.'), 252 'participation' => new external_value(PARAM_BOOL, 'participation mode'), 253 ) 254 ) 255 ); 256 } 257 258 /** 259 * Returns description of method parameters 260 * 261 * @return external_function_parameters 262 * @since Moodle 2.2 263 */ 264 public static function get_course_groups_parameters() { 265 return new external_function_parameters( 266 array( 267 'courseid' => new external_value(PARAM_INT, 'id of course'), 268 ) 269 ); 270 } 271 272 /** 273 * Get all groups in the specified course 274 * 275 * @param int $courseid id of course 276 * @return array of group objects (id, courseid, name, enrolmentkey) 277 * @since Moodle 2.2 278 */ 279 public static function get_course_groups($courseid) { 280 $params = self::validate_parameters(self::get_course_groups_parameters(), array('courseid'=>$courseid)); 281 282 // now security checks 283 $context = context_course::instance($params['courseid'], IGNORE_MISSING); 284 try { 285 self::validate_context($context); 286 } catch (Exception $e) { 287 $exceptionparam = new stdClass(); 288 $exceptionparam->message = $e->getMessage(); 289 $exceptionparam->courseid = $params['courseid']; 290 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 291 } 292 require_capability('moodle/course:managegroups', $context); 293 294 $gs = groups_get_all_groups($params['courseid'], 0, 0, 295 'g.id, g.courseid, g.name, g.idnumber, g.description, g.descriptionformat, g.enrolmentkey, ' 296 . 'g.visibility, g.participation'); 297 298 $groups = array(); 299 foreach ($gs as $group) { 300 $group->name = \core_external\util::format_string($group->name, $context); 301 [$group->description, $group->descriptionformat] = 302 \core_external\util::format_text($group->description, $group->descriptionformat, 303 $context, 'group', 'description', $group->id); 304 $groups[] = (array)$group; 305 } 306 307 return $groups; 308 } 309 310 /** 311 * Returns description of method result value 312 * 313 * @return \core_external\external_description 314 * @since Moodle 2.2 315 */ 316 public static function get_course_groups_returns() { 317 return new external_multiple_structure( 318 new external_single_structure( 319 array( 320 'id' => new external_value(PARAM_INT, 'group record id'), 321 'courseid' => new external_value(PARAM_INT, 'id of course'), 322 'name' => new external_value(PARAM_TEXT, 'group name'), 323 'description' => new external_value(PARAM_RAW, 'group description text'), 324 'descriptionformat' => new external_format_value('description'), 325 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'), 326 'idnumber' => new external_value(PARAM_RAW, 'id number'), 327 'visibility' => new external_value(PARAM_INT, 328 'group visibility mode. 0 = Visible to all. 1 = Visible to members. 2 = See own membership. ' 329 . '3 = Membership is hidden.'), 330 'participation' => new external_value(PARAM_BOOL, 'participation mode'), 331 ) 332 ) 333 ); 334 } 335 336 /** 337 * Returns description of method parameters 338 * 339 * @return external_function_parameters 340 * @since Moodle 2.2 341 */ 342 public static function delete_groups_parameters() { 343 return new external_function_parameters( 344 array( 345 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')), 346 ) 347 ); 348 } 349 350 /** 351 * Delete groups 352 * 353 * @param array $groupids array of group ids 354 * @since Moodle 2.2 355 */ 356 public static function delete_groups($groupids) { 357 global $CFG, $DB; 358 require_once("$CFG->dirroot/group/lib.php"); 359 360 $params = self::validate_parameters(self::delete_groups_parameters(), array('groupids'=>$groupids)); 361 362 $transaction = $DB->start_delegated_transaction(); 363 364 foreach ($params['groupids'] as $groupid) { 365 // validate params 366 $groupid = validate_param($groupid, PARAM_INT); 367 if (!$group = groups_get_group($groupid, '*', IGNORE_MISSING)) { 368 // silently ignore attempts to delete nonexisting groups 369 continue; 370 } 371 372 // now security checks 373 $context = context_course::instance($group->courseid, IGNORE_MISSING); 374 try { 375 self::validate_context($context); 376 } catch (Exception $e) { 377 $exceptionparam = new stdClass(); 378 $exceptionparam->message = $e->getMessage(); 379 $exceptionparam->courseid = $group->courseid; 380 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 381 } 382 require_capability('moodle/course:managegroups', $context); 383 384 groups_delete_group($group); 385 } 386 387 $transaction->allow_commit(); 388 } 389 390 /** 391 * Returns description of method result value 392 * 393 * @return null 394 * @since Moodle 2.2 395 */ 396 public static function delete_groups_returns() { 397 return null; 398 } 399 400 401 /** 402 * Returns description of method parameters 403 * 404 * @return external_function_parameters 405 * @since Moodle 2.2 406 */ 407 public static function get_group_members_parameters() { 408 return new external_function_parameters( 409 array( 410 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')), 411 ) 412 ); 413 } 414 415 /** 416 * Return all members for a group 417 * 418 * @param array $groupids array of group ids 419 * @return array with group id keys containing arrays of user ids 420 * @since Moodle 2.2 421 */ 422 public static function get_group_members($groupids) { 423 $members = array(); 424 425 $params = self::validate_parameters(self::get_group_members_parameters(), array('groupids'=>$groupids)); 426 427 foreach ($params['groupids'] as $groupid) { 428 // validate params 429 $group = groups_get_group($groupid, 'id, courseid, name, enrolmentkey', MUST_EXIST); 430 // now security checks 431 $context = context_course::instance($group->courseid, IGNORE_MISSING); 432 try { 433 self::validate_context($context); 434 } catch (Exception $e) { 435 $exceptionparam = new stdClass(); 436 $exceptionparam->message = $e->getMessage(); 437 $exceptionparam->courseid = $group->courseid; 438 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 439 } 440 require_capability('moodle/course:managegroups', $context); 441 442 $groupmembers = groups_get_members($group->id, 'u.id', 'lastname ASC, firstname ASC'); 443 444 $members[] = array('groupid'=>$groupid, 'userids'=>array_keys($groupmembers)); 445 } 446 447 return $members; 448 } 449 450 /** 451 * Returns description of method result value 452 * 453 * @return \core_external\external_description 454 * @since Moodle 2.2 455 */ 456 public static function get_group_members_returns() { 457 return new external_multiple_structure( 458 new external_single_structure( 459 array( 460 'groupid' => new external_value(PARAM_INT, 'group record id'), 461 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user id')), 462 ) 463 ) 464 ); 465 } 466 467 468 /** 469 * Returns description of method parameters 470 * 471 * @return external_function_parameters 472 * @since Moodle 2.2 473 */ 474 public static function add_group_members_parameters() { 475 return new external_function_parameters( 476 array( 477 'members'=> new external_multiple_structure( 478 new external_single_structure( 479 array( 480 'groupid' => new external_value(PARAM_INT, 'group record id'), 481 'userid' => new external_value(PARAM_INT, 'user id'), 482 ) 483 ) 484 ) 485 ) 486 ); 487 } 488 489 /** 490 * Add group members 491 * 492 * @param array $members of arrays with keys userid, groupid 493 * @since Moodle 2.2 494 */ 495 public static function add_group_members($members) { 496 global $CFG, $DB; 497 require_once("$CFG->dirroot/group/lib.php"); 498 499 $params = self::validate_parameters(self::add_group_members_parameters(), array('members'=>$members)); 500 501 $transaction = $DB->start_delegated_transaction(); 502 foreach ($params['members'] as $member) { 503 // validate params 504 $groupid = $member['groupid']; 505 $userid = $member['userid']; 506 507 $group = groups_get_group($groupid, '*', MUST_EXIST); 508 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST); 509 510 // now security checks 511 $context = context_course::instance($group->courseid, IGNORE_MISSING); 512 try { 513 self::validate_context($context); 514 } catch (Exception $e) { 515 $exceptionparam = new stdClass(); 516 $exceptionparam->message = $e->getMessage(); 517 $exceptionparam->courseid = $group->courseid; 518 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 519 } 520 require_capability('moodle/course:managegroups', $context); 521 522 // now make sure user is enrolled in course - this is mandatory requirement, 523 // unfortunately this is slow 524 if (!is_enrolled($context, $userid)) { 525 throw new invalid_parameter_exception('Only enrolled users may be members of groups'); 526 } 527 528 groups_add_member($group, $user); 529 } 530 531 $transaction->allow_commit(); 532 } 533 534 /** 535 * Returns description of method result value 536 * 537 * @return null 538 * @since Moodle 2.2 539 */ 540 public static function add_group_members_returns() { 541 return null; 542 } 543 544 545 /** 546 * Returns description of method parameters 547 * 548 * @return external_function_parameters 549 * @since Moodle 2.2 550 */ 551 public static function delete_group_members_parameters() { 552 return new external_function_parameters( 553 array( 554 'members'=> new external_multiple_structure( 555 new external_single_structure( 556 array( 557 'groupid' => new external_value(PARAM_INT, 'group record id'), 558 'userid' => new external_value(PARAM_INT, 'user id'), 559 ) 560 ) 561 ) 562 ) 563 ); 564 } 565 566 /** 567 * Delete group members 568 * 569 * @param array $members of arrays with keys userid, groupid 570 * @since Moodle 2.2 571 */ 572 public static function delete_group_members($members) { 573 global $CFG, $DB; 574 require_once("$CFG->dirroot/group/lib.php"); 575 576 $params = self::validate_parameters(self::delete_group_members_parameters(), array('members'=>$members)); 577 578 $transaction = $DB->start_delegated_transaction(); 579 580 foreach ($params['members'] as $member) { 581 // validate params 582 $groupid = $member['groupid']; 583 $userid = $member['userid']; 584 585 $group = groups_get_group($groupid, '*', MUST_EXIST); 586 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST); 587 588 // now security checks 589 $context = context_course::instance($group->courseid, IGNORE_MISSING); 590 try { 591 self::validate_context($context); 592 } catch (Exception $e) { 593 $exceptionparam = new stdClass(); 594 $exceptionparam->message = $e->getMessage(); 595 $exceptionparam->courseid = $group->courseid; 596 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 597 } 598 require_capability('moodle/course:managegroups', $context); 599 600 if (!groups_remove_member_allowed($group, $user)) { 601 $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context)); 602 throw new moodle_exception('errorremovenotpermitted', 'group', '', $fullname); 603 } 604 groups_remove_member($group, $user); 605 } 606 607 $transaction->allow_commit(); 608 } 609 610 /** 611 * Returns description of method result value 612 * 613 * @return null 614 * @since Moodle 2.2 615 */ 616 public static function delete_group_members_returns() { 617 return null; 618 } 619 620 /** 621 * Returns description of method parameters 622 * 623 * @return external_function_parameters 624 * @since Moodle 2.3 625 */ 626 public static function create_groupings_parameters() { 627 return new external_function_parameters( 628 array( 629 'groupings' => new external_multiple_structure( 630 new external_single_structure( 631 array( 632 'courseid' => new external_value(PARAM_INT, 'id of course'), 633 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 634 'description' => new external_value(PARAM_RAW, 'grouping description text'), 635 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT), 636 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL) 637 ) 638 ), 'List of grouping object. A grouping has a courseid, a name and a description.' 639 ) 640 ) 641 ); 642 } 643 644 /** 645 * Create groupings 646 * 647 * @param array $groupings array of grouping description arrays (with keys groupname and courseid) 648 * @return array of newly created groupings 649 * @since Moodle 2.3 650 */ 651 public static function create_groupings($groupings) { 652 global $CFG, $DB; 653 require_once("$CFG->dirroot/group/lib.php"); 654 655 $params = self::validate_parameters(self::create_groupings_parameters(), array('groupings'=>$groupings)); 656 657 $transaction = $DB->start_delegated_transaction(); 658 659 $groupings = array(); 660 661 foreach ($params['groupings'] as $grouping) { 662 $grouping = (object)$grouping; 663 664 if (trim($grouping->name) == '') { 665 throw new invalid_parameter_exception('Invalid grouping name'); 666 } 667 if ($DB->count_records('groupings', array('courseid'=>$grouping->courseid, 'name'=>$grouping->name))) { 668 throw new invalid_parameter_exception('Grouping with the same name already exists in the course'); 669 } 670 671 // Now security checks . 672 $context = context_course::instance($grouping->courseid); 673 try { 674 self::validate_context($context); 675 } catch (Exception $e) { 676 $exceptionparam = new stdClass(); 677 $exceptionparam->message = $e->getMessage(); 678 $exceptionparam->courseid = $grouping->courseid; 679 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 680 } 681 require_capability('moodle/course:managegroups', $context); 682 683 $grouping->descriptionformat = util::validate_format($grouping->descriptionformat); 684 685 // Finally create the grouping. 686 $grouping->id = groups_create_grouping($grouping); 687 $groupings[] = (array)$grouping; 688 } 689 690 $transaction->allow_commit(); 691 692 return $groupings; 693 } 694 695 /** 696 * Returns description of method result value 697 * 698 * @return \core_external\external_description 699 * @since Moodle 2.3 700 */ 701 public static function create_groupings_returns() { 702 return new external_multiple_structure( 703 new external_single_structure( 704 array( 705 'id' => new external_value(PARAM_INT, 'grouping record id'), 706 'courseid' => new external_value(PARAM_INT, 'id of course'), 707 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 708 'description' => new external_value(PARAM_RAW, 'grouping description text'), 709 'descriptionformat' => new external_format_value('description'), 710 'idnumber' => new external_value(PARAM_RAW, 'id number') 711 ) 712 ), 'List of grouping object. A grouping has an id, a courseid, a name and a description.' 713 ); 714 } 715 716 /** 717 * Returns description of method parameters 718 * 719 * @return external_function_parameters 720 * @since Moodle 2.3 721 */ 722 public static function update_groupings_parameters() { 723 return new external_function_parameters( 724 array( 725 'groupings' => new external_multiple_structure( 726 new external_single_structure( 727 array( 728 'id' => new external_value(PARAM_INT, 'id of grouping'), 729 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 730 'description' => new external_value(PARAM_RAW, 'grouping description text'), 731 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT), 732 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL) 733 ) 734 ), 'List of grouping object. A grouping has a courseid, a name and a description.' 735 ) 736 ) 737 ); 738 } 739 740 /** 741 * Update groupings 742 * 743 * @param array $groupings array of grouping description arrays (with keys groupname and courseid) 744 * @return array of newly updated groupings 745 * @since Moodle 2.3 746 */ 747 public static function update_groupings($groupings) { 748 global $CFG, $DB; 749 require_once("$CFG->dirroot/group/lib.php"); 750 751 $params = self::validate_parameters(self::update_groupings_parameters(), array('groupings'=>$groupings)); 752 753 $transaction = $DB->start_delegated_transaction(); 754 755 foreach ($params['groupings'] as $grouping) { 756 $grouping = (object)$grouping; 757 758 if (trim($grouping->name) == '') { 759 throw new invalid_parameter_exception('Invalid grouping name'); 760 } 761 762 if (! $currentgrouping = $DB->get_record('groupings', array('id'=>$grouping->id))) { 763 throw new invalid_parameter_exception("Grouping $grouping->id does not exist in the course"); 764 } 765 766 // Check if the new modified grouping name already exists in the course. 767 if ($grouping->name != $currentgrouping->name and 768 $DB->count_records('groupings', array('courseid'=>$currentgrouping->courseid, 'name'=>$grouping->name))) { 769 throw new invalid_parameter_exception('A different grouping with the same name already exists in the course'); 770 } 771 772 $grouping->courseid = $currentgrouping->courseid; 773 774 // Now security checks. 775 $context = context_course::instance($grouping->courseid); 776 try { 777 self::validate_context($context); 778 } catch (Exception $e) { 779 $exceptionparam = new stdClass(); 780 $exceptionparam->message = $e->getMessage(); 781 $exceptionparam->courseid = $grouping->courseid; 782 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 783 } 784 require_capability('moodle/course:managegroups', $context); 785 786 // We must force allways FORMAT_HTML. 787 $grouping->descriptionformat = util::validate_format($grouping->descriptionformat); 788 789 // Finally update the grouping. 790 groups_update_grouping($grouping); 791 } 792 793 $transaction->allow_commit(); 794 795 return null; 796 } 797 798 /** 799 * Returns description of method result value 800 * 801 * @return \core_external\external_description 802 * @since Moodle 2.3 803 */ 804 public static function update_groupings_returns() { 805 return null; 806 } 807 808 /** 809 * Returns description of method parameters 810 * 811 * @return external_function_parameters 812 * @since Moodle 2.3 813 */ 814 public static function get_groupings_parameters() { 815 return new external_function_parameters( 816 array( 817 'groupingids' => new external_multiple_structure(new external_value(PARAM_INT, 'grouping ID') 818 , 'List of grouping id. A grouping id is an integer.'), 819 'returngroups' => new external_value(PARAM_BOOL, 'return associated groups', VALUE_DEFAULT, 0) 820 ) 821 ); 822 } 823 824 /** 825 * Get groupings definition specified by ids 826 * 827 * @param array $groupingids arrays of grouping ids 828 * @param boolean $returngroups return the associated groups if true. The default is false. 829 * @return array of grouping objects (id, courseid, name) 830 * @since Moodle 2.3 831 */ 832 public static function get_groupings($groupingids, $returngroups = false) { 833 global $CFG, $DB; 834 require_once("$CFG->dirroot/group/lib.php"); 835 require_once("$CFG->libdir/filelib.php"); 836 837 $params = self::validate_parameters(self::get_groupings_parameters(), 838 array('groupingids' => $groupingids, 839 'returngroups' => $returngroups)); 840 841 $groupings = array(); 842 foreach ($params['groupingids'] as $groupingid) { 843 // Validate params. 844 $grouping = groups_get_grouping($groupingid, '*', MUST_EXIST); 845 846 // Now security checks. 847 $context = context_course::instance($grouping->courseid); 848 try { 849 self::validate_context($context); 850 } catch (Exception $e) { 851 $exceptionparam = new stdClass(); 852 $exceptionparam->message = $e->getMessage(); 853 $exceptionparam->courseid = $grouping->courseid; 854 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 855 } 856 require_capability('moodle/course:managegroups', $context); 857 858 list($grouping->description, $grouping->descriptionformat) = 859 \core_external\util::format_text($grouping->description, $grouping->descriptionformat, 860 $context, 'grouping', 'description', $grouping->id); 861 862 $groupingarray = (array)$grouping; 863 864 if ($params['returngroups']) { 865 $grouprecords = $DB->get_records_sql("SELECT * FROM {groups} g INNER JOIN {groupings_groups} gg ". 866 "ON g.id = gg.groupid WHERE gg.groupingid = ? ". 867 "ORDER BY groupid", array($groupingid)); 868 if ($grouprecords) { 869 $groups = array(); 870 foreach ($grouprecords as $grouprecord) { 871 list($grouprecord->description, $grouprecord->descriptionformat) = 872 \core_external\util::format_text($grouprecord->description, $grouprecord->descriptionformat, 873 $context, 'group', 'description', $grouprecord->groupid); 874 $groups[] = array('id' => $grouprecord->groupid, 875 'name' => $grouprecord->name, 876 'idnumber' => $grouprecord->idnumber, 877 'description' => $grouprecord->description, 878 'descriptionformat' => $grouprecord->descriptionformat, 879 'enrolmentkey' => $grouprecord->enrolmentkey, 880 'courseid' => $grouprecord->courseid 881 ); 882 } 883 $groupingarray['groups'] = $groups; 884 } 885 } 886 $groupings[] = $groupingarray; 887 } 888 889 return $groupings; 890 } 891 892 /** 893 * Returns description of method result value 894 * 895 * @return \core_external\external_description 896 * @since Moodle 2.3 897 */ 898 public static function get_groupings_returns() { 899 return new external_multiple_structure( 900 new external_single_structure( 901 array( 902 'id' => new external_value(PARAM_INT, 'grouping record id'), 903 'courseid' => new external_value(PARAM_INT, 'id of course'), 904 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 905 'description' => new external_value(PARAM_RAW, 'grouping description text'), 906 'descriptionformat' => new external_format_value('description'), 907 'idnumber' => new external_value(PARAM_RAW, 'id number'), 908 'groups' => new external_multiple_structure( 909 new external_single_structure( 910 array( 911 'id' => new external_value(PARAM_INT, 'group record id'), 912 'courseid' => new external_value(PARAM_INT, 'id of course'), 913 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 914 'description' => new external_value(PARAM_RAW, 'group description text'), 915 'descriptionformat' => new external_format_value('description'), 916 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'), 917 'idnumber' => new external_value(PARAM_RAW, 'id number') 918 ) 919 ), 920 'optional groups', VALUE_OPTIONAL) 921 ) 922 ) 923 ); 924 } 925 926 /** 927 * Returns description of method parameters 928 * 929 * @return external_function_parameters 930 * @since Moodle 2.3 931 */ 932 public static function get_course_groupings_parameters() { 933 return new external_function_parameters( 934 array( 935 'courseid' => new external_value(PARAM_INT, 'id of course'), 936 ) 937 ); 938 } 939 940 /** 941 * Get all groupings in the specified course 942 * 943 * @param int $courseid id of course 944 * @return array of grouping objects (id, courseid, name, enrolmentkey) 945 * @since Moodle 2.3 946 */ 947 public static function get_course_groupings($courseid) { 948 global $CFG; 949 require_once("$CFG->dirroot/group/lib.php"); 950 require_once("$CFG->libdir/filelib.php"); 951 952 $params = self::validate_parameters(self::get_course_groupings_parameters(), array('courseid'=>$courseid)); 953 954 // Now security checks. 955 $context = context_course::instance($params['courseid']); 956 957 try { 958 self::validate_context($context); 959 } catch (Exception $e) { 960 $exceptionparam = new stdClass(); 961 $exceptionparam->message = $e->getMessage(); 962 $exceptionparam->courseid = $params['courseid']; 963 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 964 } 965 require_capability('moodle/course:managegroups', $context); 966 967 $gs = groups_get_all_groupings($params['courseid']); 968 969 $groupings = array(); 970 foreach ($gs as $grouping) { 971 list($grouping->description, $grouping->descriptionformat) = 972 \core_external\util::format_text($grouping->description, $grouping->descriptionformat, 973 $context, 'grouping', 'description', $grouping->id); 974 $groupings[] = (array)$grouping; 975 } 976 977 return $groupings; 978 } 979 980 /** 981 * Returns description of method result value 982 * 983 * @return \core_external\external_description 984 * @since Moodle 2.3 985 */ 986 public static function get_course_groupings_returns() { 987 return new external_multiple_structure( 988 new external_single_structure( 989 array( 990 'id' => new external_value(PARAM_INT, 'grouping record id'), 991 'courseid' => new external_value(PARAM_INT, 'id of course'), 992 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 993 'description' => new external_value(PARAM_RAW, 'grouping description text'), 994 'descriptionformat' => new external_format_value('description'), 995 'idnumber' => new external_value(PARAM_RAW, 'id number') 996 ) 997 ) 998 ); 999 } 1000 1001 /** 1002 * Returns description of method parameters 1003 * 1004 * @return external_function_parameters 1005 * @since Moodle 2.3 1006 */ 1007 public static function delete_groupings_parameters() { 1008 return new external_function_parameters( 1009 array( 1010 'groupingids' => new external_multiple_structure(new external_value(PARAM_INT, 'grouping ID')), 1011 ) 1012 ); 1013 } 1014 1015 /** 1016 * Delete groupings 1017 * 1018 * @param array $groupingids array of grouping ids 1019 * @return void 1020 * @since Moodle 2.3 1021 */ 1022 public static function delete_groupings($groupingids) { 1023 global $CFG, $DB; 1024 require_once("$CFG->dirroot/group/lib.php"); 1025 1026 $params = self::validate_parameters(self::delete_groupings_parameters(), array('groupingids'=>$groupingids)); 1027 1028 $transaction = $DB->start_delegated_transaction(); 1029 1030 foreach ($params['groupingids'] as $groupingid) { 1031 1032 if (!$grouping = groups_get_grouping($groupingid)) { 1033 // Silently ignore attempts to delete nonexisting groupings. 1034 continue; 1035 } 1036 1037 // Now security checks. 1038 $context = context_course::instance($grouping->courseid); 1039 try { 1040 self::validate_context($context); 1041 } catch (Exception $e) { 1042 $exceptionparam = new stdClass(); 1043 $exceptionparam->message = $e->getMessage(); 1044 $exceptionparam->courseid = $grouping->courseid; 1045 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 1046 } 1047 require_capability('moodle/course:managegroups', $context); 1048 1049 groups_delete_grouping($grouping); 1050 } 1051 1052 $transaction->allow_commit(); 1053 } 1054 1055 /** 1056 * Returns description of method result value 1057 * 1058 * @return \core_external\external_description 1059 * @since Moodle 2.3 1060 */ 1061 public static function delete_groupings_returns() { 1062 return null; 1063 } 1064 1065 /** 1066 * Returns description of method parameters 1067 * 1068 * @return external_function_parameters 1069 * @since Moodle 2.3 1070 */ 1071 public static function assign_grouping_parameters() { 1072 return new external_function_parameters( 1073 array( 1074 'assignments'=> new external_multiple_structure( 1075 new external_single_structure( 1076 array( 1077 'groupingid' => new external_value(PARAM_INT, 'grouping record id'), 1078 'groupid' => new external_value(PARAM_INT, 'group record id'), 1079 ) 1080 ) 1081 ) 1082 ) 1083 ); 1084 } 1085 1086 /** 1087 * Assign a group to a grouping 1088 * 1089 * @param array $assignments of arrays with keys groupid, groupingid 1090 * @return void 1091 * @since Moodle 2.3 1092 */ 1093 public static function assign_grouping($assignments) { 1094 global $CFG, $DB; 1095 require_once("$CFG->dirroot/group/lib.php"); 1096 1097 $params = self::validate_parameters(self::assign_grouping_parameters(), array('assignments'=>$assignments)); 1098 1099 $transaction = $DB->start_delegated_transaction(); 1100 foreach ($params['assignments'] as $assignment) { 1101 // Validate params. 1102 $groupingid = $assignment['groupingid']; 1103 $groupid = $assignment['groupid']; 1104 1105 $grouping = groups_get_grouping($groupingid, 'id, courseid', MUST_EXIST); 1106 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST); 1107 1108 if ($DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) { 1109 // Continue silently if the group is yet assigned to the grouping. 1110 continue; 1111 } 1112 1113 // Now security checks. 1114 $context = context_course::instance($grouping->courseid); 1115 try { 1116 self::validate_context($context); 1117 } catch (Exception $e) { 1118 $exceptionparam = new stdClass(); 1119 $exceptionparam->message = $e->getMessage(); 1120 $exceptionparam->courseid = $group->courseid; 1121 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 1122 } 1123 require_capability('moodle/course:managegroups', $context); 1124 1125 groups_assign_grouping($groupingid, $groupid); 1126 } 1127 1128 $transaction->allow_commit(); 1129 } 1130 1131 /** 1132 * Returns description of method result value 1133 * 1134 * @return null 1135 * @since Moodle 2.3 1136 */ 1137 public static function assign_grouping_returns() { 1138 return null; 1139 } 1140 1141 /** 1142 * Returns description of method parameters 1143 * 1144 * @return external_function_parameters 1145 * @since Moodle 2.3 1146 */ 1147 public static function unassign_grouping_parameters() { 1148 return new external_function_parameters( 1149 array( 1150 'unassignments'=> new external_multiple_structure( 1151 new external_single_structure( 1152 array( 1153 'groupingid' => new external_value(PARAM_INT, 'grouping record id'), 1154 'groupid' => new external_value(PARAM_INT, 'group record id'), 1155 ) 1156 ) 1157 ) 1158 ) 1159 ); 1160 } 1161 1162 /** 1163 * Unassign a group from a grouping 1164 * 1165 * @param array $unassignments of arrays with keys groupid, groupingid 1166 * @return void 1167 * @since Moodle 2.3 1168 */ 1169 public static function unassign_grouping($unassignments) { 1170 global $CFG, $DB; 1171 require_once("$CFG->dirroot/group/lib.php"); 1172 1173 $params = self::validate_parameters(self::unassign_grouping_parameters(), array('unassignments'=>$unassignments)); 1174 1175 $transaction = $DB->start_delegated_transaction(); 1176 foreach ($params['unassignments'] as $unassignment) { 1177 // Validate params. 1178 $groupingid = $unassignment['groupingid']; 1179 $groupid = $unassignment['groupid']; 1180 1181 $grouping = groups_get_grouping($groupingid, 'id, courseid', MUST_EXIST); 1182 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST); 1183 1184 if (!$DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) { 1185 // Continue silently if the group is not assigned to the grouping. 1186 continue; 1187 } 1188 1189 // Now security checks. 1190 $context = context_course::instance($grouping->courseid); 1191 try { 1192 self::validate_context($context); 1193 } catch (Exception $e) { 1194 $exceptionparam = new stdClass(); 1195 $exceptionparam->message = $e->getMessage(); 1196 $exceptionparam->courseid = $group->courseid; 1197 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 1198 } 1199 require_capability('moodle/course:managegroups', $context); 1200 1201 groups_unassign_grouping($groupingid, $groupid); 1202 } 1203 1204 $transaction->allow_commit(); 1205 } 1206 1207 /** 1208 * Returns description of method result value 1209 * 1210 * @return null 1211 * @since Moodle 2.3 1212 */ 1213 public static function unassign_grouping_returns() { 1214 return null; 1215 } 1216 1217 /** 1218 * Returns description of method parameters 1219 * 1220 * @return external_function_parameters 1221 * @since Moodle 2.9 1222 */ 1223 public static function get_course_user_groups_parameters() { 1224 return new external_function_parameters( 1225 array( 1226 'courseid' => new external_value(PARAM_INT, 1227 'Id of course (empty or 0 for all the courses where the user is enrolled).', VALUE_DEFAULT, 0), 1228 'userid' => new external_value(PARAM_INT, 'Id of user (empty or 0 for current user).', VALUE_DEFAULT, 0), 1229 'groupingid' => new external_value(PARAM_INT, 'returns only groups in the specified grouping', VALUE_DEFAULT, 0) 1230 ) 1231 ); 1232 } 1233 1234 /** 1235 * Get all groups in the specified course for the specified user. 1236 * 1237 * @throws moodle_exception 1238 * @param int $courseid id of course. 1239 * @param int $userid id of user. 1240 * @param int $groupingid optional returns only groups in the specified grouping. 1241 * @return array of group objects (id, name, description, format) and possible warnings. 1242 * @since Moodle 2.9 1243 */ 1244 public static function get_course_user_groups($courseid = 0, $userid = 0, $groupingid = 0) { 1245 global $USER; 1246 1247 // Warnings array, it can be empty at the end but is mandatory. 1248 $warnings = array(); 1249 1250 $params = array( 1251 'courseid' => $courseid, 1252 'userid' => $userid, 1253 'groupingid' => $groupingid 1254 ); 1255 $params = self::validate_parameters(self::get_course_user_groups_parameters(), $params); 1256 1257 $courseid = $params['courseid']; 1258 $userid = $params['userid']; 1259 $groupingid = $params['groupingid']; 1260 1261 // Validate user. 1262 if (empty($userid)) { 1263 $userid = $USER->id; 1264 } else { 1265 $user = core_user::get_user($userid, '*', MUST_EXIST); 1266 core_user::require_active_user($user); 1267 } 1268 1269 // Get courses. 1270 if (empty($courseid)) { 1271 $courses = enrol_get_users_courses($userid, true); 1272 $checkenrolments = false; // No need to check enrolments here since they are my courses. 1273 } else { 1274 $courses = array($courseid => get_course($courseid)); 1275 $checkenrolments = true; 1276 } 1277 1278 // Security checks. 1279 list($courses, $warnings) = util::validate_courses(array_keys($courses), $courses, true); 1280 1281 $usergroups = array(); 1282 foreach ($courses as $course) { 1283 // Check if we have permissions for retrieve the information. 1284 if ($userid != $USER->id && !has_capability('moodle/course:managegroups', $course->context)) { 1285 $warnings[] = array( 1286 'item' => 'course', 1287 'itemid' => $course->id, 1288 'warningcode' => 'cannotmanagegroups', 1289 'message' => "User $USER->id cannot manage groups in course $course->id", 1290 ); 1291 continue; 1292 } 1293 1294 // Check if the user being check is enrolled in the given course. 1295 if ($checkenrolments && !is_enrolled($course->context, $userid)) { 1296 // We return a warning because the function does not fail for not enrolled users. 1297 $warnings[] = array( 1298 'item' => 'course', 1299 'itemid' => $course->id, 1300 'warningcode' => 'notenrolled', 1301 'message' => "User $userid is not enrolled in course $course->id", 1302 ); 1303 } 1304 1305 $groups = groups_get_all_groups($course->id, $userid, $groupingid, 1306 'g.id, g.name, g.description, g.descriptionformat, g.idnumber'); 1307 1308 foreach ($groups as $group) { 1309 $group->name = \core_external\util::format_string($group->name, $course->context); 1310 [$group->description, $group->descriptionformat] = 1311 \core_external\util::format_text($group->description, $group->descriptionformat, 1312 $course->context, 'group', 'description', $group->id); 1313 $group->courseid = $course->id; 1314 $usergroups[] = $group; 1315 } 1316 } 1317 1318 $results = array( 1319 'groups' => $usergroups, 1320 'warnings' => $warnings 1321 ); 1322 return $results; 1323 } 1324 1325 /** 1326 * Returns description of method result value. 1327 * 1328 * @return \core_external\external_description A single structure containing groups and possible warnings. 1329 * @since Moodle 2.9 1330 */ 1331 public static function get_course_user_groups_returns() { 1332 return new external_single_structure( 1333 array( 1334 'groups' => new external_multiple_structure(self::group_description()), 1335 'warnings' => new external_warnings(), 1336 ) 1337 ); 1338 } 1339 1340 /** 1341 * Create group return value description. 1342 * 1343 * @return external_single_structure The group description 1344 */ 1345 public static function group_description() { 1346 return new external_single_structure( 1347 array( 1348 'id' => new external_value(PARAM_INT, 'group record id'), 1349 'name' => new external_value(PARAM_TEXT, 'group name'), 1350 'description' => new external_value(PARAM_RAW, 'group description text'), 1351 'descriptionformat' => new external_format_value('description'), 1352 'idnumber' => new external_value(PARAM_RAW, 'id number'), 1353 'courseid' => new external_value(PARAM_INT, 'course id', VALUE_OPTIONAL), 1354 ) 1355 ); 1356 } 1357 1358 /** 1359 * Returns description of method parameters 1360 * 1361 * @return external_function_parameters 1362 * @since Moodle 3.0 1363 */ 1364 public static function get_activity_allowed_groups_parameters() { 1365 return new external_function_parameters( 1366 array( 1367 'cmid' => new external_value(PARAM_INT, 'course module id'), 1368 'userid' => new external_value(PARAM_INT, 'id of user, empty for current user', VALUE_DEFAULT, 0) 1369 ) 1370 ); 1371 } 1372 1373 /** 1374 * Gets a list of groups that the user is allowed to access within the specified activity. 1375 * 1376 * @throws moodle_exception 1377 * @param int $cmid course module id 1378 * @param int $userid id of user. 1379 * @return array of group objects (id, name, description, format) and possible warnings. 1380 * @since Moodle 3.0 1381 */ 1382 public static function get_activity_allowed_groups($cmid, $userid = 0) { 1383 global $USER; 1384 1385 // Warnings array, it can be empty at the end but is mandatory. 1386 $warnings = array(); 1387 1388 $params = array( 1389 'cmid' => $cmid, 1390 'userid' => $userid 1391 ); 1392 $params = self::validate_parameters(self::get_activity_allowed_groups_parameters(), $params); 1393 $cmid = $params['cmid']; 1394 $userid = $params['userid']; 1395 1396 $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST); 1397 1398 // Security checks. 1399 $context = context_module::instance($cm->id); 1400 $coursecontext = context_course::instance($cm->course); 1401 self::validate_context($context); 1402 1403 if (empty($userid)) { 1404 $userid = $USER->id; 1405 } 1406 1407 $user = core_user::get_user($userid, '*', MUST_EXIST); 1408 core_user::require_active_user($user); 1409 1410 // Check if we have permissions for retrieve the information. 1411 if ($user->id != $USER->id) { 1412 if (!has_capability('moodle/course:managegroups', $context)) { 1413 throw new moodle_exception('accessdenied', 'admin'); 1414 } 1415 1416 // Validate if the user is enrolled in the course. 1417 $course = get_course($cm->course); 1418 if (!can_access_course($course, $user, '', true)) { 1419 // We return a warning because the function does not fail for not enrolled users. 1420 $warning = array(); 1421 $warning['item'] = 'course'; 1422 $warning['itemid'] = $cm->course; 1423 $warning['warningcode'] = '1'; 1424 $warning['message'] = "User $user->id cannot access course $cm->course"; 1425 $warnings[] = $warning; 1426 } 1427 } 1428 1429 $usergroups = array(); 1430 if (empty($warnings)) { 1431 $groups = groups_get_activity_allowed_groups($cm, $user->id); 1432 1433 foreach ($groups as $group) { 1434 $group->name = \core_external\util::format_string($group->name, $coursecontext); 1435 [$group->description, $group->descriptionformat] = 1436 \core_external\util::format_text($group->description, $group->descriptionformat, 1437 $coursecontext, 'group', 'description', $group->id); 1438 $group->courseid = $cm->course; 1439 $usergroups[] = $group; 1440 } 1441 } 1442 1443 $results = array( 1444 'groups' => $usergroups, 1445 'canaccessallgroups' => has_capability('moodle/site:accessallgroups', $context, $user), 1446 'warnings' => $warnings 1447 ); 1448 return $results; 1449 } 1450 1451 /** 1452 * Returns description of method result value. 1453 * 1454 * @return \core_external\external_description A single structure containing groups and possible warnings. 1455 * @since Moodle 3.0 1456 */ 1457 public static function get_activity_allowed_groups_returns() { 1458 return new external_single_structure( 1459 array( 1460 'groups' => new external_multiple_structure(self::group_description()), 1461 'canaccessallgroups' => new external_value(PARAM_BOOL, 1462 'Whether the user will be able to access all the activity groups.', VALUE_OPTIONAL), 1463 'warnings' => new external_warnings(), 1464 ) 1465 ); 1466 } 1467 1468 /** 1469 * Returns description of method parameters 1470 * 1471 * @return external_function_parameters 1472 * @since Moodle 3.0 1473 */ 1474 public static function get_activity_groupmode_parameters() { 1475 return new external_function_parameters( 1476 array( 1477 'cmid' => new external_value(PARAM_INT, 'course module id') 1478 ) 1479 ); 1480 } 1481 1482 /** 1483 * Returns effective groupmode used in a given activity. 1484 * 1485 * @throws moodle_exception 1486 * @param int $cmid course module id. 1487 * @return array containing the group mode and possible warnings. 1488 * @since Moodle 3.0 1489 * @throws moodle_exception 1490 */ 1491 public static function get_activity_groupmode($cmid) { 1492 global $USER; 1493 1494 // Warnings array, it can be empty at the end but is mandatory. 1495 $warnings = array(); 1496 1497 $params = array( 1498 'cmid' => $cmid 1499 ); 1500 $params = self::validate_parameters(self::get_activity_groupmode_parameters(), $params); 1501 $cmid = $params['cmid']; 1502 1503 $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST); 1504 1505 // Security checks. 1506 $context = context_module::instance($cm->id); 1507 self::validate_context($context); 1508 1509 $groupmode = groups_get_activity_groupmode($cm); 1510 1511 $results = array( 1512 'groupmode' => $groupmode, 1513 'warnings' => $warnings 1514 ); 1515 return $results; 1516 } 1517 1518 /** 1519 * Returns description of method result value. 1520 * 1521 * @return \core_external\external_description 1522 * @since Moodle 3.0 1523 */ 1524 public static function get_activity_groupmode_returns() { 1525 return new external_single_structure( 1526 array( 1527 'groupmode' => new external_value(PARAM_INT, 'group mode: 1528 0 for no groups, 1 for separate groups, 2 for visible groups'), 1529 'warnings' => new external_warnings(), 1530 ) 1531 ); 1532 } 1533 1534 /** 1535 * Returns description of method parameters 1536 * 1537 * @return external_function_parameters 1538 * @since Moodle 3.6 1539 */ 1540 public static function update_groups_parameters() { 1541 return new external_function_parameters( 1542 array( 1543 'groups' => new external_multiple_structure( 1544 new external_single_structure( 1545 array( 1546 'id' => new external_value(PARAM_INT, 'ID of the group'), 1547 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 1548 'description' => new external_value(PARAM_RAW, 'group description text', VALUE_OPTIONAL), 1549 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT), 1550 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase', VALUE_OPTIONAL), 1551 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL), 1552 'visibility' => new external_value(PARAM_TEXT, 1553 'group visibility mode. 0 = Visible to all. 1 = Visible to members. ' 1554 . '2 = See own membership. 3 = Membership is hidden.', VALUE_OPTIONAL), 1555 'participation' => new external_value(PARAM_BOOL, 1556 'activity participation enabled? Only for "all" and "members" visibility', VALUE_OPTIONAL), 1557 ) 1558 ), 'List of group objects. A group is found by the id, then all other details provided will be updated.' 1559 ) 1560 ) 1561 ); 1562 } 1563 1564 /** 1565 * Update groups 1566 * 1567 * @param array $groups 1568 * @return null 1569 * @since Moodle 3.6 1570 */ 1571 public static function update_groups($groups) { 1572 global $CFG, $DB; 1573 require_once("$CFG->dirroot/group/lib.php"); 1574 1575 $params = self::validate_parameters(self::update_groups_parameters(), array('groups' => $groups)); 1576 1577 $transaction = $DB->start_delegated_transaction(); 1578 1579 foreach ($params['groups'] as $group) { 1580 $group = (object) $group; 1581 1582 if (trim($group->name) == '') { 1583 throw new invalid_parameter_exception('Invalid group name'); 1584 } 1585 1586 if (!$currentgroup = $DB->get_record('groups', array('id' => $group->id))) { 1587 throw new invalid_parameter_exception("Group $group->id does not exist"); 1588 } 1589 1590 // Check if the modified group name already exists in the course. 1591 if ($group->name != $currentgroup->name and 1592 $DB->get_record('groups', array('courseid' => $currentgroup->courseid, 'name' => $group->name))) { 1593 throw new invalid_parameter_exception('A different group with the same name already exists in the course'); 1594 } 1595 1596 if (isset($group->visibility) || isset($group->participation)) { 1597 $hasmembers = $DB->record_exists('groups_members', ['groupid' => $group->id]); 1598 if (isset($group->visibility)) { 1599 // Validate visibility. 1600 self::validate_visibility($group->visibility); 1601 if ($hasmembers && $group->visibility != $currentgroup->visibility) { 1602 throw new invalid_parameter_exception( 1603 'The visibility of this group cannot be changed as it currently has members.'); 1604 } 1605 } else { 1606 $group->visibility = $currentgroup->visibility; 1607 } 1608 if (isset($group->participation) && $hasmembers && $group->participation != $currentgroup->participation) { 1609 throw new invalid_parameter_exception( 1610 'The participation mode of this group cannot be changed as it currently has members.'); 1611 } 1612 } 1613 1614 $group->courseid = $currentgroup->courseid; 1615 1616 // Now security checks. 1617 $context = context_course::instance($group->courseid); 1618 try { 1619 self::validate_context($context); 1620 } catch (Exception $e) { 1621 $exceptionparam = new stdClass(); 1622 $exceptionparam->message = $e->getMessage(); 1623 $exceptionparam->courseid = $group->courseid; 1624 throw new moodle_exception('errorcoursecontextnotvalid', 'webservice', '', $exceptionparam); 1625 } 1626 require_capability('moodle/course:managegroups', $context); 1627 1628 if (!empty($group->description)) { 1629 $group->descriptionformat = util::validate_format($group->descriptionformat); 1630 } 1631 1632 groups_update_group($group); 1633 } 1634 1635 $transaction->allow_commit(); 1636 1637 return null; 1638 } 1639 1640 /** 1641 * Returns description of method result value 1642 * 1643 * @return null 1644 * @since Moodle 3.6 1645 */ 1646 public static function update_groups_returns() { 1647 return null; 1648 } 1649 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body