From 5802e08e4833c0567f6e2f7d7a50ece521dc3f6e Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Thu, 08 Oct 2015 05:33:53 -0400 Subject: [PATCH] Mail messages searching with predefined date interval (T103) --- skins/larry/templates/mail.html | 2 CHANGELOG | 1 program/steps/mail/search.inc | 41 +++++++++++-- skins/classic/templates/mail.html | 2 program/steps/mail/func.inc | 54 ++++++++++++----- program/localization/en_US/labels.inc | 6 ++ skins/larry/styles.css | 6 ++ program/js/app.js | 20 ++++++ skins/larry/mail.css | 3 + 9 files changed, 112 insertions(+), 23 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 52a6c1b..444447d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Implemented mail messages searching with predefined date interval - PGP encryption support via Mailvelope integration - PGP encryption support via Enigma plugin - PHP7 compatibility fixes (#1490416) diff --git a/program/js/app.js b/program/js/app.js index 8a9712f..46e0857 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -4896,6 +4896,9 @@ if (filter) url._filter = filter; + if (this.gui_objects.search_interval) + url._interval = $(this.gui_objects.search_interval).val(); + if (search) { url._q = search; @@ -4932,6 +4935,9 @@ if (this.gui_objects.qsearchbox) this.gui_objects.qsearchbox.value = ''; + if (this.gui_objects.search_interval) + $(this.gui_objects.search_interval).val(''); + if (this.env.qsearch) this.abort_request(this.env.qsearch); @@ -4961,6 +4967,20 @@ } }; + this.set_searchinterval = function(interval) + { + var old = this.env.search_interval; + this.env.search_interval = interval; + + // re-send search query with new interval + if (interval != old && this.env.search_request) { + if (!this.qsearch(this.gui_objects.qsearchbox.value) && this.env.search_filter && this.env.search_filter != 'ALL') + this.filter_mailbox(this.env.search_filter); + if (interval) + this.select_folder(this.env.mailbox, '', true); + } + }; + this.set_searchmods = function(mods) { var mbox = this.env.mailbox, diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc index 08f6a60..01a079e 100644 --- a/program/localization/en_US/labels.inc +++ b/program/localization/en_US/labels.inc @@ -225,6 +225,12 @@ $labels['currentfolder'] = 'Current folder'; $labels['subfolders'] = 'This and subfolders'; $labels['allfolders'] = 'All folders'; +$labels['searchinterval-1W'] = 'older than a week'; +$labels['searchinterval-1M'] = 'older than a month'; +$labels['searchinterval-1Y'] = 'older than a year'; +$labels['searchinterval1W'] = 'younger than a week'; +$labels['searchinterval1M'] = 'younger than a month'; +$labels['searchinterval1Y'] = 'younger than a year'; $labels['openinextwin'] = 'Open in new window'; $labels['emlsave'] = 'Download (.eml)'; diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index f456945..d949cf6 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -125,6 +125,7 @@ 'messagecontentframe' => 'rcmail_messagecontent_frame', 'messageimportform' => 'rcmail_message_import_form', 'searchfilter' => 'rcmail_search_filter', + 'searchinterval' => 'rcmail_search_interval', 'searchform' => array($OUTPUT, 'search_form'), )); @@ -2028,8 +2029,9 @@ { global $RCMAIL; - if (!strlen($attrib['id'])) + if (!strlen($attrib['id'])) { $attrib['id'] = 'rcmlistfilter'; + } $attrib['onchange'] = rcmail_output::JS_OBJECT_NAME.'.filter_mailbox(this.value)'; @@ -2043,27 +2045,45 @@ $attachment .= ' HEADER Content-Type ' . rcube_imap_generic::escape($type); } - $select_filter = new html_select($attrib); - $select_filter->add($RCMAIL->gettext('all'), 'ALL'); - $select_filter->add($RCMAIL->gettext('unread'), 'UNSEEN'); - $select_filter->add($RCMAIL->gettext('flagged'), 'FLAGGED'); - $select_filter->add($RCMAIL->gettext('unanswered'), 'UNANSWERED'); + $select = new html_select($attrib); + $select->add($RCMAIL->gettext('all'), 'ALL'); + $select->add($RCMAIL->gettext('unread'), 'UNSEEN'); + $select->add($RCMAIL->gettext('flagged'), 'FLAGGED'); + $select->add($RCMAIL->gettext('unanswered'), 'UNANSWERED'); if (!$RCMAIL->config->get('skip_deleted')) { - $select_filter->add($RCMAIL->gettext('deleted'), 'DELETED'); - $select_filter->add($RCMAIL->gettext('undeleted'), 'UNDELETED'); + $select->add($RCMAIL->gettext('deleted'), 'DELETED'); + $select->add($RCMAIL->gettext('undeleted'), 'UNDELETED'); } - $select_filter->add($RCMAIL->gettext('withattachment'), $attachment); - $select_filter->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('highest'), 'HEADER X-PRIORITY 1'); - $select_filter->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('high'), 'HEADER X-PRIORITY 2'); - $select_filter->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('normal'), 'NOT HEADER X-PRIORITY 1 NOT HEADER X-PRIORITY 2 NOT HEADER X-PRIORITY 4 NOT HEADER X-PRIORITY 5'); - $select_filter->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('low'), 'HEADER X-PRIORITY 4'); - $select_filter->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('lowest'), 'HEADER X-PRIORITY 5'); - - $out = $select_filter->show($_REQUEST['_search'] ? $_SESSION['search_filter'] : 'ALL'); + $select->add($RCMAIL->gettext('withattachment'), $attachment); + $select->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('highest'), 'HEADER X-PRIORITY 1'); + $select->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('high'), 'HEADER X-PRIORITY 2'); + $select->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('normal'), 'NOT HEADER X-PRIORITY 1 NOT HEADER X-PRIORITY 2 NOT HEADER X-PRIORITY 4 NOT HEADER X-PRIORITY 5'); + $select->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('low'), 'HEADER X-PRIORITY 4'); + $select->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('lowest'), 'HEADER X-PRIORITY 5'); $RCMAIL->output->add_gui_object('search_filter', $attrib['id']); - return $out; + return $select->show($_REQUEST['_search'] ? $_SESSION['search_filter'] : 'ALL'); +} + +function rcmail_search_interval($attrib) +{ + global $RCMAIL; + + if (!strlen($attrib['id'])) { + $attrib['id'] = 'rcmsearchinterval'; + } + + $select = new html_select($attrib); + $select->add('', ''); + + foreach (array('1W', '1M', '1Y', '-1W', '-1M', '-1Y') as $value) { + $select->add($RCMAIL->gettext('searchinterval' . $value), $value); + } + + $RCMAIL->output->add_gui_object('search_interval', $attrib['id']); + + return $select->show($_REQUEST['_search'] ? $_SESSION['search_interval'] : ''); } function rcmail_message_error() diff --git a/program/steps/mail/search.inc b/program/steps/mail/search.inc index f69892e..ee6ba88 100644 --- a/program/steps/mail/search.inc +++ b/program/steps/mail/search.inc @@ -38,16 +38,15 @@ $filter = rcube_utils::get_input_value('_filter', rcube_utils::INPUT_GET); $headers = rcube_utils::get_input_value('_headers', rcube_utils::INPUT_GET); $scope = rcube_utils::get_input_value('_scope', rcube_utils::INPUT_GET); +$interval = rcube_utils::get_input_value('_interval', rcube_utils::INPUT_GET); $continue = rcube_utils::get_input_value('_continue', rcube_utils::INPUT_GET); $subject = array(); $filter = trim($filter); -$search_request = md5($mbox.$scope.$filter.$str); +$search_request = md5($mbox.$scope.$interval.$filter.$str); // add list filter string $search_str = $filter && $filter != 'ALL' ? $filter : ''; - -$_SESSION['search_filter'] = $filter; // Check the search string for type of search if (preg_match("/^from:.*/i", $str)) { @@ -102,6 +101,10 @@ $search = isset($srch) ? trim($srch) : trim($str); +if ($search_interval = rcmail_search_interval_criteria($interval)) { + $search_str .= ' ' . $search_interval; +} + if (!empty($subject)) { $search_str .= str_repeat(' OR', count($subject)-1); foreach ($subject as $sub) { @@ -144,9 +147,10 @@ $_SESSION['search'] = $RCMAIL->storage->get_search_set(); $_SESSION['last_text_search'] = $str; } -$_SESSION['search_request'] = $search_request; -$_SESSION['search_scope'] = $scope; - +$_SESSION['search_request'] = $search_request; +$_SESSION['search_scope'] = $scope; +$_SESSION['search_interval'] = $interval; +$_SESSION['search_filter'] = $filter; // Get the headers if (!$result->incomplete) { @@ -212,3 +216,28 @@ } $OUTPUT->send(); + + +// Creates BEFORE/SINCE search criteria from the specified interval +// Interval can be: 1W, 1M, 1Y, -1W, -1M, -1Y +function rcmail_search_interval_criteria($interval) +{ + if (empty($interval)) { + return; + } + + if ($interval[0] == '-') { + $search = 'BEFORE'; + $interval = substr($interval, 1); + } + else { + $search = 'SINCE'; + } + + $date = new DateTime('now'); + $interval = new DateInterval('P' . $interval); + + $date->sub($interval); + + return $search . ' ' . $date->format('j-M-Y'); +} diff --git a/skins/classic/templates/mail.html b/skins/classic/templates/mail.html index b7af014..c0bb469 100644 --- a/skins/classic/templates/mail.html +++ b/skins/classic/templates/mail.html @@ -115,6 +115,8 @@ <li><label><input type="checkbox" name="s_mods[]" value="bcc" id="s_mod_bcc" onclick="rcmail_ui.set_searchmod(this)" /> <span><roundcube:label name="bcc" /></span></label></li> <li><label><input type="checkbox" name="s_mods[]" value="body" id="s_mod_body" onclick="rcmail_ui.set_searchmod(this)" /> <span><roundcube:label name="body" /></span></label></li> <li><label><input type="checkbox" name="s_mods[]" value="text" id="s_mod_text" onclick="rcmail_ui.set_searchmod(this)" /> <span><roundcube:label name="msgtext" /></span></label></li> + <li><label class="comment"><roundcube:label name="date" /></label></li> + <li><roundcube:object name="searchinterval" id="s_interval" onchange="rcmail.set_searchinterval($(this).val())" /></li> <li><label class="comment"><roundcube:label name="searchscope" /></label></li> <li><label><input type="radio" name="s_scope" value="base" id="s_scope_base" onclick="rcmail.set_searchscope(this.value)" /> <span><roundcube:label name="currentfolder" /></span></label></li> <li><label><input type="radio" name="s_scope" value="sub" id="s_scope_sub" onclick="rcmail.set_searchscope(this.value)" /> <span><roundcube:label name="subfolders" /></span></label></li> diff --git a/skins/larry/mail.css b/skins/larry/mail.css index 80e2109..3dc93d2 100644 --- a/skins/larry/mail.css +++ b/skins/larry/mail.css @@ -251,6 +251,9 @@ background-position: -28px -458px; } +#s_interval { + margin: 3px 8px; +} /*** message list ***/ diff --git a/skins/larry/styles.css b/skins/larry/styles.css index 88459af..a66bbac 100644 --- a/skins/larry/styles.css +++ b/skins/larry/styles.css @@ -2408,6 +2408,12 @@ ul.toolbarmenu li.separator label { color: #bbb; font-style: italic; + padding: 0 8px; + line-height: 17px; +} + +ul.toolbarmenu li input { + margin: 0; } ul.toolbarmenu li a.icon { diff --git a/skins/larry/templates/mail.html b/skins/larry/templates/mail.html index bda3efb..4bf87c9 100644 --- a/skins/larry/templates/mail.html +++ b/skins/larry/templates/mail.html @@ -52,6 +52,8 @@ <li role="menuitem"><label><input type="checkbox" name="s_mods[]" value="bcc" id="s_mod_bcc" onclick="UI.set_searchmod(this)" /> <span><roundcube:label name="bcc" /></span></label></li> <li role="menuitem"><label><input type="checkbox" name="s_mods[]" value="body" id="s_mod_body" onclick="UI.set_searchmod(this)" /> <span><roundcube:label name="body" /></span></label></li> <li role="menuitem"><label><input type="checkbox" name="s_mods[]" value="text" id="s_mod_text" onclick="UI.set_searchmod(this)" /> <span><roundcube:label name="msgtext" /></span></label></li> + <li role="separator" class="separator"><label><roundcube:label name="date" /></label></li> + <li role="menuitem"><roundcube:object name="searchinterval" id="s_interval" onchange="rcmail.set_searchinterval($(this).val())" /></li> <li role="separator" class="separator"><label><roundcube:label name="searchscope" /></label></li> <li role="menuitem"><label><input type="radio" name="s_scope" value="base" id="s_scope_base" onclick="UI.set_searchscope(this)" /> <span><roundcube:label name="currentfolder" /></span></label></li> <li role="menuitem"><label><input type="radio" name="s_scope" value="sub" id="s_scope_sub" onclick="UI.set_searchscope(this)" /> <span><roundcube:label name="subfolders" /></span></label></li> -- Gitblit v1.9.1