thomascube
2007-04-28 f1154163b0a9efb21d722bc658352739040ffd61
program/include/rcube_shared.inc
@@ -5,7 +5,7 @@
 | rcube_shared.inc                                                      |
 |                                                                       |
 | This file is part of the RoundCube PHP suite                          |
 | Copyright (C) 2005, RoundCube Dev. - Switzerland                      |
 | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 | CONTENTS:                                                             |
@@ -28,12 +28,15 @@
  
  var $scripts_path = '';
  var $script_files = array();
  var $external_scripts = array();
  var $scripts = array();
  var $charset = 'ISO-8859-1';
  
  var $script_tag_file = "<script type=\"text/javascript\" src=\"%s%s\"></script>\n";
  var $script_tag      = "<script type=\"text/javascript\">\n<!--\n%s\n\n//-->\n</script>\n";
  var $default_template = "<html>\n<head><title></title></head>\n<body></body>\n</html>";
  var $tag_format_external_script = "<script type=\"text/javascript\" src=\"%s\"></script>\n";
  var $title = '';
  var $header = '';
  var $footer = '';
@@ -68,20 +71,39 @@
    $this->script_files[$position][] = $file;
    }
    
  function include_external_script($script_location, $position='head')
  {
     if (!is_array($this->external_scripts[$position]))
     {
        $this->external_scripts[$position] = array();
     }
     $this->external_scripts[$position][] = $script_location;
  }
  function add_script($script, $position='head')
    {
    if (!isset($this->scripts[$position]))
      $this->scripts[$position] = '';
    $this->scripts[$position] .= "\n$script";
      $this->scripts[$position] = "\n".rtrim($script);
    else
      $this->scripts[$position] .= "\n".rtrim($script);
    }
  function set_title()
  function add_header($str)
    {
    $this->header .= "\n".$str;
    }
  function add_footer($str)
    {
    $this->footer .= "\n".$str;
    }
  function set_title($t)
    {
    $this->title = $t;
    }
  function set_charset($charset)
    {
@@ -95,23 +117,34 @@
        $MBSTRING = FALSE;
      }
    }
  function get_charset()
    {
    return $this->charset;
    }
  function reset()
    {
    $this->css = new rcube_css();
    $this->script_files = array();
    $this->scripts = array();
    $this->title = '';
    $this->header = '';
    $this->footer = '';
    }
  function write($templ='', $base_path='')
    {
    $output = trim($templ);
    $output = empty($templ) ? $this->default_template : trim($templ);
    // set default page title
    if (!strlen($this->title))
    if (empty($this->title))
      $this->title = 'RoundCube Mail';
  
    // replace specialchars in content
    $__page_title = rep_specialchars_output($this->title, 'html', 'show', FALSE);
    $__page_title = Q($this->title, 'show', FALSE);
    $__page_header = $__page_body = $__page_footer = '';
    
    
@@ -128,19 +161,28 @@
      foreach ($this->script_files['head'] as $file)
        $__page_header .= sprintf($this->script_tag_file, $this->scripts_path, $file);
    if (strlen($this->scripts['head']))
      $__page_header .= sprintf($this->script_tag, $this->scripts['head']);
    if (is_array($this->external_scripts['head']))
      foreach ($this->external_scripts['head'] as $xscript)
        $__page_header .= sprintf($this->tag_format_external_script, $xscript);
    $head_script = $this->scripts['head_top'] . $this->scripts['head'];
    if (!empty($head_script))
      $__page_header .= sprintf($this->script_tag, $head_script);
    if (!empty($this->header))
      $__page_header .= $this->header;
    if (is_array($this->script_files['foot']))
      foreach ($this->script_files['foot'] as $file)
        $__page_footer .= sprintf($this->script_tag_file, $this->scripts_path, $file);
    if (strlen($this->scripts['foot']))
    if (!empty($this->scripts['foot']))
      $__page_footer .= sprintf($this->script_tag, $this->scripts['foot']);
    if (!empty($this->footer))
      $__page_footer .= $this->footer;
    $__page_header .= $this->css->show();
  
    // find page header
    if($hpos = strpos(strtolower($output), '</head>'))
@@ -181,8 +223,10 @@
  
  
    // find and add page footer
    if(($fpos = strpos(strtolower($output), '</body>')) || ($fpos = strpos(strtolower($output), '</html>')))
      $output = substr($output,0,$fpos) . "$__page_footer\n" . substr($output,$fpos,strlen($output));
    $output_lc = strtolower($output);
    if(($fpos = strrstr($output_lc, '</body>')) ||
       ($fpos = strrstr($output_lc, '</html>')))
      $output = substr($output, 0, $fpos) . "$__page_footer\n" . substr($output, $fpos);
    else
      $output .= "\n$__page_footer";
  
@@ -191,8 +235,9 @@
    $__page_header = $__page_footer = '';
  
  
    // correct absolute pathes in images and other tags
    // correct absolute paths in images and other tags
    $output = preg_replace('/(src|href|background)=(["\']?)(\/[a-z0-9_\-]+)/Ui', "\\1=\\2$base_path\\3", $output);
    $output = str_replace('$__skin_path', $base_path, $output);
  
    print rcube_charset_convert($output, 'UTF-8', $this->charset);
    }
@@ -689,7 +734,7 @@
      // encode textarea content
      if ($key=='value')
        $value = rep_specialchars_output($value, 'html', 'replace', FALSE);
        $value = Q($value, 'strict', FALSE);
      // attributes with no value
      if (in_array($key, array('checked', 'multiple', 'disabled', 'selected')))
@@ -842,9 +887,9 @@
    if (isset($this->attrib['value']))
      unset($this->attrib['value']);
    if (strlen($value))
      $value = rep_specialchars_output($value, 'html', 'replace', FALSE);
    if (!empty($value) && !isset($this->attrib['mce_editable']))
      $value = Q($value, 'strict', FALSE);
    // return final tag
    return sprintf('<%s%s>%s</%s>%s',
                   $this->_conv_case('textarea', 'tag'),
@@ -973,20 +1018,22 @@
    
    if (!is_array($select))
      $select = array((string)$select);
    foreach ($this->options as $option)
      {
      $selected = ((strlen($option['value']) && in_array($option['value'], $select, TRUE)) ||
                   (in_array($option['text'], $select, TRUE))) ? $this->_conv_case(' selected', 'attrib') : '';
      $selected = ((isset($option['value']) &&
                    in_array($option['value'], $select, TRUE)) ||
                   (in_array($option['text'], $select, TRUE))) ?
        $this->_conv_case(' selected', 'attrib') : '';
      $options_str .= sprintf("<%s%s%s>%s</%s>\n",
                             $this->_conv_case('option', 'tag'),
                             strlen($option['value']) ? sprintf($value_str, $option['value']) : '',
                             !empty($option['value']) ? sprintf($value_str, Q($option['value'])) : '',
                             $selected, 
                             rep_specialchars_output($option['text'], 'html', 'replace', FALSE),
                             Q($option['text'], 'strict', FALSE),
                             $this->_conv_case('option', 'tag'));
      }
    // return final tag
    return sprintf('<%s%s>%s</%s>%s',
                   $this->_conv_case('select', 'tag'),
@@ -1068,7 +1115,7 @@
  $nr = is_numeric($attrib['nr']) ? $attrib['nr'] : 1;
  $vars = isset($attrib['vars']) ? $attrib['vars'] : '';
  $command_name = strlen($attrib['command']) ? $attrib['command'] : NULL;
  $command_name = !empty($attrib['command']) ? $attrib['command'] : NULL;
  $alias = $attrib['name'] ? $attrib['name'] : ($command_name && $command_label_map[$command_name] ? $command_label_map[$command_name] : '');
@@ -1159,8 +1206,6 @@
    return strtoupper($text);
  else if ($attrib['lowercase'])
    return strtolower($text);
  else
    return $text;
  return $text;
  }
@@ -1180,89 +1225,113 @@
// send header with expire date 30 days in future
function send_future_expire_header()
function send_future_expire_header($offset=2600000)
  {
  if (!headers_sent())
    header("Expires: ".gmdate("D, d M Y H:i:s", mktime()+2600000)." GMT");
  if (headers_sent())
    return;
  header("Expires: ".gmdate("D, d M Y H:i:s", mktime()+$offset)." GMT");
  header("Cache-Control: max-age=$offset");
  header("Pragma: ");
  }
// function to convert an array to a javascript array
function array2js($arr, $type='')
// check request for If-Modified-Since and send an according response
function send_modified_header($mdate, $etag=null)
{
  if (headers_sent())
    return;
  $iscached = false;
  if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $mdate)
    $iscached = true;
  $etag = $etag ? "\"$etag\"" : null;
  if ($etag && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag)
    $iscached = true;
  if ($iscached)
    header("HTTP/1.x 304 Not Modified");
  else
    header("Last-Modified: ".gmdate("D, d M Y H:i:s", $mdate)." GMT");
  header("Cache-Control: max-age=0");
  header("Expires: ");
  header("Pragma: ");
  if ($etag)
    header("Etag: $etag");
  if ($iscached)
    exit;
}
/**
 * Convert a variable into a javascript notation string
 */
function json_serialize($var)
  {
  if (!$type)
    $type = 'mixed';
    if (is_object($var))
      $var = get_object_vars($var);
  if (is_array($arr))
    if (is_array($var))
    {
    // no items in array
    if (!sizeof($arr))
      return 'new Array()';
    else
      // empty array
      if (!sizeof($var))
        return '[]';
      else
      {
      $a_pairs = array();
      $keys_arr = array_keys($arr);
      $is_assoc = $have_numeric = 0;
        $keys_arr = array_keys($var);
        $is_assoc = $have_numeric = 0;
      for ($i=0; $i<sizeof($keys_arr); ++$i)
        for ($i=0; $i<sizeof($keys_arr); ++$i)
        {
        if(is_numeric($keys_arr[$i]))
          $have_numeric = 1;
        if (!is_numeric($keys_arr[$i]) || $keys_arr[$i]!=$i)
          $is_assoc = 1;
        if($is_assoc && $have_numeric)
          break;
          if (is_numeric($keys_arr[$i]))
            $have_numeric = 1;
          if (!is_numeric($keys_arr[$i]) || $keys_arr[$i] != $i)
            $is_assoc = 1;
          if ($is_assoc && $have_numeric)
            break;
        }
        $brackets = $is_assoc ? '{}' : '[]';
        $pairs = array();
        foreach ($var as $key => $value)
        {
          // enclose key with quotes if it is not variable-name conform
          if (!ereg("^[_a-zA-Z]{1}[_a-zA-Z0-9]*$", $key) /* || is_js_reserved_word($key) */)
            $key = "'$key'";
          $pairs[] = sprintf("%s%s", $is_assoc ? "$key:" : '', json_serialize($value));
        }
      $previous_was_array = false;
      while (list($key, $value) = each($arr))
        {
        // enclose key with quotes if it is not variable-name conform
        if (!ereg("^[_a-zA-Z]{1}[_a-zA-Z0-9]*$", $key) /* || is_js_reserved_word($key) */)
          $key = "'$key'";
        if (!is_array($value))
          {
          $value = str_replace("\r\n", '\n', $value);
          $value = str_replace("\n", '\n', $value);
          }
        $is_string = false;
        if (!is_array($value))
          {
          if ($type=='string')
            $is_string = true;
          else if ((($type=='mixed' && is_numeric($value)) || $type=='int') && strlen($value)<16)   // js interprets numbers with digits >15 as ...e+...
            $is_string = FALSE;
          else
            $is_string = TRUE;
          }
        if ($is_string)
          $value = "'".preg_replace("/(?<!\\\)'/", "\'", $value)."'";
        $a_pairs[] = sprintf("%s%s",
                             $is_assoc ? "$key:" : '',
                             is_array($value) ? array2js($value, $type) : $value);
        }
      if ($a_pairs)
        {
        if ($is_assoc)
          $return = '{'.implode(',', $a_pairs).'}';
        else
          $return = '['.implode(',', $a_pairs).']';
        }
      return $return;
        return $brackets{0} . implode(',', $pairs) . $brackets{1};
      }
    }
  else
    return $arr;
    else if (is_numeric($var) && strval(intval($var)) === strval($var))
      return $var;
    else if (is_bool($var))
      return $var ? '1' : '0';
    else
      return "'".JQ($var)."'";
  }
/**
 * function to convert an array to a javascript array
 * @deprecated
 */
function array2js($arr, $type='')
  {
  return json_serialize($arr);
  }
// similar function as in_array() ut case-insensitive
/**
 * Similar function as in_array() but case-insensitive
 */
function in_array_nocase($needle, $haystack)
  {
  foreach ($haystack as $value)
@@ -1275,8 +1344,9 @@
  }
// find out if the string content means TRUE or FALSE
/**
 * Find out if the string content means TRUE or FALSE
 */
function get_boolean($str)
  {
  $str = strtolower($str);
@@ -1287,12 +1357,51 @@
  }
function show_bytes($numbytes)
// parse a human readable string for a number of bytes
function parse_bytes($str)
  {
  if ($numbytes > 1024)
    return sprintf('%d KB', round($numbytes/1024));
  if (is_numeric($str))
    return intval($str);
  if (preg_match('/([0-9]+)([a-z])/i', $str, $regs))
    {
      $bytes = floatval($regs[1]);
      switch (strtolower($regs[2]))
      {
        case 'g':
          $bytes *= 1073741824;
          break;
        case 'm':
          $bytes *= 1048576;
          break;
        case 'k':
          $bytes *= 1024;
          break;
      }
    }
  return intval($bytes);
  }
// create a human readable string for a number of bytes
function show_bytes($bytes)
  {
  if ($bytes > 1073741824)
    {
    $gb = $bytes/1073741824;
    $str = sprintf($gb>=10 ? "%d GB" : "%.1f GB", $gb);
    }
  else if ($bytes > 1048576)
    {
    $mb = $bytes/1048576;
    $str = sprintf($mb>=10 ? "%d MB" : "%.1f MB", $mb);
    }
  else if ($bytes > 1024)
    $str = sprintf("%d KB",  round($bytes/1024));
  else
    return sprintf('%d B', $numbytes);
    $str = sprintf('%d B', $bytes);
  return $str;
  }
@@ -1333,21 +1442,82 @@
    }
// wrapper function for strlen
function rc_strlen($str)
  {
    if (function_exists('mb_strlen'))
      return mb_strlen($str);
    else
      return strlen($str);
  }
// wrapper function for strtolower
function rc_strtolower($str)
  {
    if (function_exists('mb_strtolower'))
      return mb_strtolower($str);
    else
      return strtolower($str);
  }
// wrapper function for substr
function rc_substr($str, $start, $len=null)
  {
  if (function_exists('mb_substr'))
    return mb_substr($str, $start, $len);
  else
    return substr($str, $start, $len);
  }
// wrapper function for strpos
function rc_strpos($haystack, $needle, $offset=0)
  {
  if (function_exists('mb_strpos'))
    return mb_strpos($haystack, $needle, $offset);
  else
    return strpos($haystack, $needle, $offset);
  }
// wrapper function for strrpos
function rc_strrpos($haystack, $needle, $offset=0)
  {
  if (function_exists('mb_strrpos'))
    return mb_strrpos($haystack, $needle, $offset);
  else
    return strrpos($haystack, $needle, $offset);
  }
// replace the middle part of a string with ...
// if it is longer than the allowed length
function abbrevate_string($str, $maxlength, $place_holder='...')
  {
  $length = strlen($str);
  $first_part_length = floor($maxlength/2) - strlen($place_holder);
  $length = rc_strlen($str);
  $first_part_length = floor($maxlength/2) - rc_strlen($place_holder);
  
  if ($length > $maxlength)
    {
    $second_starting_location = $length - $maxlength + $first_part_length + 1;
    $str = substr($str, 0, $first_part_length) . $place_holder . substr($str, $second_starting_location, $length);
    $str = rc_substr($str, 0, $first_part_length) . $place_holder . rc_substr($str, $second_starting_location, $length);
    }
  return $str;
  }
// make sure the string ends with a slash
function slashify($str)
  {
  return unslashify($str).'/';
  }
// remove slash at the end of the string
function unslashify($str)
  {
  return preg_replace('/\/$/', '', $str);
  }
// delete all files within a folder
function clear_directory($dir_path)
@@ -1387,7 +1557,7 @@
      $amount *= 24;
    case 'h':
      $amount *= 60;
    case 'h':
    case 'm':
      $amount *= 60;
    case 's':
      $ts += $amount * $factor;
@@ -1397,4 +1567,31 @@
  }
/**
 * strrstr
 *
 * return the last occurence of a string in another string
 * @param haystack string string in which to search
 * @param needle string string for which to search
 * @return index of needle within haystack, or false if not found
 */
function strrstr($haystack, $needle)
  {
    $pver = phpversion();
    if ($pver[0] >= 5)
      {
        return strrpos($haystack, $needle);
      }
    else
      {
        $index = strpos(strrev($haystack), strrev($needle));
        if($index === false) {
            return false;
        }
        $index = strlen($haystack) - strlen($needle) - $index;
        return $index;
      }
  }
?>