PageRenderTime 90ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/wspp/server.class.php

https://bitbucket.org/systime/screening2
PHP | 4139 lines | 2808 code | 451 blank | 880 comment | 600 complexity | 0da73627ea8e2c09e55977d9d50ec4d5 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, GPL-3.0, BSD-3-Clause, LGPL-2.0
  1. <?php
  2. // $Id: server.class.php,v 1.14 2010/10/26 13:50:10 ppollet Exp $
  3. /**
  4. * Base class for web services server layer. PP 5 ONLY.
  5. *
  6. * @package Web Services
  7. * @version $Id: server.class.php,v 1.14 2010/10/26 13:50:10 ppollet Exp $
  8. * @author Open Knowledge Technologies - http://www.oktech.ca/
  9. * @author Justin Filip <jfilip@oktech.ca> v 1.4
  10. * @author Patrick Pollet <patrick.pollet@insa-lyon.fr> v 1.5, v 1.6, v 1.7
  11. * @author
  12. */
  13. /* rev history
  14. @see revisions.txt
  15. **/
  16. require_once ('../config.php');
  17. require_once ('wslib.php');
  18. require_once ('filterlib.php');
  19. /// increase memory limit (PHP 5.2 does different calculation, we need more memory now)
  20. // j'ai 11000 comptes
  21. @ raise_memory_limit("192M"); //fonction de lib/setuplib.php incluse via config.php
  22. //set_time_limit(0);
  23. //define('DEBUG', true); rev. 1.5.16 already set (or not) in MoodleWS.php
  24. define('cal_show_global', 1);
  25. define('cal_show_course', 2);
  26. define('cal_show_group', 4);
  27. define('cal_show_user', 8);
  28. /**
  29. * The main server class.
  30. *
  31. * The only methods that need to be extended in a child class are error() and any of
  32. * the service methods which need special transport-protocol specific handling of
  33. * input and / or output data (ie non simple type returns)
  34. *
  35. */
  36. class server {
  37. var $version = 2010101000; // also Moodle 2.0 compatible
  38. var $using17;
  39. var $using19 = false;
  40. /**
  41. * Constructor method.
  42. *
  43. * @uses $CFG
  44. * @param none
  45. * @return none
  46. */
  47. function server () {
  48. global $CFG;
  49. $this->debug_output("Server init...");
  50. $this->debug_output(' Version: ' . $this->version);
  51. $this->debug_output(' Session Timeout: ' . $this->sessiontimeout);
  52. if (! $CFG->wspp_using_moodle20) {
  53. $this->using17 = file_exists($CFG->libdir . '/accesslib.php');
  54. $this->using19 = file_exists($CFG->libdir . '/grouplib.php');
  55. //Check for any DB upgrades.
  56. if (empty ($CFG->webservices_version)) {
  57. $this->upgrade(0);
  58. } else
  59. if ($CFG->webservices_version < $this->version) {
  60. $this->upgrade($CFG->webservices_version);
  61. }
  62. } else {
  63. $this->using17 = $this->using19 = true;
  64. }
  65. // setup default values if not set in admin screens (see admin/wspp.php)
  66. if (empty ($CFG->ws_sessiontimeout))
  67. $CFG->ws_sessiontimeout = 1800;
  68. $this->sessiontimeout = $CFG->ws_sessiontimeout;
  69. if (!isset ($CFG->ws_logoperations))
  70. $CFG->ws_logoperations = 1;
  71. if (!isset ($CFG->ws_logerrors))
  72. $CFG->ws_logerrors = 0;
  73. if (!isset ($CFG->ws_logdetailedoperations))
  74. $CFG->ws_logdetailledoperations = 0;
  75. if (!isset ($CFG->ws_debug))
  76. $CFG->ws_debug = 0;
  77. if (!isset ($CFG->ws_enforceipcheck))
  78. $CFG->ws_enforceipcheck = 0; // rev 1.6.1 off by default++++
  79. }
  80. /**
  81. * Performs an upgrade of the webservices system.
  82. * Moodle < 2.0 ONLY
  83. * @uses $CFG
  84. * @param int $oldversion The old version number we are upgrading from.
  85. * @return boolean True if successful, False otherwise.
  86. */
  87. private function upgrade($oldversion) {
  88. global $CFG;
  89. if ($CFG->wspp_using_moodle20)
  90. return $this->error(get_string('ws_not_installed_moodle20', 'local_wspp'));
  91. $this->debug_output('Starting WS upgrade from version ' . $oldversion . 'to version ' . $this->version);
  92. $return = true;
  93. require_once ($CFG->libdir . '/ddllib.php');
  94. if ($oldversion < 2006050800) {
  95. $return = install_from_xmldb_file($CFG->dirroot . '/wspp/db/install.xml');
  96. } else {
  97. if ($oldversion < 2007051000) {
  98. $table = new XMLDBTable('webservices_sessions');
  99. $field = new XMLDBField('ip');
  100. // since table exists, keep NULL as true and no default value !
  101. // otherwise XMLDB do not do the change but return true ...
  102. $field->setAttributes(XMLDB_TYPE_CHAR, '64');
  103. $return = add_field($table, $field, false, false);
  104. }
  105. }
  106. if ($return) {
  107. set_config('webservices_version', $this->version);
  108. $this->debug_output('Upgraded from ' . $oldversion . ' to ' . $this->version);
  109. } else {
  110. $this->debug_output('ERROR: Could not upgrade to version ' . $this->version);
  111. }
  112. return $return;
  113. }
  114. /**
  115. * Creates a new session key.
  116. *
  117. * @param none
  118. * @return string A 32 character session key.
  119. */
  120. private function add_session_key() {
  121. $time = (string) time();
  122. $randstr = (string) random_string(10);
  123. /// XOR the current time and a random string.
  124. $str = $time;
  125. $str ^= $randstr;
  126. /// Use the MD5 sum of this random 10 character string as the session key.
  127. return md5($str);
  128. }
  129. /**
  130. * Validate's that a client has an existing session.
  131. *
  132. * @param int $client The client session ID.
  133. * @param string $sesskey The client session key.
  134. * @return boolean True if the client is valid, False otherwise.
  135. */
  136. private function validate_client($client = 0, $sesskey = '', $operation = '') {
  137. global $USER, $CFG;
  138. //return true;
  139. // rev 1.6.3 added extra securityu checks
  140. $client = clean_param($client, PARAM_INT);
  141. $sesskey = clean_param($sesskey, PARAM_ALPHANUM);
  142. /// We can't validate a session that hasn't even been initialized yet.
  143. if (!$sess = ws_get_record('webservices_sessions', 'id', $client, 'sessionend', 0, 'verified', 1)) {
  144. return false;
  145. }
  146. /// Validate this session.
  147. if ($sesskey != $sess->sessionkey) {
  148. return false;
  149. }
  150. // rev 1.6 make sure the session has not timed out
  151. if ($sess->sessionbegin + $this->sessiontimeout < time()) {
  152. $sess->sessionend = time();
  153. ws_update_record('webservices_sessions', $sess);
  154. return false;
  155. }
  156. $USER->id = $sess->userid;
  157. $USER->username = '';
  158. $USER->mnethostid = $CFG->mnet_localhost_id; //Moodle 1.95+ build sept 2009
  159. $USER->ip= getremoteaddr();
  160. unset ($USER->access); // important for get_my_courses !
  161. $this->debug_output("validate_client OK $operation $client user=" . print_r($USER, true));
  162. //$this->debug_output(print_r($CFG,true));
  163. //LOG INTO MOODLE'S LOG
  164. if ($operation && $CFG->ws_logoperations)
  165. add_to_log(SITEID, 'webservice', 'webservice pp', '', $operation);
  166. return true;
  167. }
  168. /**
  169. * Sends an FATAL error response back to the client.
  170. *
  171. * @todo Override in protocol-specific server subclass, e.g. by throwing a PHP exception
  172. * @param string $msg The error message to return.
  173. * @return An object with the error message string.(required by mdl_soapserver)
  174. */
  175. protected function error($msg) {
  176. global $CFG;
  177. $res = new StdClass();
  178. $res->error = $msg;
  179. if ($CFG->ws_logerrors)
  180. add_to_log(SITEID, 'webservice', 'webservice pp', '', 'error :' . $msg);
  181. $this->debug_output("server.soap fatal error : $msg ". getremoteaddr());
  182. return $res;
  183. }
  184. /**
  185. * return and object with error attribute set
  186. * this record will be inserted in client array of responses
  187. * do not override in protocol-specific server subclass.
  188. */
  189. private function non_fatal_error($msg) {
  190. $res = new StdClass();
  191. $res->error = $msg;
  192. $this->debug_output("server.soap non fatal error : $msg");
  193. return $res;
  194. }
  195. /**
  196. * Do server-side debugging output (to file).
  197. *
  198. * @uses $CFG
  199. * @param string $output Debugging output.
  200. * @return void
  201. */
  202. function debug_output($output) {
  203. global $CFG;
  204. if ($CFG->ws_debug) {
  205. $fp = fopen($CFG->dataroot . '/debug.out', 'a');
  206. fwrite($fp, "[" . time() . "] $output\n");
  207. fflush($fp);
  208. fclose($fp);
  209. }
  210. }
  211. /**
  212. * check that current ws user has the required capability
  213. * @param string capability
  214. * @param string type on context CONTEXT_SYSTEM, CONTEXT_COURSE ....
  215. * @param object moodle's id
  216. * @param int $userid : user to chcek, default me
  217. */
  218. private function has_capability($capability, $context_type, $instance_id,$userid=NULL) {
  219. global $USER;
  220. $context = get_context_instance($context_type, $instance_id);
  221. if (empty($userid)) { // we must accept null, 0, '0', '' etc. in $userid
  222. $userid = $USER->id;
  223. }
  224. return has_capability($capability, $context, $userid);
  225. }
  226. /**
  227. * Validates a client's login request.
  228. *
  229. * @uses $CFG
  230. * @param array $input Input data from the client request object.
  231. * @return array Return data (client record ID and session key) to be
  232. * converted into a specific data format for sending to the
  233. * client.
  234. */
  235. function login($username, $password) {
  236. global $CFG;
  237. if (!empty ($CFG->ws_disable))
  238. return $this->error(get_string('ws_accessdisabled', 'local_wspp'));
  239. if (!$this->using17)
  240. return $this->error(get_string('ws_nomoodle16', 'local_wspp'));
  241. $userip = getremoteaddr(); // rev 1.5.4
  242. if (!empty($CFG->ws_enforceipcheck)) {
  243. if (!record_exists('webservices_clients_allow','client',$userip))
  244. return $this->error(get_string('ws_accessrestricted', 'local_wspp',$userip));
  245. }
  246. // rev 1.6.3 added extra security checks
  247. $username = clean_param($username, PARAM_NOTAGS);
  248. $password = clean_param($password, PARAM_NOTAGS);
  249. /// Use Moodle authentication.
  250. /// FIRST make sure user exists , otherwise account WILL be created with CAS authentification ....
  251. if (!$knownuser = ws_get_record('user', 'username', $username)) {
  252. return $this->error(get_string('ws_invaliduser', 'local_wspp'));
  253. }
  254. //$this->debug_output(print_r($knownuser, true));
  255. $user=false;
  256. //revision 1.6.1 try to use a custom auth plugin
  257. if (!exists_auth_plugin("webservice") || ! is_enabled_auth("webservice")) {
  258. $this->debug_output('internal ');
  259. /// also make sure internal_authentication is used (a limitation to fix ...)
  260. if (!is_internal_auth($knownuser->auth)) {
  261. return $this->error(get_string('ws_invaliduser', 'local_wspp'));
  262. }
  263. // regular manual authentification (should not be allowed !)
  264. $user = authenticate_user_login(addslashes($username), $password);
  265. $this->debug_output('return of a_u_l'. print_r($user,true));
  266. }
  267. else {
  268. $this->debug_output('auth plugin');
  269. $auth=get_auth_plugin("webservice");
  270. if ($auth->user_login_webservice($username,$password)) {
  271. $user=$knownuser;
  272. }
  273. }
  274. if (($user === false) || ($user && $user->id == 0) || isguestuser($user)) {
  275. return $this->error(get_string('ws_invaliduser', 'local_wspp'));
  276. }
  277. //$this->debug_output(print_r($user,true));
  278. /// Verify that an active session does not already exist for this user.
  279. $userip = getremoteaddr(); // rev 1.5.4
  280. $sql = "userid = {$user->id} AND verified = 1 AND
  281. ip='$userip' AND sessionend = 0 AND
  282. (" . time() . "- sessionbegin) < " . $this->sessiontimeout;
  283. //$this->debug_output($sql);
  284. if ($sess = ws_get_record_select('webservices_sessions',$sql)) {
  285. //return $this->error('A session already exists for this user (' . $user->login . ')');
  286. /*
  287. if ($sess->ip != $userip)
  288. return $this->error(get_string('ws_ipadressmismatch', 'local_wspp',$userip."!=".$sess->ip));
  289. */
  290. //give him more time
  291. ws_set_field('webservices_sessions','sessionbegin',time(),'id',$sess->id);
  292. // V1.6 reuse current session
  293. } else {
  294. $this->debug_output('nouvelle session ');
  295. /// Login valid, create a new session record for this client.
  296. $sess = new stdClass;
  297. $sess->userid = $user->id;
  298. $sess->verified = true;
  299. $sess->ip = $userip;
  300. $sess->sessionbegin = time();
  301. $sess->sessionend = 0;
  302. $sess->sessionkey = $this->add_session_key();
  303. if ($sess->id = ws_insert_record('webservices_sessions', $sess)) {
  304. if ($CFG->ws_logoperations)
  305. add_to_log(SITEID, 'webservice', 'webservice pp', '', __FUNCTION__);
  306. } else
  307. return $this->error(get_string('ws_errorregistersession','local_wspp'));
  308. }
  309. /// Return standard data to be converted into the appropriate data format
  310. /// for return to the client.
  311. $ret = array (
  312. 'client' => $sess->id,
  313. 'sessionkey' => $sess->sessionkey
  314. );
  315. $this->debug_output(print_r($ret, true));
  316. return $ret;
  317. }
  318. /**
  319. * Logs a client out of the system by removing the valid flag from their
  320. * session record and any user ID that is assosciated with their particular
  321. * session.
  322. *
  323. * @param integer $client The client record ID.
  324. * @param string $sesskey The client session key.
  325. * @return boolean True if successfully logged out, false otherwise.
  326. * since this operation retunr s a simple type, no need to override it in protocol specific layer
  327. */
  328. function logout($client, $sesskey) {
  329. global $CFG;
  330. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  331. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  332. }
  333. if ($sess = ws_get_record('webservices_sessions', 'id', $client, 'sessionend', 0, 'verified', 1)) {
  334. $sess->verified = 0;
  335. $sess->sessionend = time();
  336. if (ws_update_record('webservices_sessions', $sess)) {
  337. return true;
  338. } else {
  339. return false;
  340. }
  341. }
  342. return false;
  343. }
  344. function get_version($client, $sesskey) {
  345. global $CFG;
  346. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  347. return -1; //invalid Moodle's ID
  348. }
  349. return $this->version;
  350. }
  351. /**
  352. * Find and return a list of user records.
  353. *
  354. * @param int $client The client session ID.
  355. * @param string $sesskey The client session key.
  356. * @param array $userids An array of input user values. If empty, return all users
  357. * @param string $idfield The field used to compare the user ID fields against.
  358. * @return array Return data (user record) to be converted into a
  359. * specific data format for sending to the client.
  360. */
  361. function get_users($client, $sesskey, $userids, $idfield = 'idnumber') {
  362. global $USER;
  363. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  364. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  365. }
  366. /// Verify that the user for this session can perform this operation.
  367. //nothing to check user database is public ?
  368. $ret = array (); // Return array.
  369. if (empty ($userids)) { // all users ...
  370. return filter_users($client, get_users(true), 0);
  371. }
  372. foreach ($userids as $userid) {
  373. $users = ws_get_records('user', $idfield, $userid); //may have more than one !
  374. if (empty ($users)) {
  375. $a = new StdClass();
  376. $a->critere = $idfield;
  377. $a->valeur = $userid;
  378. $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
  379. } else {
  380. $ret = array_merge($ret, $users);
  381. }
  382. }
  383. //$this->debug_output("GU" . print_r($ret, true));
  384. return filter_users($client, $ret, 0);
  385. }
  386. /**
  387. * Find and return a list of course records.
  388. *
  389. * @param int $client The client session ID.
  390. * @param string $sesskey The client session key.
  391. * @param array $courseids An array of input course values to search for.If empty, all courses
  392. * @param string $idfield searched column . May be any column of table mdl_course
  393. * @return array Return data (course record) to be converted into a specific
  394. * data format for sending to the client.
  395. */
  396. function get_courses($client, $sesskey, $courseids, $idfield = 'idnumber') {
  397. global $USER;
  398. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  399. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  400. }
  401. $ret = array ();
  402. if (empty ($courseids)) {
  403. // all courses wanted
  404. $res = ws_get_records('course', '', '');
  405. return filter_courses($client, $res);
  406. }
  407. foreach ($courseids as $courseid) {
  408. if ($courses = ws_get_records('course', $idfield, $courseid)) { //may have more than one
  409. $ret = array_merge($ret, $courses);
  410. } else {
  411. $a = new StdClass();
  412. $a->critere = $idfield;
  413. $a->valeur = $courseid;
  414. $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
  415. }
  416. }
  417. return filter_courses($client,$ret);
  418. }
  419. function get_courses_search($client, $sesskey, $search) {
  420. global $USER;
  421. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  422. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  423. }
  424. $search = trim(strip_tags($search)); // trim & clean raw searched string
  425. if (empty ($search)) {
  426. // all courses wanted
  427. $res = ws_get_records('course', '', '');
  428. return filter_courses($client, $res);
  429. }
  430. $searchterms = explode(" ", $search); // Search for words independently
  431. foreach ($searchterms as $key => $searchterm) {
  432. if (strlen($searchterm) < 2) {
  433. unset($searchterms[$key]);
  434. }
  435. }
  436. $totalcount=0;
  437. $ret = get_courses_search($searchterms, "fullname ASC",0,9999,$totalcount);
  438. return filter_courses($client,$ret);
  439. }
  440. /**
  441. * Find and return a list of resources within one or several courses.
  442. * OK PP tested with php5 5 and python clients
  443. * @param int $client The client session ID.
  444. * @param string $sesskey The client session key.
  445. * @param array $courseids An array of input course id values to search for. If empty return all ressources
  446. * @param string $idfield : the field used to identify courses
  447. * @return array An array of records.
  448. */
  449. function get_resources($client, $sesskey, $courseids, $idfield = 'idnumber') {
  450. global $CFG, $USER;
  451. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  452. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  453. }
  454. $ret = array ();
  455. if (empty ($courseids)) {
  456. $courses = ws_get_my_courses($USER->id);
  457. } else {
  458. $courses = array ();
  459. foreach ($courseids as $courseid) {
  460. if ($course = ws_get_record('course', $idfield, $courseid))
  461. $courses[] = $course;
  462. else {
  463. //append an error record to the list
  464. $a = new StdClass();
  465. $a->critere = $idfield;
  466. $a->valeur = $courseid;
  467. $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
  468. }
  469. }
  470. }
  471. //remove courses not available to current user
  472. $courses = filter_courses($client, $courses);
  473. $ilink = "{$CFG->wwwroot}/mod/resource/view.php?id=";
  474. foreach ($courses as $course) {
  475. if ($resources = get_all_instances_in_course("resource", $course, NULL, true)) {
  476. foreach ($resources as $resource) {
  477. $resource->url = $ilink . $resource->coursemodule;
  478. $ret[] = $resource;
  479. }
  480. }
  481. }
  482. //remove ressources in course where current user is not enroled
  483. return filter_resources($client, $ret);
  484. }
  485. /**
  486. * Find and return a list of sections within one or several courses.
  487. * OK PP tested with php5 5 and python clients
  488. * @param int $client The client session ID.
  489. * @param string $sesskey The client session key.
  490. * @param array $courseids An array of input course id values to search for. If empty return all sections
  491. * @param string $idfield : the field used to identify courses
  492. * @return array An array of course records.
  493. */
  494. public function get_sections($client, $sesskey, $courseids, $idfield = 'idnumber') {
  495. global $CFG, $USER;
  496. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  497. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  498. }
  499. $ret = array ();
  500. if (empty ($courseids)) {
  501. $courses = ws_get_my_courses($USER->id);
  502. } else {
  503. $courses = array ();
  504. foreach ($courseids as $courseid) {
  505. if ($course = ws_get_record('course', $idfield, $courseid))
  506. $courses[] = $course;
  507. else {
  508. //append an error record to the list
  509. $a = new StdClass();
  510. $a->critere = $idfield;
  511. $a->valeur = $courseid;
  512. $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
  513. }
  514. }
  515. }
  516. //remove courses not available to current user
  517. $courses = filter_courses($client, $courses);
  518. foreach ($courses as $course) {
  519. if ($CFG->wspp_using_moodle20)
  520. require_once ($CFG->dirroot.'/course/lib.php');
  521. if ($resources = get_all_sections($course->id))
  522. foreach ($resources as $resource) {
  523. $ret[] = $resource;
  524. }
  525. }
  526. //remove ressources in course where current user is not enroled
  527. return filter_sections($client, $ret);
  528. }
  529. public function get_instances_bytype($client, $sesskey, $courseids, $idfield = 'idnumber', $type) {
  530. //TODO merge with get_resources by giving $type="resource"
  531. global $CFG, $USER;
  532. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  533. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  534. }
  535. if (empty($type)) {
  536. return $this->error(get_string('ws_emptyparameter', 'local_wspp','type'));
  537. }
  538. $ret = array ();
  539. if (empty ($courseids)) {
  540. $courses = ws_get_my_courses($USER->id);
  541. } else {
  542. $courses = array ();
  543. foreach ($courseids as $courseid) {
  544. if ($course = ws_get_record('course', $idfield, $courseid))
  545. $courses[] = $course;
  546. else {
  547. //append an error record to the list
  548. $a = new StdClass();
  549. $a->critere = $idfield;
  550. $a->valeur = $courseid;
  551. $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
  552. }
  553. }
  554. }
  555. //remove courses not available to current user
  556. $courses = filter_courses($client, $courses);
  557. foreach ($courses as $course) {
  558. if (!$resources = get_all_instances_in_course($type, $course, NULL, true)) {
  559. //append an error record to the list
  560. $a = new StdClass();
  561. $a->critere = 'type';
  562. $a->valeur = $type;
  563. $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
  564. }else {
  565. $ilink = "{$CFG->wwwroot}/mod/$type/view.php?id=";
  566. foreach ($resources as $resource) {
  567. $resource->url = $ilink . $resource->coursemodule;
  568. $ret[] = $resource;
  569. }
  570. }
  571. }
  572. //remove ressources in course where current user is not enroled
  573. return filter_resources($client, $ret);
  574. }
  575. /**
  576. * Find and return student grades for currently enrolled courses Function for Moodle 1.9)
  577. *
  578. * @uses $CFG
  579. * @param int $client The client session ID.
  580. * @param string $sesskey The client session key.
  581. * @param string $userid The unique id of the student.
  582. * @param string $useridfield The field used to identify the student.
  583. * @param string $courseids Array of courses ids
  584. * @param string $idfield field used for course's ids (idnumber, shortname, id ...)
  585. * @return userGrade [] The student grades
  586. *
  587. */
  588. function get_grades($client, $sesskey, $userid, $useridfield = 'idnumber', $courseids, $courseidfield = 'idnumber') {
  589. global $CFG;
  590. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  591. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  592. }
  593. if (empty ($courseids))
  594. return server :: get_user_grades($client, $sesskey, $userid, $useridfield);
  595. if (!$this->using19)
  596. return $this->error(get_string(' ws_notsupportedgradebook', 'local_wspp'));
  597. require_once ($CFG->dirroot . '/grade/lib.php');
  598. require_once ($CFG->dirroot . '/grade/querylib.php');
  599. if (!$user = ws_get_record('user', $useridfield, $userid)) {
  600. return $this->error(get_string('ws_userunknown','local_wspp',$userid));
  601. }
  602. $return = array ();
  603. /// Find grade data for the requested IDs.
  604. foreach ($courseids as $cid) {
  605. $rgrade = new stdClass;
  606. /// Get the student grades for each course requested.
  607. if ($course = ws_get_record('course', $courseidfield, $cid)) {
  608. if ($this->has_capability('moodle/grade:viewall', CONTEXT_COURSE, $course->id)) {
  609. // get the floating point final grade
  610. if ($legrade = grade_get_course_grade($user->id, $course->id)) {
  611. $rgrade = $legrade;
  612. $rgrade->error = '';
  613. $rgrade->itemid = $cid;
  614. } else {
  615. $a=new StdClass();
  616. $a->user=fullname($user);
  617. $a->course= $course->fullname;
  618. $rgrade->error = get_string('ws_nogrades','local_wspp',$a);
  619. }
  620. } else {
  621. $rgrade->error= get_string('ws_noseegrades','local_wspp',$course->fullname);
  622. }
  623. } else {
  624. $rgrade->error = get_string('ws_courseunknown','local_wspp', $cid);
  625. }
  626. $return[] = $rgrade;
  627. }
  628. //$this->debug_output("GG".print_r($return, true));
  629. return filter_grades($client, $return);
  630. }
  631. /**
  632. * return user's grade in all courses
  633. * @use get_grades by first creating an array of courses Moodle's ids
  634. */
  635. public function get_user_grades($client, $sesskey, $userid, $idfield = "idnumber") {
  636. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  637. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  638. }
  639. if (!$this->using19)
  640. return $this->error(get_string(' ws_notsupportedgradebook', 'local_wspp'));
  641. if (!$user = ws_get_record('user', $idfield, $userid)) {
  642. return $this->error(get_string('ws_userunknown','local_wspp',$idfield.'='.$userid));
  643. }
  644. // we cannot call API grade_get_course_grade($user->id) since it does not set the courseid as we want it
  645. if (!$courses = ws_get_my_courses($user->id, $sort = 'sortorder ASC', $fields = 'idnumber')) {
  646. return $this->error(get_string('ws_nocourseforuser','local_wspp',$userid));
  647. }
  648. $courseids = array ();
  649. foreach ($courses as $c)
  650. if (!empty ($c->idnumber))
  651. $courseids[] = $c->idnumber;
  652. //$this->debug_output("GUG=" . print_r($courseids, true));
  653. if (empty ($courseids))
  654. return $this->error(get_string('ws_nocoursewithidnumberforuser','local_wspp', $userid));
  655. // caution not $this->get_user_grades THAT WILL call mdl_sopaserver::get_grades
  656. // resulting in two calls of to_soaparray !!!!
  657. return server :: get_grades($client, $sesskey, $userid, $idfield, $courseids, 'idnumber');
  658. }
  659. public function get_course_grades($client, $sesskey, $courseid, $idfield = "idnumber") {
  660. global $CFG, $USER;
  661. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  662. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  663. }
  664. if (!$this->using19)
  665. return $this->error(get_string(' ws_notsupportedgradebook', 'local_wspp'));
  666. require_once ($CFG->dirroot . '/grade/lib.php');
  667. require_once ($CFG->dirroot . '/grade/querylib.php');
  668. $return = array ();
  669. //Get all student grades for course requested.
  670. if ($course = ws_get_record('course', $idfield, $courseid)) {
  671. $context = get_context_instance(CONTEXT_COURSE, $course->id);
  672. if (has_capability('moodle/grade:viewall', $context)) {
  673. $students = array ();
  674. $students = get_role_users(5, $context, true, '');
  675. //$this->debug_output("GcG".print_r($students, true));
  676. foreach ($students as $user) {
  677. if ($legrade = grade_get_course_grade($user->id, $course->id)) {
  678. $rgrade = $legrade;
  679. $rgrade->error = '';
  680. $rgrade->itemid = $user->idnumber;
  681. // $this->debug_output("IDS=".print_r($legrade,true));
  682. $return[] = $rgrade;
  683. } else {
  684. $a=new StdClass();
  685. $a->user=fullname($user);
  686. $a->course= $course->fullname;
  687. $rgrade=new StdClass();
  688. $rgrade->error = get_string('ws_nogrades','local_wspp',$a);
  689. $return[] = $rgrade;
  690. }
  691. }
  692. } else {
  693. $rgrade=new StdClass();
  694. $rgrade->error = get_string('ws_noseegrades','local_wspp',$course->fullname);
  695. $return[] = $rgrade;
  696. }
  697. } else {
  698. $rgrade=new StdClass();
  699. $rgrade->error = get_string('ws_courseunknown','local_wspp', $courseid);
  700. $return[] = $rgrade;
  701. }
  702. //$this->debug_output("GcG".print_r($return, true));
  703. return filter_grades($client, $return);
  704. }
  705. /**
  706. * determine the primary role of user in a course
  707. * @param int $client The client session record ID.
  708. * @param string $sesskey The session key returned by a previous login.
  709. * @param string userid
  710. * @param string useridfield
  711. * @param string courseid
  712. * @param string courseidfield
  713. * @return integer
  714. * 1 admin
  715. * 2 coursecreator
  716. * 3 editing teacher
  717. * 4 non editing teacher
  718. * 5 student
  719. * 6 guest IF course allows guest AND username ==guest
  720. * 0 nothing
  721. * since this operation retunr s a simple type, no need to override it in protocol specific layer
  722. */
  723. function get_primaryrole_incourse($client, $sesskey, $userid, $useridfield, $courseid, $courseidfield) {
  724. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  725. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  726. }
  727. // convert user request criteria to an userid
  728. $user = ws_get_record('user', $useridfield, $userid);
  729. if (!$user)
  730. return $this->error(get_string('ws_userunknown','local_wspp',$useridfield."=".$userid));
  731. $userid = $user->id;
  732. // convert course request criteria to a courseid
  733. $course = ws_get_record('course', $courseidfield, $courseid);
  734. if (!$course)
  735. return $this->error(get_string('ws_courseunknown','local_wspp',$courseidfield."=".$courseid ));
  736. return ws_get_primaryrole_incourse($course, $userid);
  737. }
  738. /**
  739. * determine if user has (at least) a given role in a course
  740. * @param int $client The client session record ID.
  741. * @param string $sesskey The session key returned by a previous login.
  742. * @param string userid
  743. * @param string useridfield
  744. * @param string courseid
  745. * @param string courseidfield
  746. * @param int roleid
  747. * @return boolean True if Ok , False otherwise.
  748. * since this operation retunr s a simple type, no need to override it in protocol specific layer
  749. */
  750. function has_role_incourse($client, $sesskey, $userid, $useridfield, $courseid, $courseidfield, $roleid) {
  751. $tmp = server :: get_primaryrole_incourse($client, $sesskey, $userid, $useridfield, $courseid, $courseidfield);
  752. return ($tmp <= $roleid);
  753. }
  754. /**
  755. * Find and return a list of courses that a user is a member of.
  756. *
  757. * @param int $client The client session ID.
  758. * @param string $sesskey The client session key.
  759. * @param string $uinfo (optional) Moodle's id of user. If absent, uses current session user id
  760. * @param string $idfield (default ='id', ignored if $uinfo is empty)
  761. * @param string $sort requested order . Default fullname as per rev 1.5.11
  762. * @return array Return data (course record) to be converted into a specific
  763. * data format for sending to the client.
  764. */
  765. function get_my_courses($client, $sesskey, $uinfo = '', $idfield = 'id', $sort = '') {
  766. global $CFG,$USER;
  767. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  768. return $this->error(get_string('ws_invalidclient', 'local_wspp')." ".__FUNCTION__);
  769. }
  770. $cuid = $USER->id;
  771. if (!empty($uinfo)) {
  772. // find userid if not current user
  773. if (!$user = ws_get_record('user', $idfield, $uinfo))
  774. return $this->error(get_string('ws_userunknown','local_wspp',idfield."=".$uinfo));
  775. $uid=$user->id;
  776. } else
  777. $uid = $cuid; //use current user and ignore $idfield
  778. //only admin user can request courses for others
  779. if ($uid != $cuid) {
  780. if (!$this->has_capability('moodle/user:loginas', CONTEXT_SYSTEM, 0)) {
  781. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  782. }
  783. }
  784. $sort = $sort ? $sort : 'fullname';
  785. if (isguestuser($user))
  786. $res = ws_get_records('course', 'guest', 1, $sort);
  787. else {
  788. //Moodle 1.95 do not return all fields set in wsdl
  789. if (!$CFG->wspp_using_moodle20)
  790. $extrafields="password,summary,format,showgrades,newsitems,enrolperiod,numsections,marker,maxbytes,
  791. hiddensections,lang,theme,cost,timecreated,timemodified,metacourse";
  792. else
  793. // some fields are not anymore defined in Moodle 2.0
  794. $extrafields="summary,format,showgrades,newsitems,numsections,marker,maxbytes,
  795. hiddensections,lang,theme,timecreated,timemodified";
  796. $res = ws_get_my_courses($uid, $sort,$extrafields);
  797. }
  798. if ($res) {
  799. //rev 1.6 return primary role for each course
  800. foreach ($res as $id=>$value)
  801. $res[$id]->myrole= ws_get_primaryrole_incourse($res[$id],$uid);
  802. //return $res;
  803. return filter_courses($client, $res);
  804. }
  805. else
  806. return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  807. }
  808. /**
  809. * returns users having $idrole in course identified by $idcourse
  810. * @param string $idcourse unique identifierr of course
  811. * @param string $idfield name of field used to finc course (idnumber, id, shortname), should be unique
  812. * @param integer $idrole role searched for (0 = any role)
  813. */
  814. function get_users_bycourse($client, $sesskey, $idcourse, $idfield, $idrole = 0) {
  815. global $USER;
  816. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  817. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  818. }
  819. if (!$course = ws_get_record('course', $idfield, $idcourse)) {
  820. return $this->error(get_string('ws_courseunknown','local_wspp',$idfield."=".$idcourse ));
  821. }
  822. if (!$this->has_capability('moodle/course:update', CONTEXT_COURSE, $course->id)
  823. && !ws_is_enrolled($course->id,$USER->id))
  824. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  825. if (!empty ($roleid) && !ws_record_exists('role', 'id', $idrole))
  826. return $this->error(get_string('ws_roleunknown','local_wspp',$idrole ));
  827. $context = get_context_instance(CONTEXT_COURSE, $course->id);
  828. if ($res = get_role_users($idrole, $context, true, '')) {
  829. //rev 1.6 if $idrole is empty return primary role for each user
  830. if (empty($idrole)) {
  831. foreach ($res as $id=>$value)
  832. $res[$id]->role=ws_get_primaryrole_incourse($course,$res[$id]->id);
  833. }
  834. return filter_users($client, $res, $idrole);
  835. } else {
  836. return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  837. }
  838. }
  839. function get_roles($client, $sesskey, $roleid = '', $idfield = '') {
  840. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  841. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  842. }
  843. // Get a list of all the roles in the database, sorted by their short names.
  844. if ($res = ws_get_records('role', $idfield, $roleid, 'shortname, id', '*')) {
  845. return $res;
  846. } else {
  847. return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  848. }
  849. }
  850. function get_categories($client, $sesskey, $catid = '', $idfield = '') {
  851. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  852. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  853. }
  854. $ret = array ();
  855. // Get a list of all the categories in the database, sorted by their name
  856. if ($res = ws_get_records('course_categories', $idfield, $catid, 'name', '*')) {
  857. return filter_categories($client, $res);
  858. } else {
  859. return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  860. }
  861. }
  862. function get_events($client, $sesskey, $eventtype, $ownerid,$owneridfield='id') {
  863. global $USER;
  864. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  865. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  866. }
  867. $ret = array ();
  868. // Get a list of all the events in the database, sorted by their short names.
  869. //TODO filter by eventype ...
  870. switch ($eventtype) {
  871. case cal_show_global :
  872. $idfield = 'courseid';
  873. $ownerid = 1;
  874. break;
  875. case cal_show_course :
  876. $idfield = 'courseid';
  877. if (!$course =ws_get_record('course',$owneridfield,$ownerid)) {
  878. return $this->error(get_string('ws_courseunknown','local_wspp',$owneridfield."=".$ownerid ));
  879. }
  880. $ownerid=$course->id;
  881. break;
  882. case cal_show_group :
  883. $idfield = 'groupid';
  884. if (!$group =ws_get_record('groups',$owneridfield,$ownerid)) {
  885. return $this->error(get_string('ws_groupunknown','local_wspp',$owneridfield."=".$ownerid ));
  886. }
  887. $ownerid=$group->id;
  888. break;
  889. case cal_show_user :
  890. $idfield = 'userid';
  891. if (!$user =ws_get_record('user',$owneridfield,$ownerid)) {
  892. return $this->error(get_string('ws_userunknown','local_wspp',$owneridfield."=".$ownerid ));
  893. }
  894. $ownerid=$user->id;
  895. break;
  896. default :
  897. $idfield = '';
  898. $ownerid = '';
  899. }
  900. if ($res = ws_get_records('event', $idfield, $ownerid)) {
  901. foreach ($res as $r) {
  902. $r = filter_event($client, $eventtype, $r);
  903. if ($r)
  904. $ret[] = $r;
  905. }
  906. } else {
  907. $ret[]=$this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  908. }
  909. return $ret;
  910. }
  911. function get_group_members($client, $sesskey, $groupid,$groupidfield='id') {
  912. global $USER;
  913. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  914. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  915. }
  916. if (!$group = ws_get_record('groups', $groupidfield, $groupid)) {
  917. return $this->error(get_string('ws_groupunknown','local_wspp',$groupid));
  918. }
  919. if (!$this->has_capability('moodle/course:update', CONTEXT_COURSE, $group->courseid)
  920. && ! ws_is_enrolled($group->courseid,$USER->id))
  921. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  922. //$res = get_group_users($group->id); deprecated Moodle 1.9 removed Moodle 2.0
  923. $res=groups_get_members($group->id);
  924. if (!$res)
  925. return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  926. return filter_users($client, $res, 0);
  927. }
  928. function get_grouping_members($client, $sesskey, $groupid,$groupidfield='id') {
  929. global $USER;
  930. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  931. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  932. }
  933. if (!$group = ws_get_record('groupings', $groupidfield, $groupid)) {
  934. return $this->error(get_string('ws_groupingunknown','local_wspp',$groupid));
  935. }
  936. if (!$this->has_capability('moodle/course:update', CONTEXT_COURSE, $group->courseid)
  937. && ! ws_is_enrolled($group->courseid,$USER->id))
  938. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  939. $res = groups_get_grouping_members($group->id);
  940. if (!$res)
  941. return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  942. return filter_users($client, $res, 0);
  943. }
  944. function get_cohort_members($client, $sesskey, $groupid,$groupidfield='id') {
  945. global $DB,$CFG;
  946. if (!$CFG->wspp_using_moodle20)
  947. return $this->error(get_string('ws_moodle20only', 'local_wspp'));
  948. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  949. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  950. }
  951. if (!$group = ws_get_record('cohort', $groupidfield, $groupid)) {
  952. return $this->error(get_string('ws_cohortunknown','local_wspp',$groupid));
  953. }
  954. /*
  955. if (!$this->has_capability('moodle/cohort:update', CONTEXT_COURSECAT, $group->contextid))
  956. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  957. */
  958. $params['cohortid'] = $group->id;
  959. $fields = 'SELECT u.*';
  960. $sql = " FROM {user} u
  961. JOIN {cohort_members} cm ON (cm.userid = u.id AND cm.cohortid = :cohortid)";
  962. try {
  963. $res = $DB->get_records_sql($fields . $sql, $params);
  964. if (!$res)
  965. return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  966. } catch (Exception $e) {
  967. ws_error_log($e);
  968. }
  969. return filter_users($client, $res, 0);
  970. }
  971. protected function get_groups($client, $sesskey,$groups,$idfield,$courseid){
  972. if (empty($groups) && $courseid) {
  973. return server::get_groups_bycourse ($client,$sesskey,$courseid);
  974. }
  975. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  976. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  977. }
  978. global $CFG;
  979. $ret = array();
  980. if ($courseid) {
  981. $courseselect = 'AND g.courseid ='.$courseid ;
  982. } else {
  983. $courselect = '';
  984. }
  985. // $this->debug_output("groupes=".print_r($groups,true));
  986. foreach ($groups as $group) {
  987. $sql= "$idfield ='$group' $courseselect ";
  988. if ($g = ws_get_records_select('groups',$sql)) {
  989. $g=filter_groups($client,$g);
  990. foreach($g as $one) {
  991. $ret[] = $one;
  992. }
  993. } else {
  994. $ret[]=$this->non_fatal_error(get_string('nogroups','local_wspp')); // "Invalid group $idfield :$group ");
  995. }
  996. }
  997. //$this->debug_output("groupes tr=".print_r($ret,true));
  998. return $ret;
  999. }
  1000. protected function get_groupings($client, $sesskey,$groups,$idfield,$courseid){
  1001. if (empty($groups) && $courseid) {
  1002. return server::get_groupings_bycourse ($client,$sesskey,$courseid);
  1003. }
  1004. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1005. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1006. }
  1007. global $CFG;
  1008. $ret = array();
  1009. if ($courseid) {
  1010. $courseselect = 'AND g.courseid ='.$courseid ;
  1011. } else {
  1012. $courselect = '';
  1013. }
  1014. //$this->debug_output("groupings=".print_r($groups,true));
  1015. foreach ($groups as $group) {
  1016. $sql= "$idfield ='$group' $courseselect ";
  1017. if ($g = ws_get_records_select('groupings',$sql)) {
  1018. $g=filter_groupings($client,$g);
  1019. foreach($g as $one) {
  1020. $ret[] = $one;
  1021. }
  1022. } else {
  1023. $ret[]=$this->non_fatal_error(get_string('nogroupings','local_wspp')); // "Invalid group $idfield :$group ");
  1024. }
  1025. }
  1026. //$this->debug_output("groupings tr=".print_r($ret,true));
  1027. return $ret;
  1028. }
  1029. protected function get_cohorts($client, $sesskey,$groups,$idfield){
  1030. if (empty($groups)) {
  1031. return server::get_all_cohorts($client,$sesskey);
  1032. }
  1033. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1034. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1035. }
  1036. $ret = array();
  1037. foreach ($groups as $group) {
  1038. $sql= "$idfield ='$group' ";
  1039. if ($g = ws_get_records_select('cohort',$sql)) {
  1040. $g=filter_cohorts($client,$g);
  1041. foreach($g as $one) {
  1042. $ret[] = $one;
  1043. }
  1044. } else {
  1045. $ret[]=$this->non_fatal_error(get_string('nocohorts','local_wspp')); // "Invalid group $idfield :$group ");
  1046. }
  1047. }
  1048. //$this->debug_output("cohorts tr=".print_r($ret,true));
  1049. return $ret;
  1050. }
  1051. /**
  1052. * Add user to group
  1053. * @uses $CFG
  1054. * @param int $client The client session ID.
  1055. * @param string $sesskey The client session key.
  1056. * @param int $userid The user's id
  1057. * @param int $groupid The group's id
  1058. * @return affectRecord Return data (affectRecord object) to be converted into a
  1059. * specific data format for sending to the client.
  1060. */
  1061. function affect_user_to_group($client, $sesskey, $userid, $groupid) {
  1062. global $CFG;
  1063. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1064. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1065. }
  1066. if (!$group = ws_get_record('groups', 'id', $groupid)) {
  1067. return $this->error(get_string('ws_groupunknown','local_wspp','id='.$groupid));
  1068. }
  1069. /// Check for correct permissions.
  1070. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $group->courseid)) {
  1071. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1072. }
  1073. if (!$user = ws_get_record("user", "id", $userid)) {
  1074. return $this->error(get_string('ws_userunknown','local_wspp','id='.$userid));
  1075. }
  1076. /// Check user is enroled in course
  1077. if (!ws_is_enrolled( $group->courseid, $user->id)) {
  1078. $a=new StdClass();
  1079. $a->user=$user->username;
  1080. $a->course=$group->courseid;
  1081. return $this->error(get_string('ws_user_notenroled','local_wspp',$a));
  1082. }
  1083. if ($CFG->wspp_using_moodle20) {
  1084. // not anymore included by defualt in Moodle 2.0
  1085. require_once ($CFG->dirroot.'/group/lib.php');
  1086. }
  1087. $resp = new stdClass();
  1088. $resp->status = groups_add_member($group->id, $user->id);
  1089. return $resp;
  1090. }
  1091. function remove_user_from_group($client, $sesskey, $userid, $groupid) {
  1092. global $CFG;
  1093. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1094. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1095. }
  1096. if (!$group = ws_get_record('groups', 'id', $groupid)) {
  1097. return $this->error(get_string('ws_groupunknown','local_wspp','id='.$groupid));
  1098. }
  1099. /// Check for correct permissions.
  1100. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $group->courseid)) {
  1101. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1102. }
  1103. if (!$user = ws_get_record("user", "id", $userid)) {
  1104. return $this->error(get_string('ws_userunknown','local_wspp','id='.$userid));
  1105. }
  1106. /// Check user is member
  1107. if (!ws_is_enrolled( $group->courseid, $user->id)) {
  1108. $a=new StdClass();
  1109. $a->user=$user->username;
  1110. $a->course=$group->courseid;
  1111. return $this->error(get_string('ws_user_notenroled','local_wspp',$a));
  1112. }
  1113. if ($CFG->wspp_using_moodle20) {
  1114. // not anymore included by defualt in Moodle 2.0
  1115. require_once ($CFG->dirroot.'/group/lib.php');
  1116. }
  1117. $resp = new stdClass();
  1118. $resp->status = groups_remove_member($group->id, $user->id);
  1119. return $resp;
  1120. }
  1121. /**
  1122. * Add user to cohort
  1123. * @uses $CFG
  1124. * @param int $client The client session ID.
  1125. * @param string $sesskey The client session key.
  1126. * @param int $userid The user's id
  1127. * @param int $groupid The group's id
  1128. * @return affectRecord Return data (affectRecord object) to be converted into a
  1129. * specific data format for sending to the client.
  1130. */
  1131. function affect_user_to_cohort($client, $sesskey, $userid, $groupid) {
  1132. global $CFG;
  1133. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1134. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1135. }
  1136. if (!$group = ws_get_record('cohort', 'id', $groupid)) {
  1137. return $this->error(get_string('ws_cohortunknown','local_wspp','id='.$groupid));
  1138. }
  1139. /// Check for correct permissions.
  1140. if (!$this->has_capability('moodle/cohort:manage', CONTEXT_COURSECAT, $group->contextid)) {
  1141. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1142. }
  1143. if (!$user = ws_get_record("user", "id", $userid)) {
  1144. return $this->error(get_string('ws_userunknown','local_wspp','id='.$userid));
  1145. }
  1146. if ($CFG->wspp_using_moodle20) {
  1147. require_once ($CFG->dirroot.'/cohort/lib.php');
  1148. }else
  1149. return $this->error(get_string('ws_moodle20only', 'local_wspp'));
  1150. cohort_add_member($group->id,$user->id);
  1151. $resp->status = 1;
  1152. return $resp;
  1153. }
  1154. /**remove user from cohort
  1155. * @uses $CFG
  1156. * @param int $client The client session ID.
  1157. * @param string $sesskey The client session key.
  1158. * @param int $userid The user's id
  1159. * @param int $groupid The group's id
  1160. * @return affectRecord Return data (affectRecord object) to be converted into a
  1161. * specific data format for sending to the client.
  1162. */
  1163. function remove_user_from_cohort($client, $sesskey, $userid, $groupid) {
  1164. global $CFG;
  1165. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1166. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1167. }
  1168. if (!$group = ws_get_record('cohort', 'id', $groupid)) {
  1169. return $this->error(get_string('ws_cohortunknown','local_wspp','id='.$groupid));
  1170. }
  1171. /// Check for correct permissions.
  1172. if (!$this->has_capability('moodle/cohort:manage', CONTEXT_COURSECAT, $group->contextid)) {
  1173. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1174. }
  1175. if (!$user = ws_get_record("user", "id", $userid)) {
  1176. return $this->error(get_string('ws_userunknown','local_wspp','id='.$userid));
  1177. }
  1178. if ($CFG->wspp_using_moodle20) {
  1179. require_once ($CFG->dirroot.'/cohort/lib.php');
  1180. }else
  1181. return $this->error(get_string('ws_moodle20only', 'local_wspp'));
  1182. cohort_remove_member($group->id,$user->id);
  1183. $resp->status = 1;
  1184. return $resp;
  1185. }
  1186. function affect_group_to_grouping($client, $sesskey, $groupid, $groupingid) {
  1187. global $CFG;
  1188. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1189. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1190. }
  1191. if (!$group = ws_get_record('groups', 'id', $groupid)) {
  1192. return $this->error(get_string('ws_groupunknown','local_wspp','id='.$groupid));
  1193. }
  1194. if (!$grouping = ws_get_record('groupings', 'id', $groupingid)) {
  1195. return $this->error(get_string('ws_groupingunknown','local_wspp','id='.$groupingid));
  1196. }
  1197. if ($group->courseid != $grouping->courseid) {
  1198. $a=new StdClass();
  1199. $a->group=$group->id;
  1200. $a->grouping=$grouping->id;
  1201. return $this->error(get_string('ws_group_grouping_notsamecourse','local_wspp',$a));
  1202. }
  1203. /// Check for correct permissions.
  1204. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $group->courseid)) {
  1205. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1206. }
  1207. if ($CFG->wspp_using_moodle20) {
  1208. // not anymore included by defualt in Moodle 2.0
  1209. require_once ($CFG->dirroot.'/group/lib.php');
  1210. }
  1211. $resp = new stdClass();
  1212. $resp->status = groups_assign_grouping($grouping->id, $group->id);
  1213. return $resp;
  1214. }
  1215. function remove_group_from_grouping($client, $sesskey, $groupid, $groupingid) {
  1216. global $CFG;
  1217. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1218. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1219. }
  1220. if (!$group = ws_get_record('groups', 'id', $groupid)) {
  1221. return $this->error(get_string('ws_groupunknown','local_wspp','id='.$groupid));
  1222. }
  1223. if (!$grouping = ws_get_record('groupings', 'id', $groupingid)) {
  1224. return $this->error(get_string('ws_groupidunknown','local_wspp','id='.$groupid));
  1225. }
  1226. if ($group->courseid != $grouping->courseid) {
  1227. $a=new StdClass();
  1228. $a->group=$group->id;
  1229. $a->grouping=$grouping->id;
  1230. return $this->error(get_string('ws_group_grouping_notsamecourse','local_wspp',$a));
  1231. }
  1232. /// Check for correct permissions.
  1233. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $group->courseid)) {
  1234. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1235. }
  1236. //$this->debug_output("RGG gid=$group->id gpip= $grouping->id");
  1237. if ($CFG->wspp_using_moodle20) {
  1238. // not anymore included by defualt in Moodle 2.0
  1239. require_once ($CFG->dirroot.'/group/lib.php');
  1240. }
  1241. $resp = new stdClass();
  1242. $resp->status = groups_unassign_grouping($grouping->id, $group->id);
  1243. return $resp;
  1244. }
  1245. /**
  1246. * Add group to course
  1247. * @uses $CFG
  1248. * @param int $client The client session ID.
  1249. * @param string $sesskey The client session key.
  1250. * @param int $groupid The group's id
  1251. * @param int $courseid The course's id
  1252. * @return affectRecord Return data (affectRecord object) to be converted into a
  1253. * specific data format for sending to the client.
  1254. */
  1255. function affect_group_to_course($client, $sesskey, $groupid, $courseid,$idfield='id') {
  1256. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1257. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1258. }
  1259. if (!$course = ws_get_record('course', $idfield, $courseid)) {
  1260. return $this->error(get_string('ws_courseunknown','local_wspp',"id=".$courseid ));
  1261. }
  1262. /// Check for correct permissions.
  1263. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $course->id)) {
  1264. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1265. }
  1266. //verify if this grup exists
  1267. if (!$group = ws_get_record('groups', 'id', $groupid)) {
  1268. return $this->error(get_string('ws_groupunknown','local_wspp','id='.$groupid));
  1269. }
  1270. //verify if this group is assigned of any course
  1271. if ($group->courseid > 0) {
  1272. $a=new StdClass();
  1273. $a->group=$group->id;
  1274. $a->course=$groupe->courseid;
  1275. return $this->error("ws_groupalreadyaffected","wspp",$a);
  1276. }
  1277. $group->courseid = $courseid;
  1278. //verify if the update operation is done
  1279. $resp = new stdClass();
  1280. $resp->status = ws_update_record('groups', $group);
  1281. return $resp;
  1282. }
  1283. function affect_grouping_to_course($client, $sesskey, $groupid, $courseid,$idfield='id') {
  1284. /**
  1285. * Add group to course
  1286. * @uses $CFG
  1287. * @param int $client The client session ID.
  1288. * @param string $sesskey The client session key.
  1289. * @param int $groupid The group's id
  1290. * @param int $courseid The course's id
  1291. * @return affectRecord Return data (affectRecord object) to be converted into a
  1292. * specific data format for sending to the client.
  1293. */
  1294. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1295. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1296. }
  1297. if (!$course = ws_get_record('course', $idfield, $courseid)) {
  1298. return $this->error(get_string('ws_courseunknown','local_wspp',"id=".$courseid ));
  1299. }
  1300. /// Check for correct permissions.
  1301. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $course->id)) {
  1302. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1303. }
  1304. //verify if this grup exists
  1305. if (!$group = ws_get_record('groupings', 'id', $groupid)) {
  1306. return $this->error(get_string('ws_groupingunknown','local_wspp','id='.$groupid));
  1307. }
  1308. //verify if this group is assigned of any course
  1309. if ($group->courseid > 0) {
  1310. $a=new StdClass();
  1311. $a->group=$group->id;
  1312. $a->course=$groupe->courseid;
  1313. return $this->error("ws_groupingalreadyaffected","wspp",$a);
  1314. }
  1315. $resp = new stdClass();
  1316. $resp->status =ws_update_record('groupings', $group);
  1317. return $resp;
  1318. }
  1319. function get_my_id($client, $sesskey) {
  1320. global $USER;
  1321. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  1322. return -1; //invalid Moodle's ID
  1323. }
  1324. return $USER->id;
  1325. }
  1326. function get_groups_bycourse($client, $sesskey, $courseid, $idfield = 'idnumber') {
  1327. global $USER;
  1328. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1329. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1330. }
  1331. if (!$course = ws_get_record('course', $idfield, $courseid)) {
  1332. return $this->error(get_string('ws_courseunknown','local_wspp',$idfield."=".$courseid ));
  1333. }
  1334. if (! $this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $course->id))
  1335. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1336. // deprecated in Moodle 1.9
  1337. // gone in Moodle 2.0
  1338. //$res = get_groups($course->id);
  1339. $res=groups_get_all_groups($course->id);
  1340. if (!$res)
  1341. return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  1342. return filter_groups($client, $res);
  1343. }
  1344. function get_groupings_bycourse($client, $sesskey, $courseid, $idfield = 'idnumber') {
  1345. global $USER;
  1346. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1347. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1348. }
  1349. if (!$course = ws_get_record('course', $idfield, $courseid)) {
  1350. return $this->error(get_string('ws_courseunknown','local_wspp',$idfield."=".$courseid ));
  1351. }
  1352. if (! $this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $course->id))
  1353. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1354. // deprecated in Moodle 1.9
  1355. // gone in Moodle 2.0
  1356. //$res = get_groups($course->id);
  1357. $res=groups_get_all_groupings($course->id);
  1358. if (!$res)
  1359. return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  1360. return filter_groupings($client, $res);
  1361. }
  1362. /**
  1363. * Returns the user's groups in all courses (not found in Moodle API)
  1364. *
  1365. * @uses $CFG
  1366. * @param int $uid The id of the user as found in the 'user' table.
  1367. * if empty, return logged in user's groups
  1368. * if uid is not equal to current's user id, current user must be admin.
  1369. * @return array of object
  1370. */
  1371. function get_my_groups($client, $sesskey, $uinfo = '', $idfield = "idnumber") {
  1372. global $USER, $CFG;
  1373. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  1374. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1375. }
  1376. $cuid = $USER->id;
  1377. if (!empty($uinfo)) {
  1378. // find userid if not current user
  1379. if (!$user = ws_get_record('user', $idfield, $uinfo))
  1380. return $this->error(get_string('ws_userunknown','local_wspp',$idfield."=".$uinfo));
  1381. $uid = $user->id;
  1382. } else
  1383. $uid = $cuid; //use current user and ignore $idfield
  1384. //only an user that can login as another can request for others
  1385. if ($uid != $cuid) {
  1386. if (!$this->has_capability('moodle/user:loginas', CONTEXT_SYSTEM, 0)) {
  1387. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1388. }
  1389. }
  1390. if ($CFG->wspp_using_moodle20)
  1391. $from=" {groups} g,{groups_members} m" ;
  1392. else
  1393. $from="{$CFG->prefix}groups g,{$CFG->prefix}groups_members m";
  1394. $sql = "SELECT g.* " .
  1395. "FROM $from
  1396. WHERE g.id = m.groupid
  1397. AND m.userid = '$uid'
  1398. ORDER BY name ASC";
  1399. $res = ws_get_records_sql($sql);
  1400. return filter_groups($client, $res);
  1401. }
  1402. /**
  1403. * Returns the user's cohorts
  1404. *
  1405. * @uses $CFG
  1406. * @param int $uid The id of the user as found in the 'user' table.
  1407. * if empty, return logged in user's groups
  1408. * if uid is not equal to current's user id, current user must be admin.
  1409. * @return array of object
  1410. */
  1411. function get_my_cohorts($client, $sesskey, $uinfo = '', $idfield = "idnumber") {
  1412. global $USER, $CFG;
  1413. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  1414. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1415. }
  1416. $cuid = $USER->id;
  1417. if (!empty($uinfo)) {
  1418. // find userid if not current user
  1419. if (!$user = ws_get_record('user', $idfield, $uinfo))
  1420. return $this->error(get_string('ws_userunknown','local_wspp',$idfield."=".$uinfo));
  1421. $uid = $user->id;
  1422. } else
  1423. $uid = $cuid; //use current user and ignore $idfield
  1424. //only an user that can login as another can request for others
  1425. if ($uid != $cuid) {
  1426. if (!$this->has_capability('moodle/user:loginas', CONTEXT_SYSTEM, 0)) {
  1427. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1428. }
  1429. }
  1430. $from=" {cohort} g,{cohort_members} m" ;
  1431. $sql = "SELECT g.* " .
  1432. "FROM $from
  1433. WHERE g.id = m.cohortid
  1434. AND m.userid = '$uid'
  1435. ORDER BY name ASC";
  1436. $res = ws_get_records_sql($sql);
  1437. return filter_cohorts($client, $res);
  1438. }
  1439. function get_last_changes($client, $sesskey, $courseid, $idfield = 'idnumber', $limit = 10) {
  1440. global $CFG, $USER;
  1441. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1442. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1443. }
  1444. if (!$course = ws_get_record('course', $idfield, $courseid)) {
  1445. return $this->error(get_string('ws_courseunknown','local_wspp',$idfield."=".$courseid ));
  1446. }
  1447. $cuid = $USER->id;
  1448. $isTeacher = $this->has_capability("moodle/course:update", CONTEXT_COURSE, $course->id);
  1449. $fmtdate=get_string('ws_sqlstrftimedatetime','local_wspp'); // '%d/%m/%Y %H:%i:%s'
  1450. //$this->debug_output('date='.$fmtdate);
  1451. //must have id as first field for proper array indexing !
  1452. $sqlAct =<<<EOS
  1453. SELECT DISTINCT {$CFG->prefix}log.id,module, {$CFG->prefix}log.url, info,
  1454. time,firstname,lastname,email,
  1455. action , cmid, course, time, FROM_UNIXTIME( time, '$fmtdate' ) AS DATE_J
  1456. FROM {$CFG->prefix}log inner join {$CFG->prefix}user on
  1457. {$CFG->prefix}log.userid={$CFG->prefix}user.id
  1458. WHERE course =$course->id
  1459. and (action like '%add%' or action like '%update%')
  1460. and cmid <>0
  1461. and module <>'label'
  1462. ORDER BY time DESC
  1463. EOS;
  1464. $return = array ();
  1465. //$this->debug_output($sqlAct);
  1466. if (!$resultAct = ws_get_records_sql($sqlAct)) {
  1467. return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
  1468. }
  1469. //$this->debug_output(print_r($resultAct,true));
  1470. foreach ($resultAct as $rowAct) {
  1471. if ($limit-- <= 0)
  1472. break;
  1473. $id_cmid = $rowAct->cmid;
  1474. $id_autre = "cmid=$id_cmid ";
  1475. $sql =<<<EOS
  1476. select {$CFG->prefix}modules.*,{$CFG->prefix}course_modules.instance,{$CFG->prefix}course_modules.visible
  1477. from {$CFG->prefix}course_modules,{$CFG->prefix}modules
  1478. where course=$course->id
  1479. and {$CFG->prefix}course_modules.module={$CFG->prefix}modules.id
  1480. and {$CFG->prefix}course_modules.id =$id_cmid
  1481. EOS;
  1482. // toutes pour un prof, seulement les ressources visibles pour un ???tudiant !!!
  1483. if (!$isTeacher) {
  1484. $sql .= " and {$CFG->prefix}course_modules.visible=1";
  1485. }
  1486. if ($row = ws_get_record_sql($sql)) {
  1487. $sql1 =<<<EOS
  1488. select * from {$CFG->prefix}{$row->name}
  1489. where id={$row->instance}
  1490. and course=$course->id
  1491. EOS;
  1492. $result1 = ws_get_records_sql($sql1);
  1493. foreach ($result1 as $row1) {
  1494. if ($row1->name) {
  1495. //retouche ?id=cc&r=xx ou ?f=xx
  1496. switch ($row->name) {
  1497. case 'forum' :
  1498. $question = "view.php?f=$row1->id";
  1499. break;
  1500. case 'assignment' :
  1501. $question = "submissions.php?id=$id_cmid";
  1502. break;
  1503. default :
  1504. $question = "view.php?id=$course->id&r=$row1->id";
  1505. }
  1506. $ret = new StdClass;
  1507. $ret->error = '';
  1508. $ret->id = $rowAct->id;
  1509. $ret->courseid = $courseid;
  1510. $ret->instance = $row->instance;
  1511. $ret->resid = $row1->id;
  1512. $ret->name = $row1->name;
  1513. $ret->date = $rowAct->DATE_J;
  1514. $ret->timestamp = $rowAct->time;
  1515. $ret->type = $rowAct->action;
  1516. $ret->author = "$rowAct->firstname $rowAct->lastname";
  1517. $ret->url = $rowAct->url;
  1518. $ret->link = $CFG->wwwroot . '/mod/' . $row->name . '/' . $question;
  1519. $ret->visible = $row->visible;
  1520. $return[] = $ret;
  1521. }
  1522. }
  1523. }
  1524. }
  1525. //$this->debug_output(print_r($return, true));
  1526. return filter_changes($client, $return);
  1527. }
  1528. /**
  1529. * return all logged actions of user in one course or any course
  1530. */
  1531. function get_activities($client, $sesskey, $userid, $useridfield, $courseid, $courseidfield, $limit, $doCount = 0) {
  1532. global $USER,$CFG;
  1533. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1534. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1535. }
  1536. //resolve user criteria to an user Moodle's id
  1537. if (!$user = ws_get_record('user', $useridfield, $userid)) {
  1538. return $this->error(get_string('ws_userunknown','local_wspp',$useridfield."=".$userid));
  1539. }
  1540. $cuid = $USER->id;
  1541. if ($courseid) {
  1542. //resolve course criteria to a course Moodle's id
  1543. if (!$course = ws_get_record('course', $courseidfield, $courseid))
  1544. return $this->error(get_string('ws_courseunknown','local_wspp',$courseidfield."=".$courseid ));
  1545. $sql_course = " AND l.course=$course->id ";
  1546. $canRead = $this->has_capability('coursereport/log:view', CONTEXT_COURSE, $course->id);
  1547. } else {
  1548. $sql_course = '';
  1549. $canRead = $this->has_capability('coursereport/log:view', CONTEXT_SYSTEM, 0);
  1550. }
  1551. if (($cuid != $user->id) && !$canRead) {
  1552. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1553. }
  1554. if ($doCount) // caution result MUST have some id value to fetch result later
  1555. $sql_select = " SELECT 1,count(l.userid) as CPT ";
  1556. else {
  1557. $fmtdate=get_string('ws_sqlstrftimedatetime','local_wspp'); // '%d/%m/%Y %H:%i:%s'
  1558. $sql_select =<<<EOS
  1559. SELECT l.*,u.auth,u.firstname,u.lastname,u.email,
  1560. u.firstaccess, u.lastaccess, u.lastlogin, u.currentlogin,
  1561. FROM_UNIXTIME(l.time,'$fmtdate' )as DATE,
  1562. FROM_UNIXTIME(u.lastaccess,'$fmtdate' )as DLA,
  1563. FROM_UNIXTIME(u.firstaccess,'$fmtdate' )as DFA,
  1564. FROM_UNIXTIME(u.lastlogin,'$fmtdate' )as DLL,
  1565. FROM_UNIXTIME(u.currentlogin,'$fmtdate' )as DCL
  1566. EOS;
  1567. }
  1568. $sql =<<<EOSS
  1569. $sql_select
  1570. FROM {$CFG->prefix}log l , {$CFG->prefix}user u
  1571. WHERE l.userid = u.id
  1572. AND u.id = $user->id
  1573. $sql_course
  1574. ORDER BY l.time DESC
  1575. EOSS;
  1576. //$this->debug_output($sql);
  1577. $res = ws_get_records_sql($sql, '', $limit);
  1578. //$this->debug_output(print_r($res,true));
  1579. if ($doCount)
  1580. return $res['1']->CPT; //caution
  1581. else
  1582. return filter_activities($client, $res);
  1583. //reconvert dates using userdate()
  1584. }
  1585. /**
  1586. * added rev 1.6.2
  1587. */
  1588. function get_assignment_submissions ($client,$sesskey,$assignmentid,$userids=array(),$useridfield='idnumber',$timemodified=0,$zipfiles=1) {
  1589. global $CFG, $USER;
  1590. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1591. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1592. }
  1593. //get the assignment record
  1594. if (!$assignment = ws_get_record("assignment", "id", $assignmentid)) {
  1595. return $this->error(get_string('ws_assignmentunknown','local_wspp','id='.$assignmentid));
  1596. }
  1597. /// Check for correct permissions.
  1598. if (!$this->has_capability('mod/assignment:grade', CONTEXT_COURSE, $assignment->course)) {
  1599. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1600. }
  1601. //set up all required variables any error is fatal
  1602. if (!$course = ws_get_record("course", "id", $assignment->course))
  1603. return $this->error(get_string('ws_databaseinconsistent','local_wspp'));
  1604. if (!$cm = get_coursemodule_from_instance("assignment", $assignment->id, $course->id))
  1605. return $this->error(get_string('ws_databaseinconsistent','local_wspp'));
  1606. if( !$context = get_context_instance(CONTEXT_COURSE, $assignment->course))
  1607. return $this->error(get_string('ws_databaseinconsistent','local_wspp'));
  1608. $ret=array();
  1609. //champs a envoyer ?  la PF
  1610. $fields='u.id, u.username,u.idnumber, u.email';
  1611. $roleid=5; //students
  1612. $moodleUserIds=array();
  1613. if (!empty($userids)) {
  1614. foreach ($userids as $userid) {
  1615. //$this->debug_output($userid.' '.$useridfield);
  1616. //caution : alias u is not set in ws_get_record, so add it !!!
  1617. if ($user=ws_get_record('user u',$useridfield,$userid,'','','','',$fields)) {
  1618. $moodleUserIds[$user->id]=$user;
  1619. // $this->debug_output(print_r($user,true));
  1620. }
  1621. }
  1622. }else {
  1623. /// Get all existing participants in this context.
  1624. if ($cm->groupingid==0 || !$cm->groupmembersonly)
  1625. $moodleUserIds = get_role_users($roleid, $context, false,$fields);
  1626. else
  1627. $moodleUserIds=groups_get_grouping_members($cm->groupingid,$fields);
  1628. }
  1629. //$this->debug_output(print_r($moodleUserIds,true));
  1630. require_once($CFG->libdir.'/filelib.php');
  1631. require_once("$CFG->dirroot/mod/assignment/lib.php");
  1632. require_once("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php");
  1633. $assignmentclass = "assignment_$assignment->assignmenttype";
  1634. $assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm, $course);
  1635. foreach($moodleUserIds as $studentid=>$student) {
  1636. // Get the submission for this student
  1637. $submission = $assignmentinstance->get_submission($studentid);
  1638. if($submission && $submission->timemodified > $timemodified) {
  1639. $submission->useridnumber=$student->idnumber;
  1640. $submission->userusername=$student->username;
  1641. $submission->useremail=$student->email;
  1642. //if upload of uploadsingle, submissions are in files
  1643. //if online, submission is in data1
  1644. $submission->assignmenttype=$assignment->assignmenttype;
  1645. $submission->files=array();
  1646. //collect file(s)
  1647. if ($basedir = $assignmentinstance->file_area_name($studentid)) {
  1648. $basedir=$CFG->dataroot.'/'.$basedir;
  1649. if ($files = get_directory_list($basedir,'',true,false,true)) {
  1650. $numfiles=0;
  1651. foreach ($files as $key => $value) {
  1652. $file=new fileRecord();
  1653. $file->setFilename($value);
  1654. $file->setFilePath($basedir);
  1655. $file->setFileurl(get_file_url("$basedir/$value", array('forcedownload'=>1)));
  1656. if ($binary = file_get_contents("$basedir/$value")) {
  1657. $file->setFilecontent(base64_encode( $binary ));
  1658. $file->setFilesize(strlen($binary));
  1659. $numfiles++;
  1660. }else {
  1661. $file->setFilecontent('');
  1662. $file->setFilesize(0);
  1663. }
  1664. $submission->files[]=$file;
  1665. }
  1666. //for some reasons this field is 0 in table mdl_assignment_submissions
  1667. $submission->numfiles=$numfiles;
  1668. }
  1669. }
  1670. $ret[]=$submission;
  1671. }
  1672. }
  1673. return $ret;
  1674. }
  1675. /**
  1676. * Enrol users with the given role name in the given course
  1677. *
  1678. * @param int $client The client session ID.
  1679. * @param string $sesskey The client session key.
  1680. * @param string $rolename shortname of role to affect
  1681. * @param string $courseid The course ID number to enrol students in <- changed to category...
  1682. * @param string $courseidfield field to use to identify course (idnumber,id, shortname)
  1683. * @param array $userids An array of input user idnumber values for enrolment.
  1684. * @param string $idfield identifier used for users . Note that $courseid is expected
  1685. * to contains an idnumber and not Moodle id.
  1686. * @return array Return data (user_student records) to be converted into a
  1687. * specific data format for sending to the client.
  1688. */
  1689. function affect_role_incourse($client, $sesskey, $rolename, $courseid, $courseidfield, $userids, $useridfield = 'idnumber', $enrol = true) {
  1690. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1691. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1692. }
  1693. global $CFG, $USER;
  1694. if (!($role = ws_get_record('role', 'shortname', $rolename))) {
  1695. return $this->error(get_string('ws_roleunknown','local_wspp',$rolename));
  1696. }
  1697. //$groupid = 0; // for the role_assign function (what does this ? not anymore in Moodle 2.0
  1698. if (!$course = ws_get_record('course', $courseidfield, $courseid)) {
  1699. return $this->error(get_string('ws_courseunknown','local_wspp',$courseidfield."=".$courseid ));
  1700. }
  1701. $context = get_context_instance(CONTEXT_COURSE, $course->id);
  1702. if (!has_capability("moodle/role:assign", $context))
  1703. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  1704. //not anymore in Moodle 2.0 ...
  1705. if (!empty($course->enrolperiod)) {
  1706. $timestart = time();
  1707. $timeend = $timestart + $course->enrolperiod;
  1708. } else {
  1709. $timestart = $timeend = 0;
  1710. }
  1711. //$this->debug_output("IDS=" . print_r($userids, true) . "\n" . $enrol ."\n ctx=".$context->id);
  1712. $return = array ();
  1713. if (!empty ($userids)) {
  1714. foreach ($userids as $userid) {
  1715. $st = new enrolRecord();
  1716. if (!$leuser = ws_get_record('user', $useridfield, $userid)) {
  1717. $st->error =get_string('ws_userunknown','local_wspp',$useridfield."=".$userid);
  1718. } else {
  1719. $st->userid = $leuser-> $useridfield; //return the sent value
  1720. $st->course = $course-> $courseidfield;
  1721. $st->timestart = $timestart;
  1722. $st->timeend = $timeend;
  1723. if ($enrol) {
  1724. if (!ws_role_assign($role->id, $leuser->id, $context->id, $timestart, $timeend,$course)) {
  1725. $st->error = "error enroling";
  1726. $op = "error enroling " . $st->userid . " to " . $st->course;
  1727. } else {
  1728. $st->enrol = "webservice";
  1729. $op = $rolename . " " . $st->userid . " added to " . $st->course;
  1730. }
  1731. } else {
  1732. if (!ws_role_unassign($role->id, $leuser->id, $context->id,$course)) {
  1733. $st->error = "error unenroling";
  1734. $op = "error unenroling " . $st->userid . " from " . $st->course;
  1735. } else {
  1736. $st->enrol = "no";
  1737. $op = $rolename . " " . $st->userid . " removed from " . $st->course;
  1738. }
  1739. }
  1740. }
  1741. $return[] = $st;
  1742. if ($CFG->ws_logdetailedoperations)
  1743. add_to_log(SITEID, 'webservice', 'webservice pp', '', $op);
  1744. }
  1745. } else {
  1746. $st = new enrolRecord();
  1747. $st->error = get_string('ws_nothingtodo','local_wspp');
  1748. $return[] = $st;
  1749. }
  1750. //$this->debug_output("ES" . print_r($return, true));
  1751. return $return;
  1752. }
  1753. /**
  1754. * Edit user records (add/update/delete).
  1755. * FIXED in rev 1.5.8
  1756. * @uses $CFG
  1757. * @param int $client The client session ID.
  1758. * @param string $sesskey The client session key.
  1759. * @param array $users An array of user records (objects or arrays) for editing
  1760. * (including opertaion to perform).
  1761. * @return array Return data (user record) to be converted into a
  1762. * specific data format for sending to the client.
  1763. *
  1764. * important for consistency with others edit functions, Moodle internal id number is used
  1765. * to identify user to be updated, deleted. see update_user, delete_user ... to use other fields
  1766. * such as idnumber of username
  1767. */
  1768. function edit_users($client, $sesskey, $users) {
  1769. global $CFG, $USER;
  1770. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1771. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1772. }
  1773. $rusers = array ();
  1774. //$this->debug_output('Attempting to update user IDS: ' . print_r($users, true));
  1775. if (!empty ($users)) {
  1776. foreach ($users->users as $user) {
  1777. $ruser = new stdClass();
  1778. //$this->debug_output('traitement de ' . print_r($user, true));
  1779. switch (trim(strtolower($user->action))) {
  1780. case 'add' :
  1781. if (!$this->has_capability('moodle/user:create', CONTEXT_SYSTEM, 0)) {
  1782. $ruser->error=get_string('ws_operationnotallowed','local_wspp');
  1783. break;
  1784. }
  1785. // fix record if needed and check for missing values or database collision
  1786. if ($errmsg=ws_checkuserrecord($user,true)) {
  1787. $ruser->error=$errmsg;
  1788. break;
  1789. }
  1790. $user->timecreated = time();
  1791. $user->timemodified = $user->timecreated;
  1792. if ($userid=ws_insert_record('user',$user)) {
  1793. $ruser = ws_get_record('user','id',$userid);
  1794. $this->debug_output('inserion ok'.print_r($ruser,true));
  1795. events_trigger('user_created', $ruser);
  1796. }else {
  1797. $ruser->error=get_string('ws_errorcreatinguser','local_wspp',$user->idnumber);
  1798. $this->debug_output('insertion KO '.print_r($user,true));
  1799. }
  1800. $this->debug_output('traitement de ' . print_r($ruser, true));
  1801. break;
  1802. case 'update' :
  1803. if (!$this->has_capability('moodle/user:update', CONTEXT_SYSTEM, 0)) {
  1804. $ruser->error=get_string('ws_operationnotallowed','local_wspp');
  1805. break;
  1806. }
  1807. if (! $olduser = ws_get_record('user', 'id', $user->id)) {
  1808. $rcourse->error = get_string('ws_userunknown','local_wspp',"id=".$user->id );
  1809. break;
  1810. }
  1811. $ruser=$user;
  1812. // fix record if needed and check for missing values or database collision
  1813. if ($errmsg=ws_checkuserrecord($user,false)) {
  1814. $ruser->error=$errmsg;
  1815. break;
  1816. }
  1817. $user->timemodified = time();
  1818. //GROS PB avec le record rempli de 0 !!!!
  1819. foreach($user as $key=>$value) { // rev 1.5.15 must ignore empty values ! serious flaw !
  1820. if (empty($value)) unset ($user->$key);
  1821. }
  1822. /// Update values in the $user database record with what
  1823. /// the client supplied.
  1824. if (ws_update_record('user', $user)) {
  1825. $ruser = ws_get_record('user', 'id', $user->id);
  1826. events_trigger('user_updated', $ruser);
  1827. } else {
  1828. $ruser->error=get_string('ws_errorupdatinguser','local_wspp',$user->id);
  1829. }
  1830. break;
  1831. case 'delete' :
  1832. /// Deleting an existing user.
  1833. if (!$this->has_capability('moodle/user:delete', CONTEXT_SYSTEM, 0)) {
  1834. $ruser->error=get_string('ws_operationnotallowed','local_wspp');
  1835. break;
  1836. }
  1837. if (! $user = ws_get_record('user', 'id', $user->id)) {
  1838. $ruser->error = get_string('ws_userunknown','local_wspp',"id=".$user->id );
  1839. break;
  1840. }
  1841. $ruser = $user;
  1842. if ($user->deleted) // rev 1.7
  1843. $ruser->error=get_string('ws_erroralreadydeleteduser','local_wspp',$user->id);
  1844. else
  1845. if (!delete_user($user)) {
  1846. $ruser->error=get_string('ws_errordeletinguser','local_wspp',$user->idnumber);
  1847. }
  1848. break;
  1849. default :
  1850. $ruser->error=get_string('ws_invalidaction','local_wspp',$user->action);
  1851. }
  1852. $rusers[] = $ruser;
  1853. }
  1854. }
  1855. return filter_users($client,$rusers,0);
  1856. }
  1857. /**
  1858. * Edit course records (add/update/delete).
  1859. * TESTED and fixed in rev 1.5.8 PP
  1860. * @uses $CFG
  1861. * @param int $client The client session ID.
  1862. * @param string $sesskey The client session key.
  1863. * @param array $courses An array of course records (objects or arrays) for editing
  1864. * (including opertaion to perform).
  1865. * @return array Return data (course record) to be converted into a specific
  1866. * data format for sending to the client.
  1867. * * important for consistency with others edit functions, Moodle internal id number is used
  1868. * to identify course to be updated, deleted. see update_course, delete_course ... to use other fields
  1869. * such as idnumber or shortname
  1870. */
  1871. function edit_courses($client, $sesskey, $courses) {
  1872. global $CFG, $USER;
  1873. require_once ($CFG->dirroot . '/course/lib.php');
  1874. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1875. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1876. }
  1877. $ret = array ();
  1878. // $this->debug_output("EDC".print_r($courses,true));
  1879. if (!empty ($courses)) {
  1880. foreach ($courses->courses as $course) {
  1881. $rcourse = new stdClass;
  1882. $rcourse->error="";
  1883. // $this->debug_output("EDC".print_r($course,true));
  1884. switch (trim(strtolower($course->action))) {
  1885. case 'add' :
  1886. /// Adding a new course.
  1887. // fix course record if needed and check for missing values or database collision
  1888. if ($errmsg=ws_checkcourserecord($course,true)) {
  1889. $rcourse->error=$errmsg;
  1890. break;
  1891. }
  1892. /// Now check for correct permissions.
  1893. if (!$this->has_capability("moodle/course:create",CONTEXT_COURSECAT,$course->category)) {
  1894. $rcourse->error=get_string('ws_operationnotallowed','local_wspp');
  1895. break;
  1896. }
  1897. if ($courseadd=create_course($course)) {
  1898. $rcourse = $courseadd;
  1899. }else {
  1900. $rcourse->error=get_string('ws_errorcreatingcourse','local_wspp',$course->idnumber);
  1901. }
  1902. break;
  1903. case 'update' :
  1904. /// Updating an existing course.
  1905. if (! $oldcourse = ws_get_record('course', 'id', $course->id)) {
  1906. $rcourse->error = get_string('ws_courseunknown','local_wspp',"idnumber=".$course->id );
  1907. break;
  1908. }
  1909. $rcourse=$course;
  1910. if (!$this->has_capability('moodle/course:update', CONTEXT_COURSE,$oldcourse->id)) {
  1911. $rcourse->error=get_string('ws_operationnotallowed','local_wspp');
  1912. break;
  1913. }
  1914. //set Moodle internal id
  1915. // fix course record if needed and check for missing values or database collision
  1916. if ($errmsg=ws_checkcourserecord($course,false)) {
  1917. $rcourse->error=$errmsg;
  1918. break;
  1919. }
  1920. $course->timemodified = time(); //not done in Moodle 1.9 update_course ?
  1921. //GROS PB avec le record rempli de 0 !!!!
  1922. foreach($course as $key=>$value) {
  1923. if (empty($value)) unset ($course->$key);
  1924. }
  1925. // in Moodle 2.0 update_course returns nothing !
  1926. if (!ws_update_course($course)) {
  1927. $rcourse->error=get_string('ws_errorupdatingcourse','local_wspp',$course->id);
  1928. } else {
  1929. $rcourse = ws_get_record('course', 'id', $course->id); //return new value
  1930. break;
  1931. }
  1932. //TODO if the category has changed ....
  1933. if ($oldcourse->category != $course->category) {
  1934. //do the move via course/lib.php#move_courses (array($course->id),$course->category)
  1935. // caution this function may send somme notify errors ...
  1936. }
  1937. break;
  1938. case 'delete' :
  1939. /// Deleting an existing course
  1940. if (! $course = ws_get_record('course', 'id', $course->id)) {
  1941. $rcourse->error = get_string('ws_courseunknown','local_wspp',"id=".$course->id );
  1942. break;
  1943. }
  1944. $rcourse=$course;
  1945. //$this->debug_output("DC".print_r($course,true));
  1946. /// Now check for correct permissions.
  1947. if (!$this->has_capability("moodle/course:delete",CONTEXT_COURSECAT,$course->category)) {
  1948. $rcourse->error=get_string('ws_operationnotallowed','local_wspp');
  1949. break;
  1950. }
  1951. if (!delete_course($course->id,false)) {
  1952. $rcourse->error=get_string('ws_errordeletingcourse','local_wspp',$course->id);
  1953. }
  1954. break;
  1955. default :
  1956. $rcourse->error=get_string('ws_invalidaction','local_wspp',$course->action);
  1957. }
  1958. $ret[] = $rcourse;
  1959. }
  1960. }
  1961. return $ret;
  1962. }
  1963. /**
  1964. * Edit grouping records (add/update/delete).
  1965. * @uses $CFG
  1966. * @param int $client The client session ID.
  1967. * @param string $sesskey The client session key.
  1968. * @param array $groupings An array of grouping records (objects or arrays) for editing
  1969. * (including operation to perform).
  1970. * @return array Return data (grouping record) to be converted into a
  1971. * specific data format for sending to the client.
  1972. */
  1973. function edit_groupings($client, $sesskey, $groupings) {
  1974. global $CFG;
  1975. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  1976. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  1977. }
  1978. if ($CFG->wspp_using_moodle20) {
  1979. // not anymore included by defualt in Moodle 2.0
  1980. require_once ($CFG->dirroot.'/group/lib.php');
  1981. }
  1982. $rets = array ();
  1983. if (!empty ($groupings)) {
  1984. foreach ($groupings->groupings as $grouping) {
  1985. $ret = new stdClass;
  1986. $ret->error="";
  1987. switch (trim(strtolower($grouping->action))) {
  1988. case 'add' :
  1989. /// Adding a new group.
  1990. if (!empty($grouping->courseid)) {
  1991. if (! $course = ws_get_record('course', 'id', $grouping->courseid)) {
  1992. $ret->error = get_string('ws_courseunknown','local_wspp',"id=".$grouping->courseid );
  1993. break;
  1994. }
  1995. if (ws_get_record('groupings','name',$grouping->name,'courseid',$grouping->courseid)) {
  1996. $ret->error = get_string('ws_duplicategroupingname','local_wspp',$grouping->name );
  1997. break;
  1998. }
  1999. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $grouping->courseid)) {
  2000. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2001. break;
  2002. }
  2003. } else {
  2004. /// Check for correct permissions. at site level
  2005. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_SYSTEM, 0)) {
  2006. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2007. break;
  2008. }
  2009. }
  2010. if ($id=groups_create_grouping($grouping)) {
  2011. $ret = ws_get_record('groupings', 'id', $id);
  2012. }else {
  2013. $ret->error=get_string('ws_errorcreatinggrouping','local_wspp',$grouping->name);
  2014. }
  2015. break;
  2016. case 'update' :
  2017. /// Updating an existing group
  2018. $ret=$grouping;
  2019. if (! $oldgrouping = ws_get_record('groupings', 'id', $grouping->id)) {
  2020. $ret->error = get_string('ws_groupingunknown','local_wspp',"id=".$grouping->id );
  2021. break;
  2022. }
  2023. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $oldgrouping->courseid)) {
  2024. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2025. break;
  2026. }
  2027. //TODO check for changing course
  2028. foreach ($grouping as $key => $value) {
  2029. if (empty ($value))
  2030. unset($grouping-> $key);
  2031. }
  2032. if (groups_update_grouping($grouping)) {
  2033. $ret = ws_get_record('groupings', 'id', $grouping->id);
  2034. }else {
  2035. $ret->error=get_string('ws_errorupdatinggrouping','local_wspp',$grouping->name);
  2036. }
  2037. break;
  2038. case 'delete' :
  2039. /// Deleting an existing grouping.
  2040. $ret=$grouping;
  2041. if (! $oldgrouping = ws_get_record('groupings', 'id', $grouping->id)) {
  2042. $ret->error = get_string('ws_groupingunknown','local_wspp',"id=".$grouping->id );
  2043. break;
  2044. }
  2045. $ret=$oldgrouping;
  2046. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $oldgrouping->courseid)) {
  2047. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2048. break;
  2049. }
  2050. if (!groups_delete_grouping($grouping)) {
  2051. $ret->error==get_string('ws_errordeletinggrouping','local_wspp',$grouping->id);
  2052. }
  2053. break;
  2054. default :
  2055. $ret->error=get_string('ws_invalidaction','local_wspp',$group->action);
  2056. break;
  2057. }
  2058. $rets[] = $ret;
  2059. }
  2060. }
  2061. return $rets;
  2062. }
  2063. /*
  2064. *****************************************************************************************************************************
  2065. * *
  2066. * START LILLE FUNCTIONS *
  2067. * *
  2068. *****************************************************************************************************************************
  2069. */
  2070. /**
  2071. * Edit group records (add/update/delete).
  2072. * @uses $CFG
  2073. * @param int $client The client session ID.
  2074. * @param string $sesskey The client session key.
  2075. * @param array $groups An array of group records (objects or arrays) for editing
  2076. * (including operation to perform).
  2077. * @return array Return data (group record) to be converted into a
  2078. * specific data format for sending to the client.
  2079. */
  2080. function edit_groups($client, $sesskey, $groups) {
  2081. global $CFG;
  2082. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  2083. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2084. }
  2085. if ($CFG->wspp_using_moodle20) {
  2086. // not anymore included by defualt in Moodle 2.0
  2087. require_once ($CFG->dirroot.'/group/lib.php');
  2088. }
  2089. $rets = array ();
  2090. if (!empty ($groups)) {
  2091. foreach ($groups->groups as $group) {
  2092. $ret = new stdClass;
  2093. $ret->error="";
  2094. switch (trim(strtolower($group->action))) {
  2095. case 'add' :
  2096. /// Adding a new group.
  2097. if (!empty($group->courseid)) {
  2098. if (! $course = ws_get_record('course', 'id', $group->courseid)) {
  2099. $ret->error = get_string('ws_courseunknown','local_wspp',"id=".$group->courseid );
  2100. break;
  2101. }
  2102. if (ws_get_record('groups','name',$group->name,'courseid',$group->courseid)) {
  2103. $ret->error = get_string('ws_duplicategroupname','local_wspp',$group->name );
  2104. break;
  2105. }
  2106. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $group->courseid)) {
  2107. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2108. break;
  2109. }
  2110. } else {
  2111. /// Check for correct permissions. at site level
  2112. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_SYSTEM, 0)) {
  2113. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2114. break;
  2115. }
  2116. }
  2117. if ($id=groups_create_group($group,false)) {
  2118. $ret = ws_get_record('groups', 'id', $id);
  2119. }else {
  2120. $ret->error=get_string('ws_errorcreatinggroup','local_wspp',$group->name);
  2121. }
  2122. break;
  2123. case 'update' :
  2124. /// Updating an existing group
  2125. $ret=$group;
  2126. if (! $oldgroup = ws_get_record('groups', 'id', $group->id)) {
  2127. $ret->error = get_string('ws_groupunknown','local_wspp',"id=".$group->id );
  2128. break;
  2129. }
  2130. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $oldgroup->courseid)) {
  2131. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2132. break;
  2133. }
  2134. //TODO check for changing course
  2135. foreach ($group as $key => $value) {
  2136. if (empty ($value))
  2137. unset($group-> $key);
  2138. }
  2139. if (groups_update_group($group,false)) {
  2140. $ret = ws_get_record('groups', 'id', $group->id);
  2141. }else {
  2142. $ret->error=get_string('ws_errorupdatinggroup','local_wspp',$group->name);
  2143. }
  2144. break;
  2145. case 'delete' :
  2146. /// Deleting an existing group.
  2147. $ret=$group;
  2148. if (! $oldgroup = ws_get_record('groups', 'id', $group->id)) {
  2149. $ret->error = get_string('ws_groupunknown','local_wspp',"id=".$group->id );
  2150. break;
  2151. }
  2152. $ret=$oldgroup;
  2153. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $oldgroup->courseid)) {
  2154. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2155. break;
  2156. }
  2157. if (!groups_delete_group($group)) {
  2158. $ret->error==get_string('ws_errordeletinggroup','local_wspp',$group->id);
  2159. }
  2160. break;
  2161. default :
  2162. $ret->error=get_string('ws_invalidaction','local_wspp',$group->action);
  2163. break;
  2164. }
  2165. $rets[] = $ret;
  2166. }
  2167. }
  2168. return $rets;
  2169. }
  2170. /**
  2171. * Edit cohorts records (add/update/delete).
  2172. * @uses $CFG
  2173. * @param int $client The client session ID.
  2174. * @param string $sesskey The client session key.
  2175. * @param array $groups An array of group records (objects or arrays) for editing
  2176. * (including operation to perform).
  2177. * @return array Return data (group record) to be converted into a
  2178. * specific data format for sending to the client.
  2179. */
  2180. function edit_cohorts($client, $sesskey, $groups) {
  2181. global $CFG;
  2182. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  2183. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2184. }
  2185. if ($CFG->wspp_using_moodle20) {
  2186. require_once ($CFG->dirroot.'/cohort/lib.php');
  2187. }else
  2188. return $this->error(get_string('ws_moodle20only', 'local_wspp'));
  2189. $rets = array ();
  2190. //$this->debug_output(print_r($groups,true));
  2191. if (!empty ($groups)) {
  2192. foreach ($groups->cohorts as $group) {
  2193. $ret = new stdClass;
  2194. $ret->error="";
  2195. switch (trim(strtolower($group->action))) {
  2196. case 'add' :
  2197. /// Adding a new cohort.
  2198. if (!empty($group->categoryid)) {
  2199. if (! $course = ws_get_record('course_categories', 'id', $group->categoryid)) {
  2200. $ret->error = get_string('ws_categoryunknown','local_wspp',"id=".$group->categoryid );
  2201. break;
  2202. }
  2203. $context=get_context_instance(CONTEXT_COURSECAT,$group->categoryid);
  2204. if (! has_capability('moodle/cohort:manage',$context )) {
  2205. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2206. break;
  2207. }
  2208. $group->contextid=$context->id;
  2209. } else {
  2210. /// Check for correct permissions. at site level
  2211. if (!$this->has_capability('moodle/cohort:manage', CONTEXT_SYSTEM, 0)) {
  2212. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2213. break;
  2214. }
  2215. $group->contextid=1; // site cohort
  2216. }
  2217. // cohorts are Moodle 2.0 only so it will raise an execption for sure
  2218. try {
  2219. $id=cohort_add_cohort($group);
  2220. $ret = ws_get_record('cohort', 'id', $id);
  2221. }catch(Exception $e) {
  2222. ws_error_log($ex);
  2223. $ret->error=get_string('ws_errorcreatingcohort','local_wspp',$group->name);
  2224. }
  2225. break;
  2226. case 'update' :
  2227. /// Updating an existing group
  2228. $ret=$group;
  2229. if (! $oldgroup = ws_get_record('cohort', 'id', $group->id)) {
  2230. $ret->error = get_string('ws_cohortunknown','local_wspp',"id=".$group->id );
  2231. break;
  2232. }
  2233. $ret=$oldgroup;
  2234. if ($oldgroup->contextid==1) {
  2235. if (!$this->has_capability('moodle/cohort:manage', CONTEXT_SYSTEM, 0)) {
  2236. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2237. break;
  2238. }
  2239. } else {
  2240. $context=get_context_instance_by_id($oldgroup->contextid);
  2241. if (! has_capability('moodle/cohort:manage',$context )) {
  2242. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2243. break;
  2244. }
  2245. }
  2246. // no way to change these !!!
  2247. $group->id=$oldgroup->id;
  2248. $group->contextid=$oldgroup->contextid;
  2249. foreach ($group as $key => $value) {
  2250. if (empty ($value))
  2251. unset($group-> $key);
  2252. }
  2253. cohort_update_cohort($group);
  2254. $ret = ws_get_record('cohort', 'id', $group->id);
  2255. break;
  2256. case 'delete' :
  2257. /// Deleting an existing cohort
  2258. $ret=$group;
  2259. if (! $oldgroup = ws_get_record('cohort', 'id', $group->id)) {
  2260. $ret->error = get_string('ws_cohortunknown','local_wspp',"id=".$group->id );
  2261. break;
  2262. }
  2263. $ret=$oldgroup;
  2264. if ($oldgroup->contextid==1) {
  2265. if (!$this->has_capability('moodle/cohort:manage', CONTEXT_SYSTEM, 0)) {
  2266. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2267. break;
  2268. }
  2269. } else {
  2270. $context=get_context_instance_by_id($oldgroup->contextid);
  2271. if (! has_capability('moodle/cohort:manage',$context )) {
  2272. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2273. break;
  2274. }
  2275. }
  2276. cohort_delete_cohort($oldgroup);
  2277. break;
  2278. default :
  2279. $ret->error=get_string('ws_invalidaction','local_wspp',$group->action);
  2280. break;
  2281. }
  2282. $rets[] = $ret;
  2283. }
  2284. }
  2285. return $rets;
  2286. }
  2287. /**
  2288. * Edit category records (add/update/delete).
  2289. * @uses $CFG
  2290. * @param int $client The client session ID.
  2291. * @param string $sesskey The client session key.
  2292. * @param array $categories An array of category records (objects or arrays) for editing
  2293. * (including operation to perform).
  2294. * @return array Return data (category record) to be converted into a
  2295. * specific data format for sending to the client.
  2296. */
  2297. function edit_categories($client, $sesskey, $categories) {
  2298. global $CFG;
  2299. require_once ("{$CFG->dirroot}/course/lib.php");
  2300. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  2301. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2302. }
  2303. $rets = array ();
  2304. if (!empty ($categories)) {
  2305. foreach ($categories->categories as $category) {
  2306. $this->debug_output("ac".print_r($category,true));
  2307. $ret=new StdClass();
  2308. switch (trim(strtolower($category->action))) {
  2309. case 'add' :
  2310. /// Adding a new category.
  2311. $ret=$category; // returns proposed values
  2312. if (!empty($category->parent)) {
  2313. /// Check if category with id specified exists
  2314. if (!$parent = ws_get_record('course_categories', 'id', $category->parent)) {
  2315. $ret->error(get_string('ws_categoryunkown','local_wspp',"id=".$category->parent));
  2316. break;
  2317. }
  2318. if (!$this->has_capability('moodle/category:manage', CONTEXT_COURSECAT, $parent->id)) {
  2319. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2320. break;
  2321. }
  2322. } else {
  2323. /// Check for correct permissions.
  2324. if (!$this->has_capability('moodle/category:manage', CONTEXT_SYSTEM, 0)) {
  2325. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2326. break;
  2327. }
  2328. }
  2329. $category->sortorder = 999; // will be fixed later
  2330. //find the max of parent category and add 1
  2331. if (!$cid = ws_insert_record('course_categories', $category)) {
  2332. $ret->error =get_string('ws_errorcreatingcategory','local_wspp',$category->name);
  2333. break;
  2334. }
  2335. $context = get_context_instance(CONTEXT_COURSECAT, $cid);
  2336. mark_context_dirty($context->path);
  2337. fix_course_sortorder(); // Required to build course_categories.depth and .path.
  2338. $ret = ws_get_record('course_categories', 'id', $cid);
  2339. break;
  2340. case 'update' :
  2341. /// Updating an existing category.
  2342. $cid = $category->id;
  2343. if (!$oldcategory = ws_get_record('course_categories', 'id', $cid)) {
  2344. $ret->error = $ret->error(get_string('ws_categoryunkown','local_wspp',"id=".$cid));
  2345. break;
  2346. }
  2347. if (!$this->has_capability("moodle/category:update", CONTEXT_COURSECAT, $cid)) {
  2348. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2349. break;
  2350. }
  2351. if ($oldcategory->parent != $category->parent) {
  2352. if (!$this->has_capability("moodle/category:create", CONTEXT_COURSECAT, $category->parent)) {
  2353. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2354. break;
  2355. }
  2356. if (!$this->has_capability("moodle/category:delete", CONTEXT_COURSECAT, $oldcategory->parent)) {
  2357. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2358. break;
  2359. }
  2360. }
  2361. /// Update values in the category database record with what
  2362. /// the client supplied.
  2363. /**
  2364. foreach ($category as $key => $value) {
  2365. if (!empty ($value)) // rev 1.5.15 must ignore empty values ! serious flaw !
  2366. unset($category-> $key);
  2367. }
  2368. **/
  2369. if ($oldcategory->parent != $category->parent) {
  2370. if (!move_category($cid, $category->parent)) {
  2371. $ret->error = get_string('ws_errorupdatingcategory','local_wspp',$cid);
  2372. break;
  2373. }
  2374. }
  2375. $category->timemodified = time();
  2376. if (! ws_update_record('course_categories', $category)) {
  2377. $ret->error = get_string('ws_errorupdatingcategory','local_wspp',$cid);
  2378. break;
  2379. }
  2380. $ret = ws_get_record('course_categories', 'id', $cid);
  2381. break;
  2382. case 'delete' :
  2383. /// Deleting an existing category.
  2384. $ret->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$category->action);
  2385. break;
  2386. default :
  2387. $ret->error=get_string('ws_invalidaction','local_wspp',$category->action);
  2388. break;
  2389. }
  2390. $rets[] = $ret;
  2391. }
  2392. }
  2393. return $rets;
  2394. }
  2395. /**
  2396. * Edit label records (add/update/delete).
  2397. * @uses $CFG
  2398. * @param int $client The client session ID.
  2399. * @param string $sesskey The client session key.
  2400. * @param array $labels An array of label records (objects or arrays) for editing
  2401. * (including operation to perform).
  2402. * @return array Return data (label record) to be converted into a
  2403. * specific data format for sending to the client.
  2404. */
  2405. function edit_labels($client, $sesskey, $labels) {
  2406. global $CFG;
  2407. require_once ("{$CFG->dirroot}/mod/label/lib.php");
  2408. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  2409. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2410. }
  2411. $rets = array ();
  2412. if (!empty ($labels)) {
  2413. foreach ($labels->labels as $label) {
  2414. switch (trim(strtolower($label->action))) {
  2415. case 'add' :
  2416. /// Adding a new label.
  2417. $ret = $label;
  2418. if (!$course = ws_get_record("course", "id", $label->course)) {
  2419. $ret->error=get_string('ws_courseunknown','local_wspp',"id=".$label->course );
  2420. break;
  2421. }
  2422. /// Check for correct permissions.
  2423. if (!$this->has_capability('moodle/course:manageactivities', CONTEXT_COURSE, $course->id)) {
  2424. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2425. break;
  2426. }
  2427. //function label_add_instance has a bug in moodle
  2428. /*
  2429. in file mod\label\lib.php
  2430. function label_add_instance calls get_label_name
  2431. inside get_label_name variable name is collected from content field and not from name
  2432. provided here ...
  2433. $name = addslashes(strip_tags(format_string(stripslashes($label->content),true)));
  2434. */
  2435. if (!$labelid = label_add_instance($label)) {
  2436. $ret->error = get_string('ws_errorcreatinglabel','local_wspp', $label->name);
  2437. break;
  2438. }
  2439. $ret = ws_get_record('label', 'id', $labelid);
  2440. break;
  2441. case 'update' :
  2442. $ret->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$label->action);
  2443. break;
  2444. case 'delete' :
  2445. $ret->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$label->action);
  2446. break;
  2447. default :
  2448. $ret->error =get_string('ws_invalidaction','local_wspp',$label->action);
  2449. }
  2450. $rets[] = $ret;
  2451. }
  2452. }
  2453. return $rets;
  2454. }
  2455. /**
  2456. * Edit section records (add/update/delete).
  2457. * @uses $CFG
  2458. * @param int $client The client session ID.
  2459. * @param string $sesskey The client session key.
  2460. * @param array $sections An array of section records (objects or arrays) for editing
  2461. * (including operation to perform).
  2462. * @return array Return data (section record) to be converted into a
  2463. * specific data format for sending to the client.
  2464. */
  2465. function edit_sections($client, $sesskey, $sections) {
  2466. global $CFG;
  2467. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  2468. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2469. }
  2470. $rets= array ();
  2471. if (!empty ($sections)) {
  2472. foreach ($sections->sections as $section) {
  2473. switch (trim(strtolower($section->action))) {
  2474. case 'add' :
  2475. /// Adding a new section.
  2476. $ret = $section;
  2477. $this->debug_output('EDIT_SECTIONS: Trying to add a new section.');
  2478. if (!$course = ws_get_record("course", "id", $section->course)) {
  2479. $ret->error=get_string('ws_courseunknown','local_wspp',"id=".$section->course );
  2480. break;
  2481. }
  2482. /// Check for correct permissions.
  2483. if (!$this->has_capability('moodle/course:update', CONTEXT_COURSE, $course->id)) {
  2484. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2485. break;
  2486. }
  2487. // verify if current section is already in database
  2488. if ($sectionExist = ws_get_record("course_sections", "course", $section->course, "section", $section->section)) {
  2489. $ret = $sectionExist;
  2490. $ret->error=get_string('ws_sectionexists','local_wspp',$section->course);
  2491. break;
  2492. }
  2493. if (!$resultInsertion = ws_insert_record("course_sections", $section)) {
  2494. $ret->error =get_string('ws_errorcreatingsection','local_wspp',$section->summary);
  2495. break;
  2496. }
  2497. $ret = ws_get_record('course_sections', 'id', $resultInsertion);
  2498. break;
  2499. case 'update' :
  2500. //get the section record
  2501. if (!($oldsection = ws_get_record('course_sections', 'id', $section->id))) {
  2502. return $this->error(get_string('ws_sectionunknown','local_wspp','id='.$section->id));
  2503. }
  2504. /// Check for correct permissions.
  2505. if (!$this->has_capability('moodle/course:update', CONTEXT_COURSE, $oldsection->course)) {
  2506. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2507. break;
  2508. }
  2509. unset($section->sequence); //don't mess with these
  2510. if (empty($section->course))
  2511. unset($section->course);
  2512. if (empty($section->section)) //TODO move_sections ?
  2513. unset($section->section);
  2514. if (! ws_update_record('course_sections', $section)) {
  2515. $ret->error = get_string('ws_errorupdatingsection','local_wspp',$section->id);
  2516. break;
  2517. }
  2518. $ret = ws_get_record('course_sections', 'id', $section->id);
  2519. if ($section->visible !=$oldsection->visible) {
  2520. set_section_visible($oldsection->course, $oldsection->section, $section->visible);
  2521. }
  2522. break;
  2523. case 'delete' :
  2524. $ret->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$section->action);
  2525. break;
  2526. default :
  2527. $ret->error = get_string('ws_invalidaction','local_wspp',$section->action);
  2528. }
  2529. $rets[] = $ret;
  2530. }
  2531. }
  2532. return $rets;
  2533. }
  2534. /**
  2535. * Edit forum records (add/update/delete).
  2536. * @uses $CFG
  2537. * @param int $client The client session ID.
  2538. * @param string $sesskey The client session key.
  2539. * @param array $forums An array of forum records (objects or arrays) for editing
  2540. * (including operation to perform).
  2541. * @return array Return data (forum record) to be converted into a
  2542. * specific data format for sending to the client.
  2543. */
  2544. function edit_forums($client, $sesskey, $forums) {
  2545. global $CFG;
  2546. require_once ("{$CFG->dirroot}/mod/forum/lib.php");
  2547. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  2548. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2549. }
  2550. $rets = array ();
  2551. if (!empty ($forums)) {
  2552. foreach ($forums->forums as $forum) {
  2553. switch (trim(strtolower($forum->action))) {
  2554. case 'add' :
  2555. /// Adding a new forum.
  2556. $ret = $forum;
  2557. if (empty ($forum->type)) {
  2558. $forum->type = "general";
  2559. }
  2560. if (!array_key_exists($forum->type, forum_get_forum_types_all())) {
  2561. $ret->error = get_string('ws_illegaleforumtype','local_wspp',$forum->type);
  2562. break;
  2563. }
  2564. //TODO in debugging mode do the operation but send and error in libgrade
  2565. // since courseid is null
  2566. //for some reason lib/gradelib.php test is_null(courseid) and not empty () !!!
  2567. // course MUST exist since this activity is graded !
  2568. if (! $course = ws_get_record('course', 'id', $forum->course)) {
  2569. $ret->error = get_string('ws_courseunknown','local_wspp',"id=".$forum->course );
  2570. break;
  2571. }
  2572. /// Check for correct permissions.
  2573. if (!$this->has_capability('moodle/course:manageactivities', CONTEXT_COURSE, $course->id)) {
  2574. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2575. break;
  2576. }
  2577. if (!$resultInsertion = forum_add_instance($forum)) {
  2578. $ret->error =get_string('ws_errorcreatingforum','local_wspp', $forum->name);
  2579. break;
  2580. }
  2581. $ret = ws_get_record('forum', 'id', $resultInsertion);
  2582. break;
  2583. case 'update' :
  2584. $ret->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$forum->action);
  2585. break;
  2586. case 'delete' :
  2587. $ret->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$forum->action);
  2588. break;
  2589. default :
  2590. $ret->error = get_string('ws_invalidaction','local_wspp',$forum->action);
  2591. }
  2592. $rets[] = $ret;
  2593. }
  2594. }
  2595. return $rets;
  2596. }
  2597. /**
  2598. * Edit assgnment records (add/update/delete).
  2599. * @uses $CFG
  2600. * @param int $client The client session ID.
  2601. * @param string $sesskey The client session key.
  2602. * @param array $assignments An array of assignments records (objects or arrays) for editing
  2603. * (including operation to perform).
  2604. * @return array Return data (assignment record) to be converted into a
  2605. * specific data format for sending to the client.
  2606. */
  2607. function edit_assignments($client, $sesskey, $assignments) {
  2608. global $CFG;
  2609. require_once ("{$CFG->dirroot}/mod/assignment/lib.php");
  2610. require_once ("{$CFG->dirroot}/course/lib.php");
  2611. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  2612. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2613. }
  2614. $rets = array ();
  2615. if (!empty ($assignments)) {
  2616. foreach ($assignments->assignments as $assignment) {
  2617. switch (trim(strtolower($assignment->action))) {
  2618. case 'add' :
  2619. //creation of the new assignment
  2620. $ret=$assignment;
  2621. // verification of the field "assignmenttype"
  2622. $assignmenttypes = get_list_of_plugins('mod/assignment/type');
  2623. if (!in_array($assignment->assignmenttype,$assignmenttypes)) {
  2624. $ret->error = get_string('ws_assignmenttypeunknown','local_wspp',$assignment->assignmenttype);
  2625. break;
  2626. }
  2627. //TODO in debugging mode do the operation but send and error in libgrade
  2628. // since courseid may be empty
  2629. //for some reason lib/gradelib.php test is_null(courseid) and not empty () !!!
  2630. // if (empty($assignment->course)) $assignment->course=NULL;
  2631. // course MUST exist since this activity is graded !
  2632. if (! $course = ws_get_record('course', 'id', $assignment->course)) {
  2633. $ret->error = get_string('ws_courseunknown','local_wspp',"id=".$assignment->course );
  2634. break;
  2635. }
  2636. /// Check for correct permissions.
  2637. if (!$this->has_capability('moodle/course:manageactivities', CONTEXT_COURSE, $course->id)) {
  2638. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2639. break;
  2640. }
  2641. if (!($assignId = assignment_add_instance($assignment))) {
  2642. $ret->error = get_string('ws_errorcreatingassignment','local_wspp', $assignment->name);
  2643. break;
  2644. }
  2645. $ret = ws_get_record("assignment",'id',$assignId);
  2646. break;
  2647. case 'update' :
  2648. $ret->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$assignment->action);
  2649. break;
  2650. case 'delete' :
  2651. //delete assignment
  2652. $ret->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$assignment->action);
  2653. break;
  2654. default :
  2655. $ret->error = get_string('ws_invalidaction','local_wspp',$assignment->action);
  2656. break;
  2657. }
  2658. $rets[] = $ret;
  2659. }
  2660. }
  2661. return $rets;
  2662. }
  2663. /**
  2664. * Edit database records (add/update/delete).
  2665. * @uses $CFG
  2666. * @param int $client The client session ID.
  2667. * @param string $sesskey The client session key.
  2668. * @param array $databases An array of database records (objects or arrays) for editing
  2669. * (including operation to perform).
  2670. * @return array Return data (database record) to be converted into a
  2671. * specific data format for sending to the client.
  2672. */
  2673. function edit_databases($client, $sesskey, $databases) {
  2674. global $CFG;
  2675. require_once ("{$CFG->dirroot}/mod/data/lib.php");
  2676. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  2677. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2678. }
  2679. $rets = array ();
  2680. if (!empty ($databases)) {
  2681. foreach ($databases->databases as $database) {
  2682. switch (trim(strtolower($database->action))) {
  2683. case 'add' :
  2684. //add a new database
  2685. $ret = $database;
  2686. if (empty ($database->name)) {
  2687. $ret->error =get_string('ws_missingvalue','local_wspp','name');
  2688. break;
  2689. }
  2690. // course MUST exist since this activity is graded !
  2691. if (! $course = ws_get_record('course', 'id', $database->course)) {
  2692. $ret->error = get_string('ws_courseunknown','local_wspp',"id=".$database->course );
  2693. break;
  2694. }
  2695. if (!$this->has_capability('moodle/category:manageactivities', CONTEXT_COURSE, $course->id)) {
  2696. $ret->error=get_string('ws_operationnotallowed','local_wspp');
  2697. break;
  2698. }
  2699. // database creation
  2700. if (!$dbid = data_add_instance($database)) {
  2701. $ret->error=get_string('ws_errorcreatingdatabase','local_wspp', $ret->name);
  2702. break;
  2703. }
  2704. $ret = ws_get_record('data','id',$dbid);
  2705. break;
  2706. case 'update' :
  2707. //not implemented
  2708. $ret->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$database->action);
  2709. break;
  2710. case 'delete' :
  2711. //not implemented
  2712. $ret->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$database->action);
  2713. break;
  2714. default :
  2715. $ret->error = $ret->error = get_string('ws_invalidaction','local_wspp',$database->action);
  2716. break;
  2717. }
  2718. $rets[] = $ret;
  2719. }
  2720. }
  2721. return $rets;
  2722. }
  2723. /**
  2724. * Edit wiki records (add/update/delete).
  2725. * @uses $CFG
  2726. * @param int $client The client session ID.
  2727. * @param string $sesskey The client session key.
  2728. * @param array $wikis An array of wiki records (objects or arrays) for editing
  2729. * (including operation to perform).
  2730. * @return array Return data (wiki record) to be converted into a
  2731. * specific data format for sending to the client.
  2732. */
  2733. function edit_wikis($client, $sesskey, $wikis) {
  2734. global $CFG,$USER;
  2735. require_once ($CFG->dirroot . '/mod/wiki/lib.php');
  2736. require_once ($CFG->dirroot . '/course/lib.php');
  2737. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  2738. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2739. }
  2740. $rets = array ();
  2741. if (!empty ($wikis)) {
  2742. foreach ($wikis->wikis as $wiki) {
  2743. switch (trim(strtolower($wiki->action))) {
  2744. case 'add' :
  2745. $this->debug_output('EDIT_WIKIS: Trying to add a new wiki.');
  2746. /// Adding a new wiki
  2747. $rwiki = $wiki;
  2748. // course MUST exist since this activity is graded !
  2749. if (! $course = ws_get_record('course', 'id', $wiki->course)) {
  2750. $rwiki->error = get_string('ws_courseunknown','local_wspp',"id=".$assignment->course );
  2751. break;
  2752. }
  2753. /// Check for correct permissions.
  2754. if (!$this->has_capability('moodle/course:manageactivities', CONTEXT_COURSE, $course->id)) {
  2755. $rwiki->error=get_string('ws_operationnotallowed','local_wspp');
  2756. break;
  2757. }
  2758. //verify if current wiki is already in database
  2759. if ($wikiExist = ws_get_record("wiki", "name", $wiki->name, "course", $wiki->course)) {
  2760. $rwiki = $wikiExist;
  2761. break;
  2762. }
  2763. $rwiki->pagename = empty ($rwiki->pagename) ? $rwiki->name : $rwiki->pagename;
  2764. $rwiki->wtype = empty ($rwiki->wtype) ? 'group' : $rwiki->wtype;
  2765. $allowedtypes=array('group','teacher','student');
  2766. if (! in_array($rwiki->wtype,$allowedtypes)) {
  2767. $rwiki->error = get_string('ws_wikiincorrecttype','local_wspp',$rwiki->wtype);
  2768. break;
  2769. }
  2770. //add instance of wiki
  2771. if (!($wikiId = wiki_add_instance($rwiki))) {
  2772. $rwiki->error=get_string('ws_errorcreatingwiki','local_wspp', $rwiki->pagename);
  2773. break;
  2774. }
  2775. $rwiki->id = $wikiId;
  2776. $wiki_entry=new StdClass();
  2777. $wiki_entry->wikiid = $wikiadd->id;
  2778. $wiki_entry->course = 0;
  2779. $wiki_entry->groupid = 0;
  2780. $wiki_entry->userid = $USER->id;
  2781. $wiki_entry->pagename = $rwiki->pagename;
  2782. if (!$result = ws_insert_record("wiki_entries", $wiki_entry)) {
  2783. $rwiki->error = get_string('ws_errorcreatingwikientry','local_wspp', $rwiki->pagename);
  2784. break;
  2785. }
  2786. $rwiki = ws_get_record('wiki', 'id', $wikiId);
  2787. break;
  2788. case 'update' :
  2789. $rwiki->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$wiki->action);
  2790. break;
  2791. case 'delete' :
  2792. $rwiki->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$wiki->action);
  2793. break;
  2794. default :
  2795. $rwiki=new StdClass();
  2796. $rwiki->error = $ret->error = get_string('ws_invalidaction','local_wspp',$wiki->action);
  2797. }
  2798. $rets[] = $rwiki;
  2799. }
  2800. }
  2801. return $rets;
  2802. }
  2803. /**
  2804. * Edit page of Wiki records (add/update/delete).
  2805. * @uses $CFG
  2806. * @param int $client The client session ID.
  2807. * @param string $sesskey The client session key.
  2808. * @param array $pagesWiki An array of page of wiki records (objects or arrays) for editing
  2809. * (including operation to perform).
  2810. * @return array Return data (page wiki record) to be converted into a
  2811. * specific data format for sending to the client.
  2812. *
  2813. */
  2814. function edit_pagesWiki($client, $sesskey, $pagesWiki) {
  2815. global $CFG,$USER;
  2816. require_once ($CFG->dirroot . '/mod/wiki/lib.php');
  2817. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  2818. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2819. }
  2820. $rets = array ();
  2821. if (!empty ($pagesWiki)) {
  2822. foreach ($pagesWiki->pagesWiki as $page) {
  2823. switch (trim(strtolower($page->action))) {
  2824. case 'add' :
  2825. $this->debug_output('EDIT_PAGESWIKI: Trying to add a new pageWiki.');
  2826. $pageadd = $page;
  2827. $pageadd->userid = $USER->id;
  2828. $pageadd->created = time();
  2829. $pageadd->lastmodified = time();
  2830. /// Check for correct permissions.
  2831. if (!$this->has_capability('moodle/course:manageactivities', CONTEXT_SYSTEM, 0)) {
  2832. $rpage->error=get_string('ws_operationnotallowed','local_wspp');
  2833. break;
  2834. }
  2835. //verify if current page is already in database
  2836. if ($pg = ws_get_record("wiki_pages", "pagename", $pageadd->pagename, "wiki", $pageadd->wiki)) {
  2837. $rpage = $pg;
  2838. break;
  2839. }
  2840. if (!$resultInsertion = ws_insert_record("wiki_pages", $pageadd)) {
  2841. $rpage->error = "EDIT_PAGESWIKI: Error at insertion of the page.";
  2842. break;
  2843. }
  2844. $rpage = ws_get_record('wiki_pages', 'id', $resultInsertion);
  2845. break;
  2846. case 'update' :
  2847. $rpage->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$page->action);
  2848. break;
  2849. case 'delete' :
  2850. $rpage->error = get_string('ws_notimplemented','local_wspp',__FUNCTION__." ".$page->action);
  2851. break;
  2852. default :
  2853. $rpage->error = get_string('ws_invalidaction','local_wspp',$page->action);
  2854. }
  2855. }
  2856. $rets[] = $rpage;
  2857. }
  2858. return $rets;
  2859. }
  2860. /*
  2861. * Comments:
  2862. * All the affect methods are returning a generic object type named affectRecord
  2863. * This object has two fields: status and error
  2864. * status indicates if operation succeded
  2865. * if status=false then the error field contains the coresponding error message
  2866. */
  2867. /**
  2868. * Add label to course section
  2869. * @uses $CFG
  2870. * @param int $client The client session ID.
  2871. * @param string $sesskey The client session key.
  2872. * @param int $labelid The label's id
  2873. * @return array Return data (affectRecord object) to be converted into a
  2874. * specific data format for sending to the client.
  2875. */
  2876. function affect_label_to_section($client, $sesskey, $labelid, $sectionid) {
  2877. global $CFG;
  2878. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  2879. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2880. }
  2881. //get the section record
  2882. if (!($section = ws_get_record('course_sections', 'id', $sectionid))) {
  2883. return $this->error(get_string('ws_sectionunknown','local_wspp','id='.$sectionid));
  2884. }
  2885. /// Check for correct permissions.
  2886. if (!$this->has_capability('moodle/course:manageactivities', CONTEXT_COURSE, $section->course)) {
  2887. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  2888. }
  2889. //get the label record
  2890. if (!($label = ws_get_record('label', 'id', $labelid))) {
  2891. return $this->error(get_string('ws_labelunknown','local_wspp','id='.$labelid));
  2892. }
  2893. //make compatible with the return type
  2894. $r = new stdClass();
  2895. $r->error="";
  2896. if ($errmsg=ws_add_mod_to_section($labelid,'label',$section)) {
  2897. $r->error=$errmsg;
  2898. }else {
  2899. $label->course = $section->course;
  2900. if (!ws_update_record("label", $label)) {
  2901. $a=new StdClass();
  2902. $a->id=$labelid;
  2903. $a->course=$section->course;
  2904. $r->error=get_string('ws_errorupdatingmodule','local_wspp',$a);
  2905. }
  2906. }
  2907. $r->status =empty($r->error);
  2908. return $r;
  2909. }
  2910. /**
  2911. * Add forum to course section
  2912. * @uses $CFG
  2913. * @param int $client The client session ID.
  2914. * @param string $sesskey The client session key.
  2915. * @param int $forumid The forum's id
  2916. * @param $groupmode The course modules group mode type. Can be 0 for NOGROUPS 1
  2917. * for SEPARATEGROUPS and 2 for VISIBLEGROUPS
  2918. * @param $sectionid The section's id
  2919. * @return affectRecord Return data (affectRecord object) to be converted into a
  2920. * specific data format for sending to the client.
  2921. */
  2922. function affect_forum_to_section($client, $sesskey, $forumid, $sectionid, $groupmode) {
  2923. global $CFG;
  2924. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  2925. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2926. }
  2927. //get the section record
  2928. if (!($section = ws_get_record('course_sections', 'id', $sectionid))) {
  2929. return $this->error(get_string('ws_sectionunknown','id='.$sectionid));
  2930. }
  2931. /// Check for correct permissions.
  2932. if (!$this->has_capability('moodle/course:manageactivities', CONTEXT_COURSE, $section->course)) {
  2933. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  2934. }
  2935. // check "groupmode" field
  2936. if (($groupmode != NOGROUPS) && ($groupmode != SEPARATEGROUPS) && ($groupmode != VISIBLEGROUPS)) {
  2937. return $this->error(get_string('ws_invalidgroupmode','local_wspp', $groupmode));
  2938. }
  2939. //get the forum record
  2940. if (!($forum = ws_get_record('forum', 'id', $forumid))) {
  2941. return $this->error(get_string('ws_forumunknown','local_wspp','id='.$forumid));
  2942. }
  2943. //make compatible with the return type
  2944. $r = new stdClass();
  2945. $r->error="";
  2946. if ($errmsg=ws_add_mod_to_section($forumid,'forum',$section,$groupmode)) {
  2947. $r->error=$errmsg;
  2948. }else {
  2949. $forum->course = $section->course;
  2950. if (!ws_update_record("forum", $forum)) {
  2951. $a=new StdClass();
  2952. $a->id=$forumid;
  2953. $a->course=$section->course;
  2954. $r->error=get_string('ws_errorupdatingmodule','local_wspp',$a);
  2955. }
  2956. }
  2957. $r->status =empty($r->error);
  2958. return $r;
  2959. }
  2960. /**
  2961. * Add database to course section
  2962. * @uses $CFG
  2963. * @param int $client The client session ID.
  2964. * @param string $sesskey The client session key.
  2965. * @param int $databaseid The database's id
  2966. * @param int $sectionid The section's id
  2967. * @return affectRecord Return data (affectRecord object) to be converted into a
  2968. * specific data format for sending to the client.
  2969. */
  2970. function affect_database_to_section($client, $sesskey, $databaseid, $sectionid) {
  2971. $this->debug_output('AFFECT_DATABASE_TO_SECTION: Trying to affect database to section.');
  2972. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  2973. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  2974. }
  2975. //get the section record
  2976. if (!($section = ws_get_record('course_sections', 'id', $sectionid))) {
  2977. return $this->error(get_string('ws_sectionunknown','local_wspp','id='.$sectionid));
  2978. }
  2979. /// Check for correct permissions.
  2980. if (!$this->has_capability('moodle/course:manageactivities', CONTEXT_COURSE, $section->course)) {
  2981. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  2982. }
  2983. //get record of database
  2984. if (!$database = ws_get_record("data", "id", $databaseid)) {
  2985. return $this->error(get_string('ws_databaseunknown','local_wspp','id='.$databaseid));
  2986. }
  2987. //make compatible with the return type
  2988. $r = new stdClass();
  2989. $r->error="";
  2990. if ($errmsg=ws_add_mod_to_section($databaseid,'data',$section)) {
  2991. $r->error=$errmsg;
  2992. }else {
  2993. $database->course = $section->course;
  2994. if (!ws_update_record("data", $database)) {
  2995. $a=new StdClass();
  2996. $a->id=$databaseid;
  2997. $a->course=$section->course;
  2998. $r->error=get_string('ws_errorupdatingmodule','local_wspp',$a);
  2999. }
  3000. }
  3001. $r->status =empty($r->error);
  3002. return $r;
  3003. }
  3004. /**
  3005. * Add assignment to course section
  3006. * @uses $CFG
  3007. * @param int $client The client session ID.
  3008. * @param string $sesskey The client session key.
  3009. * @param int $assignmentid The assignment's id
  3010. * @param int $sectionid The section's id
  3011. * @param int $groupmode The course modules group mode type. Can be 0 for NOGROUPS 1
  3012. * for SEPARATEGROUPS and 2 for VISIBLEGROUPS
  3013. * @return affectRecord Return data (affectRecord object) to be converted into a
  3014. * specific data format for sending to the client.
  3015. */
  3016. function affect_assignment_to_section($client, $sesskey, $assignmentid, $sectionid, $groupmode) {
  3017. $this->debug_output('AFFECT_DATABASE_TO_SECTION: Trying to affect database to section.');
  3018. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3019. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3020. }
  3021. //get the section record
  3022. if (!($section = ws_get_record('course_sections', 'id', $sectionid))) {
  3023. return $this->error(get_string('ws_sectionunknown','local_wspp','id='.$sectionid));
  3024. }
  3025. /// Check for correct permissions.
  3026. if (!$this->has_capability('moodle/course:manageactivities', CONTEXT_COURSE, $section->course)) {
  3027. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  3028. }
  3029. if (($groupmode != NOGROUPS) && ($groupmode != SEPARATEGROUPS) && ($groupmode != VISIBLEGROUPS)) {
  3030. return $this->error(get_string('ws_invalidgroupmode','local_wspp', $groupmode));
  3031. }
  3032. //get the assignment record
  3033. if (!$assign = ws_get_record("assignment", "id", $assignmentid)) {
  3034. return $this->error(get_string('ws_assignmentunknown','local_wspp','id='.$assignmentid));
  3035. }
  3036. //make compatible with the return type
  3037. $r = new stdClass();
  3038. $r->error="";
  3039. if ($errmsg=ws_add_mod_to_section($assignmentid,'assignment',$section,$groupmode)) {
  3040. $r->error=$errmsg;
  3041. }else {
  3042. $assign->course = $section->course;
  3043. if (!ws_update_record("assignment", $assign)) {
  3044. $a=new StdClass();
  3045. $a->id=$assignmentid;
  3046. $a->course=$section->course;
  3047. $r->error=get_string('ws_errorupdatingmodule','local_wspp',$a);
  3048. }
  3049. }
  3050. $r->status =empty($r->error);
  3051. return $r;
  3052. }
  3053. /**
  3054. * Add wiki to course section
  3055. * @uses $CFG
  3056. * @param int $client The client session ID.
  3057. * @param string $sesskey The client session key.
  3058. * @param int $wikiid The wiki's id
  3059. * @param int $sectionid The section's id
  3060. * @param int $groupmode The course modules group mode type. Can be 0 for NOGROUPS 1
  3061. * for SEPARATEGROUPS and 2 for VISIBLEGROUPS
  3062. * @param int $visible
  3063. * @return affectRecord Return data (affectRecord object) to be converted into a
  3064. * specific data format for sending to the client.
  3065. */
  3066. function affect_wiki_to_section($client, $sesskey, $wikiid, $sectionid, $groupmode, $visible) {
  3067. $this->debug_output('AFFECT_WIKI_TO_SECTION: Trying to affect a wiki to section.');
  3068. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3069. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3070. }
  3071. //get the section record
  3072. if (!($section = ws_get_record('course_sections', 'id', $sectionid))) {
  3073. return $this->error(get_string('ws_sectionunknown','local_wspp','id='.$sectionid));
  3074. }
  3075. /// Check for correct permissions.
  3076. if (!$this->has_capability($client, $sesskey, 'moodle/course:manageactivities', CONTEXT_COURSE, $section->course)) {
  3077. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  3078. }
  3079. //check if exists in db this id & get wiki record
  3080. if (!$wiki = ws_get_record("wiki", "id", $wikiid)) {
  3081. return $this->error(get_string('ws_wikiunknown','local_wspp','id='.$wikiid));
  3082. }
  3083. // check "groupmode" field
  3084. if (($groupmode != NOGROUPS) && ($groupmode != SEPARATEGROUPS) && ($groupmode != VISIBLEGROUPS)) {
  3085. return $this->error(get_string('ws_invalidgroupmode','local_wspp', $groupmode));
  3086. }
  3087. if (($groupmode == SEPARATEGROUPS) || ($groupmode == VISIBLEGROUPS)) {
  3088. if ($group = ws_get_record("groups", "courseid", $section->course)) {
  3089. $wiki2->groupid = $group->id;
  3090. } else {
  3091. $groupmode = 0;
  3092. }
  3093. }
  3094. if (!$wiki_entry = ws_get_record("wiki_entries", "wikiid", $wikiid)) {
  3095. return $this->error("AFFECT_WIKI_TO_SECTION: Wiki with ID $wikiid does not have an entry");
  3096. }
  3097. //make compatible with the return type
  3098. $r = new stdClass();
  3099. $r->error="";
  3100. if ($errmsg=ws_add_mod_to_section($wikiid,'wiki',$section,$groupmode,$visible)) {
  3101. $r->error=$errmsg;
  3102. }else {
  3103. $wiki->course = $section->course;
  3104. if (!ws_update_record("wiki", $wiki)) {
  3105. $a=new StdClass();
  3106. $a->id=$wikiid;
  3107. $a->course=$section->course;
  3108. $r->error=get_string('ws_errorupdatingmodule','local_wspp',$a);
  3109. }
  3110. $wiki2=new StdClass();
  3111. $wiki2->id = $wiki_entry->id;
  3112. $wiki2->wikiid = $wikiid;
  3113. $wiki2->course = $section->course;
  3114. //update "wiki_entries"
  3115. if (!ws_update_record("wiki_entries", $wiki2)) {
  3116. return $this->error("AFFECT_WIKI_TO_SECTION: Impossible to acces WIKI_ENTRIES table");
  3117. }
  3118. }
  3119. $r->status =empty($r->error);
  3120. return $r;
  3121. }
  3122. /**
  3123. * Add section to course
  3124. * @uses $CFG
  3125. * @param int $client The client session ID.
  3126. * @param string $sesskey The client session key.
  3127. * @param int $sectionid The section's id
  3128. * @param int $courseid The course id
  3129. * @return affectRecord Return data (affectRecord object) to be converted into a
  3130. * specific data format for sending to the client.
  3131. */
  3132. function affect_section_to_course($client, $sesskey, $sectionid, $courseid,$idfield='id') {
  3133. global $CFG;
  3134. require_once ($CFG->dirroot . '/course/lib.php');
  3135. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3136. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3137. }
  3138. if (!$course = ws_get_record("course", $idfield, $courseid)) {
  3139. return $this->error(get_string('ws_courseunknown','local_wspp',$idfield."=".$courseid ));
  3140. }
  3141. /// Check for correct permissions.
  3142. if (!$this->has_capability('moodle/course:update', CONTEXT_COURSE, $course->id)) {
  3143. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  3144. }
  3145. //get section
  3146. if (!($cur_section = ws_get_record('course_sections', 'id', $sectionid))) {
  3147. return $this->error(get_string('ws_sectionunknown','local_wspp','id='.$sectionid));
  3148. }
  3149. if ($cur_section->section > $cur_course->numsections) {
  3150. return $this->error("AFFECT_SECTION_TO_COURSE: Section index $cur_section->section too big. Maximum section number: $cur_course->numsections.");
  3151. }
  3152. //verify if current course has already assigned this section
  3153. if ($duplicate = ws_get_record("course_sections", "course", $courseid, "section", $cur_section->section)) {
  3154. if ($sectionid != $duplicate->id) {
  3155. if (!empty ($duplicate->sequence)) {
  3156. $modarray = explode(",", $duplicate->sequence);
  3157. if (!empty ($cur_section->sequence))
  3158. $modarray2 = explode(",", $cur_section->sequence);
  3159. else
  3160. $modarray2 = array ();
  3161. foreach ($modarray as $key) {
  3162. $module = ws_get_record("course_modules", "id", $key);
  3163. $module->section = $sectionid;
  3164. ws_update_record("course_modules", $module);
  3165. array_push($modarray2, $key);
  3166. }
  3167. $cur_section->sequence = implode(",", $modarray2);
  3168. }
  3169. delete_records("course_sections", "id", $duplicate->id);
  3170. }
  3171. }
  3172. $cur_section->course = $courseid;
  3173. if (!ws_update_record("course_sections", $cur_section)) {
  3174. $a=new StdClass();
  3175. $a->id=$cur_section->id;
  3176. $a->course=$courseid;
  3177. $r->error=get_string('ws_errorupdatingsection','local_wspp',$a);
  3178. }
  3179. $r = new stdClass();
  3180. $r->status = true;
  3181. return $r;
  3182. }
  3183. /**
  3184. * Add a page of wiki to wiki
  3185. * @uses $CFG
  3186. * @param int $client The client session ID.
  3187. * @param string $sesskey The client session key.
  3188. * @param int $pageid The page's id
  3189. * @param int $wikiid The wikis' id
  3190. * @return affectRecord Return data (affectRecord object) to be converted into a
  3191. * specific data format for sending to the client.
  3192. */
  3193. function affect_pageWiki_to_wiki($client, $sesskey, $pageid, $wikiid) {
  3194. global $CFG;
  3195. require_once ($CFG->dirroot . '/mod/wiki/lib.php');
  3196. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3197. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3198. }
  3199. //we verify if we have the permission to do this operation
  3200. if (!$cm = get_coursemodule_from_instance('wiki', $wikiid)) {
  3201. return $this->error("Course Module ID was not found. We can't verify if you have permission to do this operation");
  3202. }
  3203. if (!$this->has_capability('mod/wiki:participate', CONTEXT_MODULE, $cm->id)) {
  3204. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  3205. }
  3206. //verify if the wiki exist in the database
  3207. if (!($wiki = ws_get_record("wiki", "id", $wikiid))) {
  3208. return $this->error(get_string('ws_wikiunknown','local_wspp','id='.$wikiid));
  3209. }
  3210. //we verify if the wiki exist in wiki_entries
  3211. if (!($wiki_entry = ws_get_record("wiki_entries", "wikiid", $wiki->id))) {
  3212. return $this->error("AFFECT_PAGEWIKI_TO_WIKI: The wiki does not exist in wiki_entries");
  3213. }
  3214. //verify if the page of wiki exist in DB
  3215. if (!($page = ws_get_record("wiki_pages", "id", $pageid))) {
  3216. return $this->error(get_string('ws_wikipageunknown','local_wspp','id='.$pageid));
  3217. }
  3218. //verify if the page is not assigned to a wiki
  3219. if ($page->wiki > 0) {
  3220. return $this->error("AFFECT_PAGEWIKI_TO_WIKI: This page of wiki is already assigned to the wiki with ID:$page->wiki");
  3221. }
  3222. // we find the last version of the first page of wiki
  3223. // it is necessary for viewing the affected page in wiki
  3224. //at the content of this page we are adding a link to the affected page
  3225. //if this page does not exist we will create it
  3226. $sql = "SELECT wp.*
  3227. FROM {$CFG->prefix}wiki_pages wp
  3228. WHERE wp.pagename = '{$wiki->pagename}' AND
  3229. wp.wiki = {$wiki_entry->id} AND
  3230. wp.version in (select MAX(p.version)
  3231. FROM {$CFG->prefix}wiki_pages p
  3232. WHERE p.pagename = '{$wiki->pagename}' AND
  3233. p.wiki = {$wiki_entry->id}) ";
  3234. // $first_page=get_record_sql($sql);
  3235. if (!$first_page = get_record_sql($sql)) {
  3236. $first_page->pagename = $wiki->pagename;
  3237. $first_page->wiki = $wiki_entry->id;
  3238. $first_page->created = time();
  3239. $first_page->lastmodified = time();
  3240. $first_page->version = 1;
  3241. $first_page->flags = 1;
  3242. $first_page->userid = $this->get_my_id($client, $sesskey);
  3243. ;
  3244. if (!($result = ws_insert_record("wiki_pages", $first_page, true))) {
  3245. return $this->error = "AFFECT_PAGEWIKI_TO_WIKI: Error at insertion of the first page of wiki.";
  3246. }
  3247. $first_page = ws_get_record("wiki_pages", "id", $result);
  3248. }
  3249. $res = new stdClass();
  3250. //we verify if our page has the same name as the wiki's pagename
  3251. //in this case our page will became a new version of the first page of wiki
  3252. if ($page->pagename == $first_page->pagename) {
  3253. $page->version = $first_page->version + 1;
  3254. $page->wiki = $wiki_entry->id;
  3255. $page->flags = 1;
  3256. $page->created = time();
  3257. $page->lastmodified = time();
  3258. $page->content = $first_page->content . "<br>" . $page->content;
  3259. if (!ws_update_record("wiki_pages", $page)) {
  3260. return $this->error = "AFFECT_PAGEWIKI_TO_WIKI: Error at update page of wiki.";
  3261. }
  3262. $res->status = true;
  3263. return $res;
  3264. }
  3265. //verify if in database exist another page with the same name assigned to this wiki
  3266. if ($page2 = ws_get_record("wiki_pages", "pagename", $page->pagename, "wiki", $wiki_entry->id)) {
  3267. return $this->error("AFFECT_PAGEWIKI_TO_WIKI: A page of wiki with this name (id=$page2->id)is already assigned to the wiki with ID:$wiki->id");
  3268. }
  3269. $page->wiki = $wiki_entry->id;
  3270. $page->version = 1;
  3271. $page->flags = 1;
  3272. // update of the page of wiki
  3273. if (!ws_update_record("wiki_pages", $page)) {
  3274. return $this->error = "AFFECT_PAGEWIKI_TO_WIKI: Error at update page of wiki.";
  3275. }
  3276. //create link for the page affected
  3277. $first_page->content = $first_page->content . "<br>[" . $page->pagename . "]";
  3278. if (!ws_update_record("wiki_pages", $first_page)) {
  3279. return $this->error = "AFFECT_PAGEWIKI_TO_WIKI: Can not create link to the page new created.";
  3280. }
  3281. $res->status = true;
  3282. return $res;
  3283. }
  3284. /**
  3285. * Add course to category
  3286. * @uses $CFG
  3287. * @param int $client The client session ID.
  3288. * @param string $sesskey The client session key.
  3289. * @param int $courseid The course's id
  3290. * @param int $categoryid The category's id
  3291. * @return affectRecord Return data (affectRecord object) to be converted into a
  3292. * specific data format for sending to the client.
  3293. */
  3294. function affect_course_to_category($client, $sesskey, $courseid, $categoryid) {
  3295. global $CFG;
  3296. require_once ($CFG->dirroot . '/course/lib.php');
  3297. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  3298. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3299. }
  3300. /// Check if category with id specified exists
  3301. if (!$destcategory = ws_get_record('course_categories', 'id', $categoryid)) {
  3302. return $this->error(get_string('ws_categoryunkown','local_wspp',"id=".$categoryid));
  3303. }
  3304. /// Check if course with id specified exists
  3305. if (!$course = ws_get_record('course', 'id', $courseid)) {
  3306. return $this->error(get_string('ws_courseunknown','local_wspp',"id=".$courseid));
  3307. }
  3308. /// Check for correct permissions.
  3309. if (!$this->has_capability('moodle/course:create', CONTEXT_COURSECAT, $categoryid)) {
  3310. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  3311. }
  3312. move_courses(array (
  3313. $courseid
  3314. ), $categoryid);
  3315. //make compatible with the return type
  3316. $r = new stdClass();
  3317. $r->status = true;
  3318. return $r;
  3319. }
  3320. /**
  3321. * add a user to a course, giving him the role specified as parameter
  3322. * @param int $client The client session ID.
  3323. * @param string $sesskey The client session key.
  3324. * @param int $userid The user's id
  3325. * @param int $courseid The course's id
  3326. * @param string $rolename Specify the name of the role
  3327. * @return affectRecord Return data (affectRecord object) to be converted into a
  3328. * specific data format for sending to the client.
  3329. */
  3330. function affect_user_to_course($client, $sesskey, $userid, $courseid, $rolename) {
  3331. //if it isn't specified the role name, this will be set as Student
  3332. $rolename = empty ($rolename) ? "student" : $rolename;
  3333. $res = $this->affect_role_incourse($client, $sesskey, $rolename, $courseid, 'id', array (
  3334. $userid
  3335. ), 'id', true);
  3336. $r = new stdClass();
  3337. $r->status = empty ($res->error);
  3338. return $r;
  3339. }
  3340. /**
  3341. * remove a user's role from a course; the role specified as parameter
  3342. * @param int $client The client session ID.
  3343. * @param string $sesskey The client session key.
  3344. * @param int $userid The user's id
  3345. * @param int $courseid The course's id
  3346. * @param string $rolename Specify the name of the role
  3347. * @return affectRecord Return data (affectRecord object) to be converted into a
  3348. * specific data format for sending to the client.
  3349. */
  3350. function remove_user_from_course($client, $sesskey, $userid, $courseid, $rolename) {
  3351. //if it isn't specified the role name, this will be set as Student
  3352. $rolename = empty ($rolename) ? "Student" : $rolename;
  3353. $res = $this->affect_role_incourse($client, $sesskey, $rolename, $courseid, 'id', array (
  3354. $userid
  3355. ), 'id', false);
  3356. $r = new stdClass();
  3357. $r->status = empty ($res->error);
  3358. return $r;
  3359. }
  3360. /*
  3361. *******************************************************************************************
  3362. * *
  3363. * getFunctions *
  3364. * *
  3365. *******************************************************************************************
  3366. */
  3367. function get_all_wikis($client, $sesskey, $fieldname, $fieldvalue) {
  3368. if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
  3369. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3370. }
  3371. $ret = array ();
  3372. if ($res = ws_get_records('wiki', $fieldname, $fieldvalue, 'name', '*')) {
  3373. $ret = filter_wikis($client, $res);
  3374. }
  3375. return $ret;
  3376. }
  3377. function get_all_pagesWiki($client, $sesskey, $fieldname, $fieldvalue) {
  3378. if (!$this->validate_client($client, $sesskey, 'get_all_pagesWiki')) {
  3379. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3380. }
  3381. $ret = array ();
  3382. if ($res = ws_get_records('wiki_pages', $fieldname, $fieldvalue, 'pagename', '*')) {
  3383. $ret = filter_pagesWiki($client, $res);
  3384. }
  3385. return $ret;
  3386. }
  3387. function get_all_groups($client, $sesskey, $fieldname, $fieldvalue) {
  3388. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3389. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3390. }
  3391. $ret = array ();
  3392. if ($res = ws_get_records('groups', $fieldname, $fieldvalue, 'name', '*')) {
  3393. $ret = filter_groups($client, $res);
  3394. }
  3395. return $ret;
  3396. }
  3397. function get_all_forums($client, $sesskey, $fieldname, $fieldvalue) {
  3398. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3399. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3400. }
  3401. $ret = array ();
  3402. if ($forums = ws_get_records("forum", $fieldname, $fieldvalue, "name")) {
  3403. $ret = filter_forums($client, $forums);
  3404. }
  3405. return $ret;
  3406. }
  3407. function get_all_labels($client, $sesskey, $fieldname, $fieldvalue) {
  3408. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3409. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3410. }
  3411. $ret = array ();
  3412. if ($labels = ws_get_records("label", $fieldname, $fieldvalue, "name")) {
  3413. $ret = filter_labels($client, $labels);
  3414. }
  3415. return $ret;
  3416. }
  3417. function get_all_assignments($client, $sesskey, $fieldname, $fieldvalue) {
  3418. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3419. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3420. }
  3421. $ret = array ();
  3422. if ($assignments = ws_get_records("assignment", $fieldname, $fieldvalue, "name")) {
  3423. $ret = filter_assignments($client, $assignments);
  3424. }
  3425. return $ret;
  3426. }
  3427. function get_all_databases($client, $sesskey, $fieldname, $fieldvalue) {
  3428. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3429. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3430. }
  3431. $ret = array ();
  3432. if ($databases = ws_get_records("data", $fieldname, $fieldvalue, "name")) {
  3433. $ret = filter_databases($client, $databases);
  3434. }
  3435. return $ret;
  3436. }
  3437. function get_all_quizzes($client, $sesskey, $fieldname, $fieldvalue) {
  3438. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3439. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3440. }
  3441. $ret = array ();
  3442. if ($quizzes = ws_get_records("quiz", $fieldname, $fieldvalue, "name")) {
  3443. $ret = filter_resources($client, $quizzes);
  3444. }
  3445. return $ret;
  3446. }
  3447. /*
  3448. *****************************************************************************************************************************
  3449. * *
  3450. * END LILLE FUNCTIONS *
  3451. * *
  3452. *****************************************************************************************************************************
  3453. */
  3454. function get_all_groupings($client, $sesskey, $fieldname, $fieldvalue) {
  3455. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3456. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3457. }
  3458. $ret = array ();
  3459. if ($res = ws_get_records('groupings', $fieldname, $fieldvalue, 'name', '*')) {
  3460. $ret = filter_groupings($client, $res);
  3461. }
  3462. return $ret;
  3463. }
  3464. function get_all_cohorts($client, $sesskey, $fieldname, $fieldvalue) {
  3465. global $CFG;
  3466. if (!$CFG->wspp_using_moodle20) {
  3467. return $this->error(get_string('ws_moodle20only', 'local_wspp'));
  3468. }
  3469. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3470. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3471. }
  3472. $ret = array ();
  3473. if ($res = ws_get_records('cohort', $fieldname, $fieldvalue, 'name', '*')) {
  3474. $ret = filter_cohorts($client, $res);
  3475. }
  3476. $this->debug_output(print_r($res,true));
  3477. return $ret;
  3478. }
  3479. // rev 1.6.4
  3480. function set_user_profile_values ($client,$sesskey,$userid,$useridfield,$values) {
  3481. global $CFG;
  3482. require_once($CFG->dirroot.'/user/profile/lib.php');
  3483. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3484. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3485. }
  3486. if (!$this->has_capability('moodle/user:update', CONTEXT_SYSTEM, 0)) {
  3487. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  3488. }
  3489. if (!$user = ws_get_record('user', $useridfield, $userid)) {
  3490. return $this->error =get_string('ws_userunknown','local_wspp',$useridfield."=".$userid);
  3491. }
  3492. $ret=array();
  3493. foreach($values as $value) {
  3494. if (!isset($value->name) && !isset($value->value))
  3495. continue;
  3496. if (!$field = ws_get_record('user_info_field', 'shortname', $value->name))
  3497. return $this->error(get_string('ws_profileunknown','local_wspp','shortname='.$value->name));
  3498. $fvalue=$value->value;
  3499. switch ($field->datatype) {
  3500. case 'menu':
  3501. //convert the passed string to an indice in array of possible values
  3502. $fvalue=array_search($fvalue,explode("\n", $field->param1));
  3503. if ( FALSE===$fvalue)
  3504. return $this->error(get_string('ws_profileinvalidvaluemenu','local_wspp',$value->value));
  3505. break;
  3506. case 'checkbox':
  3507. if ((int)$fvalue != 0 && (int)$fvalue != 1)
  3508. return $this->error(get_string('ws_profileinvalidvaluecheckbox','local_wspp'));
  3509. break;
  3510. case 'text':
  3511. $fvalue = substr($fvalue, 0, $field->param2);
  3512. break;
  3513. }
  3514. require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
  3515. $newfield = 'profile_field_'.$field->datatype;
  3516. $formfield = new $newfield($field->id, $user->id);
  3517. $user->{$formfield->inputname}=$fvalue;
  3518. //$this->debug_output(print_r($formfield,true));
  3519. $formfield->edit_save_data($user);
  3520. $ret[]=$value;
  3521. }
  3522. return $ret;
  3523. }
  3524. function get_users_byprofile($client,$sesskey,$profilefieldname,$profilefieldvalue) {
  3525. global $CFG;
  3526. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3527. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3528. }
  3529. if (!$this->has_capability('moodle/site:viewparticipants',CONTEXT_SYSTEM, 0)) {
  3530. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  3531. }
  3532. //make sure required custom field exists
  3533. if (!($field = ws_get_record("user_info_field", "shortname", $profilefieldname))) {
  3534. return $this->error(get_string('ws_profileunknown','local_wspp','shortname='.$profilefieldname));
  3535. }
  3536. $profilefieldvalue=addslashes($profilefieldvalue);
  3537. $where = "where fieldid={$field->id} and data='$profilefieldvalue'" ;
  3538. $where="id in (SELECT userid FROM {$CFG->prefix}user_info_data $where)";
  3539. // return $this->error($where);
  3540. $ret=ws_get_records_select('user',$where);
  3541. //also add custom profile values
  3542. return filter_users($client, $ret, 0);
  3543. }
  3544. /**
  3545. * rev 1.6.5 added upon request on tstc.edu
  3546. */
  3547. function get_quiz ($client,$sesskey,$quizid,$format='xml') {
  3548. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3549. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3550. }
  3551. //get the quiz record
  3552. if (!$quiz = ws_get_record("quiz", "id", $quizid)) {
  3553. return $this->error(get_string('ws_quizunknown','local_wspp','id='.$quizid));
  3554. }
  3555. /// Check for correct permissions.
  3556. if (!$this->has_capability('mod/quiz:manage', CONTEXT_COURSE, $quiz->course)) {
  3557. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  3558. }
  3559. require_once("libquiz.php");
  3560. if (! ws_libquiz_is_supported_format ($format))
  3561. return $this->error(get_string('ws_quizexportunknownformat','local_wspp','format='.$format));
  3562. //$this->debug_output((print_r($quiz,true)));
  3563. $quiz->data=ws_libquiz_export($quiz,$format);
  3564. return filter_quiz($client,$quiz);
  3565. }
  3566. /**
  3567. * add users to a cohort
  3568. * @param int $client
  3569. * @param string $sesskey
  3570. * @param string[] $userids
  3571. * @param string $useridfield
  3572. * @param string $cohortid
  3573. * @param string $cohortidfield
  3574. * @param boolean $add true to add users, false to remove users
  3575. * @return affectRecord[]
  3576. */
  3577. function affect_users_to_cohort($client,$sesskey,$userids,$useridfield,$cohortid,$cohortidfield,$add) {
  3578. global $CFG;
  3579. if ($CFG->wspp_using_moodle20) {
  3580. require_once ($CFG->dirroot.'/cohort/lib.php');
  3581. }else
  3582. return $this->error(get_string('ws_moodle20only', 'local_wspp'));
  3583. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3584. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3585. }
  3586. if (!$cohort = ws_get_record('cohort', $cohortidfield, $cohortid)) {
  3587. return $this->error(get_string('ws_cohortunknown','local_wspp',$cohortidfield.'='.$cohortid));
  3588. }
  3589. /// Check for correct permissions.
  3590. if (!$this->has_capability('moodle/cohort:manage', CONTEXT_COURSECAT, $cohort->contextid)){
  3591. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  3592. }
  3593. $ret=array();
  3594. foreach ($userids as $userid) {
  3595. $st = new enrolRecord();
  3596. $st->setCourse($cohort->id);
  3597. $st->setUserid($userid);
  3598. $a=new StdClass();
  3599. $a->user=$userid;
  3600. $a->course=$cohortid;
  3601. if (!$user = ws_get_record('user', $useridfield, $userid)) {
  3602. $st->error =get_string('ws_userunknown','local_wspp',$useridfield."=".$userid);
  3603. } else {
  3604. if ($add) {
  3605. if (ws_get_record('cohort_members','cohortid',$cohortid, 'userid',$user->id))
  3606. $st->error=get_string('ws_useralreadymember','local_wspp',$a);
  3607. else {
  3608. cohort_add_member($cohort->id,$user->id);
  3609. }
  3610. }
  3611. else {
  3612. if (!ws_get_record('cohort_members','cohortid',$cohortid, 'userid',$user->id))
  3613. $st->error=get_string('ws_usernotmember','local_wspp',$a);
  3614. else {
  3615. cohort_remove_member($cohort->id,$user->id);
  3616. }
  3617. }
  3618. }
  3619. $ret[]=$st;
  3620. }
  3621. return $ret;
  3622. }
  3623. /**
  3624. * add users to a group
  3625. * @param int $client
  3626. * @param string $sesskey
  3627. * @param string[] $userids
  3628. * @param string $useridfield
  3629. * @param string $groupid
  3630. * @param string $groupidfield
  3631. * @param boolean $add true to add users, false to remove users
  3632. * @return affectRecord[]
  3633. */
  3634. function affect_users_to_group($client,$sesskey,$userids,$useridfield,$groupid,$groupidfield,$add) {
  3635. global $CFG;
  3636. if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
  3637. return $this->error(get_string('ws_invalidclient', 'local_wspp'));
  3638. }
  3639. if (!$group = ws_get_record('groups', $groupidfield, $groupid)) {
  3640. return $this->error(get_string('ws_groupunknown','local_wspp',$groupidfield.'='.$groupid));
  3641. }
  3642. /// Check for correct permissions.
  3643. if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $group->courseid)) {
  3644. return $this->error(get_string('ws_operationnotallowed','local_wspp'));
  3645. }
  3646. if ($CFG->wspp_using_moodle20) {
  3647. // not anymore included by defualt in Moodle 2.0
  3648. require_once ($CFG->dirroot.'/group/lib.php');
  3649. }
  3650. $ret=array();
  3651. foreach ($userids as $userid) {
  3652. $st = new enrolRecord();
  3653. $st->setCourse($cohort->id);
  3654. $st->setUserid($userid);
  3655. $a=new StdClass();
  3656. $a->user=$userid;
  3657. $a->course=$groupid;
  3658. if (!$user = ws_get_record('user', $useridfield, $userid)) {
  3659. $st->error =get_string('ws_userunknown','local_wspp',$useridfield."=".$userid);
  3660. } else {
  3661. /// Check user is enroled in course
  3662. if (!ws_is_enrolled( $group->courseid, $user->id)) {
  3663. $st->error(get_string('ws_user_notenroled','local_wspp',$a));
  3664. } else {
  3665. if ($add) {
  3666. if (ws_get_record('groups_members','groupid',$group->id, 'userid',$user->id))
  3667. $st->error=get_string('ws_useralreadymember','local_wspp',$a);
  3668. else {
  3669. groups_add_member($group->id,$user->id);
  3670. }
  3671. }
  3672. else {
  3673. if (!ws_get_record('groups_members','groupid',$group->id, 'userid',$user->id))
  3674. $st->error=get_string('ws_usernotmember','local_wspp',$a);
  3675. else {
  3676. groups_remove_member($group->id,$user->id);
  3677. }
  3678. }
  3679. }
  3680. }
  3681. $ret[]=$st;
  3682. }
  3683. return $ret;
  3684. }
  3685. }
  3686. ?>