33namespace  Knuckles \Camel ;
44
55use  Illuminate \Contracts \Support \Arrayable ;
6- use  Spatie \DataTransferObject \DataTransferObject ;
76
87
9- class  BaseDTO extends  DataTransferObject  implements  Arrayable, \ArrayAccess
8+ class  BaseDTO implements  Arrayable, \ArrayAccess
109{
1110    /** 
1211     * @var array $custom 
1312     * Added so end-users can dynamically add additional properties for their own use. 
1413     */ 
1514    public  array  $ custom
1615
16+     public  function  __construct (array  $ parameters
17+     {
18+         // Initialize all properties to their default values first 
19+         $ this initializeProperties ();
20+         
21+         foreach  ($ parametersas  $ key$ value
22+             if  (property_exists ($ this $ key
23+                 $ this $ key$ this castProperty ($ key$ value
24+             }
25+         }
26+     }
27+     
28+     protected  function  initializeProperties (): void 
29+     {
30+         $ reflectionnew  \ReflectionClass ($ this 
31+         
32+         foreach  ($ reflectiongetProperties (\ReflectionProperty::IS_PUBLIC ) as  $ property
33+             $ name$ propertygetName ();
34+             
35+             // Skip if already initialized (has a default value) 
36+             if  ($ propertyhasDefaultValue ()) {
37+                 continue ;
38+             }
39+             
40+             $ type$ propertygetType ();
41+             if  ($ type$ typeallowsNull ()) {
42+                 $ this $ namenull ;
43+             }
44+         }
45+     }
46+ 
47+     protected  function  castProperty (string  $ keymixed  $ valuemixed 
48+     {
49+         // If the value is already the correct type, return it as-is 
50+         if  (!is_array ($ value
51+             return  $ value
52+         }
53+ 
54+         // Get property type through reflection 
55+         $ reflectionnew  \ReflectionClass ($ this 
56+         if  (!$ reflectionhasProperty ($ key
57+             return  $ value
58+         }
59+ 
60+         $ property$ reflectiongetProperty ($ key
61+         $ type$ propertygetType ();
62+         
63+         if  ($ type$ typeinstanceof  \ReflectionNamedType && !$ typeisBuiltin ()) {
64+             $ className$ typegetName ();
65+             
66+             // If it's a DTO class in our namespace, instantiate it 
67+             if  (class_exists ($ classNameis_subclass_of ($ classNameself ::class)) {
68+                 return  new  $ className$ value
69+             }
70+             
71+             // If it's another class in our namespace that has a constructor accepting arrays 
72+             if  (class_exists ($ className
73+                 try  {
74+                     return  new  $ className$ value
75+                 } catch  (\Throwable   $ e
76+                     // If instantiation fails, return the original value 
77+                     return  $ value
78+                 }
79+             }
80+         }
81+         
82+         return  $ value
83+     }
84+ 
1785    public  static  function  create (BaseDTO array  $ dataBaseDTO array  $ inheritFromstatic 
1886    {
1987        if  ($ datainstanceof  static) {
@@ -49,6 +117,15 @@ protected function parseArray(array $array): array
49117        return  $ array
50118    }
51119
120+     public  function  toArray (): array 
121+     {
122+         $ array
123+         foreach  (get_object_vars ($ this as  $ property$ value
124+             $ array$ property$ value
125+         }
126+         return  $ this parseArray ($ array
127+     }
128+ 
52129    public  static  function  make (array |self $ datastatic 
53130    {
54131        return  $ datainstanceof  static ? $ datanew  static ($ data
@@ -73,4 +150,22 @@ public function offsetUnset(mixed $offset): void
73150    {
74151        unset($ this $ offset
75152    }
153+     
154+     public  function  except (string  ...$ keysarray 
155+     {
156+         $ array
157+         foreach  (get_object_vars ($ this as  $ property$ value
158+             if  (!in_array ($ property$ keys
159+                 $ array$ property$ value
160+             }
161+         }
162+         return  $ this parseArray ($ array
163+     }
164+     
165+     public  static  function  arrayOf (array  $ itemsarray 
166+     {
167+         return  array_map (function  ($ item
168+             return  $ iteminstanceof  static ? $ itemnew  static ($ item
169+         }, $ items
170+     }
76171}
0 commit comments