Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.
   1  <?php
   2  /**
   3   * Copyright 2012-2017 Horde LLC (http://www.horde.org/)
   4   *
   5   * See the enclosed file LICENSE 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 2012-2017 Horde LLC
  10   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  11   * @package   Imap_Client
  12   */
  13  
  14  /**
  15   * Mailbox synchronization results.
  16   *
  17   * @author    Michael Slusarz <slusarz@horde.org>
  18   * @category  Horde
  19   * @copyright 2012-2017 Horde LLC
  20   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  21   * @package   Imap_Client
  22   * @since     2.2.0
  23   *
  24   * @property-read Horde_Imap_Client_Ids $flagsuids  List of messages with flag
  25   *                                                  changes.
  26   * @property-read Horde_Imap_Client_Ids $newmsgsuids  List of new messages.
  27   * @property-read Horde_Imap_Client_Ids $vanisheduids  List of messages that
  28   *                                                     have vanished.
  29   */
  30  class Horde_Imap_Client_Data_Sync
  31  {
  32      /**
  33       * Mappings of status() values to sync keys.
  34       *
  35       * @since 2.8.0
  36       *
  37       * @var array
  38       */
  39      public static $map = array(
  40          'H' => 'highestmodseq',
  41          'M' => 'messages',
  42          'U' => 'uidnext',
  43          'V' => 'uidvalidity'
  44      );
  45  
  46      /**
  47       * Are there messages that have had flag changes?
  48       *
  49       * @var boolean
  50       */
  51      public $flags = null;
  52  
  53      /**
  54       * The previous value of HIGHESTMODSEQ.
  55       *
  56       * @since 2.8.0
  57       *
  58       * @var integer
  59       */
  60      public $highestmodseq = null;
  61  
  62      /**
  63       * The synchronized mailbox.
  64       *
  65       * @var Horde_Imap_Client_Mailbox
  66       */
  67      public $mailbox;
  68  
  69      /**
  70       * The previous number of messages in the mailbox.
  71       *
  72       * @since 2.8.0
  73       *
  74       * @var integer
  75       */
  76      public $messages = null;
  77  
  78      /**
  79       * Are there new messages?
  80       *
  81       * @var boolean
  82       */
  83      public $newmsgs = null;
  84  
  85      /**
  86       * The previous value of UIDNEXT.
  87       *
  88       * @since 2.8.0
  89       *
  90       * @var integer
  91       */
  92      public $uidnext = null;
  93  
  94      /**
  95       * The previous value of UIDVALIDITY.
  96       *
  97       * @since 2.8.0
  98       *
  99       * @var integer
 100       */
 101      public $uidvalidity = null;
 102  
 103      /**
 104       * The UIDs of messages that are guaranteed to have vanished. This list is
 105       * only guaranteed to be available if the server supports QRESYNC or a
 106       * list of known UIDs is passed to the sync() method.
 107       *
 108       * @var Horde_Imap_Client_Ids
 109       */
 110      public $vanished = null;
 111  
 112      /**
 113       * UIDs of messages that have had flag changes.
 114       *
 115       * @var Horde_Imap_Client_Ids
 116       */
 117      protected $_flagsuids;
 118  
 119      /**
 120       * UIDs of new messages.
 121       *
 122       * @var Horde_Imap_Client_Ids
 123       */
 124      protected $_newmsgsuids;
 125  
 126      /**
 127       * UIDs of messages that have vanished.
 128       *
 129       * @var Horde_Imap_Client_Ids
 130       */
 131      protected $_vanisheduids;
 132  
 133      /**
 134       * Constructor.
 135       *
 136       * @param Horde_Imap_Client_Base $base_ob  Base driver object.
 137       * @param mixed $mailbox                   Mailbox to sync.
 138       * @param array $sync                      Token sync data.
 139       * @param array $curr                      Current sync data.
 140       * @param integer $criteria                Mask of criteria to return.
 141       * @param Horde_Imap_Client_Ids $ids       List of known UIDs.
 142       *
 143       * @throws Horde_Imap_Client_Exception
 144       * @throws Horde_Imap_Client_Exception_Sync
 145       */
 146      public function __construct(Horde_Imap_Client_Base $base_ob, $mailbox,
 147                                  $sync, $curr, $criteria, $ids)
 148      {
 149          foreach (self::$map as $key => $val) {
 150              if (isset($sync[$key])) {
 151                  $this->$val = $sync[$key];
 152              }
 153          }
 154  
 155          /* Check uidvalidity. */
 156          if (!$this->uidvalidity || ($curr['V'] != $this->uidvalidity)) {
 157              throw new Horde_Imap_Client_Exception_Sync('UIDs in cached mailbox have changed.', Horde_Imap_Client_Exception_Sync::UIDVALIDITY_CHANGED);
 158          }
 159  
 160          $this->mailbox = $mailbox;
 161  
 162          /* This was a UIDVALIDITY check only. */
 163          if (!$criteria) {
 164              return;
 165          }
 166  
 167          $sync_all = ($criteria & Horde_Imap_Client::SYNC_ALL);
 168  
 169          /* New messages. */
 170          if ($sync_all ||
 171              ($criteria & Horde_Imap_Client::SYNC_NEWMSGS) ||
 172              ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) {
 173              $this->newmsgs = empty($this->uidnext)
 174                  ? !empty($curr['U'])
 175                  : (!empty($curr['U']) && ($curr['U'] > $this->uidnext));
 176  
 177              if ($this->newmsgs &&
 178                  ($sync_all ||
 179                   ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS))) {
 180                  $new_ids = empty($this->uidnext)
 181                      ? Horde_Imap_Client_Ids::ALL
 182                      : ($this->uidnext . ':' . $curr['U']);
 183  
 184                  $squery = new Horde_Imap_Client_Search_Query();
 185                  $squery->ids(new Horde_Imap_Client_Ids($new_ids));
 186                  $sres = $base_ob->search($mailbox, $squery);
 187  
 188                  $this->_newmsgsuids = $sres['match'];
 189              }
 190          }
 191  
 192          /* Do single status call to get all necessary data. */
 193          if ($this->highestmodseq &&
 194              ($sync_all ||
 195               ($criteria & Horde_Imap_Client::SYNC_FLAGS) ||
 196               ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS) ||
 197               ($criteria & Horde_Imap_Client::SYNC_VANISHED) ||
 198               ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS))) {
 199              $status_sync = $base_ob->status($mailbox, Horde_Imap_Client::STATUS_SYNCMODSEQ | Horde_Imap_Client::STATUS_SYNCFLAGUIDS | Horde_Imap_Client::STATUS_SYNCVANISHED);
 200  
 201              if (!is_null($ids)) {
 202                  $ids = $base_ob->resolveIds($mailbox, $ids);
 203              }
 204          }
 205  
 206          /* Flag changes. */
 207          if ($sync_all || ($criteria & Horde_Imap_Client::SYNC_FLAGS)) {
 208              $this->flags = $this->highestmodseq
 209                  ? ($this->highestmodseq != $curr['H'])
 210                  : true;
 211          }
 212  
 213          if ($sync_all || ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS)) {
 214              if ($this->highestmodseq) {
 215                  if ($this->highestmodseq == $status_sync['syncmodseq']) {
 216                      $this->_flagsuids = is_null($ids)
 217                          ? $status_sync['syncflaguids']
 218                          : $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncflaguids']->ids));
 219                  } else {
 220                      $squery = new Horde_Imap_Client_Search_Query();
 221                      $squery->modseq($this->highestmodseq + 1);
 222                      $sres = $base_ob->search($mailbox, $squery, array(
 223                          'ids' => $ids
 224                      ));
 225                      $this->_flagsuids = $sres['match'];
 226                  }
 227              } else {
 228                  /* Without MODSEQ, need to mark all FLAGS as changed. */
 229                  $this->_flagsuids = $base_ob->resolveIds($mailbox, is_null($ids) ? $base_ob->getIdsOb(Horde_Imap_Client_Ids::ALL) : $ids);
 230              }
 231          }
 232  
 233          /* Vanished messages. */
 234          if ($sync_all ||
 235              ($criteria & Horde_Imap_Client::SYNC_VANISHED) ||
 236              ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) {
 237              if ($this->highestmodseq &&
 238                  ($this->highestmodseq == $status_sync['syncmodseq'])) {
 239                  $vanished = is_null($ids)
 240                      ? $status_sync['syncvanished']
 241                      : $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncvanished']->ids));
 242              } else {
 243                  $vanished = $base_ob->vanished($mailbox, $this->highestmodseq ? $this->highestmodseq : 1, array(
 244                      'ids' => $ids
 245                  ));
 246              }
 247  
 248              $this->vanished = (bool)count($vanished);
 249              $this->_vanisheduids = $vanished;
 250          }
 251      }
 252  
 253      /**
 254       */
 255      public function __get($name)
 256      {
 257          switch ($name) {
 258          case 'flagsuids':
 259          case 'newmsgsuids':
 260          case 'vanisheduids':
 261              return empty($this->{'_' . $name})
 262                  ? new Horde_Imap_Client_Ids()
 263                  : $this->{'_' . $name};
 264          }
 265      }
 266  
 267  }