MDL-26030 update filter regex and create unittest for filter mediaplugin
[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;
dcfffe30 36 function filter($text, array $options = array()) {
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
8e7fecd9 51 if (!empty($CFG->filter_mediaplugin_enable_mp3)) {
3f5192c0 52 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.mp3)"[^>]*>.*?<\/a>/is';
35716b86 53 $newtext = preg_replace_callback($search, 'filter_mediaplugin_mp3_callback', $newtext);
9e3f34d1 54 }
55
8e7fecd9 56 if (!empty($CFG->filter_mediaplugin_enable_ogg)) {
3f5192c0 57 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.ogg)"[^>]*>.*?<\/a>/is';
ce5dc36e
RW
58 $newtext = preg_replace_callback($search, 'filter_mediaplugin_ogg_callback', $newtext);
59 }
60
8e7fecd9 61 if (!empty($CFG->filter_mediaplugin_enable_ogv)) {
3f5192c0 62 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.ogv)"[^>]*>.*?<\/a>/is';
ce5dc36e
RW
63 $newtext = preg_replace_callback($search, 'filter_mediaplugin_ogv_callback', $newtext);
64 }
8e7fecd9
PS
65
66 if (!empty($CFG->filter_mediaplugin_enable_swf)) {
3f5192c0 67 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.swf)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 68 $newtext = preg_replace_callback($search, 'filter_mediaplugin_swf_callback', $newtext);
9e3f34d1 69 }
70
8e7fecd9 71 if (!empty($CFG->filter_mediaplugin_enable_flv)) {
3f5192c0 72 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.flv)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 73 $newtext = preg_replace_callback($search, 'filter_mediaplugin_flv_callback', $newtext);
9e3f34d1 74 }
75
8e7fecd9 76 if (!empty($CFG->filter_mediaplugin_enable_mov)) {
3f5192c0 77 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.mov)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 78 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext);
46936592 79
3f5192c0 80 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.mp4)(\?d=([\d]{1,4}%?)x([\d]{1,4}%?))?"[^>]*>.*?<\/a>/is';
35716b86 81 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext);
46936592 82
3f5192c0 83 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.m4v)(\?d=([\d]{1,4}%?)x([\d]{1,4}%?))?"[^>]*>.*?<\/a>/is';
35716b86 84 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext);
a184479a 85
3f5192c0 86 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.m4a)(\?d=([\d]{1,4}%?)x([\d]{1,4}%?))?"[^>]*>.*?<\/a>/is';
35716b86 87 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext);
9e3f34d1 88 }
89
8e7fecd9 90 if (!empty($CFG->filter_mediaplugin_enable_wmv)) {
3f5192c0 91 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.wmv)(\?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
8e7fecd9 95 if (!empty($CFG->filter_mediaplugin_enable_mpg)) {
3f5192c0 96 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.mpe?g)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 97 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext);
9e3f34d1 98 }
99
8e7fecd9 100 if (!empty($CFG->filter_mediaplugin_enable_avi)) {
3f5192c0 101 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.avi)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is';
35716b86 102 $newtext = preg_replace_callback($search, 'filter_mediaplugin_wmp_callback', $newtext);
9e3f34d1 103 }
104
8e7fecd9 105 if (!empty($CFG->filter_mediaplugin_enable_ram)) {
3f5192c0 106 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.ram)"[^>]*>.*?<\/a>/is';
35716b86 107 $newtext = preg_replace_callback($search, 'filter_mediaplugin_real_callback', $newtext);
9e3f34d1 108 }
109
8e7fecd9 110 if (!empty($CFG->filter_mediaplugin_enable_rpm)) {
3f5192c0 111 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.rpm)"[^>]*>.*?<\/a>/is';
35716b86 112 $newtext = preg_replace_callback($search, 'filter_mediaplugin_real_callback', $newtext);
9e3f34d1 113 }
114
8e7fecd9 115 if (!empty($CFG->filter_mediaplugin_enable_rm)) {
3f5192c0 116 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.rm)"[^>]*>.*?<\/a>/is';
35716b86 117 $newtext = preg_replace_callback($search, 'filter_mediaplugin_real_callback', $newtext);
9e3f34d1 118 }
119
120 if (!empty($CFG->filter_mediaplugin_enable_youtube)) {
4842422f
AD
121 //see MDL-23903 for description of recent changes to this regex
122 //$search = '/<a.*?href="([^<]*)youtube.com\/watch\?v=([^"]*)"[^>]*>(.*?)<\/a>/is';
3f5192c0 123 $search = '/<a(\s+[^>]+?)?\s+href="(([^"]+youtube\.com)\/watch\?v=([^"]*))"[^>]*>(.*?)<\/a>/is';
35716b86 124 $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_callback', $newtext);
9e3f34d1 125
3f5192c0 126 $search = '/<a(\s+[^>]+?)?\s+href="(([^"]+youtube\.com)\/v\/([^"]*))"[^>]*>(.*?)<\/a>/is';
35716b86 127 $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_callback', $newtext);
469aa3ba
RW
128
129 $search = '/<a(\s+[^>]+?)?\s+href="((([^"]+)youtube\.com)\/view_play_list\?p=([^"]*))"[^>]*>(.*?)<\/a>/is';
130 $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_playlist_callback', $newtext);
9e3f34d1 131 }
132
224eccbf 133 if (!empty($CFG->filter_mediaplugin_enable_img)) {
3f5192c0 134 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.jpg)"[^>]*>.*?<\/a>/is';
35716b86 135 $newtext = preg_replace_callback($search, 'filter_mediaplugin_img_callback', $newtext);
3f5192c0
RW
136
137 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.png)"[^>]*>.*?<\/a>/is';
35716b86 138 $newtext = preg_replace_callback($search, 'filter_mediaplugin_img_callback', $newtext);
3f5192c0
RW
139
140 $search = '/<a(\s+[^>]+?)?\s+href="([^"]+\.gif)"[^>]*>.*?<\/a>/is';
35716b86 141 $newtext = preg_replace_callback($search, 'filter_mediaplugin_img_callback', $newtext);
c159f28b 142 }
143
9e3f34d1 144 if (empty($newtext) or $newtext === $text) {
145 // error or not filtered
146 unset($newtext);
147 return $text;
148 }
149
150 if (!$this->eolas_fix_applied) {
9dec75db 151 $PAGE->requires->js('/filter/mediaplugin/eolas_fix.js');
9e3f34d1 152 $this->eolas_fix_applied = true;
153 }
154
155 return $newtext;
d07851e1 156 }
6de17fde 157}
158
7e64d361 159///===========================
160/// callback filter functions
161
35716b86 162function filter_mediaplugin_mp3_callback($link) {
088ccb43
PS
163 global $CFG, $OUTPUT, $PAGE;
164
165 $c = $OUTPUT->filter_mediaplugin_colors(); // You can set this up in your theme/xxx/config.php
7e64d361 166
167 static $count = 0;
168 $count++;
169 $id = 'filter_mp3_'.time().$count; //we need something unique because it might be stored in text cache
170
3f5192c0 171 $url = $link[2];
7e64d361 172
3a42ad12
RW
173 $playerpath = $CFG->wwwroot.'/filter/mediaplugin/mp3player.swf';
174 $audioplayerpath = $CFG->wwwroot .'/filter/mediaplugin/flowplayer.audio.swf';
175 $colors = explode('&', $c);
176 $playercolors = array();
177 foreach ($colors as $color) {
178 $color = explode('=', $color);
179 $playercolors[$color[0]] = $color[1];
180 }
82afb587 181
3a42ad12
RW
182 $output = <<<OET
183 <span class="mediaplugin mediaplugin_mp3" id="$id"></span>
388d1c02 184 <noscript><div>
3a42ad12
RW
185 <object width="100" height="15" id="nonjsmp3plugin" name="undefined" data="$playerpath" type="application/x-shockwave-flash">
186 <param name="movie" value="$playerpath" />
187 <param name="allowfullscreen" value="false" />
188 <param name="allowscriptaccess" value="always" />
189 <param name="flashvars" value='config={"plugins": {"controls": {
190 "fullscreen": false,
191 "height": 15,
192 "autoHide": false,
193 "all": false,
194 "play": true,
195 "pause": true,
196 "scrubber": true
197 },
198 "audio": {"url": "$audioplayerpath"}
199 },
200 "clip":{"url":"$url",
201 "autoPlay": false},
202 "content":{"url":"$playerpath"}}}' />
4d4d20e7
PS
203 </object>
204 </div></noscript>
3a42ad12
RW
205OET;
206
207 $jsoutput = create_flowplayer($id, $url, 'mp3', $playercolors);
208 $output .= $jsoutput;
82afb587 209
210 return $output;
7e64d361 211}
212
ce5dc36e
RW
213function filter_mediaplugin_ogg_callback($link) {
214 global $CFG, $OUTPUT, $PAGE;
215
216 static $count = 0;
217 $count++;
218 $id = 'filter_ogg_'.time().$count; //we need something unique because it might be stored in text cache
219
3f5192c0 220 $url = $link[2];
ce5dc36e
RW
221 $printlink = html_writer::link($url, get_string('oggaudio', 'filter_mediaplugin'));
222 $unsupportedplugins = get_string('unsupportedplugins', 'filter_mediaplugin', $printlink);
223 $output = <<<OET
224 <audio id="$id" src="$url" controls="true" width="100">
8e7fecd9 225 $unsupportedplugins
ce5dc36e
RW
226 </audio>
227OET;
8e7fecd9 228
ce5dc36e
RW
229 return $output;
230}
231
232function filter_mediaplugin_ogv_callback($link) {
233 global $CFG, $OUTPUT, $PAGE;
234
235 static $count = 0;
236 $count++;
237 $id = 'filter_ogv_'.time().$count; //we need something unique because it might be stored in text cache
238
3f5192c0 239 $url = $link[2];
ce5dc36e
RW
240 $printlink = html_writer::link($url, get_string('ogvvideo', 'filter_mediaplugin'));
241 $unsupportedplugins = get_string('unsupportedplugins', 'filter_mediaplugin', $printlink);
242 $output = <<<OET
243 <video id="$id" src="$url" controls="true" width="600" >
8e7fecd9 244 $unsupportedplugins
ce5dc36e
RW
245 </video>
246OET;
247
248 return $output;
249}
250
35716b86 251function filter_mediaplugin_swf_callback($link) {
82afb587 252 global $PAGE;
7e64d361 253 static $count = 0;
254 $count++;
255 $id = 'filter_swf_'.time().$count; //we need something unique because it might be stored in text cache
256
3f5192c0
RW
257 $width = empty($link[4]) ? '400' : $link[4];
258 $height = empty($link[5]) ? '300' : $link[5];
259 $url = $link[2];
7e64d361 260
82afb587 261 $args = Array();
262 $args['movie'] = $url;
263 $args['width'] = $width;
264 $args['height'] = $height;
265 $args['majorversion'] = 6;
266 $args['build'] = 40;
267 $args['allowscriptaccess'] = 'never';
268 $args['quality'] = 'high';
82afb587 269
10eaeca8 270 $jsoutput = create_ufo_inline($id, $args);
35716b86 271
a845d68b 272 $output = $link[0].'<span class="mediaplugin mediaplugin_swf" id="'.$id.'">('.get_string('flashanimation', 'filter_mediaplugin').')</span>'.$jsoutput;
82afb587 273
274 return $output;
7e64d361 275}
276
35716b86 277function filter_mediaplugin_flv_callback($link) {
82afb587 278 global $CFG, $PAGE;
7e64d361 279
280 static $count = 0;
281 $count++;
282 $id = 'filter_flv_'.time().$count; //we need something unique because it might be stored in text cache
283
3f5192c0
RW
284 $width = empty($link[4]) ? '480' : $link[4];
285 $height = empty($link[5]) ? '360' : $link[5];
286 $url = $link[2];
7e64d361 287
3a42ad12
RW
288 $playerpath = $CFG->wwwroot.'/filter/mediaplugin/flvplayer.swf';
289
290 $output = <<<EOT
291 <span class="mediaplugin mediaplugin_flv" id="$id"></span>
388d1c02 292 <noscript><div>
3a42ad12
RW
293 <object width="800" height="600" id="undefined" name="undefined" data="$playerpath" type="application/x-shockwave-flash">
294 <param name="movie" value="$playerpath" />
295 <param name="allowfullscreen" value="true" />
296 <param name="allowscriptaccess" value="always" />
297 <param name="flashvars" value='config={"clip":{"url":"$url",
298 "autoPlay": false},
299 "content":{"url":"$playerpath"}}}' />
4d4d20e7
PS
300 </object>
301 </div></noscript>
3a42ad12
RW
302EOT;
303
304 $jsoutput = create_flowplayer($id, $url, 'flv');
305 $output .= $jsoutput;
82afb587 306 return $output;
7e64d361 307}
308
35716b86 309function filter_mediaplugin_real_callback($link, $autostart=false) {
3f5192c0
RW
310 $url = $link[2];
311 $jsurl = addslashes_js($link[2]);
7e64d361 312 $mimetype = mimeinfo('type', $url);
313 $autostart = $autostart ? 'true' : 'false';
314
315// embed kept for now see MDL-8674
316 return $link[0].
317'<span class="mediaplugin mediaplugin_real">
318<script type="text/javascript">
319//<![CDATA[
320document.write(\'<object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="240" height="180">\\
3f5192c0 321 <param name="src" value="'.$jsurl.'" />\\
7e64d361 322 <param name="autostart" value="'.$autostart.'" />\\
323 <param name="controls" value="imagewindow" />\\
324 <param name="console" value="video" />\\
325 <param name="loop" value="true" />\\
3f5192c0 326 <embed src="'.$jsurl.'" width="240" height="180" loop="true" type="'.$mimetype.'" controls="imagewindow" console="video" autostart="'.$autostart.'" />\\
7e64d361 327 </object><br />\\
328 <object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="240" height="30">\\
3f5192c0 329 <param name="src" value="'.$jsurl.'" />\\
7e64d361 330 <param name="autostart" value="'.$autostart.'" />\\
331 <param name="controls" value="ControlPanel" />\\
332 <param name="console" value="video" />\\
3f5192c0 333 <embed src="'.$jsurl.'" width="240" height="30" controls="ControlPanel" type="'.$mimetype.'" console="video" autostart="'.$autostart.'" />\\
7e64d361 334 </object>\');
335//]]>
336</script></span>';
337}
338
4d8bccf4 339/**
340 * Change links to Youtube into embedded Youtube videos
341 */
35716b86 342function filter_mediaplugin_youtube_callback($link, $autostart=false) {
3f5192c0
RW
343 $site = s($link[3]);
344 $param = urlencode($link[4]);
345 $info = s($link[5]);
4d8bccf4 346
4d8bccf4 347
4317f92f
PS
348 return '<object title="'.$info.'"
349 class="mediaplugin mediaplugin_youtube" type="application/x-shockwave-flash"
3f5192c0
RW
350 data="'.$site.'/v/'.$param.'&amp;fs=1&amp;rel=0" width="400" height="320">'.
351 '<param name="movie" value="'.$site.'/v/'.$param.'&amp;fs=1&amp;rel=0" />'.
4d8bccf4 352 '<param name="FlashVars" value="playerMode=embedded" />'.
353 '<param name="wmode" value="transparent" />'.
354 '<param name="allowFullScreen" value="true" />'.
e2cf2d7f 355 '</object>';
4d8bccf4 356}
357
469aa3ba
RW
358/**
359 * Change Youtube playlist into embedded Youtube playlist videos
360 */
361function filter_mediaplugin_youtube_playlist_callback($link, $autostart=false) {
362
363 $site = s($link[4]);
364 $param = s($link[5]);
365 $info = s($link[6]);
366
367 return '<object title="'.$info.'"
368 class="mediaplugin mediaplugin_youtube" type="application/x-shockwave-flash"
369 data="'.$site.'youtube.com/p/'.$param.'&amp;fs=1&amp;rel=0" width="400" height="320">'.
370 '<param name="movie" value="'.$site.'youtube.com/p/'.$param.'&amp;fs=1&amp;rel=0" />'.
371 '<param name="FlashVars" value="playerMode=embedded" />'.
372 '<param name="wmode" value="transparent" />'.
373 '<param name="allowFullScreen" value="true" />'.
374 '</object>';
375}
376
c159f28b 377/**
378 * Change links to images into embedded images
379 */
35716b86 380function filter_mediaplugin_img_callback($link, $autostart=false) {
3f5192c0
RW
381 $url = $link[2];
382 $info = s($link[2]);
c159f28b 383 return '<img class="mediaplugin mediaplugin_img" alt="" title="'.$info.'" src="'.$url.'" />';
384}
385
7e64d361 386/**
387 * Embed video using window media player if available
388 */
35716b86 389function filter_mediaplugin_wmp_callback($link, $autostart=false) {
3f5192c0
RW
390 $url = $link[2];
391 if (empty($link[4]) or empty($link[5])) {
7e64d361 392 $mpsize = '';
393 $size = 'width="300" height="260"';
394 $autosize = 'true';
395 } else {
3f5192c0 396 $size = 'width="'.$link[4].'" height="'.$link[5].'"';
7e64d361 397 $mpsize = $size;
398 $autosize = 'false';
399 }
400 $mimetype = mimeinfo('type', $url);
401 $autostart = $autostart ? 'true' : 'false';
402
403 return $link[0].
404'<span class="mediaplugin mediaplugin_wmp">
405<object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" '.$mpsize.'
406 standby="Loading Microsoft(R) Windows(R) Media Player components..."
407 type="application/x-oleobject">
408 <param name="Filename" value="'.$url.'" />
409 <param name="src" value="'.$url.'" />
410 <param name="url" value="'.$url.'" />
411 <param name="ShowControls" value="true" />
412 <param name="AutoRewind" value="true" />
413 <param name="AutoStart" value="'.$autostart.'" />
414 <param name="Autosize" value="'.$autosize.'" />
415 <param name="EnableContextMenu" value="true" />
416 <param name="TransparentAtStart" value="false" />
417 <param name="AnimationAtStart" value="false" />
418 <param name="ShowGotoBar" value="false" />
419 <param name="EnableFullScreenControls" value="true" />
420<!--[if !IE]>-->
421 <object data="'.$url.'" type="'.$mimetype.'" '.$size.'>
422 <param name="src" value="'.$url.'" />
423 <param name="controller" value="true" />
424 <param name="autoplay" value="'.$autostart.'" />
425 <param name="autostart" value="'.$autostart.'" />
426 <param name="resize" value="scale" />
427 </object>
428<!--<![endif]-->
429</object></span>';
430}
431
35716b86 432function filter_mediaplugin_qt_callback($link, $autostart=false) {
3f5192c0
RW
433 $url = $link[2];
434 if (empty($link[4]) or empty($link[5])) {
1387d5eb 435 $size = 'width="440" height="315"';
7e64d361 436 } else {
3f5192c0 437 $size = 'width="'.$link[4].'" height="'.$link[5].'"';
7e64d361 438 }
439 $mimetype = mimeinfo('type', $url);
440 $autostart = $autostart ? 'true' : 'false';
441
442 return $link[0].
443'<span class="mediaplugin mediaplugin_qt">
444<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
445 codebase="http://www.apple.com/qtactivex/qtplugin.cab" '.$size.'>
446 <param name="pluginspage" value="http://www.apple.com/quicktime/download/" />
447 <param name="src" value="'.$url.'" />
d42df9da 448 <param name="controller" value="true" />
7e64d361 449 <param name="loop" value="true" />
450 <param name="autoplay" value="'.$autostart.'" />
451 <param name="autostart" value="'.$autostart.'" />
452 <param name="scale" value="aspect" />
453<!--[if !IE]>-->
454 <object data="'.$url.'" type="'.$mimetype.'" '.$size.'>
455 <param name="src" value="'.$url.'" />
456 <param name="pluginurl" value="http://www.apple.com/quicktime/download/" />
457 <param name="controller" value="true" />
458 <param name="loop" value="true" />
459 <param name="autoplay" value="'.$autostart.'" />
460 <param name="autostart" value="'.$autostart.'" />
461 <param name="scale" value="aspect" />
462 </object>
463<!--<![endif]-->
464</object></span>';
465}
6de17fde 466
4317f92f 467