diff --git a/course/externallib.php b/course/externallib.php index d02506f251155..1dfc4c651903e 100644 --- a/course/externallib.php +++ b/course/externallib.php @@ -119,9 +119,10 @@ public static function get_course_contents($courseid, $options) { $sectionvalues = array(); $sectionvalues['id'] = $section->id; $sectionvalues['name'] = get_section_name($course, $section); - $summary = file_rewrite_pluginfile_urls($section->summary, 'webservice/pluginfile.php', $context->id, 'course', 'section', $section->id); $sectionvalues['visible'] = $section->visible; - $sectionvalues['summary'] = format_text($summary, $section->summaryformat); + list($sectionvalues['summary'], $sectionvalues['summaryformat']) = + external_format_text($section->summary, $section->summaryformat, + $context->id, 'course', 'section', $section->id); $sectioncontents = array(); //for each module of the section @@ -205,6 +206,7 @@ public static function get_course_contents_returns() { 'name' => new external_value(PARAM_TEXT, 'Section name'), 'visible' => new external_value(PARAM_INT, 'is the section visible', VALUE_OPTIONAL), 'summary' => new external_value(PARAM_RAW, 'Section description'), + 'summaryformat' => new external_format_value('summary'), 'modules' => new external_multiple_structure( new external_single_structure( array( @@ -311,8 +313,8 @@ public static function get_courses($options) { $courseinfo['fullname'] = $course->fullname; $courseinfo['shortname'] = $course->shortname; $courseinfo['categoryid'] = $course->category; - $courseinfo['summary'] = $course->summary; - $courseinfo['summaryformat'] = $course->summaryformat; + list($courseinfo['summary'], $courseinfo['summaryformat']) = + external_format_text($course->summary, $course->summaryformat, $context->id, 'course', 'summary', 0); $courseinfo['format'] = $course->format; $courseinfo['startdate'] = $course->startdate; $courseinfo['numsections'] = $course->numsections; @@ -367,8 +369,7 @@ public static function get_courses_returns() { 'fullname' => new external_value(PARAM_TEXT, 'full name'), 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL), 'summary' => new external_value(PARAM_RAW, 'summary'), - 'summaryformat' => new external_value(PARAM_INT, - 'the summary text Moodle format'), + 'summaryformat' => new external_format_value('summary'), 'format' => new external_value(PARAM_PLUGIN, 'course format: weeks, topics, social, site,..'), 'showgrades' => new external_value(PARAM_INT, @@ -435,8 +436,7 @@ public static function create_courses_parameters() { 'categoryid' => new external_value(PARAM_INT, 'category id'), 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL), 'summary' => new external_value(PARAM_RAW, 'summary', VALUE_OPTIONAL), - 'summaryformat' => new external_value(PARAM_INT, - 'the summary text Moodle format', VALUE_DEFAULT, FORMAT_MOODLE), + 'summaryformat' => new external_format_value('summary', VALUE_DEFAULT), 'format' => new external_value(PARAM_PLUGIN, 'course format: weeks, topics, social, site,..', VALUE_DEFAULT, $courseconfig->format), @@ -560,6 +560,9 @@ public static function create_courses($courses) { $course['category'] = $course['categoryid']; + // Summary format. + $course['summaryformat'] = external_validate_format($course['summaryformat']); + //Note: create_course() core function check shortname, idnumber, category $course['id'] = create_course((object) $course)->id; @@ -1085,13 +1088,9 @@ public static function get_categories($criteria = array(), $addsubcategories = t $categoryinfo = array(); $categoryinfo['id'] = $category->id; $categoryinfo['name'] = $category->name; - $categoryinfo['description'] = file_rewrite_pluginfile_urls($category->description, - 'webservice/pluginfile.php', $context->id, 'coursecat', 'description', null); - $options = new stdClass; - $options->noclean = true; - $options->para = false; - $categoryinfo['description'] = format_text($categoryinfo['description'], - $category->descriptionformat, $options); + list($categoryinfo['description'], $categoryinfo['descriptionformat']) = + external_format_text($category->description, $category->descriptionformat, + $context->id, 'coursecat', 'description', null); $categoryinfo['parent'] = $category->parent; $categoryinfo['sortorder'] = $category->sortorder; $categoryinfo['coursecount'] = $category->coursecount; @@ -1160,6 +1159,7 @@ public static function get_categories_returns() { 'name' => new external_value(PARAM_TEXT, 'category name'), 'idnumber' => new external_value(PARAM_RAW, 'category id number', VALUE_OPTIONAL), 'description' => new external_value(PARAM_RAW, 'category description'), + 'descriptionformat' => new external_format_value('description'), 'parent' => new external_value(PARAM_INT, 'parent category id'), 'sortorder' => new external_value(PARAM_INT, 'category sorting order'), 'coursecount' => new external_value(PARAM_INT, 'number of courses in this category'), @@ -1193,6 +1193,7 @@ public static function create_categories_parameters() { 'the new category idnumber', VALUE_OPTIONAL), 'description' => new external_value(PARAM_RAW, 'the new category description', VALUE_OPTIONAL), + 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT), 'theme' => new external_value(PARAM_THEME, 'the new category theme. This option must be enabled on moodle', VALUE_OPTIONAL), @@ -1257,7 +1258,7 @@ public static function create_categories($categories) { if (!empty($category['description'])) { $newcategory->description = $category['description']; } - $newcategory->descriptionformat = FORMAT_HTML; + $newcategory->descriptionformat = external_validate_format($category['descriptionformat']); if (isset($category['theme']) and !empty($CFG->allowcategorythemes)) { $newcategory->theme = $category['theme']; } @@ -1308,6 +1309,7 @@ public static function update_categories_parameters() { 'idnumber' => new external_value(PARAM_RAW, 'category id number', VALUE_OPTIONAL), 'parent' => new external_value(PARAM_INT, 'parent category id', VALUE_OPTIONAL), 'description' => new external_value(PARAM_RAW, 'category description', VALUE_OPTIONAL), + 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT), 'theme' => new external_value(PARAM_THEME, 'the category theme. This option must be enabled on moodle', VALUE_OPTIONAL), ) @@ -1356,7 +1358,7 @@ public static function update_categories($categories) { } if (!empty($cat['description'])) { $category->description = $cat['description']; - $category->descriptionformat = FORMAT_HTML; + $category->descriptionformat = external_validate_format($cat['descriptionformat']); } if (!empty($cat['theme'])) { $category->theme = $cat['theme']; diff --git a/enrol/externallib.php b/enrol/externallib.php index 08438e18b770c..0b1003142987f 100644 --- a/enrol/externallib.php +++ b/enrol/externallib.php @@ -277,7 +277,7 @@ public static function get_enrolled_users_returns() { 'firstaccess' => new external_value(PARAM_INT, 'first access to the site (0 if never)', VALUE_OPTIONAL), 'lastaccess' => new external_value(PARAM_INT, 'last access to the site (0 if never)', VALUE_OPTIONAL), 'description' => new external_value(PARAM_RAW, 'User profile description', VALUE_OPTIONAL), - 'descriptionformat' => new external_value(PARAM_INT, 'User profile description format', VALUE_OPTIONAL), + 'descriptionformat' => new external_format_value('description', VALUE_OPTIONAL), 'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL), 'url' => new external_value(PARAM_URL, 'URL of the user', VALUE_OPTIONAL), 'country' => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL), @@ -298,6 +298,7 @@ public static function get_enrolled_users_returns() { 'id' => new external_value(PARAM_INT, 'group id'), 'name' => new external_value(PARAM_RAW, 'group name'), 'description' => new external_value(PARAM_RAW, 'group description'), + 'descriptionformat' => new external_format_value('description'), ) ), 'user groups', VALUE_OPTIONAL), 'roles' => new external_multiple_structure( diff --git a/group/externallib.php b/group/externallib.php index 9045afd702f6c..080f406e9d302 100644 --- a/group/externallib.php +++ b/group/externallib.php @@ -52,6 +52,7 @@ public static function create_groups_parameters() { 'courseid' => new external_value(PARAM_INT, 'id of course'), 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 'description' => new external_value(PARAM_RAW, 'group description text'), + 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT), 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'), ) ), 'List of group object. A group has a courseid, a name, a description and an enrolment key.' @@ -99,6 +100,9 @@ public static function create_groups($groups) { } require_capability('moodle/course:managegroups', $context); + // Validate format. + $group->descriptionformat = external_validate_format($group->descriptionformat); + // finally create the group $group->id = groups_create_group($group, false); $groups[] = (array)$group; @@ -123,6 +127,7 @@ public static function create_groups_returns() { 'courseid' => new external_value(PARAM_INT, 'id of course'), 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 'description' => new external_value(PARAM_RAW, 'group description text'), + 'descriptionformat' => new external_format_value('description'), 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'), ) ), 'List of group object. A group has an id, a courseid, a name, a description and an enrolment key.' @@ -157,7 +162,7 @@ public static function get_groups($groupids) { $groups = array(); foreach ($params['groupids'] as $groupid) { // validate params - $group = groups_get_group($groupid, 'id, courseid, name, description, enrolmentkey', MUST_EXIST); + $group = groups_get_group($groupid, 'id, courseid, name, description, descriptionformat, enrolmentkey', MUST_EXIST); // now security checks $context = get_context_instance(CONTEXT_COURSE, $group->courseid); @@ -171,6 +176,10 @@ public static function get_groups($groupids) { } require_capability('moodle/course:managegroups', $context); + list($group->description, $group->descriptionformat) = + external_format_text($group->description, $group->descriptionformat, + $context->id, 'group', 'description', $group->id); + $groups[] = (array)$group; } @@ -191,6 +200,7 @@ public static function get_groups_returns() { 'courseid' => new external_value(PARAM_INT, 'id of course'), 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 'description' => new external_value(PARAM_RAW, 'group description text'), + 'descriptionformat' => new external_format_value('description'), 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'), ) ) @@ -233,10 +243,14 @@ public static function get_course_groups($courseid) { } require_capability('moodle/course:managegroups', $context); - $gs = groups_get_all_groups($params['courseid'], 0, 0, 'g.id, g.courseid, g.name, g.description, g.enrolmentkey'); + $gs = groups_get_all_groups($params['courseid'], 0, 0, + 'g.id, g.courseid, g.name, g.description, g.descriptionformat, g.enrolmentkey'); $groups = array(); foreach ($gs as $group) { + list($group->description, $group->descriptionformat) = + external_format_text($group->description, $group->descriptionformat, + $context->id, 'group', 'description', $group->id); $groups[] = (array)$group; } @@ -257,6 +271,7 @@ public static function get_course_groups_returns() { 'courseid' => new external_value(PARAM_INT, 'id of course'), 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), 'description' => new external_value(PARAM_RAW, 'group description text'), + 'descriptionformat' => new external_format_value('description'), 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'), ) ) @@ -557,7 +572,8 @@ public static function create_groupings_parameters() { array( 'courseid' => new external_value(PARAM_INT, 'id of course'), 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), - 'description' => new external_value(PARAM_RAW, 'grouping description text') + 'description' => new external_value(PARAM_RAW, 'grouping description text'), + 'descriptionformat' => new external_format_value('descripiton', VALUE_DEFAULT) ) ), 'List of grouping object. A grouping has a courseid, a name and a description.' ) @@ -604,8 +620,7 @@ public static function create_groupings($groupings) { } require_capability('moodle/course:managegroups', $context); - // We must force allways FORMAT_HTML. - $grouping->descriptionformat = FORMAT_HTML; + $grouping->descriptionformat = external_validate_format($grouping->descriptionformat); // Finally create the grouping. $grouping->id = groups_create_grouping($grouping); @@ -630,7 +645,8 @@ public static function create_groupings_returns() { 'id' => new external_value(PARAM_INT, 'grouping record id'), 'courseid' => new external_value(PARAM_INT, 'id of course'), 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), - 'description' => new external_value(PARAM_CLEANHTML, 'grouping description text') + 'description' => new external_value(PARAM_RAW, 'grouping description text'), + 'descriptionformat' => new external_format_value('description') ) ), 'List of grouping object. A grouping has an id, a courseid, a name and a description.' ); @@ -650,7 +666,8 @@ public static function update_groupings_parameters() { array( 'id' => new external_value(PARAM_INT, 'id of grouping'), 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), - 'description' => new external_value(PARAM_RAW, 'grouping description text') + 'description' => new external_value(PARAM_RAW, 'grouping description text'), + 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT) ) ), 'List of grouping object. A grouping has a courseid, a name and a description.' ) @@ -705,7 +722,7 @@ public static function update_groupings($groupings) { require_capability('moodle/course:managegroups', $context); // We must force allways FORMAT_HTML. - $grouping->descriptionformat = FORMAT_HTML; + $grouping->descriptionformat = external_validate_format($grouping->descriptionformat); // Finally update the grouping. groups_update_grouping($grouping); @@ -772,12 +789,9 @@ public static function get_groupings($groupingids) { } require_capability('moodle/course:managegroups', $context); - $grouping->description = file_rewrite_pluginfile_urls($grouping->description, 'webservice/pluginfile.php', $context->id, 'grouping', 'description', $grouping->id); - - $options = new stdClass; - $options->noclean = true; - $options->para = false; - $grouping->description = format_text($grouping->description, FORMAT_HTML, $options); + list($grouping->description, $grouping->descriptionformat) = + external_format_text($grouping->description, $grouping->descriptionformat, + $context->id, 'grouping', 'description', $grouping->id); $groupings[] = (array)$grouping; } @@ -798,7 +812,8 @@ public static function get_groupings_returns() { 'id' => new external_value(PARAM_INT, 'grouping record id'), 'courseid' => new external_value(PARAM_INT, 'id of course'), 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), - 'description' => new external_value(PARAM_CLEANHTML, 'grouping description text') + 'description' => new external_value(PARAM_RAW, 'grouping description text'), + 'descriptionformat' => new external_format_value('description') ) ) ); @@ -849,13 +864,9 @@ public static function get_course_groupings($courseid) { $groupings = array(); foreach ($gs as $grouping) { - $grouping->description = file_rewrite_pluginfile_urls($grouping->description, 'webservice/pluginfile.php', $context->id, 'grouping', 'description', $grouping->id); - - $options = new stdClass; - $options->noclean = true; - $options->para = false; - $grouping->description = format_text($grouping->description, FORMAT_HTML, $options); - + list($grouping->description, $grouping->descriptionformat) = + external_format_text($grouping->description, $grouping->descriptionformat, + $context->id, 'grouping', 'description', $grouping->id); $groupings[] = (array)$grouping; } @@ -875,7 +886,8 @@ public static function get_course_groupings_returns() { 'id' => new external_value(PARAM_INT, 'grouping record id'), 'courseid' => new external_value(PARAM_INT, 'id of course'), 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), - 'description' => new external_value(PARAM_CLEANHTML, 'grouping description text') + 'description' => new external_value(PARAM_RAW, 'grouping description text'), + 'descriptionformat' => new external_format_value('description') ) ) ); diff --git a/lib/externallib.php b/lib/externallib.php index 9ef3b12a9ac8f..1913f4546ea9e 100644 --- a/lib/externallib.php +++ b/lib/externallib.php @@ -584,19 +584,242 @@ function external_delete_descriptions($component) { } /** - * Creates a warnings external_multiple_structure + * Standard Moodle web service warnings * - * @return external_multiple_structure - * @since Moodle 2.3 + * @package core_webservice + * @copyright 2012 Jerome Mouneyrac + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.3 + */ +class external_warnings extends external_multiple_structure { + + /** + * Constructor + * + * @since Moodle 2.3 + */ + public function __construct() { + + parent::__construct( + new external_single_structure( + array( + 'item' => new external_value(PARAM_TEXT, 'item', VALUE_OPTIONAL), + 'itemid' => new external_value(PARAM_INT, 'item id', VALUE_OPTIONAL), + 'warningcode' => new external_value(PARAM_ALPHANUM, + 'the warning code can be used by the client app to implement specific behaviour'), + 'message' => new external_value(PARAM_TEXT, + 'untranslated english message to explain the warning') + ), 'warning'), + 'list of warnings', VALUE_OPTIONAL); + } +} + +/** + * A pre-filled external_value class for text format. + * + * Default is FORMAT_HTML + * This should be used all the time in external xxx_params()/xxx_returns functions + * as it is the standard way to implement text format param/return values. + * + * @package core_webservice + * @copyright 2012 Jerome Mouneyrac + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.3 */ -function external_warnings() { - return new external_multiple_structure( - new external_single_structure(array( - 'item' => new external_value(PARAM_TEXT, 'item', VALUE_OPTIONAL), - 'itemid' => new external_value(PARAM_INT, 'item id', VALUE_OPTIONAL), - 'warningcode' => new external_value(PARAM_ALPHANUM, 'the warning code can be used by - the client app to implement specific behaviour'), - 'message' => new external_value(PARAM_TEXT, 'untranslated english message to explain the warning') - ), 'warning'), 'list of warnings', VALUE_OPTIONAL - ); +class external_format_value extends external_value { + + /** + * Constructor + * + * @param string $textfieldname Name of the text field + * @param int $required if VALUE_REQUIRED then set standard default FORMAT_HTML + * @since Moodle 2.3 + */ + public function __construct($textfieldname, $required = VALUE_REQUIRED) { + + $default = ($required == VALUE_DEFAULT) ? FORMAT_HTML : null; + + $desc = $textfieldname . ' format (' . FORMAT_HTML . ' = HTML, ' + . FORMAT_MOODLE . ' = MOODLE, ' + . FORMAT_PLAIN . ' = PLAIN or ' + . FORMAT_MARKDOWN . ' = MARKDOWN)'; + + parent::__construct($type, $desc='', $required, $default); + } +} + +/** + * Validate text field format against known FORMAT_XXX + * + * @param array $format the format to validate + * @return the validated format + * @throws coding_exception + * @since 2.3 + */ +function external_validate_format($format) { + $allowedformats = array(FORMAT_HTML, FORMAT_MOODLE, FORMAT_PLAIN, FORMAT_MARKDOWN); + if (!in_array($format, $allowedformats)) { + throw new moodle_exception('formatnotsupported', 'webservice', '' , null, + 'The format with value=' . $format . ' is not supported by this Moodle site'); + } + return $format; +} + +/** + * Format the text to be returned properly as requested by the either the web service server, + * either by an internally call. + * The caller can change the format (raw, filter, file, fileurl) with the external_settings singleton + * All web service servers must set this singleton when parsing the $_GET and $_POST. + * + * @param string $text The content that may contain ULRs in need of rewriting. + * @param int $textformat The text format, by default FORMAT_HTML. + * @param int $contextid This parameter and the next two identify the file area to use. + * @param string $component + * @param string $filearea helps identify the file area. + * @param int $itemid helps identify the file area. + * @return array text + textformat + * @since Moodle 2.3 + */ +function external_format_text($text, $textformat, $contextid, $component, $filearea, $itemid) { + global $CFG; + + // Get settings (singleton). + $settings = external_settings::get_instance(); + + if ($settings->get_fileurl()) { + $text = file_rewrite_pluginfile_urls($text, $settings->get_file(), $contextid, $component, $filearea, $itemid); + } + + if (!$settings->get_raw()) { + $textformat = FORMAT_HTML; // Force format to HTML when not raw. + $text = format_text($text, $textformat, + array('noclean' => true, 'para' => false, 'filter' => $settings->get_filter())); + } + + return array($text, $textformat); +} + +/** + * Singleton to handle the external settings. + * + * We use singleton to encapsulate the "logic" + * + * @package core_webservice + * @copyright 2012 Jerome Mouneyrac + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.3 + */ +class external_settings { + + /** @var object the singleton instance */ + public static $instance = null; + + /** @var boolean Should the external function return raw text or formatted */ + private $raw = false; + + /** @var boolean Should the external function filter the text */ + private $filter = false; + + /** @var boolean Should the external function rewrite plugin file url */ + private $fileurl = true; + + /** @var string In which file should the urls be rewritten */ + private $file = 'webservice/pluginfile.php'; + + /** + * Constructor - protected - can not be instanciated + */ + protected function __construct() { + } + + /** + * Clone - private - can not be cloned + */ + private final function __clone() { + } + + /** + * Return only one instance + * + * @return object + */ + public static function get_instance() { + if (self::$instance === null) { + self::$instance = new external_settings; + } + + return self::$instance; + } + + /** + * Set raw + * + * @param boolean $raw + */ + public function set_raw($raw) { + $this->raw = $raw; + } + + /** + * Get raw + * + * @return boolean + */ + public function get_raw() { + return $this->raw; + } + + /** + * Set filter + * + * @param boolean $filter + */ + public function set_filter($filter) { + $this->filter = $filter; + } + + /** + * Get filter + * + * @return boolean + */ + public function get_filter() { + return $this->filter; + } + + /** + * Set fileurl + * + * @param boolean $fileurl + */ + public function set_fileurl($fileurl) { + $this->fileurl = $fileurl; + } + + /** + * Get fileurl + * + * @return boolean + */ + public function get_fileurl() { + return $this->fileurl; + } + + /** + * Set file + * + * @param string $file + */ + public function set_file($file) { + $this->file = $file; + } + + /** + * Get file + * + * @return string + */ + public function get_file() { + return $this->file; + } } diff --git a/message/externallib.php b/message/externallib.php index f39d51798216b..ca28d2db37624 100644 --- a/message/externallib.php +++ b/message/externallib.php @@ -50,7 +50,8 @@ public static function send_instant_messages_parameters() { new external_single_structure( array( 'touserid' => new external_value(PARAM_INT, 'id of the user to send the private message'), - 'text' => new external_value(PARAM_RAW, 'the text of the message - not that you can send anything it will be automatically cleaned to PARAM_TEXT and used againt MOODLE_FORMAT'), + 'text' => new external_value(PARAM_RAW, 'the text of the message'), + 'textformat' => new external_format_value('text', VALUE_DEFAULT), 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own client id for the message. If this id is provided, the fail message id will be returned to you', VALUE_OPTIONAL), ) ) @@ -111,7 +112,6 @@ public static function send_instant_messages($messages = array()) { $resultmessages = array(); foreach ($params['messages'] as $message) { - $text = clean_param($message['text'], PARAM_TEXT); $resultmsg = array(); //the infos about the success of the operation //we are going to do some checking @@ -143,7 +143,8 @@ public static function send_instant_messages($messages = array()) { //now we can send the message (at least try) if ($success) { //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object - $success = message_post_message($USER, $tousers[$message['touserid']], $text, FORMAT_MOODLE); + $success = message_post_message($USER, $tousers[$message['touserid']], + $message['text'], external_validate_format($message['textformat'])); } //build the resultmsg @@ -153,6 +154,9 @@ public static function send_instant_messages($messages = array()) { if ($success) { $resultmsg['msgid'] = $success; } else { + // WARNINGS: for backward compatibility we return this errormessage. + // We should have thrown exceptions as these errors prevent results to be returned. + // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side . $resultmsg['msgid'] = -1; $resultmsg['errormessage'] = $errormessage; } diff --git a/notes/externallib.php b/notes/externallib.php index f9a1bf912d6aa..fc31e9bb8fbf1 100644 --- a/notes/externallib.php +++ b/notes/externallib.php @@ -53,7 +53,11 @@ public static function create_notes_parameters() { 'publishstate' => new external_value(PARAM_ALPHA, '\'personal\', \'course\' or \'site\''), 'courseid' => new external_value(PARAM_INT, 'course id of the note (in Moodle a note can only be created into a course, even for site and personal notes)'), 'text' => new external_value(PARAM_RAW, 'the text of the message - text or HTML'), - 'format' => new external_value(PARAM_ALPHA, '\'text\' or \'html\'', VALUE_DEFAULT, 'text'), + 'format' => new external_value(PARAM_ALPHANUMEXT, // For backward compatibility it can not be PARAM_INT, so we don't use external_format_value. + 'text format (' . FORMAT_HTML . ' = HTML, ' + . FORMAT_MOODLE . ' = MOODLE, ' + . FORMAT_PLAIN . ' = PLAIN or ' + . FORMAT_MARKDOWN . ' = MARKDOWN)', VALUE_DEFAULT, FORMAT_HTML), 'clientnoteid' => new external_value(PARAM_ALPHANUMEXT, 'your own client id for the note. If this id is provided, the fail message id will be returned to you', VALUE_OPTIONAL), ) ) @@ -130,18 +134,19 @@ public static function create_notes($notes = array()) { $dbnote = new stdClass; $dbnote->courseid = $note['courseid']; $dbnote->userid = $note['userid']; - //clean param text and set format accordingly + // Need to support 'html' and 'text' format values for backward compatibility. switch (strtolower($note['format'])) { case 'html': - $dbnote->content = clean_param($note['text'], PARAM_CLEANHTML); - $dbnote->format = FORMAT_HTML; + $textformat = FORMAT_HTML; break; case 'text': + $textformat = FORMAT_PLAIN; default: - $dbnote->content = clean_param($note['text'], PARAM_TEXT); - $dbnote->format = FORMAT_PLAIN; + $textformat = external_validate_format($note['format']); break; } + $dbnote->content = $note['text']; + $dbnote->format = $textformat; //get the state ('personal', 'course', 'site') switch ($note['publishstate']) { @@ -169,6 +174,9 @@ public static function create_notes($notes = array()) { $resultnote['noteid'] = $success; } else { + // WARNINGS: for backward compatibility we return this errormessage. + // We should have thrown exceptions as these errors prevent results to be returned. + // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side . $resultnote['noteid'] = -1; $resultnote['errormessage'] = $errormessage; } diff --git a/user/externallib.php b/user/externallib.php index 8916ad02da438..c1d57bc07e717 100644 --- a/user/externallib.php +++ b/user/externallib.php @@ -473,7 +473,7 @@ public static function get_users_by_id_returns() { 'timezone' => new external_value(PARAM_TIMEZONE, 'Timezone code such as Australia/Perth, or 99 for default', VALUE_OPTIONAL), 'mailformat' => new external_value(PARAM_INTEGER, 'Mail format code is 0 for plain text, 1 for HTML etc', VALUE_OPTIONAL), 'description' => new external_value(PARAM_RAW, 'User profile description', VALUE_OPTIONAL), - 'descriptionformat' => new external_value(PARAM_INT, 'User profile description format', VALUE_OPTIONAL), + 'descriptionformat' => new external_format_value('description', VALUE_OPTIONAL), 'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL), 'url' => new external_value(PARAM_URL, 'URL of the user', VALUE_OPTIONAL), 'country' => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL), @@ -618,7 +618,7 @@ public static function get_course_user_profiles_returns() { 'firstaccess' => new external_value(PARAM_INT, 'first access to the site (0 if never)', VALUE_OPTIONAL), 'lastaccess' => new external_value(PARAM_INT, 'last access to the site (0 if never)', VALUE_OPTIONAL), 'description' => new external_value(PARAM_RAW, 'User profile description', VALUE_OPTIONAL), - 'descriptionformat' => new external_value(PARAM_INT, 'User profile description format', VALUE_OPTIONAL), + 'descriptionformat' => new external_format_value('description', VALUE_OPTIONAL), 'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL), 'url' => new external_value(PARAM_URL, 'URL of the user', VALUE_OPTIONAL), 'country' => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL), @@ -639,6 +639,7 @@ public static function get_course_user_profiles_returns() { 'id' => new external_value(PARAM_INT, 'group id'), 'name' => new external_value(PARAM_RAW, 'group name'), 'description' => new external_value(PARAM_RAW, 'group description'), + 'descriptionformat' => new external_format_value('description'), ) ), 'user groups', VALUE_OPTIONAL), 'roles' => new external_multiple_structure( diff --git a/user/lib.php b/user/lib.php index 040a095fec0d8..c4f433efac2cf 100644 --- a/user/lib.php +++ b/user/lib.php @@ -171,6 +171,10 @@ function user_get_users_by_id($userids) { * * Give user record from mdl_user, build an array conntains * all user details + * + * Warning: description file urls are 'webservice/pluginfile.php' is use. + * it can be changed with $CFG->moodlewstextformatlinkstoimagesfile + * * @param stdClass $user user record from mdl_user * @param stdClass $context context object * @param stdClass $course moodle course @@ -319,11 +323,10 @@ function user_get_user_details($user, $course = null, array $userfields = array( if (!$cannotviewdescription) { if (in_array('description', $userfields)) { - $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $usercontext->id, 'user', 'profile', null); - $userdetails['description'] = $user->description; - } - if (in_array('descriptionformat', $userfields)) { - $userdetails['descriptionformat'] = $user->descriptionformat; + // Always return the descriptionformat if description is requested. + list($userdetails['description'], $userdetails['descriptionformat']) = + external_format_text($user->description, $user->descriptionformat, + $usercontext->id, 'user', 'profile', null); } } } @@ -417,11 +420,15 @@ function user_get_user_details($user, $course = null, array $userfields = array( // If groups are in use and enforced throughout the course, then make sure we can meet in at least one course level group if (in_array('groups', $userfields) && !empty($course) && $canaccessallgroups) { - $usergroups = groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid, 'g.id, g.name,g.description'); + $usergroups = groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid, + 'g.id, g.name,g.description,g.descriptionformat'); $userdetails['groups'] = array(); foreach ($usergroups as $group) { - $group->description = file_rewrite_pluginfile_urls($group->description, 'pluginfile.php', $context->id, 'group', 'description', $group->id); - $userdetails['groups'][] = array('id'=>$group->id, 'name'=>$group->name, 'description'=>$group->description); + list($group->description, $group->descriptionformat) = + external_format_text($group->description, $group->descriptionformat, + $context->id, 'group', 'description', $group->id); + $userdetails['groups'][] = array('id'=>$group->id, 'name'=>$group->name, + 'description'=>$group->description, 'descriptionformat'=>$group->descriptionformat); } } //list of courses where the user is enrolled diff --git a/webservice/lib.php b/webservice/lib.php index 7946bd88a9750..4fac2e9722a36 100644 --- a/webservice/lib.php +++ b/webservice/lib.php @@ -960,6 +960,38 @@ protected function authenticate_by_token($tokentype){ return $user; } + + /** + * Intercept some moodlewssettingXXX $_GET and $_POST parameter + * that are related to the web service call and are not the function parameters + */ + protected function set_web_service_call_settings() { + global $CFG; + + // Default web service settings. + // Must be the same XXX key name as the external_settings::set_XXX function. + // Must be the same XXX ws parameter name as 'moodlewssettingXXX'. + $externalsettings = array( + 'raw' => false, + 'fileurl' => true, + 'filter' => false); + + // Load the external settings with the web service settings. + $settings = external_settings::get_instance(); + foreach ($externalsettings as $name => $default) { + + $wsparamname = 'moodlewssetting' . $name; + + // Retrieve and remove the setting parameter from the request. + $value = optional_param($wsparamname, $default, PARAM_BOOL); + unset($_GET[$wsparamname]); + unset($_POST[$wsparamname]); + + $functioname = 'set_' . $name; + $settings->$functioname($value); + } + + } } /** @@ -1336,7 +1368,10 @@ protected function init_zend_server() { */ protected function parse_request() { - //Get GET and POST paramters + // We are going to clean the POST/GET parameters from the parameters specific to the server. + parent::set_web_service_call_settings(); + + // Get GET and POST paramters. $methodvariables = array_merge($_GET,$_POST); if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) { diff --git a/webservice/rest/locallib.php b/webservice/rest/locallib.php index 6dcfd431636ae..abd131cfd93a1 100644 --- a/webservice/rest/locallib.php +++ b/webservice/rest/locallib.php @@ -43,10 +43,9 @@ class webservice_rest_server extends webservice_base_server { * @param string $authmethod authentication method of the web service (WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN, ...) * @param string $restformat Format of the return values: 'xml' or 'json' */ - public function __construct($authmethod, $restformat = 'xml') { + public function __construct($authmethod) { parent::__construct($authmethod); $this->wsname = 'rest'; - $this->restformat = ($restformat != 'xml' && $restformat != 'json')?'xml':$restformat; //sanity check, we accept only xml or json } /** @@ -55,11 +54,22 @@ public function __construct($authmethod, $restformat = 'xml') { * 1/ user authentication - username+password or token (wsusername, wspassword and wstoken parameters) * 2/ function name (wsfunction parameter) * 3/ function parameters (all other parameters except those above) + * 4/ text format parameters + * 5/ return rest format xml/json */ protected function parse_request() { - //Get GET and POST paramters - $methodvariables = array_merge($_GET,$_POST); + // Retrieve and clean the POST/GET parameters from the parameters specific to the server. + parent::set_web_service_call_settings(); + + // Get GET and POST parameters. + $methodvariables = array_merge($_GET, $_POST); + + // Retrieve REST format parameter - 'xml' (default) or 'json'. + $restformatisset = isset($methodvariables['moodlewsrestformat']) + && (($methodvariables['moodlewsrestformat'] == 'xml' || $methodvariables['moodlewsrestformat'] == 'json')); + $this->restformat = $restformatisset ? $methodvariables['moodlewsrestformat'] : 'xml'; + unset($methodvariables['moodlewsrestformat']); if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) { $this->username = isset($methodvariables['wsusername']) ? $methodvariables['wsusername'] : null; diff --git a/webservice/rest/server.php b/webservice/rest/server.php index c0f02bce2efb5..56d39e270cc9f 100644 --- a/webservice/rest/server.php +++ b/webservice/rest/server.php @@ -42,16 +42,7 @@ die; } -$restformat = optional_param('moodlewsrestformat', 'xml', PARAM_ALPHA); -//remove the alt from the request -if(isset($_GET['moodlewsrestformat'])) { - unset($_GET['moodlewsrestformat']); -} -if(isset($_POST['moodlewsrestformat'])) { - unset($_POST['moodlewsrestformat']); -} - -$server = new webservice_rest_server(WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN, $restformat); +$server = new webservice_rest_server(WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN); $server->run(); die;