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

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