BasicEnum   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 183
rs 10
c 0
b 0
f 0
wmc 25
lcom 1
cbo 1

10 Methods

Rating   Name   Duplication   Size   Complexity  
A ensureValidValue() 0 6 2
A getName() 0 9 2
A getNames() 0 4 1
A getValue() 0 17 4
A getValues() 0 4 1
A isValidName() 0 11 2
A isValidValue() 0 5 1
A getCaseMapping() 0 14 4
A getConstants() 0 18 4
A getNamesArray() 0 13 4
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Created by PhpStorm.
5
 * User: benedikt
6
 * Date: 9/18/17
7
 * Time: 10:24 PM
8
 */
9
10
namespace Tfboe\FmLib\Helpers;
11
12
use Tfboe\FmLib\Exceptions\ValueNotValid;
13
14
/**
15
 * Class BasicEnum
16
 * @package Tfboe\FmLib\Entity\Categories
17
 */
18
abstract class BasicEnum
19
{
20
//<editor-fold desc="Fields">
21
  /** @var null|mixed[][] */
22
  private static $constCacheArray = NULL;
23
24
  /** @var null|string[][] */
25
  private static $constCacheArrayCaseMapping = NULL;
26
27
  /** @var null|string[][] */
28
  private static $nameArray = NULL;
29
//</editor-fold desc="Fields">
30
31
//<editor-fold desc="Public Methods">
32
  /**
33
   * Ensures that the given value is valid by throwing an exception if it is not valid
34
   * @param mixed $value the value to check for validity
35
   * @param bool $strict if yes type checks are performed
36
   * @throws ValueNotValid if the value is not valid
37
   */
38
  public static function ensureValidValue($value, bool $strict = true): void
39
  {
40
    if (!self::isValidValue($value, $strict)) {
41
      throw new ValueNotValid($value, get_called_class());
42
    }
43
  }
44
45
  /**
46
   * Gets the name of the given value, throwing an exception if the value is not valid
47
   * @param mixed $value the value to get the name for
48
   * @return string the name of the value
49
   * @throws ValueNotValid if the value is not valid
50
   */
51
  public static function getName($value): string
52
  {
53
    $names = self::getNamesArray();
54
    if (array_key_exists($value, $names)) {
55
      return $names[$value];
56
    }
57
58
    throw new ValueNotValid($value, get_called_class());
59
  }
60
61
  /**
62
   * Gets a list of all names in this enum
63
   * @return mixed[]
64
   */
65
  public static function getNames(): array
66
  {
67
    return array_keys(self::getConstants());
68
  }
69
70
  /**
71
   * Gets the value corresponding to the given name
72
   * @param string $name the name for which to get the value
73
   * @param bool $strict if yes retrieval is done case sensitive and otherwise case insensitive
74
   * @return mixed the corresponding value
75
   * @throws ValueNotValid if the name is not valid
76
   */
77
  public static function getValue(string $name, bool $strict = false)
78
  {
79
    $constants = self::getConstants();
80
    if ($strict) {
81
      if (array_key_exists($name, $constants)) {
82
        return $constants[$name];
83
      }
84
    } else {
85
      $mapping = self::getCaseMapping();
86
      $key = strtolower($name);
87
      if (array_key_exists($key, $mapping)) {
88
        return $constants[$mapping[$key]];
89
      }
90
    }
91
92
    throw new ValueNotValid($name, get_called_class(), "getValues");
93
  }
94
95
  /**
96
   * Gets a list of all values in this enum
97
   * @return mixed[]
98
   */
99
  public static function getValues(): array
100
  {
101
    return array_values(self::getConstants());
102
  }
103
104
  /**
105
   * Checks if a given name is part of this enum
106
   * @param string $name the name to check for validity
107
   * @param bool $strict if yes check is done case sensitive and otherwise case insensitive
108
   * @return bool true if the name is part of the enum and false otherwise
109
   */
110
  public static function isValidName(string $name, bool $strict = false): bool
111
  {
112
    $constants = self::getConstants();
113
114
    if ($strict) {
115
      return array_key_exists($name, $constants);
116
    }
117
118
    $keys = array_map('strtolower', array_keys($constants));
119
    return in_array(strtolower($name), $keys);
120
  }
121
122
  /**
123
   * Checks if a given value is part of this enum
124
   * @param mixed $value the value to check for validity
125
   * @param bool $strict if yes type checks are performed
126
   * @return bool true if the value is part of the enum and false otherwise
127
   */
128
  public static function isValidValue($value, bool $strict = true): bool
129
  {
130
    $values = self::getValues();
131
    return in_array($value, $values, $strict);
132
  }
133
//</editor-fold desc="Public Methods">
134
135
//<editor-fold desc="Private Methods">
136
137
  /**
138
   * Gets a case mapping which maps a lower case names to the real enum names
139
   * @return mixed[]
140
   */
141
  private static function getCaseMapping(): array
142
  {
143
    if (self::$constCacheArrayCaseMapping == NULL) {
144
      self::$constCacheArrayCaseMapping = [];
145
    }
146
    $calledClass = get_called_class();
147
    if (!array_key_exists($calledClass, self::$constCacheArrayCaseMapping)) {
148
      self::$constCacheArrayCaseMapping[$calledClass] = [];
149
      foreach (self::getNames() as $name) {
150
        self::$constCacheArrayCaseMapping[$calledClass][strtolower($name)] = $name;
151
      }
152
    }
153
    return self::$constCacheArrayCaseMapping[$calledClass];
154
  }
155
156
  /** @noinspection PhpDocMissingThrowsInspection */ //ReflectionException
157
  /**
158
   * Gets a dictionary of all constants in this enum
159
   * @param string|null $calledClass
160
   * @return mixed[]
161
   */
162
  private static function getConstants($calledClass = null): array
163
  {
164
    if (self::$constCacheArray == NULL) {
165
      self::$constCacheArray = [];
166
    }
167
    if ($calledClass === null) {
168
      $calledClass = get_called_class();
169
    }
170
    if (!array_key_exists($calledClass, self::$constCacheArray)) {
171
      // ReflectionException => whe know that calledClass is a valid class since it is the result of get_called_class
172
      /** @noinspection PhpUnhandledExceptionInspection */
173
      $reflect = new \ReflectionClass($calledClass);
174
      $array = $reflect->getConstants();
175
      asort($array);
176
      self::$constCacheArray[$calledClass] = $array;
177
    }
178
    return self::$constCacheArray[$calledClass];
179
  }
180
181
  /**
182
   * Gets a dictionary mapping values to names in this enum
183
   * @param string|null $calledClass
184
   * @return string[]
185
   */
186
  private static function getNamesArray($calledClass = null): array
187
  {
188
    if (self::$nameArray == NULL) {
189
      self::$nameArray = [];
190
    }
191
    if ($calledClass === null) {
192
      $calledClass = get_called_class();
193
    }
194
    if (!array_key_exists($calledClass, self::$nameArray)) {
195
      self::$nameArray[$calledClass] = array_flip(self::getConstants($calledClass));
196
    }
197
    return self::$nameArray[$calledClass];
198
  }
199
//</editor-fold desc="Private Methods">
200
}