Horde_Imap_Client_Fetch_Query::modseq PHP Method

modseq() public method

The server must support the CONDSTORE IMAP extension, and the mailbox must support mod-sequences.
public modseq ( )
    public function modseq()
    {
        $this->_data[Horde_Imap_Client::FETCH_MODSEQ] = true;
    }

Usage Example

Esempio n. 1
0
 /**
  * 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;
 }
All Usage Examples Of Horde_Imap_Client_Fetch_Query::modseq