AC_4897, AC_4898, AC_4899: Multifile uploader fixes.
[acontent.git] / docs / home / classes / ContentUtility.class.php
1 <?php\r
2 /************************************************************************/\r
3 /* AContent                                                             */\r
4 /************************************************************************/\r
5 /* Copyright (c) 2010                                                   */\r
6 /* Inclusive Design Institute                                           */\r
7 /*                                                                      */\r
8 /* This program is free software. You can redistribute it and/or        */\r
9 /* modify it under the terms of the GNU General Public License          */\r
10 /* as published by the Free Software Foundation.                        */\r
11 /************************************************************************/\r
12 \r
13 /**\r
14 * Content Utility functions \r
15 * @access       public\r
16 * @author       Cindy Qi Li\r
17 */\r
18 \r
19 if (!defined('TR_INCLUDE_PATH')) exit;\r
20 \r
21 class ContentUtility {\r
22 \r
23         /**\r
24         * This function cuts out html body\r
25         * @access  public\r
26         * @param   $text  html text\r
27         * @author  Cindy Qi Li\r
28         */\r
29         public static function getHtmlBody($text) {\r
30                 /* strip everything before <body> */\r
31                 $start_pos      = strpos(strtolower($text), '<body');\r
32                 if ($start_pos !== false) {\r
33                         $start_pos      += strlen('<body');\r
34                         $end_pos        = strpos(strtolower($text), '>', $start_pos);\r
35                         $end_pos        += strlen('>');\r
36         \r
37                         $text = substr($text, $end_pos);\r
38                 }\r
39         \r
40                 /* strip everything after </body> */\r
41                 $end_pos        = strpos(strtolower($text), '</body>');\r
42                 if ($end_pos !== false) {\r
43                         $text = trim(substr($text, 0, $end_pos));\r
44                 }\r
45         \r
46                 return $text;\r
47         }\r
48 \r
49         /**\r
50         * This function cuts out requested tag information from html head\r
51         * @access  public\r
52         * @param   $text  html text\r
53         * @param   $tags  a string or an array of requested tags\r
54         * @author  Cindy Qi Li\r
55         */\r
56         public static function getHtmlHeadByTag($text, $tags)\r
57         {\r
58                 $head = ContentUtility::getHtmlHead($text);\r
59                 $rtn_text = "";\r
60                 \r
61                 if (!is_array($tags) && strlen(trim($tags)) > 0)\r
62                 {\r
63                         $tags = array(trim($tags));\r
64                 }\r
65                 foreach ($tags as $tag)\r
66                 {\r
67                         $tag = strtolower($tag);\r
68         \r
69                         /* strip everything before <{tag}> */\r
70                         $start_pos      = stripos($head, '<'.$tag);\r
71                         $temp_head = $head;\r
72                         \r
73                         while ($start_pos !== false) \r
74                         {\r
75                                 $temp_text = substr($temp_head, $start_pos);\r
76                 \r
77                                 /* strip everything after </{tag}> or />*/\r
78                                 $end_pos        = stripos($temp_text, '</' . $tag . '>');\r
79                 \r
80                                 if ($end_pos !== false) \r
81                                 {\r
82                                         $end_pos += strlen('</' . $tag . '>');\r
83                                         \r
84                                         // add an empty line after each tag information\r
85                                         $rtn_text .= trim(substr($temp_text, 0, $end_pos)) . '\r
86                 \r
87         ';\r
88                                 }\r
89                                 else  // match /> as ending tag if </tag> is not found\r
90                                 {\r
91                                         $end_pos        = stripos($temp_text, '/>');\r
92                                         \r
93                                         if($end_pos === false && stripos($temp_text, $tag.'>')===false){\r
94                                                 //if /> is not found, then this is not a valid XHTML\r
95                                                 //text iff it's not tag>\r
96                                                 $end_pos = stripos($temp_text, '>');\r
97                                                 $end_pos += strlen('>');\r
98                                         } else {\r
99                                                 $end_pos += strlen('/>');\r
100                                         }\r
101                                         // add an empty line after each tag information\r
102                                         $rtn_text .= trim(substr($temp_text, 0, $end_pos)) . '\r
103                 \r
104         ';\r
105                                 }\r
106                                 \r
107                                 // initialize vars for next round of matching\r
108                                 $temp_head = substr($temp_text, $end_pos);\r
109                                 $start_pos = stripos($temp_head, '<'.$tag);\r
110                         }\r
111                 }\r
112                 return $rtn_text;\r
113         }\r
114 \r
115         /**\r
116         * This function cuts out html head\r
117         * @access  private\r
118         * @param   $text  html text\r
119         * @author  Cindy Qi Li\r
120         */\r
121         private static function getHtmlHead ($text) {\r
122                 /* strip everything before <head> */\r
123                 $start_pos      = stripos($text, '<head');\r
124                 if ($start_pos !== false) {\r
125                         $start_pos      += strlen('<head');\r
126                         $end_pos        = stripos($text, '>', $start_pos);\r
127                         $end_pos        += strlen('>');\r
128         \r
129                         $text = substr($text, $end_pos);\r
130                 }\r
131         \r
132                 /* strip everything after </head> */\r
133                 $end_pos        = stripos($text, '</head');\r
134                 if ($end_pos !== false) {\r
135                         $text = trim(substr($text, 0, $end_pos));\r
136                 }\r
137                 return $text;\r
138         }\r
139 \r
140         private static function embedFLV($text) {\r
141                 global $content_base_href;\r
142                 \r
143                 $media_replace = array();\r
144                 $media_matches = array();\r
145                 $flowplayerholder_class = "atutor.flowplayerholder";  // style class used to play flowplayer medias\r
146                 $flowplayerholder_def = '$f("*.'.$flowplayerholder_class.'"';   // javascript definition for atutor.flowplayerholder \r
147                 \r
148                 // .flv\r
149                 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+)\.flv\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
150                 \r
151                 if (isset($_SESSION['flash']) && $_SESSION['flash'] == "yes") {\r
152                         $media_replace[] = "<div>\n".\r
153                                        "  <a class=\"".$flowplayerholder_class."\" style=\"display:block;width:##WIDTH##px;height:##HEIGHT##px;\" href=\"##MEDIA1##.flv\"></a>\n".\r
154                                        "</div>\n";\r
155                 } else {\r
156                         $media_replace[] = "<div>\n".\r
157                                        "  <a href=\"##MEDIA1##.flv\">##MEDIA1##.flv</a>\n".\r
158                                        "</div>\n";\r
159                 }\r
160                 \r
161                 // .mp4\r
162                 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+)\.mp4\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
163 \r
164                 if (isset($_SESSION['flash']) && $_SESSION['flash'] == "yes") {\r
165                         $media_replace[] = "<div>\n".\r
166                                        "  <a class=\"".$flowplayerholder_class."\" style=\"display:block;width:##WIDTH##px;height:##HEIGHT##px;\" href=\"##MEDIA1##.mp4\"></a>\n".\r
167                                        "</div>\n";\r
168                 } else {\r
169                         $media_replace[] = "<div>\n".\r
170                                        "  <a href=\"##MEDIA1##.mp4\">##MEDIA1##.mp4</a>\n".\r
171                                        "</div>\n";\r
172                 }\r
173                 \r
174                 // Executing the replace\r
175                 for ($i=0;$i<count($media_replace);$i++){\r
176                         foreach($media_matches[$i] as $media)\r
177                         {\r
178                                 //find width and height for each matched media\r
179                                 if (preg_match("/\[media\|([0-9]*)\|([0-9]*)\]*/", $media[0], $matches)) \r
180                                 {\r
181                                         $width = $matches[1];\r
182                                         $height = $matches[2];\r
183                                 }\r
184                                 else\r
185                                 {\r
186                                         $width = 425;\r
187                                         $height = 350;\r
188                                 }\r
189                                 \r
190                                 //replace media tags with embedded media for each media tag\r
191                                 $media_input = $media_replace[$i];\r
192                                 $media_input = str_replace("##WIDTH##","$width",$media_input);\r
193                                 $media_input = str_replace("##HEIGHT##","$height",$media_input);\r
194                                 $media_input = str_replace("##MEDIA1##","$media[1]",$media_input);\r
195                                 $media_input = str_replace("##MEDIA2##","$media[2]",$media_input);\r
196                                 $text = str_replace($media[0],$media_input,$text);\r
197                         }\r
198                 }\r
199                 \r
200                 // Include the javascript only if:\r
201                 // 1. $flowplayerholder_class is used but not defined\r
202                 // 2. exclude from export common cartridge or content package\r
203                 if (strpos($text, $flowplayerholder_class) \r
204                     && !strpos($text, $flowplayerholder_def)\r
205                     && !strpos($_SERVER['PHP_SELF'], "ims_export.php"))\r
206                 {\r
207                         $text .= '<script type="text/javascript">\r
208 '.$flowplayerholder_def.', "'.TR_BASE_HREF.'include/jscripts/flowplayer/flowplayer-3.2.4.swf", { \r
209   clip: { \r
210   autoPlay: false,\r
211   baseUrl: \''.TR_BASE_HREF.'get.php/'.$content_base_href.'\'},\r
212   plugins:  { \r
213     controls: { \r
214       buttons:true, \r
215       play: true,  \r
216       scrubber: true, \r
217       autoHide:false\r
218     }         \r
219   }\r
220 });\r
221 </script>'."\n";\r
222                 }\r
223                 return $text;           \r
224         }\r
225         \r
226     /*\r
227      * This function converts the youtube playable url used in <object> tag (for instance: http://www.youtube.com/v/a0ryB0m0MiM)\r
228      * to youtube url that is used to browse (for instance: http://www.youtube.com/watch?v=a0ryB0m0MiM)\r
229      * @param: youtube playable URL. For instance, http://www.youtube.com/v/a0ryB0m0MiM\r
230      * @return: if the param is a youtube playable url, return the according youtube URL used to browse. \r
231      *          For instance: http://www.youtube.com/watch?v=a0ryB0m0MiM\r
232      *          Otherwise, return the original send-in parameter.\r
233      */\r
234     public function convertYoutubePlayURLToWatchURL($youtube_playURL) {\r
235         return preg_replace("/(http:\/\/[a-z0-9\.]*)?youtube.com\/v\/(.*)/",\r
236                             "\\1youtube.com/watch?v=\\2", $youtube_playURL);\r
237     }\r
238 \r
239     /*\r
240      * This function converts the youtube url that is used to browse (for instance: http://www.youtube.com/watch?v=a0ryB0m0MiM)\r
241      * to youtube playable url used in <object> tag (for instance: http://www.youtube.com/v/a0ryB0m0MiM)\r
242      * @param: the youtube URL used to browse. \r
243      *         For instance: http://www.youtube.com/watch?v=a0ryB0m0MiM\r
244      * @return: if the param is a youtube url used to browse, return the according youtube playable URL. \r
245      *          For instance, http://www.youtube.com/v/a0ryB0m0MiM\r
246      *          Otherwise, return the original send-in parameter.\r
247      */\r
248     public function convertYoutubeWatchURLToPlayURL($youtube_watchURL) {\r
249         return preg_replace("/(http:\/\/[a-z0-9\.]*)?youtube.com\/watch\?v=(.*)/",\r
250                             "\\1youtube.com/v/\\2", $youtube_watchURL);\r
251     }\r
252 \r
253         public static function embedMedia($text) {\r
254                 if (preg_match("/\[media(\|[0-9]+\|[0-9]+)?\]*/", $text)==0){\r
255                         return $text;\r
256                 }\r
257         \r
258                 // remove the spaces in [media] tag, otherwise, the next line converts URL inside [media] into <a> tag\r
259                 $text = preg_replace("/(\[media\])([\s]*)(.*)(\[\/media\])/", '$1$3$4', $text);\r
260                 $text = preg_replace("/(\[media\])(.*)([\s]*)(\[\/media\])/U", '$1$2$4', $text);\r
261                 \r
262                 $media_matches = array();\r
263                 $media_replace = array();\r
264                 \r
265                 // First, we search though the text for all different kinds of media defined by media tags and store the results in $media_matches.\r
266                 // Then the different replacements for the different media tags are stored in $media_replace.\r
267                 // Lastly, we loop through all $media_matches / $media_replaces. (We choose $media_replace as index because $media_matches is multi-dimensioned.) It is important that for each $media_matches there is a $media_replace with the same index. For each media match we check the width/height, or we use the default value of 425x350. We then replace the height/width/media1/media2 parameter placeholders in $media_replace with the correct ones, before running a str_replace on $text, replacing the given media with its correct replacement.\r
268         \r
269                 // youtube videos\r
270                 preg_match_all("#\[media[0-9a-z\|]*\]http://([a-z0-9\.]*)?youtube.com/watch\?v=(.*)\[/media\]#iU",$text,$media_matches[],PREG_SET_ORDER);\r
271                 $media_replace[] = '<object width="##WIDTH##" height="##HEIGHT##"><param name="movie" value="http://##MEDIA1##youtube.com/v/##MEDIA2##"></param><embed src="http://##MEDIA1##youtube.com/v/##MEDIA2##" type="application/x-shockwave-flash" width="##WIDTH##" height="##HEIGHT##"></embed></object>';\r
272                 \r
273                 // .mpg\r
274                 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).mpg\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
275                 $media_replace[] = "<object data=\"##MEDIA1##.mpg\" type=\"video/mpeg\" width=\"##WIDTH##\" height=\"##HEIGHT##\"><param name=\"src\" value=\"##MEDIA1##.mpg\"><param name=\"autoplay\" value=\"false\"><param name=\"autoStart\" value=\"0\"><a href=\"##MEDIA1##.mpg\">##MEDIA1##.mpg</a></object>";\r
276                 \r
277                 // .avi\r
278                 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).avi\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
279                 $media_replace[] = "<object data=\"##MEDIA1##.avi\" type=\"video/x-msvideo\" width=\"##WIDTH##\" height=\"##HEIGHT##\"><param name=\"src\" value=\"##MEDIA1##.avi\"><param name=\"autoplay\" value=\"false\"><param name=\"autoStart\" value=\"0\"><a href=\"##MEDIA1##.avi\">##MEDIA1##.avi</a></object>";\r
280                 \r
281                 // .wmv\r
282                 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).wmv\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
283                 $media_replace[] = "<object data=\"##MEDIA1##.wmv\" type=\"video/x-ms-wmv\" width=\"##WIDTH##\" height=\"##HEIGHT##\"><param name=\"src\" value=\"##MEDIA1##.wmv\"><param name=\"autoplay\" value=\"false\"><param name=\"autoStart\" value=\"0\"><a href=\"##MEDIA1##.wmv\">##MEDIA1##.wmv</a></object>";\r
284                 \r
285                 // .mov\r
286                 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).mov\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
287                 $media_replace[] = "<object classid=\"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B\" codebase=\"http://www.apple.com/qtactivex/qtplugin.cab\" width=\"##WIDTH##\" height=\"##HEIGHT##\">\n".\r
288                                    "  <param name=\"src\" value=\"##MEDIA1##.mov\">\n".\r
289                                    "  <param name=\"controller\" value=\"true\">\n".\r
290                                    "  <param name=\"autoplay\" value=\"false\">\n".\r
291                                    "  <!--[if gte IE 7] > <!-->\n".\r
292                                    "  <object type=\"video/quicktime\" data=\"##MEDIA1##.mov\" width=\"##WIDTH##\" height=\"##HEIGHT##\">\n".\r
293                                    "    <param name=\"controller\" value=\"true\">\n".\r
294                                    "    <param name=\"autoplay\" value=\"false\">\n".\r
295                                    "    <a href=\"##MEDIA1##.mov\">##MEDIA1##.mov</a>\n".\r
296                                    "  </object>\n".\r
297                                    "  <!--<![endif]-->\n".\r
298                                    "  <!--[if lt IE 7]>\n".\r
299                                    "  <a href=\"##MEDIA1##.mov\">##MEDIA1##.mov</a>\n".\r
300                                    "  <![endif]-->\n".\r
301                                    "</object>";\r
302                 \r
303                 // .swf\r
304                 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).swf\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
305                 $media_replace[] = "<object type=\"application/x-shockwave-flash\" data=\"##MEDIA1##.swf\" width=\"##WIDTH##\" height=\"##HEIGHT##\">  <param name=\"movie\" value=\"##MEDIA1##.swf\"><param name=\"loop\" value=\"false\"><a href=\"##MEDIA1##.swf\">##MEDIA1##.swf</a></object>";\r
306         \r
307                 // .mp3\r
308                 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).mp3\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
309                 $media_replace[] = "<object type=\"audio/mpeg\" data=\"##MEDIA1##.mp3\" width=\"##WIDTH##\" height=\"##HEIGHT##\"><param name=\"src\" value=\"##MEDIA1##.mp3\"><param name=\"autoplay\" value=\"false\"><param name=\"autoStart\" value=\"0\"><a href=\"##MEDIA1##.mp3\">##MEDIA1##.mp3</a></object>";\r
310                 \r
311                 // .wav\r
312                 preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).wav\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
313                 $media_replace[] ="<object type=\"audio/x-wav\" data=\"##MEDIA1##.wav\" width=\"##WIDTH##\" height=\"##HEIGHT##\"><param name=\"src\" value=\"##MEDIA1##.wav\"><param name=\"autoplay\" value=\"false\"><param name=\"autoStart\" value=\"0\"><a href=\"##MEDIA1##.wav\">##MEDIA1##.wav</a></object>";\r
314                 \r
315                 // .ogg\r
316                 preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).ogg\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
317                 $media_replace[] ="<object type=\"application/ogg\" data=\"##MEDIA1##.ogg\" width=\"##WIDTH##\" height=\"##HEIGHT##\"><param name=\"src\" value=\"##MEDIA1##.ogg\"><a href=\"##MEDIA1##.ogg\">##MEDIA1##.ogg</a></object>";\r
318                 \r
319                 // .ogm\r
320                 preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).ogm\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
321                 $media_replace[] ="<object type=\"application/ogm\" data=\"##MEDIA1##.ogm\" width=\"##WIDTH##\" height=\"##HEIGHT##\"><param name=\"src\" value=\"##MEDIA1##.ogm\"><a href=\"##MEDIA1##.ogg\">##MEDIA1##.ogm</a></object>";\r
322                 \r
323                 // .mid\r
324                 preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).mid\[/media\]#i",$text,$media_matches[],PREG_SET_ORDER);\r
325                 $media_replace[] ="<object type=\"application/x-midi\" data=\"##MEDIA1##.mid\" width=\"##WIDTH##\" height=\"##HEIGHT##\"><param name=\"src\" value=\"##MEDIA1##.mid\"><a href=\"##MEDIA1##.mid\">##MEDIA1##.mid</a></object>";\r
326                 \r
327                 $text = preg_replace("#\[media[0-9a-z\|]*\](.+[^\s\"]+).mid\[/media\]#i", "<object type=\"application/x-midi\" data=\"\\1.mid\" width=\"".$width."\" height=\"".$height."\"><param name=\"src\" value=\"\\1.mid\"><a href=\"\\1.mid\">\\1.mid</a></object>", $text);\r
328         \r
329                 // Executing the replace\r
330                 for ($i=0;$i<count($media_replace);$i++){\r
331                         foreach($media_matches[$i] as $media)\r
332                         {\r
333                                 \r
334                                 //find width and height for each matched media\r
335                                 if (preg_match("/\[media\|([0-9]*)\|([0-9]*)\]*/", $media[0], $matches)) \r
336                                 {\r
337                                         $width = $matches[1];\r
338                                         $height = $matches[2];\r
339                                 }\r
340                                 else\r
341                                 {\r
342                                         $width = 425;\r
343                                         $height = 350;\r
344                                 }\r
345                                 \r
346                                 //replace media tags with embedded media for each media tag\r
347                                 $media_input = $media_replace[$i];\r
348                                 $media_input = str_replace("##WIDTH##","$width",$media_input);\r
349                                 $media_input = str_replace("##HEIGHT##","$height",$media_input);\r
350                                 $media_input = str_replace("##MEDIA1##","$media[1]",$media_input);\r
351                                 $media_input = str_replace("##MEDIA2##","$media[2]",$media_input);\r
352                                 $text = str_replace($media[0],$media_input,$text);\r
353                         }\r
354                 }\r
355                 \r
356                 return $text;\r
357         }\r
358 \r
359         public static function makeClickable($text) {\r
360                 $text = ContentUtility::embedMedia($text);\r
361         \r
362                 // convert plain text URL to clickable URL.\r
363                 // Limited conversion: It doesn't cover the case when the stuff in front of the URL is not a word. For example:\r
364                 // <p>http://google.ca</p>\r
365                 // "http://google.ca" \r
366                 $text = preg_replace('/(^|[\n ])([\w]*?)((?<!(\[media\]))http(s)?:\/\/[\w]+[^ \,\"\n\r\t\)<]*)/is', \r
367                                      '$1$2<a href="$3">$3</a>', $text);\r
368                 \r
369                 // convert email address to clickable URL that pops up "send email" interface with the address filled in\r
370                 $text = preg_replace('/(?|<a href="mailto[\s]*:[\s]*([_a-zA-Z0-9\-]+(\.[_a-zA-Z0-9\-]+)*'.'\@'\r
371                                     .'[_a-zA-Z0-9\-]+(\.[_a-zA-Z0-9\-]+)*'.'(\.[a-zA-Z]{1,6})+)">(.*)<\/a>'\r
372                                     .'|((((([_a-zA-Z0-9\-]+(\.[_a-zA-Z0-9\-]+)*'.'\@'\r
373                                     .'[_a-zA-Z0-9\-]+(\.[_a-zA-Z0-9\-]+)*'.'(\.[a-zA-Z]{1,6})+))))))/i',\r
374                                                         "<a href=\"mailto:\\1\">\\5</a>",\r
375                                                         $text);\r
376                 \r
377                 // flv conversion needs to come after url conversion (2 lines above) otherwise the url to flowplayer swf file\r
378                 // in the script for a.flowplayerholder is converted\r
379                 $text = ContentUtility::embedFLV($text);\r
380                 \r
381                 return $text;\r
382         }\r
383 \r
384         public static function myCodes($text, $html = false) {\r
385                 global $_base_path;\r
386                 global $HTTP_USER_AGENT;\r
387         \r
388                 if (substr($HTTP_USER_AGENT,0,11) == 'Mozilla/4.7') {\r
389                         $text = str_replace('[quote]','</p><p class="block">',$text);\r
390                         $text = str_replace('[/quote]','</p><p>',$text);\r
391         \r
392                         $text = str_replace('[reply]','</p><p class="block">',$text);\r
393                         $text = str_replace('[/reply]','</p><p>',$text);\r
394                 } else {\r
395                         $text = str_replace('[quote]','<blockquote>',$text);\r
396                         $text = str_replace('[/quote]','</blockquote><p>',$text);\r
397         \r
398                         $text = str_replace('[reply]','</p><blockquote class="block"><p>',$text);\r
399                         $text = str_replace('[/reply]','</p></blockquote><p>',$text);\r
400                 }\r
401         \r
402                 $text = str_replace('[b]','<strong>',$text);\r
403                 $text = str_replace('[/b]','</strong>',$text);\r
404         \r
405                 $text = str_replace('[i]','<em>',$text);\r
406                 $text = str_replace('[/i]','</em>',$text);\r
407         \r
408                 $text = str_replace('[u]','<u>',$text);\r
409                 $text = str_replace('[/u]','</u>',$text);\r
410         \r
411                 $text = str_replace('[center]','<center>',$text);\r
412                 $text = str_replace('[/center]','</center><p>',$text);\r
413         \r
414                 /* colours */\r
415                 $text = str_replace('[blue]','<span style="color: blue;">',$text);\r
416                 $text = str_replace('[/blue]','</span>',$text);\r
417         \r
418                 $text = str_replace('[orange]','<span style="color: orange;">',$text);\r
419                 $text = str_replace('[/orange]','</span>',$text);\r
420         \r
421                 $text = str_replace('[red]','<span style="color: red;">',$text);\r
422                 $text = str_replace('[/red]','</span>',$text);\r
423         \r
424                 $text = str_replace('[purple]','<span style="color: purple;">',$text);\r
425                 $text = str_replace('[/purple]','</span>',$text);\r
426         \r
427                 $text = str_replace('[green]','<span style="color: green;">',$text);\r
428                 $text = str_replace('[/green]','</span>',$text);\r
429         \r
430                 $text = str_replace('[gray]','<span style="color: gray;">',$text);\r
431                 $text = str_replace('[/gray]','</span>',$text);\r
432         \r
433                 $text = str_replace('[op]','<span class="bigspacer"></span> <a href="',$text);\r
434                 $text = str_replace('[/op]','">'._AT('view_entire_post').'</a>',$text);\r
435         \r
436                 $text = str_replace('[head1]','<h2>',$text);\r
437                 $text = str_replace('[/head1]','</h2>',$text);\r
438         \r
439                 $text = str_replace('[head2]','<h3>',$text);\r
440                 $text = str_replace('[/head2]','</h3>',$text);\r
441         \r
442                 $text = str_replace('[cid]',$_base_path.'content.php?_cid='.$_SESSION['s_cid'],$text);\r
443         \r
444                 global $sequence_links, $_course_id, $_content_id;\r
445                 if ($_course_id > 0 && !isset($sequence_links) && $_content_id > 0) {\r
446                         global $contentManager;\r
447                         $sequence_links = $contentManager->generateSequenceCrumbs($_content_id);\r
448                 }\r
449                 if (isset($sequence_links['previous']) && $sequence_links['previous']['url']) {\r
450                         $text = str_replace('[pid]', $sequence_links['previous']['url'], $text);\r
451                 }\r
452                 if (isset($sequence_links['next']) && $sequence_links['next']['url']) {\r
453                         $text = str_replace('[nid]', $sequence_links['next']['url'], $text);\r
454                 }\r
455                 if (isset($sequence_links['resume']) && $sequence_links['resume']['url']) {\r
456                         $text = str_replace('[nid]', $sequence_links['resume']['url'], $text);\r
457                 }\r
458                 if (isset($sequence_links['first']) && $sequence_links['first']['url']) {\r
459                         $text = str_replace('[fid]', $sequence_links['first']['url'], $text);\r
460                 }\r
461         \r
462                 /* contributed by Thomas M. Duffey <tduffey at homeboyz.com> */\r
463             $html = !$html ? 0 : 1;\r
464             \r
465                 // little hack added by greg to add syntax highlighting without using <?php \?\>\r
466                 \r
467                 $text = str_replace("[code]","[code]<?php",$text);\r
468                 $text = str_replace("[/code]","?>[/code]",$text);\r
469         \r
470                 $text = preg_replace("/\[code\]\s*(.*)\s*\[\\/code\]/Usei", "ContentUtility::highlightCode(ContentUtility::fixQuotes('\\1'), $html)", $text);\r
471                 // now remove the <?php added above and leave the syntax colour behind.\r
472                 $text = str_replace("&lt;?php", "", $text);\r
473                 $text = str_replace("?&gt;", "", $text);\r
474         \r
475                 return $text;\r
476         }\r
477 \r
478         /* contributed by Thomas M. Duffey <tduffey at homeboyz.com> */\r
479         private static function highlightCode($code, $html) {\r
480                 // XHTMLize PHP highlight_string output until it gets fixed in PHP\r
481                 static $search = array(\r
482                         '<br>',\r
483                         '<font',\r
484                         '</font>',\r
485                         'color="');\r
486         \r
487                 static $replace = array(\r
488                         '<br />',\r
489                         '<span',\r
490                         '</span>',\r
491                         'style="color:');\r
492                 if (!$html) {\r
493                         $code = str_replace('&lt;', '<', $code);\r
494                         $code = str_replace("\r", '', $code);\r
495                 }\r
496         \r
497                 return str_replace($search, $replace, highlight_string($code, true));\r
498         }\r
499         \r
500         /* contributed by Thomas M. Duffey <tduffey at homeboyz.com> */\r
501         private static function fixQuotes($text){\r
502                 return str_replace('\\"', '"', $text);\r
503         }\r
504 \r
505         public static function imageReplace($text) {\r
506                 /* image urls do not require http:// */\r
507                 \r
508         //      $text = eregi_replace("\[image(\|)?([[:alnum:][:space:]]*)\]" .\r
509         //                                               "[:space:]*" .\r
510         //                                               "([[:alnum:]#?/&=:\"'_.-]+)" .\r
511         //                                               "[:space:]*" .\r
512         //                                               "((\[/image\])|(.*\[/image\]))",\r
513         //                                "<img src=\"\\3\" alt=\"\\2\" />",\r
514         //                                $text);\r
515                  \r
516                 $text = preg_replace("/\[image(\|)?([a-zA-Z0-9\s]*)\]".\r
517                                      "[\s]*".\r
518                                      "([a-zA-Z0-9\#\?\/\&\=\:\\\"\'\_\.\-]+)[\s]*".\r
519                                      "((\[\/image\])|(.*\[\/image\]))/i",\r
520                                           "<img src=\"\\3\" alt=\"\\2\" />",\r
521                                           $text);\r
522                                           \r
523                 return $text;\r
524         }\r
525         \r
526         private static function formatFinalOutput($text, $nl2br = true) {\r
527                 global $_base_path;\r
528         \r
529                 $text = str_replace('CONTENT_DIR/', '', $text);\r
530                 if ($nl2br) {\r
531                         return nl2br(ContentUtility::imageReplace(ContentUtility::makeClickable(ContentUtility::myCodes(' '.$text, false))));\r
532                 }\r
533         \r
534                 return ContentUtility::imageReplace(ContentUtility::makeClickable(ContentUtility::myCodes(' '.$text, true)));\r
535         }\r
536 \r
537         /**\r
538         * This function converts the input string into AContent html content string \r
539         * @access  public\r
540         * @param   $input: input string\r
541         *          $html: whether the input is in html\r
542         * @return  converted AContent html content string\r
543         * @author  Cindy Qi Li\r
544         */\r
545         public static function formatContent($input, $html = 0) {\r
546                 global $_base_path, $_config;\r
547         \r
548                 if (!$html) {\r
549                         $input = str_replace('<', '&lt;', $input);\r
550                         $input = str_replace('&lt;?php', '<?php', $input); // for bug #2087\r
551                 } elseif ($html==2) {\r
552                         $output = '<iframe width="100%" frameborder="0" id="content_frame" marginheight="0" marginwidth="0" src="'.$input.'"></iframe>';\r
553                         $output .=      '<script type="text/javascript">\r
554                                                 function resizeIframe() {\r
555                                                         var height = document.documentElement.clientHeight;\r
556                                                         \r
557                                                         // not sure how to get this dynamically\r
558                                                         height -= 20; /* whatever you set your body bottom margin/padding to be */\r
559                                                         \r
560                                                         document.getElementById(\'content_frame\').style.height = height +"px";\r
561                                                         \r
562                                                 };\r
563                                                 document.getElementById(\'content_frame\').onload = resizeIframe;\r
564                                                 window.onresize = resizeIframe;\r
565                                                 </script>';\r
566                         return $output;\r
567                 }\r
568         \r
569                 /* Commented by Cindy Qi Li on Jan 12, 2010\r
570                  * AContent does not support glossary\r
571                 // do the glossary search and replace:\r
572                 if (is_array($glossary)) {\r
573                         foreach ($glossary as $k => $v) {\r
574                                 $k = urldecode($k);\r
575                                 $v = str_replace("\n", '<br />', $v);\r
576                                 $v = str_replace("\r", '', $v);\r
577         \r
578                                 // escape special characters\r
579                                 $k = preg_quote($k);\r
580         \r
581                                 $k = str_replace('&lt;', '<', $k);\r
582                                 $k = str_replace('/', '\/', $k);\r
583         \r
584                                 $original_term = $k;\r
585                                 $term = $original_term;\r
586         \r
587                                 $term = '(\s*'.$term.'\s*)';\r
588                                 $term = str_replace(' ','((<br \/>)*\s*)', $term); \r
589         \r
590                                 $def = htmlspecialchars($v, ENT_QUOTES, 'UTF-8');               \r
591                                 if ($simple) {\r
592                                         $input = preg_replace\r
593                                                         ("/(\[\?\])$term(\[\/\?\])/i",\r
594                                                         '<a href="'.$simple.'glossary.html#'.urlencode($original_term).'" target="body" class="at-term">\\2</a>',\r
595                                                         $input);\r
596                                 } else {\r
597                                         $input = preg_replace\r
598                                                 ("/(\[\?\])$term(\[\/\?\])/i",\r
599                                                 '\\2<sup><a class="tooltip" href="'.$_base_path.'mods/_core/glossary/index.php?g_cid='.$_SESSION['s_cid'].htmlentities(SEP).'w='.urlencode($original_term).'#term" title="'.addslashes($original_term).': '.$def.'">?</a></sup>',$input);\r
600                                 }\r
601                         }\r
602                 } else if (!$user_glossary) {\r
603                         $input = str_replace(array('[?]','[/?]'), '', $input);\r
604                 }\r
605                 */\r
606 \r
607                 \r
608                 $input = str_replace('CONTENT_DIR', '', $input);\r
609         \r
610                 if (isset($_config['latex_server']) && $_config['latex_server']) {\r
611                         // see: http://www.forkosh.com/mimetex.html\r
612                         $input = preg_replace('/\[tex\](.*?)\[\/tex\]/sie', "'<img src=\"'.\$_config['latex_server'].rawurlencode('$1').'\" align=\"middle\">'", $input);\r
613                 }\r
614         \r
615                 if ($html) {\r
616                         $x = ContentUtility::formatFinalOutput($input, false);\r
617                         return $x;\r
618                 }\r
619         \r
620         // the following has been taken out for this: \r
621         // http://atutor.ca/atutor/mantis/view.php?id=4593\r
622         // @date Oct 18, 2010\r
623         //      $output = ContentUtility::formatFinalOutput($input);\r
624         $output = $input;\r
625                 $output = '<p>'.$input.'</p>';\r
626         \r
627                 return $output;\r
628         }\r
629         \r
630         /**\r
631          * This function returns html string of "table of content"\r
632          * @access: public\r
633          * @param: $content: a string\r
634          * @return: a html string of "table of content"\r
635          */\r
636         public static function getContentTable($content)\r
637         {\r
638                 preg_match_all("/<(h[\d]+)[^>]*>(.*)<\/(\s*)\\1(\s*)>/i", $content, $found_headers, PREG_SET_ORDER);\r
639                 \r
640                 if (count($found_headers) == 0) return array("", $content);\r
641                 else\r
642                 {\r
643                         $num_of_headers = 0;\r
644         \r
645                         for ($i = 0; $i < count($found_headers); $i++)\r
646                         {\r
647                                 $div_id = "_header_" . $num_of_headers++;\r
648                                 \r
649                                 if ($i == 0)\r
650                                 {\r
651                                         $content_table = "<div id=\"toc\">\n<fieldset id=\"toc\"><legend>". _AT("table_of_contents")."</legend>\n";\r
652                                 }\r
653         \r
654                                 $content = str_replace($found_headers[$i][0], '<div id="'.$div_id.'">'.$found_headers[$i][0].'</div>', $content);\r
655                                 $content_table .= '<a href="'.$_SERVER["REQUEST_URI"].'#'.$div_id.'" class="'.$found_headers[$i][1].'">'. $found_headers[$i][2]."</a>\n";\r
656         \r
657                                 if ($i == count($found_headers) - 1)\r
658                                 {\r
659                                         $content_table .= "</fieldset></div><br />";\r
660                                 }\r
661                         }\r
662                         return array($content_table, $content);\r
663                 }\r
664         }\r
665         \r
666         /**\r
667          * This function returns an array of content tools' shortcuts\r
668          * @access: public\r
669          * @param: $content_row: an array of the current content information\r
670          * @return: an array of all the tool short cuts that apply to the current content or content folder\r
671          */\r
672         public static function getToolShortcuts($content_row)\r
673         {\r
674                 global $_current_user, $_base_href, $contentManager, $_course_id;\r
675                 \r
676                 if (((!$content_row['content_parent_id'] && ($_SESSION['packaging'] == 'top'))\r
677                       || ($_SESSION['packaging'] == 'all'))\r
678                           || (isset($_current_user) && $_current_user->isAuthor($_course_id))) {\r
679                 \r
680                         $tool_shortcuts[] = array(\r
681                                   'title' => _AT('export_content_in_cp'), \r
682                                   'url' => $_base_href . 'home/ims/ims_export.php?_cid='.$content_row['content_id'],\r
683                                   'icon' => $_base_href . 'themes/'.$_SESSION['prefs']['PREF_THEME'].'/images/export.png');\r
684                         $tool_shortcuts[] = array(\r
685                                   'title' => _AT('export_content_in_cc'), \r
686                                   'url' => $_base_href . 'home/imscc/ims_export.php?_cid='.$content_row['content_id'].SEP.'to_a4a=1',\r
687                                   'icon' => $_base_href . 'themes/'.$_SESSION['prefs']['PREF_THEME'].'/images/export_cc.png');\r
688                 }\r
689                 \r
690                 if (isset($_current_user) && $_current_user->isAuthor($_course_id)) {\r
691                         if ($content_row['content_type'] == CONTENT_TYPE_CONTENT || $content_row['content_type'] == CONTENT_TYPE_WEBLINK) {\r
692                                 $tool_shortcuts[] = array(\r
693                                           'title' => _AT('edit_this_page'),   \r
694                                            'url' => $_base_href . 'home/editor/edit_content.php?_cid='.$content_row['content_id'],\r
695                                           'icon' => $_base_href . 'images/medit.gif');\r
696                         }\r
697                 \r
698                         $tool_shortcuts[] = array(\r
699                           'title' => _AT('add_sibling_folder'), \r
700                           'url' => $_base_href .\r
701                                 'home/editor/edit_content_folder.php?pid='.$contentManager->_menu_info[$content_row['content_id']]['content_parent_id'].SEP.'_course_id='.$_course_id,\r
702                            'icon' => $_base_href . 'images/add_sibling_folder.gif');\r
703 \r
704                         if ($content_row['content_type'] == CONTENT_TYPE_FOLDER || $content_row['content_type'] == CONTENT_TYPE_WEBLINK) {\r
705                                 $tool_shortcuts[] = array(\r
706                                   'title' => _AT('add_sub_folder'), \r
707                                   'url' => $_base_href .\r
708                                         'home/editor/edit_content_folder.php?_course_id='.$_course_id.SEP.'pid='.$content_row['content_id'],\r
709                                    'icon' => $_base_href . 'images/add_sub_folder.gif');\r
710                         }\r
711                         \r
712                         $tool_shortcuts[] = array(\r
713                           'title' => _AT('add_sibling_page'), \r
714                           'url' => $_base_href .\r
715                                 'home/editor/edit_content.php?pid='.$contentManager->_menu_info[$content_row['content_id']]['content_parent_id'].SEP.'_course_id='.$_course_id,\r
716                           'icon' => $_base_href . 'images/add_sibling_page.gif');\r
717                         \r
718                         if ($content_row['content_type'] == CONTENT_TYPE_CONTENT || $content_row['content_type'] == CONTENT_TYPE_WEBLINK) {\r
719                                 $tool_shortcuts[] = array(\r
720                                   'title' => _AT('delete_this_page'),   \r
721                                   'url' => $_base_href . 'home/editor/delete_content.php?_cid='.$content_row['content_id'],\r
722                                   'icon' => $_base_href . 'images/page_delete.gif');\r
723                         }\r
724                         else if ($content_row['content_type'] == CONTENT_TYPE_FOLDER) {\r
725                                 $tool_shortcuts[] = array(\r
726                                   'title' => _AT('add_sub_page'),       \r
727                                   'url' => $_base_href . 'home/editor/edit_content.php?_course_id='.$_course_id.SEP.'pid='.$content_row['content_id'],\r
728                                   'icon' => $_base_href . 'images/add_sub_page.gif');\r
729                                 \r
730                                 $tool_shortcuts[] = array(\r
731                                   'title' => _AT('delete_this_folder'),         \r
732                                   'url' => $_base_href . 'home/editor/delete_content.php?_cid='.$content_row['content_id'],\r
733                                   'icon' => $_base_href . 'images/page_delete.gif');\r
734                         }\r
735                 }\r
736                 return $tool_shortcuts;\r
737 \r
738 //      if (isset($_current_user) && $_current_user->isAuthor($_course_id)) {\r
739 //              $shortcuts[] = array('title' => _AT('add_sub_folder'),   'url' => $_base_href . 'home/editor/edit_content_folder.php?_course_id='.$_course_id.'pid='.$cid);\r
740 //              \r
741 ////            $shortcuts[] = array('title' => _AT('add_top_page'),     'url' => $_base_href . 'home/editor/edit_content.php?_course_id='.$_course_id, 'icon' => $_base_href . 'images/page_add.gif');\r
742 //              if ($contentManager->_menu_info[$cid]['content_parent_id']) {\r
743 //                      $shortcuts[] = array('title' => _AT('add_sibling_page'), 'url' => $_base_href .\r
744 //                              'home/editor/edit_content.php?_course_id='.$_course_id.SEP.'pid='.$contentManager->_menu_info[$cid]['content_parent_id'], 'icon' => $_base_href . 'images/page_add_sibling.gif');\r
745 //              }\r
746 //      \r
747 //              $shortcuts[] = array('title' => _AT('add_sub_page'),     'url' => $_base_href . 'home/editor/edit_content.php?_course_id='.$_course_id.SEP.'pid='.$cid);\r
748 //              $shortcuts[] = array('title' => _AT('delete_this_folder'), 'url' => $_base_href . 'home/editor/delete_content.php?_cid='.$cid, 'icon' => $_base_href . 'images/page_delete.gif');\r
749 //      }\r
750         }\r
751         \r
752         /**\r
753         * replace source object with alternatives according to user's preferences\r
754         * @access       public\r
755         * @param        $cid:                           content id.\r
756         * @param        $content:                       the original content page ($content_row['text'], from content.php).\r
757         * @param    $info_only:         when "true", return the array of info (has_text_alternative, has_audio_alternative, has_visual_alternative, has_sign_lang_alternative)\r
758         * @param    $only_on_secondary_type: \r
759         * @return       string                          $content: the content page with the appropriated resources.\r
760         * @see          $db                             from include/vitals.inc.php\r
761         * @author       Cindy Qi Li\r
762         */\r
763         public static function applyAlternatives($cid, $content, $info_only = false, $only_on_secondary_type = 0){\r
764                 global $db, $_course_id;\r
765                 \r
766                 include_once(TR_INCLUDE_PATH.'classes/DAO/DAO.class.php');\r
767                 $dao = new DAO();\r
768                 \r
769         $video_exts = array("mpg", "avi", "wmv", "mov", "swf", "mp4", "flv");\r
770         \r
771         $audio_exts = array("mp3", "wav", "ogg", "mid");\r
772         $audio_width = 425;\r
773         $audio_height = 27;\r
774 \r
775                 $txt_exts = array("txt", "html", "htm");\r
776                 $image_exts = array("gif", "bmp", "png", "jpg", "jpeg", "png", "tif");\r
777                 $only_on_secondary_type = intval($only_on_secondary_type);\r
778                                 \r
779                 // intialize the 4 returned values when $info_only is on\r
780                 if ($info_only)\r
781                 {\r
782                         $has_text_alternative = false;\r
783                         $has_audio_alternative = false;\r
784                         $has_visual_alternative = false;\r
785                         $has_sign_lang_alternative = false;\r
786                 }\r
787 \r
788                 if (!$info_only && !$only_on_secondary_type && \r
789                     ($_SESSION['prefs']['PREF_USE_ALTERNATIVE_TO_TEXT']==0) && \r
790                     ($_SESSION['prefs']['PREF_USE_ALTERNATIVE_TO_AUDIO']==0) && \r
791                     ($_SESSION['prefs']['PREF_USE_ALTERNATIVE_TO_VISUAL']==0)) \r
792                 {\r
793                         //No user's preferences related to content format are declared\r
794                         if (!$info_only) {\r
795                                 return $content;\r
796                         } else {\r
797                                 return array($has_text_alternative, $has_audio_alternative, $has_visual_alternative, $has_sign_lang_alternative);\r
798                         }\r
799                 }\r
800         \r
801                 // get all relations between primary resources and their alternatives\r
802         $sql = "SELECT DISTINCT c.content_path, pr.resource,  prt.type_id primary_type,\r
803                        sr.secondary_resource, srt.type_id secondary_type\r
804                           FROM ".TABLE_PREFIX."primary_resources pr, ".\r
805                                  TABLE_PREFIX."primary_resources_types prt,".\r
806                                  TABLE_PREFIX."secondary_resources sr,".\r
807                                  TABLE_PREFIX."secondary_resources_types srt,".\r
808                                  TABLE_PREFIX."content c\r
809                          WHERE pr.content_id=".$cid."\r
810                                AND pr.primary_resource_id = prt.primary_resource_id\r
811                                AND pr.primary_resource_id = sr.primary_resource_id\r
812                                AND sr.language_code='".$_SESSION['lang']."'\r
813                                AND sr.secondary_resource_id = srt.secondary_resource_id\r
814                            AND pr.content_id = c.content_id";\r
815                 if ($only_on_secondary_type > 0) {\r
816                         $sql .= " AND srt.type_id=".$only_on_secondary_type;\r
817                 }\r
818                 $sql .= " ORDER BY pr.primary_resource_id, prt.type_id";\r
819                         \r
820                 $rows = $dao->execute($sql);\r
821         \r
822                 if (!is_array($rows)) {\r
823                         if (!$info_only) {\r
824                                 return $content;\r
825                         } else {\r
826                                 return array($has_text_alternative, $has_audio_alternative, $has_visual_alternative, $has_sign_lang_alternative);\r
827                         }\r
828                 }\r
829                 \r
830                 $primary_resource_names = array();\r
831                 foreach ($rows as $row) {\r
832                         // if the primary resource is defined with multiple resource type,\r
833                         // the primary resource would be replaced/appended multiple times.\r
834                         // This is what we want at applying alternatives by default, but\r
835                         // not when only one secondary type is chosen to apply.\r
836                         // This fix is to remove the duplicates on the same primary resource.\r
837                         // A dilemma of this fix is, for example, if the primary resource type\r
838                         // is "text" and "visual", but\r
839                         // $_SESSION['prefs']['PREF_ALT_TO_TEXT_APPEND_OR_REPLACE'] == 'replace'\r
840                         // $_SESSION['prefs']['PREF_ALT_TO_VISUAL_APPEND_OR_REPLACE'] == 'append'\r
841                         // so, should replace happen or append happen? With this fix, whichever\r
842                         // the first in the sql return gets preserved in the array and processed.\r
843                         // The further improvement is requried to keep rows based on the selected\r
844                         // secondary type (http://www.atutor.ca/atutor/mantis/view.php?id=4598). \r
845                         if ($only_on_secondary_type > 0) {\r
846                                 if (in_array($row['resource'], $primary_resource_names)) {\r
847                                         continue;\r
848                                 } else {\r
849                                         $primary_resource_names[] = $row['resource'];\r
850                                 }\r
851                         }\r
852                         $alternative_rows[] = $row;\r
853             \r
854             $youtube_playURL = ContentUtility::convertYoutubeWatchURLToPlayURL($row['resource']);\r
855             \r
856             if ($row['resource'] <> $youtube_playURL) {\r
857                 $row['resource'] = $youtube_playURL;\r
858                 $alternative_rows[] = $row;\r
859             }\r
860         }\r
861 \r
862         foreach ($alternative_rows as $row) \r
863                 {\r
864                         if ($info_only || $only_on_secondary_type ||\r
865                             ($_SESSION['prefs']['PREF_USE_ALTERNATIVE_TO_TEXT']==1 && $row['primary_type']==3 &&\r
866                             ($_SESSION['prefs']['PREF_ALT_TO_TEXT']=="audio" && $row['secondary_type']==1 || \r
867                              $_SESSION['prefs']['PREF_ALT_TO_TEXT']=="visual" && $row['secondary_type']==4 || \r
868                              $_SESSION['prefs']['PREF_ALT_TO_TEXT']=="sign_lang" && $row['secondary_type']==2)) ||\r
869                              \r
870                              ($_SESSION['prefs']['PREF_USE_ALTERNATIVE_TO_AUDIO']==1 && $row['primary_type']==1 &&\r
871                              ($_SESSION['prefs']['PREF_ALT_TO_AUDIO']=="visual" && $row['secondary_type']==4 || \r
872                               $_SESSION['prefs']['PREF_ALT_TO_AUDIO']=="text" && $row['secondary_type']==3 || \r
873                               $_SESSION['prefs']['PREF_ALT_TO_AUDIO']=="sign_lang" && $row['secondary_type']==2)) ||\r
874                               \r
875                              ($_SESSION['prefs']['PREF_USE_ALTERNATIVE_TO_VISUAL']==1 && $row['primary_type']==4 &&\r
876                              ($_SESSION['prefs']['PREF_ALT_TO_VISUAL']=="audio" && $row['secondary_type']==1 || \r
877                               $_SESSION['prefs']['PREF_ALT_TO_VISUAL']=="text" && $row['secondary_type']==3 || \r
878                               $_SESSION['prefs']['PREF_ALT_TO_VISUAL']=="sign_lang" && $row['secondary_type']==2))\r
879                             )\r
880                         {\r
881                                 $ext = substr($row['secondary_resource'], strrpos($row['secondary_resource'], '.')+1);\r
882                                 \r
883                                 // alternative is video\r
884                                 if (in_array($ext, $video_exts)|| in_array($ext, $audio_exts) || \r
885                     preg_match("/http:\/\/.*youtube.com\/watch.*/", $row['secondary_resource'])) {\r
886                     if (in_array($ext, $audio_exts)) {\r
887                         // display audio medias in a smaller width/height (425 * 27)\r
888                         // A hack for now to handle audio media player size\r
889                         $target = '[media|'.$audio_width.'|'.$audio_height.']'.$row['secondary_resource'].'[/media]';\r
890                     } else {\r
891                         // use default media size for video medias\r
892                         $target = '[media]'.$row['secondary_resource'].'[/media]';\r
893                     }\r
894                 }\r
895                                 // a text primary to be replaced by a visual alternative \r
896                                 else if (in_array($ext, $txt_exts))\r
897                                 {\r
898                                         if ($row['content_path'] <> '') \r
899                                                 $file_location = $row['content_path'].'/'.$row['secondary_resource'];\r
900                                         else \r
901                                                 $file_location = $row['secondary_resource'];\r
902                                         \r
903                                         $file = TR_CONTENT_DIR.$_SESSION['course_id'] . '/'.$file_location;\r
904                                         $target = '<br />'.file_get_contents($file);\r
905                                         \r
906                                         // check whether html file\r
907                                         if (preg_match('/.*\<html.*\<\/html\>.*/s', $target))\r
908                                         { // is a html file, use iframe to display\r
909                                                 // get real path to the text file\r
910                                                 if (defined('TR_FORCE_GET_FILE') && TR_FORCE_GET_FILE) {\r
911                                                         $course_base_href = 'get.php/';\r
912                                                 } else {\r
913                                                         $course_base_href = 'content/' . $_SESSION['course_id'] . '/';\r
914                                                 }\r
915                 \r
916                                                 $file = TR_BASE_HREF . $course_base_href.$file_location;\r
917                                                         \r
918                                                 $target = '<iframe width="100%" frameborder="0" class="autoHeight" scrolling="auto" src="'.$file.'"></iframe>';\r
919                                         }\r
920                                         else\r
921                                         { // is a text file, insert/replace into content\r
922                                                 $target = nl2br($target);\r
923                                         }\r
924                                 } \r
925                                 else if (in_array($ext, $image_exts))\r
926                                         $target = '<img border="0" alt="'._AT('alternate_text').'" src="'.$row['secondary_resource'].'"/>';\r
927                                 // otherwise\r
928                                 else\r
929                                         $target = '<p><a href="'.$row['secondary_resource'].'">'.$row['secondary_resource'].'</a></p>';\r
930         \r
931                                 // replace or append the target alternative to the source\r
932                                 if (($row['primary_type']==3 && $_SESSION['prefs']['PREF_ALT_TO_TEXT_APPEND_OR_REPLACE'] == 'replace') ||\r
933                                         ($row['primary_type']==1 && $_SESSION['prefs']['PREF_ALT_TO_AUDIO_APPEND_OR_REPLACE']=='replace') ||\r
934                                         ($row['primary_type']==4 && $_SESSION['prefs']['PREF_ALT_TO_VISUAL_APPEND_OR_REPLACE']=='replace'))\r
935                                         $pattern_replace_to = '${1}'."\n".$target."\n".'${3}';\r
936                 else\r
937                     $pattern_replace_to = '${1}${2}'."<br /><br />\n".$target."\n".'${3}';\r
938 \r
939                 // *** Alternative replace/append starts from here ***\r
940                 $processed = false;    // one primary resource is only processed once \r
941                 \r
942                 // append/replace target alternative to [media]source[/media]\r
943                 if (!$processed && preg_match("/".preg_quote("[media").".*".preg_quote("]".$row['resource']."[/media]", "/")."/sU", $content))\r
944                 {\r
945                     $processed = true;\r
946                                         if (!$info_only) {\r
947                                                 $content = preg_replace("/(.*)(".preg_quote("[media").".*".preg_quote("]".$row['resource']."[/media]", "/").")(.*)/sU", \r
948                                              $pattern_replace_to, $content);\r
949                                         } else {\r
950                                                 if ($row['secondary_type'] == 1) $has_audio_alternative = true;\r
951                                                 if ($row['secondary_type'] == 2) $has_sign_lang_alternative = true;\r
952                                                 if ($row['secondary_type'] == 3) $has_text_alternative = true;\r
953                                                 if ($row['secondary_type'] == 4) $has_visual_alternative = true;\r
954                                         }\r
955                                 }\r
956                                 \r
957                                 // append/replace target alternative to <img ... src="source" ...></a>\r
958                                 if (!$processed && preg_match("/\<img.*src=\"".preg_quote($row['resource'], "/")."\".*\/\>/sU", $content))\r
959                 {\r
960                     $processed = true;\r
961                                         if (!$info_only) {\r
962                                                 $content = preg_replace("/(.*)(\<img.*src=\"".preg_quote($row['resource'], "/")."\".*\/\>)(.*)/sU", \r
963                                                         $pattern_replace_to, $content);\r
964                                         } else {\r
965                                                 if ($row['secondary_type'] == 1) $has_audio_alternative = true;\r
966                                                 if ($row['secondary_type'] == 2) $has_sign_lang_alternative = true;\r
967                                                 if ($row['secondary_type'] == 3) $has_text_alternative = true;\r
968                                                 if ($row['secondary_type'] == 4) $has_visual_alternative = true;\r
969                                         }\r
970                                 }\r
971                                 \r
972                                 // append/replace target alternative to <object ... source ...></object>\r
973                 if (!$processed && preg_match("/\<object.*".preg_quote($row['resource'], "/").".*\<\/object\>/sU", $content))\r
974                 {\r
975                     $processed = true;\r
976                     if (!$info_only) {\r
977                         $content = preg_replace("/(.*)(\<object.*".preg_quote($row['resource'], "/").".*\<\/object\>)(.*)/sU", \r
978                                                         $pattern_replace_to, $content);\r
979                                         } else {\r
980                                                 if ($row['secondary_type'] == 1) $has_audio_alternative = true;\r
981                                                 if ($row['secondary_type'] == 2) $has_sign_lang_alternative = true;\r
982                                                 if ($row['secondary_type'] == 3) $has_text_alternative = true;\r
983                                                 if ($row['secondary_type'] == 4) $has_visual_alternative = true;\r
984                                         }\r
985                                 }\r
986         \r
987                                 // append/replace target alternative to <a>...source...</a> or <a ...source...>...</a>\r
988                 // skip this "if" when the source object has been processed in aboved <img> tag\r
989                 if (!$processed && preg_match("/\<a.*".preg_quote($row['resource'], "/").".*\<\/a\>/sU", $content))\r
990                 {\r
991                     $processed = true;\r
992                     if (!$info_only) {\r
993                         $content = preg_replace("/(.*)(\<a.*".preg_quote($row['resource'], "/").".*\<\/a\>)(.*)/sU",\r
994                                                         $pattern_replace_to, $content);\r
995                                         } else {\r
996                                                 if ($row['secondary_type'] == 1) $has_audio_alternative = true;\r
997                                                 if ($row['secondary_type'] == 2) $has_sign_lang_alternative = true;\r
998                                                 if ($row['secondary_type'] == 3) $has_text_alternative = true;\r
999                                                 if ($row['secondary_type'] == 4) $has_visual_alternative = true;\r
1000                                         }\r
1001                                 }\r
1002         \r
1003                                 // append/replace target alternative to <embed ... source ...>\r
1004                                 if (!$processed && preg_match("/\<embed.*".preg_quote($row['resource'], "/").".*\>/sU", $content))\r
1005                 {\r
1006                     $processed = true;\r
1007                                         if (!$info_only) {\r
1008                                                 $content = preg_replace("/(.*)(\<embed.*".preg_quote($row['resource'], "/").".*\>)(.*)/sU", \r
1009                                                         $pattern_replace_to, $content);\r
1010                                         } else {\r
1011                                                 if ($row['secondary_type'] == 1) $has_audio_alternative = true;\r
1012                                                 if ($row['secondary_type'] == 2) $has_sign_lang_alternative = true;\r
1013                                                 if ($row['secondary_type'] == 3) $has_text_alternative = true;\r
1014                                                 if ($row['secondary_type'] == 4) $has_visual_alternative = true;\r
1015                                         }\r
1016                                 }\r
1017                         }\r
1018                 }\r
1019                 \r
1020                 if (!$info_only) {\r
1021                         return $content;\r
1022                 } else {\r
1023                         return array($has_text_alternative, $has_audio_alternative, $has_visual_alternative, $has_sign_lang_alternative);\r
1024                 }\r
1025         }       \r
1026                 \r
1027         /**\r
1028          * This function save the last content_id accessed by current user on a course into db and set $_SESSION['s_cid']\r
1029          * @access: public\r
1030          * @param: $content_id\r
1031          * @return: save $content_id, the last visited one of the current user, into db and session\r
1032          */\r
1033         public static function saveLastCid($content_id)\r
1034         {\r
1035                 global $_course_id;\r
1036                 \r
1037                 if (!$content_id || !isset($_SESSION['user_id'])) return;\r
1038                 \r
1039                 include_once(TR_INCLUDE_PATH.'classes/DAO/UserCoursesDAO.class.php');\r
1040                 \r
1041                 $userCoursesDAO = new UserCoursesDAO();\r
1042                 if ($userCoursesDAO->isExist($_SESSION['user_id'], $_course_id))\r
1043                 {\r
1044                         $userCoursesDAO->UpdateLastCid($_SESSION['user_id'], $_course_id, $content_id);\r
1045                         $_SESSION['s_cid'] = $content_id;\r
1046                 }\r
1047         }\r
1048 }\r
1049 ?>