diff options
| author | Hugues Hiegel <root@paranoid> | 2015-04-21 12:49:44 +0200 | 
|---|---|---|
| committer | Hugues Hiegel <root@paranoid> | 2015-04-21 12:49:44 +0200 | 
| commit | 733f8e8d0ce6217d906d06dc4fb08e36d48ed794 (patch) | |
| tree | cff28366ff63ea6596f8026e1698090bd0b9405c /program/include | |
| parent | ef2e7b3f9d264ec146d4dae257b1e295ab3b462a (diff) | |
| parent | a4ba3df54834ee90fb2c9930669f1229dc80261a (diff) | |
Conflicts:
	composer.json-dist
	config/defaults.inc.php
	plugins
	plugins/acl/acl.js
	plugins/acl/acl.php
	plugins/acl/skins/classic/templates/table.html
	plugins/acl/skins/larry/templates/table.html
	plugins/enigma/README
	plugins/enigma/config.inc.php.dist
	plugins/enigma/enigma.js
	plugins/enigma/enigma.php
	plugins/enigma/lib/enigma_driver.php
	plugins/enigma/lib/enigma_driver_gnupg.php
	plugins/enigma/lib/enigma_driver_phpssl.php
	plugins/enigma/lib/enigma_engine.php
	plugins/enigma/lib/enigma_error.php
	plugins/enigma/lib/enigma_key.php
	plugins/enigma/lib/enigma_signature.php
	plugins/enigma/lib/enigma_subkey.php
	plugins/enigma/lib/enigma_ui.php
	plugins/enigma/lib/enigma_userid.php
	plugins/enigma/localization/en_US.inc
	plugins/enigma/localization/ja_JP.inc
	plugins/enigma/localization/ru_RU.inc
	plugins/enigma/skins/classic/enigma.css
	plugins/enigma/skins/classic/templates/keys.html
	plugins/help/config.inc.php.dist
	plugins/help/help.php
	plugins/help/localization/en_US.inc
	plugins/jqueryui/jqueryui.php
	plugins/managesieve/Changelog
	plugins/managesieve/composer.json
	plugins/managesieve/config.inc.php.dist
	plugins/managesieve/lib/Roundcube/rcube_sieve.php
	plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
	plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php
	plugins/managesieve/localization/en_US.inc
	plugins/managesieve/managesieve.js
	plugins/managesieve/skins/classic/managesieve.css
	plugins/managesieve/skins/larry/managesieve.css
	plugins/password/README
	plugins/password/config.inc.php.dist
	plugins/password/drivers/ldap.php
	plugins/password/drivers/poppassd.php
	plugins/password/drivers/vpopmaild.php
	plugins/vcard_attachments/vcardattach.js
	plugins/zipdownload/zipdownload.php
Diffstat (limited to 'program/include')
| -rw-r--r-- | program/include/iniset.php | 11 | ||||
| -rw-r--r-- | program/include/rcmail.php | 17 | ||||
| -rw-r--r-- | program/include/rcmail_install.php | 8 | ||||
| -rw-r--r-- | program/include/rcmail_output_html.php | 2 | ||||
| -rw-r--r-- | program/include/rcmail_utils.php | 362 | 
5 files changed, 385 insertions, 15 deletions
diff --git a/program/include/iniset.php b/program/include/iniset.php index ca1e6ad75..d91b31436 100644 --- a/program/include/iniset.php +++ b/program/include/iniset.php @@ -68,11 +68,14 @@ spl_autoload_register('rcmail_autoload');  // backward compatybility (to be removed)  require_once INSTALL_PATH . 'program/include/bc.php'; -// load the UTF-8 portablity layer from Patchwork -if (!function_exists('iconv') || !function_exists('utf8_encode') || !extension_loaded('mbstring')) { -    \Patchwork\Utf8\Bootup::initAll(); +// load the UTF-8 portability layers from Patchwork +// don't load mbstring layer as it conflicts with Roundcube Framework (#1490280) +if (!function_exists('iconv')) { +    \Patchwork\Utf8\Bootup::initIconv(); +} +if (!function_exists('utf8_encode')) { +    \Patchwork\Utf8\Bootup::initUtf8Encode();  } -  /**   * PHP5 autoloader routine for dynamic class loading diff --git a/program/include/rcmail.php b/program/include/rcmail.php index 6e74560cb..2a154d9de 100644 --- a/program/include/rcmail.php +++ b/program/include/rcmail.php @@ -1793,8 +1793,9 @@ class rcmail extends rcube       * @param string $fallback       Fallback message label       * @param array  $fallback_args  Fallback message label arguments       * @param string $suffix         Message label suffix +     * @param array  $params         Additional parameters (type, prefix)       */ -    public function display_server_error($fallback = null, $fallback_args = null, $suffix = '') +    public function display_server_error($fallback = null, $fallback_args = null, $suffix = '', $params = array())      {          $err_code = $this->storage->get_error_code();          $res_code = $this->storage->get_response_code(); @@ -1815,8 +1816,8 @@ class rcmail extends rcube                  $error = 'errornoperm';              }              // try to detect full mailbox problem and display appropriate message -            // there can be e.g. "Quota exceeded" or "quotum would exceed" -            else if (stripos($err_str, 'quot') !== false && stripos($err_str, 'exceed') !== false) { +            // there can be e.g. "Quota exceeded" / "quotum would exceed" / "Over quota" +            else if (stripos($err_str, 'quot') !== false && preg_match('/exceed|over/i', $err_str)) {                  $error = 'erroroverquota';              }              else { @@ -1830,13 +1831,21 @@ class rcmail extends rcube          else if ($fallback) {              $error = $fallback;              $args  = $fallback_args; +            $params['prefix'] = false;          }          if ($error) {              if ($suffix && $this->text_exists($error . $suffix)) {                  $error .= $suffix;              } -            $this->output->show_message($error, 'error', $args); + +            $msg = $this->gettext(array('name' => $error, 'vars' => $args)); + +            if ($params['prefix'] && $fallback) { +                $msg = $this->gettext(array('name' => $fallback, 'vars' => $fallback_args)) . ' ' . $msg; +            } + +            $this->output->show_message($msg, $params['type'] ?: 'error');          }      } diff --git a/program/include/rcmail_install.php b/program/include/rcmail_install.php index 0d5fbc5da..e16177954 100644 --- a/program/include/rcmail_install.php +++ b/program/include/rcmail_install.php @@ -773,12 +773,8 @@ class rcmail_install     */    function update_db($version)    { -    system(INSTALL_PATH . "bin/updatedb.sh --package=roundcube" -      . " --version=" . escapeshellarg($version) -      . " --dir=" . INSTALL_PATH . "SQL" -      . " 2>&1", $result); - -    return !$result; +    return rcmail_utils::db_update(INSTALL_PATH . 'SQL', 'roundcube', $version, +        array('quiet' => true));    } diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index c6c43b532..365c403e4 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -584,7 +584,7 @@ EOF;          // read template file          if (!$path || ($templ = @file_get_contents($path)) === false) {              rcube::raise_error(array( -                'code' => 501, +                'code' => 404,                  'type' => 'php',                  'line' => __LINE__,                  'file' => __FILE__, diff --git a/program/include/rcmail_utils.php b/program/include/rcmail_utils.php new file mode 100644 index 000000000..50700b0e2 --- /dev/null +++ b/program/include/rcmail_utils.php @@ -0,0 +1,362 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | program/include/rcmail_utils.php                                      | + |                                                                       | + | This file is part of the Roundcube PHP suite                          | + | Copyright (C) 2005-2015 The Roundcube Dev Team                        | + |                                                                       | + | Licensed under the GNU General Public License version 3 or            | + | any later version with exceptions for skins & plugins.                | + | See the README file for a full license statement.                     | + |                                                                       | + | CONTENTS:                                                             | + |   Roundcube utilities                                                 | + |                                                                       | + +-----------------------------------------------------------------------+ + | Author: Thomas Bruederli <roundcube@gmail.com>                        | + | Author: Aleksander Machniak <alec@alec.pl>                            | + +-----------------------------------------------------------------------+ +*/ + +/** + * Roundcube utilities + * + * @package Webmail + * @subpackage Utils + */ +class rcmail_utils +{ +    public static $db; + +    /** +     * Initialize database object and connect +     * +     * @return rcube_db Database instance +     */ +    public static function db() +    { +        if (self::$db === null) { +            $rc = rcube::get_instance(); +            $db = rcube_db::factory($rc->config->get('db_dsnw')); + +            $db->set_debug((bool)$rc->config->get('sql_debug')); + +            // Connect to database +            $db->db_connect('w'); + +            if (!$db->is_connected()) { +                rcube::raise_error("Error connecting to database: " . $db->is_error(), false, true); +            } + +            self::$db = $db; +        } + +        return self::$db; +    } + +    /** +     * Initialize database schema +     * +     * @param string Directory with sql files +     */ +    public static function db_init($dir) +    { +        $db = self::db(); + +        $file = $dir . '/' . $db->db_provider . '.initial.sql'; +        if (!file_exists($file)) { +            rcube::raise_error("DDL file $file not found", false, true); +        } + +        echo "Creating database schema... "; + +        if ($sql = file_get_contents($file)) { +            if (!$db->exec_script($sql)) { +                $error = $db->is_error(); +            } +        } +        else { +            $error = "Unable to read file $file or it is empty"; +        } + +        if ($error) { +            echo "[FAILED]\n"; +            rcube::raise_error($error, false, true); +        } +        else { +            echo "[OK]\n"; +        } +    } + +    /** +     * Update database schema +     * +     * @param string Directory with sql files +     * @param string Component name +     * @param string Optional current version number +     * @param array  Parameters (errors, quiet) +     * +     * @return True on success, False on failure +     */ +    public static function db_update($dir, $package, $ver = null, $opts = array()) +    { +        // Check if directory exists +        if (!file_exists($dir)) { +            if ($opts['errors']) { +                rcube::raise_error("Specified database schema directory doesn't exist.", false, true); +            } +            return false; +        } + +        $db = self::db(); + +        // Read DB schema version from database (if 'system' table exists) +        if (in_array($db->table_name('system'), (array)$db->list_tables())) { +            $db->query("SELECT `value`" +                . " FROM " . $db->table_name('system', true) +                . " WHERE `name` = ?", +                $package . '-version'); + +            $row     = $db->fetch_array(); +            $version = preg_replace('/[^0-9]/', '', $row[0]); +        } + +        // DB version not found, but release version is specified +        if (!$version && $ver) { +            // Map old release version string to DB schema version +            // Note: This is for backward compat. only, do not need to be updated +            $map = array( +                '0.1-stable' => 1, +                '0.1.1'      => 2008030300, +                '0.2-alpha'  => 2008040500, +                '0.2-beta'   => 2008060900, +                '0.2-stable' => 2008092100, +                '0.2.1'      => 2008092100, +                '0.2.2'      => 2008092100, +                '0.3-stable' => 2008092100, +                '0.3.1'      => 2009090400, +                '0.4-beta'   => 2009103100, +                '0.4'        => 2010042300, +                '0.4.1'      => 2010042300, +                '0.4.2'      => 2010042300, +                '0.5-beta'   => 2010100600, +                '0.5'        => 2010100600, +                '0.5.1'      => 2010100600, +                '0.5.2'      => 2010100600, +                '0.5.3'      => 2010100600, +                '0.5.4'      => 2010100600, +                '0.6-beta'   => 2011011200, +                '0.6'        => 2011011200, +                '0.7-beta'   => 2011092800, +                '0.7'        => 2011111600, +                '0.7.1'      => 2011111600, +                '0.7.2'      => 2011111600, +                '0.7.3'      => 2011111600, +                '0.7.4'      => 2011111600, +                '0.8-beta'   => 2011121400, +                '0.8-rc'     => 2011121400, +                '0.8.0'      => 2011121400, +                '0.8.1'      => 2011121400, +                '0.8.2'      => 2011121400, +                '0.8.3'      => 2011121400, +                '0.8.4'      => 2011121400, +                '0.8.5'      => 2011121400, +                '0.8.6'      => 2011121400, +                '0.9-beta'   => 2012080700, +            ); + +            $version = $map[$ver]; +        } + +        // Assume last version before the 'system' table was added +        if (empty($version)) { +            $version = 2012080700; +        } + +        $dir .= '/' . $db->db_provider; +        if (!file_exists($dir)) { +            if ($opts['errors']) { +                rcube::raise_error("DDL Upgrade files for " . $db->db_provider . " driver not found.", false, true); +            } +            return false; +        } + +        $dh     = opendir($dir); +        $result = array(); + +        while ($file = readdir($dh)) { +            if (preg_match('/^([0-9]+)\.sql$/', $file, $m) && $m[1] > $version) { +                $result[] = $m[1]; +            } +        } +        sort($result, SORT_NUMERIC); + +        foreach ($result as $v) { +            if (!$opts['quiet']) { +                echo "Updating database schema ($v)... "; +            } + +            $error = self::db_update_schema($package, $v, "$dir/$v.sql"); + +            if ($error) { +                if (!$opts['quiet']) { +                    echo "[FAILED]\n"; +                } +                if ($opts['errors']) { +                    rcube::raise_error("Error in DDL upgrade $v: $error", false, true); +                } +                return false; +            } +            else if (!$opts['quiet']) { +                echo "[OK]\n"; +            } +        } + +        return true; +    } + +    /** +     * Run database update from a single sql file +     */ +    protected static function db_update_schema($package, $version, $file) +    { +        $db = self::db(); + +        // read DDL file +        if ($sql = file_get_contents($file)) { +            if (!$db->exec_script($sql)) { +                return $db->is_error(); +            } +        } + +        // escape if 'system' table does not exist +        if ($version < 2013011000) { +            return; +        } + +        $system_table = $db->table_name('system', true); + +        $db->query("UPDATE " . $system_table +            . " SET `value` = ?" +            . " WHERE `name` = ?", +            $version, $package . '-version'); + +        if (!$db->is_error() && !$db->affected_rows()) { +            $db->query("INSERT INTO " . $system_table +                ." (`name`, `value`) VALUES (?, ?)", +                $package . '-version', $version); +        } + +        return $db->is_error(); +    } + +    /** +     * Removes all deleted records older than X days +     * +     * @param int Number of days +     */ +    public static function db_clean($days) +    { +        // mapping for table name => primary key +        $primary_keys = array( +            'contacts'      => 'contact_id', +            'contactgroups' => 'contactgroup_id', +        ); + +        $db = self::db(); + +        $threshold = date('Y-m-d 00:00:00', time() - $days * 86400); + +        foreach (array('contacts','contactgroups','identities') as $table) { +            $sqltable = $db->table_name($table, true); + +            // also delete linked records +            // could be skipped for databases which respect foreign key constraints +            if ($db->db_provider == 'sqlite' && ($table == 'contacts' || $table == 'contactgroups')) { +                $pk           = $primary_keys[$table]; +                $memberstable = $db->table_name('contactgroupmembers'); + +                $db->query( +                    "DELETE FROM " . $db->quote_identifier($memberstable) +                    . " WHERE `$pk` IN (" +                        . "SELECT `$pk` FROM $sqltable" +                        . " WHERE `del` = 1 AND `changed` < ?" +                    . ")", +                    $threshold); + +                echo $db->affected_rows() . " records deleted from '$memberstable'\n"; +            } + +            // delete outdated records +            $db->query("DELETE FROM $sqltable WHERE `del` = 1 AND `changed` < ?", $threshold); + +            echo $db->affected_rows() . " records deleted from '$table'\n"; +        } +    } + +    /** +     * Reindex contacts +     */ +    public static function indexcontacts() +    { +        $db = self::db(); + +        // iterate over all users +        $sql_result = $db->query("SELECT `user_id` FROM " . $db->table_name('users', true) . " ORDER BY `user_id`"); +        while ($sql_result && ($sql_arr = $db->fetch_assoc($sql_result))) { +            echo "Indexing contacts for user " . $sql_arr['user_id'] . "...\n"; + +            $contacts = new rcube_contacts($db, $sql_arr['user_id']); +            $contacts->set_pagesize(9999); + +            $result = $contacts->list_records(); +            while ($result->count && ($row = $result->next())) { +                unset($row['words']); +                $contacts->update($row['ID'], $row); +            } +        } + +        echo "done.\n"; +    } + +    /** +     * Modify user preferences +     * +     * @param string Option name +     * @param string Option value +     * @param int    Optional user identifier +     */ +    public static function mod_pref($name, $value, $userid = null) +    { +        $db = self::db(); + +        if ($userid) { +            $query = '`user_id` = ' . intval($userid); +        } +        else { +            $query = '1=1'; +        } + +        // iterate over all users +        $sql_result = $db->query("SELECT * FROM " . $db->table_name('users', true) . " WHERE $query"); + +        while ($sql_result && ($sql_arr = $db->fetch_assoc($sql_result))) { +            echo "Updating prefs for user " . $sql_arr['user_id'] . "..."; + +            $user  = new rcube_user($sql_arr['user_id'], $sql_arr); +            $prefs = $old_prefs = $user->get_prefs(); + +            $prefs[$name] = $value; + +            if ($prefs != $old_prefs) { +                $user->save_prefs($prefs); +                echo "saved.\n"; +            } +            else { +                echo "nothing changed.\n"; +            } +        } +    } +}  | 
