source: subversion/branches/devel-vnext/program/include/rcube_shared.inc @ 722

Last change on this file since 722 was 722, checked in by till, 6 years ago

+ added some comments
+ cs fixes

  • Property svn:executable set to *
File size: 16.3 KB
Line 
1<?php
2
3/*
4 +-----------------------------------------------------------------------+
5 | rcube_shared.inc                                                      |
6 |                                                                       |
7 | This file is part of the RoundCube PHP suite                          |
8 | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
9 | Licensed under the GNU GPL                                            |
10 |                                                                       |
11 | CONTENTS:                                                             |
12 |   Shared functions and classes used in PHP projects                   |
13 |                                                                       |
14 +-----------------------------------------------------------------------+
15 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16 +-----------------------------------------------------------------------+
17
18 $Id: rcube_shared.inc 543 2007-04-28 18:07:12Z thomasb $
19
20*/
21
22
23// ********* round cube schared classes *********
24require_once dirname(__FILE__) . '/rcube/html_page.php';
25
26require_once dirname(__FILE__) . '/rcube/css.php';
27
28require_once dirname(__FILE__) . '/rcube/base_form_element.php';
29
30require_once dirname(__FILE__) . '/rcube/form_elements.php';
31
32
33/**
34 * @todo create class file
35 */
36
37
38// ********* rcube schared functions *********
39
40
41// provide details about the client's browser
42function rcube_browser()
43  {
44  $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT'];
45
46  $bw['ver'] = 0;
47  $bw['win'] = stristr($HTTP_USER_AGENT, 'win');
48  $bw['mac'] = stristr($HTTP_USER_AGENT, 'mac');
49  $bw['linux'] = stristr($HTTP_USER_AGENT, 'linux');
50  $bw['unix']  = stristr($HTTP_USER_AGENT, 'unix');
51
52  $bw['ns4'] = stristr($HTTP_USER_AGENT, 'mozilla/4') && !stristr($HTTP_USER_AGENT, 'msie');
53  $bw['ns']  = ($bw['ns4'] || stristr($HTTP_USER_AGENT, 'netscape'));
54  $bw['ie']  = stristr($HTTP_USER_AGENT, 'msie');
55  $bw['mz']  = stristr($HTTP_USER_AGENT, 'mozilla/5');
56  $bw['opera'] = stristr($HTTP_USER_AGENT, 'opera');
57  $bw['safari'] = stristr($HTTP_USER_AGENT, 'safari');
58
59  if($bw['ns'])
60    {
61    $test = eregi("mozilla\/([0-9\.]+)", $HTTP_USER_AGENT, $regs);
62    $bw['ver'] = $test ? (float)$regs[1] : 0;
63    }
64  if($bw['mz'])
65    {
66    $test = ereg("rv:([0-9\.]+)", $HTTP_USER_AGENT, $regs);
67    $bw['ver'] = $test ? (float)$regs[1] : 0;
68    }
69  if($bw['ie'])
70    {
71    $test = eregi("msie ([0-9\.]+)", $HTTP_USER_AGENT, $regs);
72    $bw['ver'] = $test ? (float)$regs[1] : 0;
73    }
74  if($bw['opera'])
75    {
76    $test = eregi("opera ([0-9\.]+)", $HTTP_USER_AGENT, $regs);
77    $bw['ver'] = $test ? (float)$regs[1] : 0;
78    }
79
80  if(eregi(" ([a-z]{2})-([a-z]{2})", $HTTP_USER_AGENT, $regs))
81    $bw['lang'] =  $regs[1];
82  else
83    $bw['lang'] =  'en';
84
85  $bw['dom'] = ($bw['mz'] || $bw['safari'] || ($bw['ie'] && $bw['ver']>=5) || ($bw['opera'] && $bw['ver']>=7));
86  $bw['pngalpha'] = $bw['mz'] || $bw['safari'] || ($bw['ie'] && $bw['ver']>=5.5) ||
87                    ($bw['ie'] && $bw['ver']>=5 && $bw['mac']) || ($bw['opera'] && $bw['ver']>=7) ? TRUE : FALSE;
88
89  return $bw;
90  }
91
92
93// get text in the desired language from the language file
94function rcube_label($attrib)
95{
96    $registry       = rc_registry::getInstance();
97    $sess_user_lang = $registry->get('sess_user_lang', 'core');
98    $INSTALL_PATH   = $registry->get('INSTALL_PATH', 'core');
99    $OUTPUT         = $registry->get('OUTPUT', 'core');
100
101    static $sa_text_data, $s_language, $utf8_decode;
102
103    // extract attributes
104    if (is_string($attrib)) {
105        $attrib = array('name' => $attrib);
106    }
107    $nr = is_numeric($attrib['nr']) ? $attrib['nr'] : 1;
108    $vars = isset($attrib['vars']) ? $attrib['vars'] : '';
109
110    $command_name = !empty($attrib['command']) ? $attrib['command'] : NULL;
111    $alias = $attrib['name'] ? $attrib['name'] : ($command_name && $command_label_map[$command_name] ? $command_label_map[$command_name] : '');
112
113
114    // load localized texts
115    if (!$sa_text_data || $s_language != $sess_user_lang) {
116        $sa_text_data = array();
117
118        // get english labels (these should be complete)
119        @include($INSTALL_PATH.'program/localization/en_US/labels.inc');
120        @include($INSTALL_PATH.'program/localization/en_US/messages.inc');
121
122        if (is_array($labels)) {
123            $sa_text_data = $labels;
124        }
125        if (is_array($messages)) {
126            $sa_text_data = array_merge($sa_text_data, $messages);
127        }
128        // include user language files
129        if (
130            !empty($sess_user_lang)
131            && $sess_user_lang != 'en'
132            && is_dir($INSTALL_PATH.'program/localization/'.$sess_user_lang)
133        ) {
134            include_once $INSTALL_PATH.'program/localization/' . $sess_user_lang . '/labels.inc';
135            include_once $INSTALL_PATH.'program/localization/' . $sess_user_lang . '/messages.inc';
136
137            //rc_main::tfk_debug($sess_user_lang);
138
139            if (is_array($labels)) {
140                $sa_text_data = array_merge($sa_text_data, $labels);
141            }
142            if (is_array($messages)) {
143                $sa_text_data = array_merge($sa_text_data, $messages);
144            }
145        }
146        $s_language = $sess_user_lang;
147    }
148
149    // text does not exist
150    if (!($text_item = $sa_text_data[$alias])) {
151        /*
152        rc_bugs::raise_error(
153            array(
154                'code' => 500,
155                'type' => 'php',
156                'line' => __LINE__,
157                'file' => __FILE__,
158                'message' => "Missing localized text for '$alias' in '$sess_user_lang'"
159            ),
160            TRUE,
161            FALSE
162        );
163        */
164        /**
165         * We got as far - so let's see if $_SESSION contains what we are
166         * looking for.
167         *
168         * @author Till Klampaeckel <till@php.net>
169         */
170        if (substr($alias, 0, 3) == 'RC_') {
171
172            $_sess_ident = substr($alias, 3);
173
174            if (isset($_SESSION[$_sess_ident]) === true) {
175                return $_SESSION[$_sess_ident];
176            }
177        }
178        return "[$alias]";
179    }
180
181    // make text item array
182    $a_text_item = is_array($text_item) ? $text_item : array('single' => $text_item);
183
184    // decide which text to use
185    if ($nr==1) {
186        $text = $a_text_item['single'];
187    }
188    elseif ($nr>0) {
189        $text = $a_text_item['multiple'];
190    }
191    elseif ($nr==0) {
192        if ($a_text_item['none']) {
193            $text = $a_text_item['none'];
194        }
195        elseif ($a_text_item['single']) {
196            $text = $a_text_item['single'];
197        }
198        elseif ($a_text_item['multiple']) {
199            $text = $a_text_item['multiple'];
200        }
201    }
202
203    // default text is single
204    if ($text=='')
205        $text = $a_text_item['single'];
206
207    // replace vars in text
208    if (is_array($attrib['vars'])) {
209        foreach ($attrib['vars'] as $var_key=>$var_value) {
210            $a_replace_vars[substr($var_key, 0, 1)=='$' ? substr($var_key, 1) : $var_key] = $var_value;
211        }
212    }
213
214    if ($a_replace_vars) {
215        $text = preg_replace('/\${?([_a-z]{1}[_a-z0-9]*)}?/ei', '$a_replace_vars["\1"]', $text);
216    }
217    // remove variables in text which were not available in arg $vars and $nr
218    eval("\$text = <<<EOF
219$text
220EOF;
221");
222
223    // format output
224    if (($attrib['uppercase'] && strtolower($attrib['uppercase']=='first')) || $attrib['ucfirst']) {
225        return ucfirst($text);
226    }
227    elseif ($attrib['uppercase']) {
228        return strtoupper($text);
229    }
230    elseif ($attrib['lowercase']) {
231        return strtolower($text);
232    }
233    return $text;
234}
235
236
237// send HTTP header for no-cacheing steps
238function send_nocacheing_headers()
239{
240    if (headers_sent()) {
241        return;
242    }
243    header("Expires: ".gmdate("D, d M Y H:i:s")." GMT");
244    header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
245    header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
246    header("Pragma: no-cache");
247}
248
249
250// send header with expire date 30 days in future
251function send_future_expire_header($offset=2600000)
252  {
253  if (headers_sent())
254    return;
255
256  header("Expires: ".gmdate("D, d M Y H:i:s", mktime()+$offset)." GMT");
257  header("Cache-Control: max-age=$offset");
258  header("Pragma: ");
259  }
260
261
262// check request for If-Modified-Since and send an according response
263function send_modified_header($mdate, $etag=null)
264{
265    if (headers_sent()) {
266        //rc_main::tfk_debug("/ Headerz sent?!");
267        return;
268    }
269    $iscached = false;
270    if (
271        $_SERVER['HTTP_IF_MODIFIED_SINCE']
272        && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $mdate
273    ) {
274        $iscached = true;
275    }
276
277    $etag = $etag ? "\"$etag\"" : null;
278    if ($etag && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) {
279        $iscached = true;
280    }
281    if ($iscached) {
282        header("HTTP/1.x 304 Not Modified");
283    }
284    else {
285        header("Last-Modified: ".gmdate("D, d M Y H:i:s", $mdate)." GMT");
286    }
287    header("Cache-Control: max-age=0");
288    header("Expires: ");
289    header("Pragma: ");
290
291    if ($etag) {
292        header("Etag: $etag");
293    }
294    $iscached = FALSE;
295    if ($iscached) {
296        //rc_main::tfk_debug("/ serving from cache");
297        exit;
298    }
299}
300
301
302/**
303 * Convert a variable into a javascript notation string
304 */
305function json_serialize($var)
306{
307    if (is_object($var)) {
308        $var = get_object_vars($var);
309    }
310    if (is_array($var)) {
311        // empty array
312        if (!sizeof($var)) {
313            return '[]';
314        }
315        else {
316            $keys_arr = array_keys($var);
317            $is_assoc = $have_numeric = 0;
318
319            for ($i=0; $i<sizeof($keys_arr); ++$i) {
320                if (is_numeric($keys_arr[$i])) {
321                    $have_numeric = 1;
322                }
323                if (!is_numeric($keys_arr[$i]) || $keys_arr[$i] != $i) {
324                    $is_assoc = 1;
325                }
326                if ($is_assoc && $have_numeric) {
327                    break;
328                }
329            }
330
331            $brackets = $is_assoc ? '{}' : '[]';
332            $pairs = array();
333
334            foreach ($var as $key => $value) {
335                // enclose key with quotes if it is not variable-name conform
336                if (!ereg("^[_a-zA-Z]{1}[_a-zA-Z0-9]*$", $key) /* || is_js_reserved_word($key) */)
337                    $key = "'$key'";
338
339                $pairs[] = sprintf("%s%s", $is_assoc ? "$key:" : '', json_serialize($value));
340            }
341            return $brackets{0} . implode(',', $pairs) . $brackets{1};
342        }
343    }
344    else if (is_numeric($var) && strval(intval($var)) === strval($var)) {
345        return $var;
346    }
347    else if (is_bool($var)) {
348        return $var ? '1' : '0';
349    }
350    else {
351        return "'" . rc_main::JQ($var) . "'";
352    }
353}
354
355/**
356 * function to convert an array to a javascript array
357 * @deprecated
358 */
359function array2js($arr, $type='')
360{
361    return json_serialize($arr);
362}
363
364
365/**
366 * Similar function as in_array() but case-insensitive
367 */
368function in_array_nocase($needle, $haystack)
369{
370    foreach ($haystack as $value) {
371        if (strtolower($needle)===strtolower($value)) {
372            return TRUE;
373        }
374    }
375    return FALSE;
376}
377
378
379/**
380 * Find out if the string content means TRUE or FALSE
381 */
382function get_boolean($str)
383{
384    $str = strtolower($str);
385    if(in_array($str, array('false', '0', 'no', 'nein', ''), TRUE)) {
386        return FALSE;
387    }
388    else {
389        return TRUE;
390    }
391}
392
393
394// parse a human readable string for a number of bytes
395function parse_bytes($str)
396  {
397  if (is_numeric($str))
398    return intval($str);
399
400  if (preg_match('/([0-9]+)([a-z])/i', $str, $regs))
401    {
402      $bytes = floatval($regs[1]);
403      switch (strtolower($regs[2]))
404      {
405        case 'g':
406          $bytes *= 1073741824;
407          break;
408        case 'm':
409          $bytes *= 1048576;
410          break;
411        case 'k':
412          $bytes *= 1024;
413          break;
414      }
415    }
416
417  return intval($bytes);
418  }
419
420// create a human readable string for a number of bytes
421function show_bytes($bytes)
422  {
423  if ($bytes > 1073741824)
424    {
425    $gb = $bytes/1073741824;
426    $str = sprintf($gb>=10 ? "%d GB" : "%.1f GB", $gb);
427    }
428  else if ($bytes > 1048576)
429    {
430    $mb = $bytes/1048576;
431    $str = sprintf($mb>=10 ? "%d MB" : "%.1f MB", $mb);
432    }
433  else if ($bytes > 1024)
434    $str = sprintf("%d KB",  round($bytes/1024));
435  else
436    $str = sprintf('%d B', $bytes);
437
438  return $str;
439  }
440
441
442// convert paths like ../xxx to an absolute path using a base url
443function make_absolute_url($path, $base_url)
444    {
445    $host_url = $base_url;
446    $abs_path = $path;
447
448    // cut base_url to the last directory
449    if (strpos($base_url, '/')>7)
450      {
451      $host_url = substr($base_url, 0, strpos($base_url, '/'));
452      $base_url = substr($base_url, 0, strrpos($base_url, '/'));
453      }
454
455    // $path is absolute
456    if ($path{0}=='/')
457      $abs_path = $host_url.$path;
458    else
459      {
460      // strip './' because its the same as ''
461      $path = preg_replace('/^\.\//', '', $path);
462
463      if(preg_match_all('/\.\.\//', $path, $matches, PREG_SET_ORDER))
464        foreach($matches as $a_match)
465          {
466          if (strrpos($base_url, '/'))
467            $base_url = substr($base_url, 0, strrpos($base_url, '/'));
468
469          $path = substr($path, 3);
470          }
471
472      $abs_path = $base_url.'/'.$path;
473      }
474
475    return $abs_path;
476    }
477
478
479// wrapper function for strlen
480function rc_strlen($str)
481  {
482    if (function_exists('mb_strlen'))
483      return mb_strlen($str);
484    else
485      return strlen($str);
486  }
487
488// wrapper function for strtolower
489function rc_strtolower($str)
490  {
491    if (function_exists('mb_strtolower'))
492      return mb_strtolower($str);
493    else
494      return strtolower($str);
495  }
496
497// wrapper function for substr
498function rc_substr($str, $start, $len=null)
499  {
500  if (function_exists('mb_substr'))
501    return mb_substr($str, $start, $len);
502  else
503    return substr($str, $start, $len);
504  }
505
506// wrapper function for strpos
507function rc_strpos($haystack, $needle, $offset=0)
508  {
509  if (function_exists('mb_strpos'))
510    return mb_strpos($haystack, $needle, $offset);
511  else
512    return strpos($haystack, $needle, $offset);
513  }
514
515// wrapper function for strrpos
516function rc_strrpos($haystack, $needle, $offset=0)
517  {
518  if (function_exists('mb_strrpos'))
519    return mb_strrpos($haystack, $needle, $offset);
520  else
521    return strrpos($haystack, $needle, $offset);
522  }
523
524
525// replace the middle part of a string with ...
526// if it is longer than the allowed length
527function abbrevate_string($str, $maxlength, $place_holder='...')
528  {
529  $length = rc_strlen($str);
530  $first_part_length = floor($maxlength/2) - rc_strlen($place_holder);
531
532  if ($length > $maxlength)
533    {
534    $second_starting_location = $length - $maxlength + $first_part_length + 1;
535    $str = rc_substr($str, 0, $first_part_length) . $place_holder . rc_substr($str, $second_starting_location, $length);
536    }
537
538  return $str;
539  }
540
541
542// make sure the string ends with a slash
543function slashify($str)
544  {
545  return unslashify($str).'/';
546  }
547
548
549// remove slash at the end of the string
550function unslashify($str)
551  {
552  return preg_replace('/\/$/', '', $str);
553  }
554
555
556// delete all files within a folder
557function clear_directory($dir_path)
558  {
559  $dir = @opendir($dir_path);
560  if(!$dir) return FALSE;
561
562  while ($file = readdir($dir))
563    if (strlen($file)>2)
564      unlink("$dir_path/$file");
565
566  closedir($dir);
567  return TRUE;
568  }
569
570
571// create a unix timestamp with a specified offset from now
572function get_offset_time($offset_str, $factor=1)
573  {
574  if (preg_match('/^([0-9]+)\s*([smhdw])/i', $offset_str, $regs))
575    {
576    $amount = (int)$regs[1];
577    $unit = strtolower($regs[2]);
578    }
579  else
580    {
581    $amount = (int)$offset_str;
582    $unit = 's';
583    }
584
585  $ts = mktime();
586  switch ($unit)
587    {
588    case 'w':
589      $amount *= 7;
590    case 'd':
591      $amount *= 24;
592    case 'h':
593      $amount *= 60;
594    case 'm':
595      $amount *= 60;
596    case 's':
597      $ts += $amount * $factor;
598    }
599
600  return $ts;
601  }
602
603
604/**
605 * strrstr
606 *
607 * return the last occurence of a string in another string
608 * @param haystack string string in which to search
609 * @param needle string string for which to search
610 * @return index of needle within haystack, or false if not found
611 */
612function strrstr($haystack, $needle)
613  {
614    $pver = phpversion();
615    if ($pver[0] >= 5)
616      {
617        return strrpos($haystack, $needle);
618      }
619    else
620      {
621        $index = strpos(strrev($haystack), strrev($needle));
622        if($index === false) {
623            return false;
624        }
625        $index = strlen($haystack) - strlen($needle) - $index;
626        return $index;
627      }
628  }
629
630
631?>
Note: See TracBrowser for help on using the repository browser.