modseq() 공개 메소드

Search for messages modified since a specific moment. The IMAP server must support the CONDSTORE extension (RFC 7162) for this query to be used.
public modseq ( integer $value, string $name = null, string $type = null, boolean $not = false, array $opts = [] )
$value integer The mod-sequence value.
$name string The entry-name string.
$type string Either 'shared', 'priv', or 'all'. Defaults to 'all'
$not boolean If true, do a 'NOT' search.
$opts array Additional options: - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server MUST support RFC 6203.
예제 #1
0
파일: SearchTest.php 프로젝트: horde/horde
 /**
  * @dataProvider modseqSearchQueryProvider
  */
 public function testModseq($name, $type, $not, $fuzzy, $expected)
 {
     $ob = new Horde_Imap_Client_Search_Query();
     $ob->modseq(123, $name, $type, $not, array('fuzzy' => $fuzzy));
     $this->assertEquals($expected, $fuzzy ? $this->_fuzzy($ob, array('CONDSTORE')) : strval($ob));
 }
예제 #2
0
파일: Adapter.php 프로젝트: raz0rsdge/horde
 /**
  * Return message changes from the specified mailbox.
  *
  * @param Horde_ActiveSync_Folder_Imap $folder  The folder object.
  * @param array $options                        Additional options:
  *  - sincedate: (integer)       Timestamp of earliest message to retrieve.
  *                               DEFAULT: 0 (Don't filter).
  *  - protocolversion: (float)   EAS protocol version to support.
  *                               DEFAULT: none REQUIRED
  *  - softdelete: (boolean)      If true, calculate SOFTDELETE data.
  *                               @since 2.8.0
  *  - refreshfilter: (boolean)   If true, force refresh the query to reflect
  *                               changes in FILTERTYPE (using the sincedate)
  *                               @since 2.28.0
  *
  * @return Horde_ActiveSync_Folder_Imap  The folder object, containing any
  *                                       change instructions for the device.
  *
  * @throws Horde_ActiveSync_Exception_FolderGone,
  *         Horde_ActiveSync_Exception, Horde_ActiveSync_Exception_StaleState
  */
 public function getMessageChanges(Horde_ActiveSync_Folder_Imap $folder, array $options = array())
 {
     $imap = $this->_getImapOb();
     $mbox = new Horde_Imap_Client_Mailbox($folder->serverid());
     $flags = array();
     $search_uids = array();
     // Note: non-CONDSTORE servers will return a highestmodseq of 0
     $status_flags = Horde_Imap_Client::STATUS_HIGHESTMODSEQ | Horde_Imap_Client::STATUS_UIDVALIDITY | Horde_Imap_Client::STATUS_UIDNEXT_FORCE | Horde_Imap_Client::STATUS_MESSAGES | Horde_Imap_Client::STATUS_FORCE_REFRESH;
     try {
         $status = $imap->status($mbox, $status_flags);
     } catch (Horde_Imap_Client_Exception $e) {
         // If we can't status the mailbox, assume it's gone.
         throw new Horde_ActiveSync_Exception_FolderGone($e);
     }
     $this->_logger->info(sprintf('[%s] IMAP status: %s', $this->_procid, serialize($status)));
     $current_modseq = $status[Horde_ActiveSync_Folder_Imap::HIGHESTMODSEQ];
     if ($current_modseq && $folder->modseq() > 0 && ($folder->modseq() < $current_modseq || !empty($options['softdelete']) || !empty($options['refreshfilter']))) {
         $this->_logger->info(sprintf('[%s] CONDSTORE and CHANGES', $this->_procid));
         $folder->checkValidity($status);
         // Catch all *changes* since the provided MODSEQ value.
         $query = new Horde_Imap_Client_Search_Query();
         // $imap->search uses a >= comparison for MODSEQ, so we must
         // increment by one so we don't continuously receive the same change
         // set.
         $query->modseq($folder->modseq() + 1);
         if (!empty($options['sincedate'])) {
             $query->dateSearch(new Horde_Date($options['sincedate']), Horde_Imap_Client_Search_Query::DATE_SINCE);
         }
         $search_ret = $imap->search($mbox, $query, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH)));
         $search_uids = $search_ret['count'] ? $search_ret['match']->ids : array();
         // Catch changes to FILTERTYPE.
         if (!empty($options['refreshfilter'])) {
             $this->_logger->info(sprintf('[%s] Checking for additional messages within the new FilterType parameters.', $this->_procid));
             $search_ret = $this->_buildSearchQuery($folder, $options, $mbox, false);
             if ($search_ret['count']) {
                 $this->_logger->info(sprintf('[%s] Found %d messages that are now outside FilterType.', $this->_procid, $search_ret['count']));
                 $search_uids = array_merge($search_uids, $search_ret['match']->ids);
             } else {
                 $this->_logger->info(sprintf('[%s] Found NO additional messages.', $this->_procid));
             }
         }
         // Protect against very large change sets like might occur if
         // the FILTERTYPE is changed from some short interval like one week
         // to no filter at all.
         $cnt = count($search_uids) / self::MAX_FETCH + 1;
         $query = new Horde_Imap_Client_Fetch_Query();
         $query->modseq();
         $query->flags();
         $changes = array();
         $categories = array();
         for ($i = 0; $i <= $cnt; $i++) {
             $ids = new Horde_Imap_Client_Ids(array_slice($search_uids, $i * self::MAX_FETCH, self::MAX_FETCH));
             try {
                 $fetch_ret = $imap->fetch($mbox, $query, array('ids' => $ids));
             } catch (Horde_Imap_Client_Exception $e) {
                 $this->_logger->err($e->getMessage());
                 throw new Horde_ActiveSync_Exception($e);
             }
             $this->_buildModSeqChanges($changes, $flags, $categories, $fetch_ret, $options, $current_modseq);
         }
         // Set the changes in the folder object.
         $folder->setChanges($changes, $flags, $categories, !empty($options['softdelete']) || !empty($options['refreshfilter']));
         // Check for deleted messages.
         try {
             $deleted = $imap->vanished($mbox, $folder->modseq(), array('ids' => new Horde_Imap_Client_Ids($folder->messages())));
         } catch (Horde_Imap_Client_Excetion $e) {
             $this->_logger->err($e->getMessage());
             throw new Horde_ActiveSync_Exception($e);
         }
         $folder->setRemoved($deleted->ids);
         $this->_logger->info(sprintf('[%s] Found %d deleted messages.', $this->_procid, $deleted->count()));
         // Check for SOFTDELETE messages.
         if ((!empty($options['softdelete']) || !empty($options['refreshfilter'])) && !empty($options['sincedate'])) {
             $this->_logger->info(sprintf('[%s] Polling for SOFTDELETE in %s before %d', $this->_procid, $folder->serverid(), $options['sincedate']));
             $search_ret = $this->_buildSearchQuery($folder, $options, $mbox, true);
             if ($search_ret['count']) {
                 $this->_logger->info(sprintf('[%s] Found %d messages to SOFTDELETE.', $this->_procid, count($search_ret['match']->ids)));
                 $folder->setSoftDeleted($search_ret['match']->ids);
             } else {
                 $this->_logger->info(sprintf('[%s] Found NO messages to SOFTDELETE.', $this->_procid));
             }
             $folder->setSoftDeleteTimes($options['sincedate'], time());
         }
     } elseif ($folder->uidnext() == 0) {
         $this->_logger->info(sprintf('[%s] INITIAL SYNC', $this->_procid));
         $query = new Horde_Imap_Client_Search_Query();
         if (!empty($options['sincedate'])) {
             $query->dateSearch(new Horde_Date($options['sincedate']), Horde_Imap_Client_Search_Query::DATE_SINCE);
         }
         $search_ret = $imap->search($mbox, $query, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH)));
         if ($current_modseq && !$folder->haveInitialSync) {
             $this->_logger->info(sprintf('[%s] Priming IMAP folder object.', $this->_procid));
             $folder->primeFolder($search_ret['match']->ids);
         } elseif (count($search_ret['match']->ids)) {
             // No modseq.
             $query = new Horde_Imap_Client_Fetch_Query();
             $query->flags();
             $cnt = $search_ret['count'] / self::MAX_FETCH + 1;
             for ($i = 0; $i <= $cnt; $i++) {
                 $ids = new Horde_Imap_Client_Ids(array_slice($search_ret['match']->ids, $i * self::MAX_FETCH, self::MAX_FETCH));
                 $fetch_ret = $imap->fetch($mbox, $query, array('ids' => $ids));
                 foreach ($fetch_ret as $uid => $data) {
                     $flags[$uid] = array('read' => array_search(Horde_Imap_Client::FLAG_SEEN, $data->getFlags()) !== false ? 1 : 0);
                     if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWOFIVE) {
                         $flags[$uid]['flagged'] = array_search(Horde_Imap_Client::FLAG_FLAGGED, $data->getFlags()) !== false ? 1 : 0;
                     }
                 }
             }
             $folder->setChanges($search_ret['match']->ids, $flags);
         }
     } elseif ($current_modseq == 0) {
         $this->_logger->info(sprintf('[%s] NO CONDSTORE or per mailbox MODSEQ. minuid: %s, total_messages: %s', $this->_procid, $folder->minuid(), $status['messages']));
         $folder->checkValidity($status);
         $query = new Horde_Imap_Client_Search_Query();
         if (!empty($options['sincedate'])) {
             $query->dateSearch(new Horde_Date($options['sincedate']), Horde_Imap_Client_Search_Query::DATE_SINCE);
         }
         try {
             $search_ret = $imap->search($mbox, $query, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH)));
         } catch (Horde_Imap_Client_Exception $e) {
             $this->_logger->err($e->getMessage());
             throw new Horde_ActiveSync_Exception($e);
         }
         $cnt = $search_ret['count'] / self::MAX_FETCH + 1;
         $query = new Horde_Imap_Client_Fetch_Query();
         $query->flags();
         for ($i = 0; $i <= $cnt; $i++) {
             $ids = new Horde_Imap_Client_Ids(array_slice($search_ret['match']->ids, $i * self::MAX_FETCH, self::MAX_FETCH));
             try {
                 $fetch_ret = $imap->fetch($mbox, $query, array('ids' => $ids));
             } catch (Horde_Imap_Client_Exception $e) {
                 $this->_logger->err($e->getMessage());
                 throw new Horde_ActiveSync_Exception($e);
             }
             foreach ($fetch_ret as $uid => $data) {
                 $flags[$uid] = array('read' => array_search(Horde_Imap_Client::FLAG_SEEN, $data->getFlags()) !== false ? 1 : 0);
                 if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWOFIVE) {
                     $flags[$uid]['flagged'] = array_search(Horde_Imap_Client::FLAG_FLAGGED, $data->getFlags()) !== false ? 1 : 0;
                 }
             }
         }
         if (!empty($flags)) {
             $folder->setChanges($search_ret['match']->ids, $flags);
         }
         $folder->setRemoved($imap->vanished($mbox, null, array('ids' => new Horde_Imap_Client_Ids($folder->messages())))->ids);
     } elseif ($current_modseq > 0 && $folder->modseq() == 0) {
         throw new Horde_ActiveSync_Exception_StaleState('Transition to MODSEQ enabled server');
     }
     $folder->setStatus($status);
     return $folder;
 }
예제 #3
0
파일: Sync.php 프로젝트: raz0rsdge/horde
 /**
  * Constructor.
  *
  * @param Horde_Imap_Client_Base $base_ob  Base driver object.
  * @param mixed $mailbox                   Mailbox to sync.
  * @param array $sync                      Token sync data.
  * @param array $curr                      Current sync data.
  * @param integer $criteria                Mask of criteria to return.
  * @param Horde_Imap_Client_Ids $ids       List of known UIDs.
  *
  * @throws Horde_Imap_Client_Exception
  * @throws Horde_Imap_Client_Exception_Sync
  */
 public function __construct(Horde_Imap_Client_Base $base_ob, $mailbox, $sync, $curr, $criteria, $ids)
 {
     foreach (self::$map as $key => $val) {
         if (isset($sync[$key])) {
             $this->{$val} = $sync[$key];
         }
     }
     /* Check uidvalidity. */
     if (!$this->uidvalidity || $curr['V'] != $this->uidvalidity) {
         throw new Horde_Imap_Client_Exception_Sync('UIDs in cached mailbox have changed.', Horde_Imap_Client_Exception_Sync::UIDVALIDITY_CHANGED);
     }
     $this->mailbox = $mailbox;
     /* This was a UIDVALIDITY check only. */
     if (!$criteria) {
         return;
     }
     $sync_all = $criteria & Horde_Imap_Client::SYNC_ALL;
     /* New messages. */
     if ($sync_all || $criteria & Horde_Imap_Client::SYNC_NEWMSGS || $criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS) {
         $this->newmsgs = empty($this->uidnext) ? !empty($curr['U']) : !empty($curr['U']) && $curr['U'] > $this->uidnext;
         if ($this->newmsgs && ($sync_all || $criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) {
             $new_ids = empty($this->uidnext) ? Horde_Imap_Client_Ids::ALL : $this->uidnext . ':' . $curr['U'];
             $squery = new Horde_Imap_Client_Search_Query();
             $squery->ids(new Horde_Imap_Client_Ids($new_ids));
             $sres = $base_ob->search($mailbox, $squery);
             $this->_newmsgsuids = $sres['match'];
         }
     }
     /* Do single status call to get all necessary data. */
     if ($this->highestmodseq && ($sync_all || $criteria & Horde_Imap_Client::SYNC_FLAGS || $criteria & Horde_Imap_Client::SYNC_FLAGSUIDS || $criteria & Horde_Imap_Client::SYNC_VANISHED || $criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) {
         $status_sync = $base_ob->status($mailbox, Horde_Imap_Client::STATUS_SYNCMODSEQ | Horde_Imap_Client::STATUS_SYNCFLAGUIDS | Horde_Imap_Client::STATUS_SYNCVANISHED);
         if (!is_null($ids)) {
             $ids = $base_ob->resolveIds($mailbox, $ids);
         }
     }
     /* Flag changes. */
     if ($sync_all || $criteria & Horde_Imap_Client::SYNC_FLAGS) {
         $this->flags = $this->highestmodseq ? $this->highestmodseq != $curr['H'] : true;
     }
     if ($sync_all || $criteria & Horde_Imap_Client::SYNC_FLAGSUIDS) {
         if ($this->highestmodseq) {
             if ($this->highestmodseq == $status_sync['syncmodseq']) {
                 $this->_flagsuids = is_null($ids) ? $status_sync['syncflaguids'] : $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncflaguids']->ids));
             } else {
                 $squery = new Horde_Imap_Client_Search_Query();
                 $squery->modseq($this->highestmodseq + 1);
                 $sres = $base_ob->search($mailbox, $squery, array('ids' => $ids));
                 $this->_flagsuids = $sres['match'];
             }
         } else {
             /* Without MODSEQ, need to mark all FLAGS as changed. */
             $this->_flagsuids = $base_ob->resolveIds($mailbox, is_null($ids) ? $base_ob->getIdsOb(Horde_Imap_Client_Ids::ALL) : $ids);
         }
     }
     /* Vanished messages. */
     if ($sync_all || $criteria & Horde_Imap_Client::SYNC_VANISHED || $criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS) {
         if ($this->highestmodseq && $this->highestmodseq == $status_sync['syncmodseq']) {
             $vanished = is_null($ids) ? $status_sync['syncvanished'] : $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncvanished']->ids));
         } else {
             $vanished = $base_ob->vanished($mailbox, $this->highestmodseq ? $this->highestmodseq : 1, array('ids' => $ids));
         }
         $this->vanished = (bool) count($vanished);
         $this->_vanisheduids = $vanished;
     }
 }
예제 #4
0
파일: Base.php 프로젝트: Gomez/horde
 /**
  * Wrapper for fetch() to allow internal state to be reset on exception.
  *
  * @internal
  * @see fetch()
  */
 private function _fetchWrapper($mailbox, $query, $options)
 {
     $this->login();
     $query = clone $query;
     $cache_array = $header_cache = $new_query = array();
     if (empty($options['ids'])) {
         $options['ids'] = $this->getIdsOb(Horde_Imap_Client_Ids::ALL);
     } elseif ($options['ids']->isEmpty()) {
         return new Horde_Imap_Client_Fetch_Results($this->_fetchDataClass);
     } elseif ($options['ids']->search_res && !$this->_capability('SEARCHRES')) {
         /* SEARCHRES requires server support. */
         throw new Horde_Imap_Client_Exception_NoSupportExtension('SEARCHRES');
     }
     $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO);
     $mbox_ob = $this->_mailboxOb();
     if (!empty($options['nocache'])) {
         $this->_temp['fetch_nocache'] = true;
     }
     $cf = $this->_initCache(true) ? $this->_cacheFields() : array();
     if (!empty($cf)) {
         /* If using cache, we store by UID so we need to return UIDs. */
         $query->uid();
     }
     $modseq_check = !empty($options['changedsince']);
     if ($query->contains(Horde_Imap_Client::FETCH_MODSEQ)) {
         if (!$this->_capability()->isEnabled('CONDSTORE')) {
             unset($query[Horde_Imap_Client::FETCH_MODSEQ]);
         } elseif (empty($options['changedsince'])) {
             $modseq_check = true;
         }
     }
     if ($modseq_check && !$mbox_ob->getStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ)) {
         /* RFC 7162 [3.1.2.2] - trying to do a MODSEQ FETCH on a mailbox
          * that doesn't support it will return BAD. */
         throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Mailbox does not support mod-sequences."), Horde_Imap_Client_Exception::MBOXNOMODSEQ);
     }
     /* Determine if caching is available and if anything in $query is
      * cacheable. */
     foreach ($cf as $k => $v) {
         if (isset($query[$k])) {
             switch ($k) {
                 case Horde_Imap_Client::FETCH_ENVELOPE:
                 case Horde_Imap_Client::FETCH_FLAGS:
                 case Horde_Imap_Client::FETCH_IMAPDATE:
                 case Horde_Imap_Client::FETCH_SIZE:
                 case Horde_Imap_Client::FETCH_STRUCTURE:
                     $cache_array[$k] = $v;
                     break;
                 case Horde_Imap_Client::FETCH_HEADERS:
                     $this->_temp['headers_caching'] = array();
                     foreach ($query[$k] as $key => $val) {
                         /* Only cache if directly requested.  Iterate through
                          * requests to ensure at least one can be cached. */
                         if (!empty($val['cache']) && !empty($val['peek'])) {
                             $cache_array[$k] = $v;
                             ksort($val);
                             $header_cache[$key] = hash('md5', serialize($val));
                         }
                     }
                     break;
             }
         }
     }
     $ret = new Horde_Imap_Client_Fetch_Results($this->_fetchDataClass, $options['ids']->sequence ? Horde_Imap_Client_Fetch_Results::SEQUENCE : Horde_Imap_Client_Fetch_Results::UID);
     /* If nothing is cacheable, we can do a straight search. */
     if (empty($cache_array)) {
         $options['_query'] = $query;
         $this->_fetch($ret, array($options));
         return $ret;
     }
     $cs_ret = empty($options['changedsince']) ? null : clone $ret;
     /* Convert special searches to UID lists and create mapping. */
     $ids = $this->resolveIds($this->_selected, $options['ids'], empty($options['exists']) ? 1 : 2);
     /* Add non-user settable cache fields. */
     $cache_array[Horde_Imap_Client::FETCH_DOWNGRADED] = self::CACHE_DOWNGRADED;
     /* Get the cached values. */
     $data = $this->_cache->get($this->_selected, $ids->ids, array_values($cache_array), $mbox_ob->getStatus(Horde_Imap_Client::STATUS_UIDVALIDITY));
     /* Build a list of what we still need. */
     $map = array_flip($mbox_ob->map->map);
     $sequence = $options['ids']->sequence;
     foreach ($ids as $uid) {
         $crit = clone $query;
         if ($sequence) {
             if (!isset($map[$uid])) {
                 continue;
             }
             $entry_idx = $map[$uid];
         } else {
             $entry_idx = $uid;
             unset($crit[Horde_Imap_Client::FETCH_UID]);
         }
         $entry = $ret->get($entry_idx);
         if (isset($map[$uid])) {
             $entry->setSeq($map[$uid]);
             unset($crit[Horde_Imap_Client::FETCH_SEQ]);
         }
         $entry->setUid($uid);
         foreach ($cache_array as $key => $cid) {
             switch ($key) {
                 case Horde_Imap_Client::FETCH_DOWNGRADED:
                     if (!empty($data[$uid][$cid])) {
                         $entry->setDowngraded(true);
                     }
                     break;
                 case Horde_Imap_Client::FETCH_ENVELOPE:
                     if (isset($data[$uid][$cid]) && $data[$uid][$cid] instanceof Horde_Imap_Client_Data_Envelope) {
                         $entry->setEnvelope($data[$uid][$cid]);
                         unset($crit[$key]);
                     }
                     break;
                 case Horde_Imap_Client::FETCH_FLAGS:
                     if (isset($data[$uid][$cid]) && is_array($data[$uid][$cid])) {
                         $entry->setFlags($data[$uid][$cid]);
                         unset($crit[$key]);
                     }
                     break;
                 case Horde_Imap_Client::FETCH_HEADERS:
                     foreach ($header_cache as $hkey => $hval) {
                         if (isset($data[$uid][$cid][$hval])) {
                             /* We have found a cached entry with the same
                              * MD5 sum. */
                             $entry->setHeaders($hkey, $data[$uid][$cid][$hval]);
                             $crit->remove($key, $hkey);
                         } else {
                             $this->_temp['headers_caching'][$hkey] = $hval;
                         }
                     }
                     break;
                 case Horde_Imap_Client::FETCH_IMAPDATE:
                     if (isset($data[$uid][$cid]) && $data[$uid][$cid] instanceof Horde_Imap_Client_DateTime) {
                         $entry->setImapDate($data[$uid][$cid]);
                         unset($crit[$key]);
                     }
                     break;
                 case Horde_Imap_Client::FETCH_SIZE:
                     if (isset($data[$uid][$cid])) {
                         $entry->setSize($data[$uid][$cid]);
                         unset($crit[$key]);
                     }
                     break;
                 case Horde_Imap_Client::FETCH_STRUCTURE:
                     if (isset($data[$uid][$cid]) && $data[$uid][$cid] instanceof Horde_Mime_Part) {
                         $entry->setStructure($data[$uid][$cid]);
                         unset($crit[$key]);
                     }
                     break;
             }
         }
         if (count($crit)) {
             $sig = $crit->hash();
             if (isset($new_query[$sig])) {
                 $new_query[$sig]['i'][] = $entry_idx;
             } else {
                 $new_query[$sig] = array('c' => $crit, 'i' => array($entry_idx));
             }
         }
     }
     $to_fetch = array();
     foreach ($new_query as $val) {
         $ids_ob = $this->getIdsOb(null, $sequence);
         $ids_ob->duplicates = true;
         $ids_ob->add($val['i']);
         $to_fetch[] = array_merge($options, array('_query' => $val['c'], 'ids' => $ids_ob));
     }
     if (!empty($to_fetch)) {
         $this->_fetch(is_null($cs_ret) ? $ret : $cs_ret, $to_fetch);
     }
     if (is_null($cs_ret)) {
         return $ret;
     }
     /* If doing changedsince query, and all other data is cached, we still
      * need to hit IMAP server to determine proper results set. */
     if (empty($new_query)) {
         $squery = new Horde_Imap_Client_Search_Query();
         $squery->modseq($options['changedsince'] + 1);
         $squery->ids($options['ids']);
         $cs = $this->search($this->_selected, $squery, array('sequence' => $sequence));
         foreach ($cs['match'] as $val) {
             $entry = $ret->get($val);
             if ($sequence) {
                 $entry->setSeq($val);
             } else {
                 $entry->setUid($val);
             }
             $cs_ret[$val] = $entry;
         }
     } else {
         foreach ($cs_ret as $key => $val) {
             $val->merge($ret->get($key));
         }
     }
     return $cs_ret;
 }
예제 #5
0
파일: Modseq.php 프로젝트: horde/horde
 /**
  * Return a folder object containing all IMAP server change information.
  *
  * @param array $options  An array of options.
  *        @see Horde_ActiveSync_Imap_Adapter::getMessageChanges
  *
  * @return Horde_ActiveSync_Folder_Base  The populated folder object.
  */
 public function getChanges(array $options)
 {
     $this->_logger->info(sprintf('[%s] CONDSTORE and CHANGES', $this->_procid));
     $flags = array();
     $current_modseq = $this->_status[Horde_ActiveSync_Folder_Imap::HIGHESTMODSEQ];
     $query = new Horde_Imap_Client_Search_Query();
     // Increment since $imap->search uses >= operator.
     if ($this->_modseq_valid) {
         $query->modseq($this->_folder->modseq() + 1);
     }
     if (!empty($options['sincedate'])) {
         $query->dateSearch(new Horde_Date($options['sincedate']), Horde_Imap_Client_Search_Query::DATE_SINCE);
     }
     $search_ret = $this->_imap_ob->search($this->_mbox, $query, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH)));
     $search_uids = $search_ret['count'] ? $search_ret['match']->ids : array();
     // Catch changes to FILTERTYPE.
     if (!empty($options['refreshfilter'])) {
         $this->_logger->info(sprintf('[%s] Checking for additional messages within the new FilterType parameters.', $this->_procid));
         $search_ret = $this->_searchQuery($options, false);
         if ($search_ret['count']) {
             $this->_logger->info(sprintf('[%s] Found %d messages that are now outside FilterType.', $this->_procid, $search_ret['count']));
             $search_uids = array_merge($search_uids, $search_ret['match']->ids);
         }
     }
     // Protect against very large change sets.
     $cnt = count($search_uids) / Horde_ActiveSync_Imap_Adapter::MAX_FETCH + 1;
     $query = new Horde_Imap_Client_Fetch_Query();
     if ($this->_modseq_valid) {
         $query->modseq();
     }
     $query->flags();
     $changes = array();
     $categories = array();
     for ($i = 0; $i <= $cnt; $i++) {
         $ids = new Horde_Imap_Client_Ids(array_slice($search_uids, $i * Horde_ActiveSync_Imap_Adapter::MAX_FETCH, Horde_ActiveSync_Imap_Adapter::MAX_FETCH));
         try {
             $fetch_ret = $this->_imap_ob->fetch($this->_mbox, $query, array('ids' => $ids));
         } catch (Horde_Imap_Client_Exception $e) {
             $this->_logger->err($e->getMessage());
             throw new Horde_ActiveSync_Exception($e);
         }
         $this->_buildModSeqChanges($changes, $flags, $categories, $fetch_ret, $options, $current_modseq);
     }
     // Set the changes in the folder object.
     $this->_folder->setChanges($changes, $flags, $categories, !empty($options['softdelete']) || !empty($options['refreshfilter']));
     // Check for deleted messages.
     try {
         $deleted = $this->_imap_ob->vanished($this->_mbox, $this->_folder->modseq(), array('ids' => new Horde_Imap_Client_Ids($this->_folder->messages())));
     } catch (Horde_Imap_Client_Excetion $e) {
         $this->_logger->err($e->getMessage());
         throw new Horde_ActiveSync_Exception($e);
     }
     $this->_folder->setRemoved($deleted->ids);
     $this->_logger->info(sprintf('[%s] Found %d deleted messages.', $this->_procid, $deleted->count()));
     // Check for SOFTDELETE messages.
     if (!empty($options['sincedate']) && (!empty($options['softdelete']) || !empty($options['refreshfilter']))) {
         $this->_logger->info(sprintf('[%s] Polling for SOFTDELETE in %s before %d', $this->_procid, $this->_folder->serverid(), $options['sincedate']));
         $search_ret = $this->_searchQuery($options, true);
         if ($search_ret['count']) {
             $this->_logger->info(sprintf('[%s] Found %d messages to SOFTDELETE.', $this->_procid, count($search_ret['match']->ids)));
             $this->_folder->setSoftDeleted($search_ret['match']->ids);
         }
         $this->_folder->setSoftDeleteTimes($options['sincedate'], time());
     }
     return $this->_folder;
 }