From ccc161f8f0f94e0bf82cc00b1573c195cbb2974a Mon Sep 17 00:00:00 2001 From: tjhunt Date: Mon, 13 Apr 2009 06:56:32 +0000 Subject: [PATCH] filters: MDL-7336 change weblib to use the new code * Rename filter base class from filter_base to moodle_text_filter * Remove unnecessary explicit constructors in moodle_text_filter subclasses * New filter_manager class, rather than static methods in filter_base * Move some logic out of weblib, and into filter_manager * Count filtering ops when $CFG->perfdebug on, via performance_measuring_filter_manager * Kill unused filter_string function. Petr said it should have been private to weblib --- blocks/moodleblock.class.php | 2 +- course/info.php | 3 +- filter/activitynames/filter.php | 6 +- filter/algebra/filter.php | 5 +- filter/censor/filter.php | 5 +- filter/emailprotect/filter.php | 5 +- filter/mediaplugin/filter.php | 8 +- filter/multilang/filter.php | 6 +- filter/tex/filter.php | 5 +- filter/tidy/filter.php | 6 +- lib/filterlib.php | 261 +++++++++++++++++++++++---- lib/moodlelib.php | 10 + lib/simpletest/testfiltermanager.php | 129 +++++++++++++ lib/weblib.php | 152 ++++------------ 14 files changed, 410 insertions(+), 193 deletions(-) create mode 100644 lib/simpletest/testfiltermanager.php diff --git a/blocks/moodleblock.class.php b/blocks/moodleblock.class.php index e6f51ade23..c6bb802c43 100644 --- a/blocks/moodleblock.class.php +++ b/blocks/moodleblock.class.php @@ -380,7 +380,7 @@ class block_base { } //Accesssibility: added H2 (was in, weblib.php: print_side_block) - $title .= '

'.filter_text($this->title).'

'; + $title .= '

'.format_string($this->title).'

'; if ($this->edit_controls !== NULL) { $title .= $this->edit_controls; diff --git a/course/info.php b/course/info.php index 47eebd1e18..7ced5175e2 100644 --- a/course/info.php +++ b/course/info.php @@ -53,8 +53,7 @@ print_box_start('generalbox info'); - echo filter_text(text_to_html($course->summary),$course->id); - + echo format_text($course->summary, FORMAT_MOODLE, NULL, $course->id); if ($managerroles = get_config('', 'coursemanager')) { $coursemanagerroles = split(',', $managerroles); diff --git a/filter/activitynames/filter.php b/filter/activitynames/filter.php index 89347b8413..67923a2f49 100644 --- a/filter/activitynames/filter.php +++ b/filter/activitynames/filter.php @@ -3,15 +3,11 @@ //activities when its name (title) is found inside every Moodle text //It's based in the glosssary filter by Williams Castillo //Modifications by stronk7. -class activitynames_filter extends filter_base { +class activitynames_filter extends moodle_text_filter { // Trivial-cache - keyed on $cachedcourseid static $activitylist = null; static $cachedcourseid; - function __construct($courseid, $format, $options){ - parent::__construct($courseid, $format, $options); - } - function filter($text) { global $CFG, $COURSE, $DB; diff --git a/filter/algebra/filter.php b/filter/algebra/filter.php index 1ec66b13dc..555e8bfc51 100644 --- a/filter/algebra/filter.php +++ b/filter/algebra/filter.php @@ -84,10 +84,7 @@ function string_file_picture_algebra($imagefile, $tex= "", $height="", $width="" return $output; } -class algebra_filter extends filter_base { - function __construct($courseid, $format, $options){ - parent::__construct($courseid, $format, $options); - } +class algebra_filter extends moodle_text_filter { function filter($text){ global $CFG, $DB; diff --git a/filter/censor/filter.php b/filter/censor/filter.php index 919e319610..58fac89411 100644 --- a/filter/censor/filter.php +++ b/filter/censor/filter.php @@ -11,10 +11,7 @@ /// This is the filtering class. It accepts the courseid and /// options to be filtered (In HTML form). -class censor_filter extends filter_base { - function __construct($courseid, $format, $options) { - parent::__construct($courseid, $format, $options); - } +class censor_filter extends moodle_text_filter { private function _canseecensor() { $cansee = false; $context = get_context_instance(CONTEXT_SYSTEM, SITEID); diff --git a/filter/emailprotect/filter.php b/filter/emailprotect/filter.php index 612b639f58..9427b5e861 100644 --- a/filter/emailprotect/filter.php +++ b/filter/emailprotect/filter.php @@ -3,10 +3,7 @@ // hides them using the Moodle obfuscate_text function. // Original code by Mike Churchward -class emailprotect_filter extends filter_base { - function __construct($courseid, $format, $options) { - parent::__construct($courseid, $format, $options); - } +class emailprotect_filter extends moodle_text_filter { function filter($text) { /// Do a quick check using stripos to avoid unnecessary work if (strpos($text, '@') === false) { diff --git a/filter/mediaplugin/filter.php b/filter/mediaplugin/filter.php index 5086fd6ec1..f42f8f7b4c 100644 --- a/filter/mediaplugin/filter.php +++ b/filter/mediaplugin/filter.php @@ -17,12 +17,8 @@ require_once($CFG->libdir.'/filelib.php'); -class mediaplugin_filter extends filter_base { - private $eolas_fix_applied; - function __construct($courseid, $format, $options) { - parent::__construct($courseid, $format, $options); - $this->eolas_fix_applied = false; - } +class mediaplugin_filter extends moodle_text_filter { + private $eolas_fix_applied = false; function filter($text) { global $CFG; // You should never modify parameters passed to a method or function, it's BAD practice. Create a copy instead. diff --git a/filter/multilang/filter.php b/filter/multilang/filter.php index 2f5eb0c0c8..3aa23c1d5d 100644 --- a/filter/multilang/filter.php +++ b/filter/multilang/filter.php @@ -36,11 +36,7 @@ // Following new syntax is not compatible with old one: // one langanother language -class multilang_filter extends filter_base { - function __construct($courseid, $format, $options) { - parent::__construct($courseid, $format, $options); - } - +class multilang_filter extends moodle_text_filter { function filter($text) { global $CFG; diff --git a/filter/tex/filter.php b/filter/tex/filter.php index 01ee633d77..c113ec6722 100644 --- a/filter/tex/filter.php +++ b/filter/tex/filter.php @@ -101,10 +101,7 @@ function string_file_picture_tex($imagefile, $tex= "", $height="", $width="", $a return $output; } -class tex_filter extends filter_base { - function __construct($courseid, $format, $options) { - parent::__construct($courseid, $format, $options); - } +class tex_filter extends moodle_text_filter { function filter ($text) { global $CFG, $DB; diff --git a/filter/tidy/filter.php b/filter/tidy/filter.php index bb6893d669..53d1f2d11b 100644 --- a/filter/tidy/filter.php +++ b/filter/tidy/filter.php @@ -11,11 +11,7 @@ // If you want to know what you can set in $tidyoptions and what their default // values are, see http://php.net/manual/en/function.tidy-get-config.php. -class tidy_filter extends filter_base { - function __construct($courseid, $format, $options) { - parent::__construct($courseid, $format, $options); - } - +class tidy_filter extends moodle_text_filter { /** * @author Hannes Gassert * @param string text to be filtered diff --git a/lib/filterlib.php b/lib/filterlib.php index def5d45106..e953c850a4 100644 --- a/lib/filterlib.php +++ b/lib/filterlib.php @@ -9,56 +9,253 @@ define('TEXTFILTER_INHERIT', 0); define('TEXTFILTER_OFF', -1); define('TEXTFILTER_DISABLED', -9999); -abstract class filter_base { - public static $filters = array(); - protected $courseid; - protected $format; - protected $options; +/** + * Class to manage the filtering of strings. It is intended that this class is + * only used by weblib.php. Client code should probably be using the + * format_text and format_string functions. + * + * This class is a singleton. + */ +class filter_manager { + /** This list of active filters, by context, for filtering content. + * An array contextid => array of filter objects. */ + protected $textfilters = array(); - public function __construct($courseid, $format, $options) { - $this->courseid = $courseid; - $this->format = $format; - $this->options = $options; + /** This list of active filters, by context, for filtering strings. + * An array contextid => array of filter objects. */ + protected $stringfilters = array(); + + /** Exploded version of $CFG->stringfilters. */ + protected $stringfilternames = array(); + + /** Holds the singleton instance. */ + protected static $singletoninstance; + + protected function __construct() { + global $CFG; + if (!empty($CFG->filterall) && !empty($CFG->stringfilters)) { + $stringfilternames = explode(',', $CFG->stringfilters); + } } - public static function addfilter($classname, $obj) { - if (empty(self::$filters[$classname])) { - self::$filters[$classname] = $obj; - return true; - } else { - return false; + /** + * @return the singleton instance. + */ + public static function instance() { + if (is_null(self::$singletoninstance)) { + global $CFG; + if (!empty($CFG->perfdebug)) { + self::$singletoninstance = new performance_measuring_filter_manager(); + } else { + self::$singletoninstance = new self(); + } + } + return self::$singletoninstance; + } + + /** Load all the filters required by this context. */ + protected function load_filters($context, $courseid) { + $filters = filter_get_active_in_context($context); + $this->textfilters[$context->id] = array(); + $this->stringfilters[$context->id] = array(); + foreach ($filters as $filtername => $localconfig) { + $filter = $this->make_filter_object($filtername, $context, $courseid, $localconfig); + if (is_null($filter)) { + continue; + } + $this->textfilters[$context->id][] = $filter; + if (in_array($filtername, $this->stringfilternames)) { + $this->stringfilters[$context->id][] = $filter; + } } } - public static function do_filter($text, $courseid = null) { + /** + * Factory method for creating a filter. + * @param string $filter The filter name, for example 'filter/tex' or 'mod/glossary'. + * @param $context context object. + * @param $courseid course if. + * @param $localconfig array of local configuration variables for this filter. + * @return moodle_text_filter The filter, or null, if this type of filter is + * not recognised or could not be created. + */ + protected function make_filter_object($filtername, $context, $courseid, $localconfig) { global $CFG; + $path = $CFG->dirroot .'/'. $filtername .'/filter.php'; + if (!is_readable($path)) { + return null; + } + include_once($path); - foreach (self::$filters as $n=>$obj) { - $text = $obj->filter($text); + $filterclassname = basename($filtername) . '_filter'; + if (class_exists($filterclassname)) { + return new $filterclassname($courseid, $context, $localconfig); } - // back compatable with old filter plugins - if (isset($CFG->textfilters)) { - $textfilters = explode(',', $CFG->textfilters); - foreach ($textfilters as $v) { - $text_filter = basename($v).'_filter'; - if (empty(self::$filters[$text_filter]) && is_readable($CFG->dirroot .'/'. $v .'/filter.php')) { - include_once($CFG->dirroot .'/'. $v .'/filter.php'); - if (function_exists($text_filter)) { - $text = $text_filter($courseid, $text); - } - } - } + $legacyfunctionname = basename($filtername) . '_filter'; + if (function_exists($legacyfunctionname)) { + return new legacy_filter($legacyfunctionname, $courseid, $context, $localconfig); + } + + return null; + } + + protected function apply_filter_chain($text, $filterchain) { + foreach ($filterchain as $filter) { + $text = $filter->filter($text); + } + return $text; + } + + protected function get_text_filters($context, $courseid) { + if (!isset($this->textfilters[$context->id])) { + $this->load_filters($context, $courseid); } + return $this->textfilters[$context->id]; + } + + protected function get_string_filters($context, $courseid) { + if (!isset($this->stringfilters[$context->id])) { + $this->load_filters($context, $courseid); + } + return $this->stringfilters[$context->id]; + } + + public function filter_text($text, $context, $courseid) { + $text = $this->apply_filter_chain($text, $this->get_text_filters($context, $courseid)); + /// tags removed for XHTML compatibility + $text = str_replace(array('', ''), '', $text); return $text; } + public function filter_string($string, $context, $courseid) { + return $this->apply_filter_chain($string, $this->get_string_filters($context, $courseid)); + } + + public function text_filtering_hash($context, $courseid) { + $filters = $this->get_text_filters($context, $courseid); + $hashes = array(); + foreach ($filters as $filter) { + $hashes[] = $filter->hash(); + } + return implode('-', $hashes); + } +} + +/** + * Filter manager subclass that does nothing. Having this simplifies the logic + * of format_text, etc. + */ +class null_filter_manager { + public function filter_text($text, $context, $courseid) { + return $text; + } + + public function filter_string($string, $context, $courseid) { + return $text; + } + + public function text_filtering_hash() { + return ''; + } +} + +/** + * Filter manager subclass that tacks how much work it does. + */ +class performance_measuring_filter_manager extends filter_manager { + protected $filterscreated = 0; + protected $textsfiltered = 0; + protected $stringsfiltered = 0; + + protected function make_filter_object($filtername, $context, $courseid, $localconfig) { + $this->filterscreated++; + return parent::make_filter_object($filtername, $context, $courseid, $localconfig); + } + + public function filter_text($text, $context, $courseid) { + $this->textsfiltered++; + return parent::filter_text($text, $context, $courseid); + } + + public function filter_string($string, $context, $courseid) { + $this->stringsfiltered++; + return parent::filter_string($string, $context, $courseid); + } + + public function get_performance_summary() { + return array(array( + 'contextswithfilters' => count($this->textfilters), + 'filterscreated' => $this->filterscreated, + 'textsfiltered' => $this->textsfiltered, + 'stringsfiltered' => $this->stringsfiltered, + ), array( + 'contextswithfilters' => 'Contexts for which filters were loaded', + 'filterscreated' => 'Filters created', + 'textsfiltered' => 'Pieces of content filtered', + 'stringsfiltered' => 'Strings filtered', + )); + } +} + +/** + * Base class for text filters. You just need to override this class and + * implement the filter method. + */ +abstract class moodle_text_filter { + /** The course we are in. */ + protected $courseid; + /** The context we are in. */ + protected $context; + /** Any local configuration for this filter in this context. */ + protected $localconfig; + + /** + * Set any context-specific configuration for this filter. + * @param object $context The current course id. + * @param object $context The current context. + * @param array $config Any context-specific configuration for this filter. + */ + public function __construct($courseid, $context, array $localconfig) { + $this->courseid = $courseid; + $this->context = $context; + $this->localconfig = $localconfig; + } + public function hash() { return __CLASS__; } - // filter plugin must overwrite this function to filter - abstract function filter($text); + /** + * Override this funciton to actually implement the filtering. + * @param $text some HTML content. + * @return the HTML content after the filtering has been applied. + */ + public abstract function filter($text); +} + +/** + * moodle_text_filter implementation that encapsulates an old-style filter that + * only defines a function, not a class. + */ +class legacy_filter extends moodle_text_filter { + protected $filterfunction; + + /** + * Set any context-specific configuration for this filter. + * @param string $filterfunction + * @param object $context The current course id. + * @param object $context The current context. + * @param array $config Any context-specific configuration for this filter. + */ + public function __construct($filterfunction, $courseid, $context, array $localconfig) { + parent::__construct($courseid, $context, $localconfig); + $this->filterfunction = $filterfunction; + } + + public function filter($text) { + return call_user_func($this->filterfunction, $this->courseid, $text); + } } /// Define one exclusive separator that we'll use in the temp saved tags diff --git a/lib/moodlelib.php b/lib/moodlelib.php index bd3cb8062a..04774bda6f 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -7967,6 +7967,16 @@ function get_performance_info() { $info['html'] .= 'Included '.$info['includecount'].' files '; $info['txt'] .= 'includecount: '.$info['includecount'].' '; + $filtermanager = filter_manager::instance(); + if (method_exists($filtermanager, 'get_performance_summary')) { + list($filterinfo, $nicenames) = $filtermanager->get_performance_summary(); + $info = array_merge($filterinfo, $info); + foreach ($filterinfo as $key => $value) { + $info['html'] .= "$nicenames[$key]: $value "; + $info['txt'] .= "$key: $value "; + } + } + if (!empty($PERF->logwrites)) { $info['logwrites'] = $PERF->logwrites; $info['html'] .= 'Log DB writes '.$info['logwrites'].' '; diff --git a/lib/simpletest/testfiltermanager.php b/lib/simpletest/testfiltermanager.php new file mode 100644 index 0000000000..f032ce9c06 --- /dev/null +++ b/lib/simpletest/testfiltermanager.php @@ -0,0 +1,129 @@ +libdir . '/filterlib.php'); + +class testable_filter_manager extends filter_manager { + public function __construct() { + parent::__construct(); + } + public function make_filter_object($filtername, $context, $courseid, $localconfig) { + return parent::make_filter_object($filtername, $context, $courseid, $localconfig); + } + public function apply_filter_chain($text, $filterchain) { + return parent::apply_filter_chain($text, $filterchain); + } +} + +/** + * Test functions that affect filter_active table with contextid = $syscontextid. + */ +class filter_manager_test extends UnitTestCase { + protected $filtermanager; + protected $olddirroot; + + public function setUp() { + global $CFG; + $this->filtermanager = new testable_filter_manager(); + $this->olddirroot = $CFG->dirroot; + $CFG->dirroot = $CFG->dataroot . '/temp'; + } + + public function tearDown() { + global $CFG; + $CFG->dirroot = $this->olddirroot; + } + + /** Basically does file_put_contents, but ensures the directory exists first. */ + protected function write_file($path, $content) { + global $CFG; + make_upload_directory(str_replace($CFG->dataroot . '/', '', dirname($path))); + file_put_contents($path, $content); + } + + public function test_make_filter_object_newstyle() { + global $CFG; + $this->write_file($CFG->dirroot . '/filter/makenewstyletest/filter.php', <<filtermanager->make_filter_object('filter/makenewstyletest', null, 1, array()); + $this->assertIsA($filter, 'moodle_text_filter'); + $this->assertNotA($filter, 'legacy_filter'); + } + + public function test_make_filter_object_legacy() { + global $CFG; + $this->write_file($CFG->dirroot . '/filter/makelegacytest/filter.php', <<filtermanager->make_filter_object('filter/makelegacytest', null, 1, array()); + $this->assertIsA($filter, 'legacy_filter'); + } + + public function test_make_filter_object_missing() { + $this->assertNull($this->filtermanager->make_filter_object('filter/nonexistant', null, 1, array())); + } + + public function test_apply_filter_chain() { + $filterchain = array(new doubleup_test_filter(null, 1, array()), new killfrogs_test_filter(null, 1, array())); + $this->assertEqual('pawn pawn', $this->filtermanager->apply_filter_chain('frogspawn', $filterchain)); + } +} + +class doubleup_test_filter extends moodle_text_filter { + public function filter($text) { + return $text . ' ' . $text; + } +} + +class killfrogs_test_filter extends moodle_text_filter { + public function filter($text) { + return str_replace('frogs', '', $text); + } +} + +?> diff --git a/lib/weblib.php b/lib/weblib.php index aa704f6937..d94903f12a 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -1253,27 +1253,17 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL $courseid = $COURSE->id; } - // if filter plugin is OOP format, add it to filter list and append hash - // value to $hashstr - if (!empty($CFG->textfilters)) { - require_once($CFG->libdir.'/filterlib.php'); - $textfilters = explode(',', $CFG->textfilters); - foreach ($textfilters as $textfilter) { - if (is_readable($CFG->dirroot .'/'. $textfilter .'/filter.php')) { - include_once($CFG->dirroot .'/'. $textfilter .'/filter.php'); - $text_filter = basename($textfilter).'_filter'; - if (class_exists($text_filter)) { - $obj = new $text_filter($courseid, $format, $options); - filter_base::addfilter($text_filter, $obj); - $hashstr .= $obj->hash(); - } - } - } + if ($options->filter) { + $filtermanager = filter_manager::instance(); + } else { + $filtermanager = new null_filter_manager(); } + $context = get_context_instance(CONTEXT_SYSTEM); // TODO change, once we have $PAGE->context. + if (!empty($CFG->cachetext) and empty($options->nocache)) { - $hashstr .= $text.'-'.(int)$courseid.'-'.current_language().'-'.(int)$format.(int)$options->trusttext.(int)$options->noclean.(int)$options->smiley.(int)$options->filter.(int)$options->para.(int)$options->newlines; - // for debug filtering system - // $hashstr .= time(); + $hashstr .= $text.'-'.$filtermanager->text_filtering_hash($context, $courseid).'-'.(int)$courseid.'-'.current_language().'-'. + (int)$format.(int)$options->trusttext.(int)$options->noclean.(int)$options->smiley. + (int)$options->filter.(int)$options->para.(int)$options->newlines; $time = time() - $CFG->cachetext; $md5key = md5($hashstr); @@ -1316,8 +1306,6 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL $text = trusttext_strip($text); } - $CFG->currenttextiscacheable = true; // Default status - can be changed by any filter - switch ($format) { case FORMAT_HTML: if ($options->smiley) { @@ -1326,9 +1314,7 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL if (!$options->noclean) { $text = clean_text($text, FORMAT_HTML); } - if ($options->filter) { - $text = filter_base::do_filter($text, $courseid); - } + $text = $filtermanager->filter_text($text, $context, $courseid); break; case FORMAT_PLAIN: @@ -1354,10 +1340,7 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL if (!$options->noclean) { $text = clean_text($text, FORMAT_HTML); } - - if ($options->filter) { - $text = filter_base::do_filter($text, $courseid); - } + $text = $filtermanager->filter_text($text, $context, $courseid); break; default: // FORMAT_MOODLE or anything else @@ -1365,14 +1348,20 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL if (!$options->noclean) { $text = clean_text($text, FORMAT_HTML); } - - if ($options->filter) { - $text = filter_base::do_filter($text, $courseid); - } + $text = $filtermanager->filter_text($text, $context, $courseid); break; } - if (empty($options->nocache) and !empty($CFG->cachetext) and $CFG->currenttextiscacheable) { + // Warn people that we have removed this old mechanism, just in case they + // were stupid enough to rely on it. + if (isset($CFG->currenttextiscacheable)) { + debugging('Once upon a time, Moodle had a truly evil use of global variables ' . + 'called $CFG->currenttextiscacheable. The good news is that this no ' . + 'longer exists. The bad news is that you seem to be using a filter that '. + 'relies on it. Please seek out and destroy that filter code.', DEBUG_DEVELOPER); + } + + if (empty($options->nocache) and !empty($CFG->cachetext)) { if (CLI_SCRIPT) { // special static cron cache - no need to store it in db if its not already there if (count($croncache) > 150) { @@ -1457,7 +1446,7 @@ function reset_text_filters_cache() { * @param int $courseid Current course as filters can, potentially, use it * @return string */ -function format_string ($string, $striplinks=true, $courseid=NULL ) { +function format_string($string, $striplinks=true, $courseid=NULL ) { global $CFG, $COURSE; @@ -1485,7 +1474,8 @@ function format_string ($string, $striplinks=true, $courseid=NULL ) { $string = preg_replace("/\&(?![a-zA-Z0-9#]{1,8};)/", "&", $string); if (!empty($CFG->filterall)) { - $string = filter_string($string, $courseid); + $context = get_context_instance(CONTEXT_SYSTEM); // TODO change, once we have $PAGE->context. + $string = filter_manager::instance()->filter_string($string, $context, $courseid); } // If the site requires it, strip ALL tags from this string @@ -1551,16 +1541,11 @@ function format_text_email($text, $format) { /** * Given some text in HTML format, this function will pass it - * through any filters that have been defined in $CFG->textfilterx - * The variable defines a filepath to a file containing the - * filter function. The file must contain a variable called - * $textfilter_function which contains the name of the function - * with $courseid and $text parameters + * through any filters that have been configured for this context. * * @param string $text The text to be passed through format filters - * @param int $courseid ? - * @return string - * @todo Finish documenting this function + * @param int $courseid The current course. + * @return string the filtered string. */ function filter_text($text, $courseid=NULL) { global $CFG, $COURSE; @@ -1569,85 +1554,9 @@ function filter_text($text, $courseid=NULL) { $courseid = $COURSE->id; // (copied from format_text) } - if (!empty($CFG->textfilters)) { - require_once($CFG->libdir.'/filterlib.php'); - $textfilters = explode(',', $CFG->textfilters); - foreach ($textfilters as $textfilter) { - if (is_readable($CFG->dirroot .'/'. $textfilter .'/filter.php')) { - include_once($CFG->dirroot .'/'. $textfilter .'/filter.php'); - $functionname = basename($textfilter).'_filter'; - if (function_exists($functionname)) { - $text = $functionname($courseid, $text); - } - } - } - } - - /// tags removed for XHTML compatibility - $text = str_replace('', '', $text); - $text = str_replace('', '', $text); - - return $text; -} - - -/** - * Given a string (short text) in HTML format, this function will pass it - * through any filters that have been defined in $CFG->stringfilters - * The variable defines a filepath to a file containing the - * filter function. The file must contain a variable called - * $textfilter_function which contains the name of the function - * with $courseid and $text parameters - * - * @param string $string The text to be passed through format filters - * @param int $courseid The id of a course - * @return string - */ -function filter_string($string, $courseid=NULL) { - global $CFG, $COURSE; - - if (empty($CFG->textfilters)) { // All filters are disabled anyway so quit - return $string; - } - - if (empty($courseid)) { - $courseid = $COURSE->id; - } - - require_once($CFG->libdir.'/filterlib.php'); - - if (isset($CFG->stringfilters)) { // We have a predefined list to use, great! - if (empty($CFG->stringfilters)) { // but it's blank, so finish now - return $string; - } - $stringfilters = explode(',', $CFG->stringfilters); // ..use the list we have - - } else { // Otherwise try to derive a list from textfilters - if (strpos($CFG->textfilters, 'filter/multilang') !== false) { // Multilang is here - $stringfilters = array('filter/multilang'); // Let's use just that - $CFG->stringfilters = 'filter/multilang'; // Save it for next time through - } else { - $CFG->stringfilters = ''; // Save the result and return - return $string; - } - } - + $context = get_context_instance(CONTEXT_SYSTEM); // TODO change, once we have $PAGE->context. - foreach ($stringfilters as $stringfilter) { - if (is_readable($CFG->dirroot .'/'. $stringfilter .'/filter.php')) { - include_once($CFG->dirroot .'/'. $stringfilter .'/filter.php'); - $functionname = basename($stringfilter).'_filter'; - if (function_exists($functionname)) { - $string = $functionname($courseid, $string); - } - } - } - - /// tags removed for XHTML compatibility - $string = str_replace('', '', $string); - $string = str_replace('', '', $string); - - return $string; + return filter_manager::instance()->filter_text($text, $context, $courseid); } /** @@ -1698,6 +1607,7 @@ function trusttext_mark($text) { return $text; } } + function trusttext_after_edit(&$text, $context) { if (has_capability('moodle/site:trustcontent', $context)) { $text = trusttext_strip($text); -- 2.39.5