MDL-50491 filters: option to disable some filters in filter_text.
This lets you programmatically prevent certain filters running on certain content. Also, I created some unit tests for the basic format_text functionality since there did not seem to be any yet.
This commit is contained in:
@@ -3,6 +3,8 @@ information provided here is intended especially for developers.
|
||||
|
||||
=== 3.0 ===
|
||||
|
||||
* New argument $skipfilters to filter_manager::filter_text to allow applying
|
||||
the filters with a given one omitted.
|
||||
|
||||
* New admin setting class admin_setting_filter_types which can be used if you
|
||||
want to make the disablefilters value in your code configurable.
|
||||
|
||||
+21
-12
@@ -54,13 +54,13 @@ define('TEXTFILTER_EXCL_SEPARATOR', '-%-');
|
||||
class filter_manager {
|
||||
/**
|
||||
* @var moodle_text_filter[][] This list of active filters, by context, for filtering content.
|
||||
* An array contextid => array of filter objects.
|
||||
* An array contextid => ordered array of filter name => filter objects.
|
||||
*/
|
||||
protected $textfilters = array();
|
||||
|
||||
/**
|
||||
* @var moodle_text_filter[][] This list of active filters, by context, for filtering strings.
|
||||
* An array contextid => array of filter objects.
|
||||
* An array contextid => ordered array of filter name => filter objects.
|
||||
*/
|
||||
protected $stringfilters = array();
|
||||
|
||||
@@ -127,9 +127,9 @@ class filter_manager {
|
||||
if (is_null($filter)) {
|
||||
continue;
|
||||
}
|
||||
$this->textfilters[$context->id][] = $filter;
|
||||
$this->textfilters[$context->id][$filtername] = $filter;
|
||||
if (in_array($filtername, $this->stringfilternames)) {
|
||||
$this->stringfilters[$context->id][] = $filter;
|
||||
$this->stringfilters[$context->id][$filtername] = $filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,12 +162,17 @@ class filter_manager {
|
||||
/**
|
||||
* Apply a list of filters to some content.
|
||||
* @param string $text
|
||||
* @param moodle_text_filter[] $filterchain
|
||||
* @param moodle_text_filter[] $filterchain array filter name => filter object.
|
||||
* @param array $options options passed to the filters.
|
||||
* @param array $skipfilters of filter names. Any filters that should not be applied to this text.
|
||||
* @return string $text
|
||||
*/
|
||||
protected function apply_filter_chain($text, $filterchain, array $options = array()) {
|
||||
foreach ($filterchain as $filter) {
|
||||
protected function apply_filter_chain($text, $filterchain, array $options = array(),
|
||||
array $skipfilters = null) {
|
||||
foreach ($filterchain as $filtername => $filter) {
|
||||
if ($skipfilters !== null && in_array($filtername, $skipfilters)) {
|
||||
continue;
|
||||
}
|
||||
$text = $filter->filter($text, $options);
|
||||
}
|
||||
return $text;
|
||||
@@ -205,10 +210,12 @@ class filter_manager {
|
||||
* @param string $text The text to filter
|
||||
* @param context $context the context.
|
||||
* @param array $options options passed to the filters
|
||||
* @param array $skipfilters of filter names. Any filters that should not be applied to this text.
|
||||
* @return string resulting text
|
||||
*/
|
||||
public function filter_text($text, $context, array $options = array()) {
|
||||
$text = $this->apply_filter_chain($text, $this->get_text_filters($context), $options);
|
||||
public function filter_text($text, $context, array $options = array(),
|
||||
array $skipfilters = null) {
|
||||
$text = $this->apply_filter_chain($text, $this->get_text_filters($context), $options, $skipfilters);
|
||||
// <nolink> tags removed for XHTML compatibility
|
||||
$text = str_replace(array('<nolink>', '</nolink>'), '', $text);
|
||||
return $text;
|
||||
@@ -275,7 +282,8 @@ class filter_manager {
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class null_filter_manager {
|
||||
public function filter_text($text, $context, $options) {
|
||||
public function filter_text($text, $context, array $options = array(),
|
||||
array $skipfilters = null) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
@@ -320,9 +328,10 @@ class performance_measuring_filter_manager extends filter_manager {
|
||||
return parent::make_filter_object($filtername, $context, $localconfig);
|
||||
}
|
||||
|
||||
public function filter_text($text, $context, array $options = array()) {
|
||||
public function filter_text($text, $context, array $options = array(),
|
||||
array $skipfilters = null) {
|
||||
$this->textsfiltered++;
|
||||
return parent::filter_text($text, $context, $options);
|
||||
return parent::filter_text($text, $context, $options, $skipfilters);
|
||||
}
|
||||
|
||||
public function filter_string($string, $context) {
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<?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 the {@link filter_manager} class.
|
||||
*
|
||||
* @package core
|
||||
* @category test
|
||||
* @copyright 2015 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link filter_manager} class.
|
||||
*
|
||||
* @copyright 2015 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
class core_filter_manager_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Helper method to apply filters to some text and return the result.
|
||||
* @param string $text the text to filter.
|
||||
* @param array $skipfilters any filters not to apply, even if they are configured.
|
||||
* @return string the filtered text.
|
||||
*/
|
||||
protected function filter_text($text, $skipfilters) {
|
||||
global $PAGE;
|
||||
$filtermanager = filter_manager::instance();
|
||||
$filtermanager->setup_page_for_filters($PAGE, $PAGE->context);
|
||||
$filteroptions = array(
|
||||
'originalformat' => FORMAT_HTML,
|
||||
'noclean' => false,
|
||||
);
|
||||
return $filtermanager->filter_text($text, $PAGE->context, $filteroptions, $skipfilters);
|
||||
}
|
||||
|
||||
public function test_filter_normal() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
$this->assertRegExp('~^<p><img class="emoticon" alt="smile" ([^>]+)></p>$~',
|
||||
$this->filter_text('<p>:-)</p>', array()));
|
||||
}
|
||||
|
||||
public function test_one_filter_disabled() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
$this->assertEquals('<p>:-)</p>',
|
||||
$this->filter_text('<p>:-)</p>', array('emoticon')));
|
||||
}
|
||||
|
||||
public function test_disabling_other_filter_does_not_break_it() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
$this->assertRegExp('~^<p><img class="emoticon" alt="smile" ([^>]+)></p>$~',
|
||||
$this->filter_text('<p>:-)</p>', array('urltolink')));
|
||||
}
|
||||
|
||||
public function test_one_filter_of_two_disabled() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
filter_set_global_state('urltolink', TEXTFILTER_ON);
|
||||
$this->assertRegExp('~^<p><img class="emoticon" alt="smile" ([^>]+)> http://google.com/</p>$~',
|
||||
$this->filter_text('<p>:-) http://google.com/</p>', array('glossary', 'urltolink')));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?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 format_text defined in weblib.php.
|
||||
*
|
||||
* @package core
|
||||
* @category test
|
||||
* @copyright 2015 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for format_text defined in weblib.php.
|
||||
*
|
||||
* @copyright 2015 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
class core_weblib_format_text_testcase extends advanced_testcase {
|
||||
|
||||
public function test_format_text_format_html() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
$this->assertRegExp('~^<p><img class="emoticon" alt="smile" ([^>]+)></p>$~',
|
||||
format_text('<p>:-)</p>', FORMAT_HTML));
|
||||
}
|
||||
|
||||
public function test_format_text_format_html_no_filters() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
$this->assertEquals('<p>:-)</p>',
|
||||
format_text('<p>:-)</p>', FORMAT_HTML, array('filter' => false)));
|
||||
}
|
||||
|
||||
public function test_format_text_format_plain() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
$this->assertEquals(':-)',
|
||||
format_text(':-)', FORMAT_PLAIN, array('filter' => false)));
|
||||
}
|
||||
|
||||
public function test_format_text_format_markdown() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
$this->assertRegExp('~^<p><em><img class="emoticon" alt="smile" ([^>]+)></em></p>\n$~',
|
||||
format_text('*:-)*', FORMAT_MARKDOWN));
|
||||
}
|
||||
|
||||
public function test_format_text_format_markdown_nofilter() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
$this->assertEquals("<p><em>:-)</em></p>\n",
|
||||
format_text('*:-)*', FORMAT_MARKDOWN, array('filter' => false)));
|
||||
}
|
||||
|
||||
public function test_format_text_format_moodle() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
$this->assertRegExp('~^<div class="text_to_html"><p><img class="emoticon" alt="smile" ([^>]+)></p></div>$~',
|
||||
format_text('<p>:-)</p>', FORMAT_MOODLE));
|
||||
}
|
||||
|
||||
public function test_format_text_format_moodle_no_filters() {
|
||||
$this->resetAfterTest();
|
||||
filter_set_global_state('emoticon', TEXTFILTER_ON);
|
||||
$this->assertEquals('<div class="text_to_html"><p>:-)</p></div>',
|
||||
format_text('<p>:-)</p>', FORMAT_MOODLE, array('filter' => false)));
|
||||
}
|
||||
|
||||
public function test_format_text_overflowdiv() {
|
||||
$this->assertEquals('<div class="no-overflow"><p>:-)</p></div>',
|
||||
format_text('<p>:-)</p>', FORMAT_HTML, array('overflowdiv' => true)));
|
||||
}
|
||||
}
|
||||
+8
-12
@@ -1204,8 +1204,13 @@ function format_text($text, $format = FORMAT_MOODLE, $options = null, $courseidd
|
||||
if ($options['filter']) {
|
||||
$filtermanager = filter_manager::instance();
|
||||
$filtermanager->setup_page_for_filters($PAGE, $context); // Setup global stuff filters may have.
|
||||
$filteroptions = array(
|
||||
'originalformat' => $format,
|
||||
'noclean' => $options['noclean'],
|
||||
);
|
||||
} else {
|
||||
$filtermanager = new null_filter_manager();
|
||||
$filteroptions = array();
|
||||
}
|
||||
|
||||
switch ($format) {
|
||||
@@ -1213,10 +1218,7 @@ function format_text($text, $format = FORMAT_MOODLE, $options = null, $courseidd
|
||||
if (!$options['noclean']) {
|
||||
$text = clean_text($text, FORMAT_HTML, $options);
|
||||
}
|
||||
$text = $filtermanager->filter_text($text, $context, array(
|
||||
'originalformat' => FORMAT_HTML,
|
||||
'noclean' => $options['noclean']
|
||||
));
|
||||
$text = $filtermanager->filter_text($text, $context, $filteroptions);
|
||||
break;
|
||||
|
||||
case FORMAT_PLAIN:
|
||||
@@ -1239,10 +1241,7 @@ function format_text($text, $format = FORMAT_MOODLE, $options = null, $courseidd
|
||||
if (!$options['noclean']) {
|
||||
$text = clean_text($text, FORMAT_HTML, $options);
|
||||
}
|
||||
$text = $filtermanager->filter_text($text, $context, array(
|
||||
'originalformat' => FORMAT_MARKDOWN,
|
||||
'noclean' => $options['noclean']
|
||||
));
|
||||
$text = $filtermanager->filter_text($text, $context, $filteroptions);
|
||||
break;
|
||||
|
||||
default: // FORMAT_MOODLE or anything else.
|
||||
@@ -1250,10 +1249,7 @@ function format_text($text, $format = FORMAT_MOODLE, $options = null, $courseidd
|
||||
if (!$options['noclean']) {
|
||||
$text = clean_text($text, FORMAT_HTML, $options);
|
||||
}
|
||||
$text = $filtermanager->filter_text($text, $context, array(
|
||||
'originalformat' => $format,
|
||||
'noclean' => $options['noclean']
|
||||
));
|
||||
$text = $filtermanager->filter_text($text, $context, $filteroptions);
|
||||
break;
|
||||
}
|
||||
if ($options['filter']) {
|
||||
|
||||
Reference in New Issue
Block a user