first commit

This commit is contained in:
aschwarz
2022-11-28 10:24:23 +01:00
commit 5121fd03d4
3332 changed files with 768541 additions and 0 deletions

View File

@ -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.

View File

@ -0,0 +1,132 @@
# PHP Enum implementation inspired from SplEnum
[![Build Status](https://travis-ci.org/myclabs/php-enum.png?branch=master)](https://travis-ci.org/myclabs/php-enum)
[![Latest Stable Version](https://poser.pugx.org/myclabs/php-enum/version.png)](https://packagist.org/packages/myclabs/php-enum)
[![Total Downloads](https://poser.pugx.org/myclabs/php-enum/downloads.png)](https://packagist.org/packages/myclabs/php-enum)
[![psalm](https://shepherd.dev/github/myclabs/php-enum/coverage.svg)](https://shepherd.dev/github/myclabs/php-enum)
Maintenance for this project is [supported via Tidelift](https://tidelift.com/subscription/pkg/packagist-myclabs-php-enum?utm_source=packagist-myclabs-php-enum&utm_medium=referral&utm_campaign=readme).
## Why?
First, and mainly, `SplEnum` is not integrated to PHP, you have to install the extension separately.
Using an enum instead of class constants provides the following advantages:
- You can type-hint: `function setAction(Action $action) {`
- You can enrich the enum with methods (e.g. `format`, `parse`, …)
- You can extend the enum to add new values (make your enum `final` to prevent it)
- You can get a list of all the possible values (see below)
This Enum class is not intended to replace class constants, but only to be used when it makes sense.
## Installation
```
composer require myclabs/php-enum
```
## Declaration
```php
use MyCLabs\Enum\Enum;
/**
* Action enum
*/
class Action extends Enum
{
private const VIEW = 'view';
private const EDIT = 'edit';
}
```
## Usage
```php
$action = Action::VIEW();
// or with a dynamic key:
$action = Action::$key();
// or with a dynamic value:
$action = new Action($value);
```
As you can see, static methods are automatically implemented to provide quick access to an enum value.
One advantage over using class constants is to be able to type-hint enum values:
```php
function setAction(Action $action) {
// ...
}
```
## Documentation
- `__construct()` The constructor checks that the value exist in the enum
- `__toString()` You can `echo $myValue`, it will display the enum value (value of the constant)
- `getValue()` Returns the current value of the enum
- `getKey()` Returns the key of the current value on Enum
- `equals()` Tests whether enum instances are equal (returns `true` if enum values are equal, `false` otherwise)
Static methods:
- `toArray()` method Returns all possible values as an array (constant name in key, constant value in value)
- `keys()` Returns the names (keys) of all constants in the Enum class
- `values()` Returns instances of the Enum class of all Enum constants (constant name in key, Enum instance in value)
- `isValid()` Check if tested value is valid on enum set
- `isValidKey()` Check if tested key is valid on enum set
- `search()` Return key for searched value
### Static methods
```php
class Action extends Enum
{
private const VIEW = 'view';
private const EDIT = 'edit';
}
// Static method:
$action = Action::VIEW();
$action = Action::EDIT();
```
Static method helpers are implemented using [`__callStatic()`](http://www.php.net/manual/en/language.oop5.overloading.php#object.callstatic).
If you care about IDE autocompletion, you can either implement the static methods yourself:
```php
class Action extends Enum
{
private const VIEW = 'view';
/**
* @return Action
*/
public static function VIEW() {
return new Action(self::VIEW);
}
}
```
or you can use phpdoc (this is supported in PhpStorm for example):
```php
/**
* @method static Action VIEW()
* @method static Action EDIT()
*/
class Action extends Enum
{
private const VIEW = 'view';
private const EDIT = 'edit';
}
```
## Related projects
- [Doctrine enum mapping](https://github.com/acelaya/doctrine-enum-type)
- [Symfony ParamConverter integration](https://github.com/Ex3v/MyCLabsEnumParamConverter)
- [PHPStan integration](https://github.com/timeweb/phpstan-enum)

View File

@ -0,0 +1,11 @@
# Security Policy
## Supported Versions
Only the latest stable release is supported.
## Reporting a Vulnerability
To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.

View File

@ -0,0 +1,33 @@
{
"name": "myclabs/php-enum",
"type": "library",
"description": "PHP Enum implementation",
"keywords": ["enum"],
"homepage": "http://github.com/myclabs/php-enum",
"license": "MIT",
"authors": [
{
"name": "PHP Enum contributors",
"homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
}
],
"autoload": {
"psr-4": {
"MyCLabs\\Enum\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"MyCLabs\\Tests\\Enum\\": "tests/"
}
},
"require": {
"php": ">=7.1",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^7",
"squizlabs/php_codesniffer": "1.*",
"vimeo/psalm": "^3.8"
}
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<psalm
totallyTyped="true"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
<directory name="src/PHPUnit" />
</ignoreFiles>
</projectFiles>
<issueHandlers>
<MixedAssignment errorLevel="info" />
</issueHandlers>
</psalm>

View File

@ -0,0 +1,239 @@
<?php
/**
* @link http://github.com/myclabs/php-enum
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace MyCLabs\Enum;
/**
* Base Enum class
*
* Create an enum by implementing this class and adding class constants.
*
* @author Matthieu Napoli <matthieu@mnapoli.fr>
* @author Daniel Costa <danielcosta@gmail.com>
* @author Mirosław Filip <mirfilip@gmail.com>
*
* @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<class-string, array<string, mixed>>
*/
protected static $cache = [];
/**
* Creates a new value of some type
*
* @psalm-pure
* @param mixed $value
*
* @psalm-param static<T>|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<string>
* @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<string, static>
* @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<string, mixed>
* @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();
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace MyCLabs\Enum\PHPUnit;
use MyCLabs\Enum\Enum;
use SebastianBergmann\Comparator\ComparisonFailure;
/**
* Use this Comparator to get nice output when using PHPUnit assertEquals() with Enums.
*
* Add this to your PHPUnit bootstrap PHP file:
*
* \SebastianBergmann\Comparator\Factory::getInstance()->register(new \MyCLabs\Enum\PHPUnit\Comparator());
*/
final class Comparator extends \SebastianBergmann\Comparator\Comparator
{
public function accepts($expected, $actual)
{
return $expected instanceof Enum && (
$actual instanceof Enum || $actual === null
);
}
/**
* @param Enum $expected
* @param Enum|null $actual
*
* @return void
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
if ($expected->equals($actual)) {
return;
}
throw new ComparisonFailure(
$expected,
$actual,
$this->formatEnum($expected),
$this->formatEnum($actual),
false,
'Failed asserting that two Enums are equal.'
);
}
private function formatEnum(Enum $enum = null)
{
if ($enum === null) {
return "null";
}
return get_class($enum)."::{$enum->getKey()}()";
}
}