55
66namespace Lawondyss \Config ;
77
8- abstract class Config implements \ArrayAccess, \Countable, \IteratorAggregate
8+ use ArrayAccess ;
9+ use Countable ;
10+ use IteratorAggregate ;
11+ use RecursiveArrayIterator ;
12+ use ReflectionObject ;
13+ use ReflectionProperty ;
14+ use function array_map ;
15+ use function count ;
16+ use function is_array ;
17+ use function property_exists ;
18+
19+ abstract class Config implements ArrayAccess, Countable, IteratorAggregate
920{
1021 /**
1122 * @param array<string, mixed> $options
@@ -30,17 +41,14 @@ public function toArray(): array
3041 {
3142 $ arr = [];
3243 $ properties = $ this ->getProperties ();
44+
3345 foreach ($ properties as $ name ) {
3446 $ value = $ this ->$ name ;
3547
3648 if ($ value instanceof self) {
3749 $ value = $ value ->toArray ();
38- } elseif (is_array ($ value ) && count ($ value ) === count (array_filter ($ value , function ($ item ) {
39- return $ item instanceof self;
40- }))) {
41- $ value = array_map (function (Config $ item ) {
42- return $ item ->toArray ();
43- }, $ value );
50+ } elseif (is_array ($ value )) {
51+ $ value = array_map (fn (mixed $ val ) => $ val instanceof Config ? $ val ->toArray () : $ val , $ value );
4452 }
4553
4654 $ arr [$ name ] = $ value ;
@@ -57,67 +65,60 @@ public function toArray(): array
5765 public function withOptions (array $ options ): Config
5866 {
5967 $ dolly = clone $ this ;
60- foreach ($ options as $ option => $ value ) {
61- $ dolly ->$ option = $ value ;
68+
69+ foreach ($ options as $ name => $ value ) {
70+ $ dolly ->$ name = $ value ;
6271 }
6372
6473 return $ dolly ;
6574 }
6675
6776
68- public function offsetExists ($ offset )
77+ public function offsetExists ($ offset ): bool
6978 {
70- return property_exists (static ::class, $ offset ) && $ this ->$ offset !== null ;
79+ return property_exists ($ this ::class, $ offset ) && $ this ->$ offset !== null ;
7180 }
7281
7382
74- public function offsetGet ($ offset )
83+ public function offsetGet ($ offset ): mixed
7584 {
7685 return $ this ->$ offset ;
7786 }
7887
7988
80- public function offsetSet ($ offset , $ value )
89+ public function offsetSet ($ offset , $ value ): void
8190 {
8291 $ this ->$ offset = $ value ;
8392 }
8493
8594
86- public function offsetUnset ($ offset )
95+ public function offsetUnset ($ offset ): void
8796 {
8897 $ this ->$ offset = null ;
8998 }
9099
91100
92- public function count ()
101+ public function count (): int
93102 {
94103 return count ($ this ->getProperties ());
95104 }
96105
97106
98- public function getIterator ()
107+ public function getIterator (): RecursiveArrayIterator
99108 {
100- return new \ RecursiveArrayIterator ($ this ->toArray ());
109+ return new RecursiveArrayIterator ($ this ->toArray ());
101110 }
102111
103112
104113 public function __get ($ name )
105114 {
106- $ this -> assertOptionDefined ( $ name );
115+ throw UndefinedOption:: create ( $ this ::class, $ name , $ this -> getProperties () );
107116 }
108117
109118
110119 public function __set ($ name , $ value )
111120 {
112- $ this ->assertOptionDefined ($ name );
113- }
114-
115-
116- private function assertOptionDefined (string $ optionName ): void
117- {
118- if (!property_exists (static ::class, $ optionName )) {
119- throw UndefinedOption::create (static ::class, $ optionName );
120- }
121+ throw UndefinedOption::create ($ this ::class, $ name , $ this ->getProperties ());
121122 }
122123
123124
@@ -126,17 +127,11 @@ private function assertOptionDefined(string $optionName): void
126127 */
127128 private function getProperties (): array
128129 {
129- static $ cachedProperties = null ;
130-
131- if (!isset ($ cachedProperties )) {
132- $ cachedProperties = [];
133-
134- $ rf = new \ReflectionObject ($ this );
135- foreach ($ rf ->getProperties () as $ property ) {
136- $ cachedProperties [] = $ property ->name ;
137- }
138- }
130+ static $ cachedProperties = [];
139131
140- return $ cachedProperties ;
132+ return $ cachedProperties [$ this ::class] ??= (fn (): array => array_map (
133+ fn (ReflectionProperty $ rp ): string => $ rp ->name ,
134+ (new ReflectionObject ($ this ))->getProperties (~ReflectionProperty::IS_STATIC )
135+ ))();
141136 }
142137}
0 commit comments