]> git.donarmstrong.com Git - roundcube.git/blobdiff - program/include/rcube_shared.inc
Imported Upstream version 0.1~rc1~dfsg
[roundcube.git] / program / include / rcube_shared.inc
index ee95965e3ba6a209c05869b60f842e1cb950ea72..737ebaf98fdb3e3c08284c66a3bbd00f67b0e0ed 100644 (file)
@@ -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:                                                             |
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_shared.inc 288 2006-07-31 22:51:23Z thomasb $
+ $Id: rcube_shared.inc 543 2007-04-28 18:07:12Z thomasb $
 
 */
 
@@ -28,13 +28,15 @@ class rcube_html_page
   
   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<body></body>\n</html>";
-  
+  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 = '';
@@ -69,15 +71,33 @@ class rcube_html_page
     $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".rtrim($script);
+    else
+      $this->scripts[$position] .= "\n".rtrim($script);
+    }
 
-    $this->scripts[$position] .= "\n$script";
+  function add_header($str)
+    {
+    $this->header .= "\n".$str;
     }
 
+  function add_footer($str)
+    {
+    $this->footer .= "\n".$str;
+    }
 
   function set_title($t)
     {
@@ -110,19 +130,21 @@ class rcube_html_page
     $this->script_files = array();
     $this->scripts = array();
     $this->title = '';
+    $this->header = '';
+    $this->footer = '';
     }
 
 
   function write($templ='', $base_path='')
     {
     $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 = '';
     
     
@@ -139,19 +161,28 @@ class rcube_html_page
       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>'))
@@ -192,8 +223,10 @@ class rcube_html_page
   
   
     // 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";
   
@@ -202,7 +235,7 @@ class rcube_html_page
     $__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);
   
@@ -701,7 +734,7 @@ class base_form_element
 
       // 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')))
@@ -854,9 +887,9 @@ class textarea extends base_form_element
     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'),
@@ -985,20 +1018,22 @@ class select extends base_form_element
     
     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'),
@@ -1080,7 +1115,7 @@ function rcube_label($attrib)
   $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] : '');
 
 
@@ -1171,8 +1206,6 @@ EOF;
     return strtoupper($text);
   else if ($attrib['lowercase'])
     return strtolower($text);
-  else
-    return $text;
 
   return $text;
   }
@@ -1192,89 +1225,113 @@ function send_nocacheing_headers()
 
 
 // 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();
 
-      $previous_was_array = false;
-      while (list($key, $value) = each($arr))
+        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'";
-
-        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)."'";
+          // 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'";
 
-        $a_pairs[] = sprintf("%s%s",
-                             $is_assoc ? "$key:" : '',
-                             is_array($value) ? array2js($value, $type) : $value);
+          $pairs[] = sprintf("%s%s", $is_assoc ? "$key:" : '', json_serialize($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)
@@ -1287,8 +1344,9 @@ function in_array_nocase($needle, $haystack)
   }
 
 
-
-// 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);
@@ -1299,12 +1357,51 @@ function get_boolean($str)
   }
 
 
-function show_bytes($numbytes)
+// parse a human readable string for a number of bytes
+function parse_bytes($str)
+  {
+  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 ($numbytes > 1024)
-    return sprintf('%d KB', round($numbytes/1024));
+  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;
   }
 
 
@@ -1345,17 +1442,63 @@ function make_absolute_url($path, $base_url)
     }
 
 
+// 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;
@@ -1414,7 +1557,7 @@ function get_offset_time($offset_str, $factor=1)
       $amount *= 24;
     case 'h':
       $amount *= 60;
-    case 'h':
+    case 'm':
       $amount *= 60;
     case 's':
       $ts += $amount * $factor;
@@ -1424,4 +1567,31 @@ function get_offset_time($offset_str, $factor=1)
   }
 
 
+/**
+ * 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;
+      }
+  }
+
+
 ?>