Source for file search.php

Documentation is available at search.php

  1. <?php
  2.  
  3. /**
  4.  * search.php
  5.  *
  6.  * IMAP search page
  7.  *
  8.  * Subfolder search idea from Patch #806075 by Thomas Pohl xraven at users.sourceforge.net. Thanks Thomas!
  9.  *
  10.  * @author Alex Lemaresquier - Brainstorm <alex at brainstorm.fr>
  11.  * @copyright &copy; 1999-2006 The SquirrelMail Project Team
  12.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  13.  * @version $Id: search.php,v 1.167 2006/08/31 18:12:27 stevetruckstuff Exp $
  14.  * @package squirrelmail
  15.  * @subpackage search
  16.  * @link http://www.ietf.org/rfc/rfc3501.txt
  17.  * @todo explain why references are used in function calls
  18.  */
  19.  
  20. /**
  21.  * Include the SquirrelMail initialization file.
  22.  */
  23. require('../include/init.php');
  24.  
  25. /** SquirrelMail required files.
  26.  */
  27. require_once(SM_PATH . 'functions/imap_asearch.php');
  28. require_once(SM_PATH . 'functions/imap_messages.php');
  29. require_once(SM_PATH . 'functions/imap_general.php');
  30. require_once(SM_PATH . 'functions/mime.php');
  31. require_once(SM_PATH . 'functions/mailbox_display.php'); //getButton()
  32. require_once(SM_PATH . 'functions/forms.php');
  33. require_once(SM_PATH . 'functions/date.php');
  34.  
  35. /** Prefs array ordinals. Must match $recent_prefkeys and $saved_prefkeys
  36.  */
  37. define('ASEARCH_WHERE', 0);
  38. define('ASEARCH_MAILBOX', 1);
  39. define('ASEARCH_WHAT', 2);
  40. define('ASEARCH_UNOP', 3);
  41. define('ASEARCH_BIOP', 4);
  42. define('ASEARCH_EXCLUDE', 5);
  43. define('ASEARCH_SUB', 6);
  44. define('ASEARCH_MAX', 7);
  45.  
  46. /** Name of session var
  47.  */
  48. define('ASEARCH_CRITERIA', 'criteria');
  49.  
  50.  
  51. /**
  52.  * Array sort callback used to sort $imap_asearch_options
  53.  * @param string $a 
  54.  * @param string $b 
  55.  * @return bool strcoll()-like result
  56.  * @since 1.5.0
  57.  * @private
  58.  */
  59. function asearch_unhtml_strcoll($a, $b)
  60. {
  61.     // FIXME: Translation policy says "no html entities in translations"
  62. }
  63.  
  64. /**
  65.  * @param string $mailbox mailbox name or special case 'All Folders'
  66.  * @return string mailbox name ready to display (utf7 decoded or localized 'All Folders')
  67.  * @since 1.5.0
  68.  * @private
  69.  */
  70. function asearch_get_mailbox_display($mailbox)
  71. {
  72.     if ($mailbox == 'All Folders') {
  73.         return _("All Folders");
  74.     } elseif (strtoupper($mailbox) == 'INBOX') {
  75.         return _("INBOX");
  76.     }
  77.     return imap_utf7_decode_local($mailbox);
  78. }
  79.  
  80. /**
  81.  * @param array $input_array array to serialize
  82.  * @return string a string containing a byte-stream representation of value that can be stored anywhere
  83.  * @since 1.5.0
  84.  * @private
  85.  */
  86. function asearch_serialize(&$input_array)
  87. {
  88.     global $search_advanced;
  89.     if ($search_advanced)
  90.         return serialize($input_array);
  91.     return $input_array[0];
  92. }
  93.  
  94. /**
  95.  * @param string $input_string string to unserialize
  96.  * @return array 
  97.  * @since 1.5.0
  98.  * @private
  99.  */
  100. function asearch_unserialize($input_string)
  101. {
  102.     global $search_advanced;
  103.     if ($search_advanced)
  104.         return unserialize($input_string);
  105.     return array($input_string);
  106. }
  107.  
  108. /**
  109.  * Gets user's advanced search preferences
  110.  *
  111.  * Arguments are different in 1.5.0.
  112.  * @param string $key the pref key
  113.  * @param integer $index the pref key index
  114.  * @param string $default default value
  115.  * @return string pref value
  116.  * @since 1.5.0
  117.  * @private
  118.  */
  119. function asearch_getPref(&$key, $index, $default = '')
  120. {
  121.     global $data_dir, $username, $search_advanced;
  122.     return getPref($data_dir, $username, $key . ($index + !$search_advanced), $default);
  123. }
  124.  
  125. /**
  126.  * Sets user's advanced search preferences
  127.  *
  128.  * Arguments are different in 1.5.0.
  129.  * @param string $key the pref key
  130.  * @param integer $index the pref key index
  131.  * @param string $value pref value to set
  132.  * @return bool status
  133.  * @since 1.5.0
  134.  * @private
  135.  */
  136. function asearch_setPref(&$key, $index, $value)
  137. {
  138.     global $data_dir, $username, $search_advanced;
  139.     return setPref($data_dir, $username, $key . ($index + !$search_advanced), $value);
  140. }
  141.  
  142. /**
  143.  * Deletes user's advanced search preferences
  144.  *
  145.  * Arguments are different in 1.5.0.
  146.  * @param string $key the pref key
  147.  * @param integer $index the pref key index
  148.  * @return bool status
  149.  * @since 1.5.0
  150.  * @private
  151.  */
  152. function asearch_removePref(&$key, $index)
  153. {
  154.     global $data_dir, $username, $search_advanced;
  155.     return removePref($data_dir, $username, $key . ($index + !$search_advanced));
  156. }
  157.  
  158. /**
  159.  * Sanity checks, done before running the imap command and before calling push_recent
  160.  * @param array $where_array search location data
  161.  * @param array $what_array search criteria data
  162.  * @param array $exclude_array excluded criteria data
  163.  * @return string error message or empty string
  164.  * @since 1.5.0
  165.  * @private
  166.  */
  167. function asearch_check_query(&$where_array, &$what_array, &$exclude_array)
  168. {
  169.     global $imap_asearch_opcodes;
  170.  
  171.     if (empty($where_array))
  172.         return _("Please enter something to search for");
  173.     if (count($exclude_array) == count($where_array))
  174.         return _("There must be at least one criteria to search for");
  175.     for ($crit_num = 0; $crit_num < count($where_array); $crit_num++) {
  176.         $where = $where_array[$crit_num];
  177.         $what = $what_array[$crit_num];
  178.         if (!(($what == '') ^ ($imap_asearch_opcodes[$where] != '')))
  179.             return _("Error in criteria argument");
  180.     }
  181.     return '';
  182. }
  183.  
  184. /**
  185.  * Read the recent searches from the prefs
  186.  *
  187.  * Function arguments are different in 1.5.0
  188.  * @return array recent searches
  189.  * @since 1.5.0
  190.  * @private
  191.  */
  192. {
  193.     global $recent_prefkeys, $search_memory;
  194.  
  195.     $recent_array = array();
  196.     $recent_num = 0;
  197.     for ($pref_num = 0; $pref_num < $search_memory; $pref_num++) {
  198.         foreach ($recent_prefkeys as $prefkey) {
  199.             $pref = asearch_getPref($prefkey, $pref_num);
  200. /*            if (!empty($pref))*/
  201.                 $recent_array[$prefkey][$recent_num] = $pref;
  202.         }
  203.         if (empty($recent_array[$recent_prefkeys[0]][$recent_num])) {
  204.             foreach ($recent_prefkeys as $key) {
  205.                 array_pop($recent_array[$key]);
  206.             }
  207. //            break; //Disabled to support old search code broken prefs
  208.         }
  209.         else
  210.             $recent_num++;
  211.     }
  212.     return $recent_array;
  213. }
  214.  
  215. /**
  216.  * Read the saved searches from the prefs
  217.  *
  218.  * Function arguments are different in 1.5.0
  219.  * @return array saved searches
  220.  * @since 1.5.0
  221.  * @private
  222.  */
  223. function asearch_read_saved()
  224. {
  225.     global $saved_prefkeys;
  226.  
  227.     $saved_array = array();
  228.     $saved_key = $saved_prefkeys[0];
  229.     for ($saved_count = 0; ; $saved_count++) {
  230.         $pref = asearch_getPref($saved_key, $saved_count);
  231.         if (empty($pref))
  232.             break;
  233.     }
  234.     for ($saved_num = 0; $saved_num < $saved_count; $saved_num++) {
  235.         foreach ($saved_prefkeys as $key) {
  236.             $saved_array[$key][$saved_num] = asearch_getPref($key, $saved_num);
  237.         }
  238.     }
  239.     return $saved_array;
  240. }
  241.  
  242. /**
  243.  * Save a recent search to the prefs
  244.  *
  245.  * Function arguments are different in 1.5.0
  246.  * @param integer $recent_index 
  247.  * @since 1.5.0
  248.  * @private
  249.  */
  250. function asearch_save_recent($recent_index)
  251. {
  252.  
  253.     $saved_array = asearch_read_saved();
  254.     if (isset($saved_array[$saved_prefkeys[0]])) {
  255.         $saved_index = count($saved_array[$saved_prefkeys[0]]);
  256.     } else {
  257.         $saved_index = 0;
  258.     }
  259.     $recent_array = asearch_read_recent();
  260.     $n = 0;
  261.     foreach ($recent_prefkeys as $key) {
  262.         $recent_slice = array_slice($recent_array[$key], $recent_index, 1);
  263.         if (!empty($recent_slice[0]))
  264.             asearch_setPref($saved_prefkeys[$n], $saved_index, $recent_slice[0]);
  265.         else
  266.             asearch_removePref($saved_prefkeys[$n], $saved_index);
  267.         $n++;
  268.     }
  269. }
  270.  
  271. /**
  272.  * Write a recent search to prefs
  273.  *
  274.  * Function arguments are different in 1.5.0
  275.  * @param array $recent_array 
  276.  * @since 1.5.0
  277.  * @private
  278.  */
  279. function asearch_write_recent(&$recent_array)
  280. {
  281.     global $recent_prefkeys, $search_memory;
  282.  
  283.     $recent_count = min($search_memory, count($recent_array[$recent_prefkeys[0]]));
  284.     for ($recent_num = 0; $recent_num < $recent_count; $recent_num++) {
  285.         foreach ($recent_prefkeys as $key) {
  286.             asearch_setPref($key, $recent_num, $recent_array[$key][$recent_num]);
  287.         }
  288.     }
  289.     for (; $recent_num < $search_memory; $recent_num++) {
  290.         foreach ($recent_prefkeys as $key) {
  291.             asearch_removePref($key, $recent_num);
  292.         }
  293.     }
  294. }
  295.  
  296. /**
  297.  * Remove a recent search from prefs
  298.  *
  299.  * Function arguments are different in 1.5.0
  300.  * @param integer $forget_index removed search number
  301.  * @since 1.5.0
  302.  * @private
  303.  */
  304. function asearch_forget_recent($forget_index)
  305. {
  306.     global $recent_prefkeys;
  307.  
  308.     $recent_array = asearch_read_recent();
  309.     foreach ($recent_prefkeys as $key) {
  310.         array_splice($recent_array[$key], $forget_index, 1);
  311.     }
  312.     asearch_write_recent($recent_array);
  313. }
  314.  
  315. /**
  316.  * Find a recent search in the prefs (used to avoid saving duplicates)
  317.  * @param array $recent_array 
  318.  * @param array $mailbox_array 
  319.  * @param array $biop_array 
  320.  * @param array $unop_array 
  321.  * @param array $where_array 
  322.  * @param array $what_array 
  323.  * @param array $exclude_array 
  324.  * @param array $sub_array 
  325.  * @return integer 
  326.  * @since 1.5.0
  327.  * @private
  328.  */
  329. function asearch_find_recent(&$recent_array, &$mailbox_array, &$biop_array, &$unop_array, &$where_array, &$what_array, &$exclude_array, &$sub_array)
  330. {
  331.  
  332.     $where_string = asearch_serialize($where_array);
  333.     $mailbox_string = asearch_serialize($mailbox_array);
  334.     $what_string = asearch_serialize($what_array);
  335.     $unop_string = asearch_serialize($unop_array);
  336.     if ($search_advanced) {
  337.         $biop_string = asearch_serialize($biop_array);
  338.         $exclude_string = asearch_serialize($exclude_array);
  339.         $sub_string = asearch_serialize($sub_array);
  340.     }
  341.     $recent_count = count($recent_array[$recent_prefkeys[ASEARCH_WHERE]]);
  342.     for ($recent_num = 0; $recent_num < $recent_count; $recent_num++) {
  343.         if (isset($recent_array[$recent_prefkeys[ASEARCH_WHERE]][$recent_num])) {
  344.             if (
  345.                     $where_string == $recent_array[$recent_prefkeys[ASEARCH_WHERE]][$recent_num] &&
  346.                     $mailbox_string == $recent_array[$recent_prefkeys[ASEARCH_MAILBOX]][$recent_num] &&
  347.                     $what_string == $recent_array[$recent_prefkeys[ASEARCH_WHAT]][$recent_num] &&
  348.                     $unop_string == $recent_array[$recent_prefkeys[ASEARCH_UNOP]][$recent_num] &&
  349.                     ((!$search_advanced) ||
  350.                         ($biop_string == $recent_array[$recent_prefkeys[ASEARCH_BIOP]][$recent_num] &&
  351.                         $exclude_string == $recent_array[$recent_prefkeys[ASEARCH_EXCLUDE]][$recent_num] &&
  352.                         $sub_string == $recent_array[$recent_prefkeys[ASEARCH_SUB]][$recent_num]))
  353.                     )
  354.                 return $recent_num;
  355.         }
  356.     }
  357.     return -1;
  358. }
  359.  
  360. /**
  361.  * Push a recent search into the prefs
  362.  * @param array $recent_array 
  363.  * @param array $mailbox_array 
  364.  * @param array $biop_array 
  365.  * @param array $unop_array 
  366.  * @param array $where_array 
  367.  * @param array $what_array 
  368.  * @param array $exclude_array 
  369.  * @param array $sub_array 
  370.  * @since 1.5.0
  371.  * @private
  372.  */
  373. function asearch_push_recent(&$mailbox_array, &$biop_array, &$unop_array, &$where_array, &$what_array, &$exclude_array, &$sub_array)
  374. {
  375.     global $recent_prefkeys, $search_memory;
  376.     //global $what; // Hack to access issued search from read_body.php
  377.     $what = 1;
  378.     /**
  379.      * Update search history and store it in the session so we can retrieve the
  380.      * issued search when returning from an external page like read_body.php
  381.      */
  382.     $criteria[$what] = array($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  383.     sqsession_register($criteria, ASEARCH_CRITERIA);
  384.     if ($search_memory > 0) {
  385.         $recent_array = asearch_read_recent();
  386.         $recent_found = asearch_find_recent($recent_array, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  387.         if ($recent_found >= 0) { // Remove identical recent
  388.             foreach ($recent_prefkeys as $key) {
  389.                 array_splice($recent_array[$key], $recent_found, 1);
  390.             }
  391.         }
  392.         $input = array($where_array, $mailbox_array, $what_array, $unop_array, $biop_array, $exclude_array, $sub_array);
  393.         $i = 0;
  394.         foreach ($recent_prefkeys as $key) {
  395.             array_unshift($recent_array[$key], asearch_serialize($input[$i]));
  396.             $i++;
  397.         }
  398.         asearch_write_recent($recent_array);
  399.     }
  400. }
  401.  
  402. /**
  403.  * Edit a recent search
  404.  *
  405.  * Function arguments are different in 1.5.0
  406.  * @global array mailbox_array searched mailboxes
  407.  * @param mixed $index 
  408.  * @since 1.5.0
  409.  * @private
  410.  */
  411. function asearch_edit_recent($index)
  412. {
  413.  
  414.     $where_array = asearch_unserialize(asearch_getPref($recent_prefkeys[ASEARCH_WHERE], $index));
  415.     $mailbox_array = asearch_unserialize(asearch_getPref($recent_prefkeys[ASEARCH_MAILBOX], $index));
  416.     $what_array = asearch_unserialize(asearch_getPref($recent_prefkeys[ASEARCH_WHAT], $index));
  417.     $unop_array = asearch_unserialize(asearch_getPref($recent_prefkeys[ASEARCH_UNOP], $index));
  418.     if ($search_advanced) {
  419.         $biop_array = asearch_unserialize(asearch_getPref($recent_prefkeys[ASEARCH_BIOP], $index));
  420.         $exclude_array = asearch_unserialize(asearch_getPref($recent_prefkeys[ASEARCH_EXCLUDE], $index));
  421.         $sub_array = asearch_unserialize(asearch_getPref($recent_prefkeys[ASEARCH_SUB], $index));
  422.     }
  423. }
  424.  
  425. /**
  426.  * Get last search criteria from session or prefs
  427.  *
  428.  * Function arguments are different in 1.5.0
  429.  * FIXME, try to avoid globals
  430.  * @param mixed $index 
  431.  * @since 1.5.0
  432.  * @private
  433.  */
  434. function asearch_edit_last($index) {
  435.     if (sqGetGlobalVar(ASEARCH_CRITERIA, $criteria, SQ_SESSION)) {
  436.         global $where_array, $mailbox_array, $what_array, $unop_array;
  437.         global $biop_array, $exclude_array, $sub_array;
  438.         $mailbox_array = $criteria[$index][0];
  439.         $biop_array = $criteria[$index][1];
  440.         $unop_array = $criteria[$index][2];
  441.         $where_array = $criteria[$index][3];
  442.         $what_array = $criteria[$index][4];
  443.         $exclude_array = $criteria[$index][5];
  444.         $sub_array = $criteria[$index][6];
  445.         unset($criteria[$index]);
  446.         //sqsession_unregister(ASEARCH_CRITERIA);
  447.     } else {
  448.         global $search_memory;
  449.         if ($search_memory > 0) {
  450.             asearch_edit_recent(0);
  451.         }
  452.     }
  453. }
  454.  
  455. /**
  456.  * Edit a saved search
  457.  *
  458.  * Function arguments are different in 1.5.0
  459.  * @param mixed $index 
  460.  * @since 1.5.0
  461.  * @private
  462.  */
  463. function asearch_edit_saved($index)
  464. {
  465.  
  466.     $where_array = asearch_unserialize(asearch_getPref($saved_prefkeys[ASEARCH_WHERE], $index));
  467.     $mailbox_array = asearch_unserialize(asearch_getPref($saved_prefkeys[ASEARCH_MAILBOX], $index));
  468.     $what_array = asearch_unserialize(asearch_getPref($saved_prefkeys[ASEARCH_WHAT], $index));
  469.     $unop_array = asearch_unserialize(asearch_getPref($saved_prefkeys[ASEARCH_UNOP], $index));
  470.     if ($search_advanced) {
  471.         $biop_array = asearch_unserialize(asearch_getPref($saved_prefkeys[ASEARCH_BIOP], $index));
  472.         $exclude_array = asearch_unserialize(asearch_getPref($saved_prefkeys[ASEARCH_EXCLUDE], $index));
  473.         $sub_array = asearch_unserialize(asearch_getPref($saved_prefkeys[ASEARCH_SUB], $index));
  474.     }
  475. }
  476.  
  477. /**
  478.  * Write a saved search to the prefs
  479.  *
  480.  * Function arguments are different in 1.5.0
  481.  * @param array $saved_array 
  482.  * @since 1.5.0
  483.  * @private
  484.  */
  485. function asearch_write_saved(&$saved_array)
  486. {
  487.     global $saved_prefkeys;
  488.  
  489.     $saved_count = count($saved_array[$saved_prefkeys[0]]);
  490.     for ($saved_num=0; $saved_num < $saved_count; $saved_num++) {
  491.         foreach ($saved_prefkeys as $key) {
  492.             asearch_setPref($key, $saved_num, $saved_array[$key][$saved_num]);
  493.         }
  494.     }
  495.     foreach ($saved_prefkeys as $key) {
  496.         asearch_removePref($key, $saved_count);
  497.     }
  498. }
  499.  
  500. /**
  501.  * Delete a saved search from the prefs
  502.  *
  503.  * Function arguments are different in 1.5.0
  504.  * @param integer $saved_index 
  505.  * @since 1.5.0
  506.  * @private
  507.  */
  508. function asearch_delete_saved($saved_index)
  509. {
  510.     global $saved_prefkeys;
  511.  
  512.     $saved_array = asearch_read_saved();
  513.     $asearch_keys = $saved_prefkeys;
  514.     foreach ($asearch_keys as $key) {
  515.         array_splice($saved_array[$key], $saved_index, 1);
  516.     }
  517.     asearch_write_saved($saved_array);
  518. }
  519.  
  520. /** Translate the input date to imap date to local date display,
  521.  * so the user can know if the date is wrong or illegal
  522.  * @param string $what date string
  523.  * @return string locally formatted date or error text
  524.  * @since 1.5.0
  525.  * @private
  526.  */
  527. function asearch_get_date_display(&$what)
  528. {
  529.     $what_parts = sqimap_asearch_parse_date($what);
  530.     if (count($what_parts) == 4) {
  531.         if (checkdate($what_parts[2], $what_parts[1], $what_parts[3]))
  532.             return date_intl(_("M j, Y"), mktime(0,0,0,$what_parts[2],$what_parts[1],$what_parts[3]));
  533.             //return $what_parts[1] . ' ' . getMonthName($what_parts[2]) . ' ' . $what_parts[3];
  534.         return _("(Illegal date)");
  535.     }
  536.     return _("(Wrong date)");
  537. }
  538.  
  539. /**
  540.  * Translate the query to rough natural display
  541.  * @param array $color 
  542.  * @param array $mailbox_array 
  543.  * @param array $biop_array 
  544.  * @param array $unop_array 
  545.  * @param array $where_array 
  546.  * @param array $what_array 
  547.  * @param array $exclude_array 
  548.  * @param array $sub_array 
  549.  * @return string rough natural query ready to display
  550.  * @since 1.5.0
  551.  * @private
  552.  */
  553. function asearch_get_query_display(&$color, &$mailbox_array, &$biop_array, &$unop_array, &$where_array, &$what_array, &$exclude_array, &$sub_array)
  554. {
  555.     global $imap_asearch_biops_in, $imap_asearch_biops, $imap_asearch_unops, $imap_asearch_options;
  556.     global $imap_asearch_opcodes;
  557.  
  558.     $last_mailbox = $mailbox_array[0];
  559.     if (empty($last_mailbox))
  560.         $last_mailbox = 'INBOX';
  561.     $query_display = '';
  562.     for ($crit_num=0; $crit_num < count($where_array); $crit_num++) {
  563.         if ((!isset($exclude_array[$crit_num])) || (!$exclude_array[$crit_num])) {
  564.             $cur_mailbox = $mailbox_array[$crit_num];
  565.             if (empty($cur_mailbox))
  566.                 $cur_mailbox = 'INBOX';
  567.             $biop = asearch_nz($biop_array[$crit_num]);
  568.             if (($query_display == '') || ($cur_mailbox != $last_mailbox)) {
  569.                 $mailbox_display = ' <span class="mailbox">' . htmlspecialchars(asearch_get_mailbox_display($cur_mailbox)) . '</span>';
  570.                 if ($query_display == '')
  571.                     $biop_display = _("In");
  572.                 else
  573.                     $biop_display = $imap_asearch_biops_in[$biop];
  574.                 $last_mailbox = $cur_mailbox;
  575.             }
  576.             else {
  577.                 $mailbox_display = '';
  578.                 $biop_display = $imap_asearch_biops[$biop];
  579.             }
  580.             $unop = $unop_array[$crit_num];
  581.             $unop_display = $imap_asearch_unops[$unop];
  582.             if ($unop_display != '')
  583.                 $unop_display .= ' ';
  584.             $where = $where_array[$crit_num];
  585.             $where_display = $unop_display . asearch_nz($imap_asearch_options[$where], $where);
  586.             $what_type = $imap_asearch_opcodes[$where];
  587.             $what = $what_array[$crit_num];
  588.             if ($what_type) { /* Check opcode parameter */
  589.                 if ($what == '')
  590.                     $what_display = ' <span class="error">' . _("(Missing argument)") .'</span>';
  591.                 else {
  592.                     if ($what_type == 'adate')
  593.                         $what_display = asearch_get_date_display($what);
  594.                     else
  595.                         $what_display = htmlspecialchars($what);
  596.                     $what_display = ' <span class="value">' . $what_display . '</span>';
  597.                 }
  598.             }
  599.             else {
  600.                 if ($what)
  601.                     $what_display = ' <span class="error">' . _("(Spurious argument)") .'</span>';
  602.                 else
  603.                     $what_display = '';
  604.             }
  605.             if ($mailbox_display != '')
  606.                 $query_display .= ' <span class="operator">' . $biop_display . '</span>' . $mailbox_display . ' <span class="conditions">' . $where_display . '</span>' . $what_display;
  607.             else
  608.                 $query_display .= ' <span class="operator">' . $biop_display . '</span> <span class="conditions">' . $where_display . '</span>' . $what_display;
  609.         }
  610.     }
  611.     return $query_display;
  612. }
  613.  
  614. /**
  615.  * Creates button
  616.  *
  617.  * @deprecated see form functions available in 1.5.1 and 1.4.3.
  618.  * @param string $type 
  619.  * @param string $name 
  620.  * @param string $value 
  621.  * @param string $js 
  622.  * @param bool $enabled 
  623.  */
  624. function getButton($type, $name, $value, $js = '', $enabled = TRUE) {
  625.     $disabled = ( $enabled ? '' : 'disabled ' );
  626.     $js = ( $js ? $js.' ' : '' );
  627.     return '<input '.$disabled.$js.
  628.             'type="'.$type.
  629.             '" name="'.$name.
  630.             '" value="'.$value .
  631.             '" style="padding: 0px; margin: 0px" />';
  632. }
  633.  
  634. /**
  635.  * Print a whole query array, recent or saved
  636.  *
  637.  * Function arguments are different in 1.5.0
  638.  * @param array $boxes (unused)
  639.  * @param array $query_array 
  640.  * @param mixed $query_keys 
  641.  * @param array $action_array 
  642.  * @param mixed $title 
  643.  * @param string $show_pref 
  644.  * @since 1.5.0
  645.  * @private
  646.  */
  647. function asearch_print_query_array(&$boxes, &$query_array, &$query_keys, &$action_array, $title, $show_pref)
  648. {
  649.     global $data_dir, $username;
  650.     global $icon_theme_path;
  651.     global $oTemplate;
  652.  
  653.     $show_flag = getPref($data_dir, $username, $show_pref, 0) & 1;
  654.     $a = array();
  655.     $main_key = $query_keys[ASEARCH_WHERE];
  656.     $query_count = count($query_array[$main_key]);
  657.     for ($query_num = 0, $row_num = 0; $query_num < $query_count; $query_num++) {
  658.         if (!empty($query_array[$main_key][$query_num])) {
  659.             unset($search_array);
  660.             foreach ($query_keys as $query_key) {
  661.                 $search_array[] = asearch_unserialize($query_array[$query_key][$query_num]);
  662.             }
  663.             
  664.             $where_array = $search_array[ASEARCH_WHERE];
  665.             $mailbox_array = $search_array[ASEARCH_MAILBOX];
  666.             $what_array = $search_array[ASEARCH_WHAT];
  667.             $unop_array = $search_array[ASEARCH_UNOP];
  668.             $biop_array = asearch_nz($search_array[ASEARCH_BIOP], array());
  669.             $exclude_array = asearch_nz($search_array[ASEARCH_EXCLUDE], array());
  670.             $sub_array = asearch_nz($search_array[ASEARCH_SUB], array());
  671.             $query_display = asearch_get_query_display($color, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  672.             
  673.             $a[$query_num] = $query_display;
  674.         }
  675.     }
  676.             
  677.     $oTemplate->assign('list_title', $title);
  678.     $oTemplate->assign('show_list', $show_flag==1);
  679.     $oTemplate->assign('is_recent_list', $title==_("Recent Searches"));
  680.     $oTemplate->assign('expand_collapse_toggle', '../src/search.php?'.$show_pref.'='.($show_flag==1 ? 0 : 1));
  681.     $oTemplate->assign('query_list', $a);
  682.     
  683.     $oTemplate->assign('save_recent', '../src/search.php?submit=save_recent&rownum=');
  684.     $oTemplate->assign('do_recent', '../src/search.php?submit=search_recent&rownum=');
  685.     $oTemplate->assign('forget_recent', '../src/search.php?submit=forget_recent&rownum=');
  686.     
  687.     $oTemplate->assign('edit_saved', '../src/search.php?submit=edit_saved&rownum=');
  688.     $oTemplate->assign('do_saved', '../src/search.php?submit=search_saved&rownum=');
  689.     $oTemplate->assign('delete_saved', '../src/search.php?submit=delete_saved&rownum=');
  690.     
  691.     $oTemplate->display('search_list.tpl');
  692. }
  693.  
  694. /** Print the saved array
  695.  *
  696.  * Function arguments are different in 1.5.0
  697.  * @param array $boxes (unused, see asearch_print_query_array())
  698.  * @since 1.5.0
  699.  * @private
  700.  */
  701. function asearch_print_saved(&$boxes)
  702. {
  703.     global $saved_prefkeys;
  704.  
  705.     $saved_array = asearch_read_saved();
  706.     if (isset($saved_array[$saved_prefkeys[0]])) {
  707.         $saved_count = count($saved_array[$saved_prefkeys[0]]);
  708.         if ($saved_count > 0) {
  709.             $saved_actions = array('edit_saved' => _("Edit"), 'search_saved' => _("Search"), 'delete_saved' => _("Delete"));
  710.             asearch_print_query_array($boxes, $saved_array, $saved_prefkeys, $saved_actions, _("Saved Searches"), 'search_show_saved');
  711.         }
  712.     }
  713. }
  714.  
  715. /**
  716.  * Print the recent array
  717.  *
  718.  * Function arguments are different in 1.5.0
  719.  * @param array $boxes (unused, see asearch_print_query_array())
  720.  * @since 1.5.0
  721.  * @private
  722.  */
  723. function asearch_print_recent(&$boxes)
  724. {
  725.     global $recent_prefkeys, $search_memory;
  726.  
  727.     $recent_array = asearch_read_recent();
  728.     if (isset($recent_array[$recent_prefkeys[0]])) {
  729.         $recent_count = count($recent_array[$recent_prefkeys[0]]);
  730.         if (min($recent_count, $search_memory) > 0) {
  731.             $recent_actions = array('save_recent' => _("save"), 'search_recent' => _("search"), 'forget_recent' => _("forget"));
  732.             asearch_print_query_array($boxes, $recent_array, $recent_prefkeys, $recent_actions, _("Recent Searches"), 'search_show_recent');
  733.         }
  734.     }
  735. }
  736.  
  737. /** Verify that a mailbox exists
  738.  * @param string $mailbox 
  739.  * @param array $boxes 
  740.  * @return bool mailbox exists
  741.  * @deprecated FIXME use standard functions
  742.  * @since 1.5.0
  743.  * @private
  744.  */
  745. function asearch_mailbox_exists($mailbox, &$boxes)
  746. {
  747.     foreach ($boxes as $box) {
  748.         if ($box['unformatted'] == $mailbox)
  749.             return TRUE;
  750.     }
  751.     return FALSE;
  752. }
  753.  
  754. /** Print the advanced search form
  755.  * @param stream $imapConnection 
  756.  * @param array $boxes 
  757.  * @param array $mailbox_array 
  758.  * @param array $biop_array 
  759.  * @param array $unop_array 
  760.  * @param array $where_array 
  761.  * @param array $what_array 
  762.  * @param array $exclude_array 
  763.  * @param array $sub_array 
  764.  * @since 1.5.0
  765.  * @private
  766.  */
  767. function asearch_print_form($imapConnection, &$boxes, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array)
  768. {
  769.     global $oTemplate, $allow_advanced_search, $search_advanced, 
  770.            $imap_asearch_unops, $imap_asearch_biops_in, $imap_asearch_options;
  771.  
  772.     # Build the criteria array
  773.     $c = array();
  774.     for ($row_num = 0; $row_num < count($where_array); $row_num++) {
  775.         $mailbox = asearch_nz($mailbox_array[$row_num]);
  776.         $a = array();
  777.         $a['MailboxSel'] = asearch_nz($mailbox_array[$row_num]);
  778.         $a['LogicSel'] = strip_tags(asearch_nz($biop_array[$row_num]));
  779.         $a['UnarySel'] = strip_tags(asearch_nz($unop_array[$row_num]));
  780.         $a['WhereSel'] = strip_tags(asearch_nz($where_array[$row_num]));
  781.         $a['What'] = asearch_nz($what_array[$row_num]);
  782.         $a['Exclude'] = strip_tags(asearch_nz($exclude_array[$row_num])) == 'on';
  783.         $a['IncludeSubfolders'] = strip_tags(asearch_nz($sub_array[$row_num])) == 'on';
  784.         
  785.         $c[$row_num] = $a;
  786.     }
  787.         
  788.     # Build the mailbox array
  789.     $a = array();
  790.     if (($mailbox != 'All Folders') && (!asearch_mailbox_exists($mailbox, $boxes))) {
  791.         $a[$mailbox] = '[' . _("Missing") . '] ' . htmlspecialchars(asearch_get_mailbox_display($mailbox));
  792.     }
  793.     $a['All Folders'] = '[' . asearch_get_mailbox_display('All Folders') . ']';
  794.     $a = array_merge($a, sqimap_mailbox_option_array($imapConnection, 0, $boxes, NULL));
  795.     
  796.     if ($allow_advanced_search > 1) {
  797.         $link = '../src/search.php?advanced='.($search_advanced ? 0 : 1);
  798.         $txt = $search_advanced ? _("Standard Search") : _("Advanced search");
  799.     } else {
  800.         $link = NULL;
  801.         $txt = NULL;
  802.     }
  803.            
  804.     $oTemplate->assign('allow_advanced_search', $allow_advanced_search > 1);
  805.     $oTemplate->assign('adv_toggle_text', $txt);
  806.     $oTemplate->assign('adv_toggle_link', $link);
  807.     
  808.     $oTemplate->assign('mailbox_options', $a);
  809.     $oTemplate->assign('logical_options', $imap_asearch_biops_in);
  810.     $oTemplate->assign('unary_options', $imap_asearch_unops);
  811.     $oTemplate->assign('where_options', $imap_asearch_options);
  812.  
  813.     $oTemplate->assign('criteria', $c);
  814.     
  815.     echo '<form action="../src/search.php" name="form_asearch">' . "\n";
  816.     $oTemplate->display('search_advanced.tpl');
  817.     echo "</form>\n";
  818. }
  819.  
  820. /** Print the basic search form
  821.  * @param stream $imapConnection 
  822.  * @param array $boxes 
  823.  * @param array $mailbox_array 
  824.  * @param array $biop_array 
  825.  * @param array $unop_array 
  826.  * @param array $where_array 
  827.  * @param array $what_array 
  828.  * @param array $exclude_array 
  829.  * @param array $sub_array 
  830.  * @since 1.5.1
  831.  * @private
  832.  */
  833. function asearch_print_form_basic($imapConnection, &$boxes, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array)
  834. {
  835.     global $allow_advanced_search, $search_advanced, $oTemplate, $imap_asearch_unops, $imap_asearch_options;
  836.  
  837.     $row_num = 0;
  838.     $mailbox = asearch_nz($mailbox_array[$row_num]);
  839.     $biop = strip_tags(asearch_nz($biop_array[$row_num]));
  840.     $unop = strip_tags(asearch_nz($unop_array[$row_num]));
  841.     $where = strip_tags(asearch_nz($where_array[$row_num]));
  842.     $what = asearch_nz($what_array[$row_num]);
  843.     $exclude = strip_tags(asearch_nz($exclude_array[$row_num]));
  844.     $sub = strip_tags(asearch_nz($sub_array[$row_num]));
  845.  
  846.     # Build the mailbox array
  847.     $a = array();
  848.     if (($mailbox != 'All Folders') && (!asearch_mailbox_exists($mailbox, $boxes))) {
  849.         $a[$mailbox] = '[' . _("Missing") . '] ' . htmlspecialchars(asearch_get_mailbox_display($mailbox));
  850.     }
  851.     $a['All Folders'] = '[' . asearch_get_mailbox_display('All Folders') . ']';
  852.     $a = array_merge($a, sqimap_mailbox_option_array($imapConnection, 0, $boxes, NULL));
  853.         
  854.     if ($allow_advanced_search > 1) {
  855.         $link = '../src/search.php?advanced='.($search_advanced ? 0 : 1);
  856.         $txt = $search_advanced ? _("Standard Search") : _("Advanced search");
  857.     } else {
  858.         $link = NULL;
  859.         $txt = NULL;
  860.     }
  861.            
  862.     $oTemplate->assign('allow_advanced_search', $allow_advanced_search > 1);
  863.     $oTemplate->assign('adv_toggle_text', $txt);
  864.     $oTemplate->assign('adv_toggle_link', $link);
  865.  
  866.     $oTemplate->assign('mailbox_options', $a);
  867.     $oTemplate->assign('unary_options', $imap_asearch_unops);
  868.     $oTemplate->assign('where_options', $imap_asearch_options);
  869.     
  870.     $oTemplate->assign('mailbox_sel', strtolower(htmlspecialchars($mailbox)));
  871.     $oTemplate->assign('unary_sel', $unop);
  872.     $oTemplate->assign('where_sel', $where);
  873.     $oTemplate->assign('what_val', $what);
  874.         
  875.     echo '<form action="../src/search.php" name="form_asearch">' . "\n";
  876.     $oTemplate->display('search.tpl');
  877.     echo "</form>\n";
  878. }
  879.  
  880.  
  881. /**
  882.  * @param array $boxes mailboxes array (reference)
  883.  * @return array selectable unformatted mailboxes names
  884.  * @since 1.5.0
  885.  * @private
  886.  */
  887. {
  888.     $mboxes_array = array();
  889.     $boxcount = count($boxes);
  890.     for ($boxnum = 0; $boxnum < $boxcount; $boxnum++) {
  891.         if (!in_array('noselect', $boxes[$boxnum]['flags']))
  892.             $mboxes_array[] = $boxes[$boxnum]['unformatted'];
  893.     }
  894.     return $mboxes_array;
  895. }
  896.  
  897. /* ------------------------ main ------------------------ */
  898. /* get globals we will need */
  899. sqgetGlobalVar('delimiter', $delimiter, SQ_SESSION);
  900.  
  901. if ( sqgetGlobalVar('checkall', $temp, SQ_GET) ) {
  902.     $checkall = (int) $temp;
  903. }
  904.  
  905. /**
  906.  * Retrieve the mailbox cache from the session.
  907.  */
  908. sqgetGlobalVar('mailbox_cache',$mailbox_cache,SQ_SESSION);
  909.  
  910. $search_button_html = _("Search");
  911. $search_button_text = asearch_unhtmlentities($search_button_html);
  912. $add_criteria_button_html = _("Add New Criteria");
  913. $add_criteria_button_text = asearch_unhtmlentities($add_criteria_button_html);
  914. $del_excluded_button_html = _("Remove Excluded Criteria");
  915. $del_excluded_button_text = asearch_unhtmlentities($del_excluded_button_html);
  916. $del_all_button_html = _("Remove All Criteria");
  917. $del_all_button_text = asearch_unhtmlentities($del_all_button_html);
  918.  
  919. /** Maximum number of recent searches to handle
  920.  * Default 0
  921.  * @global integer $search_memory 
  922.  */
  923. $search_memory = getPref($data_dir, $username, 'search_memory', 0);
  924.  
  925. /** Advanced search control
  926.  * - 0 => allow basic interface only
  927.  * - 1 => allow advanced interface only
  928.  * - 2 => allow both
  929.  * Default 2
  930.  */
  931. $allow_advanced_search = asearch_nz($allow_advanced_search, 2);
  932.  
  933. /**
  934.  * Toggle advanced/basic search
  935.  */
  936. if (sqgetGlobalVar('advanced', $search_advanced, SQ_GET)) {
  937.     setPref($data_dir, $username, 'search_advanced', $search_advanced & 1);
  938. }
  939. /** If 1, show advanced search interface
  940.  * Default from allow_advanced_search pref
  941.  * @global integer $search_advanced 
  942.  */
  943. if ($allow_advanced_search > 1) {
  944.     $search_advanced = getPref($data_dir, $username, 'search_advanced', 0);
  945. } else {
  946.     $search_advanced = $allow_advanced_search;
  947. }
  948. if ($search_advanced) {
  949. /** Set recent prefkeys according to $search_advanced
  950.  * @global array $recent_prefkeys 
  951.  */
  952.     $recent_prefkeys = array('asearch_recent_where', 'asearch_recent_mailbox', 'asearch_recent_what', 'asearch_recent_unop', 'asearch_recent_biop', 'asearch_recent_exclude', 'asearch_recent_sub');
  953.  
  954. /** Set saved prefkeys according to $search_advanced
  955.  * @global array $saved_prefkeys 
  956.  */
  957.     $saved_prefkeys = array('asearch_saved_where', 'asearch_saved_mailbox', 'asearch_saved_what', 'asearch_saved_unop', 'asearch_saved_biop', 'asearch_saved_exclude', 'asearch_saved_sub');
  958.  
  959. /*$asearch_prefkeys = array('where', 'mailbox', 'what', 'biop', 'unop', 'exclude', 'sub');*/
  960. } else {
  961.     $recent_prefkeys = array('search_where', 'search_folder', 'search_what', 'search_unop');
  962.     $saved_prefkeys = array('saved_where', 'saved_folder', 'saved_what', 'saved_unop');
  963. }
  964.  
  965. /** How we did enter the form
  966.  * - unset : Enter key, or called from outside (eg read_body)
  967.  * - $search_button_text : Search button
  968.  * - 'Search_no_update' : Search but don't update recent
  969.  * - 'Search_last' : Same as no_update but reload and search last
  970.  * - 'Search_silent' : Same as no_update but only display results
  971.  * - $add_criteria_button_text : Add New Criteria button
  972.  * - $del_excluded_button_text : Remove Excluded Criteria button
  973.  * - $del_all_button_text : Remove All Criteria button
  974.  * - 'save_recent'
  975.  * - 'search_recent'
  976.  * - 'forget_recent'
  977.  * - 'edit_saved'
  978.  * - 'search_saved'
  979.  * - 'delete_saved'
  980.  * @global string $submit 
  981.  */
  982. $searchpressed = false;
  983. if (isset($_GET['submit'])) {
  984.     $submit = strip_tags($_GET['submit']);
  985. }
  986.  
  987. /** Searched mailboxes
  988.  * @global array $mailbox_array 
  989.  */
  990. if (isset($_GET['mailbox'])) {
  991.     $mailbox_array = $_GET['mailbox'];
  992.     $targetmailbox = $_GET['mailbox'];
  993.     if (!is_array($mailbox_array)) {
  994.         $mailbox_array = array($mailbox_array);
  995.     }
  996. } else {
  997.     $mailbox_array = array();
  998.     $targetmailbox = array();
  999. }
  1000. $aMailboxGlobalPref = array(
  1001.                        MBX_PREF_SORT         => 0,
  1002.                        MBX_PREF_LIMIT        => (int)  $show_num,
  1003.                        MBX_PREF_AUTO_EXPUNGE => (bool) $auto_expunge,
  1004.                        MBX_PREF_INTERNALDATE => (bool) getPref($data_dir, $username, 'internal_date_sort')
  1005.                     // MBX_PREF_FUTURE       => (var)  $future
  1006.                                           );
  1007.  
  1008. /**
  1009.  * system wide admin settings and incoming vars.
  1010.  */
  1011. $aConfig = array(
  1012. //                'allow_thread_sort' => $allow_thread_sort,
  1013. //                'allow_server_sort' => $allow_server_sort,
  1014.                                 'user'              => $username,
  1015.                 'setindex'          => 1
  1016.                 );
  1017.  
  1018. /** Binary operators
  1019.  * @global array $biop_array 
  1020.  */
  1021. if (isset($_GET['biop'])) {
  1022.     $biop_array = $_GET['biop'];
  1023.     if (!is_array($biop_array))
  1024.         $biop_array = array($biop_array);
  1025. } else {
  1026.     $biop_array = array();
  1027. }
  1028. /** Unary operators
  1029.  * @global array $unop_array 
  1030.  */
  1031. if (isset($_GET['unop'])) {
  1032.     $unop_array = $_GET['unop'];
  1033.     if (!is_array($unop_array))
  1034.         $unop_array = array($unop_array);
  1035. } else {
  1036.     $unop_array = array();
  1037. }
  1038. /** Where to search
  1039.  * @global array $where_array 
  1040.  */
  1041. if (isset($_GET['where'])) {
  1042.     $where_array = $_GET['where'];
  1043.     if (!is_array($where_array)) {
  1044.         $where_array = array($where_array);
  1045.     }
  1046. } else {
  1047.     $where_array = array();
  1048. }
  1049. /** What to search
  1050.  * @global array $what_array 
  1051.  */
  1052. if (isset($_GET['what'])) {
  1053.     $what_array = $_GET['what'];
  1054.     if (!is_array($what_array)) {
  1055.         $what_array = array($what_array);
  1056.     }
  1057. } else {
  1058.     $what_array = array();
  1059. }
  1060. /** Whether to exclude this criteria from search
  1061.  * @global array $exclude_array 
  1062.  */
  1063. if (isset($_GET['exclude'])) {
  1064.     $exclude_array = $_GET['exclude'];
  1065. } else {
  1066.     $exclude_array = array();
  1067. }
  1068. /** Search within subfolders
  1069.  * @global array $sub_array 
  1070.  */
  1071. if (isset($_GET['sub'])) {
  1072.     $sub_array = $_GET['sub'];
  1073. } else {
  1074.     $sub_array = array();
  1075. }
  1076. /** Row number used by recent and saved stuff
  1077.  */
  1078. if (isset($_GET['rownum'])) {
  1079.     $submit_rownum = strip_tags($_GET['rownum']);
  1080. }
  1081. /** Change global sort
  1082.  */
  1083. if (sqgetGlobalVar('srt', $temp, SQ_GET)) {
  1084.     $srt = (int) $temp;
  1085.     asearch_edit_last(1);
  1086. //    asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  1087. }
  1088. if (sqgetGlobalVar('startMessage', $temp, SQ_GET)) {
  1089.     $startMessage = (int) $temp;
  1090.     asearch_edit_last(1);
  1091. //    asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  1092. }
  1093.  
  1094. if ( sqgetGlobalVar('showall', $temp, SQ_GET) ) {
  1095.     $showall = (int) $temp;
  1096.     asearch_edit_last(1);
  1097. //    asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  1098. }
  1099.  
  1100. if ( sqgetGlobalVar('account', $temp,  SQ_GET) ) {
  1101.     $iAccount = (int) $temp;
  1102. } else {
  1103.     $iAccount = 0;
  1104. }
  1105.  
  1106. /**
  1107.  * Incoming submit buttons from the message list with search results
  1108.  */
  1109. if (sqgetGlobalVar('moveButton',      $moveButton,      SQ_POST) ||
  1110.     sqgetGlobalVar('expungeButton',   $expungeButton,   SQ_POST) ||
  1111.     sqgetGlobalVar('delete',          $markDelete,      SQ_POST) ||
  1112.     sqgetGlobalVar('undeleteButton',  $undeleteButton,  SQ_POST) ||
  1113.     sqgetGlobalVar('markRead',        $markRead,        SQ_POST) ||
  1114.     sqgetGlobalVar('markUnread',      $markUnread,      SQ_POST) ||
  1115.     sqgetGlobalVar('markFlagged',     $markFlagged,     SQ_POST) ||
  1116.     sqgetGlobalVar('markUnflagged',   $markUnflagged,   SQ_POST) ||
  1117.     sqgetGlobalVar('attache',         $attache,         SQ_POST)) {
  1118.     asearch_edit_last(1);
  1119.     $submit = '';
  1120.     asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  1121. }
  1122.  
  1123.  
  1124.  
  1125. /** Toggle show/hide saved searches
  1126.  */
  1127. if (sqgetGlobalVar('search_show_saved', $search_show_saved, SQ_GET)) {
  1128.     setPref($data_dir, $username, 'search_show_saved', $search_show_saved & 1);
  1129. }
  1130. /** Toggle show/hide recent searches
  1131.  */
  1132. if (sqgetGlobalVar('search_show_recent', $search_show_recent, SQ_GET)) {
  1133.     setPref($data_dir, $username, 'search_show_recent', $search_show_recent & 1);
  1134. }
  1135. // end of get globals
  1136.  
  1137. /** If TRUE, do not show search interface
  1138.  * Default FALSE
  1139.  * @global bool $search_silent 
  1140.  */
  1141. $search_silent = FALSE;
  1142.  
  1143. /*  See how the page was called and fire off correct function  */
  1144. if ((empty($submit)) && (!empty($where_array))) {
  1145.     /* This happens when the Enter key is used or called from outside */
  1146.     $submit = $search_button_text;
  1147.     /* Hack needed to handle coming back from read_body et als */
  1148.     if (count($where_array) != count($unop_array)) {
  1149.         /**
  1150.          * Hack to use already existen where and what vars.
  1151.          * where now contains the initiator page of the messagelist
  1152.          * and in this case 'search'. what contains an index to access
  1153.          * the search history
  1154.          */
  1155.  
  1156.         sqgetGlobalVar('what',$what,SQ_GET);
  1157.         asearch_edit_last($what);
  1158.     }
  1159. }
  1160.  
  1161. if (!isset($submit)) {
  1162.     $submit = '';
  1163. } else {
  1164.     switch ($submit) {
  1165.       case $search_button_text:
  1166.         if (asearch_check_query($where_array, $what_array, $exclude_array) == '') {
  1167.             asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  1168.         }
  1169.         break;
  1170.       case 'Search_silent':
  1171.         $search_silent = TRUE;
  1172.         /*nobreak;*/
  1173.       case 'Search_no_update':
  1174.         $submit = $search_button_text;
  1175.         break;
  1176.       case $del_excluded_button_text:
  1177.         $delarray = array_keys($exclude_array);
  1178.         while (!empty($delarray)) {
  1179.             $delrow = array_pop($delarray);
  1180.             array_splice($mailbox_array, $delrow, 1);
  1181.             array_splice($biop_array, $delrow, 1);
  1182.             array_splice($unop_array, $delrow, 1);
  1183.             array_splice($where_array, $delrow, 1);
  1184.             array_splice($what_array, $delrow, 1);
  1185.             /* array_splice($exclude_array, $delrow, 1);*/ /* There is still some php magic that eludes me */
  1186.             array_splice($sub_array, $delrow, 1);
  1187.         }
  1188.         $exclude_array = array();
  1189.         break;
  1190.       case $del_all_button_text:
  1191.         $mailbox_array = array();
  1192.         $biop_array = array();
  1193.         $unop_array = array();
  1194.         $where_array = array();
  1195.         $what_array = array();
  1196.         $exclude_array = array();
  1197.         $sub_array = array();
  1198.         break;
  1199.       case 'save_recent':
  1200.         asearch_save_recent($submit_rownum);
  1201.         break;
  1202.       case 'search_recent':
  1203.         $submit = $search_button_text;
  1204.         asearch_edit_recent($submit_rownum);
  1205.         asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  1206.         break;
  1207.       case 'edit_recent': /* no link to do this, yet */
  1208.         asearch_edit_recent($submit_rownum);
  1209.         break;
  1210.       case 'forget_recent':
  1211.         asearch_forget_recent($submit_rownum);
  1212.         break;
  1213.       case 'search_saved':
  1214.         $submit = $search_button_text;
  1215.         asearch_edit_saved($submit_rownum);
  1216.         asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  1217.         break;
  1218.       case 'edit_saved':
  1219.         asearch_edit_saved($submit_rownum);
  1220.         break;
  1221.       case 'delete_saved':
  1222.         asearch_delete_saved($submit_rownum);
  1223.         break;
  1224.     }
  1225. }
  1226.  
  1227. //Texts in both basic and advanced form
  1228. $imap_asearch_unops = array(
  1229.     '' => '',
  1230.     'NOT' => _("Not")
  1231. );
  1232.  
  1233. if ($search_advanced) {
  1234.     //Texts in advanced form only
  1235.         $imap_asearch_options = array(
  1236.         //<message set>,
  1237.         //'ALL' is binary operator
  1238.                 'ANSWERED' => _("Answered"),
  1239.         'BCC' => _("Bcc"),
  1240.         'BEFORE' => _("Before"),
  1241.         'BODY' => _("Message Body"),
  1242.         'CC' => _("Cc"),
  1243.         'DELETED' => _("Deleted"),
  1244.         'DRAFT' => _("Draft"),
  1245.         'FLAGGED' => _("Flagged"),
  1246.         'FROM' => _("Sent By"),
  1247.         'HEADER' => _("Header Field"),
  1248.         'KEYWORD' => _("Keyword"),
  1249.         'LARGER' => _("Larger Than"),
  1250.         'NEW' => _("New"),
  1251.         //'NOT' is unary operator
  1252.                 'OLD' => _("Old"),
  1253.         'ON' => _("On"),
  1254.         //'OR' is binary operator
  1255.                 'RECENT' => _("Recent"),
  1256.         'SEEN' => _("Seen"),
  1257.         'SENTBEFORE' => _("Sent Before"),
  1258.         'SENTON' => _("Sent On"),
  1259.         'SENTSINCE' => _("Sent Since"),
  1260.         'SINCE' => _("Since"),
  1261.         'SMALLER' => _("Smaller Than"),
  1262.         'SUBJECT' => _("Subject Contains"),
  1263.         'TEXT' => _("Header and Body"),
  1264.         'TO' => _("Sent To"),
  1265.         //'UID' => 'anum',
  1266. /*        'UNANSWERED' => '',
  1267.         'UNDELETED' => '',
  1268.         'UNDRAFT' => '',
  1269.         'UNFLAGGED' => '',
  1270.         'UNKEYWORD' => _("Unkeyword"),
  1271.         'UNSEEN' => _("Unseen"),*/
  1272.     );
  1273.  
  1274.     $imap_asearch_biops_in = array(
  1275.         'ALL' => _("And In"),
  1276.         'OR' => _("Or In")
  1277.     );
  1278.  
  1279.     $imap_asearch_biops = array(
  1280.         'ALL' => _("And"),
  1281.         'OR' => _("Or")
  1282.     );
  1283. } else {
  1284.     //Texts in basic form only
  1285.         $imap_asearch_options = array(
  1286.         'BCC' => _("Bcc"),
  1287.         'BODY' => _("Body"),
  1288.         'CC' => _("Cc"),
  1289.         'FROM' => _("From"),
  1290.         'SUBJECT' => _("Subject"),
  1291.         'TEXT' => _("Everywhere"),
  1292.         'TO' => _("To"),
  1293.     );
  1294. }
  1295.  
  1296. uasort($imap_asearch_options, 'asearch_unhtml_strcoll');
  1297.  
  1298. /* open IMAP connection */
  1299. $imapConnection = sqimap_login($username, false, $imapServerAddress, $imapPort, 0);
  1300.  
  1301.  
  1302. /* get mailboxes once here */
  1303. $boxes = sqimap_mailbox_list($imapConnection);
  1304. /* ensure we have a valid default mailbox name */
  1305. $mailbox = asearch_nz($mailbox_array[0]);
  1306. if (($mailbox == '') || ($mailbox == 'None')) //Workaround for sm quirk IMHO (what if I really have a mailbox called None?)
  1307.         $mailbox = $boxes[0]['unformatted']; //Usually INBOX ;)
  1308.  
  1309.  
  1310. /**
  1311. * Handle form actions like flag / unflag, seen / unseen, delete
  1312. */
  1313. if (sqgetGlobalVar('mailbox',$postMailbox,SQ_POST)) {
  1314.     if ($postMailbox) {
  1315.         /**
  1316.         * system wide admin settings and incoming vars.
  1317.         */
  1318.         $aConfig = array(
  1319.                         'user'              => $username,
  1320.                         );
  1321.         $aConfig['setindex'] = 1; // $what $where = 'search'
  1322.                 /**
  1323.          * Set the max cache size to the number of mailboxes to avoid cache cleanups
  1324.          * when searching all mailboxes
  1325.          */
  1326.         $aConfig['max_cache_size'] = count($boxes) +1;
  1327.  
  1328.         $aMailbox = sqm_api_mailbox_select($imapConnection, $iAccount, $postMailbox,$aConfig,array());
  1329.         $sError = handleMessageListForm($imapConnection,$aMailbox);
  1330.         /* add the mailbox to the cache */
  1331.         $mailbox_cache[$iAccount.'_'.$aMailbox['NAME']] = $aMailbox;
  1332.  
  1333.         if ($sError) {
  1334.             $note = $sError;
  1335.         }
  1336.     }
  1337. }
  1338.  
  1339. if (isset($aMailbox['FORWARD_SESSION'])) {
  1340.     /* add the mailbox to the cache */
  1341.     $mailbox_cache[$iAccount.'_'.$aMailbox['NAME']] = $aMailbox;
  1342.     sqsession_register($mailbox_cache,'mailbox_cache');
  1343.  
  1344.     if ($compose_new_win) {
  1345.         // write the session in order to make sure that the compose window has
  1346.         // access to the composemessages array which is stored in the session
  1347.                 session_write_close();
  1348.         // restart the session. Do not use sqsession_is_active because the session_id
  1349.         // isn't empty after a session_write_close
  1350.                 sqsession_start();
  1351.  
  1352.         if (!preg_match("/^[0-9]{3,4}$/", $compose_width)) {
  1353.             $compose_width = '640';
  1354.         }
  1355.         if (!preg_match("/^[0-9]{3,4}$/", $compose_height)) {
  1356.             $compose_height = '550';
  1357.         }
  1358.         // do not use &amp;, it will break the query string and $session will not be detected!!!
  1359.                 $comp_uri = SM_PATH . 'src/compose.php?mailbox='. urlencode($mailbox).
  1360.                     '&session='.$aMailbox['FORWARD_SESSION'];
  1361.         displayPageHeader($color, $mailbox, "comp_in_new('$comp_uri', $compose_width, $compose_height);", false);
  1362.     } else {
  1363.         // save mailboxstate
  1364.                 sqsession_register($aMailbox,'aLastSelectedMailbox');
  1365.         session_write_close();
  1366.         // we have to redirect to the compose page
  1367.                 $location = SM_PATH . 'src/compose.php?mailbox='. urlencode($mailbox).
  1368.                     '&amp;session='.$aMailbox['FORWARD_SESSION'];
  1369.         header("Location: $location");
  1370.         exit;
  1371.     }
  1372. } else {
  1373.     displayPageHeader($color, $mailbox);
  1374. //    $compose_uri = $base_uri.'src/compose.php?newmessage=1';
  1375. }
  1376.  
  1377. if (isset($note)) {
  1378.     $oTemplate->assign('note', $note);
  1379.     $oTemplate->display('note.tpl');
  1380. }
  1381.  
  1382. do_hook('search_before_form');
  1383.  
  1384. if (!$search_silent) {
  1385.     asearch_print_saved($boxes);
  1386.     asearch_print_recent($boxes);
  1387.     if (empty($where_array)) {
  1388.         global $sent_folder;
  1389.  
  1390.         $mailbox_array[0] = $mailbox;
  1391.         $biop_array[0] = '';
  1392.         $unop_array[0] = '';
  1393.         if ($mailbox == $sent_folder) {
  1394.             $where_array[0] = 'TO';
  1395.         } else {
  1396.             $where_array[0] = 'FROM';
  1397.         }
  1398.         $what_array[0] = '';
  1399.         $exclude_array[0] = '';
  1400.         $sub_array[0] = '';
  1401.     }
  1402.     //Display advanced or basic form
  1403.         if ($search_advanced) {
  1404.         if ($submit == $add_criteria_button_text) {
  1405.             $last_index = max(count($where_array) - 1, 0);
  1406.             $mailbox_array[] = asearch_nz($mailbox_array[$last_index]);
  1407.             $biop_array[] = asearch_nz($biop_array[$last_index]);
  1408.             $unop_array[] = asearch_nz($unop_array[$last_index]);
  1409.             $where_array[] = asearch_nz($where_array[$last_index]);
  1410.             $what_array[] = asearch_nz($what_array[$last_index]);
  1411.             $exclude_array[] = asearch_nz($exclude_array[$last_index]);
  1412.             $sub_array[] = asearch_nz($sub_array[$last_index]);
  1413.         }
  1414.         asearch_print_form($imapConnection, $boxes, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  1415.     } else {
  1416.         asearch_print_form_basic($imapConnection, $boxes, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
  1417.     }
  1418. }
  1419.  
  1420. do_hook('search_after_form');
  1421.  
  1422. if ($submit == $search_button_text) {
  1423.     $msgsfound = false;
  1424.  
  1425.     $err = asearch_check_query($where_array, $what_array, $exclude_array);
  1426.  
  1427.     $oTemplate->assign('query_has_error', $err!='');
  1428.     $oTemplate->assign('query_error', $err=='' ? NULL : $err);
  1429.     $oTemplate->assign('query', asearch_get_query_display($color, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array));
  1430.     
  1431.     $oTemplate->display('search_result_top.tpl');
  1432.     
  1433.     flush();
  1434.     $iMsgCnt = 0;
  1435.     if ($err == '') {
  1436.         $mboxes_array = sqimap_asearch_get_selectable_unformatted_mailboxes($boxes);
  1437.         /**
  1438.          * Retrieve the search queries
  1439.          */
  1440.         $mboxes_mailbox = sqimap_asearch($imapConnection, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array, $mboxes_array);
  1441.         foreach($mboxes_mailbox as $mbx => $search) {
  1442.  
  1443.             /**
  1444.             * until there is no per mailbox option screen to set prefs we override
  1445.             * the mailboxprefs by the default ones
  1446.             */
  1447.  
  1448.             $aMailboxPrefSer=getPref($data_dir, $username,'pref_'.$iAccount.'_'.$mbx);
  1449.             if ($aMailboxPrefSer) {
  1450.                 $aMailboxPref = unserialize($aMailboxPrefSer);
  1451.                 $aMailboxPref[MBX_PREF_COLUMNS] = $index_order;
  1452.             } else {
  1453.                 setUserPref($username,'pref_'.$iAccount.'_'.$mbx,serialize($default_mailbox_pref));
  1454.                 $aMailboxPref = $default_mailbox_pref;
  1455.             }
  1456.             if (isset($srt) && $targetmailbox == $mbx) {
  1457.                 $aMailboxPref[MBX_PREF_SORT] = (int) $srt;
  1458.             }
  1459.  
  1460.             $trash_folder = (isset($trash_folder)) ? $trash_folder : false;
  1461.             $sent_folder = (isset($sent_folder)) ? $sent_folder : false;
  1462.             $draft_folder = (isset($draft_folder)) ? $draft_folder : false;
  1463.  
  1464.  
  1465.             /**
  1466.             * until there is no per mailbox option screen to set prefs we override
  1467.             * the mailboxprefs by the default ones
  1468.             */
  1469.             $aMailboxPref[MBX_PREF_LIMIT] = (int)  $show_num;
  1470.             $aMailboxPref[MBX_PREF_AUTO_EXPUNGE] = (bool) $auto_expunge;
  1471.             $aMailboxPref[MBX_PREF_INTERNALDATE] = (bool) getPref($data_dir, $username, 'internal_date_sort');
  1472.             $aMailboxPref[MBX_PREF_COLUMNS] = $index_order;
  1473.  
  1474.             /**
  1475.             * Replace From => To  in case it concerns a draft or sent folder
  1476.             */
  1477.             if (($mbx == $sent_folder || $mbx == $draft_folder) &&
  1478.                 !in_array(SQM_COL_TO,$aMailboxPref[MBX_PREF_COLUMNS])) {
  1479.                 $aNewOrder = array(); // nice var name ;)
  1480.                                 foreach($aMailboxPref[MBX_PREF_COLUMNS] as $iCol) {
  1481.                     if ($iCol == SQM_COL_FROM) {
  1482.                         $iCol = SQM_COL_TO;
  1483.                     }
  1484.                     $aNewOrder[] = $iCol;
  1485.                 }
  1486.                 $aMailboxPref[MBX_PREF_COLUMNS] = $aNewOrder;
  1487.                 setUserPref($username,'pref_'.$iAccount.'_'.$mbx,serialize($aMailboxPref));
  1488.             }
  1489.  
  1490.             $aConfig['search'] = $search['search'];
  1491.             $aConfig['charset'] = $search['charset'];
  1492.  
  1493.             /**
  1494.              * Set the max cache size to the number of mailboxes to avoid cache cleanups
  1495.              * when searching all mailboxes
  1496.              */
  1497.             $aConfig['max_cache_size'] = count($mboxes_mailbox) +1;
  1498.             if (isset($startMessage) && $targetmailbox == $mbx) {
  1499.                 $aConfig['offset'] = $startMessage;
  1500.             } else {
  1501.                 $aConfig['offset'] = 0;
  1502.             }
  1503.             if (isset($showall) && $targetmailbox == $mbx) {
  1504.                 $aConfig['showall'] = $showall;
  1505.             } else {
  1506.                 if (isset($aConfig['showall'])) {
  1507.                     unset($aConfig['showall']);
  1508.                 }
  1509.                 $showall = false;
  1510.             }
  1511.  
  1512.             /**
  1513.             * Set the config options for the messages list
  1514.             */
  1515.             $aColumns = array();
  1516.             foreach ($aMailboxPref[MBX_PREF_COLUMNS] as $iCol) {
  1517.                 $aColumns[$iCol] = array();
  1518.                 switch ($iCol) {
  1519.                     case SQM_COL_SUBJ:
  1520.                         if ($truncate_subject) {
  1521.                             $aColumns[$iCol]['truncate'] = $truncate_subject;
  1522.                         }
  1523.                         break;
  1524.                     case SQM_COL_FROM:
  1525.                     case SQM_COL_TO:
  1526.                     case SQM_COL_CC:
  1527.                     case SQM_COL_BCC:
  1528.                         if ($truncate_sender) {
  1529.                             $aColumns[$iCol]['truncate'] = $truncate_sender;
  1530.                         }
  1531.                         break;
  1532.                 }
  1533.             }
  1534.  
  1535.  
  1536.             $aProps = array(
  1537.                 'columns' => $aColumns,
  1538.                 'config'  => array('alt_index_colors'      => $alt_index_colors,
  1539.                                     'highlight_list'        => $message_highlight_list,
  1540.                                     'fancy_index_highlite'  => $fancy_index_highlite,
  1541.                                     'show_flag_buttons'     => (isset($show_flag_buttons)) ? $show_flag_buttons : true,
  1542.                                     'lastTargetMailbox'     => (isset($lastTargetMailbox)) ? $lastTargetMailbox : '',
  1543.                                     'trash_folder'          => $trash_folder,
  1544.                                     'sent_folder'           => $sent_folder,
  1545.                                     'draft_folder'          => $draft_folder,
  1546.                                     'enablesort'            => true,
  1547.                                     'color'                 => $color
  1548.                             ),
  1549.                 'mailbox' => $mbx,
  1550.                 'account' => (isset($iAccount)) ? $iAccount : 0,
  1551.                 'module' => 'read_body',
  1552.                 'email'  => false);
  1553.  
  1554.  
  1555.             $aMailbox = sqm_api_mailbox_select($imapConnection, $iAccount, $mbx,$aConfig,$aMailboxPref);
  1556.  
  1557.             $iError = 0;
  1558.             $aTemplate = showMessagesForMailbox($imapConnection, $aMailbox,$aProps, $iError);
  1559.  
  1560.             // in th future we can make use of multiple message sets, now set it to 1 for search.
  1561.                         $iSetIndex = 1;
  1562.             if (isset($aMailbox['UIDSET'][$iSetIndex])) {
  1563.                 $iMsgCnt += count($aMailbox['UIDSET'][$iSetIndex]);
  1564.             }
  1565.             if ($iError) {
  1566.                 // error handling
  1567.                         } else {
  1568.                 /**
  1569.                 * In the future, move this the the initialisation area
  1570.                 */
  1571.                 sqgetGlobalVar('align',$align,SQ_SESSION);
  1572.  
  1573.                 /**
  1574.                  * TODO: Clean up handling of message list once the template is cleaned up.
  1575.                  */
  1576.                 if ($aMailbox['EXISTS'] > 0) {
  1577.                     if ($iError) {
  1578.                        // TODO
  1579.                                               echo "ERROR occured, errorhandler will be implemented very soon";
  1580.                     } else {
  1581.                         foreach ($aTemplate as $k => $v) {
  1582.                             $oTemplate->assign($k, $v);
  1583.                         }
  1584.  
  1585.                         $mailbox_display = asearch_get_mailbox_display($aMailbox['NAME']);
  1586.                         if (strtoupper($mbx) == 'INBOX') {
  1587.                             $mailbox_display = _("INBOX");
  1588.                         } else {
  1589.                             $mailbox_display = imap_utf7_decode_local($mbx);
  1590.                         }
  1591.  
  1592.                         $oTemplate->assign('mailbox_name', htmlspecialchars($mailbox_display));
  1593.                         $oTemplate->display('search_result_mailbox.tpl');
  1594.  
  1595.                         $oTemplate->assign('page_selector',  $page_selector);
  1596.                         $oTemplate->assign('page_selector_max', $page_selector_max);
  1597.                         $oTemplate->assign('compact_paginator', $compact_paginator);
  1598.                         $oTemplate->assign('javascript_on', $javascript_on);
  1599.                         $oTemplate->assign('enablesort', (isset($aProps['config']['enablesort'])) ? $aProps['config']['enablesort'] : false);
  1600.                         $oTemplate->assign('icon_theme_path', $icon_theme_path);
  1601.                         $oTemplate->assign('use_icons', (isset($use_icons)) ? $use_icons : false);
  1602.                         $oTemplate->assign('aOrder', array_keys($aColumns));
  1603.                         $oTemplate->assign('alt_index_colors', isset($alt_index_colors) ? $alt_index_colors: false);
  1604.                         $oTemplate->assign('color', $color);
  1605.                         $oTemplate->assign('align', $align);
  1606.  
  1607.                         $oTemplate->display('message_list.tpl');
  1608.                     }
  1609.                 }
  1610.             }
  1611.  
  1612.             /* add the mailbox to the cache */
  1613.             $mailbox_cache[$iAccount.'_'.$aMailbox['NAME']] = $aMailbox;
  1614.  
  1615.         }
  1616.     }
  1617.     if(!$iMsgCnt) {
  1618.         $oTemplate->display('search_result_empty.tpl');
  1619.     }
  1620. }
  1621.  
  1622. do_hook('search_bottom');
  1623. sqimap_logout($imapConnection);
  1624.  
  1625. $oTemplate->display('footer.tpl');
  1626. sqsession_register($mailbox_cache,'mailbox_cache');
  1627. ?>

Documentation generated on Sat, 07 Oct 2006 16:13:28 +0300 by phpDocumentor 1.3.0RC6