MDL-12886 converting user/external.php to externallib.php - work in progress

This commit is contained in:
skodak 2009-09-15 22:52:49 +00:00
parent df5f916570
commit ef22c1b664
6 changed files with 187 additions and 389 deletions

View File

@ -454,7 +454,6 @@ $string['usernotaddedadmin'] = 'Cannot delete admin accounts';
$string['usernotaddederror'] = 'User not added - error';
$string['usernotaddedregistered'] = 'User not added - already registered';
$string['usernotavailable'] = 'The details of this user are not available to you';
$string['usernotcreated'] = 'The user could not be created';
$string['usernotdeletederror'] = 'User not deleted - error';
$string['usernotdeletedmissing'] = 'User not deleted - could not find the username';
$string['usernotdeletedoff'] = 'User not deleted - deleting not allowed';
@ -477,7 +476,6 @@ $string['wrongsourcebase'] = 'Wrong source URL base';
$string['wrongusernamepassword'] = 'Wrong user/password';
$string['wrongzipfilename'] = 'Wrong ZIP file name';
$string['wscouldnotcreateecoursenopermission'] = 'WS - Could not create course - No permission';
$string['wscouldnotcreateeuserindb'] = 'WS - Could not create a user';
$string['wscouldnotcreateeusernopermission'] = 'WS - Could not create a user - No permission';
$string['wscouldnotdeletenoexistinguser'] = 'WS - Could not delete a user - User doesn\'t exist';
$string['wscouldnotdeleteusernopermission'] = 'WS - Could not delete a user - No permission';

View File

@ -25,6 +25,9 @@
*/
$functions = array(
// === group related functions ===
'moodle_group_create_groups' => array(
'classname' => 'moodle_group_external',
'methodname' => 'create_groups',
@ -73,4 +76,38 @@ $functions = array(
'returns' => null, //TODO
),
// === user related functions ===
'moodle_user_create_users' => array(
'classname' => 'moodle_user_external',
'methodname' => 'create_users',
'classpath' => 'user/externallib.php',
'params' => null, //TODO
'returns' => null, //TODO
),
'moodle_user_get_users' => array(
'classname' => 'moodle_user_external',
'methodname' => 'get_users',
'classpath' => 'user/externallib.php',
'params' => null, //TODO
'returns' => null, //TODO
),
'moodle_user_delete_users' => array(
'classname' => 'moodle_user_external',
'methodname' => 'delete_users',
'classpath' => 'user/externallib.php',
'params' => null, //TODO
'returns' => null, //TODO
),
'moodle_user_update_users' => array(
'classname' => 'moodle_user_external',
'methodname' => 'update_users',
'classpath' => 'user/externallib.php',
'params' => null, //TODO
'returns' => null, //TODO
),
);

View File

@ -1,116 +0,0 @@
<?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/>.
/**
* moodleexternal.php - parent class of any external.php file into Moodle
*
* @package moodlecore
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class moodle_external {
protected $descriptions; //the web service description of the external.php functions
function __construct () {
$this->descriptions = array();
}
/**
* Return web service description for a specific function
* @param string $functionname
* @return array the web service description of the function, return false if the function name doesn't exist
*/
public function get_function_webservice_description($functionname) {
if (key_exists($functionname, $this->descriptions)) {
return $this->descriptions[$functionname];
}
else {
return false;
}
}
/**
* Return web service description for all web service functions of the external class
* @return array
*/
public function get_descriptions() {
return $this->descriptions;
}
/**
* This function clean params,
* It's protected because we should only clean the params into external files (not server layer)
* @param array $params
*/
protected function clean_function_params($functionname, &$params) {
$description = $this->get_function_webservice_description($functionname);
$this->clean_object($description['params'], $params);
}
/**
* Clean an array param
* @param array $description - an array with only one element !
* @param array $params - an array with one or several elements
*/
protected function clean_params($description, &$params) {
foreach ($params as &$param) {
if (is_array($param) ) { //it's a list
$this->clean_params($description[0], $param);
}
else {
if (is_object($param)) { //it's an object
$this->clean_object($description[0], $param);
}
else { //it's a primary type
$param = clean_param($param, $description[0]);
}
}
}
}
/**
* Clean an object param
* @param object $objectdescription
* @param object $paramobject
*/
protected function clean_object($objectdescription, &$paramobject) {
foreach (get_object_vars($paramobject) as $propertyname => $propertyvalue) {
if (!isset($objectdescription->$propertyname)) { //if the param is not defined into the web service description
throw new moodle_exception('wswrongparams'); //throw exception
}
if (is_array($propertyvalue)) { //the object property is a list
$this->clean_params($objectdescription->$propertyname, $propertyvalue);
$paramobject->$propertyname = $propertyvalue;
}
else {
if (is_object($propertyvalue)) { //the object property is an object
$this->clean_object($objectdescription->$propertyname, $propertyvalue);
$paramobject->$propertyname = $propertyvalue;
}
else { //the object property is a primary type
$paramobject->$propertyname = clean_param($propertyvalue, $objectdescription->$propertyname);
}
}
}
}
}

View File

@ -22,6 +22,10 @@
* @copyright Copyright (c) 1999 onwards Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL License
*/
die('this file is being migrated to exxternallib.php right now...');
require_once(dirname(dirname(__FILE__)) . '/lib/moodleexternal.php');
require_once(dirname(dirname(__FILE__)) . '/user/lib.php');
@ -38,60 +42,6 @@ final class user_external extends moodle_external {
function __construct () {
$this->descriptions = array();
$user = new object();
$user->password = PARAM_ALPHANUMEXT;
$user->auth = PARAM_ALPHANUMEXT;
$user->confirmed = PARAM_NUMBER;
$user->username = PARAM_ALPHANUMEXT;
$user->idnumber = PARAM_ALPHANUMEXT;
$user->firstname = PARAM_ALPHANUMEXT;
$user->lastname = PARAM_ALPHANUMEXT;
$user->email = PARAM_NOTAGS;
$user->emailstop = PARAM_NUMBER;
$user->lang = PARAM_ALPHA;
$user->theme = PARAM_ALPHANUM;
$user->timezone = PARAM_ALPHANUMEXT;
$user->mailformat = PARAM_ALPHA;
$user->description = PARAM_TEXT;
$user->city = PARAM_ALPHANUMEXT;
$user->country = PARAM_ALPHANUMEXT;
$params = new object();
$params->users = array($user);
$return = new object();
$return->userids = array(PARAM_NUMBER);
$this->descriptions['create_users'] = array( 'params' => $params,
'optionalinformation' => 'Username, password, firstname, and username are the only mandatory',
'return' => $return,
'service' => 'user',
'requiredlogin' => 0);
$user = new object();
$user->id = PARAM_NUMBER;
$user->auth = PARAM_ALPHANUMEXT;
$user->confirmed = PARAM_NUMBER;
$user->username = PARAM_ALPHANUMEXT;
$user->idnumber = PARAM_ALPHANUMEXT;
$user->firstname = PARAM_ALPHANUMEXT;
$user->lastname = PARAM_ALPHANUMEXT;
$user->email = PARAM_NOTAGS;
$user->emailstop = PARAM_NUMBER;
$user->lang = PARAM_ALPHA;
$user->theme = PARAM_ALPHANUM;
$user->timezone = PARAM_ALPHANUMEXT;
$user->mailformat = PARAM_ALPHA;
$user->description = PARAM_TEXT;
$user->city = PARAM_ALPHANUMEXT;
$user->country = PARAM_ALPHANUMEXT;
$params = new object();
$params->search = PARAM_ALPHANUM;
$return = new object();
$return->users = array($user);
$this->descriptions['get_users'] = array( 'params' => $params,
'optionalparams' => 'All params are not mandatory',
'return' => $return,
'service' => 'user',
'requiredlogin' => 0);
$params = new object();
$params->usernames = array(PARAM_ALPHANUMEXT);
$return = new object();
@ -112,49 +62,6 @@ final class user_external extends moodle_external {
'requiredlogin' => 0);
}
/**
* Retrieve all user
* @param object|struct $params - need to be define as struct for XMLRPC
* @return object $return
*/
public function get_users($params) {
global $USER;
$this->clean_function_params('get_users', $params);
if (has_capability('moodle/user:viewdetails', get_context_instance(CONTEXT_SYSTEM))) {
return get_users(true, $params->search, false, null, 'firstname ASC','', '', '', 1000, 'id, auth, confirmed, username, idnumber, firstname, lastname, email, emailstop, lang, theme, timezone, mailformat, city, description, country');
}
else {
throw new moodle_exception('wscouldnotvieweusernopermission');
}
}
/**
* Create multiple users
* @param object|struct $params - need to be define as struct for XMLRPC
* @return object $return
*/
public function create_users($params) {
global $USER;
if (has_capability('moodle/user:create', get_context_instance(CONTEXT_SYSTEM))) {
$userids = array();
$this->clean_function_params('create_users', $params);
foreach ($params->users as $user) {
try {
$userids[$user->username] = create_user($user);
}
catch (dml_write_exception $e) {
throw new moodle_exception('wscouldnotcreateeuserindb');
}
}
return $userids;
}
else {
throw new moodle_exception('wscouldnotcreateeusernopermission');
}
}
/**
* Delete multiple users
* @global object $DB
@ -208,9 +115,7 @@ final class user_external extends moodle_external {
}
$user->username = $paramuser->newusername;
try {
if( !update_user($user)) {
$updatesuccessfull = false;
}
$DB->update_record('user', $user);
}
catch (dml_write_exception $e) {
throw new moodle_exception('wscouldnotupdateuserindb');

145
user/externallib.php Normal file
View File

@ -0,0 +1,145 @@
<?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 user 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_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 static function create_users($params) {
global $CFG, $DB;
$context = get_context_instance(CONTEXT_SYSTEM);
requier_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
$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'])) {
$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']])) {
unset($user['lang']);
}
//TODO: add more param validations here: username, etc.
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");
}
if (isset($users[$user['username']])) {
throw new invalid_parameter_exception("multiple users with the same username requested");
}
$users[$user['username']] = $user;
}
$result = array();
foreach ($users as $user) {
$record = create_user_record($user['username'], $user['password'], $user['auth']);
unset($user['username']);
unset($user['password']);
unset($user['auth']);
// now override the default (or external) values
foreach ($user as $key=>$value) {
$record->$key = $value;
}
$DB->update_record('user', $record);
unset($record->password); // lets keep this as a secret ;-)
$result[$record->id] = $record;
}
return $result;
}
public static function delete_users($params) {
//TODO
}
public static function update_users($params) {
//TODO
}
}

View File

@ -1,171 +0,0 @@
<?php
/**
* Created on 01/12/2008
*
* user core functions
*
* @author Jerome Mouneyrac
*/
/**
* User library
*/
/**
* Returns a subset of users (DO NOT COUNT)
* @global object $DB
* @param string $sort A SQL snippet for the sorting criteria to use
* @param string $recordsperpage how many records do pages have
* @param string $page which page to return (starts from 0)
* @param string $fields A comma separated list of fields to be returned from the chosen table.
* @param object $selectioncriteria:
* ->search string A simple string to search for
* ->confirmed bool A switch to allow/disallow unconfirmed users
* ->exceptions array(int) A list of IDs to ignore, eg 2,4,5,8,9,10
* ->firstinitial string ?
* ->lastinitial string ?
* @return array|false Array of {@link $USER} objects. False is returned if an error is encountered.
*/
function get_users_2($sort='firstname ASC', $recordsperpage=999999, $page=0, $fields='*', $selectioncriteria=NULL) {
global $DB;
///WS: convert array into an object
if (!empty($selectioncriteria) && is_array($selectioncriteria)) {
$selectioncriteria = (object) $selectioncriteria;
}
$LIKE = $DB->sql_ilike();
$fullname = $DB->sql_fullname();
$select = " username <> :guest AND deleted = 0";
$params = array('guest'=>'guest');
if (!empty($selectioncriteria->search)){
$selectioncriteria->search = trim($selectioncriteria->search);
$select .= " AND ($fullname $LIKE :search1 OR email $LIKE :search2 OR username = :search3)";
$params['search1'] = "%".$selectioncriteria->search."%";
$params['search2'] = "%".$selectioncriteria->search."%";
$params['search3'] = $selectioncriteria->search;
}
if (!empty($selectioncriteria->confirmed)) {
$select .= " AND confirmed = 1";
}
if (!empty($selectioncriteria->exceptions)) {
list($selectioncriteria->exceptions, $eparams) = $DB->get_in_or_equal($selectioncriteria->exceptions, SQL_PARAMS_NAMED, 'ex0000', false);
$params = $params + $eparams;
$except = " AND id ".$selectioncriteria->exceptions;
}
if (!empty($selectioncriteria->firstinitial)) {
$select .= " AND firstname $LIKE :fni";
$params['fni'] = $selectioncriteria->firstinitial."%";
}
if (!empty($selectioncriteria->lastinitial)) {
$select .= " AND lastname $LIKE :lni";
$params['lni'] = $selectioncriteria->lastinitial."%";
}
if (!empty($selectioncriteria->extraselect)) {
$select .= " AND ".$selectioncriteria->extraselect;
if (empty($selectioncriteria->extraparams)){
$params = $params + (array)$selectioncriteria->extraparams;
}
}
return $DB->get_records_select('user', $select, $params, $sort, $fields, $page, $recordsperpage);
}
/**
* Creates an User with given information. Required fields are:
* -username
* -idnumber
* -firstname
* -lastname
* -email
*
* And there's some interesting fields:
* -password
* -auth
* -confirmed
* -timezone
* -country
* -emailstop
* -theme
* -lang
* -mailformat
*
* @param assoc array or object $user
*
* @return string or thrown exceptions
*/
function create_user($user) {
global $CFG, $DB;
/// WS: convert user array into an user object
if (is_array($user)) {
$user = (object) $user;
}
/// check auth fields
if (!isset($user->auth)) {
$user->auth = 'manual';
} else {
/// check that the auth value exists
$authplugin = get_directory_list($CFG->dirroot."/auth", '', false, true, false);
if (array_search($user->auth, $authplugin)===false) {
throw new moodle_exception('authnotexisting');
}
}
$required = array('username','firstname','lastname','email', 'password');
foreach ($required as $req) {
if (!isset($user->{$req})) {
throw new moodle_exception('missingrequiredfield');
}
}
$password = hash_internal_user_password($user->password);
$record = create_user_record($user->username, $password, $user->auth);
if ($record) {
$user->id = $record->id;
if ($DB->update_record('user',$user)) {
return $record->id;
} else {
//we could not update properly the newly created user, we need to delete it
$DB->delete_record('user',array('id' => $record->id));
throw new moodle_exception('usernotcreated');
}
}
throw new moodle_exception('usernotcreated');
}
/**
* Update a user record from its id
* Warning: no checks are done on the data!!!
* @param object $user
* @return boolean
*/
function update_user($user) {
global $DB;
//check that the user exist
$existinguser = $DB->get_record('user', array('id'=>$user->id));
if (empty($existinguser)) {
throw new moodle_exception('couldnotupdatenoexistinguser');
}
if ($DB->update_record('user', $user)) {
//TODO check the php warning that this line produce
events_trigger('user_updated', $user);
return true;
} else {
return false;
}
}
?>