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

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