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