Commit | Line | Data |
---|---|---|
015ba71a DM |
1 | <?php |
2 | ||
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/>. | |
17 | ||
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 | */ | |
30 | ||
31 | defined('MOODLE_INTERNAL') || die(); | |
32 | ||
33 | class filter_emoticon extends moodle_text_filter { | |
34 | ||
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; | |
42 | ||
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()) { | |
52 | ||
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 | } | |
64 | ||
65 | //////////////////////////////////////////////////////////////////////////// | |
66 | // internal implementation starts here | |
67 | //////////////////////////////////////////////////////////////////////////// | |
68 | ||
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; | |
83 | ||
84 | } elseif (array_key_exists($name, self::$globalconfig)) { | |
85 | return self::$globalconfig->{$name}; | |
86 | ||
87 | } else { | |
88 | return null; | |
89 | } | |
90 | } | |
91 | ||
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)) { | |
045c0e4d | 99 | self::$globalconfig = get_config(get_class($this)); |
015ba71a DM |
100 | } |
101 | } | |
102 | ||
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 | |
113 | ||
114 | $lang = current_language(); | |
115 | $theme = $PAGE->theme->name; | |
116 | ||
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 | } | |
129 | ||
130 | if (empty($emoticontexts[$lang][$theme])) { // No emoticons defined, nothing to process here | |
131 | return; | |
132 | } | |
133 | ||
134 | // detect all the <script> zones to take out | |
135 | $excludes = array(); | |
136 | preg_match_all('/<script language(.+?)<\/script>/is', $text, $listofexcludes); | |
137 | ||
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 | } | |
145 | ||
146 | // this is the meat of the code - this is run every time | |
147 | $text = str_replace($emoticontexts[$lang][$theme], $emoticonimgs[$lang][$theme], $text); | |
148 | ||
149 | // Recover all the <script> zones to text | |
150 | if ($excludes) { | |
151 | $text = str_replace(array_keys($excludes), $excludes, $text); | |
152 | } | |
153 | } | |
154 | } |