/wspp/server.class.php
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
Large files files are truncated, but you can click here to view the full file
- <?php
- // $Id: server.class.php,v 1.14 2010/10/26 13:50:10 ppollet Exp $
- /**
- * Base class for web services server layer. PP 5 ONLY.
- *
- * @package Web Services
- * @version $Id: server.class.php,v 1.14 2010/10/26 13:50:10 ppollet Exp $
- * @author Open Knowledge Technologies - http://www.oktech.ca/
- * @author Justin Filip <jfilip@oktech.ca> v 1.4
- * @author Patrick Pollet <patrick.pollet@insa-lyon.fr> v 1.5, v 1.6, v 1.7
- * @author
- */
- /* rev history
- @see revisions.txt
- **/
- require_once ('../config.php');
- require_once ('wslib.php');
- require_once ('filterlib.php');
- /// increase memory limit (PHP 5.2 does different calculation, we need more memory now)
- // j'ai 11000 comptes
- @ raise_memory_limit("192M"); //fonction de lib/setuplib.php incluse via config.php
- //set_time_limit(0);
- //define('DEBUG', true); rev. 1.5.16 already set (or not) in MoodleWS.php
- define('cal_show_global', 1);
- define('cal_show_course', 2);
- define('cal_show_group', 4);
- define('cal_show_user', 8);
- /**
- * The main server class.
- *
- * The only methods that need to be extended in a child class are error() and any of
- * the service methods which need special transport-protocol specific handling of
- * input and / or output data (ie non simple type returns)
- *
- */
- class server {
- var $version = 2010101000; // also Moodle 2.0 compatible
- var $using17;
- var $using19 = false;
- /**
- * Constructor method.
- *
- * @uses $CFG
- * @param none
- * @return none
- */
- function server () {
- global $CFG;
- $this->debug_output("Server init...");
- $this->debug_output(' Version: ' . $this->version);
- $this->debug_output(' Session Timeout: ' . $this->sessiontimeout);
- if (! $CFG->wspp_using_moodle20) {
- $this->using17 = file_exists($CFG->libdir . '/accesslib.php');
- $this->using19 = file_exists($CFG->libdir . '/grouplib.php');
- //Check for any DB upgrades.
- if (empty ($CFG->webservices_version)) {
- $this->upgrade(0);
- } else
- if ($CFG->webservices_version < $this->version) {
- $this->upgrade($CFG->webservices_version);
- }
- } else {
- $this->using17 = $this->using19 = true;
- }
- // setup default values if not set in admin screens (see admin/wspp.php)
- if (empty ($CFG->ws_sessiontimeout))
- $CFG->ws_sessiontimeout = 1800;
- $this->sessiontimeout = $CFG->ws_sessiontimeout;
- if (!isset ($CFG->ws_logoperations))
- $CFG->ws_logoperations = 1;
- if (!isset ($CFG->ws_logerrors))
- $CFG->ws_logerrors = 0;
- if (!isset ($CFG->ws_logdetailedoperations))
- $CFG->ws_logdetailledoperations = 0;
- if (!isset ($CFG->ws_debug))
- $CFG->ws_debug = 0;
- if (!isset ($CFG->ws_enforceipcheck))
- $CFG->ws_enforceipcheck = 0; // rev 1.6.1 off by default++++
- }
- /**
- * Performs an upgrade of the webservices system.
- * Moodle < 2.0 ONLY
- * @uses $CFG
- * @param int $oldversion The old version number we are upgrading from.
- * @return boolean True if successful, False otherwise.
- */
- private function upgrade($oldversion) {
- global $CFG;
- if ($CFG->wspp_using_moodle20)
- return $this->error(get_string('ws_not_installed_moodle20', 'local_wspp'));
- $this->debug_output('Starting WS upgrade from version ' . $oldversion . 'to version ' . $this->version);
- $return = true;
- require_once ($CFG->libdir . '/ddllib.php');
- if ($oldversion < 2006050800) {
- $return = install_from_xmldb_file($CFG->dirroot . '/wspp/db/install.xml');
- } else {
- if ($oldversion < 2007051000) {
- $table = new XMLDBTable('webservices_sessions');
- $field = new XMLDBField('ip');
- // since table exists, keep NULL as true and no default value !
- // otherwise XMLDB do not do the change but return true ...
- $field->setAttributes(XMLDB_TYPE_CHAR, '64');
- $return = add_field($table, $field, false, false);
- }
- }
- if ($return) {
- set_config('webservices_version', $this->version);
- $this->debug_output('Upgraded from ' . $oldversion . ' to ' . $this->version);
- } else {
- $this->debug_output('ERROR: Could not upgrade to version ' . $this->version);
- }
- return $return;
- }
- /**
- * Creates a new session key.
- *
- * @param none
- * @return string A 32 character session key.
- */
- private function add_session_key() {
- $time = (string) time();
- $randstr = (string) random_string(10);
- /// XOR the current time and a random string.
- $str = $time;
- $str ^= $randstr;
- /// Use the MD5 sum of this random 10 character string as the session key.
- return md5($str);
- }
- /**
- * Validate's that a client has an existing session.
- *
- * @param int $client The client session ID.
- * @param string $sesskey The client session key.
- * @return boolean True if the client is valid, False otherwise.
- */
- private function validate_client($client = 0, $sesskey = '', $operation = '') {
- global $USER, $CFG;
- //return true;
- // rev 1.6.3 added extra securityu checks
- $client = clean_param($client, PARAM_INT);
- $sesskey = clean_param($sesskey, PARAM_ALPHANUM);
- /// We can't validate a session that hasn't even been initialized yet.
- if (!$sess = ws_get_record('webservices_sessions', 'id', $client, 'sessionend', 0, 'verified', 1)) {
- return false;
- }
- /// Validate this session.
- if ($sesskey != $sess->sessionkey) {
- return false;
- }
- // rev 1.6 make sure the session has not timed out
- if ($sess->sessionbegin + $this->sessiontimeout < time()) {
- $sess->sessionend = time();
- ws_update_record('webservices_sessions', $sess);
- return false;
- }
- $USER->id = $sess->userid;
- $USER->username = '';
- $USER->mnethostid = $CFG->mnet_localhost_id; //Moodle 1.95+ build sept 2009
- $USER->ip= getremoteaddr();
- unset ($USER->access); // important for get_my_courses !
- $this->debug_output("validate_client OK $operation $client user=" . print_r($USER, true));
- //$this->debug_output(print_r($CFG,true));
- //LOG INTO MOODLE'S LOG
- if ($operation && $CFG->ws_logoperations)
- add_to_log(SITEID, 'webservice', 'webservice pp', '', $operation);
- return true;
- }
- /**
- * Sends an FATAL error response back to the client.
- *
- * @todo Override in protocol-specific server subclass, e.g. by throwing a PHP exception
- * @param string $msg The error message to return.
- * @return An object with the error message string.(required by mdl_soapserver)
- */
- protected function error($msg) {
- global $CFG;
- $res = new StdClass();
- $res->error = $msg;
- if ($CFG->ws_logerrors)
- add_to_log(SITEID, 'webservice', 'webservice pp', '', 'error :' . $msg);
- $this->debug_output("server.soap fatal error : $msg ". getremoteaddr());
- return $res;
- }
- /**
- * return and object with error attribute set
- * this record will be inserted in client array of responses
- * do not override in protocol-specific server subclass.
- */
- private function non_fatal_error($msg) {
- $res = new StdClass();
- $res->error = $msg;
- $this->debug_output("server.soap non fatal error : $msg");
- return $res;
- }
- /**
- * Do server-side debugging output (to file).
- *
- * @uses $CFG
- * @param string $output Debugging output.
- * @return void
- */
- function debug_output($output) {
- global $CFG;
- if ($CFG->ws_debug) {
- $fp = fopen($CFG->dataroot . '/debug.out', 'a');
- fwrite($fp, "[" . time() . "] $output\n");
- fflush($fp);
- fclose($fp);
- }
- }
- /**
- * check that current ws user has the required capability
- * @param string capability
- * @param string type on context CONTEXT_SYSTEM, CONTEXT_COURSE ....
- * @param object moodle's id
- * @param int $userid : user to chcek, default me
- */
- private function has_capability($capability, $context_type, $instance_id,$userid=NULL) {
- global $USER;
- $context = get_context_instance($context_type, $instance_id);
- if (empty($userid)) { // we must accept null, 0, '0', '' etc. in $userid
- $userid = $USER->id;
- }
- return has_capability($capability, $context, $userid);
- }
- /**
- * Validates a client's login request.
- *
- * @uses $CFG
- * @param array $input Input data from the client request object.
- * @return array Return data (client record ID and session key) to be
- * converted into a specific data format for sending to the
- * client.
- */
- function login($username, $password) {
- global $CFG;
- if (!empty ($CFG->ws_disable))
- return $this->error(get_string('ws_accessdisabled', 'local_wspp'));
- if (!$this->using17)
- return $this->error(get_string('ws_nomoodle16', 'local_wspp'));
- $userip = getremoteaddr(); // rev 1.5.4
- if (!empty($CFG->ws_enforceipcheck)) {
- if (!record_exists('webservices_clients_allow','client',$userip))
- return $this->error(get_string('ws_accessrestricted', 'local_wspp',$userip));
- }
- // rev 1.6.3 added extra security checks
- $username = clean_param($username, PARAM_NOTAGS);
- $password = clean_param($password, PARAM_NOTAGS);
- /// Use Moodle authentication.
- /// FIRST make sure user exists , otherwise account WILL be created with CAS authentification ....
- if (!$knownuser = ws_get_record('user', 'username', $username)) {
- return $this->error(get_string('ws_invaliduser', 'local_wspp'));
- }
- //$this->debug_output(print_r($knownuser, true));
- $user=false;
- //revision 1.6.1 try to use a custom auth plugin
- if (!exists_auth_plugin("webservice") || ! is_enabled_auth("webservice")) {
- $this->debug_output('internal ');
- /// also make sure internal_authentication is used (a limitation to fix ...)
- if (!is_internal_auth($knownuser->auth)) {
- return $this->error(get_string('ws_invaliduser', 'local_wspp'));
- }
- // regular manual authentification (should not be allowed !)
- $user = authenticate_user_login(addslashes($username), $password);
- $this->debug_output('return of a_u_l'. print_r($user,true));
- }
- else {
- $this->debug_output('auth plugin');
- $auth=get_auth_plugin("webservice");
- if ($auth->user_login_webservice($username,$password)) {
- $user=$knownuser;
- }
- }
- if (($user === false) || ($user && $user->id == 0) || isguestuser($user)) {
- return $this->error(get_string('ws_invaliduser', 'local_wspp'));
- }
- //$this->debug_output(print_r($user,true));
- /// Verify that an active session does not already exist for this user.
- $userip = getremoteaddr(); // rev 1.5.4
- $sql = "userid = {$user->id} AND verified = 1 AND
- ip='$userip' AND sessionend = 0 AND
- (" . time() . "- sessionbegin) < " . $this->sessiontimeout;
- //$this->debug_output($sql);
- if ($sess = ws_get_record_select('webservices_sessions',$sql)) {
- //return $this->error('A session already exists for this user (' . $user->login . ')');
- /*
- if ($sess->ip != $userip)
- return $this->error(get_string('ws_ipadressmismatch', 'local_wspp',$userip."!=".$sess->ip));
- */
- //give him more time
- ws_set_field('webservices_sessions','sessionbegin',time(),'id',$sess->id);
- // V1.6 reuse current session
- } else {
- $this->debug_output('nouvelle session ');
- /// Login valid, create a new session record for this client.
- $sess = new stdClass;
- $sess->userid = $user->id;
- $sess->verified = true;
- $sess->ip = $userip;
- $sess->sessionbegin = time();
- $sess->sessionend = 0;
- $sess->sessionkey = $this->add_session_key();
- if ($sess->id = ws_insert_record('webservices_sessions', $sess)) {
- if ($CFG->ws_logoperations)
- add_to_log(SITEID, 'webservice', 'webservice pp', '', __FUNCTION__);
- } else
- return $this->error(get_string('ws_errorregistersession','local_wspp'));
- }
- /// Return standard data to be converted into the appropriate data format
- /// for return to the client.
- $ret = array (
- 'client' => $sess->id,
- 'sessionkey' => $sess->sessionkey
- );
- $this->debug_output(print_r($ret, true));
- return $ret;
- }
- /**
- * Logs a client out of the system by removing the valid flag from their
- * session record and any user ID that is assosciated with their particular
- * session.
- *
- * @param integer $client The client record ID.
- * @param string $sesskey The client session key.
- * @return boolean True if successfully logged out, false otherwise.
- * since this operation retunr s a simple type, no need to override it in protocol specific layer
- */
- function logout($client, $sesskey) {
- global $CFG;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if ($sess = ws_get_record('webservices_sessions', 'id', $client, 'sessionend', 0, 'verified', 1)) {
- $sess->verified = 0;
- $sess->sessionend = time();
- if (ws_update_record('webservices_sessions', $sess)) {
- return true;
- } else {
- return false;
- }
- }
- return false;
- }
- function get_version($client, $sesskey) {
- global $CFG;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return -1; //invalid Moodle's ID
- }
- return $this->version;
- }
- /**
- * Find and return a list of user records.
- *
- * @param int $client The client session ID.
- * @param string $sesskey The client session key.
- * @param array $userids An array of input user values. If empty, return all users
- * @param string $idfield The field used to compare the user ID fields against.
- * @return array Return data (user record) to be converted into a
- * specific data format for sending to the client.
- */
- function get_users($client, $sesskey, $userids, $idfield = 'idnumber') {
- global $USER;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- /// Verify that the user for this session can perform this operation.
- //nothing to check user database is public ?
- $ret = array (); // Return array.
- if (empty ($userids)) { // all users ...
- return filter_users($client, get_users(true), 0);
- }
- foreach ($userids as $userid) {
- $users = ws_get_records('user', $idfield, $userid); //may have more than one !
- if (empty ($users)) {
- $a = new StdClass();
- $a->critere = $idfield;
- $a->valeur = $userid;
- $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
- } else {
- $ret = array_merge($ret, $users);
- }
- }
- //$this->debug_output("GU" . print_r($ret, true));
- return filter_users($client, $ret, 0);
- }
- /**
- * Find and return a list of course records.
- *
- * @param int $client The client session ID.
- * @param string $sesskey The client session key.
- * @param array $courseids An array of input course values to search for.If empty, all courses
- * @param string $idfield searched column . May be any column of table mdl_course
- * @return array Return data (course record) to be converted into a specific
- * data format for sending to the client.
- */
- function get_courses($client, $sesskey, $courseids, $idfield = 'idnumber') {
- global $USER;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- $ret = array ();
- if (empty ($courseids)) {
- // all courses wanted
- $res = ws_get_records('course', '', '');
- return filter_courses($client, $res);
- }
- foreach ($courseids as $courseid) {
- if ($courses = ws_get_records('course', $idfield, $courseid)) { //may have more than one
- $ret = array_merge($ret, $courses);
- } else {
- $a = new StdClass();
- $a->critere = $idfield;
- $a->valeur = $courseid;
- $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
- }
- }
- return filter_courses($client,$ret);
- }
- function get_courses_search($client, $sesskey, $search) {
- global $USER;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- $search = trim(strip_tags($search)); // trim & clean raw searched string
- if (empty ($search)) {
- // all courses wanted
- $res = ws_get_records('course', '', '');
- return filter_courses($client, $res);
- }
- $searchterms = explode(" ", $search); // Search for words independently
- foreach ($searchterms as $key => $searchterm) {
- if (strlen($searchterm) < 2) {
- unset($searchterms[$key]);
- }
- }
- $totalcount=0;
- $ret = get_courses_search($searchterms, "fullname ASC",0,9999,$totalcount);
- return filter_courses($client,$ret);
- }
- /**
- * Find and return a list of resources within one or several courses.
- * OK PP tested with php5 5 and python clients
- * @param int $client The client session ID.
- * @param string $sesskey The client session key.
- * @param array $courseids An array of input course id values to search for. If empty return all ressources
- * @param string $idfield : the field used to identify courses
- * @return array An array of records.
- */
- function get_resources($client, $sesskey, $courseids, $idfield = 'idnumber') {
- global $CFG, $USER;
- if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- $ret = array ();
- if (empty ($courseids)) {
- $courses = ws_get_my_courses($USER->id);
- } else {
- $courses = array ();
- foreach ($courseids as $courseid) {
- if ($course = ws_get_record('course', $idfield, $courseid))
- $courses[] = $course;
- else {
- //append an error record to the list
- $a = new StdClass();
- $a->critere = $idfield;
- $a->valeur = $courseid;
- $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
- }
- }
- }
- //remove courses not available to current user
- $courses = filter_courses($client, $courses);
- $ilink = "{$CFG->wwwroot}/mod/resource/view.php?id=";
- foreach ($courses as $course) {
- if ($resources = get_all_instances_in_course("resource", $course, NULL, true)) {
- foreach ($resources as $resource) {
- $resource->url = $ilink . $resource->coursemodule;
- $ret[] = $resource;
- }
- }
- }
- //remove ressources in course where current user is not enroled
- return filter_resources($client, $ret);
- }
- /**
- * Find and return a list of sections within one or several courses.
- * OK PP tested with php5 5 and python clients
- * @param int $client The client session ID.
- * @param string $sesskey The client session key.
- * @param array $courseids An array of input course id values to search for. If empty return all sections
- * @param string $idfield : the field used to identify courses
- * @return array An array of course records.
- */
- public function get_sections($client, $sesskey, $courseids, $idfield = 'idnumber') {
- global $CFG, $USER;
- if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- $ret = array ();
- if (empty ($courseids)) {
- $courses = ws_get_my_courses($USER->id);
- } else {
- $courses = array ();
- foreach ($courseids as $courseid) {
- if ($course = ws_get_record('course', $idfield, $courseid))
- $courses[] = $course;
- else {
- //append an error record to the list
- $a = new StdClass();
- $a->critere = $idfield;
- $a->valeur = $courseid;
- $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
- }
- }
- }
- //remove courses not available to current user
- $courses = filter_courses($client, $courses);
- foreach ($courses as $course) {
- if ($CFG->wspp_using_moodle20)
- require_once ($CFG->dirroot.'/course/lib.php');
- if ($resources = get_all_sections($course->id))
- foreach ($resources as $resource) {
- $ret[] = $resource;
- }
- }
- //remove ressources in course where current user is not enroled
- return filter_sections($client, $ret);
- }
- public function get_instances_bytype($client, $sesskey, $courseids, $idfield = 'idnumber', $type) {
- //TODO merge with get_resources by giving $type="resource"
- global $CFG, $USER;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (empty($type)) {
- return $this->error(get_string('ws_emptyparameter', 'local_wspp','type'));
- }
- $ret = array ();
- if (empty ($courseids)) {
- $courses = ws_get_my_courses($USER->id);
- } else {
- $courses = array ();
- foreach ($courseids as $courseid) {
- if ($course = ws_get_record('course', $idfield, $courseid))
- $courses[] = $course;
- else {
- //append an error record to the list
- $a = new StdClass();
- $a->critere = $idfield;
- $a->valeur = $courseid;
- $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
- }
- }
- }
- //remove courses not available to current user
- $courses = filter_courses($client, $courses);
- foreach ($courses as $course) {
- if (!$resources = get_all_instances_in_course($type, $course, NULL, true)) {
- //append an error record to the list
- $a = new StdClass();
- $a->critere = 'type';
- $a->valeur = $type;
- $ret[] = $this->non_fatal_error(get_string('ws_nomatch', 'local_wspp', $a));
- }else {
- $ilink = "{$CFG->wwwroot}/mod/$type/view.php?id=";
- foreach ($resources as $resource) {
- $resource->url = $ilink . $resource->coursemodule;
- $ret[] = $resource;
- }
- }
- }
- //remove ressources in course where current user is not enroled
- return filter_resources($client, $ret);
- }
- /**
- * Find and return student grades for currently enrolled courses Function for Moodle 1.9)
- *
- * @uses $CFG
- * @param int $client The client session ID.
- * @param string $sesskey The client session key.
- * @param string $userid The unique id of the student.
- * @param string $useridfield The field used to identify the student.
- * @param string $courseids Array of courses ids
- * @param string $idfield field used for course's ids (idnumber, shortname, id ...)
- * @return userGrade [] The student grades
- *
- */
- function get_grades($client, $sesskey, $userid, $useridfield = 'idnumber', $courseids, $courseidfield = 'idnumber') {
- global $CFG;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (empty ($courseids))
- return server :: get_user_grades($client, $sesskey, $userid, $useridfield);
- if (!$this->using19)
- return $this->error(get_string(' ws_notsupportedgradebook', 'local_wspp'));
- require_once ($CFG->dirroot . '/grade/lib.php');
- require_once ($CFG->dirroot . '/grade/querylib.php');
- if (!$user = ws_get_record('user', $useridfield, $userid)) {
- return $this->error(get_string('ws_userunknown','local_wspp',$userid));
- }
- $return = array ();
- /// Find grade data for the requested IDs.
- foreach ($courseids as $cid) {
- $rgrade = new stdClass;
- /// Get the student grades for each course requested.
- if ($course = ws_get_record('course', $courseidfield, $cid)) {
- if ($this->has_capability('moodle/grade:viewall', CONTEXT_COURSE, $course->id)) {
- // get the floating point final grade
- if ($legrade = grade_get_course_grade($user->id, $course->id)) {
- $rgrade = $legrade;
- $rgrade->error = '';
- $rgrade->itemid = $cid;
- } else {
- $a=new StdClass();
- $a->user=fullname($user);
- $a->course= $course->fullname;
- $rgrade->error = get_string('ws_nogrades','local_wspp',$a);
- }
- } else {
- $rgrade->error= get_string('ws_noseegrades','local_wspp',$course->fullname);
- }
- } else {
- $rgrade->error = get_string('ws_courseunknown','local_wspp', $cid);
- }
- $return[] = $rgrade;
- }
- //$this->debug_output("GG".print_r($return, true));
- return filter_grades($client, $return);
- }
- /**
- * return user's grade in all courses
- * @use get_grades by first creating an array of courses Moodle's ids
- */
- public function get_user_grades($client, $sesskey, $userid, $idfield = "idnumber") {
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$this->using19)
- return $this->error(get_string(' ws_notsupportedgradebook', 'local_wspp'));
- if (!$user = ws_get_record('user', $idfield, $userid)) {
- return $this->error(get_string('ws_userunknown','local_wspp',$idfield.'='.$userid));
- }
- // we cannot call API grade_get_course_grade($user->id) since it does not set the courseid as we want it
- if (!$courses = ws_get_my_courses($user->id, $sort = 'sortorder ASC', $fields = 'idnumber')) {
- return $this->error(get_string('ws_nocourseforuser','local_wspp',$userid));
- }
- $courseids = array ();
- foreach ($courses as $c)
- if (!empty ($c->idnumber))
- $courseids[] = $c->idnumber;
- //$this->debug_output("GUG=" . print_r($courseids, true));
- if (empty ($courseids))
- return $this->error(get_string('ws_nocoursewithidnumberforuser','local_wspp', $userid));
- // caution not $this->get_user_grades THAT WILL call mdl_sopaserver::get_grades
- // resulting in two calls of to_soaparray !!!!
- return server :: get_grades($client, $sesskey, $userid, $idfield, $courseids, 'idnumber');
- }
- public function get_course_grades($client, $sesskey, $courseid, $idfield = "idnumber") {
- global $CFG, $USER;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$this->using19)
- return $this->error(get_string(' ws_notsupportedgradebook', 'local_wspp'));
- require_once ($CFG->dirroot . '/grade/lib.php');
- require_once ($CFG->dirroot . '/grade/querylib.php');
- $return = array ();
- //Get all student grades for course requested.
- if ($course = ws_get_record('course', $idfield, $courseid)) {
- $context = get_context_instance(CONTEXT_COURSE, $course->id);
- if (has_capability('moodle/grade:viewall', $context)) {
- $students = array ();
- $students = get_role_users(5, $context, true, '');
- //$this->debug_output("GcG".print_r($students, true));
- foreach ($students as $user) {
- if ($legrade = grade_get_course_grade($user->id, $course->id)) {
- $rgrade = $legrade;
- $rgrade->error = '';
- $rgrade->itemid = $user->idnumber;
- // $this->debug_output("IDS=".print_r($legrade,true));
- $return[] = $rgrade;
- } else {
- $a=new StdClass();
- $a->user=fullname($user);
- $a->course= $course->fullname;
- $rgrade=new StdClass();
- $rgrade->error = get_string('ws_nogrades','local_wspp',$a);
- $return[] = $rgrade;
- }
- }
- } else {
- $rgrade=new StdClass();
- $rgrade->error = get_string('ws_noseegrades','local_wspp',$course->fullname);
- $return[] = $rgrade;
- }
- } else {
- $rgrade=new StdClass();
- $rgrade->error = get_string('ws_courseunknown','local_wspp', $courseid);
- $return[] = $rgrade;
- }
- //$this->debug_output("GcG".print_r($return, true));
- return filter_grades($client, $return);
- }
- /**
- * determine the primary role of user in a course
- * @param int $client The client session record ID.
- * @param string $sesskey The session key returned by a previous login.
- * @param string userid
- * @param string useridfield
- * @param string courseid
- * @param string courseidfield
- * @return integer
- * 1 admin
- * 2 coursecreator
- * 3 editing teacher
- * 4 non editing teacher
- * 5 student
- * 6 guest IF course allows guest AND username ==guest
- * 0 nothing
- * since this operation retunr s a simple type, no need to override it in protocol specific layer
- */
- function get_primaryrole_incourse($client, $sesskey, $userid, $useridfield, $courseid, $courseidfield) {
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- // convert user request criteria to an userid
- $user = ws_get_record('user', $useridfield, $userid);
- if (!$user)
- return $this->error(get_string('ws_userunknown','local_wspp',$useridfield."=".$userid));
- $userid = $user->id;
- // convert course request criteria to a courseid
- $course = ws_get_record('course', $courseidfield, $courseid);
- if (!$course)
- return $this->error(get_string('ws_courseunknown','local_wspp',$courseidfield."=".$courseid ));
- return ws_get_primaryrole_incourse($course, $userid);
- }
- /**
- * determine if user has (at least) a given role in a course
- * @param int $client The client session record ID.
- * @param string $sesskey The session key returned by a previous login.
- * @param string userid
- * @param string useridfield
- * @param string courseid
- * @param string courseidfield
- * @param int roleid
- * @return boolean True if Ok , False otherwise.
- * since this operation retunr s a simple type, no need to override it in protocol specific layer
- */
- function has_role_incourse($client, $sesskey, $userid, $useridfield, $courseid, $courseidfield, $roleid) {
- $tmp = server :: get_primaryrole_incourse($client, $sesskey, $userid, $useridfield, $courseid, $courseidfield);
- return ($tmp <= $roleid);
- }
- /**
- * Find and return a list of courses that a user is a member of.
- *
- * @param int $client The client session ID.
- * @param string $sesskey The client session key.
- * @param string $uinfo (optional) Moodle's id of user. If absent, uses current session user id
- * @param string $idfield (default ='id', ignored if $uinfo is empty)
- * @param string $sort requested order . Default fullname as per rev 1.5.11
- * @return array Return data (course record) to be converted into a specific
- * data format for sending to the client.
- */
- function get_my_courses($client, $sesskey, $uinfo = '', $idfield = 'id', $sort = '') {
- global $CFG,$USER;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp')." ".__FUNCTION__);
- }
- $cuid = $USER->id;
- if (!empty($uinfo)) {
- // find userid if not current user
- if (!$user = ws_get_record('user', $idfield, $uinfo))
- return $this->error(get_string('ws_userunknown','local_wspp',idfield."=".$uinfo));
- $uid=$user->id;
- } else
- $uid = $cuid; //use current user and ignore $idfield
- //only admin user can request courses for others
- if ($uid != $cuid) {
- if (!$this->has_capability('moodle/user:loginas', CONTEXT_SYSTEM, 0)) {
- return $this->error(get_string('ws_operationnotallowed','local_wspp'));
- }
- }
- $sort = $sort ? $sort : 'fullname';
- if (isguestuser($user))
- $res = ws_get_records('course', 'guest', 1, $sort);
- else {
- //Moodle 1.95 do not return all fields set in wsdl
- if (!$CFG->wspp_using_moodle20)
- $extrafields="password,summary,format,showgrades,newsitems,enrolperiod,numsections,marker,maxbytes,
- hiddensections,lang,theme,cost,timecreated,timemodified,metacourse";
- else
- // some fields are not anymore defined in Moodle 2.0
- $extrafields="summary,format,showgrades,newsitems,numsections,marker,maxbytes,
- hiddensections,lang,theme,timecreated,timemodified";
- $res = ws_get_my_courses($uid, $sort,$extrafields);
- }
- if ($res) {
- //rev 1.6 return primary role for each course
- foreach ($res as $id=>$value)
- $res[$id]->myrole= ws_get_primaryrole_incourse($res[$id],$uid);
- //return $res;
- return filter_courses($client, $res);
- }
- else
- return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
- }
- /**
- * returns users having $idrole in course identified by $idcourse
- * @param string $idcourse unique identifierr of course
- * @param string $idfield name of field used to finc course (idnumber, id, shortname), should be unique
- * @param integer $idrole role searched for (0 = any role)
- */
- function get_users_bycourse($client, $sesskey, $idcourse, $idfield, $idrole = 0) {
- global $USER;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$course = ws_get_record('course', $idfield, $idcourse)) {
- return $this->error(get_string('ws_courseunknown','local_wspp',$idfield."=".$idcourse ));
- }
- if (!$this->has_capability('moodle/course:update', CONTEXT_COURSE, $course->id)
- && !ws_is_enrolled($course->id,$USER->id))
- return $this->error(get_string('ws_operationnotallowed','local_wspp'));
- if (!empty ($roleid) && !ws_record_exists('role', 'id', $idrole))
- return $this->error(get_string('ws_roleunknown','local_wspp',$idrole ));
- $context = get_context_instance(CONTEXT_COURSE, $course->id);
- if ($res = get_role_users($idrole, $context, true, '')) {
- //rev 1.6 if $idrole is empty return primary role for each user
- if (empty($idrole)) {
- foreach ($res as $id=>$value)
- $res[$id]->role=ws_get_primaryrole_incourse($course,$res[$id]->id);
- }
- return filter_users($client, $res, $idrole);
- } else {
- return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
- }
- }
- function get_roles($client, $sesskey, $roleid = '', $idfield = '') {
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- // Get a list of all the roles in the database, sorted by their short names.
- if ($res = ws_get_records('role', $idfield, $roleid, 'shortname, id', '*')) {
- return $res;
- } else {
- return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
- }
- }
- function get_categories($client, $sesskey, $catid = '', $idfield = '') {
- if (!$this->validate_client($client, $sesskey,__FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- $ret = array ();
- // Get a list of all the categories in the database, sorted by their name
- if ($res = ws_get_records('course_categories', $idfield, $catid, 'name', '*')) {
- return filter_categories($client, $res);
- } else {
- return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
- }
- }
- function get_events($client, $sesskey, $eventtype, $ownerid,$owneridfield='id') {
- global $USER;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- $ret = array ();
- // Get a list of all the events in the database, sorted by their short names.
- //TODO filter by eventype ...
- switch ($eventtype) {
- case cal_show_global :
- $idfield = 'courseid';
- $ownerid = 1;
- break;
- case cal_show_course :
- $idfield = 'courseid';
- if (!$course =ws_get_record('course',$owneridfield,$ownerid)) {
- return $this->error(get_string('ws_courseunknown','local_wspp',$owneridfield."=".$ownerid ));
- }
- $ownerid=$course->id;
- break;
- case cal_show_group :
- $idfield = 'groupid';
- if (!$group =ws_get_record('groups',$owneridfield,$ownerid)) {
- return $this->error(get_string('ws_groupunknown','local_wspp',$owneridfield."=".$ownerid ));
- }
- $ownerid=$group->id;
- break;
- case cal_show_user :
- $idfield = 'userid';
- if (!$user =ws_get_record('user',$owneridfield,$ownerid)) {
- return $this->error(get_string('ws_userunknown','local_wspp',$owneridfield."=".$ownerid ));
- }
- $ownerid=$user->id;
- break;
- default :
- $idfield = '';
- $ownerid = '';
- }
- if ($res = ws_get_records('event', $idfield, $ownerid)) {
- foreach ($res as $r) {
- $r = filter_event($client, $eventtype, $r);
- if ($r)
- $ret[] = $r;
- }
- } else {
- $ret[]=$this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
- }
- return $ret;
- }
- function get_group_members($client, $sesskey, $groupid,$groupidfield='id') {
- global $USER;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$group = ws_get_record('groups', $groupidfield, $groupid)) {
- return $this->error(get_string('ws_groupunknown','local_wspp',$groupid));
- }
- if (!$this->has_capability('moodle/course:update', CONTEXT_COURSE, $group->courseid)
- && ! ws_is_enrolled($group->courseid,$USER->id))
- return $this->error(get_string('ws_operationnotallowed','local_wspp'));
- //$res = get_group_users($group->id); deprecated Moodle 1.9 removed Moodle 2.0
- $res=groups_get_members($group->id);
- if (!$res)
- return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
- return filter_users($client, $res, 0);
- }
- function get_grouping_members($client, $sesskey, $groupid,$groupidfield='id') {
- global $USER;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$group = ws_get_record('groupings', $groupidfield, $groupid)) {
- return $this->error(get_string('ws_groupingunknown','local_wspp',$groupid));
- }
- if (!$this->has_capability('moodle/course:update', CONTEXT_COURSE, $group->courseid)
- && ! ws_is_enrolled($group->courseid,$USER->id))
- return $this->error(get_string('ws_operationnotallowed','local_wspp'));
- $res = groups_get_grouping_members($group->id);
- if (!$res)
- return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
- return filter_users($client, $res, 0);
- }
- function get_cohort_members($client, $sesskey, $groupid,$groupidfield='id') {
- global $DB,$CFG;
- if (!$CFG->wspp_using_moodle20)
- return $this->error(get_string('ws_moodle20only', 'local_wspp'));
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$group = ws_get_record('cohort', $groupidfield, $groupid)) {
- return $this->error(get_string('ws_cohortunknown','local_wspp',$groupid));
- }
- /*
- if (!$this->has_capability('moodle/cohort:update', CONTEXT_COURSECAT, $group->contextid))
- return $this->error(get_string('ws_operationnotallowed','local_wspp'));
- */
- $params['cohortid'] = $group->id;
- $fields = 'SELECT u.*';
- $sql = " FROM {user} u
- JOIN {cohort_members} cm ON (cm.userid = u.id AND cm.cohortid = :cohortid)";
- try {
- $res = $DB->get_records_sql($fields . $sql, $params);
- if (!$res)
- return $this->non_fatal_error(get_string('ws_nothingfound','local_wspp'));
- } catch (Exception $e) {
- ws_error_log($e);
- }
- return filter_users($client, $res, 0);
- }
- protected function get_groups($client, $sesskey,$groups,$idfield,$courseid){
- if (empty($groups) && $courseid) {
- return server::get_groups_bycourse ($client,$sesskey,$courseid);
- }
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- global $CFG;
- $ret = array();
- if ($courseid) {
- $courseselect = 'AND g.courseid ='.$courseid ;
- } else {
- $courselect = '';
- }
- // $this->debug_output("groupes=".print_r($groups,true));
- foreach ($groups as $group) {
- $sql= "$idfield ='$group' $courseselect ";
- if ($g = ws_get_records_select('groups',$sql)) {
- $g=filter_groups($client,$g);
- foreach($g as $one) {
- $ret[] = $one;
- }
- } else {
- $ret[]=$this->non_fatal_error(get_string('nogroups','local_wspp')); // "Invalid group $idfield :$group ");
- }
- }
- //$this->debug_output("groupes tr=".print_r($ret,true));
- return $ret;
- }
- protected function get_groupings($client, $sesskey,$groups,$idfield,$courseid){
- if (empty($groups) && $courseid) {
- return server::get_groupings_bycourse ($client,$sesskey,$courseid);
- }
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- global $CFG;
- $ret = array();
- if ($courseid) {
- $courseselect = 'AND g.courseid ='.$courseid ;
- } else {
- $courselect = '';
- }
- //$this->debug_output("groupings=".print_r($groups,true));
- foreach ($groups as $group) {
- $sql= "$idfield ='$group' $courseselect ";
- if ($g = ws_get_records_select('groupings',$sql)) {
- $g=filter_groupings($client,$g);
- foreach($g as $one) {
- $ret[] = $one;
- }
- } else {
- $ret[]=$this->non_fatal_error(get_string('nogroupings','local_wspp')); // "Invalid group $idfield :$group ");
- }
- }
- //$this->debug_output("groupings tr=".print_r($ret,true));
- return $ret;
- }
- protected function get_cohorts($client, $sesskey,$groups,$idfield){
- if (empty($groups)) {
- return server::get_all_cohorts($client,$sesskey);
- }
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- $ret = array();
- foreach ($groups as $group) {
- $sql= "$idfield ='$group' ";
- if ($g = ws_get_records_select('cohort',$sql)) {
- $g=filter_cohorts($client,$g);
- foreach($g as $one) {
- $ret[] = $one;
- }
- } else {
- $ret[]=$this->non_fatal_error(get_string('nocohorts','local_wspp')); // "Invalid group $idfield :$group ");
- }
- }
- //$this->debug_output("cohorts tr=".print_r($ret,true));
- return $ret;
- }
- /**
- * Add user to group
- * @uses $CFG
- * @param int $client The client session ID.
- * @param string $sesskey The client session key.
- * @param int $userid The user's id
- * @param int $groupid The group's id
- * @return affectRecord Return data (affectRecord object) to be converted into a
- * specific data format for sending to the client.
- */
- function affect_user_to_group($client, $sesskey, $userid, $groupid) {
- global $CFG;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$group = ws_get_record('groups', 'id', $groupid)) {
- return $this->error(get_string('ws_groupunknown','local_wspp','id='.$groupid));
- }
- /// Check for correct permissions.
- if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $group->courseid)) {
- return $this->error(get_string('ws_operationnotallowed','local_wspp'));
- }
- if (!$user = ws_get_record("user", "id", $userid)) {
- return $this->error(get_string('ws_userunknown','local_wspp','id='.$userid));
- }
- /// Check user is enroled in course
- if (!ws_is_enrolled( $group->courseid, $user->id)) {
- $a=new StdClass();
- $a->user=$user->username;
- $a->course=$group->courseid;
- return $this->error(get_string('ws_user_notenroled','local_wspp',$a));
- }
- if ($CFG->wspp_using_moodle20) {
- // not anymore included by defualt in Moodle 2.0
- require_once ($CFG->dirroot.'/group/lib.php');
- }
- $resp = new stdClass();
- $resp->status = groups_add_member($group->id, $user->id);
- return $resp;
- }
- function remove_user_from_group($client, $sesskey, $userid, $groupid) {
- global $CFG;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$group = ws_get_record('groups', 'id', $groupid)) {
- return $this->error(get_string('ws_groupunknown','local_wspp','id='.$groupid));
- }
- /// Check for correct permissions.
- if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $group->courseid)) {
- return $this->error(get_string('ws_operationnotallowed','local_wspp'));
- }
- if (!$user = ws_get_record("user", "id", $userid)) {
- return $this->error(get_string('ws_userunknown','local_wspp','id='.$userid));
- }
- /// Check user is member
- if (!ws_is_enrolled( $group->courseid, $user->id)) {
- $a=new StdClass();
- $a->user=$user->username;
- $a->course=$group->courseid;
- return $this->error(get_string('ws_user_notenroled','local_wspp',$a));
- }
- if ($CFG->wspp_using_moodle20) {
- // not anymore included by defualt in Moodle 2.0
- require_once ($CFG->dirroot.'/group/lib.php');
- }
- $resp = new stdClass();
- $resp->status = groups_remove_member($group->id, $user->id);
- return $resp;
- }
- /**
- * Add user to cohort
- * @uses $CFG
- * @param int $client The client session ID.
- * @param string $sesskey The client session key.
- * @param int $userid The user's id
- * @param int $groupid The group's id
- * @return affectRecord Return data (affectRecord object) to be converted into a
- * specific data format for sending to the client.
- */
- function affect_user_to_cohort($client, $sesskey, $userid, $groupid) {
- global $CFG;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$group = ws_get_record('cohort', 'id', $groupid)) {
- return $this->error(get_string('ws_cohortunknown','local_wspp','id='.$groupid));
- }
- /// Check for correct permissions.
- if (!$this->has_capability('moodle/cohort:manage', CONTEXT_COURSECAT, $group->contextid)) {
- return $this->error(get_string('ws_operationnotallowed','local_wspp'));
- }
- if (!$user = ws_get_record("user", "id", $userid)) {
- return $this->error(get_string('ws_userunknown','local_wspp','id='.$userid));
- }
- if ($CFG->wspp_using_moodle20) {
- require_once ($CFG->dirroot.'/cohort/lib.php');
- }else
- return $this->error(get_string('ws_moodle20only', 'local_wspp'));
- cohort_add_member($group->id,$user->id);
- $resp->status = 1;
- return $resp;
- }
- /**remove user from cohort
- * @uses $CFG
- * @param int $client The client session ID.
- * @param string $sesskey The client session key.
- * @param int $userid The user's id
- * @param int $groupid The group's id
- * @return affectRecord Return data (affectRecord object) to be converted into a
- * specific data format for sending to the client.
- */
- function remove_user_from_cohort($client, $sesskey, $userid, $groupid) {
- global $CFG;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$group = ws_get_record('cohort', 'id', $groupid)) {
- return $this->error(get_string('ws_cohortunknown','local_wspp','id='.$groupid));
- }
- /// Check for correct permissions.
- if (!$this->has_capability('moodle/cohort:manage', CONTEXT_COURSECAT, $group->contextid)) {
- return $this->error(get_string('ws_operationnotallowed','local_wspp'));
- }
- if (!$user = ws_get_record("user", "id", $userid)) {
- return $this->error(get_string('ws_userunknown','local_wspp','id='.$userid));
- }
- if ($CFG->wspp_using_moodle20) {
- require_once ($CFG->dirroot.'/cohort/lib.php');
- }else
- return $this->error(get_string('ws_moodle20only', 'local_wspp'));
- cohort_remove_member($group->id,$user->id);
- $resp->status = 1;
- return $resp;
- }
- function affect_group_to_grouping($client, $sesskey, $groupid, $groupingid) {
- global $CFG;
- if (!$this->validate_client($client, $sesskey, __FUNCTION__)) {
- return $this->error(get_string('ws_invalidclient', 'local_wspp'));
- }
- if (!$group = ws_get_record('groups', 'id', $groupid)) {
- return $this->error(get_string('ws_groupunknown','local_wspp','id='.$groupid));
- }
- if (!$grouping = ws_get_record('groupings', 'id', $groupingid)) {
- return $this->error(get_string('ws_groupingunknown','local_wspp','id='.$groupingid));
- }
- if ($group->courseid != $grouping->courseid) {
- $a=new StdClass();
- $a->group=$group->id;
- $a->grouping=$grouping->id;
- return $this->error(get_string('ws_group_grouping_notsamecourse','local_wspp',$a));
- }
- /// Check for correct permissions.
- if (!$this->has_capability('moodle/course:managegroups', CONTEXT_COURSE, $group->courseid)) {
- return $this->error(get_string('ws_operationnotallowed','local_wspp'));
- }
- if ($CFG->wspp_using_moodle20) {
- // not anymore included by defualt in Moodle 2.0
- require_once ($CFG->dirroot.'/group/lib.php');
- }
- …
Large files files are truncated, but you can click here to view the full file