From 00de8ddf8d899a8c9a9ca89009f845f88eb7a6cc Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Wed, 06 Nov 2013 07:11:31 -0500
Subject: [PATCH] Small performance improvements, use str_replace() instead of strtr(), do not parse query if there are no params to replace, keep one instance of (potentially long) query less in memory

---
 program/include/rcmail.php |  163 +++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 118 insertions(+), 45 deletions(-)

diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index a0bc036..4b3f137 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -51,6 +51,7 @@
    */
   public $action = '';
   public $comm_path = './';
+  public $filename = '';
 
   private $address_books = array();
   private $action_map = array();
@@ -65,12 +66,13 @@
   /**
    * This implements the 'singleton' design pattern
    *
+   * @param string Environment name to run (e.g. live, dev, test)
    * @return rcmail The one and only instance
    */
-  static function get_instance()
+  static function get_instance($env = '')
   {
     if (!self::$instance || !is_a(self::$instance, 'rcmail')) {
-      self::$instance = new rcmail();
+      self::$instance = new rcmail($env);
       self::$instance->startup();  // init AFTER object was linked with self::$instance
     }
 
@@ -85,6 +87,10 @@
   protected function startup()
   {
     $this->init(self::INIT_WITH_DB | self::INIT_WITH_PLUGINS);
+
+    // set filename if not index.php
+    if (($basename = basename($_SERVER['SCRIPT_FILENAME'])) && $basename != 'index.php')
+      $this->filename = $basename;
 
     // start session
     $this->session_init();
@@ -162,7 +168,7 @@
     setlocale(LC_ALL, $lang . '.utf8', $lang . '.UTF-8', 'en_US.utf8', 'en_US.UTF-8');
 
     // workaround for http://bugs.php.net/bug.php?id=18556
-    if (in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) {
+    if (version_compare(PHP_VERSION, '5.5.0', '<') && in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) {
       setlocale(LC_CTYPE, 'en_US.utf8', 'en_US.UTF-8');
     }
   }
@@ -228,6 +234,11 @@
     }
 
     if (!$contacts) {
+      // there's no default, just return
+      if ($default) {
+        return null;
+      }
+
       self::raise_error(array(
         'code' => 700, 'type' => 'php',
         'file' => __FILE__, 'line' => __LINE__,
@@ -248,6 +259,23 @@
     }
 
     return $contacts;
+  }
+
+
+  /**
+   * Return identifier of the address book object
+   *
+   * @param rcube_addressbook Addressbook source object
+   *
+   * @return string Source identifier
+   */
+  public function get_address_book_id($object)
+  {
+    foreach ($this->address_books as $index => $book) {
+      if ($book === $object) {
+        return $index;
+      }
+    }
   }
 
 
@@ -289,7 +317,7 @@
         $list[$id] = array(
           'id'       => $id,
           'name'     => html::quote($prop['name']),
-          'groups'   => is_array($prop['groups']),
+          'groups'   => !empty($prop['groups']) || !empty($prop['group_filters']),
           'readonly' => !$prop['writable'],
           'hidden'   => $prop['hidden'],
           'autocomplete' => in_array($id, $autocomplete)
@@ -316,6 +344,44 @@
     }
 
     return $list;
+  }
+
+  /**
+   * Getter for compose responses.
+   * These are stored in local config and user preferences.
+   *
+   * @param boolean True to sort the list alphabetically
+   * @param boolean True if only this user's responses shall be listed
+   * @return array List of the current user's stored responses
+   */
+  public function get_compose_responses($sorted = false, $user_only = false)
+  {
+    $responses = array();
+
+    if (!$user_only) {
+      foreach ($this->config->get('compose_responses_static', array()) as $response) {
+        if (empty($response['key']))
+          $response['key'] = substr(md5($response['name']), 0, 16);
+        $response['static'] = true;
+        $response['class'] = 'readonly';
+        $k = $sorted ? '0000-' . strtolower($response['name']) : $response['key'];
+        $responses[$k] = $response;
+      }
+    }
+
+    foreach ($this->config->get('compose_responses', array()) as $response) {
+      if (empty($response['key']))
+        $response['key'] = substr(md5($response['name']), 0, 16);
+      $k = $sorted ? strtolower($response['name']) : $response['key'];
+      $responses[$k] = $response;
+    }
+
+    // sort list by name
+    if ($sorted) {
+      ksort($responses, SORT_LOCALE_STRING);
+    }
+
+    return array_values($responses);
   }
 
 
@@ -453,15 +519,22 @@
         $port = $config['default_port'];
     }
 
-    /* Modify username with domain if required
-       Inspired by Marco <P0L0_notspam_binware.org>
-    */
-    // Check if we need to add domain
-    if (!empty($config['username_domain']) && strpos($username, '@') === false) {
-      if (is_array($config['username_domain']) && isset($config['username_domain'][$host]))
-        $username .= '@'.rcube_utils::parse_host($config['username_domain'][$host], $host);
-      else if (is_string($config['username_domain']))
-        $username .= '@'.rcube_utils::parse_host($config['username_domain'], $host);
+    // Check if we need to add/force domain to username
+    if (!empty($config['username_domain'])) {
+      $domain = is_array($config['username_domain']) ? $config['username_domain'][$host] : $config['username_domain'];
+
+      if ($domain = rcube_utils::parse_host((string)$domain, $host)) {
+        $pos = strpos($username, '@');
+
+        // force configured domains
+        if (!empty($config['username_domain_forced']) && $pos !== false) {
+          $username = substr($username, 0, $pos) . '@' . $domain;
+        }
+        // just add domain if not specified
+        else if ($pos === false) {
+          $username .= '@' . $domain;
+        }
+      }
     }
 
     if (!isset($config['login_lc'])) {
@@ -719,7 +792,7 @@
     $p['_task'] = $task;
     unset($p['task']);
 
-    $url = './';
+    $url = './' . $this->filename;
     $delm = '?';
     foreach (array_reverse($p) as $key => $val) {
       if ($val !== '' && $val !== null) {
@@ -742,11 +815,6 @@
     foreach ($this->address_books as $book) {
       if (is_object($book) && is_a($book, 'rcube_addressbook'))
         $book->close();
-    }
-
-    // before closing the database connection, write session data
-    if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) {
-      session_write_close();
     }
 
     // write performance stats to logs/console
@@ -931,22 +999,32 @@
     /**
      * Write login data (name, ID, IP address) to the 'userlogins' log file.
      */
-    public function log_login()
+    public function log_login($user = null, $failed_login = false, $error_code = 0)
     {
         if (!$this->config->get('log_logins')) {
             return;
         }
 
-        $user_name = $this->get_user_name();
-        $user_id   = $this->get_user_id();
+        // failed login
+        if ($failed_login) {
+            $message = sprintf('Failed login for %s from %s in session %s (error: %d)',
+                $user, rcube_utils::remote_ip(), session_id(), $error_code);
+        }
+        // successful login
+        else {
+            $user_name = $this->get_user_name();
+            $user_id   = $this->get_user_id();
 
-        if (!$user_id) {
-            return;
+            if (!$user_id) {
+                return;
+            }
+
+            $message = sprintf('Successful login for %s (ID: %d) from %s in session %s',
+                    $user_name, $user_id, rcube_utils::remote_ip(), session_id());
         }
 
-        self::write_log('userlogins',
-            sprintf('Successful login for %s (ID: %d) from %s in session %s',
-                $user_name, $user_id, rcube_utils::remote_ip(), session_id()));
+        // log login
+        self::write_log('userlogins', $message);
     }
 
 
@@ -1325,9 +1403,7 @@
         $realnames = (bool)$attrib['realnames'];
         $msgcounts = $this->storage->get_cache('messagecount');
         $collapsed = $this->config->get('collapsed_folders');
-
-        if ($this->config->get('show_real_foldernames'))
-            $realnames = true;
+        $realnames = $this->config->get('show_real_foldernames');
 
         $out = '';
         foreach ($arrFolders as $folder) {
@@ -1484,8 +1560,10 @@
      */
     public function localize_foldername($name, $with_path = true)
     {
+        $realnames = $this->config->get('show_real_foldernames');
+
         // try to localize path of the folder
-        if ($with_path) {
+        if ($with_path && !$realnames) {
             $storage   = $this->get_storage();
             $delimiter = $storage->get_hierarchy_delimiter();
             $path      = explode($delimiter, $name);
@@ -1494,8 +1572,7 @@
             if ($count > 1) {
                 for ($i = 0; $i < $count; $i++) {
                     $folder = implode($delimiter, array_slice($path, 0, -$i));
-                    if (!$this->config->get('show_real_foldernames') &&
-                        ($folder_class = $this->folder_classname($folder))) {
+                    if ($folder_class = $this->folder_classname($folder)) {
                         $name = implode($delimiter, array_slice($path, $count - $i));
                         return $this->gettext($folder_class) . $delimiter . rcube_charset::convert($name, 'UTF7-IMAP');
                     }
@@ -1503,13 +1580,11 @@
             }
         }
 
-        if (!$this->config->get('show_real_foldernames') &&
-            ($folder_class = $this->folder_classname($name))) {
+        if (!$realnames && ($folder_class = $this->folder_classname($name))) {
             return $this->gettext($folder_class);
         }
-        else {
-            return rcube_charset::convert($name, 'UTF7-IMAP');
-        }
+
+        return rcube_charset::convert($name, 'UTF7-IMAP');
     }
 
 
@@ -1564,11 +1639,7 @@
         $quota_result = (array) $quota;
         $quota_result['type'] = isset($_SESSION['quota_display']) ? $_SESSION['quota_display'] : '';
 
-        if (!$quota['total'] && $this->config->get('quota_zero_as_unlimited')) {
-            $quota_result['title']   = $this->gettext('unlimited');
-            $quota_result['percent'] = 0;
-        }
-        else if ($quota['total']) {
+        if ($quota['total'] > 0) {
             if (!isset($quota['percent'])) {
                 $quota_result['percent'] = min(100, round(($quota['used']/max(1,$quota['total']))*100));
             }
@@ -1587,7 +1658,8 @@
             }
         }
         else {
-            $quota_result['title']   = $this->gettext('unknown');
+            $unlimited               = $this->config->get('quota_zero_as_unlimited');
+            $quota_result['title']   = $this->gettext($unlimited ? 'unlimited' : 'unknown');
             $quota_result['percent'] = 0;
         }
 
@@ -1766,7 +1838,8 @@
     public function upload_init()
     {
         // Enable upload progress bar
-        if (($seconds = $this->config->get('upload_progress')) && ini_get('apc.rfc1867')) {
+        $rfc1867 = filter_var(ini_get('apc.rfc1867'), FILTER_VALIDATE_BOOLEAN);
+        if ($rfc1867 && ($seconds = $this->config->get('upload_progress'))) {
             if ($field_name = ini_get('apc.rfc1867_name')) {
                 $this->output->set_env('upload_progress_name', $field_name);
                 $this->output->set_env('upload_progress_time', (int) $seconds);

--
Gitblit v1.9.1