MDL-12886 new design of external service functions, groups api improved and known...
authorskodak <skodak>
Mon, 14 Sep 2009 23:52:08 +0000 (23:52 +0000)
committerskodak <skodak>
Mon, 14 Sep 2009 23:52:08 +0000 (23:52 +0000)
group/external.php [deleted file]
group/externallib.php [new file with mode: 0644]
group/lib.php
lang/en_utf8/error.php
lib/accesslib.php
lib/db/services.php [new file with mode: 0644]
lib/externallib.php [new file with mode: 0644]
lib/grouplib.php
lib/setuplib.php

diff --git a/group/external.php b/group/external.php
deleted file mode 100644 (file)
index d4ec63b..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-<?php
-/**
- *
- * Group external api
- *
- * @author Jordi Piguillem
- * @author David Castro
- * @author Ferran Recio
- * @author Jerome Mouneyrac
- */
-require_once(dirname(dirname(__FILE__)) . '/lib/moodleexternal.php');
-require_once(dirname(dirname(__FILE__)) . '/group/lib.php');
-require_once(dirname(dirname(__FILE__)) . '/lib/grouplib.php');
-
-
-/**
- * Group external api class
- *
- */
-final class group_external extends moodle_external {
-
-    /**
-     * Create some groups
-     * @param array|struct $params
-     * @subparam string $params:group->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 (file)
index 0000000..2b20f42
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * 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
index a69c9b7..99595c8 100644 (file)
 
 /**
  * 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;
         }
     }
 
index b6d18d8..c359ea2 100644 (file)
@@ -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.<br /><br />You must download the <a href=\"$a->url\">$a->url</a> 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).<br /><br />You must download the <a href=\"$a->url\">$a->url</a> 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.<br />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';
index 76c650a..54725a5 100755 (executable)
@@ -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 (file)
index 0000000..b808156
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * 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 (file)
index 0000000..b041805
--- /dev/null
@@ -0,0 +1,137 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * 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;
+    }
+}
+
index 5db4d8c..6738c29 100644 (file)
@@ -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.
index 65b1f05..791f3f2 100644 (file)
@@ -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.