From bbfbe8e260ddd604e0b2e487cad5910391f4b053 Mon Sep 17 00:00:00 2001 From: Michael Hawkins Date: Wed, 26 Aug 2020 21:01:14 +0800 Subject: [PATCH] MDL-69548 core: Adding the php-enum library This is a dependency of ZipStream --- lib/classes/component.php | 1 + lib/php-enum/LICENSE | 18 +++ lib/php-enum/readme_moodle.txt | 7 + lib/php-enum/src/Enum.php | 239 +++++++++++++++++++++++++++++++++ lib/thirdpartylibs.xml | 6 + lib/upgrade.txt | 1 + 6 files changed, 272 insertions(+) create mode 100644 lib/php-enum/LICENSE create mode 100644 lib/php-enum/readme_moodle.txt create mode 100644 lib/php-enum/src/Enum.php diff --git a/lib/classes/component.php b/lib/classes/component.php index b689a62f976..1d1b3fd58ba 100644 --- a/lib/classes/component.php +++ b/lib/classes/component.php @@ -105,6 +105,7 @@ class core_component { 'MongoDB' => 'cache/stores/mongodb/MongoDB', 'Firebase\\JWT' => 'lib/php-jwt/src', 'ZipStream' => 'lib/zipstream/src/', + 'MyCLabs\\Enum' => 'lib/php-enum/src', ); /** diff --git a/lib/php-enum/LICENSE b/lib/php-enum/LICENSE new file mode 100644 index 00000000000..2a8cf22ec64 --- /dev/null +++ b/lib/php-enum/LICENSE @@ -0,0 +1,18 @@ +The MIT License (MIT) + +Copyright (c) 2015 My C-Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/php-enum/readme_moodle.txt b/lib/php-enum/readme_moodle.txt new file mode 100644 index 00000000000..63b65d7e3c4 --- /dev/null +++ b/lib/php-enum/readme_moodle.txt @@ -0,0 +1,7 @@ +Instructions to import php-enum into Moodle: + +1/ Download from https://github.com/myclabs/php-enum/releases + +2/ Copy the LICENSE file and the src folder into the lib/php-enum folder + +3/ Remove the src/PHPUnit folder, as it is not required diff --git a/lib/php-enum/src/Enum.php b/lib/php-enum/src/Enum.php new file mode 100644 index 00000000000..f5a59404a04 --- /dev/null +++ b/lib/php-enum/src/Enum.php @@ -0,0 +1,239 @@ + + * @author Daniel Costa + * @author Mirosław Filip + * + * @psalm-template T + * @psalm-immutable + */ +abstract class Enum implements \JsonSerializable +{ + /** + * Enum value + * + * @var mixed + * @psalm-var T + */ + protected $value; + + /** + * Store existing constants in a static cache per object. + * + * + * @var array + * @psalm-var array> + */ + protected static $cache = []; + + /** + * Creates a new value of some type + * + * @psalm-pure + * @param mixed $value + * + * @psalm-param static|T $value + * @throws \UnexpectedValueException if incompatible type is given. + */ + public function __construct($value) + { + if ($value instanceof static) { + /** @psalm-var T */ + $value = $value->getValue(); + } + + if (!$this->isValid($value)) { + /** @psalm-suppress InvalidCast */ + throw new \UnexpectedValueException("Value '$value' is not part of the enum " . static::class); + } + + /** @psalm-var T */ + $this->value = $value; + } + + /** + * @psalm-pure + * @return mixed + * @psalm-return T + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns the enum key (i.e. the constant name). + * + * @psalm-pure + * @return mixed + */ + public function getKey() + { + return static::search($this->value); + } + + /** + * @psalm-pure + * @psalm-suppress InvalidCast + * @return string + */ + public function __toString() + { + return (string)$this->value; + } + + /** + * Determines if Enum should be considered equal with the variable passed as a parameter. + * Returns false if an argument is an object of different class or not an object. + * + * This method is final, for more information read https://github.com/myclabs/php-enum/issues/4 + * + * @psalm-pure + * @psalm-param mixed $variable + * @return bool + */ + final public function equals($variable = null): bool + { + return $variable instanceof self + && $this->getValue() === $variable->getValue() + && static::class === \get_class($variable); + } + + /** + * Returns the names (keys) of all constants in the Enum class + * + * @psalm-pure + * @psalm-return list + * @return array + */ + public static function keys() + { + return \array_keys(static::toArray()); + } + + /** + * Returns instances of the Enum class of all Enum constants + * + * @psalm-pure + * @psalm-return array + * @return static[] Constant name in key, Enum instance in value + */ + public static function values() + { + $values = array(); + + /** @psalm-var T $value */ + foreach (static::toArray() as $key => $value) { + $values[$key] = new static($value); + } + + return $values; + } + + /** + * Returns all possible values as an array + * + * @psalm-pure + * @psalm-suppress ImpureStaticProperty + * + * @psalm-return array + * @return array Constant name in key, constant value in value + */ + public static function toArray() + { + $class = static::class; + + if (!isset(static::$cache[$class])) { + $reflection = new \ReflectionClass($class); + static::$cache[$class] = $reflection->getConstants(); + } + + return static::$cache[$class]; + } + + /** + * Check if is valid enum value + * + * @param $value + * @psalm-param mixed $value + * @psalm-pure + * @return bool + */ + public static function isValid($value) + { + return \in_array($value, static::toArray(), true); + } + + /** + * Check if is valid enum key + * + * @param $key + * @psalm-param string $key + * @psalm-pure + * @return bool + */ + public static function isValidKey($key) + { + $array = static::toArray(); + + return isset($array[$key]) || \array_key_exists($key, $array); + } + + /** + * Return key for value + * + * @param $value + * + * @psalm-param mixed $value + * @psalm-pure + * @return mixed + */ + public static function search($value) + { + return \array_search($value, static::toArray(), true); + } + + /** + * Returns a value when called statically like so: MyEnum::SOME_VALUE() given SOME_VALUE is a class constant + * + * @param string $name + * @param array $arguments + * + * @return static + * @psalm-pure + * @throws \BadMethodCallException + */ + public static function __callStatic($name, $arguments) + { + $array = static::toArray(); + if (isset($array[$name]) || \array_key_exists($name, $array)) { + return new static($array[$name]); + } + + throw new \BadMethodCallException("No static method or enum constant '$name' in class " . static::class); + } + + /** + * Specify data which should be serialized to JSON. This method returns data that can be serialized by json_encode() + * natively. + * + * @return mixed + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * @psalm-pure + */ + public function jsonSerialize() + { + return $this->getValue(); + } +} diff --git a/lib/thirdpartylibs.xml b/lib/thirdpartylibs.xml index 838602334c0..04fe365b27c 100644 --- a/lib/thirdpartylibs.xml +++ b/lib/thirdpartylibs.xml @@ -345,4 +345,10 @@ MIT 2.1.0 + + php-enum + php-enum + MIT + 1.7.6 + diff --git a/lib/upgrade.txt b/lib/upgrade.txt index f59ddb338ab..491f89c1a21 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -43,6 +43,7 @@ information provided here is intended especially for developers. returns information about currently-running tasks. * New library function rename_to_unused_name() to rename a file within its current location. * The ZipStream-PHP library has been added to Moodle core in /lib/zipstream. +* The php-enum library has been added to Moodle core in /lib/php-enum. === 3.9 === * Following function has been deprecated, please use \core\task\manager::run_from_cli().