MDL-30070 message: Optimised search for users over multiple courses
[moodle.git] / filter / emoticon / filter.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * Filter converting emoticon texts into images
20  *
21  * This filter uses the emoticon settings in Site admin > Appearance > HTML settings
22  * and replaces emoticon texts with images.
23  *
24  * @package    filter
25  * @subpackage emoticon
26  * @see        emoticon_manager
27  * @copyright  2010 David Mudrak <david@moodle.com>
28  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29  */
31 defined('MOODLE_INTERNAL') || die();
33 class filter_emoticon extends moodle_text_filter {
35     /**
36      * @var array global configuration for this filter
37      *
38      * This might be eventually moved into parent class if we found it
39      * useful for other filters, too.
40      */
41     protected static $globalconfig;
43     /**
44      * Apply the filter to the text
45      *
46      * @see filter_manager::apply_filter_chain()
47      * @param string $text to be processed by the text
48      * @param array $options filter options
49      * @return string text after processing
50      */
51     public function filter($text, array $options = array()) {
53         if (!isset($options['originalformat'])) {
54             // if the format is not specified, we are probably called by {@see format_string()}
55             // in that case, it would be dangerous to replace text with the image because it could
56             // be stripped. therefore, we do nothing
57             return $text;
58         }
59         if (in_array($options['originalformat'], explode(',', $this->get_global_config('formats')))) {
60             $this->replace_emoticons($text);
61         }
62         return $text;
63     }
65     ////////////////////////////////////////////////////////////////////////////
66     // internal implementation starts here
67     ////////////////////////////////////////////////////////////////////////////
69     /**
70      * Returns the global filter setting
71      *
72      * If the $name is provided, returns single value. Otherwise returns all
73      * global settings in object. Returns null if the named setting is not
74      * found.
75      *
76      * @param mixed $name optional config variable name, defaults to null for all
77      * @return string|object|null
78      */
79     protected function get_global_config($name=null) {
80         $this->load_global_config();
81         if (is_null($name)) {
82             return self::$globalconfig;
84         } elseif (array_key_exists($name, self::$globalconfig)) {
85             return self::$globalconfig->{$name};
87         } else {
88             return null;
89         }
90     }
92     /**
93      * Makes sure that the global config is loaded in $this->globalconfig
94      *
95      * @return void
96      */
97     protected function load_global_config() {
98         if (is_null(self::$globalconfig)) {
99             self::$globalconfig = get_config('filter_emoticon');
100         }
101     }
103     /**
104      * Replace emoticons found in the text with their images
105      *
106      * @param string $text to modify
107      * @return void
108      */
109     protected function replace_emoticons(&$text) {
110         global $CFG, $OUTPUT, $PAGE;
111         static $emoticontexts = array();    // internal cache used for replacing
112         static $emoticonimgs = array();     // internal cache used for replacing
114         $lang = current_language();
115         $theme = $PAGE->theme->name;
117         if (!isset($emoticontexts[$lang][$theme]) or !isset($emoticonimgs[$lang][$theme])) {
118             // prepare internal caches
119             $manager = get_emoticon_manager();
120             $emoticons = $manager->get_emoticons();
121             $emoticontexts[$lang][$theme] = array();
122             $emoticonimgs[$lang][$theme] = array();
123             foreach ($emoticons as $emoticon) {
124                 $emoticontexts[$lang][$theme][] = $emoticon->text;
125                 $emoticonimgs[$lang][$theme][] = $OUTPUT->render($manager->prepare_renderable_emoticon($emoticon));
126             }
127             unset($emoticons);
128         }
130         if (empty($emoticontexts[$lang][$theme])) { // No emoticons defined, nothing to process here
131             return;
132         }
134         // detect all the <script> zones to take out
135         $excludes = array();
136         preg_match_all('/<script language(.+?)<\/script>/is', $text, $listofexcludes);
138         // take out all the <script> zones from text
139         foreach (array_unique($listofexcludes[0]) as $key => $value) {
140             $excludes['<+'.$key.'+>'] = $value;
141         }
142         if ($excludes) {
143             $text = str_replace($excludes, array_keys($excludes), $text);
144         }
146         // this is the meat of the code - this is run every time
147         $text = str_replace($emoticontexts[$lang][$theme], $emoticonimgs[$lang][$theme], $text);
149         // Recover all the <script> zones to text
150         if ($excludes) {
151             $text = str_replace(array_keys($excludes), $excludes, $text);
152         }
153     }