%PDF- %PDF-
| Direktori : /home/graphicd/public_html/vebto/vendor/spatie/enum/src/ |
| Current File : /home/graphicd/public_html/vebto/vendor/spatie/enum/src/Enum.php |
<?php
namespace Spatie\Enum;
use ArgumentCountError;
use BadMethodCallException;
use JsonSerializable;
use ReflectionClass;
use ReflectionMethod;
use Spatie\Enum\Exceptions\DuplicatedIndexException;
use Spatie\Enum\Exceptions\DuplicatedValueException;
use Spatie\Enum\Exceptions\InvalidIndexException;
use Spatie\Enum\Exceptions\InvalidNameException;
use Spatie\Enum\Exceptions\InvalidValueException;
use TypeError;
abstract class Enum implements Enumerable, JsonSerializable
{
/** @var array[] */
protected static $cache = [];
/** @var int */
protected $index;
/** @var string */
protected $value;
/** @var string */
protected $name;
/**
* This construct is not part of the public API and COULD change in a minor release.
* You SHOULD NOT use it by your own - instead you SHOULD use the make() method.
*
* @internal
* @see \Spatie\Enum\Enum::make()
*
* @param string|null $name
* @param string|null $value
* @param int|null $index
*/
public function __construct(?string $name = null, ?string $value = null, ?int $index = null)
{
if (is_null($name) && is_null($value) && is_null($index)) {
['name' => $name, 'value' => $value, 'index' => $index] = $this->resolveByStaticCall();
}
if (is_null($name) || ! static::isValidName($name)) {
throw new InvalidNameException($name, static::class);
}
if (is_null($value) || ! static::isValidValue($value)) {
throw new InvalidValueException($value, static::class);
}
if (is_null($index) || ! static::isValidIndex($index)) {
throw new InvalidIndexException($index, static::class);
}
$this->name = $name;
$this->value = $value;
$this->index = $index;
}
public function __call(string $name, array $arguments)
{
if (static::startsWith($name, 'is')) {
return $this->isEqual(substr($name, 2));
}
if (static::isValidName($name)) {
return static::make($name);
}
throw new BadMethodCallException('Call to undefined method '.static::class.'->'.$name.'()');
}
/**
* @param string $name
* @param mixed[] $arguments
*
* @return \Spatie\Enum\Enumerable|bool
*/
public static function __callStatic(string $name, array $arguments)
{
if (static::startsWith($name, 'is')) {
if (! isset($arguments[0])) {
throw new ArgumentCountError('Calling '.static::class.'::'.$name.'() in static context requires one argument');
}
try {
return static::make($arguments[0])->$name();
} catch (InvalidValueException $error) {
return false;
} catch (InvalidIndexException $error) {
return false;
}
}
if (static::isValidName($name) || static::isValidValue($name)) {
return static::make($name);
}
throw new BadMethodCallException('Call to undefined method '.static::class.'::'.$name.'()');
}
public function __toString(): string
{
return $this->getValue();
}
public function getIndex(): int
{
return $this->index;
}
public static function getIndices(): array
{
return array_column(static::resolve(), 'index');
}
public function getValue(): string
{
return $this->value;
}
public static function getValues(): array
{
return array_column(static::resolve(), 'value');
}
public function getName(): string
{
return $this->name;
}
public static function getNames(): array
{
return array_keys(static::resolve());
}
public function isAny(array $values): bool
{
foreach ($values as $value) {
if ($this->isEqual($value)) {
return true;
}
}
return false;
}
public function isEqual($value): bool
{
if (is_int($value) || is_string($value)) {
try {
$value = static::make($value);
} catch (InvalidValueException $error) {
return false;
} catch (InvalidIndexException $error) {
return false;
}
}
if ($value instanceof $this) {
return $value->getValue() === $this->getValue();
}
return false;
}
public function jsonSerialize(): string
{
return $this->getValue();
}
/**
* @param int|string $value
*
* @return static
*/
public static function make($value): Enumerable
{
if (! is_int($value) && ! is_string($value)) {
throw new TypeError(static::class.'::make() expects string|int as argument but '.gettype($value).' given');
}
$name = null;
$index = null;
if (is_int($value)) {
if (! static::isValidIndex($value)) {
throw new InvalidIndexException($value, static::class);
}
[$name, $index, $value] = static::resolveByIndex($value);
} elseif (is_string($value)) {
[$name, $index, $value] = static::resolveByString($value);
}
if (is_string($name) && method_exists(static::class, $name)) {
return forward_static_call(static::class.'::'.$name);
}
return new static($name, $value, $index);
}
public static function toArray(): array
{
return array_combine(static::getValues(), static::getIndices());
}
/**
* @return \Spatie\Enum\Enumerable[]
*/
public static function getAll(): array
{
return array_map(static function (int $index): Enumerable {
return static::make($index);
}, static::getIndices());
}
public static function isValidIndex(int $index): bool
{
return in_array($index, static::getIndices(), true);
}
public static function isValidName(string $value): bool
{
return in_array(strtoupper($value), static::getNames(), true);
}
public static function isValidValue(string $value): bool
{
return in_array($value, static::getValues(), true);
}
protected static function resolve(): array
{
$values = [];
$class = static::class;
if (isset(self::$cache[$class])) {
return self::$cache[$class];
}
self::$cache[$class] = [];
$reflection = new ReflectionClass(static::class);
foreach (static::resolveFromDocBlocks($reflection) as $value) {
$values[] = $value;
}
foreach (static::resolveFromStaticMethods($reflection) as $value) {
$values[] = $value;
}
foreach ($values as $index => $value) {
$name = strtoupper($value);
self::$cache[$class][$name] = [
'name' => $name,
'index' => static::getMappedIndex($name) ?? $index,
'value' => static::getMappedValue($name) ?? $value,
];
}
foreach (array_keys(self::$cache[$class]) as $name) {
self::$cache[$class][$name]['value'] = static::make($name)->getValue();
self::$cache[$class][$name]['index'] = static::make($name)->getIndex();
}
$duplicatedValues = array_filter(array_count_values(static::getValues()), static function (int $count): bool {
return $count > 1;
});
if (! empty($duplicatedValues)) {
self::clearCache();
throw new DuplicatedValueException(array_keys($duplicatedValues), static::class);
}
$duplicatedIndices = array_filter(array_count_values(static::getIndices()), static function (int $count): bool {
return $count > 1;
});
if (! empty($duplicatedIndices)) {
self::clearCache();
throw new DuplicatedIndexException(array_keys($duplicatedIndices), static::class);
}
return self::$cache[$class];
}
protected static function resolveFromDocBlocks(ReflectionClass $reflection): array
{
$values = [];
$docComment = $reflection->getDocComment();
if (! $docComment) {
return $values;
}
preg_match_all('/\@method static self ([\w]+)\(\)/', $docComment, $matches);
foreach ($matches[1] ?? [] as $value) {
$values[] = $value;
}
return $values;
}
protected static function resolveFromStaticMethods(ReflectionClass $reflection): array
{
$selfReflection = new ReflectionClass(self::class);
$selfMethods = array_map(static function (ReflectionMethod $method): string {
return $method->getName();
}, $selfReflection->getMethods(ReflectionMethod::IS_STATIC | ReflectionMethod::IS_PUBLIC));
$values = [];
foreach ($reflection->getMethods(ReflectionMethod::IS_STATIC | ReflectionMethod::IS_PUBLIC) as $method) {
if (
$method->getDeclaringClass()->getName() === self::class
|| ! ($method->isPublic() && $method->isStatic())
|| in_array($method->getName(), $selfMethods)
) {
continue;
}
$values[] = $method->getName();
}
return $values;
}
protected function resolveByStaticCall(): array
{
if (strpos(static::class, 'class@anonymous') !== 0) {
throw new InvalidValueException(null, static::class);
}
$backtrace = debug_backtrace();
$name = $backtrace[2]['function'];
if (! static::isValidName($name)) {
throw new InvalidValueException($name, static::class);
}
return static::resolve()[strtoupper($name)];
}
protected static function resolveByIndex(int $index): array
{
$name = array_combine(static::getIndices(), static::getNames())[$index];
return static::resolveByName($name);
}
protected static function resolveByString(string $string): array
{
if (static::isValidValue($string)) {
return static::resolveByValue($string);
}
if (static::isValidName($string)) {
return static::resolveByName($string);
}
throw new InvalidValueException($string, static::class);
}
protected static function resolveByValue(string $value): array
{
$name = array_combine(static::getValues(), static::getNames())[$value];
return static::resolveByName($name);
}
protected static function resolveByName(string $name): array
{
$name = strtoupper($name);
['value' => $value, 'index' => $index] = static::resolve()[$name];
return [$name, $index, $value];
}
protected static function startsWith(string $haystack, string $needle): bool
{
return strlen($haystack) > 2 && strpos($haystack, $needle) === 0;
}
protected static function clearCache(): void
{
unset(self::$cache[static::class]);
}
protected static function getMappedIndex(string $name): ?int
{
if (! defined(static::class.'::MAP_INDEX')) {
return null;
}
$map = [];
foreach (constant(static::class.'::MAP_INDEX') as $key => $index) {
$map[strtoupper($key)] = $index;
}
return $map[$name] ?? null;
}
protected static function getMappedValue(string $name): ?string
{
if (! defined(static::class.'::MAP_VALUE')) {
return null;
}
$map = [];
foreach (constant(static::class.'::MAP_VALUE') as $key => $index) {
$map[strtoupper($key)] = $index;
}
return $map[$name] ?? null;
}
}