diff options
Diffstat (limited to 'program/lib/Roundcube')
-rw-r--r-- | program/lib/Roundcube/rcube.php | 12 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_addressbook.php | 7 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_config.php | 6 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_contacts.php | 44 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_imap.php | 46 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_imap_cache.php | 6 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_ldap.php | 17 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_plugin_api.php | 1 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_storage.php | 12 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_utils.php | 31 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_washtml.php | 9 |
11 files changed, 156 insertions, 35 deletions
diff --git a/program/lib/Roundcube/rcube.php b/program/lib/Roundcube/rcube.php index e0fa22c3c..331b57e96 100644 --- a/program/lib/Roundcube/rcube.php +++ b/program/lib/Roundcube/rcube.php @@ -642,10 +642,11 @@ class rcube /** * Load a localization package * - * @param string Language ID - * @param array Additional text labels/messages + * @param string $lang Language ID + * @param array $add Additional text labels/messages + * @param array $merge Additional text labels/messages to merge */ - public function load_language($lang = null, $add = array()) + public function load_language($lang = null, $add = array(), $merge = array()) { $lang = $this->language_prop(($lang ? $lang : $_SESSION['language'])); @@ -685,6 +686,11 @@ class rcube if (is_array($add) && !empty($add)) { $this->texts += $add; } + + // merge additional texts (from plugin) + if (is_array($merge) && !empty($merge)) { + $this->texts = array_merge($this->texts, $merge); + } } diff --git a/program/lib/Roundcube/rcube_addressbook.php b/program/lib/Roundcube/rcube_addressbook.php index 886f65cb9..4d9fa3db1 100644 --- a/program/lib/Roundcube/rcube_addressbook.php +++ b/program/lib/Roundcube/rcube_addressbook.php @@ -281,7 +281,8 @@ abstract class rcube_addressbook * @param array Assoziative array with save data * Keys: Field name with optional section in the form FIELD:SECTION * Values: Field value. Can be either a string or an array of strings for multiple values - * @return boolean True on success, False on error + * + * @return mixed On success if ID has been changed returns ID, otherwise True, False on error */ function update($id, $save_cols) { @@ -311,8 +312,10 @@ abstract class rcube_addressbook /** * Mark all records in database as deleted + * + * @param bool $with_groups Remove also groups */ - function delete_all() + function delete_all($with_groups = false) { /* empty for read-only address books */ } diff --git a/program/lib/Roundcube/rcube_config.php b/program/lib/Roundcube/rcube_config.php index 04b914c3d..0352e4772 100644 --- a/program/lib/Roundcube/rcube_config.php +++ b/program/lib/Roundcube/rcube_config.php @@ -373,7 +373,11 @@ class rcube_config */ public function all() { - return $this->prop; + $rcube = rcube::get_instance(); + $plugin = $rcube->plugins->exec_hook('config_get', array( + 'name' => '*', 'result' => $this->prop)); + + return $plugin['result']; } /** diff --git a/program/lib/Roundcube/rcube_contacts.php b/program/lib/Roundcube/rcube_contacts.php index 2e03352bf..d215760cf 100644 --- a/program/lib/Roundcube/rcube_contacts.php +++ b/program/lib/Roundcube/rcube_contacts.php @@ -626,7 +626,7 @@ class rcube_contacts extends rcube_addressbook } } - $save_data = $this->convert_save_data($save_data); + $save_data = $this->convert_save_data($save_data); $a_insert_cols = $a_insert_values = array(); foreach ($save_data as $col => $value) { @@ -655,13 +655,14 @@ class rcube_contacts extends rcube_addressbook * * @param mixed Record identifier * @param array Assoziative array with save data + * * @return boolean True on success, False on error */ function update($id, $save_cols) { - $updated = false; + $updated = false; $write_sql = array(); - $record = $this->get_record($id, true); + $record = $this->get_record($id, true); $save_cols = $this->convert_save_data($save_cols, $record); foreach ($save_cols as $col => $value) { @@ -683,7 +684,7 @@ class rcube_contacts extends rcube_addressbook $this->result = null; // clear current result (from get_record()) } - return $updated; + return $updated ? true : false; } @@ -812,16 +813,30 @@ class rcube_contacts extends rcube_addressbook /** * Remove all records from the database + * + * @param bool $with_groups Remove also groups + * + * @return int Number of removed records */ - function delete_all() + function delete_all($with_groups = false) { $this->cache = null; - $this->db->query("UPDATE ".$this->db->table_name($this->db_name). - " SET del=1, changed=".$this->db->now(). - " WHERE user_id = ?", $this->user_id); + $this->db->query("UPDATE " . $this->db->table_name($this->db_name) + . " SET del = 1, changed = " . $this->db->now() + . " WHERE user_id = ?", $this->user_id); - return $this->db->affected_rows(); + $count = $this->db->affected_rows(); + + if ($with_groups) { + $this->db->query("UPDATE " . $this->db->table_name($this->db_groups) + . " SET del = 1, changed = " . $this->db->now() + . " WHERE user_id = ?", $this->user_id); + + $count += $this->db->affected_rows(); + } + + return $count; } @@ -860,11 +875,11 @@ class rcube_contacts extends rcube_addressbook function delete_group($gid) { // flag group record as deleted - $sql_result = $this->db->query( - "UPDATE ".$this->db->table_name($this->db_groups). - " SET del=1, changed=".$this->db->now(). - " WHERE contactgroup_id=?". - " AND user_id=?", + $this->db->query( + "UPDATE " . $this->db->table_name($this->db_groups) + . " SET del = 1, changed = " . $this->db->now() + . " WHERE contactgroup_id = ?" + . " AND user_id = ?", $gid, $this->user_id ); @@ -873,7 +888,6 @@ class rcube_contacts extends rcube_addressbook return $this->db->affected_rows(); } - /** * Rename a specific contact group * diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php index fdda1d4b2..4c3bf6fcd 100644 --- a/program/lib/Roundcube/rcube_imap.php +++ b/program/lib/Roundcube/rcube_imap.php @@ -680,6 +680,41 @@ class rcube_imap extends rcube_storage /** + * Public method for listing message flags + * + * @param string $folder Folder name + * @param array $uids Message UIDs + * @param int $mod_seq Optional MODSEQ value (of last flag update) + * + * @return array Indexed array with message flags + */ + public function list_flags($folder, $uids, $mod_seq = null) + { + if (!strlen($folder)) { + $folder = $this->folder; + } + + if (!$this->check_connection()) { + return array(); + } + + // @TODO: when cache was synchronized in this request + // we might already have asked for flag updates, use it. + + $flags = $this->conn->fetch($folder, $uids, true, array('FLAGS'), $mod_seq); + $result = array(); + + if (!empty($flags)) { + foreach ($flags as $message) { + $result[$message->uid] = $message->flags; + } + } + + return $result; + } + + + /** * Public method for listing headers * * @param string $folder Folder name @@ -2121,7 +2156,7 @@ class rcube_imap extends rcube_storage // convert charset (if text or message part) if ($body && preg_match('/^(text|message)$/', $o_part->ctype_primary)) { // Remove NULL characters if any (#1486189) - if (strpos($body, "\x00") !== false) { + if ($formatted && strpos($body, "\x00") !== false) { $body = str_replace("\x00", '', $body); } @@ -2843,12 +2878,21 @@ class rcube_imap extends rcube_storage /** * Filter the given list of folders according to access rights + * + * For performance reasons we assume user has full rights + * on all personal folders. */ protected function filter_rights($a_folders, $rights) { $regex = '/('.$rights.')/'; + foreach ($a_folders as $idx => $folder) { + if ($this->folder_namespace($folder) == 'personal') { + continue; + } + $myrights = join('', (array)$this->my_rights($folder)); + if ($myrights !== null && !preg_match($regex, $myrights)) { unset($a_folders[$idx]); } diff --git a/program/lib/Roundcube/rcube_imap_cache.php b/program/lib/Roundcube/rcube_imap_cache.php index a8166545e..0c3edeaad 100644 --- a/program/lib/Roundcube/rcube_imap_cache.php +++ b/program/lib/Roundcube/rcube_imap_cache.php @@ -1250,10 +1250,8 @@ class rcube_imap_cache unset($msg->replaces); - if (is_array($msg->structure->parts)) { - foreach ($msg->structure->parts as $part) { - $this->message_object_prepare($part, $size); - } + if (is_object($msg->structure)) { + $this->message_object_prepare($msg->structure, $size); } if (is_array($msg->parts)) { diff --git a/program/lib/Roundcube/rcube_ldap.php b/program/lib/Roundcube/rcube_ldap.php index b733e2465..0da3e2c87 100644 --- a/program/lib/Roundcube/rcube_ldap.php +++ b/program/lib/Roundcube/rcube_ldap.php @@ -1324,8 +1324,10 @@ class rcube_ldap extends rcube_addressbook /** * Remove all contact records + * + * @param bool $with_groups Delete also groups if enabled */ - function delete_all() + function delete_all($with_groups = false) { // searching for contact entries $dn_list = $this->ldap->list_entries($this->base_dn, $this->prop['filter'] ? $this->prop['filter'] : '(objectclass=*)'); @@ -1336,6 +1338,16 @@ class rcube_ldap extends rcube_addressbook } $this->delete($dn_list); } + + if ($with_groups && $this->groups && ($groups = $this->_fetch_groups()) && count($groups)) { + foreach ($groups as $group) { + $this->ldap->delete($group['dn']); + } + + if ($this->cache) { + $this->cache->remove('groups'); + } + } } /** @@ -1606,11 +1618,12 @@ class rcube_ldap extends rcube_addressbook // special case: list groups from 'group_filters' config if ($vlv_page === null && !empty($this->prop['group_filters'])) { $groups = array(); + $rcube = rcube::get_instance(); // list regular groups configuration as special filter if (!empty($this->prop['groups']['filter'])) { $id = '__groups__'; - $groups[$id] = array('ID' => $id, 'name' => rcube_label('groups'), 'virtual' => true) + $this->prop['groups']; + $groups[$id] = array('ID' => $id, 'name' => $rcube->gettext('groups'), 'virtual' => true) + $this->prop['groups']; } foreach ($this->prop['group_filters'] as $id => $prop) { diff --git a/program/lib/Roundcube/rcube_plugin_api.php b/program/lib/Roundcube/rcube_plugin_api.php index ad012552d..461c3cc07 100644 --- a/program/lib/Roundcube/rcube_plugin_api.php +++ b/program/lib/Roundcube/rcube_plugin_api.php @@ -284,6 +284,7 @@ class rcube_plugin_api $composer = INSTALL_PATH . "/plugins/$plugin_name/composer.json"; if (file_exists($composer) && ($json = @json_decode(file_get_contents($composer), true))) { list($info['vendor'], $info['name']) = explode('/', $json['name']); + $info['version'] = $json['version']; $info['license'] = $json['license']; if ($license_uri = $license_uris[$info['license']]) $info['license_uri'] = $license_uri; diff --git a/program/lib/Roundcube/rcube_storage.php b/program/lib/Roundcube/rcube_storage.php index e697b2c73..ca65af1cb 100644 --- a/program/lib/Roundcube/rcube_storage.php +++ b/program/lib/Roundcube/rcube_storage.php @@ -360,6 +360,18 @@ abstract class rcube_storage /** + * Public method for listing message flags + * + * @param string $folder Folder name + * @param array $uids Message UIDs + * @param int $mod_seq Optional MODSEQ value + * + * @return array Indexed array with message flags + */ + abstract function list_flags($folder, $uids, $mod_seq = null); + + + /** * Public method for listing headers. * * @param string $folder Folder name diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php index 27a618d83..c48cd80e8 100644 --- a/program/lib/Roundcube/rcube_utils.php +++ b/program/lib/Roundcube/rcube_utils.php @@ -622,6 +622,10 @@ class rcube_utils */ public static function parse_host($name, $host = '') { + if (!is_string($name)) { + return $name; + } + // %n - host $n = preg_replace('/:\d+$/', '', $_SERVER['SERVER_NAME']); // %t - host name without first part, e.g. %n=mail.domain.tld, %t=domain.tld @@ -642,8 +646,7 @@ class rcube_utils } } - $name = str_replace(array('%n', '%t', '%d', '%h', '%z', '%s'), array($n, $t, $d, $h, $z, $s[2]), $name); - return $name; + return str_replace(array('%n', '%t', '%d', '%h', '%z', '%s'), array($n, $t, $d, $h, $z, $s[2]), $name); } @@ -680,9 +683,17 @@ class rcube_utils */ public static function remote_addr() { - foreach (array('HTTP_X_FORWARDED_FOR','HTTP_X_REAL_IP','REMOTE_ADDR') as $prop) { - if (!empty($_SERVER[$prop])) - return $_SERVER[$prop]; + if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $hosts = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2); + return $hosts[0]; + } + + if (!empty($_SERVER['HTTP_X_REAL_IP'])) { + return $_SERVER['HTTP_X_REAL_IP']; + } + + if (!empty($_SERVER['REMOTE_ADDR'])) { + return $_SERVER['REMOTE_ADDR']; } return ''; @@ -912,10 +923,20 @@ class rcube_utils * * @param string Input string (UTF-8) * @param boolean True to return list of words as array + * * @return mixed Normalized string or a list of normalized tokens */ public static function normalize_string($str, $as_array = false) { + // replace 4-byte unicode characters with '?' character, + // these are not supported in default utf-8 charset on mysql, + // the chance we'd need them in searching is very low + $str = preg_replace('/(' + . '\xF0[\x90-\xBF][\x80-\xBF]{2}' + . '|[\xF1-\xF3][\x80-\xBF]{3}' + . '|\xF4[\x80-\x8F][\x80-\xBF]{2}' + . ')/', '?', $str); + // split by words $arr = self::tokenize_string($str); diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php index e7467545f..9cf3c6222 100644 --- a/program/lib/Roundcube/rcube_washtml.php +++ b/program/lib/Roundcube/rcube_washtml.php @@ -455,7 +455,7 @@ class rcube_washtml } // fix (unknown/malformed) HTML tags before "wash" - $html = preg_replace_callback('/(<(?!\!)[\/]*)([^\s>]+)/', array($this, 'html_tag_callback'), $html); + $html = preg_replace_callback('/(<(?!\!)[\/]*)([^\s>]+)([^>]*)/', array($this, 'html_tag_callback'), $html); // Remove invalid HTML comments (#1487759) // Don't remove valid conditional comments @@ -479,7 +479,12 @@ class rcube_washtml '/[^a-z0-9_\[\]\!-]/i', // forbidden characters ), '', $tagname); - return $matches[1] . $tagname; + // fix invalid closing tags - remove any attributes (#1489446) + if ($matches[1] == '</') { + $matches[3] = ''; + } + + return $matches[1] . $tagname . $matches[3]; } /** |