Skip to content

Instantly share code, notes, and snippets.

@tmaroschik
Created September 13, 2013 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmaroschik/60d83f4b4eda2c646399 to your computer and use it in GitHub Desktop.
Save tmaroschik/60d83f4b4eda2c646399 to your computer and use it in GitHub Desktop.
<?php
/***************************************************************
* Copyright notice
*
* (c) 2013 Thomas Maroschik <tmaroschik@dfau.de>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Emulates SplEnum in vanilla PHP
*
*/
abstract class SplEnum extends SplType {
/**
* @var string
*/
private $value;
/**
* @var array
*/
protected static $enumConstants;
/**
* @param mixed $value
*/
public function __construct($value = NULL) {
if ($value === NULL) {
$value = static::__default;
}
$this->loadValues();
if (!static::isValid($value)) {
throw new UnexpectedValueException(sprintf("Invalid enumeration %s for Enum %s", $value, __CLASS__));
}
$this->setValue($value);
}
/**
* @param string $class
* @throws Exception
*/
protected function loadValues() {
$class = get_called_class();
if(!isset(static::$enumConstants[$class])) {
$reflection = new \ReflectionClass($class);
$constants = $reflection->getConstants();
if (isset($constants['__default'])) {
unset($constants['__default']);
}
if(empty($constants)) {
throw new \Exception(sprintf(
'No enumeration constants defined for "%s"', $class
));
}
foreach($constants as $constant => $value) {
if(!is_int($value) && !is_string($value)) {
throw new \Exception(sprintf(
'Constant value must be of type integer or string; constant=%s; type=%s',
$constant,
is_object($value) ? get_class($value) : gettype($value)
));
}
}
$constantValueCounts = array_count_values($constants);
arsort($constantValueCounts, SORT_NUMERIC);
$constantValueCount = current($constantValueCounts);
$constant = key($constantValueCounts);
if($constantValueCount > 1) {
throw new \Exception(sprintf(
'Constant value is not unique; constant=%s; value=%s; enum=%s',
$constant, $constantValueCount, $class
));
}
static::$enumConstants[$class] = $constants;
}
}
/**
* @param mixed $value
*/
private function setValue($value) {
$this->value = $value;
}
/**
* Check if the value on this enum is a valid value for the enum
* @return boolean
*/
private function isValid($value) {
if (!in_array($value, SplEnum::$enumConstants[get_called_class()])) {
return FALSE;
}
return TRUE;
}
/**
* Get the valid values for this enum
* Defaults to constants you define in your subclass
* override to provide custom functionality
*
* @param bool $include_default
* @return array
*/
public function getConstList($include_default = FALSE) {
$enumConstants = SplEnum::$enumConstants[get_called_class()];
if (!$include_default) {
unset($enumConstants['__default']);
}
return $enumConstants;
}
/**
* @return string
*/
public function __toString() {
return (string) $this->value;
}
}
abstract class SplType {
const __default = NULL;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment