From 9a0df45a01f848e7d31e4b12ef2a5353097009f6 Mon Sep 17 00:00:00 2001 From: skodak Date: Mon, 14 Sep 2009 23:52:08 +0000 Subject: [PATCH] MDL-12886 new design of external service functions, groups api improved and known problems fixed - still work in progress with lots of todos - sorry --- group/external.php | 198 ----------------------------------------- group/externallib.php | 196 ++++++++++++++++++++++++++++++++++++++++ group/lib.php | 62 +++++++------ lang/en_utf8/error.php | 11 +-- lib/accesslib.php | 3 +- lib/db/services.php | 76 ++++++++++++++++ lib/externallib.php | 137 ++++++++++++++++++++++++++++ lib/grouplib.php | 13 ++- lib/setuplib.php | 11 +++ 9 files changed, 464 insertions(+), 243 deletions(-) delete mode 100644 group/external.php create mode 100644 group/externallib.php create mode 100644 lib/db/services.php create mode 100644 lib/externallib.php diff --git a/group/external.php b/group/external.php deleted file mode 100644 index d4ec63b1a84..00000000000 --- a/group/external.php +++ /dev/null @@ -1,198 +0,0 @@ -groupname - * @subparam integer $params:group->courseid - * @return array $return - * @subparam integer $return:groupid - */ - static function create_groups($params) { - global $USER; - $groupids = array(); - - if (has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_SYSTEM))) { - - foreach ($params as $groupparam) { - $group = new stdClass; - $group->courseid = clean_param($groupparam['courseid'], PARAM_INTEGER); - $group->name = clean_param($groupparam['groupname'], PARAM_ALPHANUMEXT); - $groupids[] = groups_create_group($group, false); - } - - return $groupids; - } - else { - throw new moodle_exception('wscouldnotcreategroupnopermission'); - } - } - - /** - * Get some groups - * @param array|struct $params - * @subparam integer $params:groupid - * @return object $return - * @subreturn integer $return:group->id - * @subreturn integer $return:group->courseid - * @subreturn string $return:group->name - * @subreturn string $return:group->enrolmentkey - */ - static function get_groups($params){ - - if (has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_SYSTEM))) { - - foreach ($params as $groupid) { - $group = groups_get_group(clean_param($groupid, PARAM_INTEGER)); - - $ret = new StdClass(); - $ret->id = $group->id; - $ret->courseid = $group->courseid; - $ret->name = $group->name; - $ret->enrolmentkey = $group->enrolmentkey; - - $groups[] = $ret; - } - return $groups; - } - else { - throw new moodle_exception('wscouldnotgetgroupnopermission'); - } - - } - - /** - * Delete some groups - * @param array|struct $params - * @subparam integer $params:groupid - * @return boolean result - */ - static function delete_groups($params){ - - if (has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_SYSTEM))) { - $deletionsuccessfull = true; - foreach ($params as $groupid) { - if (!groups_delete_group(clean_param($groupid, PARAM_INTEGER))) { - $deletionsuccessfull = false; - } - } - return $deletionsuccessfull; - } - else { - throw new moodle_exception('wscouldnotdeletegroupnopermission'); - } - } - - /** - * Return all internal members for a group id (do not return remotely registered user) - * @param array|struct $params - * @subparam integer $params:groupid - * @return array $return - * $subparam string $return:username - */ - static function get_groupmembers($params){ - if (has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_SYSTEM))) { - $members = array(); - foreach ($params as $groupid) { - - $groupmembers = groups_get_members(clean_param($groupid, PARAM_INTEGER)); - $custommembers = array(); - foreach ($groupmembers as $member) { - $custommember = new stdClass(); - $custommember->username = $member->username; - $custommember->auth = $member->auth; - $custommember->confirmed = $member->confirmed; - $custommember->idnumber = $member->idnumber; - $custommember->firstname = $member->firstname; - $custommember->lastname = $member->lastname; - $custommember->email = $member->email; - $custommember->emailstop = $member->emailstop; - $custommember->lang = $member->lang; - $custommember->id = $member->id; - $custommember->theme = $member->theme; - $custommember->timezone = $member->timezone; - $custommember->mailformat = $member->mailformat; - $custommembers[] = $custommember; - } - - $members[] = array("groupid" => $groupid, "members" => $custommembers); - } - return $members; - } - else { - throw new moodle_exception('wscouldnotgetgroupnopermission'); - } - } - - /** - * Add some members to some groups - * @param array|struct $params - * @subparam integer $params:member->groupid - * @subparam integer $params:member->userid - * @return boolean result - */ - static function add_groupmembers($params){ - - if (has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_SYSTEM))) { - $addmembersuccessfull = true; - foreach($params as $member) { - $groupid = clean_param($member['groupid'], PARAM_INTEGER); - $userid = clean_param($member['userid'], PARAM_INTEGER); - - if (!groups_add_member($groupid, $userid)) { - $addmembersuccessfull = false; - } - } - return $addmembersuccessfull; - } - else { - throw new moodle_exception('wscouldnotaddgroupmembernopermission'); - } - } - - /** - * Delete some members from some groups - * @param array|struct $params - * @subparam integer $params:member->groupid - * @subparam integer $params:member->userid - * @return boolean result - */ - static function delete_groupmembers($params){ - if (has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_SYSTEM))) { - $addmembersuccessfull = true; - foreach($params as $member) { - $groupid = clean_param($member['groupid'], PARAM_INTEGER); - $userid = clean_param($member['userid'], PARAM_INTEGER); - if (!groups_remove_member($groupid, $userid)) { - $addmembersuccessfull = false; - } - } - return $addmembersuccessfull; - } else { - throw new moodle_exception('wscouldnotremovegroupmembernopermission'); - } - } - -} - -?> - diff --git a/group/externallib.php b/group/externallib.php new file mode 100644 index 00000000000..2b20f42c73f --- /dev/null +++ b/group/externallib.php @@ -0,0 +1,196 @@ +. + +/** + * External groups API + * + * @package moodlecore + * @subpackage webservice + * @copyright 2009 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once("$CFG->libdir/externallib.php"); + +class moodle_group_external extends external_api { + + /** + * Create groups + * @param array $params array of group description arrays (with keys groupname and courseid) + * @return array of newly created group ids + */ + public static function create_groups($params) { + global $CFG; + require_once("$CFG->dirroot/group/lib.php"); + + $groupids = array(); + + foreach ($params as $groupparam) { + $group = new object(); + // clean params + $group->courseid = clean_param($groupparam['courseid'], PARAM_INTEGER); + $group->name = clean_param($groupparam['groupname'], PARAM_MULTILANG); + if (array_key_exists('enrolmentkey', $groupparam)) { + $group->enrolmentkey = $groupparam['enrolmentkey']; + } else { + $group->enrolmentkey = ''; + } + // now security checks + $context = get_context_instance(CONTEXT_COURSE, $group->courseid); + self::validate_context($context); + require_capability('moodle/course:managegroups', $context); + + $id = groups_create_group($group, false); + $group->id = $id; + $groupids[$id] = $group; + } + + return $groupids; + } + + /** + * Get groups definition + * @param array $params arrays of group ids + * @return array of group objects (id, courseid, name, enrolmentkey) + */ + public static function get_groups($params) { + $groups = array(); + + //TODO: we do need to search for groups in courses too, + // fetching by id is not enough! + + foreach ($params as $groupid) { + $groupid = clean_param($groupid, PARAM_INTEGER); + $group = groups_get_group($groupid, 'id, courseid, name, enrolmentkey', MUST_EXIST); + // now security checks + $context = get_context_instance(CONTEXT_COURSE, $group->courseid); + self::validate_context($context); + require_capability('moodle/course:managegroups', $context); + + $groups[$group->id] = $group; + } + + return $groups; + } + + /** + * Delete groups + * @param array $params array of group ids + * @return void + */ + public static function delete_groups($params) { + global $CFG; + require_once("$CFG->dirroot/group/lib.php"); + + $groups = array(); + + foreach ($params as $groupid) { + $groupid = clean_param($groupid, PARAM_INTEGER); + if (!$group = groups_get_group($groupid, 'id, courseid', IGNORE_MISSING)) { + // silently ignore attempts to delete nonexisting groups + continue; + } + // now security checks + $context = get_context_instance(CONTEXT_COURSE, $group->courseid); + self::validate_context($context); + require_capability('moodle/course:managegroups', $context); + + groups_delete_group($group); + } + } + + + /** + * Return all members for a group + * @param array $params array of group ids + * @return array with group id keys containing arrays of user ids + */ + public static function get_groupmembers($params) { + $groups = array(); + + foreach ($params as $groupid) { + $groupid = clean_param($groupid, PARAM_INTEGER); + $group = groups_get_group($groupid, 'id, courseid, name, enrolmentkey', MUST_EXIST); + // now security checks + $context = get_context_instance(CONTEXT_COURSE, $group->courseid); + self::validate_context($context); + require_capability('moodle/course:managegroups', $context); + + $groupmembers = groups_get_members($group->id, 'u.id', 'lastname ASC, firstname ASC'); + + $groups[$group->id] = array_keys($groupmembers); + } + + return $groups; + } + + + /** + * Add group members + * @param array of arrays with keys userid, groupid + * @return void + */ + public static function add_groupmembers($params) { + global $CFG; + require_once("$CFG->dirroot/group/lib.php"); + + $groups = array(); + + foreach ($params as $member) { + $groupid = clean_param($member['groupid'], PARAM_INTEGER); + $userid = clean_param($member['userid'], PARAM_INTEGER); + $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST); + $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id)); + + // now security checks + $context = get_context_instance(CONTEXT_COURSE, $group->courseid); + self::validate_context($context); + require_capability('moodle/course:managegroups', $context); + require_capability('moodle/course:view', $context, $user->id, false); // only enrolled users may be members of group!!! + + groups_add_member($group, $user); + } + } + + + /** + * Delete group members + * @param array of arrays with keys userid, groupid + * @return void + */ + public static function delete_groupmembers($params){ + global $CFG; + require_once("$CFG->dirroot/group/lib.php"); + + $groups = array(); + + foreach ($params as $member) { + $groupid = clean_param($member['groupid'], PARAM_INTEGER); + $userid = clean_param($member['userid'], PARAM_INTEGER); + $group = groups_get_group($groupid, 'id, courseid'); + $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id)); + + // now security checks + $context = get_context_instance(CONTEXT_COURSE, $group->courseid); + self::validate_context($context); + require_capability('moodle/course:managegroups', $context); + + groups_remove_member($group, $user); + } + } + +} \ No newline at end of file diff --git a/group/lib.php b/group/lib.php index a69c9b73c2f..99595c879f3 100644 --- a/group/lib.php +++ b/group/lib.php @@ -15,26 +15,33 @@ /** * Adds a specified user to a group - * @param int $userid The user id - * @param int $groupid The group id + * @param mixed $groupid The group id or group object + * @param mixed $userid The user id or user object * @return boolean True if user added successfully or the user is already a * member of the group, false otherwise. */ -function groups_add_member($groupid, $userid) { +function groups_add_member($grouporid, $userorid) { global $DB; - if (! $DB->record_exists('user', array('id'=>$userid))) { - throw new moodle_exception('useriddoesntexist'); + if (is_object($userorid)) { + $userid = $userorid->id; + $user = $userorid; + } else { + $userid = $userorid; + $user = $DB->get_record('users', array('id'=>$userid), '*', MUST_EXIST); } - $group = $DB->get_record('groups', array('id'=>$groupid)); - if (empty($group)) { - throw new moodle_exception('cannotaddmembergroupiddoesntexist'); + if (is_object($grouporid)) { + $groupid = $grouporid->id; + $group = $grouporid; + } else { + $groupid = $grouporid; + $group = $DB->get_record('groups', array('id'=>$groupid), '*', MUST_EXIST); } //check if the user a participant of the group course if (!is_course_participant ($userid, $group->courseid)) { - throw new moodle_exception('userisnotaparticipant'); + return false; } if (groups_is_member($groupid, $userid)) { @@ -62,19 +69,27 @@ function groups_add_member($groupid, $userid) { /** * Deletes the link between the specified user and group. - * @param int $groupid The group to delete the user from - * @param int $userid The user to delete + * @param mixed $groupid The group id or group object + * @param mixed $userid The user id or user object * @return boolean True if deletion was successful, false otherwise */ -function groups_remove_member($groupid, $userid) { +function groups_remove_member($grouporid, $userorid) { global $DB; - if (! $DB->record_exists('user', array('id'=>$userid))) { - throw new moodle_exception('useriddoesntexist'); + if (is_object($userorid)) { + $userid = $userorid->id; + $user = $userorid; + } else { + $userid = $userorid; + $user = $DB->get_record('users', array('id'=>$userid), '*', MUST_EXIST); } - if (!groups_group_exists($groupid)) { - throw new moodle_exception('cannotaddmembergroupiddoesntexist'); + if (is_object($grouporid)) { + $groupid = $grouporid->id; + $group = $grouporid; + } else { + $groupid = $grouporid; + $group = $DB->get_record('groups', array('id'=>$groupid), '*', MUST_EXIST); } if (!groups_is_member($groupid, $userid)) { @@ -106,11 +121,7 @@ function groups_create_group($data, $editform=false) { require_once("$CFG->libdir/gdlib.php"); //check that courseid exists - $course = $DB->get_record('course',array('id' => $data->courseid)); - if (empty($course)) { - throw new moodle_exception('coursedoesntexistcannotcreategroup'); - } - + $course = $DB->get_record('course', array('id' => $data->courseid), '*', MUST_EXIST); $data->timecreated = time(); $data->timemodified = $data->timecreated; @@ -203,8 +214,7 @@ function groups_update_grouping($data) { * @return boolean True if deletion was successful, false otherwise */ function groups_delete_group($grouporid) { - global $CFG, $DB; - require_once($CFG->libdir.'/gdlib.php'); + global $DB; if (is_object($grouporid)) { $groupid = $grouporid->id; @@ -212,7 +222,8 @@ function groups_delete_group($grouporid) { } else { $groupid = $grouporid; if (!$group = $DB->get_record('groups', array('id'=>$groupid))) { - throw new moodle_exception('groupiddoesntexistcannotdelete');; + //silently ignore attempts to delete missing already deleted groups ;-) + return true; } } @@ -246,7 +257,8 @@ function groups_delete_grouping($groupingorid) { } else { $groupingid = $groupingorid; if (!$grouping = $DB->get_record('groupings', array('id'=>$groupingorid))) { - return false; + //silently ignore attempts to delete missing already deleted groupings ;-) + return true; } } diff --git a/lang/en_utf8/error.php b/lang/en_utf8/error.php index b6d18d8dc0e..c359ea2f153 100644 --- a/lang/en_utf8/error.php +++ b/lang/en_utf8/error.php @@ -15,7 +15,6 @@ $string['backupcontainexternal'] = 'This backup file contains external Moodle Ne $string['backuptablefail'] = 'Backup tables could NOT be set up successfully!'; $string['cannotaddcoursemodule'] = 'Could not add a new course module'; $string['cannotaddcoursemoduletosection'] = 'Could not add the new course module to that section'; -$string['cannotaddmembergroupiddoesntexist'] = 'Cannot add member group: the group id doesn\'t exist'; $string['cannotaddmodule'] = '$a module could not be added to the module list!'; $string['cannotaddnewmodule'] = 'Could not add a new module of $a'; $string['cannotaddrss'] = 'You do not have permission to add rss feeds'; @@ -149,7 +148,6 @@ $string['confirmsesskeybad'] = 'Sorry, but your session key could not be confirm $string['couldnotassignrole'] = 'A serious but unspecified error occurred while trying to assign a role to you'; $string['couldnotupdatenoexistinguser'] = 'Cannot update the user - user doesn\'t exist'; $string['countriesphpempty'] = 'Error: The file countries.php in language pack $a is empty or missing.'; -$string['coursedoesntexistcannotcreategroup'] = 'Cannot create group: the course doesn\'t exist'; $string['coursegroupunknown'] = 'Course corresponding to group $a not specified'; $string['courseidnotfound'] = 'Course id doesn\'t exist'; $string['coursemisconf'] = 'Course is misconfigured'; @@ -216,7 +214,6 @@ $string['headersent'] = 'Headers already sent'; $string['generalexceptionmessage'] = 'Exception - $a'; $string['gradepubdisable'] = 'Grade publishing disabled'; $string['groupalready'] = 'User already belongs to group $a'; -$string['groupiddoesntexistcannotdelete'] = 'Cannot delete group: group id doesn\'t exist'; $string['groupexistforcourse'] = 'Group \"$a\" already exists for this course'; $string['groupnotaddederror'] = 'Group \"$a\" not added'; $string['groupunknown'] = 'Group $a not associated to specified course'; @@ -386,6 +383,7 @@ $string['refoundto'] = 'Can be refunded to $a'; $string['remotedownloaderror'] = 'Download of component to your server failed, please verify proxy settings, PHP cURL extension is highly recommended.

You must download the url\">$a->url file manually, copy it to \"$a->dest\" in your server and unzip it there.'; $string['remotedownloadnotallowed'] = 'Download of components to your server isn\'t allowed (allow_url_fopen is disabled).

You must download the url\">$a->url file manually, copy it to \"$a->dest\" in your server and unzip it there.'; $string['restricteduser'] = 'Sorry, but your current account \"$a\" is restricted from doing that'; +$string['restrictedcontextexception'] = 'Sorry, execution of external function violates context restriction.'; $string['reportnotavailable'] = 'This type of report is only available for the site course'; $string['reverseproxyabused'] = 'Reverse proxy enabled, server can not be accessed directly, sorry.
Please contact server administrator.'; $string['rpcerror'] = 'RPC enrol/mnet/available_courses: ($a)'; @@ -450,8 +448,6 @@ $string['upgraderequires19'] = 'Error: New Moodle version was installed on serve $string['urlnotdefinerss'] = 'URL not defined for RSS feed'; $string['userautherror'] = 'Unknown auth plugin'; $string['userauthunsupported'] = 'Auth plugin not supported here'; -$string['useriddoesntexist'] = 'User id doesn\'t exist'; -$string['userisnotaparticipant'] = 'The user is not a course participant'; $string['useremailduplicate'] = 'Duplicate address'; $string['usermustbemnet'] = 'Users in the MNET access control list must be remote MNET users'; $string['usernotaddedadmin'] = 'Cannot delete admin accounts'; @@ -480,16 +476,11 @@ $string['wrongroleid'] = 'Incorrect role ID!'; $string['wrongsourcebase'] = 'Wrong source URL base'; $string['wrongusernamepassword'] = 'Wrong user/password'; $string['wrongzipfilename'] = 'Wrong ZIP file name'; -$string['wscouldnotaddgroupmembernopermission'] = 'WS - Could not add group member - No permission'; $string['wscouldnotcreateecoursenopermission'] = 'WS - Could not create course - No permission'; -$string['wscouldnotcreategroupnopermission'] = 'WS - Could not create group - No permission'; $string['wscouldnotcreateeuserindb'] = 'WS - Could not create a user'; $string['wscouldnotcreateeusernopermission'] = 'WS - Could not create a user - No permission'; -$string['wscouldnotdeletegroupnopermission'] = 'WS - Could not delete group - No permission'; $string['wscouldnotdeletenoexistinguser'] = 'WS - Could not delete a user - User doesn\'t exist'; $string['wscouldnotdeleteusernopermission'] = 'WS - Could not delete a user - No permission'; -$string['wscouldnotgetgroupnopermission'] = 'WS - Could not get group - No permission'; -$string['wscouldnotremovegroupmembernopermission'] = 'WS - Could not remove group member - No permission'; $string['wscouldnotupdatenoexistinguser'] = 'WS - Could not update a user - User doesn\'t exist'; $string['wscouldnotupdateuserindb'] = 'WS - Could not update a user'; $string['wscouldnotupdateusernopermission'] = 'WS - Could not update a user - No permission'; diff --git a/lib/accesslib.php b/lib/accesslib.php index 76c650a42c8..54725a55131 100755 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -1074,8 +1074,7 @@ function aggregate_roles_from_accessdata($context, $accessdata) { function require_capability($capability, $context, $userid = NULL, $doanything = true, $errormessage = 'nopermissions', $stringfile = '') { if (!has_capability($capability, $context, $userid, $doanything)) { - $capabilityname = get_capability_string($capability); - print_error($errormessage, $stringfile, get_context_url($context), $capabilityname); + throw new required_capability_exception($context, $capability, $errormessage, $stringfile); } } diff --git a/lib/db/services.php b/lib/db/services.php new file mode 100644 index 00000000000..b808156584f --- /dev/null +++ b/lib/db/services.php @@ -0,0 +1,76 @@ +. + +/** + * Core external functions and service definitions. + * + * @package moodlecore + * @subpackage webservice + * @copyright 2009 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$functions = array( + 'moodle_group_create_groups' => array( + 'classname' => 'moodle_group_external', + 'methodname' => 'create_groups', + 'classpath' => 'group/externallib.php', + 'params' => null, //TODO + 'returns' => null, //TODO + ), + + 'moodle_group_get_groups' => array( + 'classname' => 'moodle_group_external', + 'methodname' => 'get_groups', + 'classpath' => 'group/externallib.php', + 'params' => null, //TODO + 'returns' => null, //TODO + ), + + 'moodle_group_delete_groups' => array( + 'classname' => 'moodle_group_external', + 'methodname' => 'delete_groups', + 'classpath' => 'group/externallib.php', + 'params' => null, //TODO + 'returns' => null, //TODO + ), + + 'moodle_group_get_groupmembers' => array( + 'classname' => 'moodle_group_external', + 'methodname' => 'get_groupmembers', + 'classpath' => 'group/externallib.php', + 'params' => null, //TODO + 'returns' => null, //TODO + ), + + 'moodle_group_add_groupmembers' => array( + 'classname' => 'moodle_group_external', + 'methodname' => 'add_groupmembers', + 'classpath' => 'group/externallib.php', + 'params' => null, //TODO + 'returns' => null, //TODO + ), + + 'moodle_group_delete_groupmembers' => array( + 'classname' => 'moodle_group_external', + 'methodname' => 'delete_groupmembers', + 'classpath' => 'group/externallib.php', + 'params' => null, //TODO + 'returns' => null, //TODO + ), + +); diff --git a/lib/externallib.php b/lib/externallib.php new file mode 100644 index 00000000000..b0418051969 --- /dev/null +++ b/lib/externallib.php @@ -0,0 +1,137 @@ +. + +/** + * Support for external API + * + * @package moodlecore + * @subpackage webservice + * @copyright 2008 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Exception indicating user is not allowed to use external function in + * the current context. + */ +class restricted_context_exception extends moodle_exception { + /** + * Constructor + */ + function __construct() { + parent::__construct('restrictedcontextexception', 'error'); + } +} + +/** + * Base class for external api methods. + */ +class external_api { + + + private static $contextrestriction; + + public static function set_context_restriction($contex) { + self::$contextrestriction = $context; + } + + /** + * Makes sure user may execute functions in this context. + * @param object $context + * @return void + */ + protected static function validate_context($context) { + if (empty(self::$contextrestriction)) { + self::$contextrestriction = get_context_instance(CONTEXT_SYSTEM); + } + $rcontext = self::$contextrestriction; + + if ($rcontext->contextlevel == $context->contextlevel) { + if ($rcontex->id != $context->id) { + throw new restricted_context_exception(); + } + } else if ($rcontext->contextlevel > $context->contextlevel) { + throw new restricted_context_exception(); + } else { + $parents = get_parent_contexts($context); + if (!in_array($rcontext->id, $parents)) { + throw new restricted_context_exception(); + } + } + + if ($context->contextlevel >= CONTEXT_COURSE) { + //TODO: temporary bloody hack, this needs to be replaced by + // proper enrolment and course visibility check + // similar to require_login() (which can not be used + // because it can be used only once and redirects) + // oh - did I tell we need to rewrite enrolments in 2.0 + // to solve this bloody mess? + // + // missing: hidden courses and categories, groupmembersonly, + // conditional activities, etc. + require_capability('moodle/course:view', $context); + } + } + + /** + * Some automatic type validation of parameters + * @param string $functionname + * @param mixed $params + * @return mixed cleaned parameters + */ + protected static function cleanparams($functionname, $params) { + //TODO: implement cleaning + // do we need this? We need only basic data types for web services, right? + return $params; + } + + /** + * Returns detailed information about external function + * @param string $functionname name of external function + * @return aray + */ + public static function get_function_info($functionname) { + global $CFG, $DB; + + //TODO: this is very slow, we should add some caching here + $function = $DB->get_record('external_functions', array('name'=>$functionname), '*', MUST_EXIST); + + $defpath = get_component_directory($function->component); + if (!file_exists("$defpath/db/services.php")) { + //TODO: maybe better throw invalid parameter exception + return null; + } + + $functions = array(); + include("$defpath/db/services.php"); + + if (empty($functions[$functionname])) { + return null; + } + + $desc = $functions[$functionname]; + if (empty($desc['classpath'])) { + $desc['classpath'] = "$defpath/externallib.php"; + } else { + $desc['classpath'] = "$CFG->dirroot/".$desc['classpath']; + } + $desc['component'] = $function->component; + + return $desc; + } +} + diff --git a/lib/grouplib.php b/lib/grouplib.php index 5db4d8c8315..6738c299ac7 100644 --- a/lib/grouplib.php +++ b/lib/grouplib.php @@ -111,32 +111,29 @@ function groups_get_grouping_by_name($courseid, $name) { /** * Get the group object * - * @global object * @param int $groupid ID of the group. * @return object group object */ -function groups_get_group($groupid) { +function groups_get_group($groupid, $fields='*', $strictness=IGNORE_MISSING) { global $DB; - return $DB->get_record('groups', array('id'=>$groupid)); + return $DB->get_record('groups', array('id'=>$groupid), $fields, $strictness); } /** * Get the grouping object * - * @global object * @param int $groupingid ID of the group. + * @param string $fields * @return object group object */ -function groups_get_grouping($groupingid) { +function groups_get_grouping($groupingid, $fields='*', $strictness=IGNORE_MISSING) { global $DB; - return $DB->get_record('groupings', array('id'=>$groupingid)); + return $DB->get_record('groupings', array('id'=>$groupingid), $fields, $strictness); } /** * Gets array of all groups in a specified course. * - * @global object - * @global object * @param int $courseid The id of the course. * @param mixed $userid optional user id or array of ids, returns only groups of the user. * @param int $groupingid optional returns only groups in the specified grouping. diff --git a/lib/setuplib.php b/lib/setuplib.php index 65b1f0576aa..791f3f28b9f 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -91,6 +91,17 @@ class moodle_exception extends Exception { } } +/** + * Exceptions indicating user does not have permissions to do something + * and the execution can not continue. + */ +class required_capability_exception extends moodle_exception { + function __construct($context, $capability, $errormessage, $stringfile) { + $capabilityname = get_capability_string($capability); + parent::__construct($errormessage, $stringfile, get_context_url($context), $capabilityname); + } +} + /** * Exception indicating programming error, must be fixed by a programer. For example * a core API might throw this type of exception if a plugin calls it incorrectly.