Fixed created search strings.
This commit is contained in:
parent
3b616f3b8b
commit
73045ee858
1 changed files with 398 additions and 382 deletions
|
@ -1,36 +1,36 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* imap_search.php
|
||||
*
|
||||
* Copyright (c) 1999-2004 The SquirrelMail Project Team
|
||||
* Licensed under the GNU GPL. For full terms see the file COPYING.
|
||||
*
|
||||
* IMAP asearch routines
|
||||
*
|
||||
* Subfolder search idea from Patch #806075 by Thomas Pohl xraven at users.sourceforge.net. Thanks Thomas!
|
||||
*
|
||||
* @version $Id$
|
||||
* @package squirrelmail
|
||||
* @subpackage imap
|
||||
* @see search.php
|
||||
* @link http://www.ietf.org/rfc/rfc3501.txt
|
||||
* @author Alex Lemaresquier - Brainstorm - alex at brainstorm.fr
|
||||
*/
|
||||
* imap_search.php
|
||||
*
|
||||
* Copyright (c) 1999-2004 The SquirrelMail Project Team
|
||||
* Licensed under the GNU GPL. For full terms see the file COPYING.
|
||||
*
|
||||
* IMAP asearch routines
|
||||
*
|
||||
* Subfolder search idea from Patch #806075 by Thomas Pohl xraven at users.sourceforge.net. Thanks Thomas!
|
||||
*
|
||||
* @version $Id$
|
||||
* @package squirrelmail
|
||||
* @subpackage imap
|
||||
* @see search.php
|
||||
* @link http://www.ietf.org/rfc/rfc3501.txt
|
||||
* @author Alex Lemaresquier - Brainstorm - alex at brainstorm.fr
|
||||
*/
|
||||
|
||||
/** This functionality requires the IMAP and date functions
|
||||
*/
|
||||
*/
|
||||
require_once(SM_PATH . 'functions/imap_general.php');
|
||||
require_once(SM_PATH . 'functions/date.php');
|
||||
|
||||
/** Set to TRUE to dump the imap dialogue
|
||||
* @global bool $imap_asearch_debug_dump
|
||||
*/
|
||||
* @global bool $imap_asearch_debug_dump
|
||||
*/
|
||||
$imap_asearch_debug_dump = FALSE;
|
||||
|
||||
/** Imap SEARCH keys
|
||||
* @global array $imap_asearch_opcodes
|
||||
*/
|
||||
* @global array $imap_asearch_opcodes
|
||||
*/
|
||||
$imap_asearch_opcodes = array(
|
||||
/* <sequence-set> => 'asequence', */ // Special handling, @see sqimap_asearch_build_criteria()
|
||||
/*'ALL' is binary operator */
|
||||
|
@ -71,8 +71,8 @@ $imap_asearch_opcodes = array(
|
|||
);
|
||||
|
||||
/** Imap SEARCH month names encoding
|
||||
* @global array $imap_asearch_months
|
||||
*/
|
||||
* @global array $imap_asearch_months
|
||||
*/
|
||||
$imap_asearch_months = array(
|
||||
'01' => 'jan',
|
||||
'02' => 'feb',
|
||||
|
@ -89,8 +89,8 @@ $imap_asearch_months = array(
|
|||
);
|
||||
|
||||
/** Error message titles according to imap server returned code
|
||||
* @global array $imap_error_titles
|
||||
*/
|
||||
* @global array $imap_error_titles
|
||||
*/
|
||||
$imap_error_titles = array(
|
||||
'OK' => '',
|
||||
'NO' => _("ERROR : Could not complete request."),
|
||||
|
@ -100,15 +100,15 @@ $imap_error_titles = array(
|
|||
);
|
||||
|
||||
/**
|
||||
* Function to display an error related to an IMAP-query.
|
||||
* We need to do our own error management since we may receive NO responses on purpose (even BAD with SORT or THREAD)
|
||||
* so we call sqimap_error_box() if the function exists (sm >= 1.5) or use our own embedded code
|
||||
* @global array imap_error_titles
|
||||
* @param string $response the imap server response code
|
||||
* @param string $query the failed query
|
||||
* @param string $message an optional error message
|
||||
* @param string $link an optional link to try again
|
||||
*/
|
||||
* Function to display an error related to an IMAP-query.
|
||||
* We need to do our own error management since we may receive NO responses on purpose (even BAD with SORT or THREAD)
|
||||
* so we call sqimap_error_box() if the function exists (sm >= 1.5) or use our own embedded code
|
||||
* @global array imap_error_titles
|
||||
* @param string $response the imap server response code
|
||||
* @param string $query the failed query
|
||||
* @param string $message an optional error message
|
||||
* @param string $link an optional link to try again
|
||||
*/
|
||||
//@global array color sm colors array
|
||||
function sqimap_asearch_error_box($response, $query, $message, $link = '')
|
||||
{
|
||||
|
@ -142,11 +142,11 @@ function sqimap_asearch_error_box($response, $query, $message, $link = '')
|
|||
}
|
||||
|
||||
/**
|
||||
* This is a convenient way to avoid spreading if (isset(... all over the code
|
||||
* @param mixed $var any variable (reference)
|
||||
* @param mixed $def default value to return if unset (default is zls (''), pass 0 or array() when appropriate)
|
||||
* @return mixed $def if $var is unset, otherwise $var
|
||||
*/
|
||||
* This is a convenient way to avoid spreading if (isset(... all over the code
|
||||
* @param mixed $var any variable (reference)
|
||||
* @param mixed $def default value to return if unset (default is zls (''), pass 0 or array() when appropriate)
|
||||
* @return mixed $def if $var is unset, otherwise $var
|
||||
*/
|
||||
function asearch_nz(&$var, $def = '')
|
||||
{
|
||||
if (isset($var))
|
||||
|
@ -155,11 +155,11 @@ function asearch_nz(&$var, $def = '')
|
|||
}
|
||||
|
||||
/**
|
||||
* This should give the same results as PHP 4 >= 4.3.0's html_entity_decode(),
|
||||
* except it doesn't handle hex constructs
|
||||
* @param string $string string to unhtmlentity()
|
||||
* @return string decoded string
|
||||
*/
|
||||
* This should give the same results as PHP 4 >= 4.3.0's html_entity_decode(),
|
||||
* except it doesn't handle hex constructs
|
||||
* @param string $string string to unhtmlentity()
|
||||
* @return string decoded string
|
||||
*/
|
||||
function asearch_unhtmlentities($string) {
|
||||
$trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES));
|
||||
for ($i=127; $i<255; $i++) /* Add &#<dec>; entities */
|
||||
|
@ -172,11 +172,11 @@ function asearch_unhtmlentities($string) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Provide an easy way to dump the imap dialogue if $imap_asearch_debug_dump is TRUE
|
||||
* @global bool imap_asearch_debug_dump
|
||||
* @param string $var_name
|
||||
* @param string $var_var
|
||||
*/
|
||||
* Provide an easy way to dump the imap dialogue if $imap_asearch_debug_dump is TRUE
|
||||
* @global bool imap_asearch_debug_dump
|
||||
* @param string $var_name
|
||||
* @param string $var_var
|
||||
*/
|
||||
function s_debug_dump($var_name, $var_var)
|
||||
{
|
||||
global $imap_asearch_debug_dump;
|
||||
|
@ -193,16 +193,16 @@ function s_debug_dump($var_name, $var_var)
|
|||
}
|
||||
|
||||
/** Encode a string to quoted or literal as defined in rfc 3501
|
||||
*
|
||||
* - 4.3 String:
|
||||
* A quoted string is a sequence of zero or more 7-bit characters,
|
||||
* excluding CR and LF, with double quote (<">) characters at each end.
|
||||
* - 9. Formal Syntax:
|
||||
* quoted-specials = DQUOTE / "\"
|
||||
* @param string $what string to encode
|
||||
* @param string $charset search charset used
|
||||
* @return string encoded string
|
||||
*/
|
||||
*
|
||||
* - 4.3 String:
|
||||
* A quoted string is a sequence of zero or more 7-bit characters,
|
||||
* excluding CR and LF, with double quote (<">) characters at each end.
|
||||
* - 9. Formal Syntax:
|
||||
* quoted-specials = DQUOTE / "\"
|
||||
* @param string $what string to encode
|
||||
* @param string $charset search charset used
|
||||
* @return string encoded string
|
||||
*/
|
||||
function sqimap_asearch_encode_string($what, $charset)
|
||||
{
|
||||
if (strtoupper($charset) == 'ISO-2022-JP') // This should be now handled in imap_utf7_local?
|
||||
|
@ -213,16 +213,16 @@ function sqimap_asearch_encode_string($what, $charset)
|
|||
}
|
||||
|
||||
/**
|
||||
* Parses a user date string into an rfc 3501 date string
|
||||
* Handles space, slash, backslash, dot and comma as separators (and dash of course ;=)
|
||||
* @global array imap_asearch_months
|
||||
* @param string user date
|
||||
* @return array a preg_match-style array:
|
||||
* - [0] = fully formatted rfc 3501 date string (<day number>-<US month TLA>-<4 digit year>)
|
||||
* - [1] = day
|
||||
* - [2] = month
|
||||
* - [3] = year
|
||||
*/
|
||||
* Parses a user date string into an rfc 3501 date string
|
||||
* Handles space, slash, backslash, dot and comma as separators (and dash of course ;=)
|
||||
* @global array imap_asearch_months
|
||||
* @param string user date
|
||||
* @return array a preg_match-style array:
|
||||
* - [0] = fully formatted rfc 3501 date string (<day number>-<US month TLA>-<4 digit year>)
|
||||
* - [1] = day
|
||||
* - [2] = month
|
||||
* - [3] = year
|
||||
*/
|
||||
function sqimap_asearch_parse_date($what)
|
||||
{
|
||||
global $imap_asearch_months;
|
||||
|
@ -254,13 +254,13 @@ function sqimap_asearch_parse_date($what)
|
|||
}
|
||||
|
||||
/**
|
||||
* Build one criteria sequence
|
||||
* @global array imap_asearch_opcodes
|
||||
* @param string $opcode search opcode
|
||||
* @param string $what opcode argument
|
||||
* @param string $charset search charset
|
||||
* @return string one full criteria sequence
|
||||
*/
|
||||
* Build one criteria sequence
|
||||
* @global array imap_asearch_opcodes
|
||||
* @param string $opcode search opcode
|
||||
* @param string $what opcode argument
|
||||
* @param string $charset search charset
|
||||
* @return string one full criteria sequence
|
||||
*/
|
||||
function sqimap_asearch_build_criteria($opcode, $what, $charset)
|
||||
{
|
||||
global $imap_asearch_opcodes;
|
||||
|
@ -315,11 +315,11 @@ function sqimap_asearch_build_criteria($opcode, $what, $charset)
|
|||
}
|
||||
|
||||
/**
|
||||
* Another way to do array_values(array_unique(array_merge($to, $from)));
|
||||
* @param array $to to array (reference)
|
||||
* @param array $from from array
|
||||
* @return array uniquely merged array
|
||||
*/
|
||||
* Another way to do array_values(array_unique(array_merge($to, $from)));
|
||||
* @param array $to to array (reference)
|
||||
* @param array $from from array
|
||||
* @return array uniquely merged array
|
||||
*/
|
||||
function sqimap_array_merge_unique(&$to, $from)
|
||||
{
|
||||
if (empty($to))
|
||||
|
@ -333,13 +333,13 @@ function sqimap_array_merge_unique(&$to, $from)
|
|||
}
|
||||
|
||||
/**
|
||||
* Run the imap SEARCH command as defined in rfc 3501
|
||||
* @link http://www.ietf.org/rfc/rfc3501.txt
|
||||
* @param resource $imapConnection the current imap stream
|
||||
* @param string $search_string the full search expression eg "ALL RECENT"
|
||||
* @param string $search_charset charset to use or zls ('')
|
||||
* @return array an IDs or UIDs array of matching messages or an empty array
|
||||
*/
|
||||
* Run the imap SEARCH command as defined in rfc 3501
|
||||
* @link http://www.ietf.org/rfc/rfc3501.txt
|
||||
* @param resource $imapConnection the current imap stream
|
||||
* @param string $search_string the full search expression eg "ALL RECENT"
|
||||
* @param string $search_charset charset to use or zls ('')
|
||||
* @return array an IDs or UIDs array of matching messages or an empty array
|
||||
*/
|
||||
function sqimap_run_search($imapConnection, $search_string, $search_charset)
|
||||
{
|
||||
//For some reason, this seems to happen and forbids searching servers not allowing OPTIONAL [CHARSET]
|
||||
|
@ -375,11 +375,11 @@ function sqimap_run_search($imapConnection, $search_string, $search_charset)
|
|||
}
|
||||
|
||||
/**
|
||||
* @global bool allow_charset_search user setting
|
||||
* @global array languages sm languages array
|
||||
* @global string squirrelmail_language user language setting
|
||||
* @return string the user defined charset if $allow_charset_search is TRUE else zls ('')
|
||||
*/
|
||||
* @global bool allow_charset_search user setting
|
||||
* @global array languages sm languages array
|
||||
* @global string squirrelmail_language user language setting
|
||||
* @return string the user defined charset if $allow_charset_search is TRUE else zls ('')
|
||||
*/
|
||||
function sqimap_asearch_get_charset()
|
||||
{
|
||||
global $allow_charset_search, $languages, $squirrelmail_language;
|
||||
|
@ -390,16 +390,16 @@ function sqimap_asearch_get_charset()
|
|||
}
|
||||
|
||||
/**
|
||||
* Convert sm internal sort to imap sort taking care of:
|
||||
* - user defined date sorting (ARRIVAL vs DATE)
|
||||
* - if the searched mailbox is the sent folder then TO is being used instead of FROM
|
||||
* - reverse order by using REVERSE
|
||||
* @param string $mailbox mailbox name to sort
|
||||
* @param integer $sort_by sm sort criteria index
|
||||
* @global bool internal_date_sort sort by arrival date instead of message date
|
||||
* @global string sent_folder sent folder name
|
||||
* @return string imap sort criteria
|
||||
*/
|
||||
* Convert sm internal sort to imap sort taking care of:
|
||||
* - user defined date sorting (ARRIVAL vs DATE)
|
||||
* - if the searched mailbox is the sent folder then TO is being used instead of FROM
|
||||
* - reverse order by using REVERSE
|
||||
* @param string $mailbox mailbox name to sort
|
||||
* @param integer $sort_by sm sort criteria index
|
||||
* @global bool internal_date_sort sort by arrival date instead of message date
|
||||
* @global string sent_folder sent folder name
|
||||
* @return string imap sort criteria
|
||||
*/
|
||||
function sqimap_asearch_get_sort_criteria($mailbox, $sort_by)
|
||||
{
|
||||
global $internal_date_sort, $sent_folder;
|
||||
|
@ -415,10 +415,10 @@ function sqimap_asearch_get_sort_criteria($mailbox, $sort_by)
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $cur_mailbox unformatted mailbox name
|
||||
* @param array $boxes_unformatted selectable mailbox unformatted names array (reference)
|
||||
* @return array sub mailboxes unformatted names
|
||||
*/
|
||||
* @param string $cur_mailbox unformatted mailbox name
|
||||
* @param array $boxes_unformatted selectable mailbox unformatted names array (reference)
|
||||
* @return array sub mailboxes unformatted names
|
||||
*/
|
||||
function sqimap_asearch_get_sub_mailboxes($cur_mailbox, &$mboxes_array)
|
||||
{
|
||||
$sub_mboxes_array = array();
|
||||
|
@ -431,18 +431,18 @@ function sqimap_asearch_get_sub_mailboxes($cur_mailbox, &$mboxes_array)
|
|||
}
|
||||
|
||||
/**
|
||||
* Create the search query strings for all given criteria and merge results for every mailbox
|
||||
* @param resource $imapConnection
|
||||
* @param array $mailbox_array (reference)
|
||||
* @param array $biop_array (reference)
|
||||
* @param array $unop_array (reference)
|
||||
* @param array $where_array (reference)
|
||||
* @param array $what_array (reference)
|
||||
* @param array $exclude_array (reference)
|
||||
* @param array $sub_array (reference)
|
||||
* @param array $mboxes_array selectable unformatted mailboxes names (reference)
|
||||
* @return array array(mailbox => array(UIDs))
|
||||
*/
|
||||
* Create the search query strings for all given criteria and merge results for every mailbox
|
||||
* @param resource $imapConnection
|
||||
* @param array $mailbox_array (reference)
|
||||
* @param array $biop_array (reference)
|
||||
* @param array $unop_array (reference)
|
||||
* @param array $where_array (reference)
|
||||
* @param array $what_array (reference)
|
||||
* @param array $exclude_array (reference)
|
||||
* @param array $sub_array (reference)
|
||||
* @param array $mboxes_array selectable unformatted mailboxes names (reference)
|
||||
* @return array array(mailbox => array(UIDs))
|
||||
*/
|
||||
function sqimap_asearch($imapConnection, &$mailbox_array, &$biop_array, &$unop_array, &$where_array, &$what_array, &$exclude_array, &$sub_array, &$mboxes_array)
|
||||
{
|
||||
|
||||
|
@ -455,7 +455,7 @@ function sqimap_asearch($imapConnection, &$mailbox_array, &$biop_array, &$unop_a
|
|||
/* We loop one more time than the real array count, so the last search gets fired */
|
||||
for ($cur_crit=0,$iCnt=count($where_array); $cur_crit <= $iCnt; ++$cur_crit) {
|
||||
if (empty($exclude_array[$cur_crit])) {
|
||||
$next_mailbox = $mailbox_array[$cur_crit];
|
||||
$next_mailbox = (isset($mailbox_array[$cur_crit])) ? $mailbox_array[$cur_crit] : false;
|
||||
if ($next_mailbox != $cur_mailbox) {
|
||||
$search_string = trim($search_string); /* Trim out last space */
|
||||
if ($cur_mailbox == 'All Folders')
|
||||
|
@ -477,35 +477,51 @@ function sqimap_asearch($imapConnection, &$mailbox_array, &$biop_array, &$unop_a
|
|||
|
||||
}
|
||||
if (isset($where_array[$cur_crit]) && empty($exclude_array[$cur_crit])) {
|
||||
$criteria = sqimap_asearch_build_criteria($where_array[$cur_crit], $what_array[$cur_crit], $search_charset);
|
||||
if (!empty($criteria)) {
|
||||
//$criteria = 'ALL '. $criteria;
|
||||
$unop = $unop_array[$cur_crit];
|
||||
for ($crit = $cur_crit; $crit < count($where_array); $crit++) {
|
||||
$criteria = trim(sqimap_asearch_build_criteria($where_array[$crit], $what_array[$crit], $search_charset));
|
||||
if (!empty($criteria) && empty($exclude_array[$crit])) {
|
||||
if (asearch_nz($mailbox_array[$crit]) == $cur_mailbox) {
|
||||
$unop = $unop_array[$crit];
|
||||
if (!empty($unop)) {
|
||||
$criteria = $unop . ' ' . $criteria;
|
||||
} else {
|
||||
$criteria = 'ALL ' . $criteria;
|
||||
}
|
||||
/* We need to infix the next non-excluded criteria's biop if it's the same mailbox */
|
||||
$next_biop = '';
|
||||
for ($next_crit = $cur_crit+1; $next_crit <= count($where_array); $next_crit++) {
|
||||
if (empty($exclude_array[$next_crit])) {
|
||||
if (asearch_nz($mailbox_array[$next_crit]) == $cur_mailbox) {
|
||||
$next_biop = asearch_nz($biop_array[$next_crit]);
|
||||
if ($next_biop == 'OR' || $next_biop == 'ALL') {
|
||||
$next_criterium = sqimap_asearch_build_criteria($where_array[$next_crit], $what_array[$next_crit], $search_charset);
|
||||
$aCriteria[] = array($biop_array[$crit], $criteria);
|
||||
}
|
||||
}
|
||||
// unset something
|
||||
$exclude_array[$next_crit] = true;
|
||||
$criteria .= $next_biop . ' '. $next_criterium;
|
||||
$exclude_array[$crit] = true;
|
||||
}
|
||||
$aSearch = array();
|
||||
for($i=0,$iCnt=count($aCriteria);$i<$iCnt;++$i) {
|
||||
$cur_biop = $aCriteria[$i][0];
|
||||
$next_biop = (isset($aCriteria[$i+1][0])) ? $aCriteria[$i+1][0] : false;
|
||||
if ($next_biop != $cur_biop && $next_biop == 'OR') {
|
||||
$aSearch[] = 'OR '.$aCriteria[$i][1];
|
||||
} else if ($cur_biop != 'OR') {
|
||||
$aSearch[] = 'ALL '.$aCriteria[$i][1];
|
||||
} else { // or only supports 2 search keys so we need to create a parenthized list
|
||||
$prev_biop = (isset($aCriteria[$i-1][0])) ? $aCriteria[$i-1][0] : false;
|
||||
if ($prev_biop == $cur_biop) {
|
||||
$last = $aSearch[$i-1];
|
||||
if (!substr($last,-1) == ')') {
|
||||
$aSearch[$i-1] = "(OR $last";
|
||||
$aSearch[] = $aCriteria[$i][1].')';
|
||||
} else {
|
||||
$sEnd = '';
|
||||
while ($last && substr($last,-1) == ')') {
|
||||
$last = substr($last,0,-1);
|
||||
$sEnd .= ')';
|
||||
}
|
||||
$aSearch[$i-1] = "(OR $last";
|
||||
$aSearch[] = $aCriteria[$i][1].$sEnd.')';
|
||||
}
|
||||
} else {
|
||||
$aSearch[] = $aCriteria[$i][1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//if ($next_biop == 'OR')
|
||||
// $criteria = $next_biop . ' ' . $criteria;
|
||||
$search_string .= $criteria;
|
||||
//$cur_biop = asearch_nz($biop_array[$cur_crit]);
|
||||
}
|
||||
$search_string .= implode(' ',$aSearch);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue