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_once(TR_INCLUDE_PATH . 'classes/DAO/LanguageTextDAO.class.php');
15 require_once(TR_INCLUDE_PATH . '../home/classes/ContentUtility.class.php');
17 /**********************************************************************************/
18 /* Output functions found in this file, in order:
22 /**********************************************************************************/
25 * Converts language code to actual language message, caches them according to page url
27 * @param args unlimited number of arguments allowed but first arg MUST be name of the language variable/term
28 * i.e $args[0] = the term to the format string $_template[term]
29 * $args[1..x] = optional arguments to the formatting string
30 * @return string|array full resulting message
31 * @see $db in include/vitals.inc.php
32 * @see cache() in include/phpCache/phpCache.inc.php
33 * @see cache_variable() in include/phpCache/phpCache.inc.php
34 * @author Joel Kronenberg
37 global $_cache_template, $lang_et, $_rel_url;
40 $args = func_get_args();
42 if ($args[0] == "") return "";
44 $languageTextDAO = new LanguageTextDAO();
47 if (!is_array($args[0])) {
49 * Added functionality for translating language code String (TR_ERROR|TR_INFOS|TR_WARNING|TR_FEEDBACK).*
50 * to its text and returning the result. No caching needed.
51 * @author Jacek Materna
54 // Check for specific language prefix, extendible as needed
55 // 0002767: a substring+in_array test should be faster than a preg_match test.
56 // replaced the preg_match with a test of the substring.
57 $sub_arg = substr($args[0], 0, 7); // 7 is the shortest type of msg (TR_INFO)
58 if (in_array($sub_arg, array('TR_ERRO','TR_INFO','TR_WARN','TR_FEED','TR_CONF'))) {
59 global $_base_path, $addslashes;
61 $args[0] = $addslashes($args[0]);
63 /* get $_msgs_new from the DB */
64 $rows = $languageTextDAO->getMsgByTermAndLang($args[0], $_SESSION['lang']);
70 // do not cache key as a digit (no contstant(), use string)
71 $msgs = str_replace('SITE_URL/', $_base_path, $row['text']);
72 if (defined('TR_DEVEL') && TR_DEVEL) {
73 $msgs .= ' <small><small>('. $args[0] .')</small></small>';
81 // a template variable
82 if (!isset($_template)) {
83 $url_parts = parse_url(TR_BASE_HREF);
84 $name = substr($_SERVER['PHP_SELF'], strlen($url_parts['path'])-1);
86 if ( !($lang_et = cache(120, 'lang', $_SESSION['lang'].'_'.$name)) ) {
87 /* get $_template from the DB */
88 $rows = $languageTextDAO->getAllTemplateByLang($_SESSION['lang']);
92 foreach ($rows as $id => $row)
94 //Do not overwrite the variable that existed in the cache_template already.
95 //The edited terms (_c_template) will always be at the top of the resultset
97 if (isset($_cache_template[$row['term']])){
101 // saves us from doing an ORDER BY
102 if ($row['language_code'] == $_SESSION['lang']) {
103 $_cache_template[$row['term']] = stripslashes($row['text']);
104 } else if (!isset($_cache_template[$row['term']])) {
105 $_cache_template[$row['term']] = stripslashes($row['text']);
110 cache_variable('_cache_template');
111 endcache(true, false);
113 $_template = $_cache_template;
116 $num_args = func_num_args();
117 if (is_array($args[0])) {
119 $num_args = count($args);
121 $format = array_shift($args);
123 if (isset($_template[$format]) && count($args) > 0) {
124 $outString = vsprintf($_template[$format], $args);
125 $str = ob_get_contents();
130 if ($outString === false) {
131 return ('[Error parsing language. Variable: <code>'.$format.'</code>. Language: <code>'.$_SESSION['lang'].'</code> ]');
134 if (empty($outString)) {
136 $rows = $languageTextDAO->getByTermAndLang($format, $_SESSION['lang']);
140 $_template[$row['term']] = stripslashes($row['text']);
141 $outString = $_template[$row['term']];
144 if (empty($outString)) {
145 return ('[ '.$format.' ]');
153 The following options were added as language dependant:
154 %D: A textual representation of a week, three letters Mon through Sun
155 %F: A full textual representation of a month, such as January or March January through December
156 %l (lowercase 'L'): A full textual representation of the day of the week Sunday through Saturday
157 %M: A short textual representation of a month, three letters Jan through Dec
159 Support for the following maybe added later:
160 ?? %S: English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with j
161 ?? %a: Lowercase Ante meridiem and Post meridiem am or pm
162 ?? %A: Uppercase Ante meridiem and Post meridiem AM or PM
165 TR_DATE_MYSQL_DATETIME: YYYY-MM-DD HH:MM:SS
166 TR_DATE_MYSQL_TIMESTAMP_14: YYYYMMDDHHMMSS
167 TR_DATE_UNIX_TIMESTAMP: seconds since epoch
168 TR_DATE_INDEX_VALUE: 0-x, index into a date array
170 function AT_date($format='%Y-%M-%d', $timestamp = '', $format_type=TR_DATE_MYSQL_DATETIME) {
171 static $day_name_ext, $day_name_con, $month_name_ext, $month_name_con;
174 if (!isset($day_name_ext)) {
175 $day_name_ext = array( 'date_sunday',
183 $day_name_con = array( 'date_sun',
191 $month_name_ext = array('date_january',
204 $month_name_con = array('date_jan',
218 if ($format_type == TR_DATE_INDEX_VALUE) {
219 // apply timezone offset
220 apply_timezone($timestamp);
222 if ($format == '%D') {
223 return _AT($day_name_con[$timestamp-1]);
224 } else if ($format == '%l') {
225 return _AT($day_name_ext[$timestamp-1]);
226 } else if ($format == '%F') {
227 return _AT($month_name_ext[$timestamp-1]);
228 } else if ($format == '%M') {
229 return _AT($month_name_con[$timestamp-1]);
233 if ($timestamp == '') {
235 $format_type = TR_DATE_UNIX_TIMESTAMP;
238 /* convert the date to a Unix timestamp before we do anything with it */
239 if ($format_type == TR_DATE_MYSQL_DATETIME) {
240 $year = substr($timestamp,0,4);
241 $month = substr($timestamp,5,2);
242 $day = substr($timestamp,8,2);
243 $hour = substr($timestamp,11,2);
244 $min = substr($timestamp,14,2);
245 $sec = substr($timestamp,17,2);
246 $timestamp = mktime($hour, $min, $sec, $month, $day, $year);
248 } else if ($format_type == TR_DATE_MYSQL_TIMESTAMP_14) {
249 $year = substr($timestamp,0,4);
250 $month = substr($timestamp,4,2);
251 $day = substr($timestamp,6,2);
252 $hour = substr($timestamp,8,2);
253 $minute = substr($timestamp,10,2);
254 $second = substr($timestamp,12,2);
255 $timestamp = mktime($hour, $minute, $second, $month, $day, $year);
258 // apply timezone offset
259 apply_timezone($timestamp);
261 /* pull out all the %X items from $format */
262 $first_token = strpos($format, '%');
263 if ($first_token === false) {
264 /* no tokens found */
267 $tokened_format = substr($format, $first_token);
269 $tokens = explode('%', $tokened_format);
270 array_shift($tokens);
271 $num_tokens = count($tokens);
275 for ($i=0; $i<$num_tokens; $i++) {
276 $tokens[$i] = substr($tokens[$i],0,1);
278 if ($tokens[$i] == 'D') {
279 $output = str_replace('%D', _AT($day_name_con[date('w', $timestamp)]),$output);
281 } else if ($tokens[$i] == 'l') {
282 $output = str_replace('%l', _AT($day_name_ext[date('w', $timestamp)]),$output);
284 } else if ($tokens[$i] == 'F') {
285 $output = str_replace('%F', _AT($month_name_ext[date('n', $timestamp)-1]),$output);
287 } else if ($tokens[$i] == 'M') {
288 $output = str_replace('%M', _AT($month_name_con[date('n', $timestamp)-1]),$output);
291 /* this token doesn't need translating */
292 $value = date($tokens[$i], $timestamp);
293 if ($value != $tokens[$i]) {
294 $output = str_replace('%'.$tokens[$i], $value, $output);
295 } /* else: this token isn't valid. so don't replace it. Eg. try %q */
302 /**********************************************************************************************************/
304 * Transforms text based on formatting preferences. Original $input is also changed (passed by reference).
306 * 1) $output = AT_print($input, $name);
309 * 2) echo AT_print($input, $name); // prefered method
312 * @param string $input text being transformed
313 * @param string $name the unique name of this field (convension: table_name.field_name)
314 * @param boolean $runtime_html forcefully disables html formatting for $input (only used by fields that
315 * have the 'formatting' option
316 * @return string transformed $input
317 * @see TR_FORMAT constants in include/lib/constants.inc.php
318 * @see query_bit() in include/vitals.inc.php
319 * @author Joel Kronenberg
321 function AT_print($input, $name, $runtime_html = true) {
322 global $_field_formatting;
324 if (!isset($_field_formatting[$name])) {
325 /* field not set, check if there's a global setting */
326 $parts = explode('.', $name);
328 /* check if wildcard is set: */
329 if (isset($_field_formatting[$parts[0].'.*'])) {
330 $name = $parts[0].'.*';
332 /* field not set, and there's no global setting */
333 /* same as TR_FORMTR_NONE */
338 if (query_bit($_field_formatting[$name], TR_FORMTR_QUOTES)) {
339 $input = str_replace('"', '"', $input);
342 if (query_bit($_field_formatting[$name], TR_FORMTR_CONTENT_DIR)) {
343 $input = str_replace('CONTENT_DIR/', '', $input);
346 if (query_bit($_field_formatting[$name], TR_FORMTR_HTML) && $runtime_html) {
347 /* what special things do we have to do if this is HTML ? remove unwanted HTML? validate? */
349 $input = str_replace('<', '<', $input);
350 $input = nl2br($input);
353 /* this has to be here, only because TR_FORMTR_HTML is the only check that has an else-block */
354 if ($_field_formatting[$name] === TR_FORMTR_NONE) {
358 if (query_bit($_field_formatting[$name], TR_FORMTR_EMOTICONS)) {
359 $input = smile_replace($input);
362 if (query_bit($_field_formatting[$name], TR_FORMTR_ATCODES)) {
363 $input = trim(ContentUtility::myCodes(' ' . $input . ' '));
366 if (query_bit($_field_formatting[$name], TR_FORMTR_LINKS)) {
367 $input = trim(ContentUtility::makeClickable(' ' . $input . ' '));
370 if (query_bit($_field_formatting[$name], TR_FORMTR_IMAGES)) {
371 $input = trim(ContentUtility::imageReplace(' ' . $input . ' '));
378 /********************************************************************************************/
379 // Global variables for emoticons
383 if (!isset($smile_pics)) {
384 $smile_pics[0] = $_base_path.'images/forum/smile.gif';
385 $smile_pics[1] = $_base_path.'images/forum/wink.gif';
386 $smile_pics[2] = $_base_path.'images/forum/frown.gif';
387 $smile_pics[3] = $_base_path.'images/forum/ohwell.gif';
388 $smile_pics[4] = $_base_path.'images/forum/tongue.gif';
389 $smile_pics[5] = $_base_path.'images/forum/51.gif';
390 $smile_pics[6] = $_base_path.'images/forum/52.gif';
391 $smile_pics[7] = $_base_path.'images/forum/54.gif';
392 $smile_pics[8] = $_base_path.'images/forum/27.gif';
393 $smile_pics[9] = $_base_path.'images/forum/19.gif';
394 $smile_pics[10] = $_base_path.'images/forum/3.gif';
395 $smile_pics[11] = $_base_path.'images/forum/56.gif';
398 if (!isset($smile_codes)) {
399 $smile_codes[0] = ':)';
400 $smile_codes[1] = ';)';
401 $smile_codes[2] = ':(';
402 $smile_codes[3] = '::ohwell::';
403 $smile_codes[4] = ':P';
404 $smile_codes[5] = '::evil::';
405 $smile_codes[6] = '::angry::';
406 $smile_codes[7] = '::lol::';
407 $smile_codes[8] = '::crazy::';
408 $smile_codes[9] = '::tired::';
409 $smile_codes[10] = '::confused::';
410 $smile_codes[11] = '::muah::';
414 * Replaces smile-code text into smilie image.
416 * @param string $text smile text to be transformed
417 * @return string transformed $text
418 * @see $smile_pics in include/lib/output.inc.php (above)
419 * @see $smile_codes in include/lib/output.inc.php (above)
420 * @author Joel Kronenberg
422 function smile_replace($text) {
427 $smiles[0] = '<img src="'.$smile_pics[0].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_smile').'" />';
428 $smiles[1] = '<img src="'.$smile_pics[1].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_wink').'" />';
429 $smiles[2] = '<img src="'.$smile_pics[2].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_frown').'" />';
430 $smiles[3]= '<img src="'.$smile_pics[3].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_oh_well').'" />';
431 $smiles[4]= '<img src="'.$smile_pics[4].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_tongue').'" />';
432 $smiles[5]= '<img src="'.$smile_pics[5].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_evil').'" />';
433 $smiles[6]= '<img src="'.$smile_pics[6].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_angry').'" />';
434 $smiles[7]= '<img src="'.$smile_pics[7].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_lol').'" />';
435 $smiles[8]= '<img src="'.$smile_pics[8].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_crazy').'" />';
436 $smiles[9]= '<img src="'.$smile_pics[9].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_tired').'" />';
437 $smiles[10]= '<img src="'.$smile_pics[10].'" border="0" height="17" width="19" align="bottom" alt="'._AT('smile_confused').'" />';
438 $smiles[11]= '<img src="'.$smile_pics[11].'" border="0" height="15" width="15" align="bottom" alt="'._AT('smile_muah').'" />';
440 $text = str_replace($smile_codes[0],$smiles[0],$text);
441 $text = str_replace($smile_codes[1],$smiles[1],$text);
442 $text = str_replace($smile_codes[2],$smiles[2],$text);
443 $text = str_replace($smile_codes[3],$smiles[3],$text);
444 $text = str_replace($smile_codes[4],$smiles[4],$text);
445 $text = str_replace($smile_codes[5],$smiles[5],$text);
446 $text = str_replace($smile_codes[6],$smiles[6],$text);
447 $text = str_replace($smile_codes[7],$smiles[7],$text);
448 $text = str_replace($smile_codes[8],$smiles[8],$text);
449 $text = str_replace($smile_codes[9],$smiles[9],$text);
450 $text = str_replace($smile_codes[10],$smiles[10],$text);
451 $text = str_replace($smile_codes[11],$smiles[11],$text);
456 function html_get_list($array) {
458 foreach ($array as $value) {
459 $list .= '<li>'.$value.'</li>';
467 * print out list of page links
469 function print_paginator($current_page, $num_rows, $request_args, $rows_per_page = 50, $window = 5) {
470 $num_pages = ceil($num_rows / $rows_per_page);
471 $request_args = '?'.$request_args;
473 if ($num_pages == 1) return;
475 echo '<div class="paging">';
478 $i=max($current_page-$window - max($window-$num_pages+$current_page,0), 1);
480 if ($current_page > 1)
481 echo '<li><a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p='.($current_page-1).'">'._AT('prev').'</a> </li>';
484 echo '<li><a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p=1">1</a></li>';
486 echo '<li>…</li>';
490 for ($i; $i<= min($current_page+$window -min($current_page-$window,0),$num_pages); $i++) {
491 if ($current_page == $i) {
492 echo '<li><a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p='.$i.'" class="current"><em>'.$current_page.'</em></a></li>';
494 echo '<li><a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p='.$i.'">'.$i.'</a></li>';
497 if ($i <= $num_pages) {
498 if ($i < $num_pages) {
499 echo '<li>…</li>';
501 echo '<li><a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p='.$num_pages.'">'.$num_pages.'</a></li>';
504 if ($current_page < $num_pages)
505 echo '<li> <a href="'.$_SERVER['PHP_SELF'].$request_args.htmlspecialchars(SEP).'p='.($current_page+1).'">'._AT('next').'</a></li>';
514 * converts a unix timestamp into another UNIX timestamp with timezone offset added up.
515 * Adds the user's timezone offset, then converts back to a MYSQL timestamp
516 * Available both as a system config option, and a user preference, if both are set
517 * they are added together
518 * @param date MYSQL timestamp.
519 * @return date MYSQL timestamp plus user's and/or system's timezone offset.
522 function apply_timezone($timestamp){
525 if($_config['time_zone']){
526 $timestamp = ($timestamp + ($_config['time_zone']*3600));
529 if(isset($_SESSION['prefs']['PREF_TIMEZONE'])){
530 $timestamp = ($timestamp + ($_SESSION['prefs']['PREF_TIMEZONE']*3600));