From 95693c43aa7a2609750f2edc0e8e07ce9ceda00f Mon Sep 17 00:00:00 2001 From: Jerome Mouneyrac Date: Thu, 15 Mar 2012 11:06:24 +0800 Subject: [PATCH] MDL-32941 improve create_categories() web service function (wip) --- course/externallib.php | 122 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 40 deletions(-) diff --git a/course/externallib.php b/course/externallib.php index a3879425b48..1d7ea30a73f 100644 --- a/course/externallib.php +++ b/course/externallib.php @@ -419,37 +419,98 @@ class core_course_external extends external_api { } /** - * Create categories - * @param array $options - * @return array + * Returns description of method parameters + * + * @return external_function_parameters + * @since Moodle 2.3 + * TODO is PARAM_CLEANHTML for the description enough secured? + * Is it possible to still pass some script tag that pass PARAM_CLEANHTML + * and execute dangereous javascript in the browser? */ - public static function create_categories($options) { + public static function create_categories_parameters() { + return new external_function_parameters( + array( + 'categories' => new external_multiple_structure( + new external_single_structure( + array( + 'name' => new external_value(PARAM_TEXT, 'new category name'), + 'parent' => new external_value(PARAM_INT, 'the parent category id inside which the new category will be created'), + 'idnumber' => new external_value(PARAM_RAW, 'the new category idnumber', VALUE_OPTIONAL), + 'description' => new external_value(PARAM_CLEANHTML, 'the new category description', VALUE_OPTIONAL), + 'theme' => new external_value(PARAM_THEME, + 'the new category theme. This option must be enabled on moodle', VALUE_OPTIONAL), + ) + ) + ) + ) + ); + } + + /** + * Create categories + * + * @param array $categories - see create_categories_parameters() for the array structure + * @return array - see create_categories_returns() for the array structure + * @since Moodle 2.3 + * TODO: check exceptions + */ + public static function create_categories($categories) { global $CFG, $DB; require_once($CFG->dirroot . "/course/lib.php"); - $params = self::validate_parameters(self::create_categories_parameters(), - array('categories' => $options)); - + $params = self::validate_parameters(self::create_categories_parameters(), + array('categories' => $categories)); + + $transaction = $DB->start_delegated_transaction(); + $createdcategories = array(); foreach($params['categories'] as $category) { + + $newcategory = new stdClass(); + $newcategory->sortorder = 999; //same as in the course/editcategory.php + $newcategory->parent = $category['parent']; + if ($category['parent']) { - if (!$DB->record_exists('course_categories', array('id' => $category['parent']))) - throw new moodle_exception(get_string('unknowncategory'), 'webservice', null); + if (!$DB->record_exists('course_categories', array('id' => $category['parent']))) { + throw new moodle_exception('unknowncategory'); + } $context = context_coursecat::instance($category['parent']); } else { $context = context_system::instance(); } self::validate_context($context); + require_capability('moodle/category:manage', $context); + + //check id number + if (!empty($category['idnumber'])) { //same as in course/editcategory_form.php + if (strlen($category['idnumber'])>100) { + throw new moodle_exception('id number is too long'); + } - $newcategory = new stdClass(); - $newcategory->name = $category['name']; + if ($existing = $DB->get_record('course_categories', array('idnumber' => $category['idnumber']))) { + if ($existing->id) { + throw new moodle_exception('idnumbertaken'); + } + } + } $newcategory->idnumber = $category['idnumber']; - $newcategory->description = $category['description']; - $newcategory->parent = $category['parent']; - $newcategory->sortorder = 999; - //not sure if this is correct, but since text editor was not used, assume defaults - $newcategory->descriptionformat = 1; + + //check name + if (strlen($category['name'])>30) { + throw new moodle_exception('category name is too long.'); + } + $newcategory->name = $category['name']; + + //Format the description + if (!empty($newcategory->description)) { + $options = new stdClass(); + $options->para = false; + $options->newlines = false; + $options->context = $context; + $newcategory->description = format_text($category['description'], FORMAT_HTML, $options); + } + $newcategory->descriptionformat = FORMAT_HTML; if (isset($category['theme']) and !empty($CFG->allowcategorythemes)) { $newcategory->theme = $category['theme']; @@ -460,39 +521,20 @@ class core_course_external extends external_api { //populate special fields fix_course_sortorder(); - + $createdcategories[] = array('id' => $newcategory->id, 'name' => $newcategory->name); } + $transaction->allow_commit(); + return $createdcategories; } - - /** - * Returns description of method parameters - * @return external_function_parameters - */ - public static function create_categories_parameters() { - return new external_function_parameters( - array( - 'categories' => new external_multiple_structure( - new external_single_structure( - array( - 'name' => new external_value(PARAM_TEXT, 'new category name'), - 'parent' => new external_value(PARAM_INT, 'the parent category inside which the new category will be created'), - 'idnumber' => new external_value(PARAM_INT, 'the new category idnumber', VALUE_OPTIONAL), - 'description' => new external_value(PARAM_TEXT, 'the new category description', VALUE_OPTIONAL), - 'theme' => new external_value(PARAM_THEME, - 'the new category theme. This option must be enabled on moodle', VALUE_OPTIONAL), - ) - ) - ) - ) - ); - } /** * Returns description of method parameters + * * @return external_function_parameters + * @since Moodle 2.3 */ public static function create_categories_returns() { return new external_multiple_structure( -- 2.11.4.GIT