externallib.php 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476
  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. * External groups API
  18. *
  19. * @package core_group
  20. * @category external
  21. * @copyright 2009 Petr Skodak
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. require_once("$CFG->libdir/externallib.php");
  25. /**
  26. * Group external functions
  27. *
  28. * @package core_group
  29. * @category external
  30. * @copyright 2011 Jerome Mouneyrac
  31. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32. * @since Moodle 2.2
  33. */
  34. class core_group_external extends external_api {
  35. /**
  36. * Returns description of method parameters
  37. *
  38. * @return external_function_parameters
  39. * @since Moodle 2.2
  40. */
  41. public static function create_groups_parameters() {
  42. return new external_function_parameters(
  43. array(
  44. 'groups' => new external_multiple_structure(
  45. new external_single_structure(
  46. array(
  47. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  48. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  49. 'description' => new external_value(PARAM_RAW, 'group description text'),
  50. 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
  51. 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase', VALUE_OPTIONAL),
  52. 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL)
  53. )
  54. ), 'List of group object. A group has a courseid, a name, a description and an enrolment key.'
  55. )
  56. )
  57. );
  58. }
  59. /**
  60. * Create groups
  61. *
  62. * @param array $groups array of group description arrays (with keys groupname and courseid)
  63. * @return array of newly created groups
  64. * @since Moodle 2.2
  65. */
  66. public static function create_groups($groups) {
  67. global $CFG, $DB;
  68. require_once("$CFG->dirroot/group/lib.php");
  69. $params = self::validate_parameters(self::create_groups_parameters(), array('groups'=>$groups));
  70. $transaction = $DB->start_delegated_transaction();
  71. $groups = array();
  72. foreach ($params['groups'] as $group) {
  73. $group = (object)$group;
  74. if (trim($group->name) == '') {
  75. throw new invalid_parameter_exception('Invalid group name');
  76. }
  77. if ($DB->get_record('groups', array('courseid'=>$group->courseid, 'name'=>$group->name))) {
  78. throw new invalid_parameter_exception('Group with the same name already exists in the course');
  79. }
  80. if (!empty($group->idnumber) && $DB->count_records('groups', array('idnumber' => $group->idnumber))) {
  81. throw new invalid_parameter_exception('Group with the same idnumber already exists');
  82. }
  83. // now security checks
  84. $context = context_course::instance($group->courseid, IGNORE_MISSING);
  85. try {
  86. self::validate_context($context);
  87. } catch (Exception $e) {
  88. $exceptionparam = new stdClass();
  89. $exceptionparam->message = $e->getMessage();
  90. $exceptionparam->courseid = $group->courseid;
  91. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  92. }
  93. require_capability('moodle/course:managegroups', $context);
  94. // Validate format.
  95. $group->descriptionformat = external_validate_format($group->descriptionformat);
  96. // finally create the group
  97. $group->id = groups_create_group($group, false);
  98. if (!isset($group->enrolmentkey)) {
  99. $group->enrolmentkey = '';
  100. }
  101. if (!isset($group->idnumber)) {
  102. $group->idnumber = '';
  103. }
  104. $groups[] = (array)$group;
  105. }
  106. $transaction->allow_commit();
  107. return $groups;
  108. }
  109. /**
  110. * Returns description of method result value
  111. *
  112. * @return external_description
  113. * @since Moodle 2.2
  114. */
  115. public static function create_groups_returns() {
  116. return new external_multiple_structure(
  117. new external_single_structure(
  118. array(
  119. 'id' => new external_value(PARAM_INT, 'group record id'),
  120. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  121. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  122. 'description' => new external_value(PARAM_RAW, 'group description text'),
  123. 'descriptionformat' => new external_format_value('description'),
  124. 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
  125. 'idnumber' => new external_value(PARAM_RAW, 'id number')
  126. )
  127. ), 'List of group object. A group has an id, a courseid, a name, a description and an enrolment key.'
  128. );
  129. }
  130. /**
  131. * Returns description of method parameters
  132. *
  133. * @return external_function_parameters
  134. * @since Moodle 2.2
  135. */
  136. public static function get_groups_parameters() {
  137. return new external_function_parameters(
  138. array(
  139. 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')
  140. ,'List of group id. A group id is an integer.'),
  141. )
  142. );
  143. }
  144. /**
  145. * Get groups definition specified by ids
  146. *
  147. * @param array $groupids arrays of group ids
  148. * @return array of group objects (id, courseid, name, enrolmentkey)
  149. * @since Moodle 2.2
  150. */
  151. public static function get_groups($groupids) {
  152. $params = self::validate_parameters(self::get_groups_parameters(), array('groupids'=>$groupids));
  153. $groups = array();
  154. foreach ($params['groupids'] as $groupid) {
  155. // validate params
  156. $group = groups_get_group($groupid, 'id, courseid, name, idnumber, description, descriptionformat, enrolmentkey', MUST_EXIST);
  157. // now security checks
  158. $context = context_course::instance($group->courseid, IGNORE_MISSING);
  159. try {
  160. self::validate_context($context);
  161. } catch (Exception $e) {
  162. $exceptionparam = new stdClass();
  163. $exceptionparam->message = $e->getMessage();
  164. $exceptionparam->courseid = $group->courseid;
  165. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  166. }
  167. require_capability('moodle/course:managegroups', $context);
  168. list($group->description, $group->descriptionformat) =
  169. external_format_text($group->description, $group->descriptionformat,
  170. $context->id, 'group', 'description', $group->id);
  171. $groups[] = (array)$group;
  172. }
  173. return $groups;
  174. }
  175. /**
  176. * Returns description of method result value
  177. *
  178. * @return external_description
  179. * @since Moodle 2.2
  180. */
  181. public static function get_groups_returns() {
  182. return new external_multiple_structure(
  183. new external_single_structure(
  184. array(
  185. 'id' => new external_value(PARAM_INT, 'group record id'),
  186. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  187. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  188. 'description' => new external_value(PARAM_RAW, 'group description text'),
  189. 'descriptionformat' => new external_format_value('description'),
  190. 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
  191. 'idnumber' => new external_value(PARAM_RAW, 'id number')
  192. )
  193. )
  194. );
  195. }
  196. /**
  197. * Returns description of method parameters
  198. *
  199. * @return external_function_parameters
  200. * @since Moodle 2.2
  201. */
  202. public static function get_course_groups_parameters() {
  203. return new external_function_parameters(
  204. array(
  205. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  206. )
  207. );
  208. }
  209. /**
  210. * Get all groups in the specified course
  211. *
  212. * @param int $courseid id of course
  213. * @return array of group objects (id, courseid, name, enrolmentkey)
  214. * @since Moodle 2.2
  215. */
  216. public static function get_course_groups($courseid) {
  217. $params = self::validate_parameters(self::get_course_groups_parameters(), array('courseid'=>$courseid));
  218. // now security checks
  219. $context = context_course::instance($params['courseid'], IGNORE_MISSING);
  220. try {
  221. self::validate_context($context);
  222. } catch (Exception $e) {
  223. $exceptionparam = new stdClass();
  224. $exceptionparam->message = $e->getMessage();
  225. $exceptionparam->courseid = $params['courseid'];
  226. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  227. }
  228. require_capability('moodle/course:managegroups', $context);
  229. $gs = groups_get_all_groups($params['courseid'], 0, 0,
  230. 'g.id, g.courseid, g.name, g.idnumber, g.description, g.descriptionformat, g.enrolmentkey');
  231. $groups = array();
  232. foreach ($gs as $group) {
  233. list($group->description, $group->descriptionformat) =
  234. external_format_text($group->description, $group->descriptionformat,
  235. $context->id, 'group', 'description', $group->id);
  236. $groups[] = (array)$group;
  237. }
  238. return $groups;
  239. }
  240. /**
  241. * Returns description of method result value
  242. *
  243. * @return external_description
  244. * @since Moodle 2.2
  245. */
  246. public static function get_course_groups_returns() {
  247. return new external_multiple_structure(
  248. new external_single_structure(
  249. array(
  250. 'id' => new external_value(PARAM_INT, 'group record id'),
  251. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  252. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  253. 'description' => new external_value(PARAM_RAW, 'group description text'),
  254. 'descriptionformat' => new external_format_value('description'),
  255. 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
  256. 'idnumber' => new external_value(PARAM_RAW, 'id number')
  257. )
  258. )
  259. );
  260. }
  261. /**
  262. * Returns description of method parameters
  263. *
  264. * @return external_function_parameters
  265. * @since Moodle 2.2
  266. */
  267. public static function delete_groups_parameters() {
  268. return new external_function_parameters(
  269. array(
  270. 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
  271. )
  272. );
  273. }
  274. /**
  275. * Delete groups
  276. *
  277. * @param array $groupids array of group ids
  278. * @since Moodle 2.2
  279. */
  280. public static function delete_groups($groupids) {
  281. global $CFG, $DB;
  282. require_once("$CFG->dirroot/group/lib.php");
  283. $params = self::validate_parameters(self::delete_groups_parameters(), array('groupids'=>$groupids));
  284. $transaction = $DB->start_delegated_transaction();
  285. foreach ($params['groupids'] as $groupid) {
  286. // validate params
  287. $groupid = validate_param($groupid, PARAM_INT);
  288. if (!$group = groups_get_group($groupid, '*', IGNORE_MISSING)) {
  289. // silently ignore attempts to delete nonexisting groups
  290. continue;
  291. }
  292. // now security checks
  293. $context = context_course::instance($group->courseid, IGNORE_MISSING);
  294. try {
  295. self::validate_context($context);
  296. } catch (Exception $e) {
  297. $exceptionparam = new stdClass();
  298. $exceptionparam->message = $e->getMessage();
  299. $exceptionparam->courseid = $group->courseid;
  300. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  301. }
  302. require_capability('moodle/course:managegroups', $context);
  303. groups_delete_group($group);
  304. }
  305. $transaction->allow_commit();
  306. }
  307. /**
  308. * Returns description of method result value
  309. *
  310. * @return null
  311. * @since Moodle 2.2
  312. */
  313. public static function delete_groups_returns() {
  314. return null;
  315. }
  316. /**
  317. * Returns description of method parameters
  318. *
  319. * @return external_function_parameters
  320. * @since Moodle 2.2
  321. */
  322. public static function get_group_members_parameters() {
  323. return new external_function_parameters(
  324. array(
  325. 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
  326. )
  327. );
  328. }
  329. /**
  330. * Return all members for a group
  331. *
  332. * @param array $groupids array of group ids
  333. * @return array with group id keys containing arrays of user ids
  334. * @since Moodle 2.2
  335. */
  336. public static function get_group_members($groupids) {
  337. $members = array();
  338. $params = self::validate_parameters(self::get_group_members_parameters(), array('groupids'=>$groupids));
  339. foreach ($params['groupids'] as $groupid) {
  340. // validate params
  341. $group = groups_get_group($groupid, 'id, courseid, name, enrolmentkey', MUST_EXIST);
  342. // now security checks
  343. $context = context_course::instance($group->courseid, IGNORE_MISSING);
  344. try {
  345. self::validate_context($context);
  346. } catch (Exception $e) {
  347. $exceptionparam = new stdClass();
  348. $exceptionparam->message = $e->getMessage();
  349. $exceptionparam->courseid = $group->courseid;
  350. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  351. }
  352. require_capability('moodle/course:managegroups', $context);
  353. $groupmembers = groups_get_members($group->id, 'u.id', 'lastname ASC, firstname ASC');
  354. $members[] = array('groupid'=>$groupid, 'userids'=>array_keys($groupmembers));
  355. }
  356. return $members;
  357. }
  358. /**
  359. * Returns description of method result value
  360. *
  361. * @return external_description
  362. * @since Moodle 2.2
  363. */
  364. public static function get_group_members_returns() {
  365. return new external_multiple_structure(
  366. new external_single_structure(
  367. array(
  368. 'groupid' => new external_value(PARAM_INT, 'group record id'),
  369. 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user id')),
  370. )
  371. )
  372. );
  373. }
  374. /**
  375. * Returns description of method parameters
  376. *
  377. * @return external_function_parameters
  378. * @since Moodle 2.2
  379. */
  380. public static function add_group_members_parameters() {
  381. return new external_function_parameters(
  382. array(
  383. 'members'=> new external_multiple_structure(
  384. new external_single_structure(
  385. array(
  386. 'groupid' => new external_value(PARAM_INT, 'group record id'),
  387. 'userid' => new external_value(PARAM_INT, 'user id'),
  388. )
  389. )
  390. )
  391. )
  392. );
  393. }
  394. /**
  395. * Add group members
  396. *
  397. * @param array $members of arrays with keys userid, groupid
  398. * @since Moodle 2.2
  399. */
  400. public static function add_group_members($members) {
  401. global $CFG, $DB;
  402. require_once("$CFG->dirroot/group/lib.php");
  403. $params = self::validate_parameters(self::add_group_members_parameters(), array('members'=>$members));
  404. $transaction = $DB->start_delegated_transaction();
  405. foreach ($params['members'] as $member) {
  406. // validate params
  407. $groupid = $member['groupid'];
  408. $userid = $member['userid'];
  409. $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
  410. $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
  411. // now security checks
  412. $context = context_course::instance($group->courseid, IGNORE_MISSING);
  413. try {
  414. self::validate_context($context);
  415. } catch (Exception $e) {
  416. $exceptionparam = new stdClass();
  417. $exceptionparam->message = $e->getMessage();
  418. $exceptionparam->courseid = $group->courseid;
  419. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  420. }
  421. require_capability('moodle/course:managegroups', $context);
  422. // now make sure user is enrolled in course - this is mandatory requirement,
  423. // unfortunately this is slow
  424. if (!is_enrolled($context, $userid)) {
  425. throw new invalid_parameter_exception('Only enrolled users may be members of groups');
  426. }
  427. groups_add_member($group, $user);
  428. }
  429. $transaction->allow_commit();
  430. }
  431. /**
  432. * Returns description of method result value
  433. *
  434. * @return null
  435. * @since Moodle 2.2
  436. */
  437. public static function add_group_members_returns() {
  438. return null;
  439. }
  440. /**
  441. * Returns description of method parameters
  442. *
  443. * @return external_function_parameters
  444. * @since Moodle 2.2
  445. */
  446. public static function delete_group_members_parameters() {
  447. return new external_function_parameters(
  448. array(
  449. 'members'=> new external_multiple_structure(
  450. new external_single_structure(
  451. array(
  452. 'groupid' => new external_value(PARAM_INT, 'group record id'),
  453. 'userid' => new external_value(PARAM_INT, 'user id'),
  454. )
  455. )
  456. )
  457. )
  458. );
  459. }
  460. /**
  461. * Delete group members
  462. *
  463. * @param array $members of arrays with keys userid, groupid
  464. * @since Moodle 2.2
  465. */
  466. public static function delete_group_members($members) {
  467. global $CFG, $DB;
  468. require_once("$CFG->dirroot/group/lib.php");
  469. $params = self::validate_parameters(self::delete_group_members_parameters(), array('members'=>$members));
  470. $transaction = $DB->start_delegated_transaction();
  471. foreach ($params['members'] as $member) {
  472. // validate params
  473. $groupid = $member['groupid'];
  474. $userid = $member['userid'];
  475. $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
  476. $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
  477. // now security checks
  478. $context = context_course::instance($group->courseid, IGNORE_MISSING);
  479. try {
  480. self::validate_context($context);
  481. } catch (Exception $e) {
  482. $exceptionparam = new stdClass();
  483. $exceptionparam->message = $e->getMessage();
  484. $exceptionparam->courseid = $group->courseid;
  485. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  486. }
  487. require_capability('moodle/course:managegroups', $context);
  488. if (!groups_remove_member_allowed($group, $user)) {
  489. throw new moodle_exception('errorremovenotpermitted', 'group', '', fullname($user));
  490. }
  491. groups_remove_member($group, $user);
  492. }
  493. $transaction->allow_commit();
  494. }
  495. /**
  496. * Returns description of method result value
  497. *
  498. * @return null
  499. * @since Moodle 2.2
  500. */
  501. public static function delete_group_members_returns() {
  502. return null;
  503. }
  504. /**
  505. * Returns description of method parameters
  506. *
  507. * @return external_function_parameters
  508. * @since Moodle 2.3
  509. */
  510. public static function create_groupings_parameters() {
  511. return new external_function_parameters(
  512. array(
  513. 'groupings' => new external_multiple_structure(
  514. new external_single_structure(
  515. array(
  516. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  517. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  518. 'description' => new external_value(PARAM_RAW, 'grouping description text'),
  519. 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
  520. 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL)
  521. )
  522. ), 'List of grouping object. A grouping has a courseid, a name and a description.'
  523. )
  524. )
  525. );
  526. }
  527. /**
  528. * Create groupings
  529. *
  530. * @param array $groupings array of grouping description arrays (with keys groupname and courseid)
  531. * @return array of newly created groupings
  532. * @since Moodle 2.3
  533. */
  534. public static function create_groupings($groupings) {
  535. global $CFG, $DB;
  536. require_once("$CFG->dirroot/group/lib.php");
  537. $params = self::validate_parameters(self::create_groupings_parameters(), array('groupings'=>$groupings));
  538. $transaction = $DB->start_delegated_transaction();
  539. $groupings = array();
  540. foreach ($params['groupings'] as $grouping) {
  541. $grouping = (object)$grouping;
  542. if (trim($grouping->name) == '') {
  543. throw new invalid_parameter_exception('Invalid grouping name');
  544. }
  545. if ($DB->count_records('groupings', array('courseid'=>$grouping->courseid, 'name'=>$grouping->name))) {
  546. throw new invalid_parameter_exception('Grouping with the same name already exists in the course');
  547. }
  548. if (!empty($grouping->idnumber) && $DB->count_records('groupings', array('idnumber' => $grouping->idnumber))) {
  549. throw new invalid_parameter_exception('Grouping with the same idnumber already exists');
  550. }
  551. // Now security checks .
  552. $context = context_course::instance($grouping->courseid);
  553. try {
  554. self::validate_context($context);
  555. } catch (Exception $e) {
  556. $exceptionparam = new stdClass();
  557. $exceptionparam->message = $e->getMessage();
  558. $exceptionparam->courseid = $grouping->courseid;
  559. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  560. }
  561. require_capability('moodle/course:managegroups', $context);
  562. $grouping->descriptionformat = external_validate_format($grouping->descriptionformat);
  563. // Finally create the grouping.
  564. $grouping->id = groups_create_grouping($grouping);
  565. $groupings[] = (array)$grouping;
  566. }
  567. $transaction->allow_commit();
  568. return $groupings;
  569. }
  570. /**
  571. * Returns description of method result value
  572. *
  573. * @return external_description
  574. * @since Moodle 2.3
  575. */
  576. public static function create_groupings_returns() {
  577. return new external_multiple_structure(
  578. new external_single_structure(
  579. array(
  580. 'id' => new external_value(PARAM_INT, 'grouping record id'),
  581. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  582. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  583. 'description' => new external_value(PARAM_RAW, 'grouping description text'),
  584. 'descriptionformat' => new external_format_value('description'),
  585. 'idnumber' => new external_value(PARAM_RAW, 'id number')
  586. )
  587. ), 'List of grouping object. A grouping has an id, a courseid, a name and a description.'
  588. );
  589. }
  590. /**
  591. * Returns description of method parameters
  592. *
  593. * @return external_function_parameters
  594. * @since Moodle 2.3
  595. */
  596. public static function update_groupings_parameters() {
  597. return new external_function_parameters(
  598. array(
  599. 'groupings' => new external_multiple_structure(
  600. new external_single_structure(
  601. array(
  602. 'id' => new external_value(PARAM_INT, 'id of grouping'),
  603. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  604. 'description' => new external_value(PARAM_RAW, 'grouping description text'),
  605. 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
  606. 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL)
  607. )
  608. ), 'List of grouping object. A grouping has a courseid, a name and a description.'
  609. )
  610. )
  611. );
  612. }
  613. /**
  614. * Update groupings
  615. *
  616. * @param array $groupings array of grouping description arrays (with keys groupname and courseid)
  617. * @return array of newly updated groupings
  618. * @since Moodle 2.3
  619. */
  620. public static function update_groupings($groupings) {
  621. global $CFG, $DB;
  622. require_once("$CFG->dirroot/group/lib.php");
  623. $params = self::validate_parameters(self::update_groupings_parameters(), array('groupings'=>$groupings));
  624. $transaction = $DB->start_delegated_transaction();
  625. foreach ($params['groupings'] as $grouping) {
  626. $grouping = (object)$grouping;
  627. if (trim($grouping->name) == '') {
  628. throw new invalid_parameter_exception('Invalid grouping name');
  629. }
  630. if (! $currentgrouping = $DB->get_record('groupings', array('id'=>$grouping->id))) {
  631. throw new invalid_parameter_exception("Grouping $grouping->id does not exist in the course");
  632. }
  633. // Check if the new modified grouping name already exists in the course.
  634. if ($grouping->name != $currentgrouping->name and
  635. $DB->count_records('groupings', array('courseid'=>$currentgrouping->courseid, 'name'=>$grouping->name))) {
  636. throw new invalid_parameter_exception('A different grouping with the same name already exists in the course');
  637. }
  638. // Check if the new modified grouping idnumber already exists.
  639. if (!empty($grouping->idnumber) && $grouping->idnumber != $currentgrouping->idnumber &&
  640. $DB->count_records('groupings', array('idnumber' => $grouping->idnumber))) {
  641. throw new invalid_parameter_exception('A different grouping with the same idnumber already exists');
  642. }
  643. $grouping->courseid = $currentgrouping->courseid;
  644. // Now security checks.
  645. $context = context_course::instance($grouping->courseid);
  646. try {
  647. self::validate_context($context);
  648. } catch (Exception $e) {
  649. $exceptionparam = new stdClass();
  650. $exceptionparam->message = $e->getMessage();
  651. $exceptionparam->courseid = $grouping->courseid;
  652. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  653. }
  654. require_capability('moodle/course:managegroups', $context);
  655. // We must force allways FORMAT_HTML.
  656. $grouping->descriptionformat = external_validate_format($grouping->descriptionformat);
  657. // Finally update the grouping.
  658. groups_update_grouping($grouping);
  659. }
  660. $transaction->allow_commit();
  661. return null;
  662. }
  663. /**
  664. * Returns description of method result value
  665. *
  666. * @return external_description
  667. * @since Moodle 2.3
  668. */
  669. public static function update_groupings_returns() {
  670. return null;
  671. }
  672. /**
  673. * Returns description of method parameters
  674. *
  675. * @return external_function_parameters
  676. * @since Moodle 2.3
  677. */
  678. public static function get_groupings_parameters() {
  679. return new external_function_parameters(
  680. array(
  681. 'groupingids' => new external_multiple_structure(new external_value(PARAM_INT, 'grouping ID')
  682. , 'List of grouping id. A grouping id is an integer.'),
  683. 'returngroups' => new external_value(PARAM_BOOL, 'return associated groups', VALUE_DEFAULT, 0)
  684. )
  685. );
  686. }
  687. /**
  688. * Get groupings definition specified by ids
  689. *
  690. * @param array $groupingids arrays of grouping ids
  691. * @param boolean $returngroups return the associated groups if true. The default is false.
  692. * @return array of grouping objects (id, courseid, name)
  693. * @since Moodle 2.3
  694. */
  695. public static function get_groupings($groupingids, $returngroups = false) {
  696. global $CFG, $DB;
  697. require_once("$CFG->dirroot/group/lib.php");
  698. require_once("$CFG->libdir/filelib.php");
  699. $params = self::validate_parameters(self::get_groupings_parameters(),
  700. array('groupingids' => $groupingids,
  701. 'returngroups' => $returngroups));
  702. $groupings = array();
  703. foreach ($params['groupingids'] as $groupingid) {
  704. // Validate params.
  705. $grouping = groups_get_grouping($groupingid, '*', MUST_EXIST);
  706. // Now security checks.
  707. $context = context_course::instance($grouping->courseid);
  708. try {
  709. self::validate_context($context);
  710. } catch (Exception $e) {
  711. $exceptionparam = new stdClass();
  712. $exceptionparam->message = $e->getMessage();
  713. $exceptionparam->courseid = $grouping->courseid;
  714. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  715. }
  716. require_capability('moodle/course:managegroups', $context);
  717. list($grouping->description, $grouping->descriptionformat) =
  718. external_format_text($grouping->description, $grouping->descriptionformat,
  719. $context->id, 'grouping', 'description', $grouping->id);
  720. $groupingarray = (array)$grouping;
  721. if ($params['returngroups']) {
  722. $grouprecords = $DB->get_records_sql("SELECT * FROM {groups} g INNER JOIN {groupings_groups} gg ".
  723. "ON g.id = gg.groupid WHERE gg.groupingid = ? ".
  724. "ORDER BY groupid", array($groupingid));
  725. if ($grouprecords) {
  726. $groups = array();
  727. foreach ($grouprecords as $grouprecord) {
  728. list($grouprecord->description, $grouprecord->descriptionformat) =
  729. external_format_text($grouprecord->description, $grouprecord->descriptionformat,
  730. $context->id, 'group', 'description', $grouprecord->groupid);
  731. $groups[] = array('id' => $grouprecord->groupid,
  732. 'name' => $grouprecord->name,
  733. 'idnumber' => $grouprecord->idnumber,
  734. 'description' => $grouprecord->description,
  735. 'descriptionformat' => $grouprecord->descriptionformat,
  736. 'enrolmentkey' => $grouprecord->enrolmentkey,
  737. 'courseid' => $grouprecord->courseid
  738. );
  739. }
  740. $groupingarray['groups'] = $groups;
  741. }
  742. }
  743. $groupings[] = $groupingarray;
  744. }
  745. return $groupings;
  746. }
  747. /**
  748. * Returns description of method result value
  749. *
  750. * @return external_description
  751. * @since Moodle 2.3
  752. */
  753. public static function get_groupings_returns() {
  754. return new external_multiple_structure(
  755. new external_single_structure(
  756. array(
  757. 'id' => new external_value(PARAM_INT, 'grouping record id'),
  758. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  759. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  760. 'description' => new external_value(PARAM_RAW, 'grouping description text'),
  761. 'descriptionformat' => new external_format_value('description'),
  762. 'idnumber' => new external_value(PARAM_RAW, 'id number'),
  763. 'groups' => new external_multiple_structure(
  764. new external_single_structure(
  765. array(
  766. 'id' => new external_value(PARAM_INT, 'group record id'),
  767. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  768. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  769. 'description' => new external_value(PARAM_RAW, 'group description text'),
  770. 'descriptionformat' => new external_format_value('description'),
  771. 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
  772. 'idnumber' => new external_value(PARAM_RAW, 'id number')
  773. )
  774. ),
  775. 'optional groups', VALUE_OPTIONAL)
  776. )
  777. )
  778. );
  779. }
  780. /**
  781. * Returns description of method parameters
  782. *
  783. * @return external_function_parameters
  784. * @since Moodle 2.3
  785. */
  786. public static function get_course_groupings_parameters() {
  787. return new external_function_parameters(
  788. array(
  789. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  790. )
  791. );
  792. }
  793. /**
  794. * Get all groupings in the specified course
  795. *
  796. * @param int $courseid id of course
  797. * @return array of grouping objects (id, courseid, name, enrolmentkey)
  798. * @since Moodle 2.3
  799. */
  800. public static function get_course_groupings($courseid) {
  801. global $CFG;
  802. require_once("$CFG->dirroot/group/lib.php");
  803. require_once("$CFG->libdir/filelib.php");
  804. $params = self::validate_parameters(self::get_course_groupings_parameters(), array('courseid'=>$courseid));
  805. // Now security checks.
  806. $context = context_course::instance($params['courseid']);
  807. try {
  808. self::validate_context($context);
  809. } catch (Exception $e) {
  810. $exceptionparam = new stdClass();
  811. $exceptionparam->message = $e->getMessage();
  812. $exceptionparam->courseid = $params['courseid'];
  813. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  814. }
  815. require_capability('moodle/course:managegroups', $context);
  816. $gs = groups_get_all_groupings($params['courseid']);
  817. $groupings = array();
  818. foreach ($gs as $grouping) {
  819. list($grouping->description, $grouping->descriptionformat) =
  820. external_format_text($grouping->description, $grouping->descriptionformat,
  821. $context->id, 'grouping', 'description', $grouping->id);
  822. $groupings[] = (array)$grouping;
  823. }
  824. return $groupings;
  825. }
  826. /**
  827. * Returns description of method result value
  828. *
  829. * @return external_description
  830. * @since Moodle 2.3
  831. */
  832. public static function get_course_groupings_returns() {
  833. return new external_multiple_structure(
  834. new external_single_structure(
  835. array(
  836. 'id' => new external_value(PARAM_INT, 'grouping record id'),
  837. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  838. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  839. 'description' => new external_value(PARAM_RAW, 'grouping description text'),
  840. 'descriptionformat' => new external_format_value('description'),
  841. 'idnumber' => new external_value(PARAM_RAW, 'id number')
  842. )
  843. )
  844. );
  845. }
  846. /**
  847. * Returns description of method parameters
  848. *
  849. * @return external_function_parameters
  850. * @since Moodle 2.3
  851. */
  852. public static function delete_groupings_parameters() {
  853. return new external_function_parameters(
  854. array(
  855. 'groupingids' => new external_multiple_structure(new external_value(PARAM_INT, 'grouping ID')),
  856. )
  857. );
  858. }
  859. /**
  860. * Delete groupings
  861. *
  862. * @param array $groupingids array of grouping ids
  863. * @return void
  864. * @since Moodle 2.3
  865. */
  866. public static function delete_groupings($groupingids) {
  867. global $CFG, $DB;
  868. require_once("$CFG->dirroot/group/lib.php");
  869. $params = self::validate_parameters(self::delete_groupings_parameters(), array('groupingids'=>$groupingids));
  870. $transaction = $DB->start_delegated_transaction();
  871. foreach ($params['groupingids'] as $groupingid) {
  872. if (!$grouping = groups_get_grouping($groupingid, 'id, courseid', IGNORE_MISSING)) {
  873. // Silently ignore attempts to delete nonexisting groupings.
  874. continue;
  875. }
  876. // Now security checks.
  877. $context = context_course::instance($grouping->courseid);
  878. try {
  879. self::validate_context($context);
  880. } catch (Exception $e) {
  881. $exceptionparam = new stdClass();
  882. $exceptionparam->message = $e->getMessage();
  883. $exceptionparam->courseid = $grouping->courseid;
  884. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  885. }
  886. require_capability('moodle/course:managegroups', $context);
  887. groups_delete_grouping($grouping);
  888. }
  889. $transaction->allow_commit();
  890. }
  891. /**
  892. * Returns description of method result value
  893. *
  894. * @return external_description
  895. * @since Moodle 2.3
  896. */
  897. public static function delete_groupings_returns() {
  898. return null;
  899. }
  900. /**
  901. * Returns description of method parameters
  902. *
  903. * @return external_function_parameters
  904. * @since Moodle 2.3
  905. */
  906. public static function assign_grouping_parameters() {
  907. return new external_function_parameters(
  908. array(
  909. 'assignments'=> new external_multiple_structure(
  910. new external_single_structure(
  911. array(
  912. 'groupingid' => new external_value(PARAM_INT, 'grouping record id'),
  913. 'groupid' => new external_value(PARAM_INT, 'group record id'),
  914. )
  915. )
  916. )
  917. )
  918. );
  919. }
  920. /**
  921. * Assign a group to a grouping
  922. *
  923. * @param array $assignments of arrays with keys groupid, groupingid
  924. * @return void
  925. * @since Moodle 2.3
  926. */
  927. public static function assign_grouping($assignments) {
  928. global $CFG, $DB;
  929. require_once("$CFG->dirroot/group/lib.php");
  930. $params = self::validate_parameters(self::assign_grouping_parameters(), array('assignments'=>$assignments));
  931. $transaction = $DB->start_delegated_transaction();
  932. foreach ($params['assignments'] as $assignment) {
  933. // Validate params.
  934. $groupingid = $assignment['groupingid'];
  935. $groupid = $assignment['groupid'];
  936. $grouping = groups_get_grouping($groupingid, 'id, courseid', MUST_EXIST);
  937. $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
  938. if ($DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) {
  939. // Continue silently if the group is yet assigned to the grouping.
  940. continue;
  941. }
  942. // Now security checks.
  943. $context = context_course::instance($grouping->courseid);
  944. try {
  945. self::validate_context($context);
  946. } catch (Exception $e) {
  947. $exceptionparam = new stdClass();
  948. $exceptionparam->message = $e->getMessage();
  949. $exceptionparam->courseid = $group->courseid;
  950. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  951. }
  952. require_capability('moodle/course:managegroups', $context);
  953. groups_assign_grouping($groupingid, $groupid);
  954. }
  955. $transaction->allow_commit();
  956. }
  957. /**
  958. * Returns description of method result value
  959. *
  960. * @return null
  961. * @since Moodle 2.3
  962. */
  963. public static function assign_grouping_returns() {
  964. return null;
  965. }
  966. /**
  967. * Returns description of method parameters
  968. *
  969. * @return external_function_parameters
  970. * @since Moodle 2.3
  971. */
  972. public static function unassign_grouping_parameters() {
  973. return new external_function_parameters(
  974. array(
  975. 'unassignments'=> new external_multiple_structure(
  976. new external_single_structure(
  977. array(
  978. 'groupingid' => new external_value(PARAM_INT, 'grouping record id'),
  979. 'groupid' => new external_value(PARAM_INT, 'group record id'),
  980. )
  981. )
  982. )
  983. )
  984. );
  985. }
  986. /**
  987. * Unassign a group from a grouping
  988. *
  989. * @param array $unassignments of arrays with keys groupid, groupingid
  990. * @return void
  991. * @since Moodle 2.3
  992. */
  993. public static function unassign_grouping($unassignments) {
  994. global $CFG, $DB;
  995. require_once("$CFG->dirroot/group/lib.php");
  996. $params = self::validate_parameters(self::unassign_grouping_parameters(), array('unassignments'=>$unassignments));
  997. $transaction = $DB->start_delegated_transaction();
  998. foreach ($params['unassignments'] as $unassignment) {
  999. // Validate params.
  1000. $groupingid = $unassignment['groupingid'];
  1001. $groupid = $unassignment['groupid'];
  1002. $grouping = groups_get_grouping($groupingid, 'id, courseid', MUST_EXIST);
  1003. $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
  1004. if (!$DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) {
  1005. // Continue silently if the group is not assigned to the grouping.
  1006. continue;
  1007. }
  1008. // Now security checks.
  1009. $context = context_course::instance($grouping->courseid);
  1010. try {
  1011. self::validate_context($context);
  1012. } catch (Exception $e) {
  1013. $exceptionparam = new stdClass();
  1014. $exceptionparam->message = $e->getMessage();
  1015. $exceptionparam->courseid = $group->courseid;
  1016. throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
  1017. }
  1018. require_capability('moodle/course:managegroups', $context);
  1019. groups_unassign_grouping($groupingid, $groupid);
  1020. }
  1021. $transaction->allow_commit();
  1022. }
  1023. /**
  1024. * Returns description of method result value
  1025. *
  1026. * @return null
  1027. * @since Moodle 2.3
  1028. */
  1029. public static function unassign_grouping_returns() {
  1030. return null;
  1031. }
  1032. /**
  1033. * Returns description of method parameters
  1034. *
  1035. * @return external_function_parameters
  1036. * @since Moodle 2.9
  1037. */
  1038. public static function get_course_user_groups_parameters() {
  1039. return new external_function_parameters(
  1040. array(
  1041. 'courseid' => new external_value(PARAM_INT, 'id of course'),
  1042. 'userid' => new external_value(PARAM_INT, 'id of user'),
  1043. 'groupingid' => new external_value(PARAM_INT, 'returns only groups in the specified grouping', VALUE_DEFAULT, 0)
  1044. )
  1045. );
  1046. }
  1047. /**
  1048. * Get all groups in the specified course for the specified user.
  1049. *
  1050. * @throws moodle_exception
  1051. * @param int $courseid id of course.
  1052. * @param int $userid id of user.
  1053. * @param int $groupingid optional returns only groups in the specified grouping.
  1054. * @return array of group objects (id, name, description, format) and possible warnings.
  1055. * @since Moodle 2.9
  1056. */
  1057. public static function get_course_user_groups($courseid, $userid, $groupingid = 0) {
  1058. global $USER;
  1059. // Warnings array, it can be empty at the end but is mandatory.
  1060. $warnings = array();
  1061. $params = array(
  1062. 'courseid' => $courseid,
  1063. 'userid' => $userid,
  1064. 'groupingid' => $groupingid
  1065. );
  1066. $params = self::validate_parameters(self::get_course_user_groups_parameters(), $params);
  1067. $courseid = $params['courseid'];
  1068. $userid = $params['userid'];
  1069. $groupingid = $params['groupingid'];
  1070. // Validate course and user. get_course throws an exception if the course does not exists.
  1071. $course = get_course($courseid);
  1072. $user = core_user::get_user($userid, '*', MUST_EXIST);
  1073. core_user::require_active_user($user);
  1074. // Security checks.
  1075. $context = context_course::instance($course->id);
  1076. self::validate_context($context);
  1077. // Check if we have permissions for retrieve the information.
  1078. if ($user->id != $USER->id) {
  1079. if (!has_capability('moodle/course:managegroups', $context)) {
  1080. throw new moodle_exception('accessdenied', 'admin');
  1081. }
  1082. // Validate if the user is enrolled in the course.
  1083. if (!is_enrolled($context, $user->id)) {
  1084. // We return a warning because the function does not fail for not enrolled users.
  1085. $warning['item'] = 'course';
  1086. $warning['itemid'] = $course->id;
  1087. $warning['warningcode'] = '1';
  1088. $warning['message'] = "User $user->id is not enrolled in course $course->id";
  1089. $warnings[] = $warning;
  1090. }
  1091. }
  1092. $usergroups = array();
  1093. if (empty($warnings)) {
  1094. $groups = groups_get_all_groups($course->id, $user->id, 0, 'g.id, g.name, g.description, g.descriptionformat, g.idnumber');
  1095. foreach ($groups as $group) {
  1096. list($group->description, $group->descriptionformat) =
  1097. external_format_text($group->description, $group->descriptionformat,
  1098. $context->id, 'group', 'description', $group->id);
  1099. $group->courseid = $course->id;
  1100. $usergroups[] = $group;
  1101. }
  1102. }
  1103. $results = array(
  1104. 'groups' => $usergroups,
  1105. 'warnings' => $warnings
  1106. );
  1107. return $results;
  1108. }
  1109. /**
  1110. * Returns description of method result value.
  1111. *
  1112. * @return external_description A single structure containing groups and possible warnings.
  1113. * @since Moodle 2.9
  1114. */
  1115. public static function get_course_user_groups_returns() {
  1116. return new external_single_structure(
  1117. array(
  1118. 'groups' => new external_multiple_structure(self::group_description()),
  1119. 'warnings' => new external_warnings(),
  1120. )
  1121. );
  1122. }
  1123. /**
  1124. * Create group return value description.
  1125. *
  1126. * @return external_single_structure The group description
  1127. */
  1128. public static function group_description() {
  1129. return new external_single_structure(
  1130. array(
  1131. 'id' => new external_value(PARAM_INT, 'group record id'),
  1132. 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
  1133. 'description' => new external_value(PARAM_RAW, 'group description text'),
  1134. 'descriptionformat' => new external_format_value('description'),
  1135. 'idnumber' => new external_value(PARAM_RAW, 'id number'),
  1136. 'courseid' => new external_value(PARAM_INT, 'course id', VALUE_OPTIONAL),
  1137. )
  1138. );
  1139. }
  1140. /**
  1141. * Returns description of method parameters
  1142. *
  1143. * @return external_function_parameters
  1144. * @since Moodle 3.0
  1145. */
  1146. public static function get_activity_allowed_groups_parameters() {
  1147. return new external_function_parameters(
  1148. array(
  1149. 'cmid' => new external_value(PARAM_INT, 'course module id'),
  1150. 'userid' => new external_value(PARAM_INT, 'id of user, empty for current user', VALUE_DEFAULT, 0)
  1151. )
  1152. );
  1153. }
  1154. /**
  1155. * Gets a list of groups that the user is allowed to access within the specified activity.
  1156. *
  1157. * @throws moodle_exception
  1158. * @param int $cmid course module id
  1159. * @param int $userid id of user.
  1160. * @return array of group objects (id, name, description, format) and possible warnings.
  1161. * @since Moodle 3.0
  1162. */
  1163. public static function get_activity_allowed_groups($cmid, $userid = 0) {
  1164. global $USER;
  1165. // Warnings array, it can be empty at the end but is mandatory.
  1166. $warnings = array();
  1167. $params = array(
  1168. 'cmid' => $cmid,
  1169. 'userid' => $userid
  1170. );
  1171. $params = self::validate_parameters(self::get_activity_allowed_groups_parameters(), $params);
  1172. $cmid = $params['cmid'];
  1173. $userid = $params['userid'];
  1174. $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
  1175. // Security checks.
  1176. $context = context_module::instance($cm->id);
  1177. $coursecontext = context_course::instance($cm->course);
  1178. self::validate_context($context);
  1179. if (empty($userid)) {
  1180. $userid = $USER->id;
  1181. }
  1182. $user = core_user::get_user($userid, '*', MUST_EXIST);
  1183. core_user::require_active_user($user);
  1184. // Check if we have permissions for retrieve the information.
  1185. if ($user->id != $USER->id) {
  1186. if (!has_capability('moodle/course:managegroups', $context)) {
  1187. throw new moodle_exception('accessdenied', 'admin');
  1188. }
  1189. // Validate if the user is enrolled in the course.
  1190. $course = get_course($cm->course);
  1191. if (!can_access_course($course, $user, '', true)) {
  1192. // We return a warning because the function does not fail for not enrolled users.
  1193. $warning = array();
  1194. $warning['item'] = 'course';
  1195. $warning['itemid'] = $cm->course;
  1196. $warning['warningcode'] = '1';
  1197. $warning['message'] = "User $user->id cannot access course $cm->course";
  1198. $warnings[] = $warning;
  1199. }
  1200. }
  1201. $usergroups = array();
  1202. if (empty($warnings)) {
  1203. $groups = groups_get_activity_allowed_groups($cm, $user->id);
  1204. foreach ($groups as $group) {
  1205. list($group->description, $group->descriptionformat) =
  1206. external_format_text($group->description, $group->descriptionformat,
  1207. $coursecontext->id, 'group', 'description', $group->id);
  1208. $group->courseid = $cm->course;
  1209. $usergroups[] = $group;
  1210. }
  1211. }
  1212. $results = array(
  1213. 'groups' => $usergroups,
  1214. 'warnings' => $warnings
  1215. );
  1216. return $results;
  1217. }
  1218. /**
  1219. * Returns description of method result value.
  1220. *
  1221. * @return external_description A single structure containing groups and possible warnings.
  1222. * @since Moodle 3.0
  1223. */
  1224. public static function get_activity_allowed_groups_returns() {
  1225. return new external_single_structure(
  1226. array(
  1227. 'groups' => new external_multiple_structure(self::group_description()),
  1228. 'warnings' => new external_warnings(),
  1229. )
  1230. );
  1231. }
  1232. /**
  1233. * Returns description of method parameters
  1234. *
  1235. * @return external_function_parameters
  1236. * @since Moodle 3.0
  1237. */
  1238. public static function get_activity_groupmode_parameters() {
  1239. return new external_function_parameters(
  1240. array(
  1241. 'cmid' => new external_value(PARAM_INT, 'course module id')
  1242. )
  1243. );
  1244. }
  1245. /**
  1246. * Returns effective groupmode used in a given activity.
  1247. *
  1248. * @throws moodle_exception
  1249. * @param int $cmid course module id.
  1250. * @return array containing the group mode and possible warnings.
  1251. * @since Moodle 3.0
  1252. * @throws moodle_exception
  1253. */
  1254. public static function get_activity_groupmode($cmid) {
  1255. global $USER;
  1256. // Warnings array, it can be empty at the end but is mandatory.
  1257. $warnings = array();
  1258. $params = array(
  1259. 'cmid' => $cmid
  1260. );
  1261. $params = self::validate_parameters(self::get_activity_groupmode_parameters(), $params);
  1262. $cmid = $params['cmid'];
  1263. $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
  1264. // Security checks.
  1265. $context = context_module::instance($cm->id);
  1266. self::validate_context($context);
  1267. $groupmode = groups_get_activity_groupmode($cm);
  1268. $results = array(
  1269. 'groupmode' => $groupmode,
  1270. 'warnings' => $warnings
  1271. );
  1272. return $results;
  1273. }
  1274. /**
  1275. * Returns description of method result value.
  1276. *
  1277. * @return external_description
  1278. * @since Moodle 3.0
  1279. */
  1280. public static function get_activity_groupmode_returns() {
  1281. return new external_single_structure(
  1282. array(
  1283. 'groupmode' => new external_value(PARAM_INT, 'group mode:
  1284. 0 for no groups, 1 for separate groups, 2 for visible groups'),
  1285. 'warnings' => new external_warnings(),
  1286. )
  1287. );
  1288. }
  1289. }