Changeset 6d969b4 in github for program/include/rcube_shared.inc


Ignore:
Timestamp:
Aug 7, 2007 5:02:12 PM (6 years ago)
Author:
thomascube <thomas@…>
Branches:
master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
Children:
4b9efbb
Parents:
93be5b7
Message:

Documentation, code style and cleanup

File:
1 edited

Legend:

Unmodified
Added
Removed
  • program/include/rcube_shared.inc

    rf115416 r6d969b4  
    2121 
    2222 
    23 // ********* round cube schared classes ********* 
    24  
    25 class rcube_html_page 
    26   { 
    27   var $css; 
    28    
    29   var $scripts_path = ''; 
    30   var $script_files = array(); 
    31   var $external_scripts = array(); 
    32   var $scripts = array(); 
    33   var $charset = 'ISO-8859-1'; 
    34    
    35   var $script_tag_file = "<script type=\"text/javascript\" src=\"%s%s\"></script>\n"; 
    36   var $script_tag      = "<script type=\"text/javascript\">\n<!--\n%s\n\n//-->\n</script>\n"; 
    37   var $default_template = "<html>\n<head><title></title></head>\n<body></body>\n</html>"; 
    38   var $tag_format_external_script = "<script type=\"text/javascript\" src=\"%s\"></script>\n"; 
    39  
    40   var $title = ''; 
    41   var $header = ''; 
    42   var $footer = ''; 
    43   var $body = ''; 
    44   var $body_attrib = array(); 
    45   var $meta_tags = array(); 
    46  
    47  
    48   // PHP 5 constructor 
    49   function __construct() 
    50     { 
    51     $this->css = new rcube_css(); 
    52     } 
    53  
    54   // PHP 4 compatibility 
    55   function rcube_html_page() 
    56     { 
    57     $this->__construct(); 
    58     } 
    59  
    60  
    61   function include_script($file, $position='head') 
    62     { 
    63     static $sa_files = array(); 
    64      
    65     if (in_array($file, $sa_files)) 
    66       return; 
    67        
    68     if (!is_array($this->script_files[$position])) 
    69       $this->script_files[$position] = array(); 
    70        
    71     $this->script_files[$position][] = $file; 
    72     } 
    73      
    74   function include_external_script($script_location, $position='head') 
    75   { 
    76      if (!is_array($this->external_scripts[$position])) 
    77      { 
    78         $this->external_scripts[$position] = array(); 
    79      } 
    80       
    81      $this->external_scripts[$position][] = $script_location; 
    82   } 
    83  
    84   function add_script($script, $position='head') 
    85     { 
    86     if (!isset($this->scripts[$position])) 
    87       $this->scripts[$position] = "\n".rtrim($script); 
    88     else 
    89       $this->scripts[$position] .= "\n".rtrim($script); 
    90     } 
    91  
    92   function add_header($str) 
    93     { 
    94     $this->header .= "\n".$str; 
    95     } 
    96  
    97   function add_footer($str) 
    98     { 
    99     $this->footer .= "\n".$str; 
    100     } 
    101  
    102   function set_title($t) 
    103     { 
    104     $this->title = $t; 
    105     } 
    106  
    107  
    108   function set_charset($charset) 
    109     { 
    110     global $MBSTRING; 
    111      
    112     $this->charset = $charset; 
    113      
    114     if ($MBSTRING && function_exists("mb_internal_encoding")) 
    115       { 
    116       if(!@mb_internal_encoding($charset)) 
    117         $MBSTRING = FALSE; 
    118       } 
    119     } 
    120  
    121   function get_charset() 
    122     { 
    123     return $this->charset; 
    124     } 
    125  
    126  
    127   function reset() 
    128     { 
    129     $this->css = new rcube_css(); 
    130     $this->script_files = array(); 
    131     $this->scripts = array(); 
    132     $this->title = ''; 
    133     $this->header = ''; 
    134     $this->footer = ''; 
    135     } 
    136  
    137  
    138   function write($templ='', $base_path='') 
    139     { 
    140     $output = empty($templ) ? $this->default_template : trim($templ); 
    141      
    142     // set default page title 
    143     if (empty($this->title)) 
    144       $this->title = 'RoundCube Mail'; 
    145    
    146     // replace specialchars in content 
    147     $__page_title = Q($this->title, 'show', FALSE); 
    148     $__page_header = $__page_body = $__page_footer = ''; 
    149      
    150      
    151     // include meta tag with charset 
    152     if (!empty($this->charset)) 
    153       { 
    154       header('Content-Type: text/html; charset='.$this->charset); 
    155       $__page_header = '<meta http-equiv="content-type" content="text/html; charset='.$this->charset.'" />'."\n"; 
    156       } 
    157    
    158    
    159     // definition of the code to be placed in the document header and footer 
    160     if (is_array($this->script_files['head'])) 
    161       foreach ($this->script_files['head'] as $file) 
    162         $__page_header .= sprintf($this->script_tag_file, $this->scripts_path, $file); 
    163  
    164     if (is_array($this->external_scripts['head'])) 
    165       foreach ($this->external_scripts['head'] as $xscript) 
    166         $__page_header .= sprintf($this->tag_format_external_script, $xscript); 
    167  
    168     $head_script = $this->scripts['head_top'] . $this->scripts['head']; 
    169     if (!empty($head_script)) 
    170       $__page_header .= sprintf($this->script_tag, $head_script); 
    171  
    172     if (!empty($this->header)) 
    173       $__page_header .= $this->header; 
    174  
    175     if (is_array($this->script_files['foot'])) 
    176       foreach ($this->script_files['foot'] as $file) 
    177         $__page_footer .= sprintf($this->script_tag_file, $this->scripts_path, $file); 
    178  
    179     if (!empty($this->scripts['foot'])) 
    180       $__page_footer .= sprintf($this->script_tag, $this->scripts['foot']); 
    181        
    182     if (!empty($this->footer)) 
    183       $__page_footer .= $this->footer; 
    184  
    185     $__page_header .= $this->css->show(); 
    186    
    187     // find page header 
    188     if($hpos = strpos(strtolower($output), '</head>')) 
    189       $__page_header .= "\n"; 
    190     else  
    191       { 
    192       if (!is_numeric($hpos)) 
    193         $hpos = strpos(strtolower($output), '<body'); 
    194       if (!is_numeric($hpos) && ($hpos = strpos(strtolower($output), '<html'))) 
    195         { 
    196         while($output[$hpos]!='>') 
    197         $hpos++; 
    198         $hpos++; 
    199         } 
    200    
    201       $__page_header = "<head>\n<title>$__page_title</title>\n$__page_header\n</head>\n"; 
    202       } 
    203    
    204     // add page hader 
    205     if($hpos) 
    206       $output = substr($output,0,$hpos) . $__page_header . substr($output,$hpos,strlen($output)); 
    207     else 
    208       $output = $__page_header . $output; 
    209    
    210    
    211     // find page body 
    212     if($bpos = strpos(strtolower($output), '<body')) 
    213       { 
    214       while($output[$bpos]!='>') $bpos++; 
    215       $bpos++; 
    216       } 
    217     else 
    218       $bpos = strpos(strtolower($output), '</head>')+7; 
    219    
    220     // add page body 
    221     if($bpos && $__page_body) 
    222       $output = substr($output,0,$bpos) . "\n$__page_body\n" . substr($output,$bpos,strlen($output)); 
    223    
    224    
    225     // find and add page footer 
    226     $output_lc = strtolower($output); 
    227     if(($fpos = strrstr($output_lc, '</body>')) || 
    228        ($fpos = strrstr($output_lc, '</html>'))) 
    229       $output = substr($output, 0, $fpos) . "$__page_footer\n" . substr($output, $fpos); 
    230     else 
    231       $output .= "\n$__page_footer"; 
    232    
    233    
    234     // reset those global vars 
    235     $__page_header = $__page_footer = ''; 
    236    
    237    
    238     // correct absolute paths in images and other tags 
    239     $output = preg_replace('/(src|href|background)=(["\']?)(\/[a-z0-9_\-]+)/Ui', "\\1=\\2$base_path\\3", $output); 
    240     $output = str_replace('$__skin_path', $base_path, $output); 
    241    
    242     print rcube_charset_convert($output, 'UTF-8', $this->charset); 
    243     } 
    244      
    245      
    246   function _parse($templ) 
    247     { 
    248      
    249     } 
    250   } 
    251  
    252  
    253  
    254  
    255 class rcube_css 
    256   { 
    257   var $css_data = array(); 
    258  
    259   var $css_groups = array(); 
    260  
    261   var $include_files = array(); 
    262  
    263   var $grouped_output = TRUE; 
    264  
    265   var $content_type = 'text/css'; 
    266  
    267   var $base_path = ''; 
    268  
    269   var $indent_chars = "\t"; 
    270  
    271  
    272   // add or overwrite a css definition 
    273   // either pass porperty and value as separate arguments 
    274   // or provide an associative array as second argument 
    275   function set_style($selector, $property, $value='') 
    276     { 
    277     $a_elements = $this->_parse_selectors($selector); 
    278     foreach ($a_elements as $element) 
    279       { 
    280       if (!is_array($property)) 
    281         $property = array($property => $value); 
    282  
    283       foreach ($property as $name => $value) 
    284         $this->css_data[$element][strtolower($name)] = $value; 
    285       } 
    286  
    287     // clear goups array 
    288     $this->css_groups = array(); 
    289     } 
    290  
    291  
    292   // unset a style property 
    293   function remove_style($selector, $property) 
    294     { 
    295     if (!is_array($property)) 
    296       $property = array($property); 
    297  
    298     foreach ($property as $key) 
    299       unset($this->css_data[$selector][strtolower($key)]); 
    300  
    301     // clear goups array 
    302     $this->css_groups = array(); 
    303     } 
    304  
    305  
    306   // define base path for external css files 
    307   function set_basepath($path) 
    308     { 
    309     $this->base_path = preg_replace('/\/$/', '', $path); 
    310     } 
    311  
    312  
    313   // enable/disable grouped output 
    314   function set_grouped_output($grouped) 
    315     { 
    316     $this->grouped_output = $grouped; 
    317     } 
    318  
    319  
    320   // add a css file as external source 
    321   function include_file($filename, $media='') 
    322     { 
    323     // include multiple files 
    324     if (is_array($filename)) 
    325       { 
    326       foreach ($filename as $file) 
    327         $this->include_file($file, $media); 
    328       } 
    329     // add single file 
    330     else if (!in_array($filename, $this->include_files)) 
    331       $this->include_files[] = array('file' => $filename, 
    332                                      'media' => $media); 
    333     } 
    334  
    335  
    336   // parse css code 
    337   function import_string($str) 
    338     { 
    339     $ret = FALSE; 
    340     if (strlen($str)) 
    341       $ret = $this->_parse($str); 
    342  
    343     return $ret; 
    344     } 
    345  
    346  
    347   // open and parse a css file 
    348   function import_file($file) 
    349     { 
    350     $ret = FALSE; 
    351  
    352     if (!is_file($file)) 
    353       return $ret; 
    354  
    355     // for php version >= 4.3.0 
    356     if (function_exists('file_get_contents')) 
    357       $ret = $this->_parse(file_get_contents($file)); 
    358  
    359     // for order php versions 
    360     else if ($fp = fopen($file, 'r')) 
    361       { 
    362       $ret = $this->_parse(fread($fp, filesize($file))); 
    363       fclose($fp); 
    364       } 
    365  
    366     return $ret; 
    367     } 
    368  
    369  
    370   // copy all properties inherited from superior styles to a specific selector 
    371   function copy_inherited_styles($selector) 
    372     { 
    373     // get inherited props from body and tag/class selectors 
    374     $css_props = $this->_get_inherited_styles($selector); 
    375  
    376     // write modified props back and clear goups array 
    377     if (sizeof($css_props)) 
    378       { 
    379       $this->css_data[$selector] = $css_props; 
    380       $this->css_groups = array(); 
    381       } 
    382     } 
    383  
    384  
    385   // return css definition for embedding in HTML 
    386   function show() 
    387     { 
    388     $out = ''; 
    389  
    390     // include external css files 
    391     if (sizeof($this->include_files)) 
    392       foreach ($this->include_files as $file_arr) 
    393       $out .= sprintf('<link rel="stylesheet" type="%s" href="%s"%s>'."\n", 
    394                         $this->content_type, 
    395                         $this->_get_file_path($file_arr['file']), 
    396                         $file_arr['media'] ? ' media="'.$file_arr['media'].'"' : ''); 
    397  
    398  
    399     // compose css string 
    400     if (sizeof($this->css_data)) 
    401       $out .= sprintf("<style type=\"%s\">\n<!--\n\n%s-->\n</style>", 
    402                       $this->content_type, 
    403                       $this->to_string()); 
    404  
    405  
    406     return $out; 
    407     } 
    408  
    409  
    410   // return valid css code of the current styles grid 
    411   function to_string($selector=NULL) 
    412     { 
    413     // return code for a single selector 
    414     if ($selector) 
    415       { 
    416       $indent_str = $this->indent_chars; 
    417       $this->indent_chars = ''; 
    418  
    419       $prop_arr = $this->to_array($selector); 
    420       $out = $this->_style2string($prop_arr, TRUE); 
    421  
    422       $this->indent_chars = $indent_str; 
    423       } 
    424  
    425     // compose css code for complete data grid 
    426     else 
    427       { 
    428       $out = ''; 
    429       $css_data = $this->to_array(); 
    430  
    431       foreach ($css_data as $key => $prop_arr) 
    432         $out .= sprintf("%s {\n%s}\n\n", 
    433                         $key, 
    434                         $this->_style2string($prop_arr, TRUE)); 
    435       } 
    436  
    437     return $out; 
    438     } 
    439  
    440  
    441   // return a single-line string of a css definition 
    442   function to_inline($selector) 
    443     { 
    444     if ($this->css_data[$selector]) 
    445       return str_replace('"', '\\"', $this->_style2string($this->css_data[$selector], FALSE)); 
    446     } 
    447  
    448  
    449   // return an associative array with selector(s) as key and styles array as value 
    450   function to_array($selector=NULL) 
    451     { 
    452     if (!$selector && $this->grouped_output) 
    453       { 
    454       // build groups if desired 
    455       if (!sizeof($this->css_groups)) 
    456         $this->_build_groups(); 
    457  
    458       // modify group array to get an array(selector => properties) 
    459       $out_arr = array(); 
    460       foreach ($this->css_groups as $group_arr) 
    461         { 
    462         $key = join(', ', $group_arr['selectors']); 
    463         $out_arr[$key] = $group_arr['properties']; 
    464         } 
    465       } 
    466     else 
    467       $out_arr = $this->css_data; 
    468  
    469     return $selector ? $out_arr[$selector] : $out_arr; 
    470     } 
    471  
    472  
    473   // create a css file 
    474   function to_file($filepath) 
    475     { 
    476     if ($fp = fopen($filepath, 'w')) 
    477       { 
    478       fwrite($fp, $this->to_string()); 
    479       fclose($fp); 
    480       return TRUE; 
    481       } 
    482  
    483     return FALSE; 
    484     } 
    485  
    486  
    487   // alias method for import_string() [DEPRECATED] 
    488   function add($str) 
    489     { 
    490     $this->import_string($str); 
    491     } 
    492  
    493   // alias method for to_string() [DEPRECATED] 
    494   function get() 
    495     { 
    496     return $this->to_string(); 
    497     } 
    498  
    499  
    500  
    501   // ******** private methods ******** 
    502  
    503  
    504   // parse a string and add styles to internal data grid 
    505   function _parse($str) 
    506     { 
    507     // remove comments 
    508     $str = preg_replace("/\/\*(.*)?\*\//Usi", '', $str); 
    509  
    510     // parse style definitions 
    511     if (!preg_match_all ('/([a-z0-9\.#*:_][a-z0-9\.\-_#:*,\[\]\(\)\s\"\'\+\|>~=]+)\s*\{([^\}]*)\}/ims', $str, $matches, PREG_SET_ORDER)) 
    512       return FALSE; 
    513  
    514  
    515     foreach ($matches as $match_arr) 
    516       { 
    517       // split selectors into array 
    518       $a_keys = $this->_parse_selectors(trim($match_arr[1])); 
    519  
    520       // parse each property of an element 
    521       $codes = explode(";", trim($match_arr[2])); 
    522       foreach ($codes as $code) 
    523         { 
    524         if (strlen(trim($code))>0) 
    525           { 
    526           // find the property and the value 
    527           if (!($sep = strpos($code, ':'))) 
    528             continue; 
    529  
    530           $property = strtolower(trim(substr($code, 0, $sep))); 
    531           $value    = trim(substr($code, $sep+1)); 
    532  
    533           // add the property to the object array 
    534           foreach ($a_keys as $key) 
    535             $this->css_data[$key][$property] = $value; 
    536           } 
    537         } 
    538       } 
    539  
    540     // clear goups array 
    541     if (sizeof($matches)) 
    542       { 
    543       $this->css_groups = array(); 
    544       return TRUE; 
    545       } 
    546  
    547     return FALSE; 
    548     } 
    549  
    550  
    551   // split selector group 
    552   function _parse_selectors($selector) 
    553     { 
    554     // trim selector and remove multiple spaces 
    555     $selector = preg_replace('/\s+/', ' ', trim($selector)); 
    556  
    557     if (strpos($selector, ',')) 
    558       return preg_split('/[\t\s\n\r]*,[\t\s\n\r]*/mi', $selector); 
    559     else 
    560       return array($selector); 
    561     } 
    562  
    563  
    564   // compare identical styles and make groups 
    565   function _build_groups() 
    566     { 
    567     // clear group array 
    568     $this->css_groups = array(); 
    569     $string_group_map = array(); 
    570  
    571     // bulild css string for each selector and check if the same is already defines 
    572     foreach ($this->css_data as $selector => $prop_arr) 
    573       { 
    574       // make shure to compare props in the same order 
    575       ksort($prop_arr); 
    576       $compare_str = preg_replace('/[\s\t]+/', '', $this->_style2string($prop_arr, FALSE)); 
    577  
    578       // add selector to extisting group 
    579       if (isset($string_group_map[$compare_str])) 
    580         { 
    581         $group_index = $string_group_map[$compare_str]; 
    582         $this->css_groups[$group_index]['selectors'][] = $selector; 
    583         } 
    584  
    585       // create new group 
    586       else 
    587         { 
    588         $i = sizeof($this->css_groups); 
    589         $string_group_map[$compare_str] = $i; 
    590         $this->css_groups[$i] = array('selectors' => array($selector), 
    591                                       'properties' => $this->css_data[$selector]); 
    592         } 
    593       } 
    594     } 
    595  
    596  
    597   // convert the prop array into a valid css definition 
    598   function _style2string($prop_arr, $multiline=TRUE) 
    599     { 
    600     $out = ''; 
    601     $delm   = $multiline ? "\n" : ''; 
    602     $spacer = $multiline ? ' ' : ''; 
    603     $indent = $multiline ? $this->indent_chars : ''; 
    604  
    605     if (is_array($prop_arr)) 
    606       foreach ($prop_arr as $prop => $value) 
    607         if (strlen($value)) 
    608           $out .= sprintf('%s%s:%s%s;%s', 
    609                           $indent, 
    610                           $prop, 
    611                           $spacer, 
    612                           $value, 
    613                           $delm); 
    614  
    615     return $out; 
    616     } 
    617  
    618  
    619   // copy all properties inherited from superior styles to a specific selector 
    620   function _get_inherited_styles($selector, $loop=FALSE) 
    621     { 
    622     $css_props = $this->css_data[$selector] ? $this->css_data[$selector] : array(); 
    623  
    624     // get styles from tag selector 
    625     if (preg_match('/(([a-z0-9]*)(\.[^\s]+)?)$/i', $selector, $regs)) 
    626       { 
    627       $sel = $regs[1]; 
    628       $tagname = $regs[2]; 
    629       $class = $regs[3]; 
    630  
    631       if ($sel && is_array($this->css_data[$sel])) 
    632         $css_props = $this->_merge_styles($this->css_data[$sel], $css_props); 
    633  
    634       if ($class && is_array($this->css_data[$class])) 
    635         $css_props = $this->_merge_styles($this->css_data[$class], $css_props); 
    636  
    637       if ($tagname && is_array($this->css_data[$tagname])) 
    638         $css_props = $this->_merge_styles($this->css_data[$tagname], $css_props); 
    639       } 
    640  
    641     // analyse inheritance 
    642     if (strpos($selector, ' ')) 
    643       { 
    644       $a_hier = split(' ', $selector); 
    645       if (sizeof($a_hier)>1) 
    646         { 
    647         array_pop($a_hier); 
    648         $base_selector = join(' ', $a_hier); 
    649  
    650         // call this method recursively 
    651         $new_props = $this->_get_inherited_styles($base_selector, TRUE); 
    652         $css_props = $this->_merge_styles($new_props, $css_props); 
    653         } 
    654       } 
    655  
    656     // get body style 
    657     if (!$loop && is_array($this->css_data['body'])) 
    658       $css_props = $this->_merge_styles($this->css_data['body'], $css_props); 
    659  
    660     return $css_props; 
    661     } 
    662  
    663  
    664   // merge two arrays with style properties together like a browser would do 
    665   function _merge_styles($one, $two) 
    666     { 
    667     // these properties are additive 
    668     foreach (array('text-decoration') as $prop) 
    669       if ($one[$prop] && $two[$prop]) 
    670         { 
    671         // if value contains 'none' it's ignored 
    672         if (strstr($one[$prop], 'none')) 
    673           continue; 
    674         else if (strstr($two[$prop], 'none')) 
    675           unset($two[$prop]); 
    676  
    677         $a_values_one = split(' ', $one[$prop]); 
    678         $a_values_two = split(' ', $two[$prop]); 
    679         $two[$prop] = join(' ', array_unique(array_merge($a_values_one, $a_values_two))); 
    680         } 
    681  
    682     return array_merge($one, $two); 
    683     } 
    684  
    685  
    686   // resolve file path 
    687   function _get_file_path($file) 
    688     { 
    689     if (!$this->base_path && $GLOBALS['CSS_PATH']) 
    690       $this->set_basepath($GLOBALS['CSS_PATH']); 
    691  
    692     $base = ($file{0}=='/' || $file{0}=='.' || substr($file, 0, 7)=='http://') ? '' : 
    693             ($this->base_path ? $this->base_path.'/' : ''); 
    694     return $base.$file; 
    695     } 
    696  
    697   } 
    698  
    699  
    700  
    701 class base_form_element 
    702   { 
    703   var $uppertags = FALSE; 
    704   var $upperattribs = FALSE; 
    705   var $upperprops = FALSE; 
    706   var $newline = FALSE; 
    707    
    708   var $attrib = array(); 
    709  
    710  
    711   // create string with attributes 
    712   function create_attrib_string($tagname='') 
    713     { 
    714     if (!sizeof($this->attrib)) 
    715       return ''; 
    716  
    717     if ($this->name!='') 
    718       $this->attrib['name'] = $this->name; 
    719  
    720     $attrib_arr = array(); 
    721     foreach ($this->attrib as $key => $value) 
    722       { 
    723       // don't output some internally used attributes 
    724       if (in_array($key, array('form', 'quicksearch'))) 
    725         continue; 
    726  
    727       // skip if size if not numeric 
    728       if (($key=='size' && !is_numeric($value))) 
    729         continue; 
    730          
    731       // skip empty eventhandlers 
    732       if ((strpos($key,'on')===0 && $value=='')) 
    733         continue; 
    734  
    735       // encode textarea content 
    736       if ($key=='value') 
    737         $value = Q($value, 'strict', FALSE); 
    738  
    739       // attributes with no value 
    740       if (in_array($key, array('checked', 'multiple', 'disabled', 'selected'))) 
    741         { 
    742         if ($value) 
    743           $attrib_arr[] = $key; 
    744         } 
    745       // don't convert size of value attribute 
    746       else if ($key=='value') 
    747         $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), $value, 'value'); 
    748          
    749       // regular tag attributes 
    750       else 
    751         $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), $this->_conv_case($value, 'value')); 
    752       } 
    753  
    754     return sizeof($attrib_arr) ? ' '.implode(' ', $attrib_arr) : ''; 
    755     } 
    756      
    757      
    758   // convert tags and attributes to upper-/lowercase 
    759   // $type can either be "tag" or "attrib" 
    760   function _conv_case($str, $type='attrib') 
    761     { 
    762     if ($type == 'tag') 
    763       return $this->uppertags ? strtoupper($str) : strtolower($str); 
    764     else if ($type == 'attrib') 
    765       return $this->upperattribs ? strtoupper($str) : strtolower($str); 
    766     else if ($type == 'value') 
    767       return $this->upperprops ? strtoupper($str) : strtolower($str); 
    768     }     
    769   } 
    770  
    771  
    772 class input_field extends base_form_element 
    773   { 
    774   var $type = 'text'; 
    775    
    776   // PHP 5 constructor 
    777   function __construct($attrib=NULL) 
    778     { 
    779     if (is_array($attrib)) 
    780       $this->attrib = $attrib; 
    781  
    782     if ($attrib['type']) 
    783       $this->type = $attrib['type'];     
    784  
    785     if ($attrib['newline']) 
    786       $this->newline = TRUE;     
    787     } 
    788  
    789   // PHP 4 compatibility 
    790   function input_field($attrib=array()) 
    791     { 
    792     $this->__construct($attrib); 
    793     }   
    794  
    795   // compose input tag 
    796   function show($value=NULL, $attrib=NULL) 
    797     { 
    798     // overwrite object attributes 
    799     if (is_array($attrib)) 
    800       $this->attrib = array_merge($this->attrib, $attrib); 
    801  
    802     // set value attribute 
    803     if ($value!==NULL) 
    804       $this->attrib['value'] = $value; 
    805  
    806     $this->attrib['type'] = $this->type; 
    807  
    808     // return final tag 
    809     return sprintf('<%s%s />%s', 
    810                    $this->_conv_case('input', 'tag'), 
    811                    $this->create_attrib_string(), 
    812                    ($this->newline ? "\n" : ""));     
    813     }   
    814   } 
    815  
    816  
    817 class textfield extends input_field 
    818   { 
    819   var $type = 'text'; 
    820   } 
    821  
    822 class passwordfield extends input_field 
    823   { 
    824   var $type = 'password'; 
    825   } 
    826  
    827 class radiobutton extends input_field 
    828   { 
    829   var $type = 'radio'; 
    830   } 
    831  
    832 class checkbox extends input_field 
    833   { 
    834   var $type = 'checkbox'; 
    835  
    836  
    837   function show($value='', $attrib=NULL) 
    838     { 
    839     // overwrite object attributes 
    840     if (is_array($attrib)) 
    841       $this->attrib = array_merge($this->attrib, $attrib);     
    842  
    843     $this->attrib['type'] = $this->type; 
    844  
    845     if ($value && (string)$value==(string)$this->attrib['value']) 
    846       $this->attrib['checked'] = TRUE; 
    847     else 
    848       $this->attrib['checked'] = FALSE; 
    849  
    850     // return final tag 
    851     return sprintf('<%s%s />%s', 
    852                    $this->_conv_case('input', 'tag'), 
    853                    $this->create_attrib_string(), 
    854                    ($this->newline ? "\n" : ""));     
    855     } 
    856   } 
    857  
    858  
    859 class textarea extends base_form_element 
    860   { 
    861   // PHP 5 constructor 
    862   function __construct($attrib=array()) 
    863     { 
    864     $this->attrib = $attrib; 
    865  
    866     if ($attrib['newline']) 
    867       $this->newline = TRUE;     
    868     } 
    869  
    870   // PHP 4 compatibility 
    871   function textarea($attrib=array()) 
    872     { 
    873     $this->__construct($attrib); 
    874     } 
    875      
    876   function show($value='', $attrib=NULL) 
    877     { 
    878     // overwrite object attributes 
    879     if (is_array($attrib)) 
    880       $this->attrib = array_merge($this->attrib, $attrib); 
    881      
    882     // take value attribute as content 
    883     if ($value=='') 
    884       $value = $this->attrib['value']; 
    885      
    886     // make shure we don't print the value attribute 
    887     if (isset($this->attrib['value'])) 
    888       unset($this->attrib['value']); 
    889  
    890     if (!empty($value) && !isset($this->attrib['mce_editable'])) 
    891       $value = Q($value, 'strict', FALSE); 
    892  
    893     // return final tag 
    894     return sprintf('<%s%s>%s</%s>%s', 
    895                    $this->_conv_case('textarea', 'tag'), 
    896                    $this->create_attrib_string(), 
    897                    $value, 
    898                    $this->_conv_case('textarea', 'tag'), 
    899                    ($this->newline ? "\n" : ""));        
    900     } 
    901   } 
    902  
    903  
    904 class hiddenfield extends base_form_element 
    905   { 
    906   var $fields_arr = array(); 
    907   var $newline = TRUE; 
    908  
    909   // PHP 5 constructor 
    910   function __construct($attrib=NULL) 
    911     { 
    912     if (is_array($attrib)) 
    913       $this->add($attrib); 
    914     } 
    915  
    916   // PHP 4 compatibility 
    917   function hiddenfield($attrib=NULL) 
    918     { 
    919     $this->__construct($attrib); 
    920     } 
    921  
    922   // add a hidden field to this instance 
    923   function add($attrib) 
    924     { 
    925     $this->fields_arr[] = $attrib; 
    926     } 
    927  
    928  
    929   function show() 
    930     { 
    931     $out = ''; 
    932     foreach ($this->fields_arr as $attrib) 
    933       { 
    934       $this->attrib = $attrib; 
    935       $this->attrib['type'] = 'hidden'; 
    936        
    937       $out .= sprintf('<%s%s />%s', 
    938                    $this->_conv_case('input', 'tag'), 
    939                    $this->create_attrib_string(), 
    940                    ($this->newline ? "\n" : ""));    
    941       } 
    942  
    943     return $out; 
    944     } 
    945   } 
    946  
    947  
    948 class select extends base_form_element 
    949   { 
    950   var $options = array(); 
    951  
    952   /* 
    953   syntax: 
    954   ------- 
    955   // create instance. arguments are used to set attributes of select-tag 
    956   $select = new select(array('name' => 'fieldname')); 
    957  
    958   // add one option 
    959   $select->add('Switzerland', 'CH'); 
    960  
    961   // add multiple options 
    962   $select->add(array('Switzerland', 'Germany'), 
    963                array('CH', 'DE')); 
    964  
    965   // add 10 blank options with 50 chars 
    966   // used to fill with javascript (necessary for 4.x browsers) 
    967   $select->add_blank(10, 50); 
    968  
    969   // generate pulldown with selection 'Switzerland'  and return html-code 
    970   // as second argument the same attributes available to instanciate can be used 
    971   print $select->show('CH'); 
    972   */ 
    973  
    974   // PHP 5 constructor 
    975   function __construct($attrib=NULL) 
    976     { 
    977     if (is_array($attrib)) 
    978       $this->attrib = $attrib; 
    979  
    980     if ($attrib['newline']) 
    981       $this->newline = TRUE; 
    982     } 
    983  
    984   // PHP 4 compatibility 
    985   function select($attrib=NULL) 
    986     { 
    987     $this->__construct($attrib); 
    988     } 
    989  
    990  
    991   function add($names, $values=NULL) 
    992     { 
    993     if (is_array($names)) 
    994       { 
    995       foreach ($names as $i => $text) 
    996         $this->options[] = array('text' => $text, 'value' => (string)$values[$i]); 
    997       } 
    998     else 
    999       { 
    1000       $this->options[] = array('text' => $names, 'value' => (string)$values); 
    1001       } 
    1002     } 
    1003  
    1004      
    1005   function add_blank($nr, $width=0) 
    1006     { 
    1007     $text = $width ? str_repeat('&nbsp;', $width) : ''; 
    1008      
    1009     for ($i=0; $i < $nr; $i++) 
    1010       $this->options[] = array('text' => $text); 
    1011     } 
    1012  
    1013    
    1014   function show($select=array(), $attrib=NULL) 
    1015     { 
    1016     $options_str = "\n"; 
    1017     $value_str = $this->_conv_case(' value="%s"', 'attrib'); 
    1018      
    1019     if (!is_array($select)) 
    1020       $select = array((string)$select); 
    1021  
    1022     foreach ($this->options as $option) 
    1023       { 
    1024       $selected = ((isset($option['value']) && 
    1025                     in_array($option['value'], $select, TRUE)) || 
    1026                    (in_array($option['text'], $select, TRUE))) ? 
    1027         $this->_conv_case(' selected', 'attrib') : ''; 
    1028                     
    1029       $options_str .= sprintf("<%s%s%s>%s</%s>\n", 
    1030                              $this->_conv_case('option', 'tag'), 
    1031                              !empty($option['value']) ? sprintf($value_str, Q($option['value'])) : '', 
    1032                              $selected,  
    1033                              Q($option['text'], 'strict', FALSE), 
    1034                              $this->_conv_case('option', 'tag')); 
    1035       } 
    1036  
    1037     // return final tag 
    1038     return sprintf('<%s%s>%s</%s>%s', 
    1039                    $this->_conv_case('select', 'tag'), 
    1040                    $this->create_attrib_string(), 
    1041                    $options_str, 
    1042                    $this->_conv_case('select', 'tag'), 
    1043                    ($this->newline ? "\n" : ""));     
    1044     } 
    1045   } 
    1046  
    1047  
    1048  
    1049  
    1050 // ********* rcube schared functions ********* 
    1051  
    1052  
    1053 // provide details about the client's browser 
     23/** 
     24 * RoundCube shared functions 
     25 *  
     26 * @package Core 
     27 */ 
     28 
     29 
     30/** 
     31 * Provide details about the client's browser 
     32 * 
     33 * @return array Key-value pairs of browser properties 
     34 */ 
    105435function rcube_browser() 
    1055   { 
     36{ 
    105637  $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT']; 
    105738 
     
    107051 
    107152  if($bw['ns']) 
    1072     { 
     53  { 
    107354    $test = eregi("mozilla\/([0-9\.]+)", $HTTP_USER_AGENT, $regs); 
    107455    $bw['ver'] = $test ? (float)$regs[1] : 0; 
    1075     } 
     56  } 
    107657  if($bw['mz']) 
    1077     { 
     58  { 
    107859    $test = ereg("rv:([0-9\.]+)", $HTTP_USER_AGENT, $regs); 
    107960    $bw['ver'] = $test ? (float)$regs[1] : 0; 
    1080     } 
     61  } 
    108162  if($bw['ie']) 
    1082     { 
     63  { 
    108364    $test = eregi("msie ([0-9\.]+)", $HTTP_USER_AGENT, $regs); 
    108465    $bw['ver'] = $test ? (float)$regs[1] : 0; 
    1085     } 
     66  } 
    108667  if($bw['opera']) 
    1087     { 
     68  { 
    108869    $test = eregi("opera ([0-9\.]+)", $HTTP_USER_AGENT, $regs); 
    108970    $bw['ver'] = $test ? (float)$regs[1] : 0; 
    1090     } 
     71  } 
    109172 
    109273  if(eregi(" ([a-z]{2})-([a-z]{2})", $HTTP_USER_AGENT, $regs)) 
     
    110081 
    110182  return $bw; 
    1102   } 
    1103  
    1104  
    1105 // get text in the desired language from the language file 
     83} 
     84 
     85 
     86/** 
     87 * Get localized text in the desired language 
     88 * 
     89 * @param mixed Named parameters array or label name 
     90 * @return string Localized text 
     91 */ 
    110692function rcube_label($attrib) 
    1107   { 
     93{ 
    110894  global $sess_user_lang, $INSTALL_PATH, $OUTPUT; 
    110995  static $sa_text_data, $s_language, $utf8_decode; 
     
    1136122    // include user language files 
    1137123    if ($sess_user_lang!='en' && is_dir($INSTALL_PATH.'program/localization/'.$sess_user_lang)) 
    1138       { 
     124    { 
    1139125      include_once($INSTALL_PATH.'program/localization/'.$sess_user_lang.'/labels.inc'); 
    1140126      include_once($INSTALL_PATH.'program/localization/'.$sess_user_lang.'/messages.inc'); 
     
    1144130      if (is_array($messages)) 
    1145131        $sa_text_data = array_merge($sa_text_data, $messages); 
    1146       } 
     132    } 
    1147133       
    1148134    $s_language = $sess_user_lang; 
    1149     } 
     135  } 
    1150136 
    1151137  // text does not exist 
    1152138  if (!($text_item = $sa_text_data[$alias])) 
    1153     { 
     139  { 
    1154140    /* 
    1155     raise_error(array('code' => 500, 
    1156                       'type' => 'php', 
    1157                       'line' => __LINE__, 
    1158                       'file' => __FILE__, 
    1159                       'message' => "Missing localized text for '$alias' in '$sess_user_lang'"), TRUE, FALSE); 
     141    raise_error(array( 
     142      'code' => 500, 
     143      'type' => 'php', 
     144      'line' => __LINE__, 
     145      'file' => __FILE__, 
     146      'message' => "Missing localized text for '$alias' in '$sess_user_lang'"), TRUE, FALSE); 
    1160147    */ 
    1161148    return "[$alias]"; 
    1162     } 
     149  } 
    1163150 
    1164151  // make text item array  
     
    1171158    $text = $a_text_item['multiple']; 
    1172159  else if ($nr==0) 
    1173     { 
     160  { 
    1174161    if ($a_text_item['none']) 
    1175162      $text = $a_text_item['none']; 
     
    1178165    else if ($a_text_item['multiple']) 
    1179166      $text = $a_text_item['multiple']; 
    1180     } 
     167  } 
    1181168 
    1182169  // default text is single 
     
    1186173  // replace vars in text 
    1187174  if (is_array($attrib['vars'])) 
    1188     { 
     175  { 
    1189176    foreach ($attrib['vars'] as $var_key=>$var_value) 
    1190177      $a_replace_vars[substr($var_key, 0, 1)=='$' ? substr($var_key, 1) : $var_key] = $var_value; 
    1191     } 
     178  } 
    1192179 
    1193180  if ($a_replace_vars) 
     
    1209196 
    1210197  return $text; 
    1211   } 
    1212  
    1213  
    1214 // send HTTP header for no-cacheing steps 
     198} 
     199 
     200 
     201/** 
     202 * Send HTTP headers to prevent caching this page 
     203 */ 
    1215204function send_nocacheing_headers() 
    1216   { 
     205{ 
    1217206  if (headers_sent()) 
    1218207    return; 
     
    1222211  header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); 
    1223212  header("Pragma: no-cache"); 
    1224   } 
    1225  
    1226  
    1227 // send header with expire date 30 days in future 
     213} 
     214 
     215 
     216/** 
     217 * Send header with expire date 30 days in future 
     218 * 
     219 * @param int Expiration time in seconds 
     220 */ 
    1228221function send_future_expire_header($offset=2600000) 
    1229   { 
     222{ 
    1230223  if (headers_sent()) 
    1231224    return; 
     
    1234227  header("Cache-Control: max-age=$offset"); 
    1235228  header("Pragma: "); 
    1236   } 
    1237  
    1238  
    1239 // check request for If-Modified-Since and send an according response 
     229} 
     230 
     231 
     232/** 
     233 * Check request for If-Modified-Since and send an according response. 
     234 * This will terminate the current script if headers match the given values 
     235 * 
     236 * @param int Modified date as unix timestamp 
     237 * @param string Etag value for caching 
     238 */ 
    1240239function send_modified_header($mdate, $etag=null) 
    1241240{ 
     
    1269268 
    1270269/** 
    1271  * Convert a variable into a javascript notation string 
     270 * Convert a variable into a javascript object notation 
     271 * 
     272 * @param mixed Input value 
     273 * @return string Serialized JSON string 
    1272274 */ 
    1273275function json_serialize($var) 
    1274   { 
    1275     if (is_object($var)) 
    1276       $var = get_object_vars($var); 
    1277  
    1278     if (is_array($var)) 
     276{ 
     277  if (is_object($var)) 
     278    $var = get_object_vars($var); 
     279 
     280  if (is_array($var)) 
     281  { 
     282    // empty array 
     283    if (!sizeof($var)) 
     284      return '[]'; 
     285    else 
    1279286    { 
    1280       // empty array 
    1281       if (!sizeof($var)) 
    1282         return '[]'; 
    1283       else 
     287      $keys_arr = array_keys($var); 
     288      $is_assoc = $have_numeric = 0; 
     289 
     290      for ($i=0; $i<sizeof($keys_arr); ++$i) 
    1284291      { 
    1285         $keys_arr = array_keys($var); 
    1286         $is_assoc = $have_numeric = 0; 
    1287  
    1288         for ($i=0; $i<sizeof($keys_arr); ++$i) 
    1289         { 
    1290           if (is_numeric($keys_arr[$i])) 
    1291             $have_numeric = 1; 
    1292           if (!is_numeric($keys_arr[$i]) || $keys_arr[$i] != $i) 
    1293             $is_assoc = 1; 
    1294           if ($is_assoc && $have_numeric) 
    1295             break; 
    1296         } 
    1297          
    1298         $brackets = $is_assoc ? '{}' : '[]'; 
    1299         $pairs = array(); 
    1300  
    1301         foreach ($var as $key => $value) 
    1302         { 
    1303           // enclose key with quotes if it is not variable-name conform 
    1304           if (!ereg("^[_a-zA-Z]{1}[_a-zA-Z0-9]*$", $key) /* || is_js_reserved_word($key) */) 
    1305             $key = "'$key'"; 
    1306  
    1307           $pairs[] = sprintf("%s%s", $is_assoc ? "$key:" : '', json_serialize($value)); 
    1308         } 
    1309  
    1310         return $brackets{0} . implode(',', $pairs) . $brackets{1}; 
     292        if (is_numeric($keys_arr[$i])) 
     293          $have_numeric = 1; 
     294        if (!is_numeric($keys_arr[$i]) || $keys_arr[$i] != $i) 
     295          $is_assoc = 1; 
     296        if ($is_assoc && $have_numeric) 
     297          break; 
    1311298      } 
     299       
     300      $brackets = $is_assoc ? '{}' : '[]'; 
     301      $pairs = array(); 
     302 
     303      foreach ($var as $key => $value) 
     304      { 
     305        // enclose key with quotes if it is not variable-name conform 
     306        if (!ereg("^[_a-zA-Z]{1}[_a-zA-Z0-9]*$", $key) /* || is_js_reserved_word($key) */) 
     307          $key = "'$key'"; 
     308 
     309        $pairs[] = sprintf("%s%s", $is_assoc ? "$key:" : '', json_serialize($value)); 
     310      } 
     311 
     312      return $brackets{0} . implode(',', $pairs) . $brackets{1}; 
    1312313    } 
    1313     else if (is_numeric($var) && strval(intval($var)) === strval($var)) 
    1314       return $var; 
    1315     else if (is_bool($var)) 
    1316       return $var ? '1' : '0'; 
    1317     else 
    1318       return "'".JQ($var)."'"; 
    1319    
    1320   } 
    1321  
    1322 /** 
    1323  * function to convert an array to a javascript array 
     314  } 
     315  else if (is_numeric($var) && strval(intval($var)) === strval($var)) 
     316    return $var; 
     317  else if (is_bool($var)) 
     318    return $var ? '1' : '0'; 
     319  else 
     320    return "'".JQ($var)."'"; 
     321 
     322} 
     323 
     324/** 
     325 * Function to convert an array to a javascript array 
     326 * Actually an alias function for json_serialize() 
    1324327 * @deprecated 
    1325328 */ 
    1326329function array2js($arr, $type='') 
    1327   { 
     330{ 
    1328331  return json_serialize($arr); 
    1329   } 
     332} 
    1330333 
    1331334 
    1332335/** 
    1333336 * Similar function as in_array() but case-insensitive 
     337 * 
     338 * @param mixed Needle value 
     339 * @param array Array to search in 
     340 * @return boolean True if found, False if not 
    1334341 */ 
    1335342function in_array_nocase($needle, $haystack) 
    1336   { 
     343{ 
    1337344  foreach ($haystack as $value) 
    1338     { 
    1339345    if (strtolower($needle)===strtolower($value)) 
    1340       return TRUE; 
    1341     } 
    1342      
    1343   return FALSE; 
    1344   } 
     346      return true; 
     347   
     348  return false; 
     349} 
    1345350 
    1346351 
    1347352/** 
    1348353 * Find out if the string content means TRUE or FALSE 
     354 * 
     355 * @param string Input value 
     356 * @return boolean Imagine what! 
    1349357 */ 
    1350358function get_boolean($str) 
    1351   { 
     359{ 
    1352360  $str = strtolower($str); 
    1353361  if(in_array($str, array('false', '0', 'no', 'nein', ''), TRUE)) 
     
    1355363  else 
    1356364    return TRUE; 
    1357   } 
    1358  
    1359  
    1360 // parse a human readable string for a number of bytes 
     365} 
     366 
     367 
     368/** 
     369 * Parse a human readable string for a number of bytes 
     370 * 
     371 * @param string Input string 
     372 * @return int Number of bytes 
     373 */ 
    1361374function parse_bytes($str) 
    1362   { 
     375{ 
    1363376  if (is_numeric($str)) 
    1364377    return intval($str); 
    1365378     
    1366379  if (preg_match('/([0-9]+)([a-z])/i', $str, $regs)) 
     380  { 
     381    $bytes = floatval($regs[1]); 
     382    switch (strtolower($regs[2])) 
    1367383    { 
    1368       $bytes = floatval($regs[1]); 
    1369       switch (strtolower($regs[2])) 
    1370       { 
    1371         case 'g': 
    1372           $bytes *= 1073741824; 
    1373           break; 
    1374         case 'm': 
    1375           $bytes *= 1048576; 
    1376           break; 
    1377         case 'k': 
    1378           $bytes *= 1024; 
    1379           break; 
    1380       } 
     384      case 'g': 
     385        $bytes *= 1073741824; 
     386        break; 
     387      case 'm': 
     388        $bytes *= 1048576; 
     389        break; 
     390      case 'k': 
     391        $bytes *= 1024; 
     392        break; 
    1381393    } 
     394  } 
    1382395 
    1383396  return intval($bytes); 
    1384   } 
    1385      
    1386 // create a human readable string for a number of bytes 
     397} 
     398     
     399/** 
     400 * Create a human readable string for a number of bytes 
     401 * 
     402 * @param int Number of bytes 
     403 * @return string Byte string 
     404 */ 
    1387405function show_bytes($bytes) 
    1388   { 
     406{ 
    1389407  if ($bytes > 1073741824) 
    1390     { 
     408  { 
    1391409    $gb = $bytes/1073741824; 
    1392410    $str = sprintf($gb>=10 ? "%d GB" : "%.1f GB", $gb); 
    1393     } 
     411  } 
    1394412  else if ($bytes > 1048576) 
    1395     { 
     413  { 
    1396414    $mb = $bytes/1048576; 
    1397415    $str = sprintf($mb>=10 ? "%d MB" : "%.1f MB", $mb); 
    1398     } 
     416  } 
    1399417  else if ($bytes > 1024) 
    1400418    $str = sprintf("%d KB",  round($bytes/1024)); 
     
    1403421 
    1404422  return $str; 
    1405   } 
    1406  
    1407  
    1408 // convert paths like ../xxx to an absolute path using a base url 
     423} 
     424 
     425 
     426/** 
     427 * Convert paths like ../xxx to an absolute path using a base url 
     428 * 
     429 * @param string Relative path 
     430 * @param string Base URL 
     431 * @return string Absolute URL 
     432 */ 
    1409433function make_absolute_url($path, $base_url) 
    1410     { 
    1411     $host_url = $base_url; 
    1412     $abs_path = $path; 
    1413  
    1414     // cut base_url to the last directory 
    1415     if (strpos($base_url, '/')>7) 
     434{ 
     435  $host_url = $base_url; 
     436  $abs_path = $path; 
     437 
     438  // cut base_url to the last directory 
     439  if (strpos($base_url, '/')>7) 
     440  { 
     441    $host_url = substr($base_url, 0, strpos($base_url, '/')); 
     442    $base_url = substr($base_url, 0, strrpos($base_url, '/')); 
     443  } 
     444 
     445  // $path is absolute 
     446  if ($path{0}=='/') 
     447    $abs_path = $host_url.$path; 
     448  else 
     449  { 
     450    // strip './' because its the same as '' 
     451    $path = preg_replace('/^\.\//', '', $path); 
     452 
     453    if (preg_match_all('/\.\.\//', $path, $matches, PREG_SET_ORDER)) 
     454      foreach ($matches as $a_match) 
    1416455      { 
    1417       $host_url = substr($base_url, 0, strpos($base_url, '/')); 
    1418       $base_url = substr($base_url, 0, strrpos($base_url, '/')); 
     456        if (strrpos($base_url, '/')) 
     457          $base_url = substr($base_url, 0, strrpos($base_url, '/')); 
     458         
     459        $path = substr($path, 3); 
    1419460      } 
    1420461 
    1421     // $path is absolute 
    1422     if ($path{0}=='/') 
    1423       $abs_path = $host_url.$path; 
    1424     else 
    1425       { 
    1426       // strip './' because its the same as '' 
    1427       $path = preg_replace('/^\.\//', '', $path); 
    1428  
    1429       if(preg_match_all('/\.\.\//', $path, $matches, PREG_SET_ORDER)) 
    1430         foreach($matches as $a_match) 
    1431           { 
    1432           if (strrpos($base_url, '/')) 
    1433             $base_url = substr($base_url, 0, strrpos($base_url, '/')); 
    1434            
    1435           $path = substr($path, 3); 
    1436           } 
    1437  
    1438       $abs_path = $base_url.'/'.$path; 
    1439       } 
    1440        
    1441     return $abs_path; 
    1442     } 
    1443  
    1444  
    1445 // wrapper function for strlen 
     462    $abs_path = $base_url.'/'.$path; 
     463  } 
     464     
     465  return $abs_path; 
     466} 
     467 
     468 
     469/** 
     470 * Wrapper function for strlen 
     471 */ 
    1446472function rc_strlen($str) 
    1447   { 
    1448     if (function_exists('mb_strlen')) 
    1449       return mb_strlen($str); 
    1450     else 
    1451       return strlen($str); 
    1452   } 
    1453    
    1454 // wrapper function for strtolower 
     473{ 
     474  if (function_exists('mb_strlen')) 
     475    return mb_strlen($str); 
     476  else 
     477    return strlen($str); 
     478} 
     479   
     480/** 
     481 * Wrapper function for strtolower 
     482 */ 
    1455483function rc_strtolower($str) 
    1456   { 
    1457     if (function_exists('mb_strtolower')) 
    1458       return mb_strtolower($str); 
    1459     else 
    1460       return strtolower($str); 
    1461   } 
    1462  
    1463 // wrapper function for substr 
     484{ 
     485  if (function_exists('mb_strtolower')) 
     486    return mb_strtolower($str); 
     487  else 
     488    return strtolower($str); 
     489} 
     490 
     491/** 
     492 * Wrapper function for substr 
     493 */ 
    1464494function rc_substr($str, $start, $len=null) 
    1465   { 
     495{ 
    1466496  if (function_exists('mb_substr')) 
    1467497    return mb_substr($str, $start, $len); 
    1468498  else 
    1469499    return substr($str, $start, $len); 
    1470   } 
    1471  
    1472 // wrapper function for strpos 
     500} 
     501 
     502/** 
     503 * Wrapper function for strpos 
     504 */ 
    1473505function rc_strpos($haystack, $needle, $offset=0) 
    1474   { 
     506{ 
    1475507  if (function_exists('mb_strpos')) 
    1476508    return mb_strpos($haystack, $needle, $offset); 
    1477509  else 
    1478510    return strpos($haystack, $needle, $offset); 
    1479   } 
    1480  
    1481 // wrapper function for strrpos 
     511} 
     512 
     513/** 
     514 * Wrapper function for strrpos 
     515 */ 
    1482516function rc_strrpos($haystack, $needle, $offset=0) 
    1483   { 
     517{ 
    1484518  if (function_exists('mb_strrpos')) 
    1485519    return mb_strrpos($haystack, $needle, $offset); 
    1486520  else 
    1487521    return strrpos($haystack, $needle, $offset); 
    1488   } 
    1489  
    1490  
    1491 // replace the middle part of a string with ... 
    1492 // if it is longer than the allowed length 
     522} 
     523 
     524 
     525/** 
     526 * Replace the middle part of a string with ... 
     527 * if it is longer than the allowed length 
     528 * 
     529 * @param string Input string 
     530 * @param int    Max. length 
     531 * @param string Replace removed chars with this 
     532 * @return string Abbrevated string 
     533 */ 
    1493534function abbrevate_string($str, $maxlength, $place_holder='...') 
    1494   { 
     535{ 
    1495536  $length = rc_strlen($str); 
    1496537  $first_part_length = floor($maxlength/2) - rc_strlen($place_holder); 
    1497538   
    1498539  if ($length > $maxlength) 
    1499     { 
     540  { 
    1500541    $second_starting_location = $length - $maxlength + $first_part_length + 1; 
    1501542    $str = rc_substr($str, 0, $first_part_length) . $place_holder . rc_substr($str, $second_starting_location, $length); 
    1502     } 
     543  } 
    1503544 
    1504545  return $str; 
    1505   } 
    1506  
    1507  
    1508 // make sure the string ends with a slash 
     546} 
     547 
     548 
     549/** 
     550 * Make sure the string ends with a slash 
     551 */ 
    1509552function slashify($str) 
    1510   { 
     553{ 
    1511554  return unslashify($str).'/'; 
    1512   } 
    1513  
    1514  
    1515 // remove slash at the end of the string 
     555} 
     556 
     557 
     558/** 
     559 * Remove slash at the end of the string 
     560 */ 
    1516561function unslashify($str) 
    1517   { 
     562{ 
    1518563  return preg_replace('/\/$/', '', $str); 
    1519   } 
    1520    
    1521  
    1522 // delete all files within a folder 
     564} 
     565   
     566 
     567/** 
     568 * Delete all files within a folder 
     569 * 
     570 * @param string Path to directory 
     571 * @return boolean True on success, False if directory was not found 
     572 */ 
    1523573function clear_directory($dir_path) 
    1524   { 
     574{ 
    1525575  $dir = @opendir($dir_path); 
    1526576  if(!$dir) return FALSE; 
     
    1532582  closedir($dir); 
    1533583  return TRUE; 
    1534   } 
    1535  
    1536  
    1537 // create a unix timestamp with a specified offset from now 
     584} 
     585 
     586 
     587/** 
     588 * Create a unix timestamp with a specified offset from now 
     589 * 
     590 * @param string String representation of the offset (e.g. 20min, 5h, 2days) 
     591 * @param int Factor to multiply with the offset 
     592 * @return int Unix timestamp 
     593 */ 
    1538594function get_offset_time($offset_str, $factor=1) 
    1539595  { 
    1540596  if (preg_match('/^([0-9]+)\s*([smhdw])/i', $offset_str, $regs)) 
    1541     { 
     597  { 
    1542598    $amount = (int)$regs[1]; 
    1543599    $unit = strtolower($regs[2]); 
    1544     } 
    1545   else 
    1546     { 
     600  } 
     601  else 
     602  { 
    1547603    $amount = (int)$offset_str; 
    1548604    $unit = 's'; 
    1549     } 
     605  } 
    1550606     
    1551607  $ts = mktime(); 
    1552608  switch ($unit) 
    1553     { 
     609  { 
    1554610    case 'w': 
    1555611      $amount *= 7; 
     
    1562618    case 's': 
    1563619      $ts += $amount * $factor; 
    1564     } 
     620  } 
    1565621 
    1566622  return $ts; 
    1567   } 
    1568  
    1569  
    1570 /** 
    1571  * strrstr 
    1572  * 
    1573  * return the last occurence of a string in another string 
     623} 
     624 
     625 
     626/** 
     627 * Return the last occurence of a string in another string 
     628 * 
    1574629 * @param haystack string string in which to search 
    1575630 * @param needle string string for which to search 
     
    1577632 */ 
    1578633function strrstr($haystack, $needle) 
    1579   { 
    1580     $pver = phpversion(); 
    1581     if ($pver[0] >= 5) 
    1582       { 
    1583         return strrpos($haystack, $needle); 
    1584       } 
    1585     else 
    1586       { 
    1587         $index = strpos(strrev($haystack), strrev($needle)); 
    1588         if($index === false) { 
    1589             return false; 
    1590         } 
    1591         $index = strlen($haystack) - strlen($needle) - $index; 
    1592         return $index; 
    1593       } 
    1594   } 
     634{ 
     635  $pver = phpversion(); 
     636  if ($pver[0] >= 5) 
     637      return strrpos($haystack, $needle); 
     638  else 
     639  { 
     640    $index = strpos(strrev($haystack), strrev($needle)); 
     641    if($index === false) 
     642        return false; 
     643     
     644    $index = strlen($haystack) - strlen($needle) - $index; 
     645    return $index; 
     646  } 
     647} 
    1595648 
    1596649 
Note: See TracChangeset for help on using the changeset viewer.