- Fix problems with subfolders of INBOX folder on some IMAP servers (#1487725)

- Fix handling of folders that doesn't belong to any namespace (#1487637)
release-0.6
alecpl 13 years ago
parent 4764079c6a
commit d08333ea57

@ -1,6 +1,8 @@
CHANGELOG Roundcube Webmail
===========================
- Fix problems with subfolders of INBOX folder on some IMAP servers (#1487725)
- Fix handling of folders that doesn't belong to any namespace (#1487637)
- Fix bug where messages were deleted instead moved to trash folder after Shift key was used (#1487902)
- Enable multiselection for attachments uploading in capable browsers (#1485969)
- Add possibility to change HTML editor configuration by skin

@ -97,9 +97,13 @@ GO
ALTER TABLE [dbo].[contacts] ALTER COLUMN [email] [varchar] (255) COLLATE Latin1_General_CI_AI NOT NULL
GO
-- Updates from version 0.5.1
-- Updates from version 0.5.2
ALTER TABLE [dbo].[contacts] ADD [words] [text] COLLATE Latin1_General_CI_AI NULL
GO
CREATE INDEX [IX_contactgroupmembers_contact_id] ON [dbo].[contactgroupmembers]([contact_id]) ON [PRIMARY]
CREATE INDEX [IX_contactgroupmembers_contact_id] ON [dbo].[contactgroupmembers]([contact_id]) ON [PRIMARY]
GO
DELETE FROM [dbo].[messages]
GO
DELETE FROM [dbo].[cache]
GO

@ -133,8 +133,11 @@ ALTER TABLE `contacts` MODIFY `email` varchar(255) NOT NULL;
TRUNCATE TABLE `messages`;
-- Updates from version 0.5.1
-- Updates from version 0.5.2
ALTER TABLE `contacts` ADD `words` TEXT NULL AFTER `vcard`;
ALTER TABLE `contacts` CHANGE `vcard` `vcard` LONGTEXT /*!40101 CHARACTER SET utf8 */ NULL DEFAULT NULL;
ALTER TABLE `contactgroupmembers` ADD INDEX `contactgroupmembers_contact_index` (`contact_id`);
TRUNCATE TABLE `messages`;
TRUNCATE TABLE `cache`;

@ -90,7 +90,10 @@ ALTER TABLE contacts ALTER email TYPE varchar(255);
TRUNCATE messages;
-- Updates from version 0.5.1
-- Updates from version 0.5.2
ALTER TABLE contacts ADD words TEXT NULL;
CREATE INDEX contactgroupmembers_contact_id_idx ON contactgroupmembers (contact_id);
TRUNCATE messages;
TRUNCATE cache;

@ -183,7 +183,7 @@ DROP TABLE contacts_tmp;
DELETE FROM messages;
-- Updates from version 0.5.1
-- Updates from version 0.5.2
CREATE TABLE contacts_tmp (
contact_id integer NOT NULL PRIMARY KEY,
@ -221,4 +221,5 @@ CREATE INDEX ix_contacts_user_id ON contacts(user_id, email);
DROP TABLE contacts_tmp;
DELETE FROM messages;
DELETE FROM cache;
CREATE INDEX ix_contactgroupmembers_contact_id ON contactgroupmembers (contact_id);

@ -48,3 +48,6 @@ Post-Upgrade Activities
-----------------------
1. Check .htaccess settings (some php settings could become required)
2. If you're using build-in addressbook, run indexing script /bin/indexcontacts.sh.
3. When upgrading from version older than 0.6-beta you should make sure
your folder settings contain namespace prefix. For example Courier users
should add INBOX. prefix to folder names in main configuration file.

@ -374,21 +374,26 @@ $rcmail_config['date_format'] = 'Y-m-d';
// store draft message is this mailbox
// leave blank if draft messages should not be stored
// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
$rcmail_config['drafts_mbox'] = 'Drafts';
// store spam messages in this mailbox
// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
$rcmail_config['junk_mbox'] = 'Junk';
// store sent message is this mailbox
// leave blank if sent messages should not be stored
// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
$rcmail_config['sent_mbox'] = 'Sent';
// move messages to this folder when deleting them
// leave blank if they should be deleted directly
// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
$rcmail_config['trash_mbox'] = 'Trash';
// display these folders separately in the mailbox list.
// these folders will also be displayed with localized names
// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
$rcmail_config['default_imap_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Trash');
// automatically create the above listed default folders on login

@ -361,7 +361,7 @@ echo $text_sentmbox->show($RCI->getprop('sent_mbox'));
?>
<div>Store sent messages in this folder</div>
<p class="hint">Leave blank if sent messages should not be stored</p>
<p class="hint">Leave blank if sent messages should not be stored. Note: folder must include namespace prefix if any.</p>
</dd>
<dt class="propname">trash_mbox</dt>
@ -374,7 +374,7 @@ echo $text_trashmbox->show($RCI->getprop('trash_mbox'));
?>
<div>Move messages to this folder when deleting them</div>
<p class="hint">Leave blank if they should be deleted directly</p>
<p class="hint">Leave blank if they should be deleted directly. Note: folder must include namespace prefix if any.</p>
</dd>
<dt class="propname">drafts_mbox</dt>
@ -387,7 +387,7 @@ echo $text_draftsmbox->show($RCI->getprop('drafts_mbox'));
?>
<div>Store draft messages in this folder</div>
<p class="hint">Leave blank if they should not be stored</p>
<p class="hint">Leave blank if they should not be stored. Note: folder must include namespace prefix if any.</p>
</dd>
<dt class="propname">junk_mbox</dt>
@ -399,6 +399,10 @@ echo $text_junkmbox->show($RCI->getprop('junk_mbox'));
?>
<div>Store spam messages in this folder</div>
<p class="hint">Note: folder must include namespace prefix if any.</p>
</dd>
</dd>
</dl>
</fieldset>

@ -1228,17 +1228,20 @@ function rcmail_mailbox_select($p = array())
else
$list = $RCMAIL->imap->list_mailboxes();
foreach ($list as $folder)
$delimiter = $RCMAIL->imap->get_hierarchy_delimiter();
foreach ($list as $folder) {
if (empty($p['exceptions']) || !in_array($folder, $p['exceptions']))
rcmail_build_folder_tree($a_mailboxes, $folder, $RCMAIL->imap->get_hierarchy_delimiter());
rcmail_build_folder_tree($a_mailboxes, $folder, $delimiter);
}
$select = new html_select($p);
if ($p['noselection'])
$select->add($p['noselection'], '');
rcmail_render_folder_tree_select($a_mailboxes, $mbox, $p['maxlength'], $select, $p['realnames']);
return $select;
}
@ -1252,6 +1255,17 @@ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='')
{
global $RCMAIL;
// Handle namespace prefix
$prefix = '';
if (!$path) {
$n_folder = $folder;
$folder = $RCMAIL->imap->mod_mailbox($folder);
if ($n_folder != $folder) {
$prefix = substr($n_folder, 0, -strlen($folder));
}
}
$pos = strpos($folder, $delm);
if ($pos !== false) {
@ -1272,14 +1286,14 @@ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='')
$virtual = false;
}
$path .= $currentFolder;
// Check \Noselect option (if options are in cache)
if (!$virtual && ($opts = $RCMAIL->imap->mailbox_options($path))) {
$virtual = in_array('\\Noselect', $opts);
}
$path .= $prefix.$currentFolder;
if (!isset($arrFolders[$currentFolder])) {
// Check \Noselect option (if options are in cache)
if (!$virtual && ($opts = $RCMAIL->imap->mailbox_options($path))) {
$virtual = in_array('\\Noselect', $opts);
}
$arrFolders[$currentFolder] = array(
'id' => $path,
'name' => rcube_charset_convert($currentFolder, 'UTF7-IMAP'),

@ -735,9 +735,13 @@ class rcmail
// user already registered -> update user's record
if (is_object($user)) {
// fix some old settings according to namespace prefix
$this->fix_namespace_settings($user);
// create default folders on first login
if (!$user->data['last_login'] && $config['create_default_folders'])
$this->imap->create_default_folders();
// update last login timestamp
$user->touch();
}
// create new system user
@ -1453,4 +1457,104 @@ class rcmail
return strtr($this->action, '-', '_') . '.inc';
}
/**
* Fixes some user preferences according to namespace handling change.
* Old Roundcube versions were using folder names with removed namespace prefix.
* Now we need to add the prefix on servers where personal namespace has prefix.
*
* @param rcube_user $user User object
*/
private function fix_namespace_settings($user)
{
$prefix = $this->imap->get_namespace('prefix');
$prefix_len = strlen($prefix);
if (!$prefix_len)
return;
$prefs = $user->get_prefs();
if (empty($prefs) || $prefs['namespace_fixed'])
return;
// Build namespace prefix regexp
$ns = $this->imap->get_namespace();
$regexp = array();
foreach ($ns as $entry) {
if (!empty($entry)) {
foreach ($entry as $item) {
if (strlen($item[0])) {
$regexp[] = preg_quote($item[0], '/');
}
}
}
}
$regexp = '/^('. implode('|', $regexp).')/';
// Fix preferences
$opts = array('drafts_mbox', 'junk_mbox', 'sent_mbox', 'trash_mbox', 'archive_mbox');
foreach ($opts as $opt) {
if ($value = $prefs[$opt]) {
if ($value != 'INBOX' && !preg_match($regexp, $value)) {
$prefs[$opt] = $prefix.$value;
}
}
}
if (!empty($prefs['default_imap_folders'])) {
foreach ($prefs['default_imap_folders'] as $idx => $name) {
if ($name != 'INBOX' && !preg_match($regexp, $name)) {
$prefs['default_imap_folders'][$idx] = $prefix.$name;
}
}
}
if (!empty($prefs['search_mods'])) {
$folders = array();
foreach ($prefs['search_mods'] as $idx => $value) {
if ($idx != 'INBOX' && $idx != '*' && !preg_match($regexp, $idx)) {
$idx = $prefix.$idx;
}
$folders[$idx] = $value;
}
$prefs['search_mods'] = $folders;
}
if (!empty($prefs['message_threading'])) {
$folders = array();
foreach ($prefs['message_threading'] as $idx => $value) {
if ($idx != 'INBOX' && !preg_match($regexp, $idx)) {
$idx = $prefix.$idx;
}
$folders[$prefix.$idx] = $value;
}
$prefs['message_threading'] = $folders;
}
if (!empty($prefs['collapsed_folders'])) {
$folders = explode('&&', $prefs['collapsed_folders']);
$count = count($folders);
$folders_str = '';
if ($count) {
$folders[0] = substr($folders[0], 1);
$folders[$count-1] = substr($folders[$count-1], 0, -1);
}
foreach ($folders as $value) {
if ($value != 'INBOX' && !preg_match($regexp, $value)) {
$value = $prefix.$value;
}
$folders_str .= '&'.$value.'&';
}
$prefs['collapsed_folders'] = $folders_str;
}
$prefs['namespace_fixed'] = true;
// save updated preferences and reset imap settings (default folders)
$user->save_prefs($prefs);
$this->set_imap_prop();
}
}

File diff suppressed because it is too large Load Diff

@ -130,7 +130,7 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage',
'copy', 'move', 'quota');
$OUTPUT->set_pagetitle(rcmail_localize_foldername($mbox_name));
$OUTPUT->set_pagetitle(rcmail_localize_foldername($IMAP->mod_mailbox($mbox_name)));
}

@ -54,6 +54,20 @@ function rcube_folder_form($attrib)
else {
$options = array();
$path = $parent_imap;
// allow creating subfolders of INBOX folder
if ($path == 'INBOX') {
$path = $RCMAIL->imap->mod_mailbox($path, 'in');
}
}
// remove personal namespace prefix
if (strlen($path)) {
$path_id = $path;
$path = $RCMAIL->imap->mod_mailbox($path.$delimiter);
if ($path[strlen($path)-1] == $delimiter) {
$path = substr($path, 0, -1);
}
}
$form = array();
@ -93,15 +107,15 @@ function rcube_folder_form($attrib)
);
if (strlen($path)) {
if ($options['norename'] || $options['namespace'] != 'personal') {
if (!empty($options) && ($options['norename'] || $options['namespace'] != 'personal')) {
// prevent user from moving folder
$hidden_path = new html_hiddenfield(array('name' => '_parent', 'value' => $path));
$form['props']['fieldsets']['location']['content']['name']['value'] .= $hidden_path->show();
}
else {
$radio1 = new html_radiobutton(array('name' => '_parent', 'value' => ''));
$radio2 = new html_radiobutton(array('name' => '_parent', 'value' => $path));
$selected = isset($_POST['_parent']) ? $_POST['_parent'] : $path;
$radio2 = new html_radiobutton(array('name' => '_parent', 'value' => $path_id));
$selected = isset($_POST['_parent']) ? $_POST['_parent'] : $path_id;
$html_path = str_replace($delimiter, ' &raquo; ', rcmail_localize_folderpath($path));

@ -126,12 +126,11 @@ else if ($RCMAIL->action == 'rename-folder')
// subfolders
for ($x=sizeof($folderlist)-1; $x>=0; $x--) {
if (preg_match($regexp, $folderlist[$x])) {
$oldfolder = $oldname . $delimiter . preg_replace($regexp, '', $folderlist[$x]);
$foldersplit = explode($delimiter, $folderlist[$x]);
$level = count($foldersplit) - 1;
$oldfolder = $oldname . $delimiter . preg_replace($regexp, '', $folderlist[$x]);
$foldersplit = explode($delimiter, $IMAP->mod_mailbox($folderlist[$x]));
$level = count($foldersplit) - 1;
$display_rename = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $level)
. rcube_charset_convert($foldersplit[$level], 'UTF7-IMAP');
$before = isset($folderlist[$x+1]) ? rcube_charset_convert($folderlist[$x+1], 'UTF7-IMAP') : false;
$OUTPUT->command('replace_folder_row', rcube_charset_convert($oldfolder, 'UTF7-IMAP'),
@ -139,14 +138,14 @@ else if ($RCMAIL->action == 'rename-folder')
}
}
$index = array_search($name, $folderlist);
$name = $IMAP->mod_mailbox($name);
$foldersplit = explode($delimiter, $name);
$level = count($foldersplit) - 1;
$level = count($foldersplit) - 1;
$display_rename = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $level) . rcube_charset_convert($foldersplit[$level], 'UTF7-IMAP');
$index = array_search($name, $folderlist);
$before = $index !== false && isset($folderlist[$index+1]) ? rcube_charset_convert($folderlist[$index+1], 'UTF7-IMAP') : false;
$before = $index !== false && isset($folderlist[$index+1]) ? rcube_charset_convert($folderlist[$index+1], 'UTF7-IMAP') : false;
$OUTPUT->command('replace_folder_row', $oldname_utf8,
rcube_charset_convert($name, 'UTF7-IMAP'), $display_rename, $before);
$OUTPUT->command('replace_folder_row', $oldname_utf8, $name_utf8, $display_rename, $before);
}
else if (!$rename) {
rcmail_display_server_error('errorsaving');
@ -243,13 +242,15 @@ function rcube_subscription_form($attrib)
// pre-process folders list
foreach ($a_unsubscribed as $i => $folder) {
$foldersplit = explode($delimiter, $folder);
$name = rcube_charset_convert(array_pop($foldersplit), 'UTF7-IMAP');
$folder_id = $folder;
$folder = $IMAP->mod_mailbox($folder);
$foldersplit = explode($delimiter, $folder);
$name = rcube_charset_convert(array_pop($foldersplit), 'UTF7-IMAP');
$parent_folder = join($delimiter, $foldersplit);
$level = count($foldersplit);
$level = count($foldersplit);
// add any necessary "virtual" parent folders
if ($parent_folder && !$seen[$parent_folder]) {
if ($parent_folder && !isset($seen[$parent_folder])) {
for ($i=1; $i<=$level; $i++) {
$ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i));
if ($ancestor_folder && !$seen[$ancestor_folder]++) {
@ -263,11 +264,16 @@ function rcube_subscription_form($attrib)
}
}
}
// Handle properly INBOX.INBOX situation
if (isset($seen[$folder])) {
continue;
}
$seen[$folder]++;
$list_folders[] = array(
'id' => $folder,
'id' => $folder_id,
'name' => $name,
'level' => $level,
);
@ -354,11 +360,11 @@ function rcmail_rename_folder($oldname, $newname)
foreach ($a_threaded as $key => $val) {
if ($key == $oldname) {
unset($a_threaded[$key]);
$a_threaded[$newname] = true;
$a_threaded[$newname] = true;
}
else if (preg_match($oldprefix, $key)) {
unset($a_threaded[$key]);
$a_threaded[preg_replace($oldprefix, $newname.$delimiter, $key)] = true;
$a_threaded[preg_replace($oldprefix, $newname.$delimiter, $key)] = true;
}
}
$RCMAIL->user->save_prefs(array('message_threading' => $a_threaded));

@ -65,6 +65,9 @@ else {
else if (strlen($path)) {
$name_imap = $path . $delimiter . $name_imap;
}
else {
$name_imap = $RCMAIL->imap->mod_mailbox($name, 'in');
}
$folder['name'] = $name_imap;
$folder['oldname'] = $old_imap;

Loading…
Cancel
Save