yui MDL-24146 Removed 3.1.1
[moodle.git] / filter / mediaplugin / filter.php
CommitLineData
4317f92f 1<?php
35716b86
PS
2
3// This file is part of Moodle - http://moodle.org/
6de17fde 4//
35716b86
PS
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.
6de17fde 9//
35716b86
PS
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.
6de17fde 14//
35716b86
PS
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 * Media plugin filtering
20 *
21 * This filter will replace any links to a media file with
22 * a media plugin that plays that media inline
23 *
24 * @package filter
25 * @subpackage mediaplugin
26 * @copyright 2004 onwards Martin Dougiamas {@link http://moodle.com}
27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28 */
6de17fde 29
35716b86 30defined('MOODLE_INTERNAL') || die();
6de17fde 31
7e64d361 32require_once($CFG->libdir.'/filelib.php');
33
35716b86 34class filter_mediaplugin extends moodle_text_filter {
ccc161f8 35 private $eolas_fix_applied = false;
9e3f34d1 36 function filter($text) {
82afb587 37 global $CFG, $PAGE;
9e3f34d1 38 // You should never modify parameters passed to a method or function, it's BAD practice. Create a copy instead.
39 // The reason is that you must always be able to refer to the original parameter that was passed.
40 // For this reason, I changed $text = preg_replace(..,..,$text) into $newtext = preg.... (NICOLAS CONNAULT)
41 // Thanks to Pablo Etcheverry for pointing this out! MDL-10177
42
43 // We're using the UFO technique for flash to attain XHTML Strict 1.0
44 // See: http://www.bobbyvandersluis.com/ufo/
45 if (!is_string($text)) {
46 // non string data can not be filtered anyway
47 return $text;
48 }
49 $newtext = $text; // fullclone is slow and not needed here
50
51 if ($CFG->filter_mediaplugin_enable_mp3) {
52 $search = '/<a.*?href="([^<]+\.mp3)"[^>]*>.*?<\/a>/is';
35716b86 53 $newtext = preg_replace_callback($search, 'filter_mediaplugin_mp3_callback', $newtext);
9e3f34d1 54 }
55
56 if ($CFG->filter_mediaplugin_enable_swf) {
57 $search = '/<a.*?href="([^<]+\.swf)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 58 $newtext = preg_replace_callback($search, 'filter_mediaplugin_swf_callback', $newtext);
9e3f34d1 59 }
60
61 if ($CFG->filter_mediaplugin_enable_flv) {
62 $search = '/<a.*?href="([^<]+\.flv)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 63 $newtext = preg_replace_callback($search, 'filter_mediaplugin_flv_callback', $newtext);
9e3f34d1 64 }
65
66 if ($CFG->filter_mediaplugin_enable_mov) {
67 $search = '/<a.*?href="([^<]+\.mov)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 68 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext);
46936592 69
70 $search = '/<a.*?href="([^<]+\.mp4)(\?d=([\d]{1,4}%?)x([\d]{1,4}%?))?"[^>]*>.*?<\/a>/is';
35716b86 71 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext);
46936592 72
73 $search = '/<a.*?href="([^<]+\.m4v)(\?d=([\d]{1,4}%?)x([\d]{1,4}%?))?"[^>]*>.*?<\/a>/is';
35716b86 74 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext);
a184479a 75
76 $search = '/<a.*?href="([^<]+\.m4a)(\?d=([\d]{1,4}%?)x([\d]{1,4}%?))?"[^>]*>.*?<\/a>/is';
35716b86 77 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext);
9e3f34d1 78 }
79
80 if ($CFG->filter_mediaplugin_enable_wmv) {
81 $search = '/<a.*?href="([^<]+\.wmv)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 82 $newtext = preg_replace_callback($search, 'filter_mediaplugin_wmp_callback', $newtext);
9e3f34d1 83 }
84
85 if ($CFG->filter_mediaplugin_enable_mpg) {
86 $search = '/<a.*?href="([^<]+\.mpe?g)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 87 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext);
9e3f34d1 88 }
89
90 if ($CFG->filter_mediaplugin_enable_avi) {
91 $search = '/<a.*?href="([^<]+\.avi)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 92 $newtext = preg_replace_callback($search, 'filter_mediaplugin_wmp_callback', $newtext);
9e3f34d1 93 }
94
95 if ($CFG->filter_mediaplugin_enable_ram) {
96 $search = '/<a.*?href="([^<]+\.ram)"[^>]*>.*?<\/a>/is';
35716b86 97 $newtext = preg_replace_callback($search, 'filter_mediaplugin_real_callback', $newtext);
9e3f34d1 98 }
99
100 if ($CFG->filter_mediaplugin_enable_rpm) {
101 $search = '/<a.*?href="([^<]+\.rpm)"[^>]*>.*?<\/a>/is';
35716b86 102 $newtext = preg_replace_callback($search, 'filter_mediaplugin_real_callback', $newtext);
9e3f34d1 103 }
104
105 if ($CFG->filter_mediaplugin_enable_rm) {
106 $search = '/<a.*?href="([^<]+\.rm)"[^>]*>.*?<\/a>/is';
35716b86 107 $newtext = preg_replace_callback($search, 'filter_mediaplugin_real_callback', $newtext);
9e3f34d1 108 }
109
110 if (!empty($CFG->filter_mediaplugin_enable_youtube)) {
4842422f
AD
111 //see MDL-23903 for description of recent changes to this regex
112 //$search = '/<a.*?href="([^<]*)youtube.com\/watch\?v=([^"]*)"[^>]*>(.*?)<\/a>/is';
113 $search = '/<a[^>]*href="([^<]*?)youtube.com\/watch\?v=([^"]*)"[^>]*>(.*?)<\/a>/is';
35716b86 114 $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_callback', $newtext);
9e3f34d1 115
116 $search = '/<a.*?href="([^<]*)youtube.com\/v\/([^"]*)"[^>]*>(.*?)<\/a>/is';
35716b86 117 $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_callback', $newtext);
9e3f34d1 118 }
119
224eccbf 120 if (!empty($CFG->filter_mediaplugin_enable_img)) {
c159f28b 121 $search = '/<a.*?href="([^<]+\.jpg)"[^>]*>(.*?)<\/a>/is';
35716b86 122 $newtext = preg_replace_callback($search, 'filter_mediaplugin_img_callback', $newtext);
c159f28b 123 $search = '/<a.*?href="([^<]+\.png)"[^>]*>(.*?)<\/a>/is';
35716b86 124 $newtext = preg_replace_callback($search, 'filter_mediaplugin_img_callback', $newtext);
c159f28b 125 $search = '/<a.*?href="([^<]+\.gif)"[^>]*>(.*?)<\/a>/is';
35716b86 126 $newtext = preg_replace_callback($search, 'filter_mediaplugin_img_callback', $newtext);
c159f28b 127 }
128
9e3f34d1 129 if (empty($newtext) or $newtext === $text) {
130 // error or not filtered
131 unset($newtext);
132 return $text;
133 }
134
135 if (!$this->eolas_fix_applied) {
9dec75db 136 $PAGE->requires->js('/filter/mediaplugin/eolas_fix.js');
9e3f34d1 137 $this->eolas_fix_applied = true;
138 }
139
140 return $newtext;
d07851e1 141 }
6de17fde 142}
143
7e64d361 144///===========================
145/// callback filter functions
146
35716b86 147function filter_mediaplugin_mp3_callback($link) {
088ccb43
PS
148 global $CFG, $OUTPUT, $PAGE;
149
150 $c = $OUTPUT->filter_mediaplugin_colors(); // You can set this up in your theme/xxx/config.php
7e64d361 151
152 static $count = 0;
153 $count++;
154 $id = 'filter_mp3_'.time().$count; //we need something unique because it might be stored in text cache
155
156 $url = addslashes_js($link[1]);
157
82afb587 158 $args = Array();
159 $args['movie'] = $CFG->wwwroot.'/filter/mediaplugin/mp3player.swf?src='.$url;
160 $args['width'] = 90;
161 $args['height'] = 15;
162 $args['majorversion'] = 6;
163 $args['build'] = 40;
164 $args['flashvars'] = $c;
165 $args['quality'] = 'high';
4d49202f 166
10eaeca8 167 $jsoutput = create_ufo_inline($id, $args);
82afb587 168
a845d68b 169 $output = $link[0].'<span class="mediaplugin mediaplugin_mp3" id="'.$id.'">('.get_string('mp3audio', 'filter_mediaplugin').')</span>'.$jsoutput;
82afb587 170
171 return $output;
7e64d361 172}
173
35716b86 174function filter_mediaplugin_swf_callback($link) {
82afb587 175 global $PAGE;
7e64d361 176 static $count = 0;
177 $count++;
178 $id = 'filter_swf_'.time().$count; //we need something unique because it might be stored in text cache
179
180 $width = empty($link[3]) ? '400' : $link[3];
181 $height = empty($link[4]) ? '300' : $link[4];
182 $url = addslashes_js($link[1]);
183
82afb587 184 $args = Array();
185 $args['movie'] = $url;
186 $args['width'] = $width;
187 $args['height'] = $height;
188 $args['majorversion'] = 6;
189 $args['build'] = 40;
190 $args['allowscriptaccess'] = 'never';
191 $args['quality'] = 'high';
82afb587 192
10eaeca8 193 $jsoutput = create_ufo_inline($id, $args);
35716b86 194
a845d68b 195 $output = $link[0].'<span class="mediaplugin mediaplugin_swf" id="'.$id.'">('.get_string('flashanimation', 'filter_mediaplugin').')</span>'.$jsoutput;
82afb587 196
197 return $output;
7e64d361 198}
199
35716b86 200function filter_mediaplugin_flv_callback($link) {
82afb587 201 global $CFG, $PAGE;
7e64d361 202
203 static $count = 0;
204 $count++;
205 $id = 'filter_flv_'.time().$count; //we need something unique because it might be stored in text cache
206
207 $width = empty($link[3]) ? '480' : $link[3];
208 $height = empty($link[4]) ? '360' : $link[4];
209 $url = addslashes_js($link[1]);
210
82afb587 211 $args = Array();
212 $args['movie'] = $CFG->wwwroot.'/filter/mediaplugin/flvplayer.swf?file='.$url;
213 $args['width'] = $width;
214 $args['height'] = $height;
215 $args['majorversion'] = 6;
216 $args['build'] = 40;
217 $args['allowscriptaccess'] = 'never';
218 $args['quality'] = 'high';
219 $args['allowfullscreen'] = 'true';
10eaeca8 220 $jsoutput = create_ufo_inline($id, $args);
82afb587 221
a845d68b 222 $output = $link[0].'<span class="mediaplugin mediaplugin_flv" id="'.$id.'">('.get_string('flashvideo', 'filter_mediaplugin').')</span>'.$jsoutput;
82afb587 223
224 return $output;
7e64d361 225}
226
35716b86 227function filter_mediaplugin_real_callback($link, $autostart=false) {
7e64d361 228 $url = addslashes_js($link[1]);
229 $mimetype = mimeinfo('type', $url);
230 $autostart = $autostart ? 'true' : 'false';
231
232// embed kept for now see MDL-8674
233 return $link[0].
234'<span class="mediaplugin mediaplugin_real">
235<script type="text/javascript">
236//<![CDATA[
237document.write(\'<object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="240" height="180">\\
238 <param name="src" value="'.$url.'" />\\
239 <param name="autostart" value="'.$autostart.'" />\\
240 <param name="controls" value="imagewindow" />\\
241 <param name="console" value="video" />\\
242 <param name="loop" value="true" />\\
7c59f3be 243 <embed src="'.$url.'" width="240" height="180" loop="true" type="'.$mimetype.'" controls="imagewindow" console="video" autostart="'.$autostart.'" />\\
7e64d361 244 </object><br />\\
245 <object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="240" height="30">\\
246 <param name="src" value="'.$url.'" />\\
247 <param name="autostart" value="'.$autostart.'" />\\
248 <param name="controls" value="ControlPanel" />\\
249 <param name="console" value="video" />\\
250 <embed src="'.$url.'" width="240" height="30" controls="ControlPanel" type="'.$mimetype.'" console="video" autostart="'.$autostart.'" />\\
251 </object>\');
252//]]>
253</script></span>';
254}
255
4d8bccf4 256/**
257 * Change links to Youtube into embedded Youtube videos
258 */
35716b86 259function filter_mediaplugin_youtube_callback($link, $autostart=false) {
4d8bccf4 260
261 $site = addslashes_js($link[1]);
262 $url = addslashes_js($link[2]);
4842422f 263 $info = addslashes_js(strip_tags($link[3]));//strip out html tags as they won't work in the title attribute
4d8bccf4 264
4317f92f
PS
265 return '<object title="'.$info.'"
266 class="mediaplugin mediaplugin_youtube" type="application/x-shockwave-flash"
4d8bccf4 267 data="'.$site.'youtube.com/v/'.$url.'&amp;fs=1&amp;rel=0" width="425" height="344">'.
6188deb8 268 '<param name="movie" value="'.$site.'youtube.com/v/'.$url.'&amp;fs=1&amp;rel=0" />'.
4d8bccf4 269 '<param name="FlashVars" value="playerMode=embedded" />'.
270 '<param name="wmode" value="transparent" />'.
271 '<param name="allowFullScreen" value="true" />'.
e2cf2d7f 272 '</object>';
4d8bccf4 273}
274
c159f28b 275/**
276 * Change links to images into embedded images
277 */
35716b86 278function filter_mediaplugin_img_callback($link, $autostart=false) {
c159f28b 279 $url = addslashes_js($link[1]);
280 $info = addslashes_js($link[2]);
281
282 return '<img class="mediaplugin mediaplugin_img" alt="" title="'.$info.'" src="'.$url.'" />';
283}
284
7e64d361 285/**
286 * Embed video using window media player if available
287 */
35716b86 288function filter_mediaplugin_wmp_callback($link, $autostart=false) {
7e64d361 289 $url = $link[1];
290 if (empty($link[3]) or empty($link[4])) {
291 $mpsize = '';
292 $size = 'width="300" height="260"';
293 $autosize = 'true';
294 } else {
295 $size = 'width="'.$link[3].'" height="'.$link[4].'"';
296 $mpsize = $size;
297 $autosize = 'false';
298 }
299 $mimetype = mimeinfo('type', $url);
300 $autostart = $autostart ? 'true' : 'false';
301
302 return $link[0].
303'<span class="mediaplugin mediaplugin_wmp">
304<object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" '.$mpsize.'
305 standby="Loading Microsoft(R) Windows(R) Media Player components..."
306 type="application/x-oleobject">
307 <param name="Filename" value="'.$url.'" />
308 <param name="src" value="'.$url.'" />
309 <param name="url" value="'.$url.'" />
310 <param name="ShowControls" value="true" />
311 <param name="AutoRewind" value="true" />
312 <param name="AutoStart" value="'.$autostart.'" />
313 <param name="Autosize" value="'.$autosize.'" />
314 <param name="EnableContextMenu" value="true" />
315 <param name="TransparentAtStart" value="false" />
316 <param name="AnimationAtStart" value="false" />
317 <param name="ShowGotoBar" value="false" />
318 <param name="EnableFullScreenControls" value="true" />
319<!--[if !IE]>-->
320 <object data="'.$url.'" type="'.$mimetype.'" '.$size.'>
321 <param name="src" value="'.$url.'" />
322 <param name="controller" value="true" />
323 <param name="autoplay" value="'.$autostart.'" />
324 <param name="autostart" value="'.$autostart.'" />
325 <param name="resize" value="scale" />
326 </object>
327<!--<![endif]-->
328</object></span>';
329}
330
35716b86 331function filter_mediaplugin_qt_callback($link, $autostart=false) {
7e64d361 332 $url = $link[1];
333 if (empty($link[3]) or empty($link[4])) {
1387d5eb 334 $size = 'width="440" height="315"';
7e64d361 335 } else {
336 $size = 'width="'.$link[3].'" height="'.$link[4].'"';
337 }
338 $mimetype = mimeinfo('type', $url);
339 $autostart = $autostart ? 'true' : 'false';
340
341 return $link[0].
342'<span class="mediaplugin mediaplugin_qt">
343<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
344 codebase="http://www.apple.com/qtactivex/qtplugin.cab" '.$size.'>
345 <param name="pluginspage" value="http://www.apple.com/quicktime/download/" />
346 <param name="src" value="'.$url.'" />
d42df9da 347 <param name="controller" value="true" />
7e64d361 348 <param name="loop" value="true" />
349 <param name="autoplay" value="'.$autostart.'" />
350 <param name="autostart" value="'.$autostart.'" />
351 <param name="scale" value="aspect" />
352<!--[if !IE]>-->
353 <object data="'.$url.'" type="'.$mimetype.'" '.$size.'>
354 <param name="src" value="'.$url.'" />
355 <param name="pluginurl" value="http://www.apple.com/quicktime/download/" />
356 <param name="controller" value="true" />
357 <param name="loop" value="true" />
358 <param name="autoplay" value="'.$autostart.'" />
359 <param name="autostart" value="'.$autostart.'" />
360 <param name="scale" value="aspect" />
361 </object>
362<!--<![endif]-->
363</object></span>';
364}
6de17fde 365
4317f92f 366