<?php
declare(strict_types=1);
namespace fema\enums;
abstract class Enum {
protected $name, $ordinal;
/**
* @return string the name of the enum
*/
public function name() : string {
return $this->name;
}
/**
* @return int a number representing this enum. Starts at 0.
*/
public function ordinal() : int {
return $this->ordinal;
}
/**
* Alias of name()
* @return string the name of the enum
*/
public function __toString() : string {
return $this->name();
}
/**
* @return Enum[] all the enums that are defined in the class
*/
public abstract static function getAll() : array;
/**
* Return a specific enum given its name
* @param string $name the name of the enum
* @return Enum the enum that corresponds to the passed name
* @throws EnumNotFoundException if an enum with the passed name is not found
*/
public static function fromName(string $name) : Enum {
foreach (static::getAll() as $item) {
if ($item->name() === $name) {
return $item;
}
}
throw new EnumNotFoundException("The enum " . static::class . " with name '$name' wasn't found!");
}
/**
* Return a specific enum given its ordinal
* @param int $ordinal the ordinal of the enum
* @return Enum the enum that corresponds to the passed ordinal
* @throws EnumNotFoundException if an enum with the passed ordinal is not found
*/
public static function fromOrdinal(int $ordinal) : Enum {
foreach (static::getAll() as $item) {
if ($item->ordinal() === $ordinal) {
return $item;
}
}
throw new EnumNotFoundException("The enum " . static::class . " with ordinal '$ordinal' wasn't found!");
}
}
class DocEnum extends Enum {
private static $enums = null;
private function __construct() {
}
/**
* @inheritDoc
*/
public static function getAll() : array {
if (static::$enums === null) {
$last = new \ReflectionClass(static::class);
/** @var \ReflectionClass[] $classes */
$classes = [$last];
while ($last->getParentClass()->getName() !== self::class) {
//Put on top of array
array_unshift($classes, $last = new \ReflectionClass($last->getParentClass()->getName()));
}
$enums = [];
$ordinal = 0;
foreach ($classes as $class) {
$doc = $class->getDocComment();
$matches = [];
if (preg_match_all('/^\\s*\\*\\s*@method\\s+static\\s+([A-Z]+)\\(\\)\\s*$/m', $doc, $matches) > 0) {
foreach ($matches[1] as $name) {
$enum = new DocEnum();
$enum->name = $name;
$enum->ordinal = $ordinal++;
$enums[] = $enum;
}
}
}
static::$enums = $enums;
}
return static::$enums;
}
}
/**
*
* @method static MONDAY()
* @method static TUESDAY()
* @method static WENSDAY()
* @method static THURSDAY()
* @method static FRIDAY()
*/
class WorkDays extends DocEnum {
}
/*
* @method static SATURDAY()
* @method static SUNDAY()
*/
class Days extends WorkDays {
}
var_dump(WorkDays::getAll());
var_dump(Days::getAll());
Fatal error: Uncaught Error: Cannot access property fema\enums\WorkDays::$enums in /in/VRXsm:82
Stack trace:
#0 /in/VRXsm(131): fema\enums\DocEnum::getAll()
#1 {main}
thrown in /in/VRXsm on line 82
Process exited with code 255.
Output for 5.6.0 - 5.6.40
Warning: Unsupported declare 'strict_types' in /in/VRXsm on line 2
Parse error: syntax error, unexpected ':', expecting ';' or '{' in /in/VRXsm on line 14
Process exited with code 255.