4 +-----------------------------------------------------------------------+
7 | This file is part of the RoundCube PHP suite |
8 | Copyright (C) 2005, RoundCube Dev. - Switzerland |
9 | Licensed under the GNU GPL |
12 | Shared functions and classes used in PHP projects |
14 +-----------------------------------------------------------------------+
15 | Author: Thomas Bruederli <roundcube@gmail.com> |
16 +-----------------------------------------------------------------------+
18 $Id: rcube_shared.inc 288 2006-07-31 22:51:23Z thomasb $
23 // ********* round cube schared classes *********
29 var $scripts_path = '';
30 var $script_files = array();
31 var $scripts = array();
32 var $charset = 'ISO-8859-1';
34 var $script_tag_file = "<script type=\"text/javascript\" src=\"%s%s\"></script>\n";
35 var $script_tag = "<script type=\"text/javascript\">\n<!--\n%s\n\n//-->\n</script>\n";
36 var $default_template = "<html>\n<body></body>\n</html>";
42 var $body_attrib = array();
43 var $meta_tags = array();
47 function __construct()
49 $this->css = new rcube_css();
52 // PHP 4 compatibility
53 function rcube_html_page()
59 function include_script($file, $position='head')
61 static $sa_files = array();
63 if (in_array($file, $sa_files))
66 if (!is_array($this->script_files[$position]))
67 $this->script_files[$position] = array();
69 $this->script_files[$position][] = $file;
73 function add_script($script, $position='head')
75 if (!isset($this->scripts[$position]))
76 $this->scripts[$position] = '';
78 $this->scripts[$position] .= "\n$script";
82 function set_title($t)
88 function set_charset($charset)
92 $this->charset = $charset;
94 if ($MBSTRING && function_exists("mb_internal_encoding"))
96 if(!@mb_internal_encoding($charset))
101 function get_charset()
103 return $this->charset;
109 $this->css = new rcube_css();
110 $this->script_files = array();
111 $this->scripts = array();
116 function write($templ='', $base_path='')
118 $output = empty($templ) ? $this->default_template : trim($templ);
120 // set default page title
121 if (!strlen($this->title))
122 $this->title = 'RoundCube Mail';
124 // replace specialchars in content
125 $__page_title = rep_specialchars_output($this->title, 'html', 'show', FALSE);
126 $__page_header = $__page_body = $__page_footer = '';
129 // include meta tag with charset
130 if (!empty($this->charset))
132 header('Content-Type: text/html; charset='.$this->charset);
133 $__page_header = '<meta http-equiv="content-type" content="text/html; charset='.$this->charset.'" />'."\n";
137 // definition of the code to be placed in the document header and footer
138 if (is_array($this->script_files['head']))
139 foreach ($this->script_files['head'] as $file)
140 $__page_header .= sprintf($this->script_tag_file, $this->scripts_path, $file);
142 if (strlen($this->scripts['head']))
143 $__page_header .= sprintf($this->script_tag, $this->scripts['head']);
145 if (is_array($this->script_files['foot']))
146 foreach ($this->script_files['foot'] as $file)
147 $__page_footer .= sprintf($this->script_tag_file, $this->scripts_path, $file);
149 if (strlen($this->scripts['foot']))
150 $__page_footer .= sprintf($this->script_tag, $this->scripts['foot']);
153 $__page_header .= $this->css->show();
157 if($hpos = strpos(strtolower($output), '</head>'))
158 $__page_header .= "\n";
161 if (!is_numeric($hpos))
162 $hpos = strpos(strtolower($output), '<body');
163 if (!is_numeric($hpos) && ($hpos = strpos(strtolower($output), '<html')))
165 while($output[$hpos]!='>')
170 $__page_header = "<head>\n<title>$__page_title</title>\n$__page_header\n</head>\n";
175 $output = substr($output,0,$hpos) . $__page_header . substr($output,$hpos,strlen($output));
177 $output = $__page_header . $output;
181 if($bpos = strpos(strtolower($output), '<body'))
183 while($output[$bpos]!='>') $bpos++;
187 $bpos = strpos(strtolower($output), '</head>')+7;
190 if($bpos && $__page_body)
191 $output = substr($output,0,$bpos) . "\n$__page_body\n" . substr($output,$bpos,strlen($output));
194 // find and add page footer
195 if(($fpos = strpos(strtolower($output), '</body>')) || ($fpos = strpos(strtolower($output), '</html>')))
196 $output = substr($output,0,$fpos) . "$__page_footer\n" . substr($output,$fpos,strlen($output));
198 $output .= "\n$__page_footer";
201 // reset those global vars
202 $__page_header = $__page_footer = '';
205 // correct absolute pathes in images and other tags
206 $output = preg_replace('/(src|href|background)=(["\']?)(\/[a-z0-9_\-]+)/Ui', "\\1=\\2$base_path\\3", $output);
207 $output = str_replace('$__skin_path', $base_path, $output);
209 print rcube_charset_convert($output, 'UTF-8', $this->charset);
213 function _parse($templ)
224 var $css_data = array();
226 var $css_groups = array();
228 var $include_files = array();
230 var $grouped_output = TRUE;
232 var $content_type = 'text/css';
236 var $indent_chars = "\t";
239 // add or overwrite a css definition
240 // either pass porperty and value as separate arguments
241 // or provide an associative array as second argument
242 function set_style($selector, $property, $value='')
244 $a_elements = $this->_parse_selectors($selector);
245 foreach ($a_elements as $element)
247 if (!is_array($property))
248 $property = array($property => $value);
250 foreach ($property as $name => $value)
251 $this->css_data[$element][strtolower($name)] = $value;
255 $this->css_groups = array();
259 // unset a style property
260 function remove_style($selector, $property)
262 if (!is_array($property))
263 $property = array($property);
265 foreach ($property as $key)
266 unset($this->css_data[$selector][strtolower($key)]);
269 $this->css_groups = array();
273 // define base path for external css files
274 function set_basepath($path)
276 $this->base_path = preg_replace('/\/$/', '', $path);
280 // enable/disable grouped output
281 function set_grouped_output($grouped)
283 $this->grouped_output = $grouped;
287 // add a css file as external source
288 function include_file($filename, $media='')
290 // include multiple files
291 if (is_array($filename))
293 foreach ($filename as $file)
294 $this->include_file($file, $media);
297 else if (!in_array($filename, $this->include_files))
298 $this->include_files[] = array('file' => $filename,
304 function import_string($str)
308 $ret = $this->_parse($str);
314 // open and parse a css file
315 function import_file($file)
322 // for php version >= 4.3.0
323 if (function_exists('file_get_contents'))
324 $ret = $this->_parse(file_get_contents($file));
326 // for order php versions
327 else if ($fp = fopen($file, 'r'))
329 $ret = $this->_parse(fread($fp, filesize($file)));
337 // copy all properties inherited from superior styles to a specific selector
338 function copy_inherited_styles($selector)
340 // get inherited props from body and tag/class selectors
341 $css_props = $this->_get_inherited_styles($selector);
343 // write modified props back and clear goups array
344 if (sizeof($css_props))
346 $this->css_data[$selector] = $css_props;
347 $this->css_groups = array();
352 // return css definition for embedding in HTML
357 // include external css files
358 if (sizeof($this->include_files))
359 foreach ($this->include_files as $file_arr)
360 $out .= sprintf('<link rel="stylesheet" type="%s" href="%s"%s>'."\n",
362 $this->_get_file_path($file_arr['file']),
363 $file_arr['media'] ? ' media="'.$file_arr['media'].'"' : '');
366 // compose css string
367 if (sizeof($this->css_data))
368 $out .= sprintf("<style type=\"%s\">\n<!--\n\n%s-->\n</style>",
377 // return valid css code of the current styles grid
378 function to_string($selector=NULL)
380 // return code for a single selector
383 $indent_str = $this->indent_chars;
384 $this->indent_chars = '';
386 $prop_arr = $this->to_array($selector);
387 $out = $this->_style2string($prop_arr, TRUE);
389 $this->indent_chars = $indent_str;
392 // compose css code for complete data grid
396 $css_data = $this->to_array();
398 foreach ($css_data as $key => $prop_arr)
399 $out .= sprintf("%s {\n%s}\n\n",
401 $this->_style2string($prop_arr, TRUE));
408 // return a single-line string of a css definition
409 function to_inline($selector)
411 if ($this->css_data[$selector])
412 return str_replace('"', '\\"', $this->_style2string($this->css_data[$selector], FALSE));
416 // return an associative array with selector(s) as key and styles array as value
417 function to_array($selector=NULL)
419 if (!$selector && $this->grouped_output)
421 // build groups if desired
422 if (!sizeof($this->css_groups))
423 $this->_build_groups();
425 // modify group array to get an array(selector => properties)
427 foreach ($this->css_groups as $group_arr)
429 $key = join(', ', $group_arr['selectors']);
430 $out_arr[$key] = $group_arr['properties'];
434 $out_arr = $this->css_data;
436 return $selector ? $out_arr[$selector] : $out_arr;
441 function to_file($filepath)
443 if ($fp = fopen($filepath, 'w'))
445 fwrite($fp, $this->to_string());
454 // alias method for import_string() [DEPRECATED]
457 $this->import_string($str);
460 // alias method for to_string() [DEPRECATED]
463 return $this->to_string();
468 // ******** private methods ********
471 // parse a string and add styles to internal data grid
472 function _parse($str)
475 $str = preg_replace("/\/\*(.*)?\*\//Usi", '', $str);
477 // parse style definitions
478 if (!preg_match_all ('/([a-z0-9\.#*:_][a-z0-9\.\-_#:*,\[\]\(\)\s\"\'\+\|>~=]+)\s*\{([^\}]*)\}/ims', $str, $matches, PREG_SET_ORDER))
482 foreach ($matches as $match_arr)
484 // split selectors into array
485 $a_keys = $this->_parse_selectors(trim($match_arr[1]));
487 // parse each property of an element
488 $codes = explode(";", trim($match_arr[2]));
489 foreach ($codes as $code)
491 if (strlen(trim($code))>0)
493 // find the property and the value
494 if (!($sep = strpos($code, ':')))
497 $property = strtolower(trim(substr($code, 0, $sep)));
498 $value = trim(substr($code, $sep+1));
500 // add the property to the object array
501 foreach ($a_keys as $key)
502 $this->css_data[$key][$property] = $value;
508 if (sizeof($matches))
510 $this->css_groups = array();
518 // split selector group
519 function _parse_selectors($selector)
521 // trim selector and remove multiple spaces
522 $selector = preg_replace('/\s+/', ' ', trim($selector));
524 if (strpos($selector, ','))
525 return preg_split('/[\t\s\n\r]*,[\t\s\n\r]*/mi', $selector);
527 return array($selector);
531 // compare identical styles and make groups
532 function _build_groups()
535 $this->css_groups = array();
536 $string_group_map = array();
538 // bulild css string for each selector and check if the same is already defines
539 foreach ($this->css_data as $selector => $prop_arr)
541 // make shure to compare props in the same order
543 $compare_str = preg_replace('/[\s\t]+/', '', $this->_style2string($prop_arr, FALSE));
545 // add selector to extisting group
546 if (isset($string_group_map[$compare_str]))
548 $group_index = $string_group_map[$compare_str];
549 $this->css_groups[$group_index]['selectors'][] = $selector;
555 $i = sizeof($this->css_groups);
556 $string_group_map[$compare_str] = $i;
557 $this->css_groups[$i] = array('selectors' => array($selector),
558 'properties' => $this->css_data[$selector]);
564 // convert the prop array into a valid css definition
565 function _style2string($prop_arr, $multiline=TRUE)
568 $delm = $multiline ? "\n" : '';
569 $spacer = $multiline ? ' ' : '';
570 $indent = $multiline ? $this->indent_chars : '';
572 if (is_array($prop_arr))
573 foreach ($prop_arr as $prop => $value)
575 $out .= sprintf('%s%s:%s%s;%s',
586 // copy all properties inherited from superior styles to a specific selector
587 function _get_inherited_styles($selector, $loop=FALSE)
589 $css_props = $this->css_data[$selector] ? $this->css_data[$selector] : array();
591 // get styles from tag selector
592 if (preg_match('/(([a-z0-9]*)(\.[^\s]+)?)$/i', $selector, $regs))
598 if ($sel && is_array($this->css_data[$sel]))
599 $css_props = $this->_merge_styles($this->css_data[$sel], $css_props);
601 if ($class && is_array($this->css_data[$class]))
602 $css_props = $this->_merge_styles($this->css_data[$class], $css_props);
604 if ($tagname && is_array($this->css_data[$tagname]))
605 $css_props = $this->_merge_styles($this->css_data[$tagname], $css_props);
608 // analyse inheritance
609 if (strpos($selector, ' '))
611 $a_hier = split(' ', $selector);
612 if (sizeof($a_hier)>1)
615 $base_selector = join(' ', $a_hier);
617 // call this method recursively
618 $new_props = $this->_get_inherited_styles($base_selector, TRUE);
619 $css_props = $this->_merge_styles($new_props, $css_props);
624 if (!$loop && is_array($this->css_data['body']))
625 $css_props = $this->_merge_styles($this->css_data['body'], $css_props);
631 // merge two arrays with style properties together like a browser would do
632 function _merge_styles($one, $two)
634 // these properties are additive
635 foreach (array('text-decoration') as $prop)
636 if ($one[$prop] && $two[$prop])
638 // if value contains 'none' it's ignored
639 if (strstr($one[$prop], 'none'))
641 else if (strstr($two[$prop], 'none'))
644 $a_values_one = split(' ', $one[$prop]);
645 $a_values_two = split(' ', $two[$prop]);
646 $two[$prop] = join(' ', array_unique(array_merge($a_values_one, $a_values_two)));
649 return array_merge($one, $two);
654 function _get_file_path($file)
656 if (!$this->base_path && $GLOBALS['CSS_PATH'])
657 $this->set_basepath($GLOBALS['CSS_PATH']);
659 $base = ($file{0}=='/' || $file{0}=='.' || substr($file, 0, 7)=='http://') ? '' :
660 ($this->base_path ? $this->base_path.'/' : '');
668 class base_form_element
670 var $uppertags = FALSE;
671 var $upperattribs = FALSE;
672 var $upperprops = FALSE;
673 var $newline = FALSE;
675 var $attrib = array();
678 // create string with attributes
679 function create_attrib_string($tagname='')
681 if (!sizeof($this->attrib))
685 $this->attrib['name'] = $this->name;
687 $attrib_arr = array();
688 foreach ($this->attrib as $key => $value)
690 // don't output some internally used attributes
691 if (in_array($key, array('form', 'quicksearch')))
694 // skip if size if not numeric
695 if (($key=='size' && !is_numeric($value)))
698 // skip empty eventhandlers
699 if ((strpos($key,'on')===0 && $value==''))
702 // encode textarea content
704 $value = rep_specialchars_output($value, 'html', 'replace', FALSE);
706 // attributes with no value
707 if (in_array($key, array('checked', 'multiple', 'disabled', 'selected')))
710 $attrib_arr[] = $key;
712 // don't convert size of value attribute
713 else if ($key=='value')
714 $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), $value, 'value');
716 // regular tag attributes
718 $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), $this->_conv_case($value, 'value'));
721 return sizeof($attrib_arr) ? ' '.implode(' ', $attrib_arr) : '';
725 // convert tags and attributes to upper-/lowercase
726 // $type can either be "tag" or "attrib"
727 function _conv_case($str, $type='attrib')
730 return $this->uppertags ? strtoupper($str) : strtolower($str);
731 else if ($type == 'attrib')
732 return $this->upperattribs ? strtoupper($str) : strtolower($str);
733 else if ($type == 'value')
734 return $this->upperprops ? strtoupper($str) : strtolower($str);
739 class input_field extends base_form_element
744 function __construct($attrib=NULL)
746 if (is_array($attrib))
747 $this->attrib = $attrib;
750 $this->type = $attrib['type'];
752 if ($attrib['newline'])
753 $this->newline = TRUE;
756 // PHP 4 compatibility
757 function input_field($attrib=array())
759 $this->__construct($attrib);
763 function show($value=NULL, $attrib=NULL)
765 // overwrite object attributes
766 if (is_array($attrib))
767 $this->attrib = array_merge($this->attrib, $attrib);
769 // set value attribute
771 $this->attrib['value'] = $value;
773 $this->attrib['type'] = $this->type;
776 return sprintf('<%s%s />%s',
777 $this->_conv_case('input', 'tag'),
778 $this->create_attrib_string(),
779 ($this->newline ? "\n" : ""));
784 class textfield extends input_field
789 class passwordfield extends input_field
791 var $type = 'password';
794 class radiobutton extends input_field
799 class checkbox extends input_field
801 var $type = 'checkbox';
804 function show($value='', $attrib=NULL)
806 // overwrite object attributes
807 if (is_array($attrib))
808 $this->attrib = array_merge($this->attrib, $attrib);
810 $this->attrib['type'] = $this->type;
812 if ($value && (string)$value==(string)$this->attrib['value'])
813 $this->attrib['checked'] = TRUE;
815 $this->attrib['checked'] = FALSE;
818 return sprintf('<%s%s />%s',
819 $this->_conv_case('input', 'tag'),
820 $this->create_attrib_string(),
821 ($this->newline ? "\n" : ""));
826 class textarea extends base_form_element
829 function __construct($attrib=array())
831 $this->attrib = $attrib;
833 if ($attrib['newline'])
834 $this->newline = TRUE;
837 // PHP 4 compatibility
838 function textarea($attrib=array())
840 $this->__construct($attrib);
843 function show($value='', $attrib=NULL)
845 // overwrite object attributes
846 if (is_array($attrib))
847 $this->attrib = array_merge($this->attrib, $attrib);
849 // take value attribute as content
851 $value = $this->attrib['value'];
853 // make shure we don't print the value attribute
854 if (isset($this->attrib['value']))
855 unset($this->attrib['value']);
858 $value = rep_specialchars_output($value, 'html', 'replace', FALSE);
861 return sprintf('<%s%s>%s</%s>%s',
862 $this->_conv_case('textarea', 'tag'),
863 $this->create_attrib_string(),
865 $this->_conv_case('textarea', 'tag'),
866 ($this->newline ? "\n" : ""));
871 class hiddenfield extends base_form_element
873 var $fields_arr = array();
877 function __construct($attrib=NULL)
879 if (is_array($attrib))
883 // PHP 4 compatibility
884 function hiddenfield($attrib=NULL)
886 $this->__construct($attrib);
889 // add a hidden field to this instance
890 function add($attrib)
892 $this->fields_arr[] = $attrib;
899 foreach ($this->fields_arr as $attrib)
901 $this->attrib = $attrib;
902 $this->attrib['type'] = 'hidden';
904 $out .= sprintf('<%s%s />%s',
905 $this->_conv_case('input', 'tag'),
906 $this->create_attrib_string(),
907 ($this->newline ? "\n" : ""));
915 class select extends base_form_element
917 var $options = array();
922 // create instance. arguments are used to set attributes of select-tag
923 $select = new select(array('name' => 'fieldname'));
926 $select->add('Switzerland', 'CH');
928 // add multiple options
929 $select->add(array('Switzerland', 'Germany'),
932 // add 10 blank options with 50 chars
933 // used to fill with javascript (necessary for 4.x browsers)
934 $select->add_blank(10, 50);
936 // generate pulldown with selection 'Switzerland' and return html-code
937 // as second argument the same attributes available to instanciate can be used
938 print $select->show('CH');
942 function __construct($attrib=NULL)
944 if (is_array($attrib))
945 $this->attrib = $attrib;
947 if ($attrib['newline'])
948 $this->newline = TRUE;
951 // PHP 4 compatibility
952 function select($attrib=NULL)
954 $this->__construct($attrib);
958 function add($names, $values=NULL)
960 if (is_array($names))
962 foreach ($names as $i => $text)
963 $this->options[] = array('text' => $text, 'value' => (string)$values[$i]);
967 $this->options[] = array('text' => $names, 'value' => (string)$values);
972 function add_blank($nr, $width=0)
974 $text = $width ? str_repeat(' ', $width) : '';
976 for ($i=0; $i < $nr; $i++)
977 $this->options[] = array('text' => $text);
981 function show($select=array(), $attrib=NULL)
984 $value_str = $this->_conv_case(' value="%s"', 'attrib');
986 if (!is_array($select))
987 $select = array((string)$select);
989 foreach ($this->options as $option)
991 $selected = ((strlen($option['value']) && in_array($option['value'], $select, TRUE)) ||
992 (in_array($option['text'], $select, TRUE))) ? $this->_conv_case(' selected', 'attrib') : '';
994 $options_str .= sprintf("<%s%s%s>%s</%s>\n",
995 $this->_conv_case('option', 'tag'),
996 strlen($option['value']) ? sprintf($value_str, $option['value']) : '',
998 rep_specialchars_output($option['text'], 'html', 'replace', FALSE),
999 $this->_conv_case('option', 'tag'));
1003 return sprintf('<%s%s>%s</%s>%s',
1004 $this->_conv_case('select', 'tag'),
1005 $this->create_attrib_string(),
1007 $this->_conv_case('select', 'tag'),
1008 ($this->newline ? "\n" : ""));
1015 // ********* rcube schared functions *********
1018 // provide details about the client's browser
1019 function rcube_browser()
1021 $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT'];
1024 $bw['win'] = stristr($HTTP_USER_AGENT, 'win');
1025 $bw['mac'] = stristr($HTTP_USER_AGENT, 'mac');
1026 $bw['linux'] = stristr($HTTP_USER_AGENT, 'linux');
1027 $bw['unix'] = stristr($HTTP_USER_AGENT, 'unix');
1029 $bw['ns4'] = stristr($HTTP_USER_AGENT, 'mozilla/4') && !stristr($HTTP_USER_AGENT, 'msie');
1030 $bw['ns'] = ($bw['ns4'] || stristr($HTTP_USER_AGENT, 'netscape'));
1031 $bw['ie'] = stristr($HTTP_USER_AGENT, 'msie');
1032 $bw['mz'] = stristr($HTTP_USER_AGENT, 'mozilla/5');
1033 $bw['opera'] = stristr($HTTP_USER_AGENT, 'opera');
1034 $bw['safari'] = stristr($HTTP_USER_AGENT, 'safari');
1038 $test = eregi("mozilla\/([0-9\.]+)", $HTTP_USER_AGENT, $regs);
1039 $bw['ver'] = $test ? (float)$regs[1] : 0;
1043 $test = ereg("rv:([0-9\.]+)", $HTTP_USER_AGENT, $regs);
1044 $bw['ver'] = $test ? (float)$regs[1] : 0;
1048 $test = eregi("msie ([0-9\.]+)", $HTTP_USER_AGENT, $regs);
1049 $bw['ver'] = $test ? (float)$regs[1] : 0;
1053 $test = eregi("opera ([0-9\.]+)", $HTTP_USER_AGENT, $regs);
1054 $bw['ver'] = $test ? (float)$regs[1] : 0;
1057 if(eregi(" ([a-z]{2})-([a-z]{2})", $HTTP_USER_AGENT, $regs))
1058 $bw['lang'] = $regs[1];
1062 $bw['dom'] = ($bw['mz'] || $bw['safari'] || ($bw['ie'] && $bw['ver']>=5) || ($bw['opera'] && $bw['ver']>=7));
1063 $bw['pngalpha'] = $bw['mz'] || $bw['safari'] || ($bw['ie'] && $bw['ver']>=5.5) ||
1064 ($bw['ie'] && $bw['ver']>=5 && $bw['mac']) || ($bw['opera'] && $bw['ver']>=7) ? TRUE : FALSE;
1070 // get text in the desired language from the language file
1071 function rcube_label($attrib)
1073 global $sess_user_lang, $INSTALL_PATH, $OUTPUT;
1074 static $sa_text_data, $s_language, $utf8_decode;
1076 // extract attributes
1077 if (is_string($attrib))
1078 $attrib = array('name' => $attrib);
1080 $nr = is_numeric($attrib['nr']) ? $attrib['nr'] : 1;
1081 $vars = isset($attrib['vars']) ? $attrib['vars'] : '';
1083 $command_name = strlen($attrib['command']) ? $attrib['command'] : NULL;
1084 $alias = $attrib['name'] ? $attrib['name'] : ($command_name && $command_label_map[$command_name] ? $command_label_map[$command_name] : '');
1087 // load localized texts
1088 if (!$sa_text_data || $s_language != $sess_user_lang)
1090 $sa_text_data = array();
1092 // get english labels (these should be complete)
1093 @include($INSTALL_PATH.'program/localization/en_US/labels.inc');
1094 @include($INSTALL_PATH.'program/localization/en_US/messages.inc');
1096 if (is_array($labels))
1097 $sa_text_data = $labels;
1098 if (is_array($messages))
1099 $sa_text_data = array_merge($sa_text_data, $messages);
1101 // include user language files
1102 if ($sess_user_lang!='en' && is_dir($INSTALL_PATH.'program/localization/'.$sess_user_lang))
1104 include_once($INSTALL_PATH.'program/localization/'.$sess_user_lang.'/labels.inc');
1105 include_once($INSTALL_PATH.'program/localization/'.$sess_user_lang.'/messages.inc');
1107 if (is_array($labels))
1108 $sa_text_data = array_merge($sa_text_data, $labels);
1109 if (is_array($messages))
1110 $sa_text_data = array_merge($sa_text_data, $messages);
1113 $s_language = $sess_user_lang;
1116 // text does not exist
1117 if (!($text_item = $sa_text_data[$alias]))
1120 raise_error(array('code' => 500,
1124 'message' => "Missing localized text for '$alias' in '$sess_user_lang'"), TRUE, FALSE);
1129 // make text item array
1130 $a_text_item = is_array($text_item) ? $text_item : array('single' => $text_item);
1132 // decide which text to use
1134 $text = $a_text_item['single'];
1136 $text = $a_text_item['multiple'];
1139 if ($a_text_item['none'])
1140 $text = $a_text_item['none'];
1141 else if ($a_text_item['single'])
1142 $text = $a_text_item['single'];
1143 else if ($a_text_item['multiple'])
1144 $text = $a_text_item['multiple'];
1147 // default text is single
1149 $text = $a_text_item['single'];
1151 // replace vars in text
1152 if (is_array($attrib['vars']))
1154 foreach ($attrib['vars'] as $var_key=>$var_value)
1155 $a_replace_vars[substr($var_key, 0, 1)=='$' ? substr($var_key, 1) : $var_key] = $var_value;
1158 if ($a_replace_vars)
1159 $text = preg_replace('/\${?([_a-z]{1}[_a-z0-9]*)}?/ei', '$a_replace_vars["\1"]', $text);
1161 // remove variables in text which were not available in arg $vars and $nr
1162 eval("\$text = <<<EOF
1168 if (($attrib['uppercase'] && strtolower($attrib['uppercase']=='first')) || $attrib['ucfirst'])
1169 return ucfirst($text);
1170 else if ($attrib['uppercase'])
1171 return strtoupper($text);
1172 else if ($attrib['lowercase'])
1173 return strtolower($text);
1181 // send HTTP header for no-cacheing steps
1182 function send_nocacheing_headers()
1187 header("Expires: ".gmdate("D, d M Y H:i:s")." GMT");
1188 header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
1189 header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
1190 header("Pragma: no-cache");
1194 // send header with expire date 30 days in future
1195 function send_future_expire_header()
1197 if (!headers_sent())
1198 header("Expires: ".gmdate("D, d M Y H:i:s", mktime()+2600000)." GMT");
1202 // function to convert an array to a javascript array
1203 function array2js($arr, $type='')
1210 // no items in array
1212 return 'new Array()';
1216 $keys_arr = array_keys($arr);
1217 $is_assoc = $have_numeric = 0;
1219 for ($i=0; $i<sizeof($keys_arr); ++$i)
1221 if(is_numeric($keys_arr[$i]))
1223 if (!is_numeric($keys_arr[$i]) || $keys_arr[$i]!=$i)
1225 if($is_assoc && $have_numeric)
1229 $previous_was_array = false;
1230 while (list($key, $value) = each($arr))
1232 // enclose key with quotes if it is not variable-name conform
1233 if (!ereg("^[_a-zA-Z]{1}[_a-zA-Z0-9]*$", $key) /* || is_js_reserved_word($key) */)
1236 if (!is_array($value))
1238 $value = str_replace("\r\n", '\n', $value);
1239 $value = str_replace("\n", '\n', $value);
1243 if (!is_array($value))
1245 if ($type=='string')
1247 else if ((($type=='mixed' && is_numeric($value)) || $type=='int') && strlen($value)<16) // js interprets numbers with digits >15 as ...e+...
1254 $value = "'".preg_replace("/(?<!\\\)'/", "\'", $value)."'";
1256 $a_pairs[] = sprintf("%s%s",
1257 $is_assoc ? "$key:" : '',
1258 is_array($value) ? array2js($value, $type) : $value);
1264 $return = '{'.implode(',', $a_pairs).'}';
1266 $return = '['.implode(',', $a_pairs).']';
1277 // similar function as in_array() ut case-insensitive
1278 function in_array_nocase($needle, $haystack)
1280 foreach ($haystack as $value)
1282 if (strtolower($needle)===strtolower($value))
1291 // find out if the string content means TRUE or FALSE
1292 function get_boolean($str)
1294 $str = strtolower($str);
1295 if(in_array($str, array('false', '0', 'no', 'nein', ''), TRUE))
1302 function show_bytes($numbytes)
1304 if ($numbytes > 1024)
1305 return sprintf('%d KB', round($numbytes/1024));
1307 return sprintf('%d B', $numbytes);
1311 // convert paths like ../xxx to an absolute path using a base url
1312 function make_absolute_url($path, $base_url)
1314 $host_url = $base_url;
1317 // cut base_url to the last directory
1318 if (strpos($base_url, '/')>7)
1320 $host_url = substr($base_url, 0, strpos($base_url, '/'));
1321 $base_url = substr($base_url, 0, strrpos($base_url, '/'));
1324 // $path is absolute
1326 $abs_path = $host_url.$path;
1329 // strip './' because its the same as ''
1330 $path = preg_replace('/^\.\//', '', $path);
1332 if(preg_match_all('/\.\.\//', $path, $matches, PREG_SET_ORDER))
1333 foreach($matches as $a_match)
1335 if (strrpos($base_url, '/'))
1336 $base_url = substr($base_url, 0, strrpos($base_url, '/'));
1338 $path = substr($path, 3);
1341 $abs_path = $base_url.'/'.$path;
1348 // replace the middle part of a string with ...
1349 // if it is longer than the allowed length
1350 function abbrevate_string($str, $maxlength, $place_holder='...')
1352 $length = strlen($str);
1353 $first_part_length = floor($maxlength/2) - strlen($place_holder);
1355 if ($length > $maxlength)
1357 $second_starting_location = $length - $maxlength + $first_part_length + 1;
1358 $str = substr($str, 0, $first_part_length) . $place_holder . substr($str, $second_starting_location, $length);
1365 // make sure the string ends with a slash
1366 function slashify($str)
1368 return unslashify($str).'/';
1372 // remove slash at the end of the string
1373 function unslashify($str)
1375 return preg_replace('/\/$/', '', $str);
1379 // delete all files within a folder
1380 function clear_directory($dir_path)
1382 $dir = @opendir($dir_path);
1383 if(!$dir) return FALSE;
1385 while ($file = readdir($dir))
1386 if (strlen($file)>2)
1387 unlink("$dir_path/$file");
1394 // create a unix timestamp with a specified offset from now
1395 function get_offset_time($offset_str, $factor=1)
1397 if (preg_match('/^([0-9]+)\s*([smhdw])/i', $offset_str, $regs))
1399 $amount = (int)$regs[1];
1400 $unit = strtolower($regs[2]);
1404 $amount = (int)$offset_str;
1420 $ts += $amount * $factor;