Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]

   1  <?php
   2  /**
   3   * @link    http://github.com/myclabs/php-enum
   4   * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
   5   */
   6  
   7  namespace MyCLabs\Enum;
   8  
   9  /**
  10   * Base Enum class
  11   *
  12   * Create an enum by implementing this class and adding class constants.
  13   *
  14   * @author Matthieu Napoli <matthieu@mnapoli.fr>
  15   * @author Daniel Costa <danielcosta@gmail.com>
  16   * @author Mirosław Filip <mirfilip@gmail.com>
  17   *
  18   * @psalm-template T
  19   * @psalm-immutable
  20   */
  21  abstract class Enum implements \JsonSerializable
  22  {
  23      /**
  24       * Enum value
  25       *
  26       * @var mixed
  27       * @psalm-var T
  28       */
  29      protected $value;
  30  
  31      /**
  32       * Store existing constants in a static cache per object.
  33       *
  34       *
  35       * @var array
  36       * @psalm-var array<class-string, array<string, mixed>>
  37       */
  38      protected static $cache = [];
  39  
  40      /**
  41       * Cache of instances of the Enum class
  42       *
  43       * @var array
  44       * @psalm-var array<class-string, array<string, static>>
  45       */
  46      protected static $instances = [];
  47  
  48      /**
  49       * Creates a new value of some type
  50       *
  51       * @psalm-pure
  52       * @param mixed $value
  53       *
  54       * @psalm-param static<T>|T $value
  55       * @throws \UnexpectedValueException if incompatible type is given.
  56       */
  57      public function __construct($value)
  58      {
  59          if ($value instanceof static) {
  60             /** @psalm-var T */
  61              $value = $value->getValue();
  62          }
  63  
  64          if (!$this->isValid($value)) {
  65              /** @psalm-suppress InvalidCast */
  66              throw new \UnexpectedValueException("Value '$value' is not part of the enum " . static::class);
  67          }
  68  
  69          /** @psalm-var T */
  70          $this->value = $value;
  71      }
  72  
  73      /**
  74       * @psalm-pure
  75       * @return mixed
  76       * @psalm-return T
  77       */
  78      public function getValue()
  79      {
  80          return $this->value;
  81      }
  82  
  83      /**
  84       * Returns the enum key (i.e. the constant name).
  85       *
  86       * @psalm-pure
  87       * @return mixed
  88       */
  89      public function getKey()
  90      {
  91          return static::search($this->value);
  92      }
  93  
  94      /**
  95       * @psalm-pure
  96       * @psalm-suppress InvalidCast
  97       * @return string
  98       */
  99      public function __toString()
 100      {
 101          return (string)$this->value;
 102      }
 103  
 104      /**
 105       * Determines if Enum should be considered equal with the variable passed as a parameter.
 106       * Returns false if an argument is an object of different class or not an object.
 107       *
 108       * This method is final, for more information read https://github.com/myclabs/php-enum/issues/4
 109       *
 110       * @psalm-pure
 111       * @psalm-param mixed $variable
 112       * @return bool
 113       */
 114      final public function equals($variable = null): bool
 115      {
 116          return $variable instanceof self
 117              && $this->getValue() === $variable->getValue()
 118              && static::class === \get_class($variable);
 119      }
 120  
 121      /**
 122       * Returns the names (keys) of all constants in the Enum class
 123       *
 124       * @psalm-pure
 125       * @psalm-return list<string>
 126       * @return array
 127       */
 128      public static function keys()
 129      {
 130          return \array_keys(static::toArray());
 131      }
 132  
 133      /**
 134       * Returns instances of the Enum class of all Enum constants
 135       *
 136       * @psalm-pure
 137       * @psalm-return array<string, static>
 138       * @return static[] Constant name in key, Enum instance in value
 139       */
 140      public static function values()
 141      {
 142          $values = array();
 143  
 144          /** @psalm-var T $value */
 145          foreach (static::toArray() as $key => $value) {
 146              $values[$key] = new static($value);
 147          }
 148  
 149          return $values;
 150      }
 151  
 152      /**
 153       * Returns all possible values as an array
 154       *
 155       * @psalm-pure
 156       * @psalm-suppress ImpureStaticProperty
 157       *
 158       * @psalm-return array<string, mixed>
 159       * @return array Constant name in key, constant value in value
 160       */
 161      public static function toArray()
 162      {
 163          $class = static::class;
 164  
 165          if (!isset(static::$cache[$class])) {
 166              $reflection            = new \ReflectionClass($class);
 167              static::$cache[$class] = $reflection->getConstants();
 168          }
 169  
 170          return static::$cache[$class];
 171      }
 172  
 173      /**
 174       * Check if is valid enum value
 175       *
 176       * @param $value
 177       * @psalm-param mixed $value
 178       * @psalm-pure
 179       * @return bool
 180       */
 181      public static function isValid($value)
 182      {
 183          return \in_array($value, static::toArray(), true);
 184      }
 185  
 186      /**
 187       * Check if is valid enum key
 188       *
 189       * @param $key
 190       * @psalm-param string $key
 191       * @psalm-pure
 192       * @return bool
 193       */
 194      public static function isValidKey($key)
 195      {
 196          $array = static::toArray();
 197  
 198          return isset($array[$key]) || \array_key_exists($key, $array);
 199      }
 200  
 201      /**
 202       * Return key for value
 203       *
 204       * @param $value
 205       *
 206       * @psalm-param mixed $value
 207       * @psalm-pure
 208       * @return mixed
 209       */
 210      public static function search($value)
 211      {
 212          return \array_search($value, static::toArray(), true);
 213      }
 214  
 215      /**
 216       * Returns a value when called statically like so: MyEnum::SOME_VALUE() given SOME_VALUE is a class constant
 217       *
 218       * @param string $name
 219       * @param array  $arguments
 220       *
 221       * @return static
 222       * @throws \BadMethodCallException
 223       */
 224      public static function __callStatic($name, $arguments)
 225      {
 226          $class = static::class;
 227          if (!isset(self::$instances[$class][$name])) {
 228              $array = static::toArray();
 229              if (!isset($array[$name]) && !\array_key_exists($name, $array)) {
 230                  $message = "No static method or enum constant '$name' in class " . static::class;
 231                  throw new \BadMethodCallException($message);
 232              }
 233              return self::$instances[$class][$name] = new static($array[$name]);
 234          }
 235          return clone self::$instances[$class][$name];
 236      }
 237  
 238      /**
 239       * Specify data which should be serialized to JSON. This method returns data that can be serialized by json_encode()
 240       * natively.
 241       *
 242       * @return mixed
 243       * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
 244       * @psalm-pure
 245       */
 246      public function jsonSerialize()
 247      {
 248          return $this->getValue();
 249      }
 250  }