33namespace PhpDto \Services ;
44
55use PhpDto \DtoSerialize ;
6+ use PhpDto \Enum \Types ;
67
78class DtoBuilder
89{
@@ -23,22 +24,26 @@ public function getNamespace( array $configs ): string
2324 }
2425
2526 /**
26- * @param array $dtoConfigs
27+ * @param array $configs
2728 * @return string
2829 */
29- public function getClassName ( array $ dtoConfigs ): string
30+ public function getClassName ( array $ configs ): string
3031 {
31- $ classPrefix = ucfirst ( $ dtoConfigs ['class ' ] );
32+ $ classPrefix = ucfirst ( $ configs ['class ' ] );
3233
3334 return $ classPrefix .getenv ( 'PHP_DTO_CLASS_POSTFIX ' );
3435 }
3536
3637 /**
38+ * @param array $configs
3739 * @return array
3840 */
39- public function getModules (): array
41+ public function getModules ( array $ configs ): array
4042 {
41- return [];
43+ return $ this ->mergeModulesFromProps (
44+ modules: $ configs ['modules ' ] ?? [],
45+ props: $ configs ['props ' ] ?? []
46+ );
4247 }
4348
4449 /**
@@ -62,20 +67,11 @@ public function getProps( array $configs, string $visibility = 'private' ): arra
6267
6368 foreach ($ configs ['props ' ] as $ key => $ value )
6469 {
65- $ type = '' ;
66-
67- if ( str_contains ($ value , 'nullable ' ) !== false )
68- {
69- $ type = '? ' ;
70- $ value = str_replace ('nullable| ' , '' , $ value );
71- $ value = str_replace ('|nullable ' , '' , $ value );
72- }
73-
74- $ type .= $ value ;
75-
7670 $ key = $ this ->convertPropToSnakeCase ($ key );
7771
78- $ props [] = "{$ visibility } {$ type }" . ' $_ ' . "{$ key }; " ;
72+ $ value = $ this ->getLastSegmentFromPath ($ value );
73+
74+ $ props [] = "{$ visibility } {$ value }" . ' $_ ' . "{$ key }; " ;
7975 }
8076
8177 return $ props ;
@@ -115,45 +111,36 @@ public function getConstructorProps( array $configs ): array
115111 */
116112 public function getMethods ( array $ configs , string $ visibility = 'public ' ): array
117113 {
118- $ methods = [];
119-
120- foreach ($ configs ['props ' ] as $ key => $ value )
121- {
122- $ props = explode ('| ' , $ value );
114+ $ methods = [];
123115
124- $ returnType = '' ;
116+ foreach ($ configs ['props ' ] as $ key => $ value )
117+ {
118+ if (str_contains ($ key , '_ ' ))
119+ {
120+ $ key = join ('' , array_map ('ucfirst ' , explode ('_ ' , $ key )));
121+ }
125122
126- $ returnType .= in_array ( 'nullable ' , $ props ) ? '? ' : '' ;
127- $ returnType .= in_array ( 'int ' , $ props ) ? 'int ' : '' ;
128- $ returnType .= in_array ( 'float ' , $ props ) ? 'float ' : '' ;
129- $ returnType .= in_array ( 'string ' , $ props ) ? 'string ' : '' ;
130- $ returnType .= in_array ( 'bool ' , $ props ) ? 'bool ' : '' ;
131- $ returnType .= in_array ( 'array ' , $ props ) ? 'array ' : '' ;
123+ $ returnType = $ this ->getReturnTypeFromValue ($ value );
132124
133- if (strpos ($ key , '_ ' ) !== false )
134- {
135- $ key = join ('' , array_map ('ucfirst ' , explode ('_ ' , $ key )));
136- }
125+ $ declaration = 'function get ' . ucfirst ($ key ) . '(): ' . $ returnType ;
137126
138- $ declaration = 'function get ' .ucfirst ($ key ).'(): ' .$ returnType ;
127+ $ method ['visibility ' ] = $ visibility ;
128+ $ method ['declaration ' ] = $ declaration ;
129+ $ method ['body ' ] = 'return $this->_ ' . lcfirst ($ key ) . '; ' ;
139130
140- $ method ['visibility ' ] = $ visibility ;
141- $ method ['declaration ' ] = $ declaration ;
142- $ method ['body ' ] = 'return $this->_ ' .lcfirst ($ key ).'; ' ;
131+ $ methods [] = $ method ;
132+ }
143133
144- $ methods [] = $ method ;
145- }
146-
147- return $ methods ;
148- }
134+ return $ methods ;
135+ }
149136
150137 /**
151138 * @param string $prop
152139 * @return string
153140 */
154141 public function convertPropToSnakeCase (string $ prop ): string
155142 {
156- if (strlen ($ prop ) > 0 && strpos ($ prop , '_ ' ) !== false )
143+ if (strlen ($ prop ) > 0 && str_contains ($ prop , '_ ' ))
157144 {
158145 $ exploded = explode ('_ ' , $ prop );
159146
@@ -173,4 +160,74 @@ public function convertPropToSnakeCase(string $prop): string
173160
174161 return $ prop ;
175162 }
163+
164+ /**
165+ * @param string $value
166+ * @return string
167+ */
168+ public function getReturnTypeFromValue (string $ value ): string
169+ {
170+ return $ this ->getLastSegmentFromPath ($ value );
171+ }
172+
173+ /**
174+ * @param array $modules
175+ * @param array $props
176+ * @return array
177+ */
178+ public function mergeModulesFromProps (array $ modules , array $ props ): array
179+ {
180+ $ types = new Types ();
181+
182+ foreach ($ props as $ prop )
183+ {
184+ $ prop = str_replace ('? ' , '' , $ prop );
185+
186+ if ( !$ types ->hasValue ($ prop ) && !$ this ->isPropInModules ($ prop , $ modules ) )
187+ {
188+ $ modules [] = $ prop ;
189+ }
190+ }
191+
192+ return $ modules ;
193+ }
194+
195+ /**
196+ * @param string $prop
197+ * @param array $modules
198+ * @return bool
199+ */
200+ public function isPropInModules (string $ prop , array $ modules ): bool
201+ {
202+ $ modules = array_map (function (string $ namespace ) use ($ prop ) {
203+ if (str_contains ($ namespace , '\\' ))
204+ {
205+ $ exploded = explode ('\\' , $ namespace );
206+
207+ return $ exploded [count ($ exploded )-1 ];
208+ }
209+
210+ return $ prop ;
211+ }, $ modules );
212+
213+ return in_array (needle: $ prop , haystack: $ modules );
214+ }
215+
216+ /**
217+ * @param string $value
218+ * @return string
219+ */
220+ public function getLastSegmentFromPath (string $ value ): string
221+ {
222+ if (str_contains ($ value , '\\' ))
223+ {
224+ $ nullChar = $ value [0 ] === '? ' ? '? ' : '' ;
225+
226+ $ exploded = explode ('\\' , $ value );
227+
228+ $ value = $ nullChar . $ exploded [count ($ exploded )-1 ];
229+ }
230+
231+ return $ value ;
232+ }
176233}
0 commit comments