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 2011-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 2011-2017 Horde LLC
  10   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  11   * @package   Imap_Client
  12   */
  13  
  14  /**
  15   * Available ACL rights for a mailbox/identifier (see RFC 2086/4314).
  16   *
  17   * @author    Michael Slusarz <slusarz@horde.org>
  18   * @category  Horde
  19   * @copyright 2011-2017 Horde LLC
  20   * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
  21   * @package   Imap_Client
  22   */
  23  class Horde_Imap_Client_Data_AclRights extends Horde_Imap_Client_Data_AclCommon implements ArrayAccess, Iterator, Serializable
  24  {
  25      /**
  26       * ACL optional rights.
  27       *
  28       * @var array
  29       */
  30      protected $_optional = array();
  31  
  32      /**
  33       * ACL required rights.
  34       *
  35       * @var array
  36       */
  37      protected $_required = array();
  38  
  39      /**
  40       * Constructor.
  41       *
  42       * @param array $required  The required rights (see RFC 4314 [2.1]).
  43       * @param array $optional  The optional rights (see RFC 4314 [2.1]).
  44       */
  45      public function __construct(array $required = array(),
  46                                  array $optional = array())
  47      {
  48          $this->_required = $required;
  49  
  50          foreach ($optional as $val) {
  51              foreach (str_split($val) as $right) {
  52                  $this->_optional[$right] = $val;
  53              }
  54          }
  55  
  56          $this->_normalize();
  57      }
  58  
  59      /**
  60       * String representation of the ACL.
  61       *
  62       * @return string  String representation (RFC 4314 compliant).
  63       *
  64       */
  65      public function __toString()
  66      {
  67          return implode('', array_keys(array_flip(array_merge(array_values($this->_required), array_keys($this->_optional)))));
  68      }
  69  
  70      /**
  71       * Normalize virtual rights (see RFC 4314 [2.1.1]).
  72       */
  73      protected function _normalize()
  74      {
  75          /* Clients conforming to RFC 4314 MUST ignore the virtual ACL_CREATE
  76           * and ACL_DELETE rights. See RFC 4314 [2.1]. However, we still need
  77           * to handle these rights when dealing with RFC 2086 servers since
  78           * we are abstracting out use of ACL_CREATE/ACL_DELETE to their
  79           * component RFC 4314 rights. */
  80          foreach ($this->_virtual as $key => $val) {
  81              if (isset($this->_optional[$key])) {
  82                  unset($this->_optional[$key]);
  83                  foreach ($val as $val2) {
  84                      $this->_optional[$val2] = implode('', $val);
  85                  }
  86              } elseif (($pos = array_search($key, $this->_required)) !== false) {
  87                  unset($this->_required[$pos]);
  88                  $this->_required = array_unique(array_merge($this->_required, $val));
  89              }
  90          }
  91      }
  92  
  93      /* ArrayAccess methods. */
  94  
  95      /**
  96       */
  97      #[ReturnTypeWillChange]
  98      public function offsetExists($offset)
  99      {
 100          return (bool)$this[$offset];
 101      }
 102  
 103      /**
 104       */
 105      #[ReturnTypeWillChange]
 106      public function offsetGet($offset)
 107      {
 108          if (isset($this->_optional[$offset])) {
 109              return $this->_optional[$offset];
 110          }
 111  
 112          $pos = array_search($offset, $this->_required);
 113  
 114          return ($pos === false)
 115              ? null
 116              : $this->_required[$pos];
 117      }
 118  
 119      /**
 120       */
 121      #[ReturnTypeWillChange]
 122      public function offsetSet($offset, $value)
 123      {
 124          $this->_optional[$offset] = $value;
 125          $this->_normalize();
 126      }
 127  
 128      /**
 129       */
 130      #[ReturnTypeWillChange]
 131      public function offsetUnset($offset)
 132      {
 133          unset($this->_optional[$offset]);
 134          $this->_required = array_values(array_diff($this->_required, array($offset)));
 135  
 136          if (isset($this->_virtual[$offset])) {
 137              foreach ($this->_virtual[$offset] as $val) {
 138                  unset($this[$val]);
 139              }
 140          }
 141      }
 142  
 143      /* Iterator methods. */
 144  
 145      /**
 146       */
 147      #[ReturnTypeWillChange]
 148      public function current()
 149      {
 150          $val = current($this->_required);
 151          return is_null($val)
 152              ? current($this->_optional)
 153              : $val;
 154      }
 155  
 156      /**
 157       */
 158      #[ReturnTypeWillChange]
 159      public function key()
 160      {
 161          $key = key($this->_required);
 162          return is_null($key)
 163              ? key($this->_optional)
 164              : $key;
 165      }
 166  
 167      /**
 168       */
 169      #[ReturnTypeWillChange]
 170      public function next()
 171      {
 172          if (key($this->_required) === null) {
 173              next($this->_optional);
 174          } else {
 175              next($this->_required);
 176          }
 177      }
 178  
 179      /**
 180       */
 181      #[ReturnTypeWillChange]
 182      public function rewind()
 183      {
 184          reset($this->_required);
 185          reset($this->_optional);
 186      }
 187  
 188      /**
 189       */
 190      #[ReturnTypeWillChange]
 191      public function valid()
 192      {
 193          return ((key($this->_required) !== null) ||
 194                  (key($this->_optional) !== null));
 195  
 196      }
 197  
 198      /* Serializable methods. */
 199  
 200      /**
 201       */
 202      public function serialize()
 203      {
 204          return serialize($this->__serialize());
 205      }
 206  
 207      /**
 208       */
 209      public function unserialize($data)
 210      {
 211          $data = @unserialize($data);
 212          if (!is_array($data)) {
 213              throw new Exception('Cache version changed.');
 214          }
 215          $this->__unserialize($data);
 216      }
 217  
 218      /**
 219       * @return array
 220       */
 221      public function __serialize()
 222      {
 223          return [$this->_required, $this->_optional];
 224      }
 225  
 226      public function __unserialize(array $data)
 227      {
 228          list($this->_required, $this->_optional) = $data;
 229      }
 230  
 231  }