55use Faker \Generator as Faker ;
66use Illuminate \Support \Arr ;
77use Illuminate \Support \Str ;
8- use RonasIT \Support \Exceptions \ModelFactoryNotFound ;
8+ use InvalidArgumentException ;
9+ use RonasIT \Support \Exceptions \FakerMethodNotFoundException ;
910use RonasIT \Support \Exceptions \ClassNotExistsException ;
10- use RonasIT \Support \Exceptions \ModelFactoryNotFoundedException ;
1111use RonasIT \Support \Exceptions \ClassAlreadyExistsException ;
1212use RonasIT \Support \Events \SuccessCreateMessage ;
13- use Exception ;
1413
1514class FactoryGenerator extends EntityGenerator
1615{
@@ -26,109 +25,33 @@ class FactoryGenerator extends EntityGenerator
2625 'json ' => '[] ' ,
2726 ];
2827
29- protected function generateSeparateClass (): string
28+ public function generate (): void
3029 {
3130 if (!$ this ->classExists ('models ' , $ this ->model )) {
3231 $ this ->throwFailureException (
33- ClassNotExistsException::class,
34- "Cannot create {$ this ->model }Factory cause {$ this ->model } Model does not exists. " ,
35- "Create a {$ this ->model } Model by himself or run command 'php artisan make:entity {$ this ->model } --only-model'. "
32+ exceptionClass: ClassNotExistsException::class,
33+ failureMessage: "Cannot create {$ this ->model }Factory cause {$ this ->model } Model does not exists. " ,
34+ recommendedMessage: "Create a {$ this ->model } Model by itself or run command 'php artisan make:entity {$ this ->model } --only-model'. " ,
3635 );
3736 }
3837
39- if ($ this ->classExists ('factory ' , "{$ this ->model }Factory " )) {
38+ if ($ this ->classExists ('factories ' , "{$ this ->model }Factory " )) {
4039 $ this ->throwFailureException (
41- ClassAlreadyExistsException::class,
42- "Cannot create {$ this ->model }Factory cause {$ this ->model }Factory already exists. " ,
43- "Remove {$ this ->model }Factory. "
40+ exceptionClass: ClassAlreadyExistsException::class,
41+ failureMessage: "Cannot create {$ this ->model }Factory cause {$ this ->model }Factory already exists. " ,
42+ recommendedMessage: "Remove {$ this ->model }Factory. " ,
4443 );
4544 }
4645
4746 $ factoryContent = $ this ->getStub ('factory ' , [
48- 'namespace ' => $ this ->getOrCreateNamespace ('factory ' ),
47+ 'namespace ' => $ this ->getOrCreateNamespace ('factories ' ),
4948 'entity ' => $ this ->model ,
50- 'fields ' => $ this ->prepareFields ()
49+ 'fields ' => $ this ->prepareFields (),
5150 ]);
5251
53- $ this ->saveClass ('factory ' , "{$ this ->model }Factory " , $ factoryContent );
54-
55- return "Created a new Factory: {$ this ->model }Factory " ;
56- }
57-
58- protected function generateToGenericClass (): string
59- {
60- if (!file_exists ($ this ->paths ['factory ' ])) {
61- $ this ->prepareEmptyFactory ();
62- }
63-
64- if (!$ this ->checkExistModelFactory () && $ this ->checkExistRelatedModelsFactories ()) {
65- $ stubPath = config ("entity-generator.stubs.legacy_factory " );
66-
67- $ content = view ($ stubPath )->with ([
68- 'entity ' => $ this ->model ,
69- 'fields ' => $ this ->prepareFields (),
70- 'modelsNamespace ' => $ this ->getOrCreateNamespace ('models ' )
71- ])->render ();
72-
73- $ content = "\n\n" . $ content ;
74-
75- $ createMessage = "Created a new Test factory for {$ this ->model } model in ' {$ this ->paths ['factory ' ]}' " ;
76-
77- file_put_contents ($ this ->paths ['factory ' ], $ content , FILE_APPEND );
78-
79- $ this ->prepareRelatedFactories ();
80- } else {
81- $ createMessage = "Factory for {$ this ->model } model has already created, so new factory not necessary create. " ;
82- }
83-
84- return $ createMessage ;
85- }
52+ $ this ->saveClass ('factories ' , "{$ this ->model }Factory " , $ factoryContent );
8653
87- public function generate (): void
88- {
89- $ createMessage = (version_compare (app ()->version (), '8 ' , '>= ' ))
90- ? $ this ->generateSeparateClass ()
91- : $ this ->generateToGenericClass ();
92-
93- event (new SuccessCreateMessage ($ createMessage ));
94- }
95-
96- protected function prepareEmptyFactory (): void
97- {
98- $ stubPath = config ('entity-generator.stubs.legacy_empty_factory ' );
99- $ content = "<?php \n\n" . view ($ stubPath , [
100- 'modelsNamespace ' => $ this ->getOrCreateNamespace ('models ' )
101- ])->render ();
102-
103- list ($ basePath , $ databaseFactoryDir ) = extract_last_part (config ('entity-generator.paths.factory ' ), '/ ' );
104-
105- if (!is_dir ($ databaseFactoryDir )) {
106- mkdir ($ databaseFactoryDir );
107- }
108-
109- file_put_contents ($ this ->paths ['factory ' ], $ content );
110- }
111-
112- protected function checkExistRelatedModelsFactories (): bool
113- {
114- $ modelFactoryContent = file_get_contents ($ this ->paths ['factory ' ]);
115- $ relatedModels = $ this ->getRelatedModels ($ this ->model , "{$ this ->model }Factory " );
116- $ modelNamespace = $ this ->getOrCreateNamespace ('models ' );
117-
118- foreach ($ relatedModels as $ relatedModel ) {
119- $ relatedFactoryClass = "{$ modelNamespace }\\$ relatedModel::class " ;
120- $ existModelFactory = strpos ($ modelFactoryContent , $ relatedFactoryClass );
121-
122- if (!$ existModelFactory ) {
123- $ this ->throwFailureException (
124- ModelFactoryNotFoundedException::class,
125- "Not found $ relatedModel factory for $ relatedModel model in ' {$ this ->paths ['factory ' ]}" ,
126- "Please declare a factory for $ relatedModel model on ' {$ this ->paths ['factory ' ]}' path and run your command with option '--only-tests'. "
127- );
128- }
129- }
130-
131- return true ;
54+ event (new SuccessCreateMessage ("Created a new Factory: {$ this ->model }Factory " ));
13255 }
13356
13457 protected static function getFakerMethod ($ field ): string
@@ -146,42 +69,10 @@ protected static function getCustomMethod($field): string
14669 return self ::CUSTOM_METHODS [$ field ['type ' ]];
14770 }
14871
149- $ message = $ field ['type ' ] . 'not found in CUSTOM_METHODS variable CUSTOM_METHODS = ' . self ::CUSTOM_METHODS ;
150- throw new Exception ($ message );
151- }
152-
153- protected function prepareRelatedFactories (): void
154- {
155- $ relations = array_merge (
156- $ this ->relations ['hasOne ' ],
157- $ this ->relations ['hasMany ' ]
158- );
159-
160- foreach ($ relations as $ relation ) {
161- $ modelFactoryContent = file_get_contents ($ this ->paths ['factory ' ]);
162-
163- if (!Str::contains ($ modelFactoryContent , $ this ->getModelClass ($ relation ))) {
164- $ this ->throwFailureException (
165- ModelFactoryNotFound::class,
166- "Model factory for mode {$ relation } not found. " ,
167- "Please create it and after thar you can run this command with flag '--only-tests'. "
168- );
169- }
170-
171- $ matches = [];
172-
173- preg_match ($ this ->getFactoryPattern ($ relation ), $ modelFactoryContent , $ matches );
174-
175- foreach ($ matches as $ match ) {
176- $ field = Str::snake ($ this ->model ) . '_id ' ;
177-
178- $ newField = "\n \"{$ field }\" => 1, " ;
72+ $ message = "Cannot generate fake data for unsupported {$ field ['type ' ]} field type. "
73+ . "Supported custom field types are " . implode (', ' , array_keys (self ::CUSTOM_METHODS ));
17974
180- $ modelFactoryContent = str_replace ($ match , $ match . $ newField , $ modelFactoryContent );
181- }
182-
183- file_put_contents ($ this ->paths ['factory ' ], $ modelFactoryContent );
184- }
75+ throw new FakerMethodNotFoundException ($ message );
18576 }
18677
18778 public static function getFactoryFieldsContent ($ field ): string
@@ -193,49 +84,33 @@ public static function getFactoryFieldsContent($field): string
19384 return 1 ;
19485 }
19586
196- if (property_exists ($ faker , $ field ['name ' ])) {
197- return "\$faker-\> {$ field ['name ' ]}" ;
87+ try {
88+ $ faker ->{$ field ['name ' ]};
89+ $ hasFormatter = true ;
90+ } catch (InvalidArgumentException $ e ) {
91+ $ hasFormatter = false ;
19892 }
19993
200- if (method_exists ( $ faker , $ field [ ' name ' ]) ) {
201- return "\$faker-\ > {$ field ['name ' ]}() " ;
94+ if ($ hasFormatter ) {
95+ return "\$faker-> {$ field ['name ' ]}" ;
20296 }
20397
20498 return self ::getFakerMethod ($ field );
20599 }
206100
207- protected function checkExistModelFactory (): int
208- {
209- $ modelFactoryContent = file_get_contents ($ this ->paths ['factory ' ]);
210- $ modelNamespace = $ this ->getOrCreateNamespace ('models ' );
211- $ factoryClass = "{$ modelNamespace }\\$ this ->model ::class " ;
212-
213- return strpos ($ modelFactoryContent , $ factoryClass );
214- }
215-
216101 protected function prepareFields (): array
217102 {
218103 $ result = [];
219104
220105 foreach ($ this ->fields as $ type => $ fields ) {
221106 foreach ($ fields as $ field ) {
222- $ explodedType = explode ('- ' , $ type );
223-
224107 $ result [] = [
225108 'name ' => $ field ,
226- 'type ' => head ( $ explodedType )
109+ 'type ' => Str:: before ( $ type , ' - ' ),
227110 ];
228111 }
229112 }
230113
231114 return $ result ;
232115 }
233-
234- protected function getFactoryPattern ($ model ): string
235- {
236- $ modelNamespace = "App \\\\Models \\\\" . $ model ;
237- $ return = "return \\[ " ;
238-
239- return "/ {$ modelNamespace }.* {$ return }/sU " ;
240- }
241116}
0 commit comments