|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00029 defined('MOODLE_INTERNAL') || die(); 00030 00031 require_once($CFG->libdir.'/filelib.php'); 00032 00033 if (!defined('FILTER_MEDIAPLUGIN_VIDEO_WIDTH')) { 00038 define('FILTER_MEDIAPLUGIN_VIDEO_WIDTH', 400); 00039 } 00040 00041 if (!defined('FILTER_MEDIAPLUGIN_VIDEO_HEIGHT')) { 00047 define('FILTER_MEDIAPLUGIN_VIDEO_HEIGHT', 300); 00048 } 00049 00050 00051 //TODO: we should use /u modifier in regex, unfortunately it may not work properly on some misconfigured servers, see lib/filter/urltolink/filter.php ... 00052 00053 //TODO: we should migrate to proper config_plugin settings ... 00054 00055 00067 class filter_mediaplugin extends moodle_text_filter { 00068 00069 function filter($text, array $options = array()) { 00070 global $CFG; 00071 00072 if (!is_string($text) or empty($text)) { 00073 // non string data can not be filtered anyway 00074 return $text; 00075 } 00076 if (stripos($text, '</a>') === false) { 00077 // performance shortcut - all regexes below end with the </a> tag, 00078 // if not present nothing can match 00079 return $text; 00080 } 00081 00082 $newtext = $text; // we need to return the original value if regex fails! 00083 00084 // YouTube and Vimeo are great because the files are not served by Moodle server 00085 00086 if (!empty($CFG->filter_mediaplugin_enable_youtube)) { 00087 $search = '/<a\s[^>]*href="(https?:\/\/www\.youtube(-nocookie)?\.com)\/watch\?v=([a-z0-9\-_]+)[^"#]*(#d=([\d]{1,4})x([\d]{1,4}))?"[^>]*>([^>]*)<\/a>/is'; 00088 $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_callback', $newtext); 00089 00090 $search = '/<a\s[^>]*href="(https?:\/\/www\.youtube(-nocookie)?\.com)\/v\/([a-z0-9\-_]+)[^"#]*(#d=([\d]{1,4})x([\d]{1,4}))?[^>]*>([^>]*)<\/a>/is'; 00091 $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_callback', $newtext); 00092 00093 $search = '/<a\s[^>]*href="(https?:\/\/www\.youtube(-nocookie)?\.com)\/view_play_list\?p=([a-z0-9\-_]+)[^"#]*(#d=([\d]{1,4})x([\d]{1,4}))?[^>]*>([^>]*)<\/a>/is'; 00094 $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_playlist_callback', $newtext); 00095 00096 $search = '/<a\s[^>]*href="(https?:\/\/www\.youtube(-nocookie)?\.com)\/p\/([a-z0-9\-_]+)[^"#]*(#d=([\d]{1,4})x([\d]{1,4}))?[^>]*>([^>]*)<\/a>/is'; 00097 $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_playlist_callback', $newtext); 00098 } 00099 00100 if (!empty($CFG->filter_mediaplugin_enable_vimeo)) { 00101 $search = '/<a\s[^>]*href="http:\/\/vimeo\.com\/([0-9]+)[^"#]*(#d=([\d]{1,4})x([\d]{1,4}))?[^>]*>([^>]*)<\/a>/is'; 00102 $newtext = preg_replace_callback($search, 'filter_mediaplugin_vimeo_callback', $newtext); 00103 } 00104 00105 00106 // HTML 5 audio and video tags are the future! If only if vendors decided to use just one audio and video format... 00107 00108 if (!empty($CFG->filter_mediaplugin_enable_html5audio)) { 00109 $search = '/<a\s[^>]*href="([^"#\?]+\.(ogg|oga|aac|m4a)([#\?][^"]*)?)"[^>]*>([^>]*)<\/a>/is'; 00110 $newtext = preg_replace_callback($search, 'filter_mediaplugin_html5audio_callback', $newtext); 00111 } 00112 00113 if (!empty($CFG->filter_mediaplugin_enable_html5video)) { 00114 $search = '/<a\s[^>]*href="([^"#\?]+\.(m4v|webm|ogv|mp4)([#\?][^"]*)?)"[^>]*>([^>]*)<\/a>/is'; 00115 $newtext = preg_replace_callback($search, 'filter_mediaplugin_html5video_callback', $newtext); 00116 } 00117 00118 00119 // Flash stuff 00120 00121 if (!empty($CFG->filter_mediaplugin_enable_mp3)) { 00122 $search = '/<a\s[^>]*href="([^"#\?]+\.mp3)"[^>]*>([^>]*)<\/a>/is'; 00123 $newtext = preg_replace_callback($search, 'filter_mediaplugin_mp3_callback', $newtext); 00124 } 00125 00126 if ((!empty($options['noclean']) or !empty($CFG->allowobjectembed)) and !empty($CFG->filter_mediaplugin_enable_swf)) { 00127 $search = '/<a\s[^>]*href="([^"#\?]+\.swf)([#\?]d=([\d]{1,4})x([\d]{1,4}))?"[^>]*>([^>]*)<\/a>/is'; 00128 $newtext = preg_replace_callback($search, 'filter_mediaplugin_swf_callback', $newtext); 00129 } 00130 00131 if (!empty($CFG->filter_mediaplugin_enable_flv)) { 00132 $search = '/<a\s[^>]*href="([^"#\?]+\.(flv|f4v)([#\?][^"]*)?)"[^>]*>([^>]*)<\/a>/is'; 00133 $newtext = preg_replace_callback($search, 'filter_mediaplugin_flv_callback', $newtext); 00134 } 00135 00136 00137 // The rest of legacy formats - these should not be used if possible 00138 00139 if (!empty($CFG->filter_mediaplugin_enable_wmp)) { 00140 $search = '/<a\s[^>]*href="([^"#\?]+\.(wmv|avi))(\?d=([\d]{1,4})x([\d]{1,4}))?"[^>]*>([^>]*)<\/a>/is'; 00141 $newtext = preg_replace_callback($search, 'filter_mediaplugin_wmp_callback', $newtext); 00142 } 00143 00144 if (!empty($CFG->filter_mediaplugin_enable_qt)) { 00145 // HTML5 filtering may steal mpeg 4 formats 00146 $search = '/<a\s[^>]*href="([^"#\?]+\.(mpg|mpeg|mov|mp4|m4v|m4a))(\?d=([\d]{1,4})x([\d]{1,4}))?"[^>]*>([^>]*)<\/a>/is'; 00147 $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext); 00148 } 00149 00150 if (!empty($CFG->filter_mediaplugin_enable_rm)) { 00151 // hopefully nobody is using this any more!! 00152 // rpm is redhat packaging format these days, it is better to prevent these in default installs 00153 00154 $search = '/<a\s[^>]*href="([^"#\?]+\.(ra|ram|rm|rv))"[^>]*>([^>]*)<\/a>/is'; 00155 $newtext = preg_replace_callback($search, 'filter_mediaplugin_real_callback', $newtext); 00156 } 00157 00158 00159 if (empty($newtext) or $newtext === $text) { 00160 // error or not filtered 00161 unset($newtext); 00162 return $text; 00163 } 00164 00165 00166 return $newtext; 00167 } 00168 } 00169 00170 00173 00181 function filter_mediaplugin_get_mimetype($url) { 00182 $matches = null; 00183 if (preg_match("|^(.*)/[a-z]*file.php(\?file=)?(/[^&\?#]*)|", $url, $matches)) { 00184 // remove the special moodle file serving hacks so that the *file.php is ignored 00185 $url = $matches[1].$matches[3]; 00186 } else { 00187 $url = preg_replace('/[#\?].*$/', '', $url); 00188 } 00189 00190 $mimetype = mimeinfo('type', $url); 00191 00192 return $mimetype; 00193 } 00194 00202 function filter_mediaplugin_parse_alternatives($url, $defaultwidth = 0, $defaultheight = 0) { 00203 $urls = explode('#', $url); 00204 $width = $defaultwidth; 00205 $height = $defaultheight; 00206 $returnurls = array(); 00207 00208 foreach ($urls as $url) { 00209 $matches = null; 00210 00211 if (preg_match('/^d=([\d]{1,4})x([\d]{1,4})$/i', $url, $matches)) { // #d=640x480 00212 $width = $matches[1]; 00213 $height = $matches[2]; 00214 continue; 00215 } 00216 if (preg_match('/\?d=([\d]{1,4})x([\d]{1,4})$/i', $url, $matches)) { // old style file.ext?d=640x480 00217 $width = $matches[1]; 00218 $height = $matches[2]; 00219 $url = str_replace($matches[0], '', $url); 00220 } 00221 00222 $url = str_replace('&', '&', $url); 00223 $url = clean_param($url, PARAM_URL); 00224 if (empty($url)) { 00225 continue; 00226 } 00227 00228 $returnurls[] = $url; 00229 } 00230 00231 return array($returnurls, $width, $height); 00232 } 00233 00239 function filter_mediaplugin_ignore($tag) { 00240 if (preg_match('/class="[^"]*nomediaplugin/i', $tag)) { 00241 return true; 00242 } else { 00243 false; 00244 } 00245 } 00246 00249 00250 00257 function filter_mediaplugin_html5audio_callback(array $link) { 00258 global $CFG; 00259 00260 if (filter_mediaplugin_ignore($link[0])) { 00261 return $link[0]; 00262 } 00263 00264 $info = trim($link[4]); 00265 if (empty($info) or strpos($info, 'http') === 0) { 00266 $info = get_string('fallbackaudio', 'filter_mediaplugin'); 00267 } 00268 00269 list($urls, $ignorewidth, $ignoredheight) = filter_mediaplugin_parse_alternatives($link[1]); 00270 00271 $fallbackurl = null; 00272 $fallbackmime = null; 00273 $sources = array(); 00274 $fallbacklink = null; 00275 00276 foreach ($urls as $url) { 00277 $mimetype = filter_mediaplugin_get_mimetype($url); 00278 if (strpos($mimetype, 'audio/') !== 0) { 00279 continue; 00280 } 00281 $sources[] = html_writer::tag('source', '', array('src' => $url, 'type' => $mimetype)); 00282 00283 if ($fallbacklink === null) { 00284 $fallbacklink = html_writer::link($url.'#', $info); // the extra '#' prevents linking in mp3 filter below 00285 } 00286 if ($fallbackurl === null) { 00287 if ($mimetype === 'audio/mp3' or $mimetype === 'audio/aac') { 00288 $fallbackurl = str_replace('&', '&', $url); 00289 $fallbackmime = $mimetype; 00290 } 00291 } 00292 } 00293 if (!$sources) { 00294 return $link[0]; 00295 } 00296 00297 if ($fallbackmime !== null) { 00298 // fallback to quicktime 00299 $fallback = <<<OET 00300 <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" width="200" height="20"> 00301 <param name="pluginspage" value="http://www.apple.com/quicktime/download/" /> 00302 <param name="src" value="$fallbackurl" /> 00303 <param name="controller" value="true" /> 00304 <param name="loop" value="false" /> 00305 <param name="autoplay" value="false" /> 00306 <param name="autostart" value="false" /> 00307 <param name="scale" value="aspect" /> 00308 $fallbacklink 00309 <!--[if !IE]>--> 00310 <object data="$fallbackurl" type="$fallbackmime" width="200" height="20"> 00311 <param name="src" value="$fallbackurl" /> 00312 <param name="pluginurl" value="http://www.apple.com/quicktime/download/" /> 00313 <param name="controller" value="true" /> 00314 <param name="loop" value="false" /> 00315 <param name="autoplay" value="false" /> 00316 <param name="autostart" value="false" /> 00317 <param name="scale" value="aspect" /> 00318 $fallbacklink 00319 </object> 00320 <!--<![endif]--> 00321 </object> 00322 OET; 00323 } else { 00324 $fallback = $fallbacklink; 00325 } 00326 00327 $sources = implode("\n", $sources); 00328 $title = s($info); 00329 00330 // audio players are supposed to be inline elements 00331 $output = <<<OET 00332 <audio controls="true" width="200" class="mediaplugin mediaplugin_html5audio" preload="no" title="$title"> 00333 $sources 00334 $fallback 00335 </audio> 00336 OET; 00337 00338 return $output; 00339 } 00340 00350 function filter_mediaplugin_html5video_callback(array $link) { 00351 00352 if (filter_mediaplugin_ignore($link[0])) { 00353 return $link[0]; 00354 } 00355 00356 $info = trim($link[4]); 00357 if (empty($info) or strpos($info, 'http') === 0) { 00358 $info = get_string('fallbackvideo', 'filter_mediaplugin'); 00359 } 00360 00361 list($urls, $width, $height) = filter_mediaplugin_parse_alternatives($link[1], FILTER_MEDIAPLUGIN_VIDEO_WIDTH, 0); 00362 00363 $fallbackurl = null; 00364 $fallbackmime = null; 00365 $sources = array(); 00366 $fallbacklink = null; 00367 00368 foreach ($urls as $url) { 00369 $mimetype = filter_mediaplugin_get_mimetype($url); 00370 if (strpos($mimetype, 'video/') !== 0) { 00371 continue; 00372 } 00373 $source = html_writer::tag('source', '', array('src' => $url, 'type' => $mimetype)); 00374 if ($mimetype === 'video/mp4') { 00375 // better add m4v as first source, it might be a bit more compatible with problematic browsers 00376 array_unshift($sources, $source); 00377 } else { 00378 $sources[] = $source; 00379 } 00380 00381 if ($fallbacklink === null) { 00382 $fallbacklink = html_writer::link($url.'#', $info); // the extra '#' prevents linking in mp3 filter below 00383 } 00384 if ($fallbackurl === null) { 00385 if ($mimetype === 'video/mp4') { 00386 $fallbackurl = str_replace('&', '&', $url); 00387 $fallbackmime = $mimetype; 00388 } 00389 } 00390 } 00391 if (!$sources) { 00392 return $link[0]; 00393 } 00394 00395 if ($fallbackmime !== null) { 00396 $qtheight = ($height == 0) ? FILTER_MEDIAPLUGIN_VIDEO_HEIGHT : ($height + 15); 00397 // fallback to quicktime 00398 $fallback = <<<OET 00399 <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" width="$width" height="$qtheight"> 00400 <param name="pluginspage" value="http://www.apple.com/quicktime/download/" /> 00401 <param name="src" value="$fallbackurl" /> 00402 <param name="controller" value="true" /> 00403 <param name="loop" value="false" /> 00404 <param name="autoplay" value="false" /> 00405 <param name="autostart" value="false" /> 00406 <param name="scale" value="aspect" /> 00407 $fallbacklink 00408 <!--[if !IE]>--> 00409 <object data="$fallbackurl" type="$fallbackmime" width="$width" height="$qtheight"> 00410 <param name="src" value="$fallbackurl" /> 00411 <param name="pluginurl" value="http://www.apple.com/quicktime/download/" /> 00412 <param name="controller" value="true" /> 00413 <param name="loop" value="false" /> 00414 <param name="autoplay" value="false" /> 00415 <param name="autostart" value="false" /> 00416 <param name="scale" value="aspect" /> 00417 $fallbacklink 00418 </object> 00419 <!--<![endif]--> 00420 </object> 00421 OET; 00422 } else { 00423 $fallback = $fallbacklink; 00424 } 00425 00426 $sources = implode("\n", $sources); 00427 $title = s($info); 00428 00429 if (empty($height)) { 00430 // automatic height 00431 $size = "width=\"$width\""; 00432 } else { 00433 $size = "width=\"$width\" height=\"$height\""; 00434 } 00435 00436 $output = <<<OET 00437 <span class="mediaplugin mediaplugin_html5video"> 00438 <video controls="true" $size preload="metadata" title="$title"> 00439 $sources 00440 $fallback 00441 </video> 00442 </span> 00443 OET; 00444 00445 return $output; 00446 } 00447 00454 function filter_mediaplugin_mp3_callback($link) { 00455 static $count = 0; 00456 00457 if (filter_mediaplugin_ignore($link[0])) { 00458 return $link[0]; 00459 } 00460 00461 $count++; 00462 $id = 'filter_mp3_'.time().'_'.$count; //we need something unique because it might be stored in text cache 00463 00464 $url = $link[1]; 00465 $rawurl = str_replace('&', '&', $url); 00466 00467 $info = trim($link[2]); 00468 if (empty($info) or strpos($info, 'http') === 0) { 00469 $info = get_string('mp3audio', 'filter_mediaplugin'); 00470 00471 } 00472 $printlink = html_writer::link($rawurl, $info, array('class'=>'mediafallbacklink')); 00473 00474 //note: when flash or javascript not available only the $printlink is displayed, 00475 // audio players are supposed to be inline elements 00476 00477 $output = html_writer::tag('span', $printlink, array('id'=>$id, 'class'=>'mediaplugin mediaplugin_mp3')); 00478 $output .= html_writer::script(js_writer::function_call('M.util.add_audio_player', array($id, $rawurl, true))); // we can not use standard JS init because this may be cached 00479 00480 return $output; 00481 } 00482 00492 function filter_mediaplugin_swf_callback($link) { 00493 00494 if (filter_mediaplugin_ignore($link[0])) { 00495 return $link[0]; 00496 } 00497 00498 $width = empty($link[3]) ? FILTER_MEDIAPLUGIN_VIDEO_WIDTH : $link[3]; 00499 $height = empty($link[4]) ? FILTER_MEDIAPLUGIN_VIDEO_HEIGHT : $link[4]; 00500 00501 $url = $link[1]; 00502 $rawurl = str_replace('&', '&', $url); 00503 00504 $info = trim($link[5]); 00505 if (empty($info) or strpos($info, 'http') === 0) { 00506 $info = get_string('flashanimation', 'filter_mediaplugin'); 00507 00508 } 00509 $printlink = html_writer::link($rawurl, $info, array('class'=>'mediafallbacklink')); 00510 00511 $output = <<<OET 00512 <span class="mediaplugin mediaplugin_swf"> 00513 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="$width" height="$height"> 00514 <param name="movie" value="$url" /> 00515 <param name="autoplay" value="true" /> 00516 <param name="loop" value="true" /> 00517 <param name="controller" value="true" /> 00518 <param name="scale" value="aspect" /> 00519 <param name="base" value="." /> 00520 <param name="allowscriptaccess" value="never" /> 00521 <!--[if !IE]>--> 00522 <object type="application/x-shockwave-flash" data="$url" width="$width" height="$height"> 00523 <param name="controller" value="true" /> 00524 <param name="autoplay" value="true" /> 00525 <param name="loop" value="true" /> 00526 <param name="scale" value="aspect" /> 00527 <param name="base" value="." /> 00528 <param name="allowscriptaccess" value="never" /> 00529 <!--<![endif]--> 00530 $printlink 00531 <!--[if !IE]>--> 00532 </object> 00533 <!--<![endif]--> 00534 </object> 00535 </span> 00536 OET; 00537 00538 return $output; 00539 00540 } 00541 00548 function filter_mediaplugin_flv_callback($link) { 00549 static $count = 0; 00550 00551 if (filter_mediaplugin_ignore($link[0])) { 00552 return $link[0]; 00553 } 00554 00555 $count++; 00556 $id = 'filter_flv_'.time().'_'.$count; //we need something unique because it might be stored in text cache 00557 00558 list($urls, $width, $height) = filter_mediaplugin_parse_alternatives($link[1], 0, 0); 00559 00560 $autosize = false; 00561 if (!$width and !$height) { 00562 $width = FILTER_MEDIAPLUGIN_VIDEO_WIDTH; 00563 $height = FILTER_MEDIAPLUGIN_VIDEO_HEIGHT; 00564 $autosize = true; 00565 } 00566 00567 $flashurl = null; 00568 $sources = array(); 00569 00570 foreach ($urls as $url) { 00571 $mimetype = filter_mediaplugin_get_mimetype($url); 00572 if (strpos($mimetype, 'video/') !== 0) { 00573 continue; 00574 } 00575 $source = html_writer::tag('source', '', array('src' => $url, 'type' => $mimetype)); 00576 if ($mimetype === 'video/mp4') { 00577 // better add m4v as first source, it might be a bit more compatible with problematic browsers 00578 array_unshift($sources, $source); 00579 } else { 00580 $sources[] = $source; 00581 } 00582 00583 if ($flashurl === null) { 00584 $flashurl = $url; 00585 } 00586 } 00587 if (!$sources) { 00588 return $link[0]; 00589 } 00590 00591 $info = trim($link[4]); 00592 if (empty($info) or strpos($info, 'http') === 0) { 00593 $info = get_string('fallbackvideo', 'filter_mediaplugin'); 00594 } 00595 $printlink = html_writer::link($flashurl.'#', $info, array('class'=>'mediafallbacklink')); // the '#' prevents the QT filter 00596 00597 $title = s($info); 00598 00599 if (count($sources) > 1) { 00600 $sources = implode("\n", $sources); 00601 00602 // html 5 fallback 00603 $printlink = <<<OET 00604 <video controls="true" width="$width" height="$height" preload="metadata" title="$title"> 00605 $sources 00606 $printlink 00607 </video> 00608 <noscript><br /> 00609 $printlink 00610 </noscript> 00611 OET; 00612 } 00613 00614 // note: no need to print "this is flv link" because it is printed automatically if JS or Flash not available 00615 00616 $output = html_writer::tag('span', $printlink, array('id'=>$id, 'class'=>'mediaplugin mediaplugin_flv')); 00617 $output .= html_writer::script(js_writer::function_call('M.util.add_video_player', array($id, rawurlencode($flashurl), $width, $height, $autosize))); // we can not use standard JS init because this may be cached 00618 00619 return $output; 00620 } 00621 00631 function filter_mediaplugin_real_callback($link) { 00632 00633 if (filter_mediaplugin_ignore($link[0])) { 00634 return $link[0]; 00635 } 00636 00637 $url = $link[1]; 00638 $rawurl = str_replace('&', '&', $url); 00639 00640 //Note: the size is hardcoded intentionally because this does not work anyway! 00641 00642 $width = FILTER_MEDIAPLUGIN_VIDEO_WIDTH; 00643 $height = FILTER_MEDIAPLUGIN_VIDEO_HEIGHT; 00644 00645 $info = trim($link[3]); 00646 if (empty($info) or strpos($info, 'http') === 0) { 00647 $info = get_string('fallbackvideo', 'filter_mediaplugin'); 00648 } 00649 $printlink = html_writer::link($rawurl, $info, array('class'=>'mediafallbacklink')); 00650 00651 return <<<OET 00652 <span class="mediaplugin mediaplugin_real"> 00653 $printlink <br /> 00654 <object title="$info" classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" data="$url" width="$width" height="$height""> 00655 <param name="src" value="$url" /> 00656 <param name="controls" value="All" /> 00657 <!--[if !IE]>--> 00658 <object title="$info" type="audio/x-pn-realaudio-plugin" data="$url" width="$width" height="$height"> 00659 <param name="src" value="$url" /> 00660 <param name="controls" value="All" /> 00661 <!--<![endif]--> 00662 <!--[if !IE]>--> 00663 </object> 00664 <!--<![endif]--> 00665 </object> 00666 </span> 00667 OET; 00668 } 00669 00678 function filter_mediaplugin_youtube_callback($link) { 00679 global $CFG; 00680 00681 if (filter_mediaplugin_ignore($link[0])) { 00682 return $link[0]; 00683 } 00684 00685 $site = $link[1]; 00686 $videoid = $link[3]; 00687 00688 $info = trim($link[7]); 00689 if (empty($info) or strpos($info, 'http') === 0) { 00690 $info = get_string('siteyoutube', 'filter_mediaplugin'); 00691 } 00692 $info = s($info); 00693 00694 $width = empty($link[5]) ? FILTER_MEDIAPLUGIN_VIDEO_WIDTH : $link[5]; 00695 $height = empty($link[6]) ? FILTER_MEDIAPLUGIN_VIDEO_HEIGHT : $link[6]; 00696 00697 if (empty($CFG->xmlstrictheaders)) { 00698 return <<<OET 00699 <iframe title="$info" width="$width" height="$height" src="$site/embed/$videoid?rel=0" frameborder="0" allowfullscreen></iframe> 00700 OET; 00701 } 00702 00703 //NOTE: we can not use any link fallback because it breaks built-in player on iOS devices 00704 00705 $output = <<<OET 00706 <span class="mediaplugin mediaplugin_youtube"> 00707 <object title="$info" type="application/x-shockwave-flash" data="$site/v/$videoid&fs=1&rel=0" width="$width" height="$height"> 00708 <param name="movie" value="$site/v/$videoid&fs=1&rel=0" /> 00709 <param name="FlashVars" value="playerMode=embedded" /> 00710 <param name="allowFullScreen" value="true" /> 00711 </object> 00712 </span> 00713 OET; 00714 00715 return $output; 00716 } 00717 00726 function filter_mediaplugin_youtube_playlist_callback($link) { 00727 global $CFG; 00728 00729 if (filter_mediaplugin_ignore($link[0])) { 00730 return $link[0]; 00731 } 00732 00733 $site = $link[1]; 00734 $playlist = $link[3]; 00735 00736 $info = trim($link[7]); 00737 if (empty($info) or strpos($info, 'http') === 0) { 00738 $info = get_string('siteyoutube', 'filter_mediaplugin'); 00739 } 00740 $printlink = html_writer::link("$site/view_play_list\?p=$playlist", $info, array('class'=>'mediafallbacklink')); 00741 $info = s($info); 00742 00743 $width = empty($link[5]) ? FILTER_MEDIAPLUGIN_VIDEO_WIDTH : $link[5]; 00744 $height = empty($link[6]) ? FILTER_MEDIAPLUGIN_VIDEO_HEIGHT : $link[6]; 00745 00746 // TODO: iframe HTML 5 video not implemented and object does work on iOS devices 00747 00748 $output = <<<OET 00749 <span class="mediaplugin mediaplugin_youtube"> 00750 <object title="$info" type="application/x-shockwave-flash" data="$site/p/$playlist&fs=1&rel=0" width="$width" height="$height"> 00751 <param name="movie" value="$site/v/$playlist&fs=1&rel=0" /> 00752 <param name="FlashVars" value="playerMode=embedded" /> 00753 <param name="allowFullScreen" value="true" /> 00754 $printlink</object> 00755 </span> 00756 OET; 00757 00758 return $output; 00759 } 00760 00767 function filter_mediaplugin_vimeo_callback($link) { 00768 global $CFG; 00769 00770 if (filter_mediaplugin_ignore($link[0])) { 00771 return $link[0]; 00772 } 00773 00774 $videoid = $link[1]; 00775 $info = s(strip_tags($link[5])); 00776 00777 //Note: resizing via url is not supported, user can click the fullscreen button instead 00778 // iframe embedding is not xhtml strict but it is the only option that seems to work on most devices 00779 00780 $width = empty($link[3]) ? FILTER_MEDIAPLUGIN_VIDEO_WIDTH : $link[3]; 00781 $height = empty($link[4]) ? FILTER_MEDIAPLUGIN_VIDEO_HEIGHT : $link[4]; 00782 00783 $output = <<<OET 00784 <span class="mediaplugin mediaplugin_vimeo"> 00785 <iframe title="$info" src="http://player.vimeo.com/video/$videoid" width="$width" height="$height" frameborder="0"></iframe> 00786 </span> 00787 OET; 00788 00789 return $output; 00790 } 00791 00800 function filter_mediaplugin_wmp_callback($link) { 00801 00802 if (filter_mediaplugin_ignore($link[0])) { 00803 return $link[0]; 00804 } 00805 00806 $url = $link[1]; 00807 $rawurl = str_replace('&', '&', $url); 00808 00809 $info = trim($link[6]); 00810 if (empty($info) or strpos($info, 'http') === 0) { 00811 $info = get_string('fallbackvideo', 'filter_mediaplugin'); 00812 } 00813 $printlink = html_writer::link($rawurl, $info, array('class'=>'mediafallbacklink')); 00814 00815 if (empty($link[4]) or empty($link[5])) { 00816 $mpsize = ''; 00817 $size = 'width="'.FILTER_MEDIAPLUGIN_VIDEO_WIDTH.'" height="'.(FILTER_MEDIAPLUGIN_VIDEO_HEIGHT+64).'"'; 00818 $autosize = 'true'; 00819 } else { 00820 $size = 'width="'.$link[4].'" height="'.($link[5] + 15).'"'; 00821 $mpsize = 'width="'.$link[4].'" height="'.($link[5] + 64).'"'; 00822 $autosize = 'false'; 00823 } 00824 $mimetype = filter_mediaplugin_get_mimetype($url); 00825 00826 00827 00828 return <<<OET 00829 <span class="mediaplugin mediaplugin_wmp"> 00830 $printlink <br /> 00831 <object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" $mpsize standby="Loading Microsoft(R) Windows(R) Media Player components..." type="application/x-oleobject"> 00832 <param name="Filename" value="$url" /> 00833 <param name="src" value="$url" /> 00834 <param name="url" value="$url" /> 00835 <param name="ShowControls" value="true" /> 00836 <param name="AutoRewind" value="true" /> 00837 <param name="AutoStart" value="false" /> 00838 <param name="Autosize" value="$autosize" /> 00839 <param name="EnableContextMenu" value="true" /> 00840 <param name="TransparentAtStart" value="false" /> 00841 <param name="AnimationAtStart" value="false" /> 00842 <param name="ShowGotoBar" value="false" /> 00843 <param name="EnableFullScreenControls" value="true" /> 00844 <param name="uimode" value="full" /> 00845 <!--[if !IE]>--> 00846 <object data="$url" type="$mimetype" $size> 00847 <param name="src" value="$url" /> 00848 <param name="controller" value="true" /> 00849 <param name="autoplay" value="false" /> 00850 <param name="autostart" value="false" /> 00851 <param name="resize" value="scale" /> 00852 </object> 00853 <!--<![endif]--> 00854 </object></span> 00855 OET; 00856 } 00857 00866 function filter_mediaplugin_qt_callback($link) { 00867 00868 if (filter_mediaplugin_ignore($link[0])) { 00869 return $link[0]; 00870 } 00871 00872 $url = $link[1]; 00873 $rawurl = str_replace('&', '&', $url); 00874 00875 $info = trim($link[6]); 00876 if (empty($info) or strpos($info, 'http') === 0) { 00877 $info = get_string('fallbackvideo', 'filter_mediaplugin'); 00878 } 00879 $printlink = html_writer::link($rawurl, $info, array('class'=>'mediafallbacklink')); 00880 00881 if (empty($link[4]) or empty($link[5])) { 00882 $size = 'width="'.FILTER_MEDIAPLUGIN_VIDEO_WIDTH.'" height="'.(FILTER_MEDIAPLUGIN_VIDEO_HEIGHT+15).'"'; 00883 } else { 00884 $size = 'width="'.$link[4].'" height="'.($link[5]+15).'"'; 00885 } 00886 $mimetype = filter_mediaplugin_get_mimetype($url); 00887 00888 // this is the safest fallback for incomplete or missing browser support for this format 00889 return <<<OET 00890 <span class="mediaplugin mediaplugin_qt"> 00891 $printlink <br /> 00892 <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" $size> 00893 <param name="pluginspage" value="http://www.apple.com/quicktime/download/" /> 00894 <param name="src" value="$url" /> 00895 <param name="controller" value="true" /> 00896 <param name="loop" value="true" /> 00897 <param name="autoplay" value="false" /> 00898 <param name="autostart" value="false" /> 00899 <param name="scale" value="aspect" /> 00900 <!--[if !IE]>--> 00901 <object data="$url" type="$mimetype" $size> 00902 <param name="src" value="$url" /> 00903 <param name="pluginurl" value="http://www.apple.com/quicktime/download/" /> 00904 <param name="controller" value="true" /> 00905 <param name="loop" value="true" /> 00906 <param name="autoplay" value="false" /> 00907 <param name="autostart" value="false" /> 00908 <param name="scale" value="aspect" /> 00909 </object> 00910 <!--<![endif]--> 00911 </object></span> 00912 OET; 00913 } 00914