. /** * Media plugin filtering * * This filter will replace any links to a media file with * a media plugin that plays that media inline * * @package filter * @subpackage mediaplugin * @copyright 2004 onwards Martin Dougiamas {@link http://moodle.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); require_once($CFG->libdir.'/filelib.php'); class filter_mediaplugin extends moodle_text_filter { private $eolas_fix_applied = false; function filter($text, array $options = array()) { global $CFG, $PAGE; // You should never modify parameters passed to a method or function, it's BAD practice. Create a copy instead. // The reason is that you must always be able to refer to the original parameter that was passed. // For this reason, I changed $text = preg_replace(..,..,$text) into $newtext = preg.... (NICOLAS CONNAULT) // Thanks to Pablo Etcheverry for pointing this out! MDL-10177 // We're using the UFO technique for flash to attain XHTML Strict 1.0 // See: http://www.bobbyvandersluis.com/ufo/ if (!is_string($text)) { // non string data can not be filtered anyway return $text; } $newtext = $text; // fullclone is slow and not needed here if (!empty($CFG->filter_mediaplugin_enable_mp3)) { $search = '/]*?href="([^<]+\.mp3)"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_mp3_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_ogg)) { $search = '/]*?href="([^<]+\.ogg)"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_ogg_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_ogv)) { $search = '/]*?href="([^<]+\.ogv)"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_ogv_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_swf)) { $search = '/]*?href="([^<]+\.swf)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_swf_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_flv)) { $search = '/]*?href="([^<]+\.flv)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_flv_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_mov)) { $search = '/]*?href="([^<]+\.mov)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext); $search = '/]*?href="([^<]+\.mp4)(\?d=([\d]{1,4}%?)x([\d]{1,4}%?))?"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext); $search = '/]*?href="([^<]+\.m4v)(\?d=([\d]{1,4}%?)x([\d]{1,4}%?))?"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext); $search = '/]*?href="([^<]+\.m4a)(\?d=([\d]{1,4}%?)x([\d]{1,4}%?))?"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_wmv)) { $search = '/]*?href="([^<]+\.wmv)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_wmp_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_mpg)) { $search = '/]*?href="([^<]+\.mpe?g)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_qt_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_avi)) { $search = '/]*?href="([^<]+\.avi)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_wmp_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_ram)) { $search = '/]*?href="([^<]+\.ram)"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_real_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_rpm)) { $search = '/]*?href="([^<]+\.rpm)"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_real_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_rm)) { $search = '/]*?href="([^<]+\.rm)"[^>]*>.*?<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_real_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_youtube)) { //see MDL-23903 for description of recent changes to this regex //$search = '/]*>(.*?)<\/a>/is'; $search = '/]*href="([^<]*?)youtube.com\/watch\?v=([^"]*)"[^>]*>(.*?)<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_callback', $newtext); $search = '/]*>(.*?)<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_callback', $newtext); } if (!empty($CFG->filter_mediaplugin_enable_img)) { $search = '/]*?href="([^<]+\.jpg)"[^>]*>(.*?)<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_img_callback', $newtext); $search = '/]*?href="([^<]+\.png)"[^>]*>(.*?)<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_img_callback', $newtext); $search = '/]*?href="([^<]+\.gif)"[^>]*>(.*?)<\/a>/is'; $newtext = preg_replace_callback($search, 'filter_mediaplugin_img_callback', $newtext); } if (empty($newtext) or $newtext === $text) { // error or not filtered unset($newtext); return $text; } if (!$this->eolas_fix_applied) { $PAGE->requires->js('/filter/mediaplugin/eolas_fix.js'); $this->eolas_fix_applied = true; } return $newtext; } } ///=========================== /// callback filter functions function filter_mediaplugin_mp3_callback($link) { global $CFG, $OUTPUT, $PAGE; $c = $OUTPUT->filter_mediaplugin_colors(); // You can set this up in your theme/xxx/config.php static $count = 0; $count++; $id = 'filter_mp3_'.time().$count; //we need something unique because it might be stored in text cache $url = addslashes_js($link[1]); $playerpath = $CFG->wwwroot.'/filter/mediaplugin/mp3player.swf'; $audioplayerpath = $CFG->wwwroot .'/filter/mediaplugin/flowplayer.audio.swf'; $colors = explode('&', $c); $playercolors = array(); foreach ($colors as $color) { $color = explode('=', $color); $playercolors[$color[0]] = $color[1]; } $output = << OET; $jsoutput = create_flowplayer($id, $url, 'mp3', $playercolors); $output .= $jsoutput; return $output; } function filter_mediaplugin_ogg_callback($link) { global $CFG, $OUTPUT, $PAGE; static $count = 0; $count++; $id = 'filter_ogg_'.time().$count; //we need something unique because it might be stored in text cache $url = addslashes_js($link[1]); $printlink = html_writer::link($url, get_string('oggaudio', 'filter_mediaplugin')); $unsupportedplugins = get_string('unsupportedplugins', 'filter_mediaplugin', $printlink); $output = << $unsupportedplugins OET; return $output; } function filter_mediaplugin_ogv_callback($link) { global $CFG, $OUTPUT, $PAGE; static $count = 0; $count++; $id = 'filter_ogv_'.time().$count; //we need something unique because it might be stored in text cache $url = addslashes_js($link[1]); $printlink = html_writer::link($url, get_string('ogvvideo', 'filter_mediaplugin')); $unsupportedplugins = get_string('unsupportedplugins', 'filter_mediaplugin', $printlink); $output = << $unsupportedplugins OET; return $output; } function filter_mediaplugin_swf_callback($link) { global $PAGE; static $count = 0; $count++; $id = 'filter_swf_'.time().$count; //we need something unique because it might be stored in text cache $width = empty($link[3]) ? '400' : $link[3]; $height = empty($link[4]) ? '300' : $link[4]; $url = addslashes_js($link[1]); $args = Array(); $args['movie'] = $url; $args['width'] = $width; $args['height'] = $height; $args['majorversion'] = 6; $args['build'] = 40; $args['allowscriptaccess'] = 'never'; $args['quality'] = 'high'; $jsoutput = create_ufo_inline($id, $args); $output = $link[0].'('.get_string('flashanimation', 'filter_mediaplugin').')'.$jsoutput; return $output; } function filter_mediaplugin_flv_callback($link) { global $CFG, $PAGE; static $count = 0; $count++; $id = 'filter_flv_'.time().$count; //we need something unique because it might be stored in text cache $width = empty($link[3]) ? '480' : $link[3]; $height = empty($link[4]) ? '360' : $link[4]; $url = addslashes_js($link[1]); $playerpath = $CFG->wwwroot.'/filter/mediaplugin/flvplayer.swf'; $output = << EOT; $jsoutput = create_flowplayer($id, $url, 'flv'); $output .= $jsoutput; return $output; } function filter_mediaplugin_real_callback($link, $autostart=false) { $url = addslashes_js($link[1]); $mimetype = mimeinfo('type', $url); $autostart = $autostart ? 'true' : 'false'; // embed kept for now see MDL-8674 return $link[0]. ' '; } /** * Change links to Youtube into embedded Youtube videos */ function filter_mediaplugin_youtube_callback($link, $autostart=false) { $site = addslashes_js($link[1]); $url = addslashes_js($link[2]); $info = addslashes_js(strip_tags($link[3]));//strip out html tags as they won't work in the title attribute return ''. ''. ''. ''. ''. ''; } /** * Change links to images into embedded images */ function filter_mediaplugin_img_callback($link, $autostart=false) { $url = addslashes_js($link[1]); $info = addslashes_js($link[2]); return ''; } /** * Embed video using window media player if available */ function filter_mediaplugin_wmp_callback($link, $autostart=false) { $url = $link[1]; if (empty($link[3]) or empty($link[4])) { $mpsize = ''; $size = 'width="300" height="260"'; $autosize = 'true'; } else { $size = 'width="'.$link[3].'" height="'.$link[4].'"'; $mpsize = $size; $autosize = 'false'; } $mimetype = mimeinfo('type', $url); $autostart = $autostart ? 'true' : 'false'; return $link[0]. ' '; } function filter_mediaplugin_qt_callback($link, $autostart=false) { $url = $link[1]; if (empty($link[3]) or empty($link[4])) { $size = 'width="440" height="315"'; } else { $size = 'width="'.$link[3].'" height="'.$link[4].'"'; } $mimetype = mimeinfo('type', $url); $autostart = $autostart ? 'true' : 'false'; return $link[0]. ' '; }