MDL-38298 Take out harcoded dependency + tests.
[moodle.git] / filter / emoticon / filter.php
CommitLineData
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
31defined('MOODLE_INTERNAL') || die();
32
33class 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}