2 namespace TYPO3\CMS\Core\Type
;
5 * This file is part of the TYPO3 CMS project.
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
14 * The TYPO3 project - inspiring people to share!
17 use TYPO3\CMS\Core\Type\Exception
;
20 * Abstract class for Enumeration.
21 * Inspired by SplEnum.
23 * The prefix "Abstract" has been left out by intention because
24 * a "type" is abstract by definition.
26 abstract class Enumeration
implements TypeInterface
{
36 protected static $enumConstants;
40 * @throws Exception\InvalidEnumerationValueException
42 public function __construct($value = NULL
) {
43 if ($value === NULL
&& !defined('static::__default')) {
44 throw new Exception\
InvalidEnumerationValueException(
45 sprintf('A value for %s is required if no __default is defined.', get_class($this)),
49 if ($value === NULL
) {
50 $value = static::__default
;
53 if (!$this->isValid($value)) {
54 throw new Exception\
InvalidEnumerationValueException(
55 sprintf('Invalid value %s for %s', $value, get_class($this)),
59 $this->setValue($value);
63 * @throws Exception\InvalidEnumerationValueException
64 * @throws Exception\InvalidEnumerationDefinitionException
65 * @internal param string $class
67 static protected function loadValues() {
68 $class = get_called_class();
70 if (isset(static::$enumConstants[$class])) {
74 $reflection = new \
ReflectionClass($class);
75 $constants = $reflection->getConstants();
77 if (isset($constants['__default'])) {
78 $defaultValue = $constants['__default'];
79 unset($constants['__default']);
81 if (empty($constants)) {
82 throw new Exception\
InvalidEnumerationValueException(
84 'No enumeration constants defined for "%s"', $class
89 foreach ($constants as $constant => $value) {
90 if (!is_int($value) && !is_string($value)) {
91 throw new Exception\
InvalidEnumerationDefinitionException(
93 'Constant value must be of type integer or string; constant=%s; type=%s',
95 is_object($value) ?
get_class($value) : gettype($value)
101 $constantValueCounts = array_count_values($constants);
102 arsort($constantValueCounts, SORT_NUMERIC
);
103 $constantValueCount = current($constantValueCounts);
104 $constant = key($constantValueCounts);
105 if ($constantValueCount > 1) {
106 throw new Exception\
InvalidEnumerationDefinitionException(
108 'Constant value is not unique; constant=%s; value=%s; enum=%s',
109 $constant, $constantValueCount, $class
114 if ($defaultValue !== NULL
) {
115 $constants['__default'] = $defaultValue;
117 static::$enumConstants[$class] = $constants;
121 * Set the Enumeration value to the associated enumeration value by a loose comparison.
122 * The value, that is used as the enumeration value, will be of the same type like defined in the enumeration
124 * @param mixed $value
125 * @throws Exception\InvalidEnumerationValueException
127 protected function setValue($value) {
128 $enumKey = array_search($value, static::$enumConstants[get_class($this)]);
129 if ($enumKey === FALSE
) {
130 throw new Exception\
InvalidEnumerationValueException(
131 sprintf('Invalid value %s for %s', $value, __CLASS__
),
135 $this->value
= static::$enumConstants[get_class($this)][$enumKey];
139 * Check if the value on this enum is a valid value for the enum
141 * @param mixed $value
144 protected function isValid($value) {
145 $value = (string) $value;
146 foreach (static::$enumConstants[get_class($this)] as $constantValue) {
147 if ($value === (string) $constantValue) {
155 * Get the valid values for this enum
156 * Defaults to constants you define in your subclass
157 * override to provide custom functionality
159 * @param boolean $include_default
162 static public function getConstants($include_default = FALSE
) {
163 static::loadValues();
164 $enumConstants = static::$enumConstants[get_called_class()];
165 if (!$include_default) {
166 unset($enumConstants['__default']);
168 return $enumConstants;
172 * Cast value to enumeration type
174 * @param mixed $value Value that has to be casted
175 * @return Enumeration
177 public static function cast($value) {
178 $currentClass = get_called_class();
179 if (!is_object($value) ||
get_class($value) !== $currentClass) {
180 $value = new $currentClass($value);
186 * Compare if the value of the current object value equals the given value
188 * @param mixed $value default
191 public function equals($value) {
192 $value = static::cast($value);
193 return $this == $value;
199 public function __toString() {
200 return (string)$this->value
;