[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/horde/framework/Horde/Imap/Client/Search/ -> Query.php (source)

   1  <?php
   2  /**
   3   * Copyright 2008-2014 Horde LLC (http://www.horde.org/)
   4   *
   5   * See the enclosed file COPYING for license information (LGPL). If you
   6   * did not receive this file, see http://www.horde.org/licenses/lgpl21.
   7   *
   8   * @category  Horde
   9   * @copyright 2008-2014 Horde LLC
  10   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  11   * @package   Imap_Client
  12   */
  13  
  14  /**
  15   * Abstraction of the IMAP4rev1 search criteria (see RFC 3501 [6.4.4]).
  16   * Allows translation between abstracted search criteria and a generated IMAP
  17   * search criteria string suitable for sending to a remote IMAP server.
  18   *
  19   * @author    Michael Slusarz <slusarz@horde.org>
  20   * @category  Horde
  21   * @copyright 2008-2014 Horde LLC
  22   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  23   * @package   Imap_Client
  24   */
  25  class Horde_Imap_Client_Search_Query implements Serializable
  26  {
  27      /**
  28       * Serialized version.
  29       */
  30      const VERSION = 3;
  31  
  32      /**
  33       * Constants for dateSearch()
  34       */
  35      const DATE_BEFORE = 'BEFORE';
  36      const DATE_ON = 'ON';
  37      const DATE_SINCE = 'SINCE';
  38  
  39      /**
  40       * Constants for intervalSearch()
  41       */
  42      const INTERVAL_OLDER = 'OLDER';
  43      const INTERVAL_YOUNGER = 'YOUNGER';
  44  
  45      /**
  46       * The charset of the search strings.  All text strings must be in
  47       * this charset. By default, this is 'US-ASCII' (see RFC 3501 [6.4.4]).
  48       *
  49       * @var string
  50       */
  51      protected $_charset = null;
  52  
  53      /**
  54       * The list of search params.
  55       *
  56       * @var array
  57       */
  58      protected $_search = array();
  59  
  60      /**
  61       * String representation: The IMAP search string.
  62       */
  63      public function __toString()
  64      {
  65          try {
  66              $res = $this->build(null);
  67              return $res['query']->escape();
  68          } catch (Exception $e) {
  69              return '';
  70          }
  71      }
  72  
  73      /**
  74       * Sets the charset of the search text.
  75       *
  76       * @param string $charset   The charset to use for the search.
  77       * @param boolean $convert  Convert existing text values?
  78       *
  79       * @throws Horde_Imap_Client_Exception_SearchCharset
  80       */
  81      public function charset($charset, $convert = true)
  82      {
  83          $oldcharset = $this->_charset;
  84          $this->_charset = strtoupper($charset);
  85  
  86          if (!$convert || ($oldcharset == $this->_charset)) {
  87              return;
  88          }
  89  
  90          foreach (array('header', 'text') as $item) {
  91              if (isset($this->_search[$item])) {
  92                  foreach ($this->_search[$item] as $key => $val) {
  93                      $new_val = Horde_String::convertCharset($val['text'], $oldcharset, $this->_charset);
  94                      if (Horde_String::convertCharset($new_val, $this->_charset, $oldcharset) != $val['text']) {
  95                          throw new Horde_Imap_Client_Exception_SearchCharset($this->_charset);
  96                      }
  97                      $this->_search[$item][$key]['text'] = $new_val;
  98                  }
  99              }
 100          }
 101      }
 102  
 103      /**
 104       * Builds an IMAP4rev1 compliant search string.
 105       *
 106       * @param array $exts  The list of extensions supported by the server.
 107       *                     This determines whether certain criteria can be
 108       *                     used, and determines whether workarounds are used
 109       *                     for other criteria. In the format returned by
 110       *                     Horde_Imap_Client_Base::capability(). If this value
 111       *                     is null, all extensions are assumed to be
 112       *                     available.
 113       *
 114       * @return array  An array with these elements:
 115       *   - charset: (string) The charset of the search string. If null, no
 116       *              text strings appear in query.
 117       *   - exts: (array) The list of IMAP extensions used to create the
 118       *           string.
 119       *   - query: (Horde_Imap_Client_Data_Format_List) The IMAP search
 120       *            command.
 121       *
 122       * @throws Horde_Imap_Client_Exception_NoSupportExtension
 123       */
 124      public function build($exts = array())
 125      {
 126          $temp = array(
 127              'cmds' => new Horde_Imap_Client_Data_Format_List(),
 128              'exts' => $exts,
 129              'exts_used' => array()
 130          );
 131          $cmds = &$temp['cmds'];
 132          $charset = null;
 133          $exts_used = &$temp['exts_used'];
 134          $ptr = &$this->_search;
 135  
 136          if (isset($ptr['new'])) {
 137              $this->_addFuzzy(!empty($ptr['newfuzzy']), $temp);
 138              if ($ptr['new']) {
 139                  $cmds->add('NEW');
 140                  unset($ptr['flag']['UNSEEN']);
 141              } else {
 142                  $cmds->add('OLD');
 143              }
 144              unset($ptr['flag']['RECENT']);
 145          }
 146  
 147          if (!empty($ptr['flag'])) {
 148              foreach ($ptr['flag'] as $key => $val) {
 149                  $this->_addFuzzy(!empty($val['fuzzy']), $temp);
 150  
 151                  $tmp = '';
 152                  if (empty($val['set'])) {
 153                      // This is a 'NOT' search.  All system flags but \Recent
 154                      // have 'UN' equivalents.
 155                      if ($key == 'RECENT') {
 156                          $cmds->add('NOT');
 157                      } else {
 158                          $tmp = 'UN';
 159                      }
 160                  }
 161  
 162                  if ($val['type'] == 'keyword') {
 163                      $cmds->add(array(
 164                          $tmp . 'KEYWORD',
 165                          $key
 166                      ));
 167                  } else {
 168                      $cmds->add($tmp . $key);
 169                  }
 170              }
 171          }
 172  
 173          if (!empty($ptr['header'])) {
 174              /* The list of 'system' headers that have a specific search
 175               * query. */
 176              $systemheaders = array(
 177                  'BCC', 'CC', 'FROM', 'SUBJECT', 'TO'
 178              );
 179  
 180              foreach ($ptr['header'] as $val) {
 181                  $this->_addFuzzy(!empty($val['fuzzy']), $temp);
 182  
 183                  if (!empty($val['not'])) {
 184                      $cmds->add('NOT');
 185                  }
 186  
 187                  if (in_array($val['header'], $systemheaders)) {
 188                      $cmds->add($val['header']);
 189                  } else {
 190                      $cmds->add(array(
 191                          'HEADER',
 192                          new Horde_Imap_Client_Data_Format_Astring($val['header'])
 193                      ));
 194                  }
 195                  $cmds->add(new Horde_Imap_Client_Data_Format_Astring(isset($val['text']) ? $val['text'] : ''));
 196                  $charset = is_null($this->_charset)
 197                      ? 'US-ASCII'
 198                      : $this->_charset;
 199              }
 200          }
 201  
 202          if (!empty($ptr['text'])) {
 203              foreach ($ptr['text'] as $val) {
 204                  $this->_addFuzzy(!empty($val['fuzzy']), $temp);
 205  
 206                  if (!empty($val['not'])) {
 207                      $cmds->add('NOT');
 208                  }
 209                  $cmds->add(array(
 210                      $val['type'],
 211                      new Horde_Imap_Client_Data_Format_Astring($val['text'])
 212                  ));
 213                  if (is_null($charset)) {
 214                      $charset = is_null($this->_charset)
 215                          ? 'US-ASCII'
 216                          : $this->_charset;
 217                  }
 218              }
 219          }
 220  
 221          if (!empty($ptr['size'])) {
 222              foreach ($ptr['size'] as $key => $val) {
 223                  $this->_addFuzzy(!empty($val['fuzzy']), $temp);
 224                  if (!empty($val['not'])) {
 225                      $cmds->add('NOT');
 226                  }
 227                  $cmds->add(array(
 228                      $key,
 229                      new Horde_Imap_Client_Data_Format_Number($val['size'])
 230                  ));
 231              }
 232          }
 233  
 234          if (isset($ptr['ids']) &&
 235              (count($ptr['ids']['ids']) || $ptr['ids']['ids']->special)) {
 236              $this->_addFuzzy(!empty($ptr['ids']['fuzzy']), $temp);
 237              if (!empty($ptr['ids']['not'])) {
 238                  $cmds->add('NOT');
 239              }
 240              if (!$ptr['ids']['ids']->sequence) {
 241                  $cmds->add('UID');
 242              }
 243              $cmds->add(strval($ptr['ids']['ids']));
 244          }
 245  
 246          if (!empty($ptr['date'])) {
 247              foreach ($ptr['date'] as $val) {
 248                  $this->_addFuzzy(!empty($val['fuzzy']), $temp);
 249  
 250                  if (!empty($val['not'])) {
 251                      $cmds->add('NOT');
 252                  }
 253  
 254                  if (empty($val['header'])) {
 255                      $cmds->add($val['range']);
 256                  } else {
 257                      $cmds->add('SENT' . $val['range']);
 258                  }
 259                  $cmds->add($val['date']);
 260              }
 261          }
 262  
 263          if (!empty($ptr['within'])) {
 264              if (is_null($exts) || isset($exts['WITHIN'])) {
 265                  $exts_used[] = 'WITHIN';
 266              }
 267  
 268              foreach ($ptr['within'] as $key => $val) {
 269                  $this->_addFuzzy(!empty($val['fuzzy']), $temp);
 270                  if (!empty($val['not'])) {
 271                      $cmds->add('NOT');
 272                  }
 273  
 274                  if (is_null($exts) || isset($exts['WITHIN'])) {
 275                      $cmds->add(array(
 276                          $key,
 277                          new Horde_Imap_Client_Data_Format_Number($val['interval'])
 278                      ));
 279                  } else {
 280                      // This workaround is only accurate to within 1 day, due
 281                      // to limitations with the IMAP4rev1 search commands.
 282                      $cmds->add(array(
 283                          ($key == self::INTERVAL_OLDER) ? self::DATE_BEFORE : self::DATE_SINCE,
 284                          new Horde_Imap_Client_Data_Format_Date('now -' . $val['interval'] . ' seconds')
 285                      ));
 286                  }
 287              }
 288          }
 289  
 290          if (!empty($ptr['modseq'])) {
 291              if (!is_null($exts) && !isset($exts['CONDSTORE'])) {
 292                  throw new Horde_Imap_Client_Exception_NoSupportExtension('CONDSTORE');
 293              }
 294  
 295              $exts_used[] = 'CONDSTORE';
 296  
 297              $this->_addFuzzy(!empty($ptr['modseq']['fuzzy']), $temp);
 298  
 299              if (!empty($ptr['modseq']['not'])) {
 300                  $cmds->add('NOT');
 301              }
 302              $cmds->add('MODSEQ');
 303              if (isset($ptr['modseq']['name'])) {
 304                  $cmds->add(array(
 305                      new Horde_Imap_Client_Data_Format_String($ptr['modseq']['name']),
 306                      $ptr['modseq']['type']
 307                  ));
 308              }
 309              $cmds->add(new Horde_Imap_Client_Data_Format_Number($ptr['modseq']['value']));
 310          }
 311  
 312          if (isset($ptr['prevsearch'])) {
 313              if (!is_null($exts) && !isset($exts['SEARCHRES'])) {
 314                  throw new Horde_Imap_Client_Exception_NoSupportExtension('SEARCHRES');
 315              }
 316  
 317              $exts_used[] = 'SEARCHRES';
 318  
 319              $this->_addFuzzy(!empty($ptr['prevsearchfuzzy']), $temp);
 320  
 321              if (!$ptr['prevsearch']) {
 322                  $cmds->add('NOT');
 323              }
 324              $cmds->add('$');
 325          }
 326  
 327          // Add AND'ed queries
 328          if (!empty($ptr['and'])) {
 329              foreach ($ptr['and'] as $val) {
 330                  $ret = $val->build();
 331                  if ($ret['charset'] != 'US-ASCII') {
 332                      $charset = $ret['charset'];
 333                  }
 334                  $exts_used = array_merge($exts_used, $ret['exts']);
 335                  $cmds->add($ret['query'], true);
 336              }
 337          }
 338  
 339          // Add OR'ed queries
 340          if (!empty($ptr['or'])) {
 341              foreach ($ptr['or'] as $val) {
 342                  $ret = $val->build();
 343  
 344                  if ($ret['charset'] != 'US-ASCII') {
 345                      $charset = $ret['charset'];
 346                  }
 347                  $exts_used = array_merge($exts_used, $ret['exts']);
 348  
 349                  // First OR'd query
 350                  if (count($cmds)) {
 351                      $new_cmds = new Horde_Imap_Client_Data_Format_List();
 352                      $new_cmds->add(array(
 353                          'OR',
 354                          $ret['query'],
 355                          $cmds
 356                      ));
 357                      $cmds = $new_cmds;
 358                  } else {
 359                      $cmds = $ret['query'];
 360                  }
 361              }
 362          }
 363  
 364          // Default search is 'ALL'
 365          if (!count($cmds)) {
 366              $cmds->add('ALL');
 367          }
 368  
 369          return array(
 370              'charset' => $charset,
 371              'exts' => array_keys(array_flip($exts_used)),
 372              'query' => $cmds
 373          );
 374      }
 375  
 376      /**
 377       * Adds fuzzy modifier to search keys.
 378       *
 379       * @param boolean $add  Add the fuzzy modifier?
 380       * @param array $temp   Temporary build data.
 381       *
 382       * @throws Horde_Imap_Client_Exception_NoSupport_Extension
 383       */
 384      protected function _addFuzzy($add, &$temp)
 385      {
 386          if ($add) {
 387              if (!isset($temp['exts']['SEARCH']) ||
 388                  !in_array('FUZZY', $temp['exts']['SEARCH'])) {
 389                  throw new Horde_Imap_Client_Exception_NoSupportExtension('SEARCH=FUZZY');
 390              }
 391              $temp['cmds']->add('FUZZY');
 392              $temp['exts_used'][] = 'SEARCH=FUZZY';
 393          }
 394      }
 395  
 396      /**
 397       * Search for a flag/keywords.
 398       *
 399       * @param string $name  The flag or keyword name.
 400       * @param boolean $set  If true, search for messages that have the flag
 401       *                      set.  If false, search for messages that do not
 402       *                      have the flag set.
 403       * @param array $opts   Additional options:
 404       *   - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server
 405       *            MUST support RFC 6203.
 406       */
 407      public function flag($name, $set = true, array $opts = array())
 408      {
 409          $name = strtoupper(ltrim($name, '\\'));
 410          if (!isset($this->_search['flag'])) {
 411              $this->_search['flag'] = array();
 412          }
 413  
 414          /* The list of defined system flags (see RFC 3501 [2.3.2]). */
 415          $systemflags = array(
 416              'ANSWERED', 'DELETED', 'DRAFT', 'FLAGGED', 'RECENT', 'SEEN'
 417          );
 418  
 419          $this->_search['flag'][$name] = array_filter(array(
 420              'fuzzy' => !empty($opts['fuzzy']),
 421              'set' => $set,
 422              'type' => in_array($name, $systemflags) ? 'flag' : 'keyword'
 423          ));
 424      }
 425  
 426      /**
 427       * Determines if flags are a part of the search.
 428       *
 429       * @return boolean  True if search query involves flags.
 430       */
 431      public function flagSearch()
 432      {
 433          return !empty($this->_search['flag']);
 434      }
 435  
 436      /**
 437       * Search for either new messages (messages that have the '\Recent' flag
 438       * but not the '\Seen' flag) or old messages (messages that do not have
 439       * the '\Recent' flag).  If new messages are searched, this will clear
 440       * any '\Recent' or '\Unseen' flag searches.  If old messages are searched,
 441       * this will clear any '\Recent' flag search.
 442       *
 443       * @param boolean $newmsgs  If true, searches for new messages.  Else,
 444       *                          search for old messages.
 445       * @param array $opts       Additional options:
 446       *   - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server
 447       *            MUST support RFC 6203.
 448       */
 449      public function newMsgs($newmsgs = true, array $opts = array())
 450      {
 451          $this->_search['new'] = $newmsgs;
 452          if (!empty($opts['fuzzy'])) {
 453              $this->_search['newfuzzy'] = true;
 454          }
 455      }
 456  
 457      /**
 458       * Search for text in the header of a message.
 459       *
 460       * @param string $header  The header field.
 461       * @param string $text    The search text.
 462       * @param boolean $not    If true, do a 'NOT' search of $text.
 463       * @param array $opts     Additional options:
 464       *   - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server
 465       *            MUST support RFC 6203.
 466       */
 467      public function headerText($header, $text, $not = false,
 468                                  array $opts = array())
 469      {
 470          if (!isset($this->_search['header'])) {
 471              $this->_search['header'] = array();
 472          }
 473          $this->_search['header'][] = array_filter(array(
 474              'fuzzy' => !empty($opts['fuzzy']),
 475              'header' => strtoupper($header),
 476              'text' => $text,
 477              'not' => $not
 478          ));
 479      }
 480  
 481      /**
 482       * Search for text in either the entire message, or just the body.
 483       *
 484       * @param string $text      The search text.
 485       * @param string $bodyonly  If true, only search in the body of the
 486       *                          message. If false, also search in the headers.
 487       * @param boolean $not      If true, do a 'NOT' search of $text.
 488       * @param array $opts       Additional options:
 489       *   - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server
 490       *            MUST support RFC 6203.
 491       */
 492      public function text($text, $bodyonly = true, $not = false,
 493                           array $opts = array())
 494      {
 495          if (!isset($this->_search['text'])) {
 496              $this->_search['text'] = array();
 497          }
 498  
 499          $this->_search['text'][] = array_filter(array(
 500              'fuzzy' => !empty($opts['fuzzy']),
 501              'not' => $not,
 502              'text' => $text,
 503              'type' => $bodyonly ? 'BODY' : 'TEXT'
 504          ));
 505      }
 506  
 507      /**
 508       * Search for messages smaller/larger than a certain size.
 509       *
 510       * @todo: Remove $not for 3.0
 511       *
 512       * @param integer $size    The size (in bytes).
 513       * @param boolean $larger  Search for messages larger than $size?
 514       * @param boolean $not     If true, do a 'NOT' search of $text.
 515       * @param array $opts      Additional options:
 516       *   - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server
 517       *            MUST support RFC 6203.
 518       */
 519      public function size($size, $larger = false, $not = false,
 520                           array $opts = array())
 521      {
 522          if (!isset($this->_search['size'])) {
 523              $this->_search['size'] = array();
 524          }
 525          $this->_search['size'][$larger ? 'LARGER' : 'SMALLER'] = array_filter(array(
 526              'fuzzy' => !empty($opts['fuzzy']),
 527              'not' => $not,
 528              'size' => (float)$size
 529          ));
 530      }
 531  
 532      /**
 533       * Search for messages within a given UID range. Only one message range
 534       * can be specified per query.
 535       *
 536       * @param Horde_Imap_Client_Ids $ids  The list of UIDs to search.
 537       * @param boolean $not                If true, do a 'NOT' search of the
 538       *                                    UIDs.
 539       * @param array $opts                 Additional options:
 540       *   - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server
 541       *            MUST support RFC 6203.
 542       */
 543      public function ids(Horde_Imap_Client_Ids $ids, $not = false,
 544                          array $opts = array())
 545      {
 546          if (!$ids->isEmpty()) {
 547              $this->_search['ids'] = array_filter(array(
 548                  'fuzzy' => !empty($opts['fuzzy']),
 549                  'ids' => $ids,
 550                  'not' => $not
 551              ));
 552          }
 553      }
 554  
 555      /**
 556       * Search for messages within a date range.
 557       *
 558       * @param mixed $date    DateTime or Horde_Date object.
 559       * @param string $range  Either:
 560       *   - Horde_Imap_Client_Search_Query::DATE_BEFORE
 561       *   - Horde_Imap_Client_Search_Query::DATE_ON
 562       *   - Horde_Imap_Client_Search_Query::DATE_SINCE
 563       * @param boolean $header  If true, search using the date in the message
 564       *                         headers. If false, search using the internal
 565       *                         IMAP date (usually arrival time).
 566       * @param boolean $not     If true, do a 'NOT' search of the range.
 567       * @param array $opts      Additional options:
 568       *   - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server
 569       *            MUST support RFC 6203.
 570       */
 571      public function dateSearch($date, $range, $header = true, $not = false,
 572                                 array $opts = array())
 573      {
 574          if (!isset($this->_search['date'])) {
 575              $this->_search['date'] = array();
 576          }
 577  
 578          // We should really be storing the raw DateTime object as data,
 579          // but all versions of the query object have converted at this stage.
 580          $ob = new Horde_Imap_Client_Data_Format_Date($date);
 581  
 582          $this->_search['date'][] = array_filter(array(
 583              'date' => $ob->escape(),
 584              'fuzzy' => !empty($opts['fuzzy']),
 585              'header' => $header,
 586              'range' => $range,
 587              'not' => $not
 588          ));
 589      }
 590  
 591      /**
 592       * Search for messages within a given interval. Only one interval of each
 593       * type can be specified per search query. If the IMAP server supports
 594       * the WITHIN extension (RFC 5032), it will be used.  Otherwise, the
 595       * search query will be dynamically created using IMAP4rev1 search
 596       * terms.
 597       *
 598       * @param integer $interval  Seconds from the present.
 599       * @param string $range      Either:
 600       *   - Horde_Imap_Client_Search_Query::INTERVAL_OLDER
 601       *   - Horde_Imap_Client_Search_Query::INTERVAL_YOUNGER
 602       * @param boolean $not       If true, do a 'NOT' search.
 603       * @param array $opts        Additional options:
 604       *   - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server
 605       *            MUST support RFC 6203.
 606       */
 607      public function intervalSearch($interval, $range, $not = false,
 608                                     array $opts = array())
 609      {
 610          if (!isset($this->_search['within'])) {
 611              $this->_search['within'] = array();
 612          }
 613          $this->_search['within'][$range] = array(
 614              'fuzzy' => !empty($opts['fuzzy']),
 615              'interval' => $interval,
 616              'not' => $not
 617          );
 618      }
 619  
 620      /**
 621       * AND queries - the contents of this query will be AND'ed (in its
 622       * entirety) with the contents of EACH of the queries passed in.  All
 623       * AND'd queries must share the same charset as this query.
 624       *
 625       * @param mixed $queries  A query, or an array of queries, to AND with the
 626       *                        current query.
 627       */
 628      public function andSearch($queries)
 629      {
 630          if (!isset($this->_search['and'])) {
 631              $this->_search['and'] = array();
 632          }
 633  
 634          if ($queries instanceof Horde_Imap_Client_Search_Query) {
 635              $queries = array($queries);
 636          }
 637  
 638          $this->_search['and'] = array_merge($this->_search['and'], $queries);
 639      }
 640  
 641      /**
 642       * OR a query - the contents of this query will be OR'ed (in its entirety)
 643       * with the contents of EACH of the queries passed in.  All OR'd queries
 644       * must share the same charset as this query.  All contents of any single
 645       * query will be AND'ed together.
 646       *
 647       * @param mixed $queries  A query, or an array of queries, to OR with the
 648       *                        current query.
 649       */
 650      public function orSearch($queries)
 651      {
 652          if (!isset($this->_search['or'])) {
 653              $this->_search['or'] = array();
 654          }
 655  
 656          if ($queries instanceof Horde_Imap_Client_Search_Query) {
 657              $queries = array($queries);
 658          }
 659  
 660          $this->_search['or'] = array_merge($this->_search['or'], $queries);
 661      }
 662  
 663      /**
 664       * Search for messages modified since a specific moment. The IMAP server
 665       * must support the CONDSTORE extension (RFC 7162) for this query to be
 666       * used.
 667       *
 668       * @param integer $value  The mod-sequence value.
 669       * @param string $name    The entry-name string.
 670       * @param string $type    Either 'shared', 'priv', or 'all'. Defaults to
 671       *                        'all'
 672       * @param boolean $not    If true, do a 'NOT' search.
 673       * @param array $opts     Additional options:
 674       *   - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server
 675       *            MUST support RFC 6203.
 676       */
 677      public function modseq($value, $name = null, $type = null, $not = false,
 678                             array $opts = array())
 679      {
 680          if (!is_null($type)) {
 681              $type = strtolower($type);
 682              if (!in_array($type, array('shared', 'priv', 'all'))) {
 683                  $type = 'all';
 684              }
 685          }
 686  
 687          $this->_search['modseq'] = array_filter(array(
 688              'fuzzy' => !empty($opts['fuzzy']),
 689              'name' => $name,
 690              'not' => $not,
 691              'type' => (!is_null($name) && is_null($type)) ? 'all' : $type,
 692              'value' => $value
 693          ));
 694      }
 695  
 696      /**
 697       * Use the results from the previous SEARCH command. The IMAP server must
 698       * support the SEARCHRES extension (RFC 5182) for this query to be used.
 699       *
 700       * @param boolean $not  If true, don't match the previous query.
 701       * @param array $opts   Additional options:
 702       *   - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server
 703       *            MUST support RFC 6203.
 704       */
 705      public function previousSearch($not = false, array $opts = array())
 706      {
 707          $this->_search['prevsearch'] = $not;
 708          if (!empty($opts['fuzzy'])) {
 709              $this->_search['prevsearchfuzzy'] = true;
 710          }
 711      }
 712  
 713      /* Serializable methods. */
 714  
 715      /**
 716       * Serialization.
 717       *
 718       * @return string  Serialized data.
 719       */
 720      public function serialize()
 721      {
 722          $data = array(
 723              // Serialized data ID.
 724              self::VERSION,
 725              $this->_search
 726          );
 727  
 728          if (!is_null($this->_charset)) {
 729              $data[] = $this->_charset;
 730          }
 731  
 732          return serialize($data);
 733      }
 734  
 735      /**
 736       * Unserialization.
 737       *
 738       * @param string $data  Serialized data.
 739       *
 740       * @throws Exception
 741       */
 742      public function unserialize($data)
 743      {
 744          $data = @unserialize($data);
 745          if (!is_array($data) ||
 746              !isset($data[0]) ||
 747              ($data[0] != self::VERSION)) {
 748              throw new Exception('Cache version change');
 749          }
 750  
 751          $this->_search = $data[1];
 752          if (isset($data[2])) {
 753              $this->_charset = $data[2];
 754          }
 755      }
 756  
 757  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1