Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]

   1  <?php
   2  /**
   3   * Copyright 2004-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 2004-2017 Horde LLC
  10   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  11   * @package   Imap_Client
  12   */
  13  
  14  /**
  15   * Container of IMAP mailboxes.
  16   *
  17   * @author    Michael Slusarz <slusarz@horde.org>
  18   * @category  Horde
  19   * @copyright 2004-2017 Horde LLC
  20   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  21   * @package   Imap_Client
  22   */
  23  class Horde_Imap_Client_Mailbox_List implements Countable, IteratorAggregate
  24  {
  25      /**
  26       * The delimiter character to use.
  27       *
  28       * @var string
  29       */
  30      protected $_delimiter;
  31  
  32      /**
  33       * Mailbox list.
  34       *
  35       * @var array
  36       */
  37      protected $_mboxes = array();
  38  
  39      /**
  40       * Should we sort with INBOX at the front of the list?
  41       *
  42       * @var boolean
  43       */
  44      protected $_sortinbox;
  45  
  46      /**
  47       * Constructor.
  48       *
  49       * @param mixed $mboxes  A mailbox or list of mailboxes.
  50       */
  51      public function __construct($mboxes)
  52      {
  53          $this->_mboxes = is_array($mboxes)
  54              ? $mboxes
  55              : array($mboxes);
  56      }
  57  
  58      /**
  59       * Sort the list of mailboxes.
  60       *
  61       * @param array $opts  Options:
  62       *   - delimiter: (string) The delimiter to use.
  63       *                DEFAULT: '.'
  64       *   - inbox: (boolean) Always put INBOX at the head of the list?
  65       *            DEFAULT: Yes
  66       *   - noupdate: (boolean) Do not update the object's mailbox list?
  67       *               DEFAULT: true
  68       *
  69       * @return array  List of sorted mailboxes (index association is kept).
  70       */
  71      public function sort(array $opts = array())
  72      {
  73          $this->_delimiter = isset($opts['delimiter'])
  74              ? $opts['delimiter']
  75              : '.';
  76          $this->_sortinbox = (!isset($opts['inbox']) || !empty($opts['inbox']));
  77  
  78          if (empty($opts['noupdate'])) {
  79              $mboxes = &$this->_mboxes;
  80          } else {
  81              $mboxes = $this->_mboxes;
  82          }
  83  
  84          uasort($mboxes, array($this, '_mboxCompare'));
  85  
  86          return $mboxes;
  87      }
  88  
  89      /**
  90       * Hierarchical folder sorting function (used with usort()).
  91       *
  92       * @param string $a  Comparison item 1.
  93       * @param string $b  Comparison item 2.
  94       *
  95       * @return integer  See usort().
  96       */
  97      final protected function _mboxCompare($a, $b)
  98      {
  99          /* Always return INBOX as "smaller". */
 100          if ($this->_sortinbox) {
 101              if (strcasecmp($a, 'INBOX') === 0) {
 102                  return -1;
 103              } elseif (strcasecmp($b, 'INBOX') === 0) {
 104                  return 1;
 105              }
 106          }
 107  
 108          $a_parts = explode($this->_delimiter, $a);
 109          $b_parts = explode($this->_delimiter, $b);
 110  
 111          $a_count = count($a_parts);
 112          $b_count = count($b_parts);
 113  
 114          for ($i = 0, $iMax = min($a_count, $b_count); $i < $iMax; ++$i) {
 115              if ($a_parts[$i] != $b_parts[$i]) {
 116                  /* If only one of the folders is under INBOX, return it as
 117                   * "smaller". */
 118                  if ($this->_sortinbox && ($i === 0)) {
 119                      $a_base = (strcasecmp($a_parts[0], 'INBOX') === 0);
 120                      $b_base = (strcasecmp($b_parts[0], 'INBOX') === 0);
 121                      if ($a_base && !$b_base) {
 122                          return -1;
 123                      } elseif (!$a_base && $b_base) {
 124                          return 1;
 125                      }
 126                  }
 127  
 128                  $cmp = strnatcasecmp($a_parts[$i], $b_parts[$i]);
 129                  return ($cmp === 0)
 130                      ? strcmp($a_parts[$i], $b_parts[$i])
 131                      : $cmp;
 132              } elseif ($a_parts[$i] !== $b_parts[$i]) {
 133                  return strlen($a_parts[$i]) - strlen($b_parts[$i]);
 134              }
 135          }
 136  
 137          return ($a_count - $b_count);
 138      }
 139  
 140      /* Countable methods. */
 141  
 142      /**
 143       */
 144      #[ReturnTypeWillChange]
 145      public function count()
 146      {
 147          return count($this->_mboxes);
 148      }
 149  
 150      /* IteratorAggregate methods. */
 151  
 152      /**
 153       */
 154      #[ReturnTypeWillChange]
 155      public function getIterator()
 156      {
 157          return new ArrayIterator($this->_mboxes);
 158      }
 159  
 160  }