These are generic search queries that can be applied to any mailbox.
Presently, these filters are only usable in IMP. The dimp interface has
not yet been written.
See, e.g., Request #8659.
'value' => 'a:1:{i:0;C:25:"IMP_Search_Vfolder_Vinbox":175:{a:3:{s:1:"c";a:2:{i:0;C:23:"IMP_Search_Element_Flag":24:{[1,{"f":"\\seen","s":0}]}i:1;C:23:"IMP_Search_Element_Flag":27:{[1,{"f":"\\deleted","s":0}]}}s:1:"e";i:1;s:1:"v";i:1;}}}'
);
+$_prefs['filter'] = array(
+ // 'value' => serialize(array(
+ // // Bulk filter, enabled by default
+ // new IMP_Search_Filter_Bulk(array(
+ // 'disable' => false
+ // ))
+ // ))
+ 'value' => 'a:1:{i:0;C:22:"IMP_Search_Filter_Bulk":88:{a:3:{s:1:"c";a:1:{i:0;C:23:"IMP_Search_Element_Bulk":5:{[1,0]}}s:1:"e";i:1;s:1:"v";i:1;}}}'
+);
+
// *** Compose Preferences ***
v5.0-git
--------
+[mms] Add ability to define search criteria to be applied to any mailbox
+ (Request #8659).
[mms] Use recipient search (To/Cc/Bcc) by default instead of To search.
[mms] Virtual folders now editable via a preferences group.
[mms] Search code has been entirely rewritten.
submit: function(actID)
{
- if (!this.anySelected()) {
- alert(IMP.text.mailbox_submit);
- return;
+ switch (actID) {
+ case 'filter_messages':
+ // No-op
+ break;
+
+ default:
+ if (!this.anySelected()) {
+ alert(IMP.text.mailbox_submit);
+ return;
+ }
+ break;
}
switch (actID) {
}
},
+ filterMessages: function(form)
+ {
+ var f1 = $('filter1'), f2 = $('filter2');
+
+ if ((form == 1 && $F(f1) != "") ||
+ (form == 2 && $F(f2) != "")) {
+ $('messages').down('[name=filter]').setValue((form == 1) ? $F(f1) : $F(f2));
+ this.submit('filter_messages');
+ }
+ },
+
getMessage: function(id, offset)
{
if (!offset) {
if (id) {
if (id.startsWith('flag')) {
this.flagMessages(id.substring(4));
+ } else if (id.startsWith('filter')) {
+ this.filterMessages(id.substring(6));
} else if (id.startsWith('targetMailbox')) {
this.updateFolders(id.substring(13));
}
submitHandler: function(e)
{
- if (e.element().readAttribute('id').startsWith('select')) {
+ if (e.element().hasClassName('navbarselect')) {
e.stop();
}
}
updateSelectedFolders: function(folders)
{
- var tmp = $('search_folders_hdr').next();
+ var tmp = $('search_folders_hdr');
+
+ if (!tmp) {
+ return;
+ }
+
+ tmp = tmp.next();
this.selectFolders(false);
folders.each(function(f) {
var i = tmp.down('INPUT[value=' + f + ']');
{
var data = [], tmp;
- if (!this._getAll().findAll(function(i) { return i.checked; }).size()) {
+ if ($('search_folders_hdr') &&
+ !this._getAll().findAll(function(i) { return i.checked; }).size()) {
alert(this.text.need_folder);
- } else if ($F('search_save') && !$('search_label').present()) {
+ } else if ($F('search_type') && !$('search_label').present()) {
alert(this.text.need_label);
} else {
tmp = $('search_criteria_table').childElements().pluck('id');
*/
var ImpSearchesPrefs = {
- // Variables set by other code: confirm_delete_vfolder, mailboxids
+ // Variables set by PHP script: confirm_delete_filter,
+ // confirm_delete_vfolder, mailboxids
clickHandler: function(e)
{
var elt = e.element();
while (Object.isElement(elt)) {
- if (elt.hasClassName('vfolderdelete')) {
+ if (elt.hasClassName('filterdelete')) {
+ if (window.confirm(this.confirm_delete_filter)) {
+ this._sendData('delete', elt.up().previous('.enabled').down('INPUT').readAttribute('name'));
+ }
+ e.stop();
+ return;
+ } else if (elt.hasClassName('vfolderdelete')) {
if (window.confirm(this.confirm_delete_vfolder)) {
this._sendData('delete', elt.up().previous('.enabled').down('INPUT').readAttribute('name'));
}
break;
case 'searches':
- if ($prefs->isLocked('vfolder')) {
- $ui->suppress[] = 'searchesmanagement';
- } else {
- Horde::addScriptFile('searchesprefs.js', 'imp');
- }
+ Horde::addScriptFile('searchesprefs.js', 'imp');
break;
case 'server':
*/
protected function _searchesManagement()
{
- $t = $GLOBALS['injector']->createInstance('Horde_Template');
+ global $injector, $prefs;
+
+ $t = $injector->createInstance('Horde_Template');
$t->setOption('gettext', true);
- $imp_search = $GLOBALS['injector']->getInstance('IMP_Search');
- $mailboxids = $out = array();
+ $imp_search = $injector->getInstance('IMP_Search');
+ $fout = $mailboxids = $vout = array();
$view_mode = IMP::getViewMode();
$imp_search->setIteratorFilter(IMP_Search::LIST_VFOLDER | IMP_Search::LIST_DISABLED);
+ $vfolder_locked = $prefs->isLocked('vfolder');
+
foreach ($imp_search as $key => $val) {
if (!$val->prefDisplay) {
continue;
}
- $editable = $imp_search->isVFolder($val, true);
+ $editable = !$vfolder_locked && $imp_search->isVFolder($val, true);
$m_url = ($val->enabled && ($view_mode == 'imp'))
? IMP::generateIMPUrl('mailbox.php', strval($val))->link(array('class' => 'vfolderenabled'))
: null;
$mailboxids['enable_' . $key] = strval($val);
}
- $out[] = array(
+ $vout[] = array(
'description' => Horde_String::truncate($val->querytext, 200),
'edit' => ($editable ? $imp_search->editUrl($val) : null),
'enabled' => $val->enabled,
+ 'enabled_locked' => $vfolder_locked,
'key' => $key,
'label' => htmlspecialchars($val->label),
'm_url' => $m_url
);
+ }
+ $t->set('vfolders', $vout);
+
+ $imp_search->setIteratorFilter(IMP_Search::LIST_FILTER | IMP_Search::LIST_DISABLED);
+ $filter_locked = $prefs->isLocked('filter');
+
+ foreach ($imp_search as $key => $val) {
+ $editable = !$filter_locked && $imp_search->isFilter($val, true);
+
+ if ($view_mode == 'dimp') {
+ $mailboxids['enable_' . $key] = strval($val);
+ }
+ $fout[] = array(
+ 'description' => Horde_String::truncate($val->querytext, 200),
+ 'edit' => ($editable ? $imp_search->editUrl($val) : null),
+ 'enabled' => $val->enabled,
+ 'enabled_locked' => $filter_locked,
+ 'key' => $key,
+ 'label' => htmlspecialchars($val->label)
+ );
}
- $t->set('vfolders', $out);
+ $t->set('filters', $fout);
- Horde::addInlineJsVars(array(
- 'ImpSearchesPrefs.confirm_delete_vfolder' => _("Are you sure you want to delete this virtual folder?"),
- 'ImpSearchesPrefs.mailboxids' => $mailboxids
- ));
+ if (empty($fout) && empty($vout)) {
+ $t->set('nosearches', true);
+ } else {
+ Horde::addInlineJsVars(array(
+ 'ImpSearchesPrefs.confirm_delete_filter' => _("Are you sure you want to delete this filter?"),
+ 'ImpSearchesPrefs.confirm_delete_vfolder' => _("Are you sure you want to delete this virtual folder?"),
+ 'ImpSearchesPrefs.mailboxids' => $mailboxids
+ ));
+ }
return $t->fetch(IMP_TEMPLATES . '/prefs/searches.html');
}
/* Remove 'enable_' prefix. */
$key = substr($ui->vars->searches_data, 7);
if ($ob = $imp_search[$key]) {
- $GLOBALS['notification']->push(sprintf(_("Virtual Folder \"%s\" deleted."), $ob->label), 'horde.success');
+ if ($imp_search->isVFolder($ob)) {
+ $GLOBALS['notification']->push(sprintf(_("Virtual Folder \"%s\" deleted."), $ob->label), 'horde.success');
+ } elseif ($imp_search->isFilter($ob)) {
+ $GLOBALS['notification']->push(sprintf(_("Filter \"%s\" deleted."), $ob->label), 'horde.success');
+ }
unset($imp_search[$key]);
}
break;
default:
- /* Update enabled status. */
+ /* Update enabled status for Virtual Folders. */
$imp_search->setIteratorFilter(IMP_Search::LIST_VFOLDER | IMP_Search::LIST_DISABLED);
$vfolders = array();
}
}
$imp_search->setVFolders($vfolders);
+
+ /* Update enabled status for Filters. */
+ $imp_search->setIteratorFilter(IMP_Search::LIST_FILTER | IMP_Search::LIST_DISABLED);
+ $filters = array();
+
+ foreach ($imp_search as $key => $val) {
+ $form_key = 'enable_' . $key;
+ $val->enabled = !empty($ui->vars->$form_key);
+ $filters[$key] = $val;
+ }
+ $imp_search->setFilters($filters);
break;
}
}
const DIMP_QUICKSEARCH = 'dimpqsearch';
/* Bitmask filters for iterator. */
- const LIST_SEARCH = 1;
- const LIST_VFOLDER = 2;
- const LIST_DISABLED = 4;
+ const LIST_FILTER = 1;
+ const LIST_QUERY = 2;
+ const LIST_VFOLDER = 4;
+ const LIST_DISABLED = 8;
/* Query creation types. */
- const CREATE_QUERY = 1;
- const CREATE_VFOLDER = 2;
+ const CREATE_FILTER = 1;
+ const CREATE_QUERY = 2;
+ const CREATE_VFOLDER = 3;
/**
* Has the object data changed?
* @var array
*/
protected $_search = array(
+ 'filters' => array(),
'query' => array(),
'vfolders' => array()
);
*/
public function init()
{
+ $this->setFilters($this->getFilters(), false);
$this->setVFolders($this->getVFolders(), false);
}
* @param string $id Use as the mailbox ID.
*
* @return IMP_Search_Query Returns the query object.
+ * @throws InvalidArgumentException
*/
- public function createQuery($criteria, $mboxes, $label = null,
+ public function createQuery($criteria, $mboxes = array(), $label = null,
$type = self::CREATE_QUERY, $id = null)
{
if (!is_null($id)) {
}
switch ($type) {
+ case self::CREATE_FILTER:
+ $cname = 'IMP_Search_Filter';
+ break;
+
case self::CREATE_QUERY:
$cname = 'IMP_Search_Query';
+ if (empty($mboxes)) {
+ throw new InvalidArgumentException('Search query requires at least one mailbox.');
+ }
break;
case self::CREATE_VFOLDER:
$cname = 'IMP_Search_Vfolder';
+ if (empty($mboxes)) {
+ throw new InvalidArgumentException('Search query requires at least one mailbox.');
+ }
break;
}
)));
switch ($type) {
+ case self::CREATE_FILTER:
+ /* This will overwrite previous value, if it exists. */
+ $this->_search['filters'][$ob->id] = $ob;
+ $this->setFilters($this->_search['filters']);
+ break;
+
case self::CREATE_QUERY:
$this->_search['query'][$ob->id] = $ob;
break;
}
/**
+ * Obtains the list of filters for the current user.
+ *
+ * @return array The list of filters. Keys are mailbox IDs, values are
+ * IMP_Search_Filter objects.
+ */
+ public function getFilters()
+ {
+ if ($f_list = $GLOBALS['prefs']->getValue('filter')) {
+ $f_list = @unserialize($f_list);
+ }
+
+ $filters = array();
+
+ if (is_array($f_list)) {
+ foreach ($f_list as $val) {
+ if ($val instanceof IMP_Search_Filter) {
+ $filters[$val->id] = $val;
+ }
+ }
+ }
+
+ return $filters;
+ }
+
+ /**
+ * Saves the list of filters for the current user.
+ *
+ * @param array $filters The filter list.
+ * @param boolean $save Save the filter list to the preference backend?
+ */
+ public function setFilters($filters, $save = true)
+ {
+ if ($save) {
+ $GLOBALS['prefs']->setValue('filter', serialize(array_values($filters)));
+ }
+
+ $this->_search['filters'] = $filters;
+ $this->changed = true;
+ }
+
+ /**
+ * Is a mailbox a filter query?
+ *
+ * @param string $id The mailbox ID.
+ * @param boolean $editable Is this an editable (i.e. not built-in)
+ * filter query?
+ */
+ public function isFilter($id, $editable = false)
+ {
+ return (isset($this->_search['filters'][$this->_strip($id)]) &&
+ (!$editable || $this[$id]->canEdit));
+ }
+
+ /**
+ * Converts a filter to a search query and stores it in the local
+ * session.
+ *
+ * @param string $id The mailbox ID of the filter.
+ * @param array $mboxes The list of mailboxes to apply the filter on.
+ *
+ * @return IMP_Search_Query The created query object.
+ * @throws InvalidArgumentException
+ */
+ public function applyFilter($id, array $mboxes)
+ {
+ if (!$this->isFilter($id)) {
+ throw new InvalidArgumentException('Invalid filter ID given.');
+ }
+
+ $q_ob = $this[$id]->toQuery($mboxes);
+ $this->_search['query'][$q_ob->id] = $q_ob;
+ $this->changed = true;
+
+ return $q_ob;
+ }
+
+ /**
* Obtains the list of virtual folders for the current user.
*
* @return array The list of virtual folders. Keys are mailbox IDs,
public function offsetExists($offset)
{
$id = $this->_strip($offset);
- return (isset($this->_search['query'][$id]) ||
- isset($this->_search['vfolders'][$id]));
+
+ foreach (array_keys($this->_search) as $key) {
+ if (isset($this->_search[$key][$id])) {
+ return true;
+ }
+ }
+
+ return false;
}
public function offsetGet($offset)
{
$id = $this->_strip($offset);
- if (isset($this->_search['query'][$id])) {
- return $this->_search['query'][$id];
- } elseif (isset($this->_search['vfolders'][$id])) {
- return $this->_search['vfolders'][$id];
+
+ foreach (array_keys($this->_search) as $key) {
+ if (isset($this->_search[$key][$id])) {
+ return $this->_search[$key][$id];
+ }
}
return null;
}
$id = $this->_strip($offset);
- if (isset($this->_search['query'][$id])) {
- $this->_search['query'][$id] = $value;
- return;
- } elseif (isset($this->_search['vfolders'][$id])) {
- $this->_search['vfolders'][$id] = $value;
- return;
+
+ foreach (array_keys($this->_search) as $key) {
+ if (isset($this->_search[$key][$id])) {
+ $this->_search[$key][$id] = $value;
+ return;
+ }
}
throw new InvalidArgumentException('Creating search queries by array index is not supported. Use createQuery() instead.');
*
* @param integer $mask A mask with the following possible elements:
* <pre>
- * IMP_Search::LIST_SEARCH
+ * IMP_Search::LIST_FILTER
+ * IMP_Search::LIST_QUERY
* IMP_Search::LIST_VFOLDER
* </pre>
*/
return true;
}
- if (($this->_filter & self::LIST_VFOLDER) &&
- $this->isVfolder($ob)) {
+ if (($this->_filter & self::LIST_FILTER) &&
+ $this->isFilter($ob)) {
return true;
}
- if (($this->_filter & self::LIST_SEARCH) &&
- !$this->isVfolder($ob)) {
+ if (($this->_filter & self::LIST_QUERY) &&
+ $this->isQuery($ob)) {
return true;
}
- if ($this->isQuery($ob, true)) {
+ if (($this->_filter & self::LIST_VFOLDER) &&
+ $this->isVfolder($ob)) {
return true;
}
}
--- /dev/null
+<?php
+/**
+ * This class provides a data structure for storing a stored filter.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Search_Filter extends IMP_Search_Query
+{
+ /**
+ * Get object properties.
+ *
+ * @see parent::__get()
+ */
+ public function __get($name)
+ {
+ switch ($name) {
+ case 'querytext':
+ $text = array(_("Search"));
+
+ foreach ($this->_criteria as $elt) {
+ $text[] = $elt->queryText();
+ if (!($elt instanceof IMP_Search_Element_Or)) {
+ $text[] = _("and");
+ }
+ }
+ array_pop($text);
+
+ return implode(' ', $text);
+ }
+
+ return parent::__get($name);
+ }
+
+ /**
+ * Creates a query object from this filter.
+ *
+ * @param array $mboxes The list of mailboxes to apply the filter to.
+ *
+ * @return IMP_Search_Query A query object.
+ */
+ public function toQuery(array $mboxes)
+ {
+ return new IMP_Search_Query(array(
+ 'add' => $this->_criteria,
+ 'label' => $this->label,
+ 'mboxes' => $mboxes
+ ));
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides a filter for bulk mail.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Search_Filter_Bulk extends IMP_Search_Filter
+{
+ /**
+ * Can this query be edited?
+ *
+ * @var boolean
+ */
+ protected $_canEdit = false;
+
+ /**
+ * List of serialize entries not to save.
+ *
+ * @var array
+ */
+ protected $_nosave = array('i', 'l');
+
+ /**
+ * Constructor.
+ *
+ * The 'add', 'id', 'label', and 'mboxes' parameters are ignored.
+ *
+ * @see parent::__construct()
+ */
+ public function __construct(array $opts = array())
+ {
+ $this->enabled = empty($opts['disable']);
+
+ $this->add(new IMP_Search_Element_Bulk());
+
+ $this->_init();
+ }
+
+ /**
+ * Initialization tasks.
+ */
+ protected function _init()
+ {
+ $this->_id = 'filter_bulk';
+ $this->_label = _("Bulk Messages");
+ }
+
+ /**
+ * Unserialization.
+ *
+ * @param string $data Serialized data.
+ *
+ * @throws Exception
+ */
+ public function unserialize($data)
+ {
+ parent::unserialize($data);
+ $this->_init();
+ }
+
+}
/* Determine if mailbox is readonly. */
$readonly = $imp_imap->isReadOnly(IMP::$mailbox);
if ($readonly &&
- in_array($actionID, array('delete_messages', 'undelete_messages', 'move_messages', 'flag_messages', 'empty_mailbox', 'filter'))) {
+ in_array($actionID, array('delete_messages', 'undelete_messages', 'move_messages', 'flag_messages', 'filter_messages', 'empty_mailbox', 'filter'))) {
$actionID = null;
}
break;
case 'flag_messages':
- $flag = Horde_Util::getPost('flag');
- if ($flag && count($indices)) {
- $flag = $imp_flags->parseFormId($flag);
+ if ($vars->flag && count($indices)) {
+ $flag = $imp_flags->parseFormId($vars->flag);
$injector->getInstance('IMP_Message')->flag(array($flag['flag']), $indices, $flag['set']);
}
break;
+case 'filter_messages':
+ $filter = IMP::formMbox($vars->filter, false);
+ try {
+ $q_ob = $imp_search->applyFilter($filter, array(IMP::$mailbox));
+ Horde::url('mailbox.php', true)->add('mailbox', strval($q_ob))->redirect();
+ exit;
+ } catch (InvalidArgumentException $e) {}
+ break;
+
case 'hide_deleted':
$prefs->setValue('delhide', !$prefs->getValue('delhide'));
IMP::hideDeletedMsgs(IMP::$mailbox, true);
$n_template->set('flaglist_set', $tmp['set']);
$n_template->set('flaglist_unset', $tmp['unset']);
+ if (!$search_mbox) {
+ $filters = array();
+ $imp_search->setIteratorFilter(IMP_Search::LIST_FILTER);
+ foreach ($imp_search as $val) {
+ $filters[] = array(
+ 'l' => htmlspecialchars($val->label),
+ 'v' => IMP::formMbox(strval($val), true)
+ );
+ }
+ if (!empty($filters)) {
+ $n_template->set('filters', $filters);
+ }
+ }
+
if ($n_template->get('use_folders')) {
$n_template->set('move', Horde::widget('#', _("Move to folder"), 'widget moveAction', '', '', _("Move"), true));
$n_template->set('copy', Horde::widget('#', _("Copy to folder"), 'widget copyAction', '', '', _("Copy"), true));
* ---------------
* 'criteria_form' - (string) JSON representation of the search query.
* 'edit_query' - (string) The search query to edit.
- * 'edit_query_vfolder' - (string) The name of the vfolder being edited.
+ * 'edit_query_filter' - (string) The name of the filter being edited.
+ * 'edit_query_vfolder' - (string) The name of the virtual folder being
+ * edited.
* 'folder_list' - (array) The list of folders to add to the query.
* 'search_label' - (string) The label to use when saving the search.
* 'search_mailbox' - (string) Use this mailbox as the default value.
* DEFAULT: INBOX
- * 'search_save' - (integer) If set, save search.
- * 'search_type' - (string) The type of saved search ('vfolder').
+ * 'search_type' - (string) The type of saved search ('filter', 'vfolder').
+ * If empty, the search should not be saved.
*
* Copyright 1999-2010 The Horde Project (http://www.horde.org/)
*
/* Generate the search query if 'criteria_form' is present in the form
* data. */
if ($vars->criteria_form) {
- $criteria = Horde_Serialize::unserialize($vars->criteria_form, Horde_Serialize::JSON);
+ $c_data = Horde_Serialize::unserialize($vars->criteria_form, Horde_Serialize::JSON);
$c_list = array();
- foreach ($criteria as $val) {
+ foreach ($c_data as $val) {
switch ($val->t) {
case 'from':
case 'to':
}
}
- /* Save the search if requested. */
- if ($vars->search_save) {
- switch ($vars->search_type) {
- case 'vfolder':
- $q_ob = $imp_search->createQuery(
- $c_list,
- $vars->folder_list,
- $vars->search_label,
- IMP_Search::CREATE_VFOLDER,
- IMP::formMbox($vars->edit_query_vfolder, false)
- );
+ $redirect_dimp = true;
+ $redirect_target = false;
+
+ switch ($vars->search_type) {
+ case 'filter':
+ $q_ob = $imp_search->createQuery(
+ $c_list,
+ array(),
+ $vars->search_label,
+ IMP_Search::CREATE_FILTER,
+ IMP::formMbox($vars->edit_query_filter, false)
+ );
- if ($vars->edit_query_vfolder) {
- $notification->push(sprintf(_("Virtual Folder \"%s\" edited successfully."), $vars->search_label), 'horde.success');
- if ($dimp_view) {
- IMP_Dimp::returnToDimp(strval($q_ob));
- }
- Horde::getServiceLink('prefs', 'imp')->add('group', 'searches')->redirect();
- exit;
- }
+ if ($vars->edit_query_filter) {
+ $notification->push(sprintf(_("Filter \"%s\" edited successfully."), $vars->search_label), 'horde.success');
+ $redirect_dimp = false;
+ $redirect_target = 'prefs';
+ } else {
+ $notification->push(sprintf(_("Filter \"%s\" created succesfully."), $vars->search_label), 'horde.success');
+ }
+ break;
+ case 'vfolder':
+ $q_ob = $imp_search->createQuery(
+ $c_list,
+ $vars->folder_list,
+ $vars->search_label,
+ IMP_Search::CREATE_VFOLDER,
+ IMP::formMbox($vars->edit_query_vfolder, false)
+ );
+
+ if ($vars->edit_query_vfolder) {
+ $notification->push(sprintf(_("Virtual Folder \"%s\" edited successfully."), $vars->search_label), 'horde.success');
+ $redirect_target = 'prefs';
+ } else {
$notification->push(sprintf(_("Virtual Folder \"%s\" created succesfully."), $vars->search_label), 'horde.success');
- break;
+ $redirect_target = 'mailbox';
}
- } else {
- /* Set the search in the session. */
+ break;
+
+ default:
$q_ob = $imp_search->createQuery(
$c_list,
$vars->folder_list
);
+ $redirect_target = 'mailbox';
+ break;
}
/* Redirect to the mailbox page. */
- if ($dimp_view) {
- IMP_Dimp::returnToDimp(strval($q_ob));
- }
+ if ($redirect_target) {
+ if ($dimp_view && $redirect_dimp) {
+ IMP_Dimp::returnToDimp(strval($q_ob));
+ exit;
+ }
- Horde::url('mailbox.php', true)->add('mailbox', strval($q_ob))->redirect();
- exit;
+ switch ($redirect_target) {
+ case 'mailbox':
+ Horde::url('mailbox.php', true)->add('mailbox', strval($q_ob))->redirect();
+ break;
+
+ case 'prefs':
+ Horde::getServiceLink('prefs', 'imp')->add('group', 'searches')->redirect();
+ break;
+ }
+
+ exit;
+ }
}
/* Preselect mailboxes. */
$q_ob = $imp_search[$vars->edit_query];
if ($imp_search->isVFolder($q_ob)) {
if (!$imp_search->isVFolder($q_ob, true)) {
- $notification->push(_("Special Virtual Folders cannot be edited."), 'horde.error');
+ $notification->push(_("Built-in Virtual Folders cannot be edited."), 'horde.error');
Horde::getServiceLink('prefs', 'imp')->add('group', 'searches')->redirect();
}
+ $t->set('edit_query', true);
$t->set('edit_query_vfolder', IMP::formMbox($q_ob, true));
- $t->set('search_label', htmlspecialchars($q_ob->label));
+ } elseif ($imp_search->isFilter($q_ob)) {
+ if (!$imp_search->isFilter($q_ob, true)) {
+ $notification->push(_("Built-in Filters cannot be edited."), 'horde.error');
+ Horde::getServiceLink('prefs', 'imp')->add('group', 'searches')->redirect();
+ }
+ $t->set('edit_query', true);
+ $t->set('edit_query_filter', IMP::formMbox($q_ob, true));
+ }
+ if ($t->get('edit_query')) {
+ $t->set('search_label', htmlspecialchars($q_ob->label));
$js_vars['ImpSearch.prefsurl'] = strval(Horde::getServiceLink('prefs', 'imp')->add('group', 'searches')->setRaw(true));
}
+
$js_vars['ImpSearch.i_criteria'] = $q_ob->criteria;
} else {
/* Process list of recent searches. */
$rs = array();
- $imp_search->setIteratorFilter(IMP_Search::LIST_SEARCH);
+ $imp_search->setIteratorFilter(IMP_Search::LIST_QUERY);
foreach ($imp_search as $val) {
$rs[$val->id] = array(
'c' => $val->criteria,
$t->set('flist', $flag_set);
/* Generate master folder list. */
-$tree = $injector->getInstance('IMP_Imap_Tree')->createTree('imp_search', array(
- 'checkbox' => true,
-));
-$t->set('tree', $tree->getTree());
+if (!$t->get('edit_query_filter')) {
+ $tree = $injector->getInstance('IMP_Imap_Tree')->createTree('imp_search', array(
+ 'checkbox' => true,
+ ));
+ $t->set('tree', $tree->getTree());
+}
Horde_Core_Ui_JsCalendar::init();
Horde::addScriptFile('horde.js', 'horde');
<input type="hidden" id="targetMbox" name="targetMbox" value="" />
<input type="hidden" id="newMbox" name="newMbox" value="0" />
<input type="hidden" id="flag" name="flag" value="" />
+ <input type="hidden" id="filter" name="filter" value="" />
<if:readonly><else:readonly>
<if:use_pop><else:use_pop>
<div class="leftFloat">
- <form id="select<tag:id />">
- <input type="hidden" name="mailbox" value="<tag:mailbox />" />
- <label for="flag<tag:id />" class="hidden"><gettext>Mark Messages</gettext></label>
- <select id="flag<tag:id />" name="flag">
- <option value="" selected="selected"><gettext>Mark Messages</gettext></option>
- <option value="" disabled="disabled">- - - - - - - -</option>
- <option value=""><gettext>Mark as:</gettext></option>
+ <form class="navbarselect">
+ <label for="flag<tag:id />" class="hidden"><gettext>Mark Messages</gettext></label>
+ <select id="flag<tag:id />" name="flag">
+ <option value="" selected="selected"><gettext>Mark Messages</gettext></option>
+ <option value="" disabled="disabled">- - - - - - - -</option>
+ <option value=""><gettext>Mark as:</gettext></option>
<loop:flaglist_set>
- <option value="<tag:flaglist_set.f />"> <tag:flaglist_set.l /></option>
+ <option value="<tag:flaglist_set.f />"> <tag:flaglist_set.l /></option>
</loop:flaglist_set>
- <option value="" disabled="disabled">- - - - - - - -</option>
- <option value=""><gettext>Unmark as:</gettext></option>
+ <option value="" disabled="disabled">- - - - - - - -</option>
+ <option value=""><gettext>Unmark as:</gettext></option>
<loop:flaglist_unset>
- <option value="<tag:flaglist_unset.f />"> <tag:flaglist_unset.l /></option>
+ <option value="<tag:flaglist_unset.f />"> <tag:flaglist_unset.l /></option>
</loop:flaglist_unset>
- </select>
+ </select>
+ </form>
+ </div>
+<if:filters>
+ <div class="leftFloat">
+ <form class="navbarselect">
+ <label for="filter<tag:id />" class="hidden"><gettext>Filter Messages</gettext></label>
+ <select id="filter<tag:id />" name="filter">
+ <option value="" selected="selected"><gettext>Filter Messages</gettext></option>
+ <option value="" disabled="disabled">- - - - - - - -</option>
+<loop:filters>
+ <option value="<tag:filters.v />"><tag:filters.l /></option>
+</loop:filters>
+ </select>
</form>
</div>
+</if:filters>
</else:use_pop></if:use_pop>
<if:use_folders>
<div class="leftFloat" style="padding-left:10px">
<if:edit_query_vfolder>
<gettext>Edit Virtual Folder</gettext>
<else:edit_query_vfolder>
+<if:edit_query_filter>
+ <gettext>Edit Filter</gettext>
+<else:edit_query_filter>
<gettext>Search</gettext>
+</else:edit_query_filter></if:edit_query_filter>
</else:edit_query_vfolder></if:edit_query_vfolder>
</strong>
</h1>
</div>
</div>
+<if:edit_query_filter><else:edit_query_filter>
<div class="smallheader leftAlign" id="search_folders_hdr">
<span class="searchuiImg arrowExpanded" style="display:none"></span>
<span class="searchuiImg arrowCollapsed"></span>
<div class="item" id="search_folders_tree" style="display:none">
<tag:tree />
</div>
+</else:edit_query_filter></if:edit_query_filter>
<if:virtualfolder>
<div class="smallheader leftAlign">
<div style="display:none">
<if:edit_query_vfolder>
- <input type="hidden" name="search_save" id="search_save" value="1" />
- <input type="hidden" name="search_type" value="vfolder" />
+ <input type="hidden" id="search_type" name="search_type" value="vfolder" />
<input type="hidden" name="edit_query_vfolder" value="<tag:edit_query_vfolder />" />
<else:edit_query_vfolder>
- <div class="item">
- <input type="checkbox" class="checkbox" id="search_save" name="search_save" /> <label for="search_save"><gettext>Save search?</gettext></label>
- </div>
+<if:edit_query_filter>
+ <input type="hidden" id="search_type" name="search_type" value="filter" />
+ <input type="hidden" name="edit_query_filter" value="<tag:edit_query_filter />" />
+<else:edit_query_filter>
<div class="item">
<label for="search_type"><gettext>Type:</gettext></label>
<select id="search_type" name="search_type">
+ <option value="" selected="selected">- - - - - -</option>
<option value="filter"><gettext>Filter</gettext></option>
<option value="vfolder"><gettext>Virtual Folder</gettext></option>
</select>
</div>
+</else:edit_query_filter></if:edit_query_filter>
</else:edit_query_vfolder></if:edit_query_vfolder>
<div class="item">
<label for="search_label"><gettext>Label:</gettext></label> <input type="text" name="search_label" id="search_label"<if:search_label> value="<tag:search_label />"</if:search_label> />
</if:virtualfolder>
<div class="searchuiButtons">
-<if:edit_query_vfolder>
+<if:edit_query>
<input type="button" id="search_submit" class="button" value="<gettext>Save</gettext>" />
<input type="button" id="search_edit_query_cancel" class="button" value="<gettext>Cancel</gettext>" />
-<else:edit_query_vfolder>
+<else:edit_query>
<input type="button" id="search_submit" class="button" value="<gettext>Submit</gettext>" />
<input type="button" id="search_reset" class="button" value="<gettext>Reset</gettext>" />
-</else:edit_query_vfolder></if:edit_query_vfolder>
+</else:edit_query></if:edit_query>
<if:return_mailbox_val>
<input type="button" id="search_dimp_return" class="button" value="<tag:return_mailbox_val />" />
</if:return_mailbox_val>
<input type="hidden" name="searches_action" id="searches_action" />
<input type="hidden" name="searches_data" id="searches_data" />
+
+<if:vfolders>
<table class="searchesmanagement">
<thead>
<tr>
</else:vfolders.enabled></if:vfolders.enabled>
</td>
<td class="enabled">
- <input class="checkbox" type="checkbox" name="enable_<tag:vfolders.key />"<if:vfolders.enabled> checked="checked"</if:vfolders.enabled> />
+ <input class="checkbox" type="checkbox" name="enable_<tag:vfolders.key />"<if:vfolders.enabled> checked="checked"</if:vfolders.enabled><if:vfolders.enabled_locked> disabled="disabled"</if:vfolders.enabled_locked> />
</td>
<td>
<if:vfolders.edit>
</td>
</tr>
<tr>
- <td colspan="3" class="fixed vfolderdescription">
+ <td colspan="3" class="fixed searchdescription">
<tag:vfolders.description />
</td>
</loop:vfolders>
</tbody>
</table>
+</if:vfolders>
+
+<if:filters>
+<table class="searchesmanagement">
+ <thead>
+ <tr>
+ <td><gettext>Filter</gettext></td>
+ <td><gettext>Enabled?</gettext></td>
+ <td><gettext>Actions</gettext></td>
+ </tr>
+ </thead>
+ <tbody>
+<loop:filters>
+ <tr>
+ <td>
+ <tag:filters.label />
+ </td>
+ <td class="enabled">
+ <input class="checkbox" type="checkbox" name="enable_<tag:filters.key />"<if:filters.enabled> checked="checked"</if:filters.enabled><if:filters.enabled_locked> disabled="disabled"</if:filters.enabled_locked> />
+ </td>
+ <td>
+<if:filters.edit>
+ <a class="filteredit" href="<tag:filters.edit />"><span class="editImg"></span></a>
+ <a class="filterdelete" href="#"><span class="deleteImg"></span></a>
+<else:filters.edit>
+ <gettext>No Actions Available</gettext>
+</else:filters.edit></if:filters.edit>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3" class="fixed searchdescription">
+ <tag:filters.description />
+ </td>
+</loop:filters>
+ </tbody>
+</table>
+</if:filters>
+
+<if:nosearches>
+<div>
+ <em><gettext>No Saved Searches Defined.</gettext></em>
+</div>
+</if:nosearches>
text-align: center;
}
-table.searchesmanagement td.vfolderdescription {
+table.searchesmanagement td.searchdescription {
background-color: #ffa;
width: 500px;
}