1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Chromabits\Nucleus\Meditation;
13:
14: use Chromabits\Nucleus\Foundation\BaseObject;
15: use Chromabits\Nucleus\Meditation\Exceptions\UnknownTypeException;
16: use Chromabits\Nucleus\Meditation\Primitives\CompoundTypes;
17: use Chromabits\Nucleus\Meditation\Primitives\ScalarTypes;
18: use Chromabits\Nucleus\Meditation\Primitives\SpecialTypes;
19:
20: 21: 22: 23: 24: 25: 26: 27:
28: class TypeHound extends BaseObject
29: {
30: 31: 32: 33: 34:
35: protected $value;
36:
37: 38: 39: 40: 41:
42: protected static $types = [];
43:
44: 45: 46:
47: protected static $definitions = [];
48:
49: 50: 51:
52: protected static $compounds = [];
53:
54: 55: 56:
57: protected static $scalars = [];
58:
59: 60: 61:
62: protected static $specials = [];
63:
64: 65: 66: 67: 68:
69: public function __construct($value)
70: {
71: parent::__construct();
72:
73: $this->value = $value;
74: }
75:
76: 77: 78:
79: protected static function registerDefinitions()
80: {
81: static::$definitions = [
82: new CompoundTypes(),
83: new ScalarTypes(),
84: new SpecialTypes(),
85: ];
86: }
87:
88: 89: 90:
91: protected static function aggregateDefinitions()
92: {
93: array_map(function (TypesDefinition $definition) {
94: static::$compounds = array_merge(
95: static::$compounds,
96: $definition->getCompounds()
97: );
98:
99: static::$scalars = array_merge(
100: static::$scalars,
101: $definition->getScalars()
102: );
103:
104: static::$specials = array_merge(
105: static::$specials,
106: $definition->getSpecial()
107: );
108:
109: static::$types = array_merge(
110: static::$types,
111: $definition->getCompounds(),
112: $definition->getScalars(),
113: $definition->getSpecial()
114: );
115: }, static::$definitions);
116: }
117:
118: 119: 120: 121: 122: 123:
124: public function resolve()
125: {
126:
127:
128: if (is_scalar($this->value)) {
129: if (is_string($this->value)) {
130: return ScalarTypes::SCALAR_STRING;
131: } elseif (is_bool($this->value)) {
132: return ScalarTypes::SCALAR_BOOLEAN;
133: } elseif (is_integer($this->value)) {
134: return ScalarTypes::SCALAR_INTEGER;
135: } elseif (is_float($this->value)) {
136: return ScalarTypes::SCALAR_FLOAT;
137: }
138: } elseif (is_array($this->value)) {
139: return CompoundTypes::COMPOUND_ARRAY;
140: } elseif (is_object($this->value)) {
141: return CompoundTypes::COMPOUND_OBJECT;
142: } elseif (is_resource($this->value)) {
143: return SpecialTypes::SPECIAL_RESOURCE;
144: } elseif ($this->value === null) {
145: return SpecialTypes::SPECIAL_NULL;
146: }
147:
148: throw new UnknownTypeException(gettype($this->value));
149: }
150:
151: 152: 153: 154: 155: 156: 157: 158:
159: public function matches(TypeHound $other)
160: {
161: return $this->resolve() === $other->resolve();
162: }
163:
164: 165: 166: 167: 168: 169: 170:
171: public static function isKnown($typeName)
172: {
173: static::registerDefinitions();
174: static::aggregateDefinitions();
175:
176: return in_array($typeName, static::$types);
177: }
178:
179: 180: 181: 182: 183: 184: 185: 186: 187:
188: public static function createAndResolve($value)
189: {
190: return static::fetch($value);
191: }
192:
193: 194: 195: 196: 197: 198: 199: 200:
201: public static function fetch($value)
202: {
203: return (new static($value))->resolve();
204: }
205: }
206: