2 /************************************************************************/
4 /************************************************************************/
5 /* Copyright (c) 2010 */
6 /* Inclusive Design Institute */
8 /* This program is free software. You can redistribute it and/or */
9 /* modify it under the terms of the GNU General Public License */
10 /* as published by the Free Software Foundation. */
11 /************************************************************************/
13 if (!defined('TR_INCLUDE_PATH')) { exit; }
14 require(TR_INCLUDE_PATH . 'classes/DAO/LanguageTextDAO.class.php');
16 /**********************************************************************************/
17 /* Output functions found in this file, in order:
21 /**********************************************************************************/
24 * Converts language code to actual language message, caches them according to page url
26 * @param args unlimited number of arguments allowed but first arg MUST be name of the language variable/term
27 * i.e $args[0] = the term to the format string $_template[term]
28 * $args[1..x] = optional arguments to the formatting string
29 * @return string|array full resulting message
30 * @see $db in include/vitals.inc.php
31 * @see cache() in include/phpCache/phpCache.inc.php
32 * @see cache_variable() in include/phpCache/phpCache.inc.php
33 * @author Joel Kronenberg
36 global $_cache_template, $lang_et, $_rel_url;
39 $args = func_get_args();
41 if ($args[0] == "") return "";
43 $languageTextDAO = new LanguageTextDAO();
46 if (!is_array($args[0])) {
48 * Added functionality for translating language code String (TR_ERROR|TR_INFOS|TR_WARNING|TR_FEEDBACK).*
49 * to its text and returning the result. No caching needed.
50 * @author Jacek Materna
53 // Check for specific language prefix, extendible as needed
54 // 0002767: a substring+in_array test should be faster than a preg_match test.
55 // replaced the preg_match with a test of the substring.
56 $sub_arg = substr($args[0], 0, 7); // 7 is the shortest type of msg (TR_INFO)
57 if (in_array($sub_arg, array('TR_ERRO','TR_INFO','TR_WARN','TR_FEED','TR_CONF'))) {
58 global $_base_path, $addslashes;
60 $args[0] = $addslashes($args[0]);
62 /* get $_msgs_new from the DB */
63 $rows = $languageTextDAO->getMsgByTermAndLang($args[0], $_SESSION['lang']);
69 // do not cache key as a digit (no contstant(), use string)
70 $msgs = str_replace('SITE_URL/', $_base_path, $row['text']);
71 if (defined('TR_DEVEL') && TR_DEVEL) {
72 $msgs .= ' <small><small>('. $args[0] .')</small></small>';
80 // a template variable
81 if (!isset($_template)) {
82 $url_parts = parse_url(TR_BASE_HREF);
83 $name = substr($_SERVER['PHP_SELF'], strlen($url_parts['path'])-1);
85 if ( !($lang_et = cache(120, 'lang', $_SESSION['lang'].'_'.$name)) ) {
86 /* get $_template from the DB */
87 $rows = $languageTextDAO->getAllTemplateByLang($_SESSION['lang']);
91 foreach ($rows as $id => $row)
93 //Do not overwrite the variable that existed in the cache_template already.
94 //The edited terms (_c_template) will always be at the top of the resultset
96 if (isset($_cache_template[$row['term']])){
100 // saves us from doing an ORDER BY
101 if ($row['language_code'] == $_SESSION['lang']) {
102 $_cache_template[$row['term']] = stripslashes($row['text']);
103 } else if (!isset($_cache_template[$row['term']])) {
104 $_cache_template[$row['term']] = stripslashes($row['text']);
109 cache_variable('_cache_template');
110 endcache(true, false);
112 $_template = $_cache_template;
115 $num_args = func_num_args();
116 if (is_array($args[0])) {
118 $num_args = count($args);
120 $format = array_shift($args);
122 if (isset($_template[$format]) && count($args) > 0) {
123 $outString = vsprintf($_template[$format], $args);
124 $str = ob_get_contents();
129 if ($outString === false) {
130 return ('[Error parsing language. Variable: <code>'.$format.'</code>. Language: <code>'.$_SESSION['lang'].'</code> ]');
133 if (empty($outString)) {
135 $rows = $languageTextDAO->getByTermAndLang($format, $_SESSION['lang']);
139 $_template[$row['term']] = stripslashes($row['text']);
140 $outString = $_template[$row['term']];
143 if (empty($outString)) {
144 return ('[ '.$format.' ]');
152 The following options were added as language dependant:
153 %D: A textual representation of a week, three letters Mon through Sun
154 %F: A full textual representation of a month, such as January or March January through December
155 %l (lowercase 'L'): A full textual representation of the day of the week Sunday through Saturday
156 %M: A short textual representation of a month, three letters Jan through Dec
158 Support for the following maybe added later:
159 ?? %S: English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with j
160 ?? %a: Lowercase Ante meridiem and Post meridiem am or pm
161 ?? %A: Uppercase Ante meridiem and Post meridiem AM or PM
164 TR_DATE_MYSQL_DATETIME: YYYY-MM-DD HH:MM:SS
165 TR_DATE_MYSQL_TIMESTAMP_14: YYYYMMDDHHMMSS
166 TR_DATE_UNIX_TIMESTAMP: seconds since epoch
167 TR_DATE_INDEX_VALUE: 0-x, index into a date array
169 function AT_date($format='%Y-%M-%d', $timestamp = '', $format_type=TR_DATE_MYSQL_DATETIME) {
170 static $day_name_ext, $day_name_con, $month_name_ext, $month_name_con;
173 if (!isset($day_name_ext)) {
174 $day_name_ext = array( 'date_sunday',
182 $day_name_con = array( 'date_sun',
190 $month_name_ext = array('date_january',
203 $month_name_con = array('date_jan',
217 if ($format_type == TR_DATE_INDEX_VALUE) {
218 // apply timezone offset
219 apply_timezone($timestamp);
221 if ($format == '%D') {
222 return _AT($day_name_con[$timestamp-1]);
223 } else if ($format == '%l') {
224 return _AT($day_name_ext[$timestamp-1]);
225 } else if ($format == '%F') {
226 return _AT($month_name_ext[$timestamp-1]);
227 } else if ($format == '%M') {
228 return _AT($month_name_con[$timestamp-1]);
232 if ($timestamp == '') {
234 $format_type = TR_DATE_UNIX_TIMESTAMP;
237 /* convert the date to a Unix timestamp before we do anything with it */
238 if ($format_type == TR_DATE_MYSQL_DATETIME) {
239 $year = substr($timestamp,0,4);
240 $month = substr($timestamp,5,2);
241 $day = substr($timestamp,8,2);
242 $hour = substr($timestamp,11,2);
243 $min = substr($timestamp,14,2);
244 $sec = substr($timestamp,17,2);
245 $timestamp = mktime($hour, $min, $sec, $month, $day, $year);
247 } else if ($format_type == TR_DATE_MYSQL_TIMESTAMP_14) {
248 $year = substr($timestamp,0,4);
249 $month = substr($timestamp,4,2);
250 $day = substr($timestamp,6,2);
251 $hour = substr($timestamp,8,2);
252 $minute = substr($timestamp,10,2);
253 $second = substr($timestamp,12,2);
254 $timestamp = mktime($hour, $minute, $second, $month, $day, $year);
257 // apply timezone offset
258 apply_timezone($timestamp);
260 /* pull out all the %X items from $format */
261 $first_token = strpos($format, '%');
262 if ($first_token === false) {
263 /* no tokens found */
266 $tokened_format = substr($format, $first_token);
268 $tokens = explode('%', $tokened_format);
269 array_shift($tokens);
270 $num_tokens = count($tokens);
274 for ($i=0; $i<$num_tokens; $i++) {
275 $tokens[$i] = substr($tokens[$i],0,1);
277 if ($tokens[$i] == 'D') {
278 $output = str_replace('%D', _AT($day_name_con[date('w', $timestamp)]),$output);
280 } else if ($tokens[$i] == 'l') {
281 $output = str_replace('%l', _AT($day_name_ext[date('w', $timestamp)]),$output);
283 } else if ($tokens[$i] == 'F') {
284 $output = str_replace('%F', _AT($month_name_ext[date('n', $timestamp)-1]),$output);
286 } else if ($tokens[$i] == 'M') {
287 $output = str_replace('%M', _AT($month_name_con[date('n', $timestamp)-1]),$output);
290 /* this token doesn't need translating */
291 $value = date($tokens[$i], $timestamp);
292 if ($value != $tokens[$i]) {
293 $output = str_replace('%'.$tokens[$i], $value, $output);
294 } /* else: this token isn't valid. so don't replace it. Eg. try %q */
301 /**********************************************************************************************************/
303 * Transforms text based on formatting preferences. Original $input is also changed (passed by reference).
305 * 1) $output = AT_print($input, $name);
308 * 2) echo AT_print($input, $name); // prefered method
311 * @param string $input text being transformed
312 * @param string $name the unique name of this field (convension: table_name.field_name)
313 * @param boolean $runtime_html forcefully disables html formatting for $input (only used by fields that
314 * have the 'formatting' option
315 * @return string transformed $input
316 * @see TR_FORMAT constants in include/lib/constants.inc.php
317 * @see query_bit() in include/vitals.inc.php
318 * @author Joel Kronenberg
320 function AT_print($input, $name, $runtime_html = true) {
321 global $_field_formatting;
323 if (!isset($_field_formatting[$name])) {
324 /* field not set, check if there's a global setting */
325 $parts = explode('.', $name);
327 /* check if wildcard is set: */
328 if (isset($_field_formatting[$parts[0].'.*'])) {
329 $name = $parts[0].'.*';
331 /* field not set, and there's no global setting */
332 /* same as TR_FORMTR_NONE */
337 if (query_bit($_field_formatting[$name], TR_FORMTR_QUOTES)) {
338 $input = str_replace('"', '"', $input);
341 if (query_bit($_field_formatting[$name], TR_FORMTR_CONTENT_DIR)) {
342 $input = str_replace('CONTENT_DIR/', '', $input);
345 if (query_bit($_field_formatting[$name], TR_FORMTR_HTML) && $runtime_html) {
346 /* what special things do we have to do if this is HTML ? remove unwanted HTML? validate? */
348 $input = str_replace('<', '<', $input);
349 $input = nl2br($input);
352 /* this has to be here, only because TR_FORMTR_HTML is the only check that has an else-block */
353 if ($_field_formatting[$name] === TR_FORMTR_NONE) {
357 if (query_bit($_field_formatting[$name], TR_FORMTR_EMOTICONS)) {
358 $input = smile_replace($input);
361 if (query_bit($_field_formatting[$name], TR_FORMTR_ATCODES)) {
362 $input = trim(myCodes(' ' . $input . ' '));
365 if (query_bit($_field_formatting[$name], TR_FORMTR_LINKS)) {
366 $input = trim(make_clickable(' ' . $input . ' '));
369 if (query_bit($_field_formatting[$name], TR_FORMTR_IMAGES)) {
370 $input = trim(image_replace(' ' . $input . ' '));
377 /********************************************************************************************/
378 // Global variables for emoticons
382 if (!isset($smile_pics)) {
383 $smile_pics[0] = $_base_path.'images/forum/smile.gif';
384 $smile_pics[1] = $_base_path.'images/forum/wink.gif';
385 $smile_pics[2] = $_base_path.'images/forum/frown.gif';
386 $smile_pics[3] = $_base_path.'images/forum/ohwell.gif';
387 $smile_pics[4] = $_base_path.'images/forum/tongue.gif';
388 $smile_pics[5] = $_base_path.'images/forum/51.gif';
389 $smile_pics[6] = $_base_path.'images/forum/52.gif';
390 $smile_pics[7] = $_base_path.'images/forum/54.gif';
391 $smile_pics[8] = $_base_path.'images/forum/27.gif';
392 $smile_pics[9] = $_base_path.'images/forum/19.gif';
393 $smile_pics[10] = $_base_path.'images/forum/3.gif';
394 $smile_pics[11] = $_base_path.'images/forum/56.gif';
397 if (!isset($smile_codes)) {
398 $smile_codes[0] = ':)';
399 $smile_codes[1] = ';)';
400 $smile_codes[2] = ':(';
401 $smile_codes[3] = '::ohwell::';
402 $smile_codes[4] = ':P';
403 $smile_codes[5] = '::evil::';
404 $smile_codes[6] = '::angry::';
405 $smile_codes[7] = '::lol::';
406 $smile_codes[8] = '::crazy::';
407 $smile_codes[9] = '::tired::';
408 $smile_codes[10] = '::confused::';
409 $smile_codes[11] = '::muah::';
413 * Replaces smile-code text into smilie image.
415 * @param string $text smile text to be transformed
416 * @return string transformed $text
417 * @see $smile_pics in include/lib/output.inc.php (above)
418 * @see $smile_codes in include/lib/output.inc.php (above)
419 * @author Joel Kronenberg
421 function smile_replace($text) {
426 $smiles[0] = '<img src="'.$smile_pics[0].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_smile').'" />';
427 $smiles[1] = '<img src="'.$smile_pics[1].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_wink').'" />';
428 $smiles[2] = '<img src="'.$smile_pics[2].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_frown').'" />';
429 $smiles[3]= '<img src="'.$smile_pics[3].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_oh_well').'" />';
430 $smiles[4]= '<img src="'.$smile_pics[4].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_tongue').'" />';
431 $smiles[5]= '<img src="'.$smile_pics[5].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_evil').'" />';
432 $smiles[6]= '<img src="'.$smile_pics[6].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_angry').'" />';
433 $smiles[7]= '<img src="'.$smile_pics[7].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_lol').'" />';
434 $smiles[8]= '<img src="'.$smile_pics[8].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_crazy').'" />';
435 $smiles[9]= '<img src="'.$smile_pics[9].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_tired').'" />';
436 $smiles[10]= '<img src="'.$smile_pics[10].'" border="0" height="17" width="19" align="bottom" alt="'._AT('smile_confused').'" />';
437 $smiles[11]= '<img src="'.$smile_pics[11].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_muah').'" />';
439 $text = str_replace($smile_codes[0],$smiles[0],$text);
440 $text = str_replace($smile_codes[1],$smiles[1],$text);
441 $text = str_replace($smile_codes[2],$smiles[2],$text);
442 $text = str_replace($smile_codes[3],$smiles[3],$text);
443 $text = str_replace($smile_codes[4],$smiles[4],$text);
444 $text = str_replace($smile_codes[5],$smiles[5],$text);
445 $text = str_replace($smile_codes[6],$smiles[6],$text);
446 $text = str_replace($smile_codes[7],$smiles[7],$text);
447 $text = str_replace($smile_codes[8],$smiles[8],$text);
448 $text = str_replace($smile_codes[9],$smiles[9],$text);
449 $text = str_replace($smile_codes[10],$smiles[10],$text);
450 $text = str_replace($smile_codes[11],$smiles[11],$text);
456 /* Used specifically for the visual editor
458 function smile_javascript () {
465 while ($smile_pics [$i]) {
466 echo 'case "'.$smile_codes[$i].'":'."\n";
467 echo 'pic = "'.$smile_pics[$i].'";'."\n";
473 function myCodes($text, $html = false) {
475 global $HTTP_USER_AGENT;
477 if (substr($HTTP_USER_AGENT,0,11) == 'Mozilla/4.7') {
478 $text = str_replace('[quote]','</p><p class="block">',$text);
479 $text = str_replace('[/quote]','</p><p>',$text);
481 $text = str_replace('[reply]','</p><p class="block">',$text);
482 $text = str_replace('[/reply]','</p><p>',$text);
484 $text = str_replace('[quote]','<blockquote>',$text);
485 $text = str_replace('[/quote]','</blockquote><p>',$text);
487 $text = str_replace('[reply]','</p><blockquote class="block"><p>',$text);
488 $text = str_replace('[/reply]','</p></blockquote><p>',$text);
491 $text = str_replace('[b]','<strong>',$text);
492 $text = str_replace('[/b]','</strong>',$text);
494 $text = str_replace('[i]','<em>',$text);
495 $text = str_replace('[/i]','</em>',$text);
497 $text = str_replace('[u]','<u>',$text);
498 $text = str_replace('[/u]','</u>',$text);
500 $text = str_replace('[center]','<center>',$text);
501 $text = str_replace('[/center]','</center><p>',$text);
504 $text = str_replace('[blue]','<span style="color: blue;">',$text);
505 $text = str_replace('[/blue]','</span>',$text);
507 $text = str_replace('[orange]','<span style="color: orange;">',$text);
508 $text = str_replace('[/orange]','</span>',$text);
510 $text = str_replace('[red]','<span style="color: red;">',$text);
511 $text = str_replace('[/red]','</span>',$text);
513 $text = str_replace('[purple]','<span style="color: purple;">',$text);
514 $text = str_replace('[/purple]','</span>',$text);
516 $text = str_replace('[green]','<span style="color: green;">',$text);
517 $text = str_replace('[/green]','</span>',$text);
519 $text = str_replace('[gray]','<span style="color: gray;">',$text);
520 $text = str_replace('[/gray]','</span>',$text);
522 $text = str_replace('[op]','<span class="bigspacer"></span> <a href="',$text);
523 $text = str_replace('[/op]','">'._AT('view_entire_post').'</a>',$text);
525 $text = str_replace('[head1]','<h2>',$text);
526 $text = str_replace('[/head1]','</h2>',$text);
528 $text = str_replace('[head2]','<h3>',$text);
529 $text = str_replace('[/head2]','</h3>',$text);
531 $text = str_replace('[cid]',$_base_path.'content.php?cid='.$_SESSION['s_cid'],$text);
533 global $sequence_links;
534 if (isset($sequence_links['previous']) && $sequence_links['previous']['url']) {
535 $text = str_replace('[pid]', $sequence_links['previous']['url'], $text);
537 if (isset($sequence_links['next']) && $sequence_links['next']['url']) {
538 $text = str_replace('[nid]', $sequence_links['next']['url'], $text);
540 if (isset($sequence_links['resume']) && $sequence_links['resume']['url']) {
541 $text = str_replace('[nid]', $sequence_links['resume']['url'], $text);
543 if (isset($sequence_links['first']) && $sequence_links['first']['url']) {
544 $text = str_replace('[fid]', $sequence_links['first']['url'], $text);
547 /* contributed by Thomas M. Duffey <tduffey at homeboyz.com> */
548 $html = !$html ? 0 : 1;
549 $text = preg_replace("/\[code\]\s*(.*)\s*\[\\/code\]/Usei", "highlight_code(fix_quotes('\\1'), $html)", $text);
554 /* contributed by Thomas M. Duffey <tduffey at homeboyz.com> */
555 function highlight_code($code, $html) {
556 // XHTMLize PHP highlight_string output until it gets fixed in PHP
557 static $search = array(
563 static $replace = array(
569 $code = str_replace('<', '<', $code);
570 $code = str_replace("\r", '', $code);
573 return str_replace($search, $replace, highlight_string($code, true));
576 /* contributed by Thomas M. Duffey <tduffey at homeboyz.com> */
577 function fix_quotes($text){
578 return str_replace('\\"', '"', $text);
581 function embed_media($text) {
582 if (preg_match("/\[media(\|[0-9]+\|[0-9]+)?\]*/", $text)==0){
586 $media_matches = Array();
589 First, we search though the text for all different kinds of media defined by media tags and store the results in $media_matches.
591 Then the different replacements for the different media tags are stored in $media_replace.
593 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.
598 preg_match_all("#\[media[0-9a-z\|]*\]http://([a-z0-9\.]*)?youtube.com/watch\?v=([a-z0-9_-]+)\[/media\]#i",$text,$media_matches[1],PREG_SET_ORDER);
599 $media_replace[1] = '<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>';
602 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).mpg\[/media\]#i",$text,$media_matches[2],PREG_SET_ORDER);
603 $media_replace[2] = "<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>";
606 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).avi\[/media\]#i",$text,$media_matches[3],PREG_SET_ORDER);
607 $media_replace[3] = "<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>";
610 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).wmv\[/media\]#i",$text,$media_matches[4],PREG_SET_ORDER);
611 $media_replace[4] = "<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>";
614 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).mov\[/media\]#i",$text,$media_matches[5],PREG_SET_ORDER);
615 $media_replace[5] = "<object classid=\"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B\" codebase=\"http://www.apple.com/qtactivex/qtplugin.cab\" width=\"##WIDTH##\" height=\"##HEIGHT##\"><param name=\"src\" value=\"##MEDIA1##.mov\"><param name=\"controller\" value=\"true\"><param name=\"autoplay\" value=\"false\"><!--[if gte IE 7]> <!--><object type=\"video/quicktime\" data=\"##MEDIA1##.mov\" width=\"##WIDTH##\" height=\"##HEIGHT##\"><param name=\"controller\" value=\"true\"><param name=\"autoplay\" value=\"false\"><a href=\"##MEDIA1##.mov\">##MEDIA1##.mov</a></object><!--<![endif]--><!--[if lt IE 7]><a href=\"##MEDIA1##.mov\">##MEDIA1##.mov</a><![endif]--></object>";
618 preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).swf\[/media\]#i",$text,$media_matches[6],PREG_SET_ORDER);
619 $media_replace[6] = "<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>";
622 preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).mp3\[/media\]#i",$text,$media_matches[7],PREG_SET_ORDER);
623 $media_replace[7] = "<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>";
626 preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).wav\[/media\]#i",$text,$media_matches[8],PREG_SET_ORDER);
627 $media_replace[8] ="<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>";
630 preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).ogg\[/media\]#i",$text,$media_matches[9],PREG_SET_ORDER);
631 $media_replace[9] ="<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>";
634 preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).mid\[/media\]#i",$text,$media_matches[10],PREG_SET_ORDER);
635 $media_replace[10] ="<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>";
637 $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);
639 // Executing the replace
640 for ($i=1;$i<=count($media_replace);$i++){
641 foreach($media_matches[$i] as $media)
644 //find width and height for each matched media
645 if (preg_match("/\[media\|([0-9]*)\|([0-9]*)\]*/", $media[0], $matches))
647 $width = $matches[1];
648 $height = $matches[2];
656 //replace media tags with embedded media for each media tag
657 $media_input = $media_replace[$i];
658 $media_input = str_replace("##WIDTH##","$width",$media_input);
659 $media_input = str_replace("##HEIGHT##","$height",$media_input);
660 $media_input = str_replace("##MEDIA1##","$media[1]",$media_input);
661 $media_input = str_replace("##MEDIA2##","$media[2]",$media_input);
662 $text = str_replace($media[0],$media_input,$text);
669 function make_clickable($text) {
670 $text = embed_media($text);
672 // The next 3 preg_replace convert plain text URL to clickable URL.
673 // limited conversion. It doesn't cover the case when the stuff in front of the URL is not a word. For example:
674 // <p>http://google.ca</p>
675 // "http://google.ca"
676 // 1. remove the spaces in [media] tag, otherwise, the next line converts URL inside [media] into <a> tag
677 $text = preg_replace("/(\[media\])([\s]*)(.*)(\[\/media\])/", '$1$3$4', $text);
678 $text = preg_replace("/(\[media\])(.*)([\s]*)(\[\/media\])/U", '$1$2$4', $text);
680 $text = preg_replace('/(^|[\n ])([\w]*?)((?<!(\[media\]))http(s)?:\/\/[\w]+[^ \,\"\n\r\t<]*)/is',
681 '$1$2<a href="$3">$3</a>', $text);
683 // convert email address to clickable URL that pops up "send email" interface with the address filled in
684 $text = preg_replace('/(?|<a href="mailto[\s]*:[\s]*([_a-zA-Z0-9\-]+(\.[_a-zA-Z0-9\-]+)*'.'\@'
685 .'[_a-zA-Z0-9\-]+(\.[_a-zA-Z0-9\-]+)*'.'(\.[a-zA-Z]{1,6})+)">(.*)<\/a>'
686 .'|((((([_a-zA-Z0-9\-]+(\.[_a-zA-Z0-9\-]+)*'.'\@'
687 .'[_a-zA-Z0-9\-]+(\.[_a-zA-Z0-9\-]+)*'.'(\.[a-zA-Z]{1,6})+))))))/i',
688 "<a href=\"mailto:\\1\">\\5</a>",
694 function image_replace($text) {
695 /* image urls do not require http:// */
697 $text = preg_replace("/\[image(\|)?([a-zA-Z0-9\s]*)\]".
699 "([a-zA-Z0-9\#\?\/\&\=\:\\\"\'\_\.\-]+)[\s]*".
700 "((\[\/image\])|(.*\[\/image\]))/i",
701 "<img src=\"\\3\" alt=\"\\2\" />",
707 function formTR_final_output($text, $nl2br = true) {
710 $text = str_replace('CONTENT_DIR/', '', $text);
713 return nl2br(image_replace(make_clickable(myCodes(' '.$text, false))));
715 return image_replace(make_clickable(myCodes(' '.$text, true)));
718 /****************************************************************************************/
719 /* @See: ./user/search.php & ./index.php */
720 function highlight($input, $var) {//$input is the string, $var is the text to be highlighted
725 The following 'if' statement is a check to ensure that the search term is not part of the tag, '<strong class="highlight">'. Words within this string are avoided in case a previously highlighted string is used for the haystack, $input. To avoid any html breaks in the highlighted string, the search word is avoided completely.
727 if (strpos('<strong class="highlight">', $var) !== false) {
730 while($i<strlen($input)){
731 if((($i + strlen($var)) <= strlen($input)) && (strcasecmp($var, substr($input, $i, strlen($var))) == 0)) {
732 $xtemp .= '<strong class="highlight">' . substr($input, $i , strlen($var)) . '</strong>';
736 $xtemp .= $input{$i};
746 /* @See: ./index.php */
747 function formTR_content($input, $html = 0, $glossary, $simple = false) {
748 global $_base_path, $_config_defaults;
751 $input = str_replace('<', '<', $input);
752 $input = str_replace('<?php', '<?php', $input); // for bug #2087
755 /* do the glossary search and replace: */
756 if (is_array($glossary)) {
757 foreach ($glossary as $k => $v) {
759 $v = str_replace("\n", '<br />', $v);
760 $v = str_replace("\r", '', $v);
762 /* escape special characters */
765 $k = str_replace('<', '<', $k);
766 $k = str_replace('/', '\/', $k);
769 $term = $original_term;
771 $term = '(\s*'.$term.'\s*)';
772 $term = str_replace(' ','((<br \/>)*\s*)', $term);
774 $def = htmlspecialchars($v);
776 $input = preg_replace
777 ("/(\[\?\])$term(\[\/\?\])/i",
778 '<a href="'.$simple.'glossary.html#'.urlencode($original_term).'" target="body" class="at-term">\\2</a>',
781 $input = preg_replace
782 ("/(\[\?\])$term(\[\/\?\])/i",
783 '\\2<sup><a href="'.$_base_path.'glossary/index.php?g_cid='.$_SESSION['s_cid'].SEP.'w='.urlencode($original_term).'#term" onmouseover="return overlib(\''.$def.'\', CAPTION, \''.addslashes($original_term).'\', AUTOSTATUS);" onmouseout="return nd();" onfocus="return overlib(\''.$def.'\', CAPTION, \''.addslashes($original_term).'\', AUTOSTATUS);" onblur="return nd();"><span style="color: blue; text-decoration: none;font-size:small; font-weight:bolder;">?</span></a></sup>',
787 } else if (!$user_glossary) {
788 $input = str_replace(array('[?]','[/?]'), '', $input);
791 $input = str_replace('CONTENT_DIR', '', $input);
793 if (isset($_config_defaults['latex_server']) && $_config_defaults['latex_server']) {
794 // see: http://www.forkosh.com/mimetex.html
795 $input = preg_replace('/\[tex\](.*?)\[\/tex\]/sie', "'<img src=\"'.\$_config_defaults['latex_server'].rawurlencode('$1').'\" align=\"middle\">'", $input);
799 $x = formTR_final_output($input, false);
803 $output = formTR_final_output($input);
805 $output = '<p>'.$output.'</p>';
810 /***********************************************************************
811 @See /include/Classes/Message/Message.class.php
816 * Take a code as input and grab its language specific message. Also cache the resulting
817 * message. Return the message. Same as get_message but key value in cache is string
819 * @param string $codes Message Code to translate - > 'term' field in DB
820 * @return string The translated language specific message for code $code
821 * @author Jacek Materna
823 function getTranslatedCodeStr($codes) {
825 /* this is where we want to get the msgs from the database inside a static variable */
826 global $_cache_msgs_new;
829 if (!isset($_msgs_new)) {
830 if ( !($lang_et = cache(120, 'msgs_new', $_SESSION['lang'])) ) {
831 global $db, $_base_path;
833 $parent = Language::getParentCode($_SESSION['lang']);
835 /* get $_msgs_new from the DB */
836 $sql = 'SELECT * FROM '.TABLE_PREFIX.'language_text WHERE variable="_msgs" AND (language_code="'.$_SESSION['lang'].'" OR language_code="'.$parent.'")';
837 $result = @mysql_query($sql, $db);
839 while ($row = @mysql_fetch_assoc($result)) {
840 // do not cache key as a digit (no contstant(), use string)
841 $_cache_msgs_new[$row['term']] = str_replace('SITE_URL/', $_base_path, $row['text']);
843 $_cache_msgs_new[$row['term']] .= ' <small><small>('.$row['term'].')</small></small>';
847 cache_variable('_cache_msgs_new');
848 endcache(true, false);
850 $_msgs_new = $_cache_msgs_new;
853 if (is_array($codes)) {
854 /* this is an array with terms to replace */
855 $code = array_shift($codes);
857 $message = $_msgs_new[$code];
860 /* replace the tokens with the terms */
861 $message = vsprintf($message, $terms);
864 $message = $_msgs_new[$codes];
866 if ($message == '') {
867 /* the language for this msg is missing: */
869 $sql = 'SELECT * FROM '.TABLE_PREFIX.'language_text WHERE variable="_msgs"';
870 $result = @mysql_query($sql, $db);
872 while ($row = @mysql_fetch_assoc($result)) {
873 if (($row['term']) === $codes) {
874 $message = '['.$row['term'].']';
884 function html_get_list($array) {
886 foreach ($array as $value) {
887 $list .= '<li>'.$value.'</li>';
895 * print out list of page links
897 function print_paginator($current_page, $num_rows, $request_args, $rows_per_page = 50, $window = 5) {
898 $num_pages = ceil($num_rows / $rows_per_page);
899 $request_args = '?'.$request_args;
901 if ($num_pages == 1) return;
903 echo '<div class="paging">';
906 $i=max($current_page-$window - max($window-$num_pages+$current_page,0), 1);
908 if ($current_page > 1)
909 echo '<li><a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p='.($current_page-1).'">'._AT('prev').'</a> </li>';
912 echo '<li><a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p=1">1</a></li>';
914 echo '<li>…</li>';
918 for ($i; $i<= min($current_page+$window -min($current_page-$window,0),$num_pages); $i++) {
919 if ($current_page == $i) {
920 echo '<li><a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p='.$i.'" class="current"><em>'.$current_page.'</em></a></li>';
922 echo '<li><a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p='.$i.'">'.$i.'</a></li>';
925 if ($i <= $num_pages) {
926 if ($i < $num_pages) {
927 echo '<li>…</li>';
929 echo '<li><a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p='.$num_pages.'">'.$num_pages.'</a></li>';
932 if ($current_page < $num_pages)
933 echo '<li> <a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p='.($current_page+1).'">'._AT('next').'</a></li>';
942 * converts a unix timestamp into another UNIX timestamp with timezone offset added up.
943 * Adds the user's timezone offset, then converts back to a MYSQL timestamp
944 * Available both as a system config option, and a user preference, if both are set
945 * they are added together
946 * @param date MYSQL timestamp.
947 * @return date MYSQL timestamp plus user's and/or system's timezone offset.
950 function apply_timezone($timestamp){
953 if($_config['time_zone']){
954 $timestamp = ($timestamp + ($_config['time_zone']*3600));
957 if(isset($_SESSION['prefs']['PREF_TIMEZONE'])){
958 $timestamp = ($timestamp + ($_SESSION['prefs']['PREF_TIMEZONE']*3600));