From 1d0140757a156526da8e9f46756325fa810a54b6 Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Tue, 3 May 2016 19:40:47 +0800 Subject: [PATCH] MDL-54034 ajax: Apply filters in ajax requests This also clarified that developers can decide to force filters to be ignored when using external_format_text, though they cannot force filters to be turned on as the clients should be able to opt-out from filtering should they want to. --- course/externallib.php | 1 + lib/ajax/service.php | 7 ++++++ lib/externallib.php | 12 ++++++---- lib/tests/externallib_test.php | 43 +++++++++++++++++++++++++++++----- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/course/externallib.php b/course/externallib.php index da654a2fcd5..8099e0afadc 100644 --- a/course/externallib.php +++ b/course/externallib.php @@ -2177,6 +2177,7 @@ class core_course_external extends external_api { 'requiredcapabilities' => $requiredcapabilities ); $params = self::validate_parameters(self::search_courses_parameters(), $parameters); + self::validate_context(context_system::instance()); $allowedcriterianames = array('search', 'modulelist', 'blocklist', 'tagid'); if (!in_array($params['criterianame'], $allowedcriterianames)) { diff --git a/lib/ajax/service.php b/lib/ajax/service.php index d3d23ab9d77..19a43b68762 100644 --- a/lib/ajax/service.php +++ b/lib/ajax/service.php @@ -41,6 +41,13 @@ if ($requests === null) { } $responses = array(); +// Defines the external settings required for Ajax processing. +$settings = external_settings::get_instance(); +$settings->set_file('pluginfile.php'); +$settings->set_fileurl(true); +$settings->set_filter(true); +$settings->set_raw(false); + foreach ($requests as $request) { $response = array(); $methodname = clean_param($request['methodname'], PARAM_ALPHANUMEXT); diff --git a/lib/externallib.php b/lib/externallib.php index 7c0e838e2cb..befa4e6ed32 100644 --- a/lib/externallib.php +++ b/lib/externallib.php @@ -853,6 +853,11 @@ function external_validate_format($format) { * The caller can change the format (raw) with the external_settings singleton * All web service servers must set this singleton when parsing the $_GET and $_POST. * + *
+ * Options are the same that in {@link format_string()} with some changes:
+ *      filter      : Can be set to false to force filters off, else observes {@link external_settings}.
+ * 
+ * * @param string $str The string to be filtered. Should be plain text, expect * possibly for multilang tags. * @param boolean $striplinks To strip any link in the result text. Moodle 1.8 default changed from false to true! MDL-8713 @@ -872,7 +877,7 @@ function external_format_string($str, $contextid, $striplinks = true, $options = if (!$settings->get_raw()) { $context = context::instance_by_id($contextid); $options['context'] = $context; - $options['filter'] = $settings->get_filter(); + $options['filter'] = isset($options['filter']) && !$options['filter'] ? false : $settings->get_filter(); $str = format_string($str, $striplinks, $options); } @@ -890,8 +895,7 @@ function external_format_string($str, $contextid, $striplinks = true, $options = * trusted : If true the string won't be cleaned. Default false. * noclean : If true the string won't be cleaned only if trusted is also true. Default false. * nocache : If true the string will not be cached and will be formatted every call. Default false. - * filter : If true the string will be run through applicable filters as well. Default (different from format_text) - * got form settings. + * filter : Can be set to false to force filters off, else observes {@link external_settings}. * para : If true then the returned string will be wrapped in div tags. Default (different from format_text) false. * Default changed because div tags are not commonly needed. * newlines : If true then lines newline breaks will be converted to HTML newline breaks. Default true. @@ -935,7 +939,7 @@ function external_format_text($text, $textformat, $contextid, $component, $filea } } - $options['filter'] = isset($options['filter']) ? $options['filter'] : $settings->get_filter(); + $options['filter'] = isset($options['filter']) && !$options['filter'] ? false : $settings->get_filter(); $options['para'] = isset($options['para']) ? $options['para'] : false; $options['context'] = context::instance_by_id($contextid); $options['allowid'] = isset($options['allowid']) ? $options['allowid'] : true; diff --git a/lib/tests/externallib_test.php b/lib/tests/externallib_test.php index c018617b2c6..39796cc351f 100644 --- a/lib/tests/externallib_test.php +++ b/lib/tests/externallib_test.php @@ -96,6 +96,13 @@ class core_externallib_testcase extends advanced_testcase { ', FORMAT_HTML); $this->assertSame(external_format_text($test, $testformat, $context->id, 'core', '', 0), $correct); + // Filters can be opted out from by the developer. + $test = '$$ \pi $$'; + $testformat = FORMAT_MARKDOWN; + $correct = array('

$$ \pi $$

+', FORMAT_HTML); + $this->assertSame(external_format_text($test, $testformat, $context->id, 'core', '', 0, ['filter' => false]), $correct); + $test = '

Text

'; $testformat = FORMAT_HTML; $correct = array($test, FORMAT_HTML); @@ -135,23 +142,47 @@ class core_externallib_testcase extends advanced_testcase { } public function test_external_format_string() { + $this->resetAfterTest(); $settings = external_settings::get_instance(); - $currentraw = $settings->get_raw(); $currentfilter = $settings->get_filter(); + // Enable multilang filter to on content and heading. + filter_set_global_state('multilang', TEXTFILTER_ON); + filter_set_applies_to_strings('multilang', 1); + $filtermanager = filter_manager::instance(); + $filtermanager->reset_caches(); + $settings->set_raw(true); + $settings->set_filter(true); $context = context_system::instance(); - $test = '$$ \pi $$

there

'; + $test = 'ENFR ' . + '

there

!'; $correct = $test; - $this->assertSame(external_format_string($test, $context->id), $correct); + $this->assertSame($correct, external_format_string($test, $context->id)); $settings->set_raw(false); + $settings->set_filter(false); + + $test = 'ENFR ' . + '

there

?'; + $correct = 'ENFR hi there?'; + $this->assertSame($correct, external_format_string($test, $context->id)); + + $settings->set_filter(true); + + $test = 'ENFR ' . + '

there

@'; + $correct = 'EN hi there@'; + $this->assertSame($correct, external_format_string($test, $context->id)); + + // Filters can be opted out. + $test = 'ENFR ' . + '

there

%'; + $correct = 'ENFR hi there%'; + $this->assertSame($correct, external_format_string($test, $context->id, false, ['filter' => false])); - $test = '$$ \pi $$

there

'; - $correct = '$$ \pi $$hi there'; - $this->assertSame(external_format_string($test, $context->id), $correct); $settings->set_raw($currentraw); $settings->set_filter($currentfilter);