From d7338a42033be12185614dc799c19aabeb00df4d Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Sun, 29 Aug 2021 11:06:04 +0200 Subject: [PATCH] Add option to purge deleted mails older than 30, 60 or 90 days (#5493) --- CHANGELOG.md | 1 + config/defaults.inc.php | 3 ++- program/actions/settings/index.php | 20 +++++++++++++++++-- program/actions/settings/prefs_save.php | 9 ++++++++- program/include/rcmail.php | 12 ++++++++++- program/lib/Roundcube/rcube_storage.php | 2 +- program/localization/en_US/labels.inc | 2 ++ .../Settings/Preferences/ServerTest.php | 16 +++++++++++---- 8 files changed, 55 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8b30423d..c9f87c06e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Dropped support for strftime-like format (with % sign) in date and time format configuration - Replace Endroid QrCode with BaconQrCode (#8173) - Support responses (snippets) in HTML format (#5315) +- Add option to purge deleted mails older than 30, 60 or 90 days (#5493) - Support displaying RTF content (including encapsulated HTML) from a TNEF attachment - Newmail_notifier: Improved the notification sound (#8155) - Add option to control links handling behavior on html to text conversion (#6485) diff --git a/config/defaults.inc.php b/config/defaults.inc.php index 044f38399..b5a1dc7fe 100644 --- a/config/defaults.inc.php +++ b/config/defaults.inc.php @@ -1317,7 +1317,8 @@ $config['layout'] = 'widescreen'; // Set to -1 if messages should not be marked as read $config['mail_read_time'] = 0; -// Clear Trash on logout +// Clear Trash on logout. Remove all messages or only older than N days. +// Supported values: false, true, 30, 60, 90. Default: false. $config['logout_purge'] = false; // Compact INBOX on logout diff --git a/program/actions/settings/index.php b/program/actions/settings/index.php index 8843b6b91..1bef45f82 100644 --- a/program/actions/settings/index.php +++ b/program/actions/settings/index.php @@ -1416,11 +1416,27 @@ class rcmail_action_settings_index extends rcmail_action } $field_id = 'rcmfd_logout_purge'; - $input = new html_checkbox(['name' => '_logout_purge', 'id' => $field_id, 'value' => 1]); + $select = new html_select([ + 'name' => '_logout_purge', + 'id' => $field_id, + 'class' => 'custom-select' + ]); + + $select->add($rcmail->gettext('never'), 'never'); + $select->add($rcmail->gettext('allmessages'), 'all'); + + foreach ([30, 60, 90] as $days) { + $select->add($rcmail->gettext(['name' => 'olderxdays', 'vars' => ['x' => $days]]), (string) $days); + } + + $purge = (string) $config['logout_purge']; + if (!is_numeric($purge)) { + $purge = empty($purge) ? 'never' : 'all'; + } $blocks['maintenance']['options']['logout_purge'] = [ 'title' => html::label($field_id, rcube::Q($rcmail->gettext('logoutclear'))), - 'content' => $input->show($config['logout_purge']?1:0), + 'content' => $select->show($purge), ]; } diff --git a/program/actions/settings/prefs_save.php b/program/actions/settings/prefs_save.php index cf18d4a43..41012c28a 100644 --- a/program/actions/settings/prefs_save.php +++ b/program/actions/settings/prefs_save.php @@ -134,7 +134,7 @@ class rcmail_action_settings_prefs_save extends rcmail_action 'skip_deleted' => isset($_POST['_skip_deleted']), 'flag_for_deletion' => isset($_POST['_flag_for_deletion']), 'delete_junk' => isset($_POST['_delete_junk']), - 'logout_purge' => isset($_POST['_logout_purge']), + 'logout_purge' => self::prefs_input('logout_purge', '/^(all|never|30|60|90)$/'), 'logout_expunge' => isset($_POST['_logout_expunge']), ]; @@ -235,6 +235,13 @@ class rcmail_action_settings_prefs_save extends rcmail_action $storage->set_special_folders($specials); + break; + + case 'server': + if (isset($a_user_prefs['logout_purge']) && !is_numeric($a_user_prefs['logout_purge'])) { + $a_user_prefs['logout_purge'] = $a_user_prefs['logout_purge'] !== 'never'; + } + break; } diff --git a/program/include/rcmail.php b/program/include/rcmail.php index bff3af68b..0eb85e239 100644 --- a/program/include/rcmail.php +++ b/program/include/rcmail.php @@ -1039,7 +1039,17 @@ class rcmail extends rcube $trash_mbox = $this->config->get('trash_mbox'); if ($logout_purge && !empty($trash_mbox)) { - $storage->clear_folder($trash_mbox); + $messages = '*'; + + if (is_numeric($logout_purge)) { + $now = new DateTime('now'); + $interval = new DateInterval('P' . intval($logout_purge) . 'D'); + + $index = $storage->search_once($trash_mbox, 'BEFORE ' . $now->sub($interval)->format('j-M-Y')); + $messages = $index->get_compressed(); + } + + $storage->delete_message($messages, $trash_mbox); } if ($logout_expunge) { diff --git a/program/lib/Roundcube/rcube_storage.php b/program/lib/Roundcube/rcube_storage.php index 810960220..1f73bfe0d 100644 --- a/program/lib/Roundcube/rcube_storage.php +++ b/program/lib/Roundcube/rcube_storage.php @@ -713,7 +713,7 @@ abstract class rcube_storage } /** - * Remove all messages in a folder.. + * Remove all messages in a folder. * * @param string $folder Folder name * diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc index 53d80df34..848c235dd 100644 --- a/program/localization/en_US/labels.inc +++ b/program/localization/en_US/labels.inc @@ -630,6 +630,8 @@ $labels['asattachment'] = 'as attachment'; $labels['replyallmode'] = 'Default action of [Reply all] button'; $labels['replyalldefault'] = 'reply to all'; $labels['replyalllist'] = 'reply to mailing list only (if found)'; +$labels['allmessages'] = 'all messages'; +$labels['olderxdays'] = 'older than $x days'; $labels['folder'] = 'Folder'; $labels['folders'] = 'Folders'; diff --git a/tests/Browser/Settings/Preferences/ServerTest.php b/tests/Browser/Settings/Preferences/ServerTest.php index be6ee65ad..94eac04f6 100644 --- a/tests/Browser/Settings/Preferences/ServerTest.php +++ b/tests/Browser/Settings/Preferences/ServerTest.php @@ -20,7 +20,7 @@ class ServerTest extends \Tests\Browser\TestCase 'flag_for_deletion' => false, 'skip_deleted' => false, 'delete_junk' => false, - 'logout_purge' => false, + 'logout_purge' => 'never', 'logout_expunge' => false, ]; @@ -74,8 +74,11 @@ class ServerTest extends \Tests\Browser\TestCase $browser->assertSeeIn('legend', 'Maintenance'); $browser->assertSeeIn('label[for=rcmfd_logout_purge]', 'Clear Trash on logout') - ->assertCheckboxState('_logout_purge', $this->settings['logout_purge']) - ->setCheckboxState('_logout_purge', $this->settings['logout_purge'] = !$this->settings['logout_purge']); + ->assertVisible('select[name=_logout_purge]') + ->assertSelected('select[name=_logout_purge]', $this->settings['logout_purge']); + + $this->settings['logout_purge'] = '30'; + $browser->select('select[name=_logout_purge]', '30'); $browser->assertSeeIn('label[for=rcmfd_logout_expunge]', 'Compact Inbox on logout') ->assertCheckboxState('_logout_expunge', $this->settings['logout_expunge']) @@ -97,7 +100,12 @@ class ServerTest extends \Tests\Browser\TestCase // Verify if every option has been updated $browser->withinFrame('#preferences-frame', function ($browser) { foreach ($this->settings as $key => $value) { - $browser->assertCheckboxState('_' . $key, $value); + if (is_bool($value)) { + $browser->assertCheckboxState('_' . $key, $value); + } + else { + $browser->assertValue("[name=_{$key}]", $value); + } } }); });