Aleksander Machniak
2015-10-08 5802e08e4833c0567f6e2f7d7a50ece521dc3f6e
Mail messages searching with predefined date interval (T103)
9 files modified
135 ■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
program/js/app.js 20 ●●●●● patch | view | raw | blame | history
program/localization/en_US/labels.inc 6 ●●●●● patch | view | raw | blame | history
program/steps/mail/func.inc 54 ●●●●● patch | view | raw | blame | history
program/steps/mail/search.inc 41 ●●●● patch | view | raw | blame | history
skins/classic/templates/mail.html 2 ●●●●● patch | view | raw | blame | history
skins/larry/mail.css 3 ●●●●● patch | view | raw | blame | history
skins/larry/styles.css 6 ●●●●● patch | view | raw | blame | history
skins/larry/templates/mail.html 2 ●●●●● patch | view | raw | blame | history
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)
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,
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)';
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()
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');
}
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>
skins/larry/mail.css
@@ -251,6 +251,9 @@
    background-position: -28px -458px;
}
#s_interval {
    margin: 3px 8px;
}
/*** message list ***/
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 {
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>