7e64d361 |
1 | <?php // $Id$ |
6de17fde |
2 | ////////////////////////////////////////////////////////////// |
3 | // Media plugin filtering |
7e64d361 |
4 | // |
5 | // This filter will replace any links to a media file with |
6de17fde |
6 | // a media plugin that plays that media inline |
7 | // |
4da85078 |
8 | // To activate this filter, add a line like this to your |
9 | // list of filters in your Filter configuration: |
6de17fde |
10 | // |
4da85078 |
11 | // filter/mediaplugin/filter.php |
6de17fde |
12 | // |
13 | ////////////////////////////////////////////////////////////// |
14 | |
7e64d361 |
15 | /// This is the filtering function itself. It accepts the |
6de17fde |
16 | /// courseid and the text to be filtered (in HTML form). |
17 | |
7e64d361 |
18 | require_once($CFG->libdir.'/filelib.php'); |
19 | |
ccc161f8 |
20 | class mediaplugin_filter extends moodle_text_filter { |
21 | private $eolas_fix_applied = false; |
9e3f34d1 |
22 | function filter($text) { |
23 | global $CFG; |
24 | // You should never modify parameters passed to a method or function, it's BAD practice. Create a copy instead. |
25 | // The reason is that you must always be able to refer to the original parameter that was passed. |
26 | // For this reason, I changed $text = preg_replace(..,..,$text) into $newtext = preg.... (NICOLAS CONNAULT) |
27 | // Thanks to Pablo Etcheverry for pointing this out! MDL-10177 |
28 | |
29 | // We're using the UFO technique for flash to attain XHTML Strict 1.0 |
30 | // See: http://www.bobbyvandersluis.com/ufo/ |
31 | if (!is_string($text)) { |
32 | // non string data can not be filtered anyway |
33 | return $text; |
34 | } |
35 | $newtext = $text; // fullclone is slow and not needed here |
36 | |
37 | if ($CFG->filter_mediaplugin_enable_mp3) { |
38 | $search = '/<a.*?href="([^<]+\.mp3)"[^>]*>.*?<\/a>/is'; |
39 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_mp3_callback', $newtext); |
40 | } |
41 | |
42 | if ($CFG->filter_mediaplugin_enable_swf) { |
43 | $search = '/<a.*?href="([^<]+\.swf)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; |
44 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_swf_callback', $newtext); |
45 | } |
46 | |
47 | if ($CFG->filter_mediaplugin_enable_flv) { |
48 | $search = '/<a.*?href="([^<]+\.flv)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; |
49 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_flv_callback', $newtext); |
50 | } |
51 | |
52 | if ($CFG->filter_mediaplugin_enable_mov) { |
53 | $search = '/<a.*?href="([^<]+\.mov)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; |
54 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_qt_callback', $newtext); |
55 | } |
56 | |
57 | if ($CFG->filter_mediaplugin_enable_wmv) { |
58 | $search = '/<a.*?href="([^<]+\.wmv)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; |
59 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_wmp_callback', $newtext); |
60 | } |
61 | |
62 | if ($CFG->filter_mediaplugin_enable_mpg) { |
63 | $search = '/<a.*?href="([^<]+\.mpe?g)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; |
64 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_qt_callback', $newtext); |
65 | } |
66 | |
67 | if ($CFG->filter_mediaplugin_enable_avi) { |
68 | $search = '/<a.*?href="([^<]+\.avi)(\?d=([\d]{1,3}%?)x([\d]{1,3}%?))?"[^>]*>.*?<\/a>/is'; |
69 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_wmp_callback', $newtext); |
70 | } |
71 | |
72 | if ($CFG->filter_mediaplugin_enable_ram) { |
73 | $search = '/<a.*?href="([^<]+\.ram)"[^>]*>.*?<\/a>/is'; |
74 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); |
75 | } |
76 | |
77 | if ($CFG->filter_mediaplugin_enable_rpm) { |
78 | $search = '/<a.*?href="([^<]+\.rpm)"[^>]*>.*?<\/a>/is'; |
79 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); |
80 | } |
81 | |
82 | if ($CFG->filter_mediaplugin_enable_rm) { |
83 | $search = '/<a.*?href="([^<]+\.rm)"[^>]*>.*?<\/a>/is'; |
84 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); |
85 | } |
86 | |
87 | if (!empty($CFG->filter_mediaplugin_enable_youtube)) { |
88 | $search = '/<a.*?href="([^<]*)youtube.com\/watch\?v=([^"]*)"[^>]*>(.*?)<\/a>/is'; |
89 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_youtube_callback', $newtext); |
90 | |
91 | $search = '/<a.*?href="([^<]*)youtube.com\/v\/([^"]*)"[^>]*>(.*?)<\/a>/is'; |
92 | $newtext = preg_replace_callback($search, 'mediaplugin_filter_youtube_callback', $newtext); |
93 | } |
94 | |
95 | if (empty($newtext) or $newtext === $text) { |
96 | // error or not filtered |
97 | unset($newtext); |
98 | return $text; |
99 | } |
100 | |
101 | if (!$this->eolas_fix_applied) { |
102 | $newtext .= '<script defer="defer" src="' . $CFG->wwwroot . '/filter/mediaplugin/eolas_fix.js" type="text/javascript">// <![CDATA[ ]]></script>'; |
103 | $this->eolas_fix_applied = true; |
104 | } |
105 | |
106 | return $newtext; |
d07851e1 |
107 | } |
6de17fde |
108 | } |
109 | |
7e64d361 |
110 | ///=========================== |
111 | /// callback filter functions |
112 | |
113 | function mediaplugin_filter_mp3_callback($link) { |
114 | global $CFG, $THEME; |
115 | |
116 | if (!empty($THEME->filter_mediaplugin_colors)) { |
117 | $c = $THEME->filter_mediaplugin_colors; // You can set this up in your theme/xxx/config.php |
118 | } else { |
119 | $c = 'bgColour=000000&btnColour=ffffff&btnBorderColour=cccccc&iconColour=000000&'. |
120 | 'iconOverColour=00cc00&trackColour=cccccc&handleColour=ffffff&loaderColour=ffffff&'. |
121 | 'waitForPlay=yes'; |
122 | } |
123 | $c = htmlentities($c); |
124 | |
125 | static $count = 0; |
126 | $count++; |
127 | $id = 'filter_mp3_'.time().$count; //we need something unique because it might be stored in text cache |
128 | |
129 | $url = addslashes_js($link[1]); |
130 | |
131 | return $link[0]. |
132 | '<span class="mediaplugin mediaplugin_mp3" id="'.$id.'">('.get_string('mp3audio', 'mediaplugin').')</span> |
133 | <script type="text/javascript"> |
134 | //<![CDATA[ |
135 | var FO = { movie:"'.$CFG->wwwroot.'/filter/mediaplugin/mp3player.swf?src='.$url.'", |
136 | width:"90", height:"15", majorversion:"6", build:"40", flashvars:"'.$c.'", quality: "high" }; |
5bed8102 |
137 | UFO.create(FO, "'.$id.'"); |
7e64d361 |
138 | //]]> |
139 | </script>'; |
140 | } |
141 | |
142 | function mediaplugin_filter_swf_callback($link) { |
143 | static $count = 0; |
144 | $count++; |
145 | $id = 'filter_swf_'.time().$count; //we need something unique because it might be stored in text cache |
146 | |
147 | $width = empty($link[3]) ? '400' : $link[3]; |
148 | $height = empty($link[4]) ? '300' : $link[4]; |
149 | $url = addslashes_js($link[1]); |
150 | |
151 | return $link[0]. |
152 | '<span class="mediaplugin mediaplugin_swf" id="'.$id.'">('.get_string('flashanimation', 'mediaplugin').')</span> |
153 | <script type="text/javascript"> |
154 | //<![CDATA[ |
155 | var FO = { movie:"'.$url.'", width:"'.$width.'", height:"'.$height.'", majorversion:"6", build:"40", |
156 | allowscriptaccess:"never", quality: "high" }; |
5bed8102 |
157 | UFO.create(FO, "'.$id.'"); |
7e64d361 |
158 | //]]> |
159 | </script>'; |
160 | } |
161 | |
162 | function mediaplugin_filter_flv_callback($link) { |
163 | global $CFG; |
164 | |
165 | static $count = 0; |
166 | $count++; |
167 | $id = 'filter_flv_'.time().$count; //we need something unique because it might be stored in text cache |
168 | |
169 | $width = empty($link[3]) ? '480' : $link[3]; |
170 | $height = empty($link[4]) ? '360' : $link[4]; |
171 | $url = addslashes_js($link[1]); |
172 | |
173 | return $link[0]. |
174 | '<span class="mediaplugin mediaplugin_flv" id="'.$id.'">('.get_string('flashvideo', 'mediaplugin').')</span> |
175 | <script type="text/javascript"> |
176 | //<![CDATA[ |
177 | var FO = { movie:"'.$CFG->wwwroot.'/filter/mediaplugin/flvplayer.swf?file='.$url.'", |
178 | width:"'.$width.'", height:"'.$height.'", majorversion:"6", build:"40", |
179 | allowscriptaccess:"never", quality: "high" }; |
5bed8102 |
180 | UFO.create(FO, "'.$id.'"); |
7e64d361 |
181 | //]]> |
182 | </script>'; |
183 | } |
184 | |
185 | function mediaplugin_filter_real_callback($link, $autostart=false) { |
186 | $url = addslashes_js($link[1]); |
187 | $mimetype = mimeinfo('type', $url); |
188 | $autostart = $autostart ? 'true' : 'false'; |
189 | |
190 | // embed kept for now see MDL-8674 |
191 | return $link[0]. |
192 | '<span class="mediaplugin mediaplugin_real"> |
193 | <script type="text/javascript"> |
194 | //<![CDATA[ |
195 | document.write(\'<object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="240" height="180">\\ |
196 | <param name="src" value="'.$url.'" />\\ |
197 | <param name="autostart" value="'.$autostart.'" />\\ |
198 | <param name="controls" value="imagewindow" />\\ |
199 | <param name="console" value="video" />\\ |
200 | <param name="loop" value="true" />\\ |
201 | <embed src="'.$url.'" width=240" height="180" loop="true" type="'.$mimetype.'" controls="imagewindow" console="video" autostart="'.$autostart.'" />\\ |
202 | </object><br />\\ |
203 | <object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="240" height="30">\\ |
204 | <param name="src" value="'.$url.'" />\\ |
205 | <param name="autostart" value="'.$autostart.'" />\\ |
206 | <param name="controls" value="ControlPanel" />\\ |
207 | <param name="console" value="video" />\\ |
208 | <embed src="'.$url.'" width="240" height="30" controls="ControlPanel" type="'.$mimetype.'" console="video" autostart="'.$autostart.'" />\\ |
209 | </object>\'); |
210 | //]]> |
211 | </script></span>'; |
212 | } |
213 | |
4d8bccf4 |
214 | /** |
215 | * Change links to Youtube into embedded Youtube videos |
216 | */ |
217 | function mediaplugin_filter_youtube_callback($link, $autostart=false) { |
218 | |
219 | $site = addslashes_js($link[1]); |
220 | $url = addslashes_js($link[2]); |
221 | $info = addslashes_js($link[3]); |
222 | |
e2cf2d7f |
223 | return '<object title="'.$info.'" |
224 | class="mediaplugin mediaplugin_youtube" type="application/x-shockwave-flash" |
4d8bccf4 |
225 | data="'.$site.'youtube.com/v/'.$url.'&fs=1&rel=0" width="425" height="344">'. |
6188deb8 |
226 | '<param name="movie" value="'.$site.'youtube.com/v/'.$url.'&fs=1&rel=0" />'. |
4d8bccf4 |
227 | '<param name="FlashVars" value="playerMode=embedded" />'. |
228 | '<param name="wmode" value="transparent" />'. |
229 | '<param name="allowFullScreen" value="true" />'. |
e2cf2d7f |
230 | '</object>'; |
4d8bccf4 |
231 | } |
232 | |
7e64d361 |
233 | /** |
234 | * Embed video using window media player if available |
235 | */ |
236 | function mediaplugin_filter_wmp_callback($link, $autostart=false) { |
237 | $url = $link[1]; |
238 | if (empty($link[3]) or empty($link[4])) { |
239 | $mpsize = ''; |
240 | $size = 'width="300" height="260"'; |
241 | $autosize = 'true'; |
242 | } else { |
243 | $size = 'width="'.$link[3].'" height="'.$link[4].'"'; |
244 | $mpsize = $size; |
245 | $autosize = 'false'; |
246 | } |
247 | $mimetype = mimeinfo('type', $url); |
248 | $autostart = $autostart ? 'true' : 'false'; |
249 | |
250 | return $link[0]. |
251 | '<span class="mediaplugin mediaplugin_wmp"> |
252 | <object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" '.$mpsize.' |
253 | standby="Loading Microsoft(R) Windows(R) Media Player components..." |
254 | type="application/x-oleobject"> |
255 | <param name="Filename" value="'.$url.'" /> |
256 | <param name="src" value="'.$url.'" /> |
257 | <param name="url" value="'.$url.'" /> |
258 | <param name="ShowControls" value="true" /> |
259 | <param name="AutoRewind" value="true" /> |
260 | <param name="AutoStart" value="'.$autostart.'" /> |
261 | <param name="Autosize" value="'.$autosize.'" /> |
262 | <param name="EnableContextMenu" value="true" /> |
263 | <param name="TransparentAtStart" value="false" /> |
264 | <param name="AnimationAtStart" value="false" /> |
265 | <param name="ShowGotoBar" value="false" /> |
266 | <param name="EnableFullScreenControls" value="true" /> |
267 | <!--[if !IE]>--> |
268 | <object data="'.$url.'" type="'.$mimetype.'" '.$size.'> |
269 | <param name="src" value="'.$url.'" /> |
270 | <param name="controller" value="true" /> |
271 | <param name="autoplay" value="'.$autostart.'" /> |
272 | <param name="autostart" value="'.$autostart.'" /> |
273 | <param name="resize" value="scale" /> |
274 | </object> |
275 | <!--<![endif]--> |
276 | </object></span>'; |
277 | } |
278 | |
279 | function mediaplugin_filter_qt_callback($link, $autostart=false) { |
280 | $url = $link[1]; |
281 | if (empty($link[3]) or empty($link[4])) { |
282 | $size = 'width="280" height="210"'; |
283 | } else { |
284 | $size = 'width="'.$link[3].'" height="'.$link[4].'"'; |
285 | } |
286 | $mimetype = mimeinfo('type', $url); |
287 | $autostart = $autostart ? 'true' : 'false'; |
288 | |
289 | return $link[0]. |
290 | '<span class="mediaplugin mediaplugin_qt"> |
291 | <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" |
292 | codebase="http://www.apple.com/qtactivex/qtplugin.cab" '.$size.'> |
293 | <param name="pluginspage" value="http://www.apple.com/quicktime/download/" /> |
294 | <param name="src" value="'.$url.'" /> |
d42df9da |
295 | <param name="controller" value="true" /> |
7e64d361 |
296 | <param name="loop" value="true" /> |
297 | <param name="autoplay" value="'.$autostart.'" /> |
298 | <param name="autostart" value="'.$autostart.'" /> |
299 | <param name="scale" value="aspect" /> |
300 | <!--[if !IE]>--> |
301 | <object data="'.$url.'" type="'.$mimetype.'" '.$size.'> |
302 | <param name="src" value="'.$url.'" /> |
303 | <param name="pluginurl" value="http://www.apple.com/quicktime/download/" /> |
304 | <param name="controller" value="true" /> |
305 | <param name="loop" value="true" /> |
306 | <param name="autoplay" value="'.$autostart.'" /> |
307 | <param name="autostart" value="'.$autostart.'" /> |
308 | <param name="scale" value="aspect" /> |
309 | </object> |
310 | <!--<![endif]--> |
311 | </object></span>'; |
312 | } |
6de17fde |
313 | |
314 | ?> |