[ Index ] |
|
Code source de IMP H3 (4.1.5) |
1 <?php 2 3 /* Defines used to determine what kind of field query we are dealing with. */ 4 define('IMP_SEARCH_HEADER', 1); 5 define('IMP_SEARCH_BODY', 2); 6 define('IMP_SEARCH_DATE', 3); 7 define('IMP_SEARCH_TEXT', 4); 8 9 /* Defines used to identify the flag input. */ 10 define('IMP_SEARCH_FLAG_SEEN', 1); 11 define('IMP_SEARCH_FLAG_ANSWERED', 2); 12 define('IMP_SEARCH_FLAG_FLAGGED', 3); 13 define('IMP_SEARCH_FLAG_DELETED', 4); 14 15 /* Defines used to identify whether to show unsubscribed folders. */ 16 define('IMP_SEARCH_SHOW_UNSUBSCRIBED', 0); 17 define('IMP_SEARCH_SHOW_SUBSCRIBED_ONLY', 1); 18 19 /** 20 * The IMP_Search:: class contains all code related to mailbox searching 21 * in IMP. 22 * 23 * The class uses the $_SESSION['imp']['search'] variable to store information 24 * across page accesses. The format of that entry is as follows: 25 * 26 * $_SESSION['imp']['search'] = array( 27 * 'q' => array( 28 * 'id_1' => array( 29 * 'query' => IMAP_Search_Query object (serialized), 30 * 'folders' => array (List of folders to search), 31 * 'uiinfo' => array (Info used by search.php to render page), 32 * 'label' => string (Description of search), 33 * 'vfolder' => boolean (True if this is a Virtual Folder) 34 * ), 35 * 'id_2' => array( 36 * .... 37 * ), 38 * .... 39 * ), 40 * 'vtrash_id' => string (The Virtual Trash query ID), 41 * 'vinbox_id' => string (The Virtual Inbox query ID) 42 * ); 43 * 44 * $Horde: imp/lib/Search.php,v 1.37.10.37 2007/01/02 13:54:56 jan Exp $ 45 * 46 * Copyright 2002-2007 Michael Slusarz <slusarz@bigworm.colorado.edu> 47 * 48 * See the enclosed file COPYING for license information (GPL). If you 49 * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. 50 * 51 * @author Michael Slusarz <slusarz@bigworm.colorado.edu> 52 * @since IMP 4.0 53 * @package IMP 54 */ 55 class IMP_Search { 56 57 /** 58 * The ID of the current search query in use. 59 * 60 * @var string 61 */ 62 var $_id = null; 63 64 /** 65 * The IMP_Tree:: object to update. 66 * 67 * @var object 68 */ 69 var $_imptree; 70 71 /** 72 * Save Virtual Folder information when adding entries? 73 * 74 * @var boolean 75 */ 76 var $_saveVFolder = true; 77 78 /** 79 * Constructor. 80 * 81 * @param array $params Available parameters: 82 * <pre> 83 * 'id' -- The ID of the search query in use. 84 * </pre> 85 */ 86 function IMP_Search($params = array()) 87 { 88 if (!empty($params['id'])) { 89 $this->_id = $this->_strip($params['id']); 90 } 91 } 92 93 /** 94 * Set up IMP_Search variables for the current session. 95 */ 96 function sessionSetup() 97 { 98 if (!isset($_SESSION['imp']['search'])) { 99 $_SESSION['imp']['search'] = array('q' => array()); 100 } 101 foreach ($this->_getVFolderList() as $key => $val) { 102 if (!empty($val['vfolder']) && 103 !$this->isVTrashFolder($key) && 104 !$this->isVINBOXFolder($key)) { 105 $_SESSION['imp']['search']['q'][$key] = $val; 106 $this->_updateIMPTree('add', $key, $val['label']); 107 } 108 } 109 $this->createVINBOXFolder(); 110 $this->createVTrashFolder(); 111 } 112 113 /** 114 * Run a search. 115 * 116 * @param IMAP_Search_Query &$ob An optional search query to add (via 117 * 'AND') to the active search. 118 * @param string $id The search query id to use (by default, 119 * will use the current ID set in the 120 * object). 121 * 122 * @return array The sorted list. 123 */ 124 function runSearch(&$ob, $id = null) 125 { 126 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 127 $mbox = ''; 128 $sorted = array(); 129 $use_pop3 = ($_SESSION['imp']['base_protocol'] == 'pop3'); 130 131 if (empty($_SESSION['imp']['search']['q'][$id])) { 132 return $sorted; 133 } 134 $search = &$_SESSION['imp']['search']['q'][$id]; 135 136 $charset = NLS::getCharset(); 137 $search_params = array('pop3' => $use_pop3, 'charset' => $charset); 138 139 /* Check if the IMAP server supports searches in the current 140 * charset. */ 141 if (empty($_SESSION['imp']['imap_server']['search_charset'][$charset])) { 142 $search_params['no_imap_charset'] = true; 143 } 144 145 require_once IMP_BASE . '/lib/IMAP/Search.php'; 146 $imap_search = &IMP_IMAP_Search::singleton($search_params); 147 148 /* Prepare the search query. */ 149 if (!empty($ob)) { 150 $old_query = unserialize($search['query']); 151 $query = &new IMP_IMAP_Search_Query(); 152 $query->imapAnd(array($ob, $old_query)); 153 } else { 154 $query = unserialize($search['query']); 155 } 156 157 /* How do we want to sort results? */ 158 $sortby = $GLOBALS['prefs']->getValue('sortby'); 159 if ($sortby == SORTTHREAD) { 160 $sortby = SORTDATE; 161 } 162 $sortdir = $GLOBALS['prefs']->getValue('sortdir'); 163 164 foreach ($search['folders'] as $val) { 165 $results = $imap_search->searchSortMailbox($query, $_SESSION['imp']['stream'], $val, $sortby, $sortdir); 166 167 if (is_array($results)) { 168 foreach ($results as $val2) { 169 $sorted[] = $val2 . IMP_IDX_SEP . $val; 170 } 171 } 172 } 173 174 return $sorted; 175 } 176 177 /** 178 * Creates the IMAP search query in the IMP session. 179 * 180 * @param IMAP_Search_Query $query The search query object. 181 * @param array $folders The list of folders to search. 182 * @param array $search The search array used to build the 183 * search UI screen. 184 * @param string $label The label to use for the search 185 * results. 186 * @param string $id The query id to use (or else one is 187 * automatically generated). 188 * 189 * @return string Returns the search query id. 190 */ 191 function createSearchQuery($query, $folders, $search, $label, $id = null) 192 { 193 $id = (empty($id)) ? base_convert(microtime() . mt_rand(), 16, 36) : $this->_strip($id); 194 $_SESSION['imp']['search']['q'][$id] = array( 195 'query' => serialize($query), 196 'folders' => $folders, 197 'uiinfo' => $search, 198 'label' => $label, 199 'vfolder' => false 200 ); 201 return $id; 202 } 203 204 /** 205 * Deletes an IMAP search query. 206 * 207 * @param string $id The search query id to use (by default, will use 208 * the current ID set in the object). 209 * 210 * @return string Returns the search query id. 211 */ 212 function deleteSearchQuery($id = null) 213 { 214 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 215 $is_vfolder = !empty($_SESSION['imp']['search']['q'][$id]['vfolder']); 216 unset($_SESSION['imp']['search']['q'][$id]); 217 218 if ($is_vfolder) { 219 $vfolders = $this->_getVFolderList(); 220 unset($vfolders[$id]); 221 $this->_saveVFolderList($vfolders); 222 $this->_updateIMPTree('delete', $id); 223 } 224 } 225 226 /** 227 * Retrieves the previously stored search UI information. 228 * 229 * @param string $id The search query id to use (by default, will use 230 * the current ID set in the object). 231 * 232 * @return array The array necessary to rebuild the search UI page. 233 */ 234 function retrieveUIQuery($id = null) 235 { 236 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 237 return (isset($_SESSION['imp']['search']['q'][$id]['uiinfo'])) 238 ? $GLOBALS['imp']['search']['q'][$id]['uiinfo'] 239 : array(); 240 } 241 242 /** 243 * Generates the label to use for search results. 244 * 245 * @param string $id The search query id to use (by default, will use 246 * the current ID set in the object). 247 * 248 * @return string The search results label. 249 */ 250 function getLabel($id = null) 251 { 252 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 253 return (isset($_SESSION['imp']['search']['q'][$id]['label'])) 254 ? $GLOBALS['imp']['search']['q'][$id]['label'] 255 : ''; 256 } 257 258 /** 259 * Obtains the list of virtual folders for the current user. 260 * 261 * @access private 262 * 263 * @return array The list of virtual folders. 264 */ 265 function _getVFolderList() 266 { 267 $vfolder = $GLOBALS['prefs']->getValue('vfolder'); 268 if (empty($vfolder)) { 269 return array(); 270 } 271 272 $vfolder = @unserialize($vfolder); 273 if (!is_array($vfolder)) { 274 return array(); 275 } 276 277 $elt = reset($vfolder); 278 if (!isset($elt['ob'])) { 279 // Already in 4.1+ format. 280 return $vfolder; 281 } 282 283 // Convert from 4.0 format to 4.1+ format, if necessary 284 $convert = array(); 285 foreach ($vfolder as $key => $val) { 286 $convert[$key] = array( 287 'query' => $val['ob'], 288 'folders' => $val['search']['folders'], 289 'uiinfo' => $val['search'], 290 'label' => $val['search']['vfolder_label'], 291 'vfolder' => true 292 ); 293 unset($convert[$key]['search']['folders'], $convert[$key]['search']['vfolder_label']); 294 } 295 return $convert; 296 } 297 298 /** 299 * Saves the list of virtual folders for the current user. 300 * 301 * @access private 302 * 303 * @param array The virtual folder list. 304 */ 305 function _saveVFolderList($vfolder) 306 { 307 $GLOBALS['prefs']->setValue('vfolder', serialize($vfolder)); 308 } 309 310 /** 311 * Add a virtual folder for the current user. 312 * 313 * @param IMAP_Search_Query $query The search query object. 314 * @param array $folders The list of folders to search. 315 * @param array $search The search array used to build the 316 * search UI screen. 317 * @param string $label The label to use for the search 318 * results. 319 * @param string $id The virtual folder id. 320 * 321 * @return string The virtual folder ID. 322 */ 323 function addVFolder($query, $folders, $search, $label, $id = null) 324 { 325 $id = $this->createSearchQuery($query, $folders, $search, $label, $id); 326 $_SESSION['imp']['search']['q'][$id]['vfolder'] = true; 327 if ($this->_saveVFolder) { 328 $vfolders = $this->_getVFolderList(); 329 $vfolders[$id] = $_SESSION['imp']['search']['q'][$id]; 330 $this->_saveVFolderList($vfolders); 331 } 332 $this->_updateIMPTree('add', $id, $label); 333 return $id; 334 } 335 336 /** 337 * Add a virtual trash folder for the current user. 338 */ 339 function createVTrashFolder() 340 { 341 /* Delete the current Virtual Trash folder, if it exists. */ 342 $vtrash_id = $GLOBALS['prefs']->getValue('vtrash_id'); 343 if (!empty($vtrash_id)) { 344 $this->deleteSearchQuery($vtrash_id); 345 } 346 347 if (!$GLOBALS['prefs']->getValue('use_vtrash')) { 348 return; 349 } 350 351 /* Create Virtual Trash with new folder list. */ 352 require_once IMP_BASE . '/lib/Folder.php'; 353 $imp_folder = &IMP_Folder::singleton(); 354 $fl = $imp_folder->flist_IMP(); 355 $flist = array(); 356 foreach ($fl as $mbox) { 357 if (!empty($mbox['val'])) { 358 $flist[] = $mbox['val']; 359 } 360 } 361 array_unshift($flist, 'INBOX'); 362 363 require_once IMP_BASE . '/lib/IMAP/Search.php'; 364 $query = &new IMP_IMAP_Search_query(); 365 $query->deleted(true); 366 $label = _("Virtual Trash"); 367 368 $this->_saveVFolder = false; 369 if (empty($vtrash_id)) { 370 $vtrash_id = $this->addVFolder($query, $flist, array(), $label); 371 $GLOBALS['prefs']->setValue('vtrash_id', $vtrash_id); 372 } else { 373 $this->addVFolder($query, $flist, array(), $label, $vtrash_id); 374 } 375 $this->_saveVFolder = true; 376 $_SESSION['imp']['search']['vtrash_id'] = $vtrash_id; 377 } 378 379 /** 380 * Determines whether a virtual folder ID is the Virtual Trash Folder. 381 * 382 * @param string $id The search query id to use (by default, will use 383 * the current ID set in the object). 384 * 385 * @return boolean True if the virutal folder ID is the Virtual Trash 386 * folder. 387 */ 388 function isVTrashFolder($id = null) 389 { 390 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 391 $vtrash_id = $GLOBALS['prefs']->getValue('vtrash_id'); 392 return (!empty($vtrash_id) && ($id == $vtrash_id)); 393 } 394 395 /** 396 * Add a virtual INBOX folder for the current user. 397 */ 398 function createVINBOXFolder() 399 { 400 /* Initialize IMP_Tree. */ 401 require_once IMP_BASE . '/lib/IMAP/Tree.php'; 402 $imptree = &IMP_Tree::singleton(); 403 404 /* Delete the current Virtual Trash folder, if it exists. */ 405 $vinbox_id = $GLOBALS['prefs']->getValue('vinbox_id'); 406 if (!empty($vinbox_id)) { 407 $this->deleteSearchQuery($vinbox_id); 408 } 409 410 if (!$GLOBALS['prefs']->getValue('use_vinbox')) { 411 return; 412 } 413 414 /* Create Virtual INBOX with nav_poll list. Filter out any nav_poll 415 * entries that don't exist. */ 416 $flist = array_values(array_intersect(array_keys($imptree->getPollList()), $imptree->folderList())); 417 418 /* Sort Virtual INBOX list. */ 419 require_once IMP_BASE . '/lib/IMAP/Sort.php'; 420 $ns_new = IMP::getNamespace(); 421 $imap_sort = new IMP_IMAP_Sort($ns_new['delimiter']); 422 $imap_sort->sortMailboxes($flist); 423 424 require_once IMP_BASE . '/lib/IMAP/Search.php'; 425 $query = &new IMP_IMAP_Search_query(); 426 $query->seen(false); 427 $query->deleted(false); 428 $label = _("Virtual INBOX"); 429 430 $this->_saveVFolder = false; 431 if (empty($vinbox_id)) { 432 $vinbox_id = $this->addVFolder($query, $flist, array(), $label); 433 $GLOBALS['prefs']->setValue('vinbox_id', $vinbox_id); 434 } else { 435 $this->addVFolder($query, $flist, array(), $label, $vinbox_id); 436 } 437 $this->_saveVFolder = true; 438 $_SESSION['imp']['search']['vinbox_id'] = $vinbox_id; 439 } 440 441 /** 442 * Determines whether a virtual folder ID is the Virtual INBOX Folder. 443 * 444 * @param string $id The search query id to use (by default, will use 445 * the current ID set in the object). 446 * 447 * @return boolean True if the virutal folder ID is the Virtual INBOX 448 * folder. 449 */ 450 function isVINBOXFolder($id = null) 451 { 452 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 453 $vinbox_id = $GLOBALS['prefs']->getValue('vinbox_id'); 454 return (!empty($vinbox_id) && ($id == $vinbox_id)); 455 } 456 457 /** 458 * Is the current active folder an editable Virtual Folder? 459 * 460 * @param string $id The search query id to use (by default, will use 461 * the current ID set in the object). 462 * 463 * @return boolean True if the current folder is both a virtual folder 464 * and can be edited. 465 */ 466 function isEditableVFolder($id = null) 467 { 468 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 469 return ($this->isVFolder($id) && !$this->isVTrashFolder($id) && !$this->isVINBOXFolder($id)); 470 } 471 472 /** 473 * Return a list of IDs and query labels, sorted by the label. 474 * 475 * @param boolean $vfolder If true, only return Virtual Folders? 476 * 477 * @return array An array with the folder IDs as the key and the labels 478 * as the value. 479 */ 480 function listQueries($vfolder = false) 481 { 482 $vfolders = array(); 483 484 if (empty($_SESSION['imp']['search']['q'])) { 485 return $vfolders; 486 } 487 488 foreach ($_SESSION['imp']['search']['q'] as $key => $val) { 489 if (!$vfolder || !empty($val['vfolder'])) { 490 $vfolders[$key] = $this->getLabel($key); 491 } 492 } 493 natcasesort($vfolders); 494 495 return $vfolders; 496 } 497 498 /** 499 * Get the list of searchable folders for the given search query. 500 * 501 * @param string $id The search query id to use (by default, will use 502 * the current ID set in the object). 503 * 504 * @return array The list of searchable folders. 505 */ 506 function getSearchFolders($id = null) 507 { 508 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 509 return (isset($_SESSION['imp']['search']['q'][$id]['folders'])) ? $_SESSION['imp']['search']['q'][$id]['folders'] : array(); 510 } 511 512 /** 513 * Returns a link to edit a given search query. 514 * 515 * @param string $id The search query id to use (by default, will use 516 * the current ID set in the object). 517 * 518 * @rerturn string The URL to the search page. 519 */ 520 function editURL($id = null) 521 { 522 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 523 return Util::addParameter(Horde::applicationUrl('search.php'), array('edit_query' => $id)); 524 } 525 526 /** 527 * Returns a link to delete a given search query. 528 * 529 * @param string $id The search query id to use (by default, will use 530 * the current ID set in the object). 531 * 532 * @return string The URL to allow deletion of the search query. 533 */ 534 function deleteURL($id = null) 535 { 536 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 537 return Util::addParameter(Horde::applicationUrl('folders.php'), array('actionID' => 'delete_search_query', 'queryid' => $id)); 538 } 539 540 /** 541 * Is the given mailbox a search mailbox? 542 * 543 * @param string $id The search query id to use (by default, will use 544 * the current ID set in the object). 545 * 546 * @return boolean Whether the given mailbox name is a search mailbox. 547 */ 548 function isSearchMbox($id = null) 549 { 550 return (is_null($id)) ? !empty($this->_id) : isset($_SESSION['imp']['search']['q'][$this->_strip($id)]); 551 } 552 553 /** 554 * Is the given mailbox a virtual folder? 555 * 556 * @param string $id The search query id to use (by default, will use 557 * the current ID set in the object). 558 * 559 * @return boolean Whether the given mailbox name is a virtual folder. 560 */ 561 function isVFolder($id = null) 562 { 563 $id = (is_null($id)) ? $this->_id : $this->_strip($id); 564 return (!empty($_SESSION['imp']['search']['q'][$id]['vfolder'])); 565 } 566 567 /** 568 * Get the ID for the search mailbox, if we are currently in a search 569 * mailbox. 570 * 571 * @return mixed The search ID if in a mailbox, else false. 572 */ 573 function searchMboxID() 574 { 575 return (!is_null($this->_id)) ? $this->_id : false; 576 } 577 578 /** 579 * Strip the identifying label from a mailbox ID. 580 * 581 * @access private 582 * 583 * @param string $id The mailbox query ID. 584 * 585 * @return string The virtual folder ID, with any IMP specific identifying 586 * information stripped off. 587 */ 588 function _strip($id) 589 { 590 return (strpos($id, IMP_SEARCH_MBOX) === 0) ? substr($id, strlen(IMP_SEARCH_MBOX)) : $id; 591 } 592 593 /** 594 * Create the canonical search ID for a given search query. 595 * 596 * @since IMP 4.1.2 597 * 598 * @access public 599 * 600 * @param string $id The mailbox query ID. 601 * 602 * @return string The canonical search query ID. 603 */ 604 function createSearchID($id) 605 { 606 return IMP_SEARCH_MBOX . $this->_strip($id); 607 } 608 609 /** 610 * Return the base search fields. 611 * 612 * @return array The base search fields. 613 */ 614 function searchFields() 615 { 616 return array( 617 'from' => array( 618 'label' => _("From"), 619 'type' => IMP_SEARCH_HEADER 620 ), 621 'to' => array( 622 'label' => _("To"), 623 'type' => IMP_SEARCH_HEADER 624 ), 625 'cc' => array( 626 'label' => _("Cc"), 627 'type' => IMP_SEARCH_HEADER 628 ), 629 'bcc' => array( 630 'label' => _("Bcc"), 631 'type' => IMP_SEARCH_HEADER 632 ), 633 'subject' => array( 634 'label' => _("Subject"), 635 'type' => IMP_SEARCH_HEADER 636 ), 637 'body' => array( 638 'label' => _("Body"), 639 'type' => IMP_SEARCH_BODY 640 ), 641 'text' => array( 642 'label' => _("Entire Message"), 643 'type' => IMP_SEARCH_TEXT 644 ), 645 'received_on' => array( 646 'label' => _("Received On"), 647 'type' => IMP_SEARCH_DATE 648 ), 649 'received_until' => array( 650 'label' => _("Received Until"), 651 'type' => IMP_SEARCH_DATE 652 ), 653 'received_since' => array( 654 'label' => _("Received Since"), 655 'type' => IMP_SEARCH_DATE 656 ) 657 ); 658 } 659 660 /** 661 * Update IMAP_Tree object. 662 * 663 * @access private 664 * 665 * @param string $action Either 'delete' or 'add'. 666 * @param string $id The query ID to update. 667 * @param string $label If $action = 'add', the label to use for the 668 * query ID. 669 */ 670 function _updateIMPTree($action, $id, $label = null) 671 { 672 if (empty($this->_imptree)) { 673 require_once IMP_BASE . '/lib/IMAP/Tree.php'; 674 $this->_imptree = &IMP_Tree::singleton(); 675 } 676 677 switch ($action) { 678 case 'delete': 679 $this->_imptree->delete($id); 680 break; 681 682 case 'add': 683 $this->_imptree->insertVFolders(array($id => $label)); 684 break; 685 } 686 } 687 688 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Nov 29 12:30:07 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |