global $CFG;
require_once("$CFG->dirroot/group/lib.php");
- $params = self::validate_prameters(self::create_groups_parameters(), array('groups'=>$groups));
+ $params = self::validate_parameters(self::create_groups_parameters(), array('groups'=>$groups));
$groups = array();
public static function get_groups_parameters() {
return new external_function_parameters(
array(
- 'groups' => new external_multiple_structure(
- new external_single_structure(
- array(
- 'groupid' => new external_param(PARAM_INT, 'Group ID')
- )
- )
- )
+ 'groups' => new external_multiple_structure(new external_param(PARAM_INT, 'Group ID'))
)
);
}
public static function get_groups($groupids) {
$groups = array();
- $params = self::validate_prameters(self::get_groups_parameters(), array('groupids'=>$groupids));
+ $params = self::validate_parameters(self::get_groups_parameters(), array('groupids'=>$groupids));
//TODO: we do need to search for groups in courses too,
// fetching by id is not enough!
global $CFG;
require_once("$CFG->dirroot/group/lib.php");
- $params = self::validate_prameters(self::delete_groups_parameters(), array('groupids'=>$groupids));
+ $params = self::validate_parameters(self::delete_groups_parameters(), array('groupids'=>$groupids));
$groups = array();
public static function get_groupmembers($groupids) {
$groups = array();
- $params = self::validate_prameters(self::get_groupmembers_parameters(), array('groupids'=>$groupids));
+ $params = self::validate_parameters(self::get_groupmembers_parameters(), array('groupids'=>$groupids));
foreach ($params['groupids'] as $groupid) {
// validate params
global $CFG;
require_once("$CFG->dirroot/group/lib.php");
- $params = self::validate_prameters(self::add_groupmembers_parameters(), array('members'=>$members));
+ $params = self::validate_parameters(self::add_groupmembers_parameters(), array('members'=>$members));
foreach ($params['members'] as $member) {
// validate params
global $CFG;
require_once("$CFG->dirroot/group/lib.php");
- $params = self::validate_prameters(self::delete_groupmembers_parameters(), array($members=>'members'));
+ $params = self::validate_parameters(self::delete_groupmembers_parameters(), array($members=>'members'));
foreach ($params['members'] as $member) {
// validate params
}
/**
- * Validates submitted function barameters, if anything is incorrect
+ * Validates submitted function parameters, if anything is incorrect
* invalid_parameter_exception is thrown.
- * @param ? $description description of parameters
- * @param ? $params the actual parameters
- * @return ? params with added defaults for optional items, invalid_parameters_exception thrown if any problem found
+ * @param external_description $description description of parameters
+ * @param mixed $params the actual parameters
+ * @return mixed params with added defaults for optional items, invalid_parameters_exception thrown if any problem found
*/
- public static function validate_prameters($description, $params) {
- //TODO: we need to define the structure of param descriptions
+ public static function validate_parameters(external_description $description, $params) {
+ if ($description instanceof external_param) {
+ if (is_array($params) or is_object($params)) {
+ throw new invalid_parameter_exception('Scalar type expected, array or object received.');
+ }
+ return validate_param($params, $description->type, $description->allownull, 'Invalid external api parameter');
+
+ } else if ($description instanceof external_single_structure) {
+ if (!is_array($params)) {
+ throw new invalid_parameter_exception('Only arrays accepted.');
+ }
+ $result = array();
+ foreach ($description->keys as $key=>$subdesc) {
+ if (!array_key_exists($key, $params)) {
+ if ($subdesc->required) {
+ throw new invalid_parameter_exception('Missing required key in single structure.');
+ }
+ if ($subdesc instanceof external_param) {
+ $result[$key] = self::validate_parameters($subdesc, $subdesc->default);
+ }
+ } else {
+ $result[$key] = self::validate_parameters($subdesc, $params[$key]);
+ }
+ unset($params[$key]);
+ }
+ if (!empty($params)) {
+ throw new invalid_parameter_exception('Unexpected keys detected in parameter array.');
+ }
+ return $result;
- return $params;
+ } else if ($description instanceof external_multiple_structure) {
+ if (!is_array($params)) {
+ throw new invalid_parameter_exception('Only arrays accepted.');
+ }
+ $result = array();
+ foreach ($params as $param) {
+ $result[] = self::validate_parameters($description->content, $param);
+ }
+ return $result;
+
+ } else {
+ throw new invalid_parameter_exception('Invalid external api description.');
+ }
}
/**
// 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
+ // oh - did I say we need to rewrite enrolments in 2.0
// to solve this bloody mess?
//
// missing: hidden courses and categories, groupmembersonly,
* @param string $desc
* @param bool $required
*/
- public function __contruct($desc, $required) {
+ public function __construct($desc, $required) {
$this->desc = $desc;
$this->required = $required;
}
* @param mixed $default
* @param bool $allownull
*/
- public function __contruct($type, $desc='', $required=true, $default=null, $allownull=true) {
- parent::_construct($desc, $required);
+ public function __construct($type, $desc='', $required=true, $default=null, $allownull=true) {
+ parent::__construct($desc, $required);
$this->type = $type;
$this->default = $default;
$this->allownull = $allownull;
* @param bool $required
*/
public function __construct(array $keys, $desc='', $required=true) {
- parent::_construct($desc, $required);
+ parent::__construct($desc, $required);
$this->keys = $keys;
}
}
* @param bool $required
*/
public function __construct(external_description $content, $desc='', $required=true) {
- parent::_construct($desc, $required);
+ parent::__construct($desc, $required);
$this->content = $content;
}
}
--- /dev/null
+<?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/>.
+
+
+/**
+ * Unit tests for /lib/externallib.php.
+ *
+ * @package webservices
+ * @copyright 2009 Pwetr Skoda
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+if (!defined('MOODLE_INTERNAL')) {
+ die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
+}
+require_once($CFG->libdir . '/externallib.php');
+
+class externallib_test extends UnitTestCase {
+ public function test_validate_params1() {
+ $params = array('text'=>'aaa', 'someid'=>'6',);
+ $description = new external_function_parameters(array('someid' => new external_param(PARAM_INT, 'Some int value'),
+ 'text' => new external_param(PARAM_ALPHA, 'Some text value')));
+ $result = external_api::validate_parameters($description, $params);
+ $this->assertEqual(count($result), 2);
+ reset($result);
+ $this->assertTrue(key($result) === 'someid');
+ $this->assertTrue($result['someid'] === 6);
+ $this->assertTrue($result['text'] === 'aaa');
+
+
+ $params = array('someids'=>array('1', 2, 'a'=>'3'), 'scalar'=>666);
+ $description = new external_function_parameters(array('someids' => new external_multiple_structure(new external_param(PARAM_INT, 'Some ID')),
+ 'scalar' => new external_param(PARAM_ALPHANUM, 'Some text value')));
+ $result = external_api::validate_parameters($description, $params);
+ $this->assertEqual(count($result), 2);
+ reset($result);
+ $this->assertTrue(key($result) === 'someids');
+ $this->assertTrue($result['someids'] == array(0=>1, 1=>2, 2=>3));
+ $this->assertTrue($result['scalar'] === '666');
+ }
+
+ //TODO: add unittests for all description options and validation failures
+}
// 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
- $params = self::validate_prameters(self::create_users_parameters(), $params);
+ $params = self::validate_parameters(self::create_users_parameters(), $params);
// Perform further checks and build up a clean array of user data
require_capability('moodle/user:viewdetails', $context);
self::validate_context($context);
- $params = self::validate_prameters(self::get_users_parameters(), $params);
+ $params = self::validate_parameters(self::get_users_parameters(), $params);
//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