diff options
| -rw-r--r-- | program/include/html.php | 2 | ||||
| -rw-r--r-- | program/include/rcube.php | 1318 | ||||
| -rw-r--r-- | program/include/rcube_browser.php | 2 | 
3 files changed, 682 insertions, 640 deletions
| diff --git a/program/include/html.php b/program/include/html.php index d15d50875..c6507f813 100644 --- a/program/include/html.php +++ b/program/include/html.php @@ -154,7 +154,7 @@ class html              $attr = array('src' => $attr);          }          return self::tag('img', $attr + array('alt' => ''), null, array_merge(self::$common_attrib, -	        array('src','alt','width','height','border','usemap','onclick'))); +            array('src','alt','width','height','border','usemap','onclick')));      }      /** diff --git a/program/include/rcube.php b/program/include/rcube.php index 494b5c3dd..84014ef5c 100644 --- a/program/include/rcube.php +++ b/program/include/rcube.php @@ -25,364 +25,372 @@   * Base class of the Roundcube Framework   * implemented as singleton   * - * @package Core + * @package    Framework + * @subpackage Core   */  class rcube  { -  const INIT_WITH_DB = 1; -  const INIT_WITH_PLUGINS = 2; +    const INIT_WITH_DB = 1; +    const INIT_WITH_PLUGINS = 2; -  /** -   * Singleton instace of rcube -   * -   * @var rcmail -   */ -  static protected $instance; +    /** +     * Singleton instace of rcube +     * +     * @var rcmail +     */ +    static protected $instance; -  /** -   * Stores instance of rcube_config. -   * -   * @var rcube_config -   */ -  public $config; +    /** +     * Stores instance of rcube_config. +     * +     * @var rcube_config +     */ +    public $config; -  /** -   * Instace of database class. -   * -   * @var rcube_pdo -   */ -  public $db; +    /** +     * Instace of database class. +     * +     * @var rcube_db +     */ +    public $db; -  /** -   * Instace of Memcache class. -   * -   * @var Memcache -   */ -  public $memcache; +    /** +     * Instace of Memcache class. +     * +     * @var Memcache +     */ +    public $memcache; -  /** -   * Instace of rcube_session class. -   * -   * @var rcube_session -   */ -  public $session; +   /** +     * Instace of rcube_session class. +     * +     * @var rcube_session +     */ +    public $session; -  /** -   * Instance of rcube_smtp class. -   * -   * @var rcube_smtp -   */ -  public $smtp; +    /** +     * Instance of rcube_smtp class. +     * +     * @var rcube_smtp +     */ +    public $smtp; -  /** -   * Instance of rcube_storage class. -   * -   * @var rcube_storage -   */ -  public $storage; +    /** +     * Instance of rcube_storage class. +     * +     * @var rcube_storage +     */ +    public $storage; -  /** -   * Instance of rcube_output class. -   * -   * @var rcube_output -   */ -  public $output; +    /** +     * Instance of rcube_output class. +     * +     * @var rcube_output +     */ +    public $output; -  /** -   * Instance of rcube_plugin_api. -   * -   * @var rcube_plugin_api -   */ -  public $plugins; +    /** +     * Instance of rcube_plugin_api. +     * +     * @var rcube_plugin_api +     */ +    public $plugins; -  /* private/protected vars */ -  protected $texts; -  protected $caches = array(); -  protected $shutdown_functions = array(); -  protected $expunge_cache = false; +    /* private/protected vars */ +    protected $texts; +    protected $caches = array(); +    protected $shutdown_functions = array(); +    protected $expunge_cache = false; -  /** -   * This implements the 'singleton' design pattern -   * -   * @param integer Options to initialize with this instance. See rcube::INIT_WITH_* constants -   * @return rcube The one and only instance -   */ -  static function get_instance($mode = 0) -  { -    if (!self::$instance) { -      self::$instance = new rcube(); -      self::$instance->init($mode); +    /** +     * This implements the 'singleton' design pattern +     * +     * @param integer Options to initialize with this instance. See rcube::INIT_WITH_* constants +     * +     * @return rcube The one and only instance +     */ +    static function get_instance($mode = 0) +    { +        if (!self::$instance) { +            self::$instance = new rcube(); +            self::$instance->init($mode); +        } + +        return self::$instance;      } -    return self::$instance; -  } +    /** +     * Private constructor +     */ +    protected function __construct() +    { +        // load configuration +        $this->config  = new rcube_config; +        $this->plugins = new rcube_dummy_plugin_api; -  /** -   * Private constructor -   */ -  protected function __construct() -  { -    // load configuration -    $this->config = new rcube_config(); -    $this->plugins = new rcube_dummy_plugin_api; +        register_shutdown_function(array($this, 'shutdown')); +    } -    register_shutdown_function(array($this, 'shutdown')); -  } +    /** +     * Initial startup function +     */ +    protected function init($mode = 0) +    { +        // initialize syslog +        if ($this->config->get('log_driver') == 'syslog') { +            $syslog_id       = $this->config->get('syslog_id', 'roundcube'); +            $syslog_facility = $this->config->get('syslog_facility', LOG_USER); +            openlog($syslog_id, LOG_ODELAY, $syslog_facility); +        } -  /** -   * Initial startup function -   */ -  protected function init($mode = 0) -  { -    // initialize syslog -    if ($this->config->get('log_driver') == 'syslog') { -      $syslog_id = $this->config->get('syslog_id', 'roundcube'); -      $syslog_facility = $this->config->get('syslog_facility', LOG_USER); -      openlog($syslog_id, LOG_ODELAY, $syslog_facility); -    } +        // connect to database +        if ($mode & self::INIT_WITH_DB) { +            $this->get_dbh(); +        } -    // connect to database -    if ($mode & self::INIT_WITH_DB) { -      $this->get_dbh(); +        // create plugin API and load plugins +        if ($mode & self::INIT_WITH_PLUGINS) { +            $this->plugins = rcube_plugin_api::get_instance(); +        }      } -    // create plugin API and load plugins -    if ($mode & self::INIT_WITH_PLUGINS) { -      $this->plugins = rcube_plugin_api::get_instance(); -    } -  } +    /** +     * Get the current database connection +     * +     * @return rcube_db Database object +     */ +    public function get_dbh() +    { +        if (!$this->db) { +            $config_all = $this->config->all(); +            $this->db = rcube_db::factory($config_all['db_dsnw'], $config_all['db_dsnr'], $config_all['db_persistent']); +            $this->db->set_debug((bool)$config_all['sql_debug']); +        } -  /** -   * Get the current database connection -   * -   * @return rcube_pdo  Database connection object -   */ -  public function get_dbh() -  { -    if (!$this->db) { -      $config_all = $this->config->all(); -      $this->db = rcube_db::factory($config_all['db_dsnw'], $config_all['db_dsnr'], $config_all['db_persistent']); -      $this->db->set_debug((bool)$config_all['sql_debug']); +        return $this->db;      } -    return $this->db; -  } +    /** +     * Get global handle for memcache access +     * +     * @return object Memcache +     */ +    public function get_memcache() +    { +        if (!isset($this->memcache)) { +            // no memcache support in PHP +            if (!class_exists('Memcache')) { +                $this->memcache = false; +                return false; +            } -  /** -   * Get global handle for memcache access -   * -   * @return object Memcache -   */ -  public function get_memcache() -  { -    if (!isset($this->memcache)) { -      // no memcache support in PHP -      if (!class_exists('Memcache')) { -        $this->memcache = false; -        return false; -      } +            $this->memcache     = new Memcache; +            $this->mc_available = 0; -      $this->memcache = new Memcache; -      $this->mc_available = 0; +            // add all configured hosts to pool +            $pconnect = $this->config->get('memcache_pconnect', true); +            foreach ($this->config->get('memcache_hosts', array()) as $host) { +                if (substr($host, 0, 7) != 'unix://') { +                    list($host, $port) = explode(':', $host); +                    if (!$port) $port = 11211; +                } +                else { +                    $port = 0; +                } -      // add all configured hosts to pool -      $pconnect = $this->config->get('memcache_pconnect', true); -      foreach ($this->config->get('memcache_hosts', array()) as $host) { -        if (substr($host, 0, 7) != 'unix://') { -          list($host, $port) = explode(':', $host); -          if (!$port) $port = 11211; -        } -        else { -          $port = 0; -        } +                $this->mc_available += intval($this->memcache->addServer( +                    $host, $port, $pconnect, 1, 1, 15, false, array($this, 'memcache_failure'))); +            } -        $this->mc_available += intval($this->memcache->addServer($host, $port, $pconnect, 1, 1, 15, false, array($this, 'memcache_failure'))); -      } +            // test connection and failover (will result in $this->mc_available == 0 on complete failure) +            $this->memcache->increment('__CONNECTIONTEST__', 1);  // NOP if key doesn't exist -      // test connection and failover (will result in $this->mc_available == 0 on complete failure) -      $this->memcache->increment('__CONNECTIONTEST__', 1);  // NOP if key doesn't exist +            if (!$this->mc_available) { +                $this->memcache = false; +            } +        } -      if (!$this->mc_available) -        $this->memcache = false; +        return $this->memcache;      } -    return $this->memcache; -  } +    /** +     * Callback for memcache failure +     */ +    public function memcache_failure($host, $port) +    { +        static $seen = array(); -  /** -   * Callback for memcache failure -   */ -  public function memcache_failure($host, $port) -  { -    static $seen = array(); - -    // only report once -    if (!$seen["$host:$port"]++) { -      $this->mc_available--; -      self::raise_error(array('code' => 604, 'type' => 'db', -        'line' => __LINE__, 'file' => __FILE__, -        'message' => "Memcache failure on host $host:$port"), -        true, false); +        // only report once +        if (!$seen["$host:$port"]++) { +            $this->mc_available--; +            self::raise_error(array( +                'code' => 604, 'type' => 'db', +                'line' => __LINE__, 'file' => __FILE__, +                'message' => "Memcache failure on host $host:$port"), +                true, false); +        }      } -  } -  /** -   * Initialize and get cache object -   * -   * @param string $name   Cache identifier -   * @param string $type   Cache type ('db', 'apc' or 'memcache') -   * @param string $ttl    Expiration time for cache items -   * @param bool   $packed Enables/disables data serialization -   * -   * @return rcube_cache Cache object -   */ -  public function get_cache($name, $type='db', $ttl=0, $packed=true) -  { -    if (!isset($this->caches[$name]) && ($userid = $this->get_user_id())) { -      $this->caches[$name] = new rcube_cache($type, $userid, $name, $ttl, $packed); +    /** +     * Initialize and get cache object +     * +     * @param string $name   Cache identifier +     * @param string $type   Cache type ('db', 'apc' or 'memcache') +     * @param string $ttl    Expiration time for cache items +     * @param bool   $packed Enables/disables data serialization +     * +     * @return rcube_cache Cache object +     */ +    public function get_cache($name, $type='db', $ttl=0, $packed=true) +    { +        if (!isset($this->caches[$name]) && ($userid = $this->get_user_id())) { +            $this->caches[$name] = new rcube_cache($type, $userid, $name, $ttl, $packed); +        } + +        return $this->caches[$name];      } -    return $this->caches[$name]; -  } +    /** +     * Create SMTP object and connect to server +     * +     * @param boolean True if connection should be established +     */ +    public function smtp_init($connect = false) +    { +        $this->smtp = new rcube_smtp(); -  /** -   * Create SMTP object and connect to server -   * -   * @param boolean True if connection should be established -   */ -  public function smtp_init($connect = false) -  { -    $this->smtp = new rcube_smtp(); +        if ($connect) { +            $this->smtp->connect(); +        } +    } -    if ($connect) -      $this->smtp->connect(); -  } +    /** +     * Initialize and get storage object +     * +     * @return rcube_storage Storage object +     */ +    public function get_storage() +    { +        // already initialized +        if (!is_object($this->storage)) { +            $this->storage_init(); +        } -  /** -   * Initialize and get storage object -   * -   * @return rcube_storage Storage object -   */ -  public function get_storage() -  { -    // already initialized -    if (!is_object($this->storage)) { -      $this->storage_init(); +        return $this->storage;      } -    return $this->storage; -  } - -  /** -   * Initialize storage object -   */ -  public function storage_init() -  { -    // already initialized -    if (is_object($this->storage)) { -      return; -    } +    /** +     * Initialize storage object +     */ +    public function storage_init() +    { +        // already initialized +        if (is_object($this->storage)) { +            return; +        } -    $driver = $this->config->get('storage_driver', 'imap'); -    $driver_class = "rcube_{$driver}"; +        $driver       = $this->config->get('storage_driver', 'imap'); +        $driver_class = "rcube_{$driver}"; -    if (!class_exists($driver_class)) { -      self::raise_error(array( -        'code' => 700, 'type' => 'php', -        'file' => __FILE__, 'line' => __LINE__, -        'message' => "Storage driver class ($driver) not found!"), -        true, true); -    } +        if (!class_exists($driver_class)) { +            self::raise_error(array( +                'code' => 700, 'type' => 'php', +                'file' => __FILE__, 'line' => __LINE__, +                'message' => "Storage driver class ($driver) not found!"), +                true, true); +        } -    // Initialize storage object -    $this->storage = new $driver_class; +        // Initialize storage object +        $this->storage = new $driver_class; -    // for backward compat. (deprecated, will be removed) -    $this->imap = $this->storage; +        // for backward compat. (deprecated, will be removed) +        $this->imap = $this->storage; -    // enable caching of mail data -    $storage_cache  = $this->config->get("{$driver}_cache"); -    $messages_cache = $this->config->get('messages_cache'); -    // for backward compatybility -    if ($storage_cache === null && $messages_cache === null && $this->config->get('enable_caching')) { -        $storage_cache  = 'db'; -        $messages_cache = true; -    } +        // enable caching of mail data +        $storage_cache  = $this->config->get("{$driver}_cache"); +        $messages_cache = $this->config->get('messages_cache'); +        // for backward compatybility +        if ($storage_cache === null && $messages_cache === null && $this->config->get('enable_caching')) { +            $storage_cache  = 'db'; +            $messages_cache = true; +        } -    if ($storage_cache) -        $this->storage->set_caching($storage_cache); -    if ($messages_cache) -        $this->storage->set_messages_caching(true); +        if ($storage_cache) { +            $this->storage->set_caching($storage_cache); +        } +        if ($messages_cache) { +            $this->storage->set_messages_caching(true); +        } -    // set pagesize from config -    $pagesize = $this->config->get('mail_pagesize'); -    if (!$pagesize) { -        $pagesize = $this->config->get('pagesize', 50); -    } -    $this->storage->set_pagesize($pagesize); +        // set pagesize from config +        $pagesize = $this->config->get('mail_pagesize'); +        if (!$pagesize) { +            $pagesize = $this->config->get('pagesize', 50); +        } +        $this->storage->set_pagesize($pagesize); -    // set class options -    $options = array( -      'auth_type'   => $this->config->get("{$driver}_auth_type", 'check'), -      'auth_cid'    => $this->config->get("{$driver}_auth_cid"), -      'auth_pw'     => $this->config->get("{$driver}_auth_pw"), -      'debug'       => (bool) $this->config->get("{$driver}_debug"), -      'force_caps'  => (bool) $this->config->get("{$driver}_force_caps"), -      'timeout'     => (int) $this->config->get("{$driver}_timeout"), -      'skip_deleted' => (bool) $this->config->get('skip_deleted'), -      'driver'      => $driver, -    ); +        // set class options +        $options = array( +            'auth_type'   => $this->config->get("{$driver}_auth_type", 'check'), +            'auth_cid'    => $this->config->get("{$driver}_auth_cid"), +            'auth_pw'     => $this->config->get("{$driver}_auth_pw"), +            'debug'       => (bool) $this->config->get("{$driver}_debug"), +            'force_caps'  => (bool) $this->config->get("{$driver}_force_caps"), +            'timeout'     => (int) $this->config->get("{$driver}_timeout"), +            'skip_deleted' => (bool) $this->config->get('skip_deleted'), +            'driver'      => $driver, +        ); -    if (!empty($_SESSION['storage_host'])) { -      $options['host']     = $_SESSION['storage_host']; -      $options['user']     = $_SESSION['username']; -      $options['port']     = $_SESSION['storage_port']; -      $options['ssl']      = $_SESSION['storage_ssl']; -      $options['password'] = $this->decrypt($_SESSION['password']); -      $_SESSION[$driver.'_host'] = $_SESSION['storage_host']; -    } +        if (!empty($_SESSION['storage_host'])) { +            $options['host']     = $_SESSION['storage_host']; +            $options['user']     = $_SESSION['username']; +            $options['port']     = $_SESSION['storage_port']; +            $options['ssl']      = $_SESSION['storage_ssl']; +            $options['password'] = $this->decrypt($_SESSION['password']); +            $_SESSION[$driver.'_host'] = $_SESSION['storage_host']; +        } -    $options = $this->plugins->exec_hook("storage_init", $options); +        $options = $this->plugins->exec_hook("storage_init", $options); -    // for backward compat. (deprecated, to be removed) -    $options = $this->plugins->exec_hook("imap_init", $options); +        // for backward compat. (deprecated, to be removed) +        $options = $this->plugins->exec_hook("imap_init", $options); -    $this->storage->set_options($options); -    $this->set_storage_prop(); -  } +        $this->storage->set_options($options); +        $this->set_storage_prop(); +    } -  /** -   * Set storage parameters. -   * This must be done AFTER connecting to the server! -   */ -  protected function set_storage_prop() -  { -    $storage = $this->get_storage(); +    /** +     * Set storage parameters. +     * This must be done AFTER connecting to the server! +     */ +    protected function set_storage_prop() +    { +        $storage = $this->get_storage(); -    $storage->set_charset($this->config->get('default_charset', RCMAIL_CHARSET)); +        $storage->set_charset($this->config->get('default_charset', RCMAIL_CHARSET)); -    if ($default_folders = $this->config->get('default_folders')) { -      $storage->set_default_folders($default_folders); -    } -    if (isset($_SESSION['mbox'])) { -      $storage->set_folder($_SESSION['mbox']); -    } -    if (isset($_SESSION['page'])) { -      $storage->set_page($_SESSION['page']); +        if ($default_folders = $this->config->get('default_folders')) { +            $storage->set_default_folders($default_folders); +        } +        if (isset($_SESSION['mbox'])) { +            $storage->set_folder($_SESSION['mbox']); +        } +        if (isset($_SESSION['page'])) { +            $storage->set_page($_SESSION['page']); +        }      } -  }      /** @@ -492,433 +500,469 @@ class rcube      } -  /** -   * Get localized text in the desired language -   * -   * @param mixed   $attrib  Named parameters array or label name -   * @param string  $domain  Label domain (plugin) name -   * -   * @return string Localized text -   */ -  public function gettext($attrib, $domain=null) -  { -    // load localization files if not done yet -    if (empty($this->texts)) -      $this->load_language(); +    /** +     * Get localized text in the desired language +     * +     * @param mixed   $attrib  Named parameters array or label name +     * @param string  $domain  Label domain (plugin) name +     * +     * @return string Localized text +     */ +    public function gettext($attrib, $domain=null) +    { +        // load localization files if not done yet +        if (empty($this->texts)) { +            $this->load_language(); +        } -    // extract attributes -    if (is_string($attrib)) -      $attrib = array('name' => $attrib); +        // extract attributes +        if (is_string($attrib)) { +            $attrib = array('name' => $attrib); +        } -    $name = $attrib['name'] ? $attrib['name'] : ''; +        $name = $attrib['name'] ? $attrib['name'] : ''; -    // attrib contain text values: use them from now -    if (($setval = $attrib[strtolower($_SESSION['language'])]) || ($setval = $attrib['en_us'])) -        $this->texts[$name] = $setval; +        // attrib contain text values: use them from now +        if (($setval = $attrib[strtolower($_SESSION['language'])]) || ($setval = $attrib['en_us'])) { +            $this->texts[$name] = $setval; +        } -    // check for text with domain -    if ($domain && ($text = $this->texts[$domain.'.'.$name])) -      ; -    // text does not exist -    else if (!($text = $this->texts[$name])) { -      return "[$name]"; -    } +        // check for text with domain +        if ($domain && ($text = $this->texts[$domain.'.'.$name])) { +        } +        // text does not exist +        else if (!($text = $this->texts[$name])) { +            return "[$name]"; +        } -    // replace vars in text -    if (is_array($attrib['vars'])) { -      foreach ($attrib['vars'] as $var_key => $var_value) -        $text = str_replace($var_key[0]!='$' ? '$'.$var_key : $var_key, $var_value, $text); -    } +        // replace vars in text +        if (is_array($attrib['vars'])) { +            foreach ($attrib['vars'] as $var_key => $var_value) { +                $text = str_replace($var_key[0]!='$' ? '$'.$var_key : $var_key, $var_value, $text); +            } +        } -    // format output -    if (($attrib['uppercase'] && strtolower($attrib['uppercase']=='first')) || $attrib['ucfirst']) -      return ucfirst($text); -    else if ($attrib['uppercase']) -      return mb_strtoupper($text); -    else if ($attrib['lowercase']) -      return mb_strtolower($text); +        // format output +        if (($attrib['uppercase'] && strtolower($attrib['uppercase'] == 'first')) || $attrib['ucfirst']) { +            return ucfirst($text); +        } +        else if ($attrib['uppercase']) { +            return mb_strtoupper($text); +        } +        else if ($attrib['lowercase']) { +            return mb_strtolower($text); +        } -    return strtr($text, array('\n' => "\n")); -  } +        return strtr($text, array('\n' => "\n")); +    } -  /** -   * Check if the given text label exists -   * -   * @param string  $name       Label name -   * @param string  $domain     Label domain (plugin) name or '*' for all domains -   * @param string  $ref_domain Sets domain name if label is found -   * -   * @return boolean True if text exists (either in the current language or in en_US) -   */ -  public function text_exists($name, $domain = null, &$ref_domain = null) -  { -    // load localization files if not done yet -    if (empty($this->texts)) -      $this->load_language(); +    /** +     * Check if the given text label exists +     * +     * @param string  $name       Label name +     * @param string  $domain     Label domain (plugin) name or '*' for all domains +     * @param string  $ref_domain Sets domain name if label is found +     * +     * @return boolean True if text exists (either in the current language or in en_US) +     */ +    public function text_exists($name, $domain = null, &$ref_domain = null) +    { +        // load localization files if not done yet +        if (empty($this->texts)) { +            $this->load_language(); +        } -    if (isset($this->texts[$name])) { -        $ref_domain = ''; -        return true; -    } +        if (isset($this->texts[$name])) { +            $ref_domain = ''; +            return true; +        } -    // any of loaded domains (plugins) -    if ($domain == '*') { -      foreach ($this->plugins->loaded_plugins() as $domain) -        if (isset($this->texts[$domain.'.'.$name])) { -          $ref_domain = $domain; -          return true; +        // any of loaded domains (plugins) +        if ($domain == '*') { +            foreach ($this->plugins->loaded_plugins() as $domain) { +                if (isset($this->texts[$domain.'.'.$name])) { +                    $ref_domain = $domain; +                    return true; +                } +            }          } +        // specified domain +        else if ($domain) { +            $ref_domain = $domain; +            return isset($this->texts[$domain.'.'.$name]); +        } + +        return false;      } -    // specified domain -    else if ($domain) { -      $ref_domain = $domain; -      return isset($this->texts[$domain.'.'.$name]); -    } -    return false; -  } -  /** -   * Load a localization package -   * -   * @param string Language ID -   */ -  public function load_language($lang = null, $add = array()) -  { -    $lang = $this->language_prop(($lang ? $lang : $_SESSION['language'])); +    /** +     * Load a localization package +     * +     * @param string Language ID +     * @param array  Additional text labels/messages +     */ +    public function load_language($lang = null, $add = array()) +    { +        $lang = $this->language_prop(($lang ? $lang : $_SESSION['language'])); + +        // load localized texts +        if (empty($this->texts) || $lang != $_SESSION['language']) { +            $this->texts = array(); -    // load localized texts -    if (empty($this->texts) || $lang != $_SESSION['language']) { -      $this->texts = array(); +            // handle empty lines after closing PHP tag in localization files +            ob_start(); -      // handle empty lines after closing PHP tag in localization files -      ob_start(); +            // get english labels (these should be complete) +            @include(INSTALL_PATH . 'program/localization/en_US/labels.inc'); +            @include(INSTALL_PATH . 'program/localization/en_US/messages.inc'); -      // get english labels (these should be complete) -      @include(INSTALL_PATH . 'program/localization/en_US/labels.inc'); -      @include(INSTALL_PATH . 'program/localization/en_US/messages.inc'); +            if (is_array($labels)) +                $this->texts = $labels; +            if (is_array($messages)) +                $this->texts = array_merge($this->texts, $messages); -      if (is_array($labels)) -        $this->texts = $labels; -      if (is_array($messages)) -        $this->texts = array_merge($this->texts, $messages); +            // include user language files +            if ($lang != 'en' && $lang != 'en_US' && is_dir(INSTALL_PATH . 'program/localization/' . $lang)) { +                include_once(INSTALL_PATH . 'program/localization/' . $lang . '/labels.inc'); +                include_once(INSTALL_PATH . 'program/localization/' . $lang . '/messages.inc'); -      // include user language files -      if ($lang != 'en' && $lang != 'en_US' && is_dir(INSTALL_PATH . 'program/localization/' . $lang)) { -        include_once(INSTALL_PATH . 'program/localization/' . $lang . '/labels.inc'); -        include_once(INSTALL_PATH . 'program/localization/' . $lang . '/messages.inc'); +                if (is_array($labels)) +                    $this->texts = array_merge($this->texts, $labels); +                if (is_array($messages)) +                    $this->texts = array_merge($this->texts, $messages); +            } -        if (is_array($labels)) -          $this->texts = array_merge($this->texts, $labels); -        if (is_array($messages)) -          $this->texts = array_merge($this->texts, $messages); -      } +            ob_end_clean(); -      ob_end_clean(); +            $_SESSION['language'] = $lang; +        } -      $_SESSION['language'] = $lang; +        // append additional texts (from plugin) +        if (is_array($add) && !empty($add)) { +            $this->texts += $add; +        }      } -    // append additional texts (from plugin) -    if (is_array($add) && !empty($add)) -      $this->texts += $add; -  } +    /** +     * Check the given string and return a valid language code +     * +     * @param string Language code +     * +     * @return string Valid language code +     */ +    protected function language_prop($lang) +    { +        static $rcube_languages, $rcube_language_aliases; -  /** -   * Check the given string and return a valid language code -   * -   * @param string Language code -   * @return string Valid language code -   */ -  protected function language_prop($lang) -  { -    static $rcube_languages, $rcube_language_aliases; +        // user HTTP_ACCEPT_LANGUAGE if no language is specified +        if (empty($lang) || $lang == 'auto') { +            $accept_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); +            $lang         = str_replace('-', '_', $accept_langs[0]); +        } -    // user HTTP_ACCEPT_LANGUAGE if no language is specified -    if (empty($lang) || $lang == 'auto') { -       $accept_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); -       $lang = str_replace('-', '_', $accept_langs[0]); -     } +        if (empty($rcube_languages)) { +            @include(INSTALL_PATH . 'program/localization/index.inc'); +        } -    if (empty($rcube_languages)) { -      @include(INSTALL_PATH . 'program/localization/index.inc'); -    } +        // check if we have an alias for that language +        if (!isset($rcube_languages[$lang]) && isset($rcube_language_aliases[$lang])) { +            $lang = $rcube_language_aliases[$lang]; +        } +        // try the first two chars +        else if (!isset($rcube_languages[$lang])) { +            $short = substr($lang, 0, 2); -    // check if we have an alias for that language -    if (!isset($rcube_languages[$lang]) && isset($rcube_language_aliases[$lang])) { -      $lang = $rcube_language_aliases[$lang]; -    } -    // try the first two chars -    else if (!isset($rcube_languages[$lang])) { -      $short = substr($lang, 0, 2); +            // check if we have an alias for the short language code +            if (!isset($rcube_languages[$short]) && isset($rcube_language_aliases[$short])) { +                $lang = $rcube_language_aliases[$short]; +            } +            // expand 'nn' to 'nn_NN' +            else if (!isset($rcube_languages[$short])) { +                $lang = $short.'_'.strtoupper($short); +            } +        } -      // check if we have an alias for the short language code -      if (!isset($rcube_languages[$short]) && isset($rcube_language_aliases[$short])) { -        $lang = $rcube_language_aliases[$short]; -      } -      // expand 'nn' to 'nn_NN' -      else if (!isset($rcube_languages[$short])) { -        $lang = $short.'_'.strtoupper($short); -      } -    } +        if (!isset($rcube_languages[$lang]) || !is_dir(INSTALL_PATH . 'program/localization/' . $lang)) { +            $lang = 'en_US'; +        } -    if (!isset($rcube_languages[$lang]) || !is_dir(INSTALL_PATH . 'program/localization/' . $lang)) { -      $lang = 'en_US'; +        return $lang;      } -    return $lang; -  } +    /** +     * Read directory program/localization and return a list of available languages +     * +     * @return array List of available localizations +     */ +    public function list_languages() +    { +        static $sa_languages = array(); -  /** -   * Read directory program/localization and return a list of available languages -   * -   * @return array List of available localizations -   */ -  public function list_languages() -  { -    static $sa_languages = array(); - -    if (!sizeof($sa_languages)) { -      @include(INSTALL_PATH . 'program/localization/index.inc'); +        if (!sizeof($sa_languages)) { +            @include(INSTALL_PATH . 'program/localization/index.inc'); -      if ($dh = @opendir(INSTALL_PATH . 'program/localization')) { -        while (($name = readdir($dh)) !== false) { -          if ($name[0] == '.' || !is_dir(INSTALL_PATH . 'program/localization/' . $name)) -            continue; +            if ($dh = @opendir(INSTALL_PATH . 'program/localization')) { +                while (($name = readdir($dh)) !== false) { +                    if ($name[0] == '.' || !is_dir(INSTALL_PATH . 'program/localization/' . $name)) { +                        continue; +                    } -          if ($label = $rcube_languages[$name]) -            $sa_languages[$name] = $label; +                    if ($label = $rcube_languages[$name]) { +                        $sa_languages[$name] = $label; +                    } +                } +                closedir($dh); +            }          } -        closedir($dh); -      } + +        return $sa_languages;      } -    return $sa_languages; -  } +    /** +     * Encrypt using 3DES +     * +     * @param string $clear clear text input +     * @param string $key encryption key to retrieve from the configuration, defaults to 'des_key' +     * @param boolean $base64 whether or not to base64_encode() the result before returning +     * +     * @return string encrypted text +     */ +    public function encrypt($clear, $key = 'des_key', $base64 = true) +    { +        if (!$clear) { +            return ''; +        } -  /** -   * Encrypt using 3DES -   * -   * @param string $clear clear text input -   * @param string $key encryption key to retrieve from the configuration, defaults to 'des_key' -   * @param boolean $base64 whether or not to base64_encode() the result before returning -   * -   * @return string encrypted text -   */ -  public function encrypt($clear, $key = 'des_key', $base64 = true) -  { -    if (!$clear) -      return ''; +        /*- +         * Add a single canary byte to the end of the clear text, which +         * will help find out how much of padding will need to be removed +         * upon decryption; see http://php.net/mcrypt_generic#68082 +         */ +        $clear = pack("a*H2", $clear, "80"); -    /*- -     * Add a single canary byte to the end of the clear text, which -     * will help find out how much of padding will need to be removed -     * upon decryption; see http://php.net/mcrypt_generic#68082 -     */ -    $clear = pack("a*H2", $clear, "80"); +        if (function_exists('mcrypt_module_open') && +            ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, "")) +        ) { +            $iv = $this->create_iv(mcrypt_enc_get_iv_size($td)); +            mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv); +            $cipher = $iv . mcrypt_generic($td, $clear); +            mcrypt_generic_deinit($td); +            mcrypt_module_close($td); +        } +        else { +            @include_once 'des.inc'; -    if (function_exists('mcrypt_module_open') && -        ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, ""))) { -      $iv = $this->create_iv(mcrypt_enc_get_iv_size($td)); -      mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv); -      $cipher = $iv . mcrypt_generic($td, $clear); -      mcrypt_generic_deinit($td); -      mcrypt_module_close($td); -    } -    else { -      @include_once 'des.inc'; +            if (function_exists('des')) { +                $des_iv_size = 8; +                $iv = $this->create_iv($des_iv_size); +                $cipher = $iv . des($this->config->get_crypto_key($key), $clear, 1, 1, $iv); +            } +            else { +                self::raise_error(array( +                    'code' => 500, 'type' => 'php', +                    'file' => __FILE__, 'line' => __LINE__, +                    'message' => "Could not perform encryption; make sure Mcrypt is installed or lib/des.inc is available" +                    ), true, true); +            } +        } -      if (function_exists('des')) { -        $des_iv_size = 8; -        $iv = $this->create_iv($des_iv_size); -        $cipher = $iv . des($this->config->get_crypto_key($key), $clear, 1, 1, $iv); -      } -      else { -        self::raise_error(array( -          'code' => 500, 'type' => 'php', -          'file' => __FILE__, 'line' => __LINE__, -          'message' => "Could not perform encryption; make sure Mcrypt is installed or lib/des.inc is available" -        ), true, true); -      } +        return $base64 ? base64_encode($cipher) : $cipher;      } -    return $base64 ? base64_encode($cipher) : $cipher; -  } -  /** -   * Decrypt 3DES-encrypted string -   * -   * @param string $cipher encrypted text -   * @param string $key encryption key to retrieve from the configuration, defaults to 'des_key' -   * @param boolean $base64 whether or not input is base64-encoded -   * -   * @return string decrypted text -   */ -  public function decrypt($cipher, $key = 'des_key', $base64 = true) -  { -    if (!$cipher) -      return ''; +    /** +     * Decrypt 3DES-encrypted string +     * +     * @param string $cipher encrypted text +     * @param string $key encryption key to retrieve from the configuration, defaults to 'des_key' +     * @param boolean $base64 whether or not input is base64-encoded +     * +     * @return string decrypted text +     */ +    public function decrypt($cipher, $key = 'des_key', $base64 = true) +    { +        if (!$cipher) { +            return ''; +        } + +        $cipher = $base64 ? base64_decode($cipher) : $cipher; -    $cipher = $base64 ? base64_decode($cipher) : $cipher; +        if (function_exists('mcrypt_module_open') && +            ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, "")) +        ) { +            $iv_size = mcrypt_enc_get_iv_size($td); +            $iv = substr($cipher, 0, $iv_size); -    if (function_exists('mcrypt_module_open') && -        ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, ""))) { -      $iv_size = mcrypt_enc_get_iv_size($td); -      $iv = substr($cipher, 0, $iv_size); +            // session corruption? (#1485970) +            if (strlen($iv) < $iv_size) { +                return ''; +            } -      // session corruption? (#1485970) -      if (strlen($iv) < $iv_size) -        return ''; +            $cipher = substr($cipher, $iv_size); +            mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv); +            $clear = mdecrypt_generic($td, $cipher); +            mcrypt_generic_deinit($td); +            mcrypt_module_close($td); +        } +        else { +            @include_once 'des.inc'; -      $cipher = substr($cipher, $iv_size); -      mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv); -      $clear = mdecrypt_generic($td, $cipher); -      mcrypt_generic_deinit($td); -      mcrypt_module_close($td); -    } -    else { -      @include_once 'des.inc'; +            if (function_exists('des')) { +                $des_iv_size = 8; +                $iv = substr($cipher, 0, $des_iv_size); +                $cipher = substr($cipher, $des_iv_size); +                $clear = des($this->config->get_crypto_key($key), $cipher, 0, 1, $iv); +            } +            else { +                self::raise_error(array( +                    'code' => 500, 'type' => 'php', +                    'file' => __FILE__, 'line' => __LINE__, +                    'message' => "Could not perform decryption; make sure Mcrypt is installed or lib/des.inc is available" +                    ), true, true); +            } +        } + +        /*- +         * Trim PHP's padding and the canary byte; see note in +         * rcube::encrypt() and http://php.net/mcrypt_generic#68082 +         */ +        $clear = substr(rtrim($clear, "\0"), 0, -1); -      if (function_exists('des')) { -        $des_iv_size = 8; -        $iv = substr($cipher, 0, $des_iv_size); -        $cipher = substr($cipher, $des_iv_size); -        $clear = des($this->config->get_crypto_key($key), $cipher, 0, 1, $iv); -      } -      else { -        self::raise_error(array( -          'code' => 500, 'type' => 'php', -          'file' => __FILE__, 'line' => __LINE__, -          'message' => "Could not perform decryption; make sure Mcrypt is installed or lib/des.inc is available" -        ), true, true); -      } +        return $clear;      } -    /*- -     * Trim PHP's padding and the canary byte; see note in -     * rcube::encrypt() and http://php.net/mcrypt_generic#68082 + +    /** +     * Generates encryption initialization vector (IV) +     * +     * @param int Vector size +     * +     * @return string Vector string       */ -    $clear = substr(rtrim($clear, "\0"), 0, -1); +    private function create_iv($size) +    { +        // mcrypt_create_iv() can be slow when system lacks entrophy +        // we'll generate IV vector manually +        $iv = ''; +        for ($i = 0; $i < $size; $i++) { +            $iv .= chr(mt_rand(0, 255)); +        } -    return $clear; -  } +        return $iv; +    } -  /** -   * Generates encryption initialization vector (IV) -   * -   * @param int Vector size -   * @return string Vector string -   */ -  private function create_iv($size) -  { -    // mcrypt_create_iv() can be slow when system lacks entrophy -    // we'll generate IV vector manually -    $iv = ''; -    for ($i = 0; $i < $size; $i++) -        $iv .= chr(mt_rand(0, 255)); -    return $iv; -  } +    /** +     * Build a valid URL to this instance of Roundcube +     * +     * @param mixed Either a string with the action or url parameters as key-value pairs +     * @return string Valid application URL +     */ +    public function url($p) +    { +        // STUB: should be overloaded by the application +        return ''; +    } -  /** -   * Build a valid URL to this instance of Roundcube -   * -   * @param mixed Either a string with the action or url parameters as key-value pairs -   * @return string Valid application URL -   */ -  public function url($p) -  { -      // STUB: should be overloaded by the application -      return ''; -  } +    /** +     * Function to be executed in script shutdown +     * Registered with register_shutdown_function() +     */ +    public function shutdown() +    { +        foreach ($this->shutdown_functions as $function) { +            call_user_func($function); +        } -  /** -   * Function to be executed in script shutdown -   * Registered with register_shutdown_function() -   */ -  public function shutdown() -  { -    foreach ($this->shutdown_functions as $function) -      call_user_func($function); +        if (is_object($this->smtp)) { +            $this->smtp->disconnect(); +        } -    if (is_object($this->smtp)) -      $this->smtp->disconnect(); +        foreach ($this->caches as $cache) { +            if (is_object($cache)) { +                $cache->close(); +            } +        } -    foreach ($this->caches as $cache) { -        if (is_object($cache)) -            $cache->close(); +        if (is_object($this->storage)) { +            if ($this->expunge_cache) { +                $this->storage->expunge_cache(); +            } +            $this->storage->close(); +        }      } -    if (is_object($this->storage)) { -      if ($this->expunge_cache) -        $this->storage->expunge_cache(); -      $this->storage->close(); -    } -  } +    /** +     * Registers shutdown function to be executed on shutdown. +     * The functions will be executed before destroying any +     * objects like smtp, imap, session, etc. +     * +     * @param callback Function callback +     */ +    public function add_shutdown_function($function) +    { +        $this->shutdown_functions[] = $function; +    } -  /** -   * Registers shutdown function to be executed on shutdown. -   * The functions will be executed before destroying any -   * objects like smtp, imap, session, etc. -   * -   * @param callback Function callback -   */ -  public function add_shutdown_function($function) -  { -    $this->shutdown_functions[] = $function; -  } +    /** +     * Construct shell command, execute it and return output as string. +     * Keywords {keyword} are replaced with arguments +     * +     * @param $cmd Format string with {keywords} to be replaced +     * @param $values (zero, one or more arrays can be passed) +     * +     * @return output of command. shell errors not detectable +     */ +    public static function exec(/* $cmd, $values1 = array(), ... */) +    { +        $args   = func_get_args(); +        $cmd    = array_shift($args); +        $values = $replacements = array(); -  /** -   * Construct shell command, execute it and return output as string. -   * Keywords {keyword} are replaced with arguments -   * -   * @param $cmd Format string with {keywords} to be replaced -   * @param $values (zero, one or more arrays can be passed) -   * @return output of command. shell errors not detectable -   */ -  public static function exec(/* $cmd, $values1 = array(), ... */) -  { -    $args = func_get_args(); -    $cmd = array_shift($args); -    $values = $replacements = array(); +        // merge values into one array +        foreach ($args as $arg) { +            $values += (array)$arg; +        } -    // merge values into one array -    foreach ($args as $arg) -      $values += (array)$arg; +        preg_match_all('/({(-?)([a-z]\w*)})/', $cmd, $matches, PREG_SET_ORDER); +        foreach ($matches as $tags) { +            list(, $tag, $option, $key) = $tags; +            $parts = array(); -    preg_match_all('/({(-?)([a-z]\w*)})/', $cmd, $matches, PREG_SET_ORDER); -    foreach ($matches as $tags) { -      list(, $tag, $option, $key) = $tags; -      $parts = array(); +            if ($option) { +                foreach ((array)$values["-$key"] as $key => $value) { +                    if ($value === true || $value === false || $value === null) { +                        $parts[] = $value ? $key : ""; +                    } +                    else { +                        foreach ((array)$value as $val) { +                            $parts[] = "$key " . escapeshellarg($val); +                        } +                    } +                } +            } +            else { +                foreach ((array)$values[$key] as $value) { +                    $parts[] = escapeshellarg($value); +                } +            } -      if ($option) { -        foreach ((array)$values["-$key"] as $key => $value) { -          if ($value === true || $value === false || $value === null) -            $parts[] = $value ? $key : ""; -          else foreach ((array)$value as $val) -            $parts[] = "$key " . escapeshellarg($val); +            $replacements[$tag] = join(" ", $parts);          } -      } -      else { -        foreach ((array)$values[$key] as $value) -          $parts[] = escapeshellarg($value); -      } -      $replacements[$tag] = join(" ", $parts); -    } - -    // use strtr behaviour of going through source string once -    $cmd = strtr($cmd, $replacements); +        // use strtr behaviour of going through source string once +        $cmd = strtr($cmd, $replacements); -    return (string)shell_exec($cmd); -  } +        return (string)shell_exec($cmd); +    }      /** diff --git a/program/include/rcube_browser.php b/program/include/rcube_browser.php index 06033e036..7cfae709d 100644 --- a/program/include/rcube_browser.php +++ b/program/include/rcube_browser.php @@ -20,8 +20,6 @@  */  /** - * rcube_browser - *   * Provide details about the client's browser based on the User-Agent header   *   * @package Core | 
