]> git.mjollnir.org Git - moodle.git/commitdiff
Checking in proposed new externallib.php for Petr to look at.
authormoodler <moodler>
Wed, 16 Sep 2009 06:50:31 +0000 (06:50 +0000)
committermoodler <moodler>
Wed, 16 Sep 2009 06:50:31 +0000 (06:50 +0000)
user/externallib.php

index 9a8e4277c556c4ed67fa79007aab859b9042937e..f36e585f7114a070e4c3aabc12bb11be76c84909 100644 (file)
@@ -28,93 +28,100 @@ require_once("$CFG->libdir/externallib.php");
 
 class moodle_user_external extends external_api {
 
-    public static function get_users($params) {
-        $context = get_context_instance(CONTEXT_SYSTEM);
-        requier_capability('moodle/user:viewdetails', $context);
-        self::validate_context($context);
-
-        $search = validate_param($params['search'], PARAM_RAW);
-
-        //TODO: this search is probably useless for external systems because it is not exact
-        //      1/ we should specify multiple search parameters including the mnet host id
-        //      2/ custom profile fileds not inlcuded
-
-        return get_users(true, $search, false, null, 'firstname ASC','', '', '', 1000, 'id, mnethostid, auth, confirmed, username, idnumber, firstname, lastname, email, emailstop, lang, theme, timezone, mailformat, city, description, country');
-    }
-
+/// Public descriptions of parameters and returned variables for validation and documentation
+
+/// Create_users
+    $userpreference = new object();
+    $userpreference->name =  array(PARAM_ALPHANUMEXT, 'The name of the preference to set');
+    $userpreference->value =  array(PARAM_RAW, 'The value of the preference');
+
+    $usercustomfields = new object();
+    $usercustomfields->name =  array(PARAM_ALPHANUMEXT, 'The name of the custom field (must exist)');
+    $usercustomfields->value =  array(PARAM_RAW, 'The value of the custom field');
+
+    $usertocreate = new object(); 
+    $usertocreate->username    = array(PARAM_USERNAME, 'Username policy is defined in Moodle security config', REQUIRED);
+    $usertocreate->password    = array(PARAM_RAW, 'Moodle passwords can consist of any character', REQUIRED);
+    $usertocreate->firstname   = array(PARAM_NOTAGS, 'The first name(s) of the user', REQUIRED);
+    $usertocreate->lastname    = array(PARAM_NOTAGS, 'The family name of the user', REQUIRED);
+    $usertocreate->email       = array(PARAM_EMAIL, 'A valid and unique email address', REQUIRED);
+    $usertocreate->auth        = array(PARAM_AUTH, 'Auth plugins include manual, ldap, imap, etc');
+    $usertocreate->confirmed   = array(PARAM_NUMBER, 'Active user: 1 if confirmed, 0 otherwise');
+    $usertocreate->idnumber    = array(PARAM_RAW, 'An arbitrary ID code number perhaps from the institution');
+    $usertocreate->emailstop   = array(PARAM_NUMBER, 'Email is blocked: 1 is blocked and 0 otherwise');
+    $usertocreate->lang        = array(PARAM_LANG, 'Language code such as "en_utf8", must exist on server');
+    $usertocreate->theme       = array(PARAM_THEME, 'Theme name such as "standard", must exist on server');
+    $usertocreate->timezone    = array(PARAM_ALPHANUMEXT, 'Timezone code such as Australia/Perth, or 99 for default');
+    $usertocreate->mailformat  = array(PARAM_INTEGER, 'Mail format code is 0 for plain text, 1 for HTML etc');
+    $usertocreate->description = array(PARAM_TEXT, 'User profile description, as HTML');
+    $usertocreate->city        = array(PARAM_NOTAGS, 'Home city of the user');
+    $usertocreate->country     = array(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ');
+    $usertocreate->preferences = array('multiple' => $userpreference);
+    $usertocreate->custom      = array('multiple' -> $usercustomfields);
+
+    $createusersparams = new object();
+    $createusersparams->users  = array('multiple' => $usertocreate);
+
+    $createusersreturn = new object();
+    $createusersreturn->userids = array('multiple' => PARAM_NUMBER);
+
+    /* 
+     * Create one or more users
+     *
+     * @param $params  An array of users to create.  Each user is defined by $usertocreate above.
+     * 
+     * @return $return  An array of userids, one for each user that was created
+     */
     public static function create_users($params) {
         global $CFG, $DB;
 
+        // Ensure the current user is allowed to run this function
         $context = get_context_instance(CONTEXT_SYSTEM);
-        requier_capability('moodle/user:create', $context);
+        require_capability('moodle/user:create', $context);
         self::validate_context($context);
 
-        //TODO: this list is incomplete - we have preferences and custom fields too
-        $accepted = array(
-            'password' => PARAM_RAW,
-            'auth' => PARAM_SAFEDIR,
-            'username' => PARAM_RAW,
-            'idnumber' => PARAM_RAW,
-            'firstname' => PARAM_CLEAN,
-            'lastname' => PARAM_CLEAN,
-            'email' => PARAM_EMAIL,
-            'emailstop' => PARAM_BOOL,
-            'lang' => PARAM_SAFEDIR, // validate using list of available langs - ignored if wrong
-            'theme' => PARAM_SAFEDIR,
-            'timezone' => PARAM_ALPHANUMEXT,
-            'mailformat' => PARAM_ALPHA,
-            'description' => PARAM_RAW,
-            'city' => PARAM_CLEAN,
-            'country' => PARAM_ALPHANUMEXT,
-        );
-
-        $required = array('username', 'firstname', 'lastname', 'email', 'password'); //TODO: password may not be required in some cases
-        $langs = get_list_of_languages();
-
-        // verify data first, only then start creating records
+        // Do basic automatic PARAM checks on incoming data, using params description
+        // This checks to make sure that:
+        //      1) No extra data was sent
+        //      2) All required items were sent 
+        //      3) All data passes clean_param without changes (yes this is strict)
+        // If any problems are found then exceptions are thrown with helpful error messages
+        self::validate_params($params, $this->createuserparams);
+
+
+        // Perform further checks and build up a clean array of user data
+        // Nothing is actually performed until the whole dataset is checked
         $users = array();
-        foreach ($params as $data) {
-            $user = array();
-            foreach ($accepted as $key=>$type) {
-                if (array_key_exists($key, $data)) {
-                    $user[$key] = validate_param($data[$key], $type);
-                    unset($data[$key]);
-                }
-            }
-            if (!empty($data)) {
-                throw new invalid_parameter_exception('Unsupported parameters in user array');
-            }
-            foreach ($required as $req) {
-                if (!array_key_exists($req, $user) or empty($user[$req])) {
-                    throw new invalid_parameter_exception("$req is required in user array");
-                }
-            }
-            if (!isset($user['auth'])) {
+        foreach ($params as $user) {
+
+            // Empty or no auth is assumed to be manual
+            if (empty($user['auth'])) {     
                 $user['auth'] = 'manual';
             }
-            if (!exists_auth_plugin($user['auth'])) {
-                throw new invalid_parameter_exception($user['auth']." is not valid authentication plugin");
-            }
 
-            if (isset($user['lang']) and !isset($langs[$user['lang']])) {
+            // Lang must be a real code, not empty string
+            if (isset($user['lang']) && empty($user['lang'])) {
                 unset($user['lang']);
             }
 
-            //TODO: add more param validations here: username, etc.
-
+            // Make sure that the username doesn't already exist
             if ($DB->get_record('user', array('username'=>$user['username'], 'mnethostid'=>$CFG->mnet_localhost_id))) {
                 throw new invalid_parameter_exception($user['username']." username is already taken, sorry");
             }
 
+            // Make sure that incoming data doesn't contain duplicate usernames
             if (isset($users[$user['username']])) {
                 throw new invalid_parameter_exception("multiple users with the same username requested");
             }
-            $users[$user['username']] = $user;
+
+            // TODO: More checks here?
+
+            $users[$user['username']] = $user;   // Add this data to an array (mem overflows?)
         }
 
         $result = array();
 
-        foreach ($users as $user) {
+        foreach ($users as $user) {  // Actually create the user accounts now
             $record = create_user_record($user['username'], $user['password'], $user['auth']);
             unset($user['username']);
             unset($user['password']);
@@ -126,8 +133,10 @@ class moodle_user_external extends external_api {
             }
             $DB->update_record('user', $record);
 
-            unset($record->password); // lets keep this as a secret ;-)
-            $result[$record->id] = $record;
+            $result[] = $record->id;
+
+            // TODO: Save all the preferences and custom fields here
+
         }
 
         return $result;
@@ -142,4 +151,19 @@ class moodle_user_external extends external_api {
     public static function update_users($params) {
         //TODO
     }
-}
\ No newline at end of file
+
+    public static function get_users($params) {
+        $context = get_context_instance(CONTEXT_SYSTEM);
+        require_capability('moodle/user:viewdetails', $context);
+        self::validate_context($context);
+
+        $search = validate_param($params['search'], PARAM_RAW);
+
+        //TODO: this search is probably useless for external systems because it is not exact
+        //      1/ we should specify multiple search parameters including the mnet host id
+        //      2/ custom profile fileds not inlcuded
+
+        return get_users(true, $search, false, null, 'firstname ASC','', '', '', 1000, 'id, mnethostid, auth, confirmed, username, idnumber, firstname, lastname, email, emailstop, lang, theme, timezone, mailformat, city, description, country');
+    }
+
+}