- var_dump: documentation ( source)
- count: documentation ( source)
- preg_match_all: documentation ( source)
<?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!");
}
}
abstract class DocEnum extends Enum {
protected static $enums = [];
private function __construct() {
}
/**
* @inheritDoc
*/
public static function getAll() : array {
return static::getOrLoad(static::class);
}
private static function getOrLoad(string $class) {
if (!isset(self::$enums[$class])) {
$cls = new \ReflectionClass($class);
if ($cls->getParentClass()->getName() !== self::class) {
$enums = static::getOrLoad($cls->getParentClass()->getName());
} else {
$enums = [];
}
$ordinal = count($enums);
$doc = $cls->getDocComment();
if ($doc !== false) {
$matches = [];
if (preg_match_all('/^\\s*\\*\\s*@method\\s+static\\s+([A-Z]+)\\(\\s*\\)\\s*$/m', $doc, $matches) > 0) {
foreach ($matches[1] as $name) {
$enum = new $class();
$enum->name = $name;
$enum->ordinal = $ordinal++;
$enums[] = $enum;
}
}
}
static::$enums[$class] = $enums;
}
return static::$enums[$class];
}
}
/**
*
* @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());