From 9e3f34d1c73c01507a3637f9e7796b57ff43c6b5 Mon Sep 17 00:00:00 2001 From: dongsheng Date: Fri, 19 Dec 2008 02:16:00 +0000 Subject: [PATCH] "FILTER/MDL-14582, filters 2.0, compatible with old filters" --- filter/activitynames/filter.php | 55 +++---- filter/algebra/filter.php | 250 ++++++++++++++++---------------- filter/censor/filter.php | 72 +++++---- filter/emailprotect/filter.php | 55 +++---- filter/mediaplugin/filter.php | 175 +++++++++++----------- filter/multilang/filter.php | 48 +++--- filter/tex/filter.php | 96 ++++++------ filter/tidy/filter.php | 65 +++++---- lib/filterlib.php | 49 +++++++ lib/weblib.php | 34 ++++- 10 files changed, 510 insertions(+), 389 deletions(-) diff --git a/filter/activitynames/filter.php b/filter/activitynames/filter.php index 7027a7d134..89347b8413 100644 --- a/filter/activitynames/filter.php +++ b/filter/activitynames/filter.php @@ -3,33 +3,37 @@ //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 { + // Trivial-cache - keyed on $cachedcourseid + static $activitylist = null; + static $cachedcourseid; - function activitynames_filter($courseid, $text) { - global $CFG, $COURSE, $DB; + function __construct($courseid, $format, $options){ + parent::__construct($courseid, $format, $options); + } - // Trivial-cache - keyed on $cachedcourseid - static $activitylist = null; - static $cachedcourseid; + function filter($text) { + global $CFG, $COURSE, $DB; - if (empty($courseid)) { - $courseid = SITEID; + if (empty($this->courseid)) { + $this->courseid = SITEID; } // Initialise/invalidate our trivial cache if dealing with a different course - if (!isset($cachedcourseid) || $cachedcourseid !== (int)$courseid) { - $activitylist = null; + if (!isset($this->cachedcourseid) || $this->cachedcourseid !== (int)$this->courseid) { + $this->activitylist = null; } - $cachedcourseid = (int)$courseid; + $this->cachedcourseid = (int)$this->courseid; /// It may be cached - if (is_null($activitylist)) { - $activitylist = array(); + if (is_null($this->activitylist)) { + $this->activitylist = array(); - if ($COURSE->id == $courseid) { + if ($COURSE->id == $this->courseid) { $course = $COURSE; } else { - $course = $DB->get_record("course", array("id"=>$courseid)); + $course = $DB->get_record("course", array("id"=>$this->courseid)); } if (!isset($course->modinfo)) { @@ -41,7 +45,7 @@ if (!empty($modinfo)) { - $activitylist = array(); /// We will store all the activities here + $this->activitylist = array(); /// We will store all the activities here //Sort modinfo by name length usort($modinfo, 'comparemodulenamesbylength'); @@ -55,9 +59,9 @@ /// Avoid empty or unlinkable activity names if (!empty($title)) { $href_tag_begin = "wwwroot/mod/$activity->mod/view.php?id=$activity->cm\" $CFG->frametarget>"; - $activitylist[] = new filterobject($currentname, $href_tag_begin, '', false, true); + $this->activitylist[] = new filterobject($currentname, $href_tag_begin, '', false, true); if ($currentname != $entitisedname) { /// If name has some entity (& " < >) add that filter too. MDL-17545 - $activitylist[] = new filterobject($entitisedname, $href_tag_begin, '', false, true); + $this->activitylist[] = new filterobject($entitisedname, $href_tag_begin, '', false, true); } } } @@ -65,20 +69,21 @@ } } - if ($activitylist) { - return $text = filter_phrases ($text, $activitylist); + if ($this->activitylist) { + return $text = filter_phrases ($text, $this->activitylist); } else { return $text; } } +} - //This function is used to order module names from longer to shorter - function comparemodulenamesbylength($a, $b) { - if (strlen($a->name) == strlen($b->name)) { - return 0; - } - return (strlen($a->name) < strlen($b->name)) ? 1 : -1; +//This function is used to order module names from longer to shorter +function comparemodulenamesbylength($a, $b) { + if (strlen($a->name) == strlen($b->name)) { + return 0; } + return (strlen($a->name) < strlen($b->name)) ? 1 : -1; +} ?> diff --git a/filter/algebra/filter.php b/filter/algebra/filter.php index d0121e45df..1ec66b13dc 100644 --- a/filter/algebra/filter.php +++ b/filter/algebra/filter.php @@ -84,16 +84,19 @@ function string_file_picture_algebra($imagefile, $tex= "", $height="", $width="" return $output; } - -function algebra_filter ($courseid, $text) { - global $CFG, $DB; - - /// Do a quick check using stripos to avoid unnecessary wor - if (!preg_match('/get_record("forum_discussions",array("id"=>$parent->discussion)); # } else if (strstr($scriptname,'discuss.php')) { -# $discussion = $DB->get_record("forum_discussions", array("id"=>$_GET['d'])); +# $discussion = $DB->get_record("forum_discussions",array("id"=>$_GET['d'])); # } else { # return $text; # } @@ -111,125 +114,126 @@ function algebra_filter ($courseid, $text) { # } - $text .= ' '; + $text .= ' '; - preg_match_all('/@(@@+)([^@])/',$text,$matches); - for ($i=0;$i some algebraic input expression - // or @@ some algebraic input expression @@ + // some algebraic input expression + // or @@ some algebraic input expression @@ - preg_match_all('/(.+?)<\/algebra>|@@(.+?)@@/is', $text, $matches); - for ($i=0; $i','',$algebra); - $algebra = str_replace('','',$algebra); - $algebra = str_replace('','',$algebra); - $algebra = str_replace('','',$algebra); - $align = "middle"; - if (preg_match('/^align=bottom /',$algebra)) { - $align = "text-bottom"; - $algebra = preg_replace('/^align=bottom /','',$algebra); - } else if (preg_match('/^align=top /',$algebra)) { - $align = "text-top"; - $algebra = preg_replace('/^align=top /','',$algebra); - } - $md5 = md5($algebra); - $filename = $md5 . ".gif"; - if (! $texcache = $DB->get_record("cache_filters", array("filter"=>"algebra", "md5key"=>$md5))) { - $algebra = str_replace('<','<',$algebra); - $algebra = str_replace('>','>',$algebra); - $algebra = str_replace('<>','#',$algebra); - $algebra = str_replace('<=','%',$algebra); - $algebra = str_replace('>=','!',$algebra); - $algebra = preg_replace('/([=><%!#] *)-/',"\$1 zeroplace -",$algebra); - $algebra = str_replace('delta','zdelta',$algebra); - $algebra = str_replace('beta','bita',$algebra); - $algebra = str_replace('theta','thita',$algebra); - $algebra = str_replace('zeta','zita',$algebra); - $algebra = str_replace('eta','xeta',$algebra); - $algebra = str_replace('epsilon','zepslon',$algebra); - $algebra = str_replace('upsilon','zupslon',$algebra); - $algebra = preg_replace('!\r\n?!',' ',$algebra); - $algebra = escapeshellarg($algebra); - if ( (PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows") ) { - $cmd = "cd $CFG->dirroot\\filter\\algebra & algebra2tex.pl $algebra"; - } else { - $cmd = "cd $CFG->dirroot/filter/algebra; ./algebra2tex.pl $algebra"; - } - $texexp = `$cmd`; - if (preg_match('/parsehilight/',$texexp)) { - $text = str_replace( $matches[0][$i],"Syntax error: " . $texexp,$text); - } else if ($texexp) { - $texexp = str_replace('zeroplace','',$texexp); - $texexp = str_replace('#','\not= ',$texexp); - $texexp = str_replace('%','\leq ',$texexp); - $texexp = str_replace('!','\geq ',$texexp); - $texexp = str_replace('\left{','{',$texexp); - $texexp = str_replace('\right}','}',$texexp); - $texexp = str_replace('\fun',' ',$texexp); - $texexp = str_replace('infty','\infty',$texexp); - $texexp = str_replace('alpha','\alpha',$texexp); - $texexp = str_replace('gamma','\gamma',$texexp); - $texexp = str_replace('iota','\iota',$texexp); - $texexp = str_replace('kappa','\kappa',$texexp); - $texexp = str_replace('lambda','\lambda',$texexp); - $texexp = str_replace('mu','\mu',$texexp); - $texexp = str_replace('nu','\nu',$texexp); - $texexp = str_replace('xi','\xi',$texexp); - $texexp = str_replace('rho','\rho',$texexp); - $texexp = str_replace('sigma','\sigma',$texexp); - $texexp = str_replace('tau','\tau',$texexp); - $texexp = str_replace('phi','\phi',$texexp); - $texexp = str_replace('chi','\chi',$texexp); - $texexp = str_replace('psi','\psi',$texexp); - $texexp = str_replace('omega','\omega',$texexp); - $texexp = str_replace('zdelta','\delta',$texexp); - $texexp = str_replace('bita','\beta',$texexp); - $texexp = str_replace('thita','\theta',$texexp); - $texexp = str_replace('zita','\zeta',$texexp); - $texexp = str_replace('xeta','\eta',$texexp); - $texexp = str_replace('zepslon','\epsilon',$texexp); - $texexp = str_replace('zupslon','\upsilon',$texexp); - $texexp = str_replace('\mbox{logten}','\mbox{log}_{10}',$texexp); - $texexp = str_replace('\mbox{acos}','\mbox{cos}^{-1}',$texexp); - $texexp = str_replace('\mbox{asin}','\mbox{sin}^{-1}',$texexp); - $texexp = str_replace('\mbox{atan}','\mbox{tan}^{-1}',$texexp); - $texexp = str_replace('\mbox{asec}','\mbox{sec}^{-1}',$texexp); - $texexp = str_replace('\mbox{acsc}','\mbox{csc}^{-1}',$texexp); - $texexp = str_replace('\mbox{acot}','\mbox{cot}^{-1}',$texexp); - $texexp = str_replace('\mbox{acosh}','\mbox{cosh}^{-1}',$texexp); - $texexp = str_replace('\mbox{asinh}','\mbox{sinh}^{-1}',$texexp); - $texexp = str_replace('\mbox{atanh}','\mbox{tanh}^{-1}',$texexp); - $texexp = str_replace('\mbox{asech}','\mbox{sech}^{-1}',$texexp); - $texexp = str_replace('\mbox{acsch}','\mbox{csch}^{-1}',$texexp); - $texexp = str_replace('\mbox{acoth}','\mbox{coth}^{-1}',$texexp); - //$texexp = preg_replace('/\\\frac{(.+?)}{\\\left\((.+?)\\\right\)}/s','\frac{'."\$1}{\$2}",$texexp); - $texexp = preg_replace('/\\\sqrt{(.+?),(.+?)}/s','\sqrt['. "\$2]{\$1}",$texexp); - $texexp = preg_replace('/\\\mbox{abs}\\\left\((.+?)\\\right\)/s',"|\$1|",$texexp); - $texexp = preg_replace('/\\\log\\\left\((.+?),(.+?)\\\right\)/s','\log_{'. "\$2}\\left(\$1\\right)",$texexp); - $texexp = preg_replace('/(\\\cos|\\\sin|\\\tan|\\\sec|\\\csc|\\\cot)([h]*)\\\left\((.+?),(.+?)\\\right\)/s',"\$1\$2^{". "\$4}\\left(\$3\\right)",$texexp); - $texexp = preg_replace('/\\\int\\\left\((.+?),(.+?),(.+?)\\\right\)/s','\int_'. "{\$2}^{\$3}\$1 ",$texexp); - $texexp = preg_replace('/\\\int\\\left\((.+?d[a-z])\\\right\)/s','\int '. "\$1 ",$texexp); - $texexp = preg_replace('/\\\lim\\\left\((.+?),(.+?),(.+?)\\\right\)/s','\lim_'. "{\$2\\to \$3}\$1 ",$texexp); - $texcache->filter = 'algebra'; - $texcache->version = 1; - $texcache->md5key = $md5; - $texcache->rawtext = $texexp; - $texcache->timemodified = time(); - $DB->insert_record("cache_filters",$texcache, false); - $text = str_replace( $matches[0][$i], string_file_picture_algebra($filename, $texexp, '', '', $align), $text); - } else { - $text = str_replace( $matches[0][$i],"Undetermined error: ",$text); - } - } else { - $text = str_replace( $matches[0][$i], string_file_picture_algebra($filename, $texcache->rawtext), $text); + preg_match_all('/(.+?)<\/algebra>|@@(.+?)@@/is', $text, $matches); + for ($i=0; $i','',$algebra); + $algebra = str_replace('','',$algebra); + $algebra = str_replace('','',$algebra); + $algebra = str_replace('','',$algebra); + $align = "middle"; + if (preg_match('/^align=bottom /',$algebra)) { + $align = "text-bottom"; + $algebra = preg_replace('/^align=bottom /','',$algebra); + } else if (preg_match('/^align=top /',$algebra)) { + $align = "text-top"; + $algebra = preg_replace('/^align=top /','',$algebra); + } + $md5 = md5($algebra); + $filename = $md5 . ".gif"; + if (! $texcache = $DB->get_record("cache_filters",array("filter"=>"algebra", "md5key"=>$md5))) { + $algebra = str_replace('<','<',$algebra); + $algebra = str_replace('>','>',$algebra); + $algebra = str_replace('<>','#',$algebra); + $algebra = str_replace('<=','%',$algebra); + $algebra = str_replace('>=','!',$algebra); + $algebra = preg_replace('/([=><%!#] *)-/',"\$1 zeroplace -",$algebra); + $algebra = str_replace('delta','zdelta',$algebra); + $algebra = str_replace('beta','bita',$algebra); + $algebra = str_replace('theta','thita',$algebra); + $algebra = str_replace('zeta','zita',$algebra); + $algebra = str_replace('eta','xeta',$algebra); + $algebra = str_replace('epsilon','zepslon',$algebra); + $algebra = str_replace('upsilon','zupslon',$algebra); + $algebra = preg_replace('!\r\n?!',' ',$algebra); + $algebra = escapeshellarg($algebra); + if ( (PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows") ) { + $cmd = "cd $CFG->dirroot\\filter\\algebra & algebra2tex.pl $algebra"; + } else { + $cmd = "cd $CFG->dirroot/filter/algebra; ./algebra2tex.pl $algebra"; + } + $texexp = `$cmd`; + if (preg_match('/parsehilight/',$texexp)) { + $text = str_replace( $matches[0][$i],"Syntax error: " . $texexp,$text); + } else if ($texexp) { + $texexp = str_replace('zeroplace','',$texexp); + $texexp = str_replace('#','\not= ',$texexp); + $texexp = str_replace('%','\leq ',$texexp); + $texexp = str_replace('!','\geq ',$texexp); + $texexp = str_replace('\left{','{',$texexp); + $texexp = str_replace('\right}','}',$texexp); + $texexp = str_replace('\fun',' ',$texexp); + $texexp = str_replace('infty','\infty',$texexp); + $texexp = str_replace('alpha','\alpha',$texexp); + $texexp = str_replace('gamma','\gamma',$texexp); + $texexp = str_replace('iota','\iota',$texexp); + $texexp = str_replace('kappa','\kappa',$texexp); + $texexp = str_replace('lambda','\lambda',$texexp); + $texexp = str_replace('mu','\mu',$texexp); + $texexp = str_replace('nu','\nu',$texexp); + $texexp = str_replace('xi','\xi',$texexp); + $texexp = str_replace('rho','\rho',$texexp); + $texexp = str_replace('sigma','\sigma',$texexp); + $texexp = str_replace('tau','\tau',$texexp); + $texexp = str_replace('phi','\phi',$texexp); + $texexp = str_replace('chi','\chi',$texexp); + $texexp = str_replace('psi','\psi',$texexp); + $texexp = str_replace('omega','\omega',$texexp); + $texexp = str_replace('zdelta','\delta',$texexp); + $texexp = str_replace('bita','\beta',$texexp); + $texexp = str_replace('thita','\theta',$texexp); + $texexp = str_replace('zita','\zeta',$texexp); + $texexp = str_replace('xeta','\eta',$texexp); + $texexp = str_replace('zepslon','\epsilon',$texexp); + $texexp = str_replace('zupslon','\upsilon',$texexp); + $texexp = str_replace('\mbox{logten}','\mbox{log}_{10}',$texexp); + $texexp = str_replace('\mbox{acos}','\mbox{cos}^{-1}',$texexp); + $texexp = str_replace('\mbox{asin}','\mbox{sin}^{-1}',$texexp); + $texexp = str_replace('\mbox{atan}','\mbox{tan}^{-1}',$texexp); + $texexp = str_replace('\mbox{asec}','\mbox{sec}^{-1}',$texexp); + $texexp = str_replace('\mbox{acsc}','\mbox{csc}^{-1}',$texexp); + $texexp = str_replace('\mbox{acot}','\mbox{cot}^{-1}',$texexp); + $texexp = str_replace('\mbox{acosh}','\mbox{cosh}^{-1}',$texexp); + $texexp = str_replace('\mbox{asinh}','\mbox{sinh}^{-1}',$texexp); + $texexp = str_replace('\mbox{atanh}','\mbox{tanh}^{-1}',$texexp); + $texexp = str_replace('\mbox{asech}','\mbox{sech}^{-1}',$texexp); + $texexp = str_replace('\mbox{acsch}','\mbox{csch}^{-1}',$texexp); + $texexp = str_replace('\mbox{acoth}','\mbox{coth}^{-1}',$texexp); + //$texexp = preg_replace('/\\\frac{(.+?)}{\\\left\((.+?)\\\right\)}/s','\frac{'."\$1}{\$2}",$texexp); + $texexp = preg_replace('/\\\sqrt{(.+?),(.+?)}/s','\sqrt['. "\$2]{\$1}",$texexp); + $texexp = preg_replace('/\\\mbox{abs}\\\left\((.+?)\\\right\)/s',"|\$1|",$texexp); + $texexp = preg_replace('/\\\log\\\left\((.+?),(.+?)\\\right\)/s','\log_{'. "\$2}\\left(\$1\\right)",$texexp); + $texexp = preg_replace('/(\\\cos|\\\sin|\\\tan|\\\sec|\\\csc|\\\cot)([h]*)\\\left\((.+?),(.+?)\\\right\)/s',"\$1\$2^{". "\$4}\\left(\$3\\right)",$texexp); + $texexp = preg_replace('/\\\int\\\left\((.+?),(.+?),(.+?)\\\right\)/s','\int_'. "{\$2}^{\$3}\$1 ",$texexp); + $texexp = preg_replace('/\\\int\\\left\((.+?d[a-z])\\\right\)/s','\int '. "\$1 ",$texexp); + $texexp = preg_replace('/\\\lim\\\left\((.+?),(.+?),(.+?)\\\right\)/s','\lim_'. "{\$2\\to \$3}\$1 ",$texexp); + $texcache->filter = 'algebra'; + $texcache->version = 1; + $texcache->md5key = $md5; + $texcache->rawtext = $texexp; + $texcache->timemodified = time(); + $DB->insert_record("cache_filters", $texcache, false); + $text = str_replace( $matches[0][$i], string_file_picture_algebra($filename, $texexp, '', '', $align), $text); + } else { + $text = str_replace( $matches[0][$i],"Undetermined error: ",$text); + } + } else { + $text = str_replace( $matches[0][$i], string_file_picture_algebra($filename, $texcache->rawtext), $text); + } } + return $text; } - return $text; } ?> diff --git a/filter/censor/filter.php b/filter/censor/filter.php index 1c244225a5..db06e151cf 100644 --- a/filter/censor/filter.php +++ b/filter/censor/filter.php @@ -9,37 +9,57 @@ // ////////////////////////////////////////////////////////////// -/// This is the filtering function itself. It accepts the -/// courseid and the text to be filtered (in HTML form). - -function censor_filter($courseid, $text) { - - static $words; - global $CFG; - - if (!isset($CFG->filter_censor_badwords)) { - set_config( 'filter_censor_badwords','' ); +/// 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); } - - if (empty($words)) { - $words = array(); - // if no user-specified words, use default list from language pack - if (empty($CFG->filter_censor_badwords)) { - $badwords = explode(',',get_string('badwords','censor') ); - } - else { - $badwords = explode(',', $CFG->filter_censor_badwords ); + private function _canseecensor() { + $cansee = false; + $context = get_context_instance(CONTEXT_SYSTEM, SITEID); + if (has_capability('moodle/site:doanything', $context)) { + $cansee = true; } - foreach ($badwords as $badword) { - $badword = trim($badword); - // See MDL-3964 for explanation of leaving the badword in the span title - $words[] = new filterobject($badword, '', '', - false, false, str_pad('',strlen($badword),'*')); + return $cansee; + } + function hash(){ + $cap = "mod/filter:censor"; + $context = get_context_instance(CONTEXT_SYSTEM, SITEID); + if (has_capability('moodle/site:doanything', $context)) { + $cap = "mod/filter:seecensor"; } + return $cap; } + function filter($text){ + static $words; + global $CFG; - return filter_phrases($text, $words); // Look for all these words in the text -} + if (!isset($CFG->filter_censor_badwords)) { + set_config( 'filter_censor_badwords','' ); + } + if (empty($words)) { + $words = array(); + if (empty($CFG->filter_censor_badwords)) { + $badwords = explode(',',get_string('badwords','censor')); + } + else { + $badwords = explode(',', $CFG->filter_censor_badwords); + } + foreach ($badwords as $badword) { + $badword = trim($badword); + if($this->_canseecensor()){ + $words[] = new filterobject($badword, '', '', + false, false, $badword); + } else { + $words[] = new filterobject($badword, '', + '', false, false, str_pad('',strlen($badword),'*')); + } + } + } + return filter_phrases($text, $words); + } +} ?> diff --git a/filter/emailprotect/filter.php b/filter/emailprotect/filter.php index 9e706c52e5..02b1f4e5fe 100644 --- a/filter/emailprotect/filter.php +++ b/filter/emailprotect/filter.php @@ -1,43 +1,44 @@ formatstring)) { - return $text; +class emailprotect_filter extends filter_base { + function __construct($courseid, $format, $options) { + parent::__construct($courseid, $format, $options); } - -/// Do a quick check using stripos to avoid unnecessary work - if (strpos($text, '@') === false) { + function filter($text) { + if (!empty($CFG->formatstring)) { + return $text; + } + + /// Do a quick check using stripos to avoid unnecessary work + if (strpos($text, '@') === false) { + return $text; + } + + /// There might be an email in here somewhere so continue ... + $matches = array(); + + /// regular expression to define a standard email string. + $emailregex = '((?:[\w\.\-])+\@(?:(?:[a-zA-Z\d\-])+\.)+(?:[a-zA-Z\d]{2,4}))'; + + /// pattern to find a mailto link with the linked text. + $pattern = '|()'.'(.*)'.'()|iU'; + $text = preg_replace_callback($pattern, 'alter_mailto', $text); + + /// pattern to find any other email address in the text. + $pattern = '/(^|\s+|>)'.$emailregex.'($|\s+|\.\s+|\.$|<)/i'; + $text = preg_replace_callback($pattern, 'alter_email', $text); + return $text; } - -/// There might be an email in here somewhere so continue ... - $matches = array(); - -/// regular expression to define a standard email string. - $emailregex = '((?:[\w\.\-])+\@(?:(?:[a-zA-Z\d\-])+\.)+(?:[a-zA-Z\d]{2,4}))'; - -/// pattern to find a mailto link with the linked text. - $pattern = '|()'.'(.*)'.'()|iU'; - $text = preg_replace_callback($pattern, 'alter_mailto', $text); - -/// pattern to find any other email address in the text. - $pattern = '/(^|\s+|>)'.$emailregex.'($|\s+|\.\s+|\.$|<)/i'; - $text = preg_replace_callback($pattern, 'alter_email', $text); - - return $text; } - function alter_email($matches) { return $matches[1].obfuscate_text($matches[2]).$matches[3]; } - function alter_mailto($matches) { return obfuscate_mailto($matches[2], $matches[4]); } diff --git a/filter/mediaplugin/filter.php b/filter/mediaplugin/filter.php index 29e4b15619..161068c440 100644 --- a/filter/mediaplugin/filter.php +++ b/filter/mediaplugin/filter.php @@ -17,93 +17,98 @@ require_once($CFG->libdir.'/filelib.php'); - -function mediaplugin_filter($courseid, $text) { - global $CFG; - static $eolas_fix_applied = false; - - // You should never modify parameters passed to a method or function, it's BAD practice. Create a copy instead. - // The reason is that you must always be able to refer to the original parameter that was passed. - // For this reason, I changed $text = preg_replace(..,..,$text) into $newtext = preg.... (NICOLAS CONNAULT) - // Thanks to Pablo Etcheverry for pointing this out! MDL-10177 - - // We're using the UFO technique for flash to attain XHTML Strict 1.0 - // See: http://www.bobbyvandersluis.com/ufo/ - if (!is_string($text)) { - // non string data can not be filtered anyway - return $text; - } - $newtext = $text; // fullclone is slow and not needed here - - if (!empty($CFG->filter_mediaplugin_enable_mp3)) { - $search = '/]*>.*?<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_mp3_callback', $newtext); - } - - if (!empty($CFG->filter_mediaplugin_enable_swf)) { - $search = '/]*>.*?<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_swf_callback', $newtext); - } - - if (!empty($CFG->filter_mediaplugin_enable_flv)) { - $search = '/]*>.*?<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_flv_callback', $newtext); - } - - if (!empty($CFG->filter_mediaplugin_enable_mov)) { - $search = '/]*>.*?<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_qt_callback', $newtext); - } - - if (!empty($CFG->filter_mediaplugin_enable_wmv)) { - $search = '/]*>.*?<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_wmp_callback', $newtext); - } - - if (!empty($CFG->filter_mediaplugin_enable_mpg)) { - $search = '/]*>.*?<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_qt_callback', $newtext); +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; } - - if (!empty($CFG->filter_mediaplugin_enable_avi)) { - $search = '/]*>.*?<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_wmp_callback', $newtext); - } - - if (!empty($CFG->filter_mediaplugin_enable_ram)) { - $search = '/]*>.*?<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); - } - - if (!empty($CFG->filter_mediaplugin_enable_rpm)) { - $search = '/]*>.*?<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); - } - - if (!empty($CFG->filter_mediaplugin_enable_rm)) { - $search = '/]*>.*?<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); + function filter($text) { + global $CFG; + // You should never modify parameters passed to a method or function, it's BAD practice. Create a copy instead. + // The reason is that you must always be able to refer to the original parameter that was passed. + // For this reason, I changed $text = preg_replace(..,..,$text) into $newtext = preg.... (NICOLAS CONNAULT) + // Thanks to Pablo Etcheverry for pointing this out! MDL-10177 + + // We're using the UFO technique for flash to attain XHTML Strict 1.0 + // See: http://www.bobbyvandersluis.com/ufo/ + if (!is_string($text)) { + // non string data can not be filtered anyway + return $text; + } + $newtext = $text; // fullclone is slow and not needed here + + if ($CFG->filter_mediaplugin_enable_mp3) { + $search = '/]*>.*?<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_mp3_callback', $newtext); + } + + if ($CFG->filter_mediaplugin_enable_swf) { + $search = '/]*>.*?<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_swf_callback', $newtext); + } + + if ($CFG->filter_mediaplugin_enable_flv) { + $search = '/]*>.*?<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_flv_callback', $newtext); + } + + if ($CFG->filter_mediaplugin_enable_mov) { + $search = '/]*>.*?<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_qt_callback', $newtext); + } + + if ($CFG->filter_mediaplugin_enable_wmv) { + $search = '/]*>.*?<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_wmp_callback', $newtext); + } + + if ($CFG->filter_mediaplugin_enable_mpg) { + $search = '/]*>.*?<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_qt_callback', $newtext); + } + + if ($CFG->filter_mediaplugin_enable_avi) { + $search = '/]*>.*?<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_wmp_callback', $newtext); + } + + if ($CFG->filter_mediaplugin_enable_ram) { + $search = '/]*>.*?<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); + } + + if ($CFG->filter_mediaplugin_enable_rpm) { + $search = '/]*>.*?<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); + } + + if ($CFG->filter_mediaplugin_enable_rm) { + $search = '/]*>.*?<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); + } + + if (!empty($CFG->filter_mediaplugin_enable_youtube)) { + $search = '/]*>(.*?)<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_youtube_callback', $newtext); + + $search = '/]*>(.*?)<\/a>/is'; + $newtext = preg_replace_callback($search, 'mediaplugin_filter_youtube_callback', $newtext); + } + + if (empty($newtext) or $newtext === $text) { + // error or not filtered + unset($newtext); + return $text; + } + + if (!$this->eolas_fix_applied) { + $newtext .= ''; + $this->eolas_fix_applied = true; + } + + return $newtext; } - - if (!empty($CFG->filter_mediaplugin_enable_youtube)) { - $search = '/]*>(.*?)<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_youtube_callback', $newtext); - - $search = '/]*>(.*?)<\/a>/is'; - $newtext = preg_replace_callback($search, 'mediaplugin_filter_youtube_callback', $newtext); - } - - if (is_null($newtext) or $newtext === $text) { - // error or not filtered - return $text; - } - - if (!$eolas_fix_applied) { - $newtext .= ''; - $eolas_fix_applied = true; - } - - return $newtext; } ///=========================== diff --git a/filter/multilang/filter.php b/filter/multilang/filter.php index 7da88d6a50..2f5eb0c0c8 100644 --- a/filter/multilang/filter.php +++ b/filter/multilang/filter.php @@ -36,32 +36,38 @@ // Following new syntax is not compatible with old one: // one langanother language -function multilang_filter($courseid, $text) { - global $CFG; +class multilang_filter extends filter_base { + function __construct($courseid, $format, $options) { + parent::__construct($courseid, $format, $options); + } - // [pj] I don't know about you but I find this new implementation funny :P - // [skodak] I was laughing while rewriting it ;-) - // [nicolasconnault] Should support inverted attributes: (Doesn't work curently) - // [skodak] it supports it now, though it is slower - any better idea? + function filter($text) { + global $CFG; - if (empty($text) or is_numeric($text)) { - return $text; - } + // [pj] I don't know about you but I find this new implementation funny :P + // [skodak] I was laughing while rewriting it ;-) + // [nicolasconnault] Should support inverted attributes: (Doesn't work curently) + // [skodak] it supports it now, though it is slower - any better idea? - if (empty($CFG->filter_multilang_force_old) and !empty($CFG->filter_multilang_converted)) { - // new syntax - $search = '/(.*?<\/span>)(\s*.*?<\/span>)+/is'; - } else { - // old syntax - $search = '/(<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.*?<\/(?:lang|span)>)(\s*<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.*?<\/(?:lang|span)>)+/is'; - } + if (empty($text) or is_numeric($text)) { + return $text; + } - $result = preg_replace_callback($search, 'multilang_filter_impl', $text); + if (empty($CFG->filter_multilang_force_old) and !empty($CFG->filter_multilang_converted)) { + // new syntax + $search = '/(.*?<\/span>)(\s*.*?<\/span>)+/is'; + } else { + // old syntax + $search = '/(<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.*?<\/(?:lang|span)>)(\s*<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.*?<\/(?:lang|span)>)+/is'; + } - if (is_null($result)) { - return $text; //error during regex processing (too many nested spans?) - } else { - return $result; + $result = preg_replace_callback($search, 'multilang_filter_impl', $text); + + if (is_null($result)) { + return $text; //error during regex processing (too many nested spans?) + } else { + return $result; + } } } diff --git a/filter/tex/filter.php b/filter/tex/filter.php index ba74ca349b..e02e906bd6 100644 --- a/filter/tex/filter.php +++ b/filter/tex/filter.php @@ -91,13 +91,18 @@ function string_file_picture_tex($imagefile, $tex= "", $height="", $width="", $a return $output; } -function tex_filter ($courseid, $text) { - global $CFG, $DB; - - /// Do a quick check using stripos to avoid unnecessary work - if (!preg_match('/forum != 130) { # return $text; # } - $text .= ' '; - preg_match_all('/\$(\$\$+?)([^\$])/s',$text,$matches); - for ($i=0;$i TeX expression - // or TeX expression - // or $$ TeX expression $$ - // or \[ TeX expression \] // original tag of MathType and TeXaide (dlnsk) - // or [tex] TeX expression [/tex] // somtime it's more comfortable than (dlnsk) - preg_match_all('/(.+?)<\/tex>|\$\$(.+?)\$\$|\\\\\[(.+?)\\\\\]|\\[tex\\](.+?)\\[\/tex\\]/is', $text, $matches); - for ($i=0; $i','',$texexp); - $texexp = str_replace('','',$texexp); - $texexp = str_replace('','',$texexp); - $texexp = str_replace('','',$texexp); - $texexp = eregi_replace("", '', $texexp); //dlnsk - $align = "middle"; - if (preg_match('/^align=bottom /',$texexp)) { - $align = "text-bottom"; - $texexp = preg_replace('/^align=bottom /','',$texexp); - } else if (preg_match('/^align=top /',$texexp)) { - $align = "text-top"; - $texexp = preg_replace('/^align=top /','',$texexp); + $text .= ' '; + preg_match_all('/\$(\$\$+?)([^\$])/s',$text,$matches); + for ($i=0;$iget_record("cache_filters", array("filter"=>"tex", "md5key"=>$md5))) { - $texcache->filter = 'tex'; - $texcache->version = 1; - $texcache->md5key = $md5; - $texcache->rawtext = $texexp; - $texcache->timemodified = time(); - $DB->insert_record("cache_filters",$texcache, false); + + // TeX expression + // or TeX expression + // or $$ TeX expression $$ + // or \[ TeX expression \] // original tag of MathType and TeXaide (dlnsk) + // or [tex] TeX expression [/tex] // somtime it's more comfortable than (dlnsk) + preg_match_all('/(.+?)<\/tex>|\$\$(.+?)\$\$|\\\\\[(.+?)\\\\\]|\\[tex\\](.+?)\\[\/tex\\]/is', $text, $matches); + for ($i=0; $i','',$texexp); + $texexp = str_replace('','',$texexp); + $texexp = str_replace('','',$texexp); + $texexp = str_replace('','',$texexp); + $texexp = eregi_replace("", '', $texexp); //dlnsk + $align = "middle"; + if (preg_match('/^align=bottom /',$texexp)) { + $align = "text-bottom"; + $texexp = preg_replace('/^align=bottom /','',$texexp); + } else if (preg_match('/^align=top /',$texexp)) { + $align = "text-top"; + $texexp = preg_replace('/^align=top /','',$texexp); + } + $md5 = md5($texexp); + if (! $texcache = $DB->get_record("cache_filters", array("filter"=>"tex", "md5key"=>$md5))) { + $texcache->filter = 'tex'; + $texcache->version = 1; + $texcache->md5key = $md5; + $texcache->rawtext = $texexp; + $texcache->timemodified = time(); + $DB->insert_record("cache_filters", $texcache, false); + } + $filename = $md5 . ".gif"; + $text = str_replace( $matches[0][$i], string_file_picture_tex($filename, $texexp, '', '', $align, $alt), $text); } - $filename = $md5 . ".gif"; - $text = str_replace( $matches[0][$i], string_file_picture_tex($filename, $texexp, '', '', $align, $alt), $text); + return $text; } - return $text; } ?> diff --git a/filter/tidy/filter.php b/filter/tidy/filter.php index c12778f8d4..bb6893d669 100644 --- a/filter/tidy/filter.php +++ b/filter/tidy/filter.php @@ -1,6 +1,6 @@ -* @param int course id -* @param string text to be filtered -*/ -function tidy_filter($courseid, $text) { - -/// Configuration for tidy. Feel free to tune for your needs, e.g. to allow -/// proprietary markup. - $tidyoptions = array( - 'output-xhtml' => true, - 'show-body-only' => true, - 'tidy-mark' => false, - 'drop-proprietary-attributes' => true, - 'drop-font-tags' => true, - 'drop-empty-paras' => true, - 'indent' => true, - 'quiet' => true, - ); - -/// Do a quick check using strpos to avoid unnecessary work - if (strpos($text, '<') === false) { - return $text; +class tidy_filter extends filter_base { + function __construct($courseid, $format, $options) { + parent::__construct($courseid, $format, $options); } - -/// If enabled: run tidy over the entire string - if (function_exists('tidy_repair_string')){ - $text = tidy_repair_string($text, $tidyoptions, 'utf8'); - } + /** + * @author Hannes Gassert + * @param string text to be filtered + */ + function filter($text) { + + /// Configuration for tidy. Feel free to tune for your needs, e.g. to allow + /// proprietary markup. + $tidyoptions = array( + 'output-xhtml' => true, + 'show-body-only' => true, + 'tidy-mark' => false, + 'drop-proprietary-attributes' => true, + 'drop-font-tags' => true, + 'drop-empty-paras' => true, + 'indent' => true, + 'quiet' => true, + ); + + /// Do a quick check using strpos to avoid unnecessary work + if (strpos($text, '<') === false) { + return $text; + } + + + /// If enabled: run tidy over the entire string + if (function_exists('tidy_repair_string')){ + $text = tidy_repair_string($text, $tidyoptions, 'utf8'); + } - return $text; + return $text; + } } ?> diff --git a/lib/filterlib.php b/lib/filterlib.php index 94c410c2c9..7227180ac2 100644 --- a/lib/filterlib.php +++ b/lib/filterlib.php @@ -1,6 +1,55 @@ courseid = $courseid; + $this->format = $format; + $this->options = $options; + } + + public static function addfilter($classname, $obj) { + if (empty(self::$filters[$classname])) { + self::$filters[$classname] = $obj; + return true; + } else { + return false; + } + } + + public static function do_filter($text, $courseid = null) { + global $CFG; + + foreach (self::$filters as $n=>$obj) { + $text = $obj->filter($text); + } + + // back compatable with old filter plugins + $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); + } + } + } + return $text; + } + + public function hash() { + return __CLASS__; + } + + // filter plugin must overwrite this function to filter + abstract function filter($text); +} /** * This is just a little object to define a phrase and some instructions diff --git a/lib/weblib.php b/lib/weblib.php index 5e45d088ae..7b5c7c0e86 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -1,6 +1,5 @@ newlines)) { $options->newlines=true; } - if (empty($courseid)) { $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 (!empty($CFG->cachetext) and empty($options->nocache)) { - $time = time() - $CFG->cachetext; - $md5key = md5($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); + $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(); + $time = time() - $CFG->cachetext; + $md5key = md5($hashstr); if (defined('FULLME') and FULLME == 'cron') { if (isset($croncache[$md5key])) { return $croncache[$md5key]; @@ -1438,7 +1458,7 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL $text = clean_text($text, FORMAT_HTML); } if ($options->filter) { - $text = filter_text($text, $courseid); + $text = filter_base::do_filter($text, $courseid); } break; @@ -1467,7 +1487,7 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL } if ($options->filter) { - $text = filter_text($text, $courseid); + $text = filter_base::do_filter($text, $courseid); } break; @@ -1478,7 +1498,7 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL } if ($options->filter) { - $text = filter_text($text, $courseid); + $text = filter_base::do_filter($text, $courseid); } break; } -- 2.39.5