Passed
Push — develop ( 249e19...c45be8 )
by Jesús
02:17
created

MakeServiceCommand::handle()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 34
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 16
nc 5
nop 0
dl 0
loc 34
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
namespace OkayBueno\ServiceGenerator\Commands;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Filesystem\Filesystem;
7
8
/**
9
 * Class MakeServiceCommand
10
 * @package OkayBueno\ServiceGenerator\Commands
11
 */
12
class MakeServiceCommand extends Command
13
{
14
15
    protected $signature = 'make:service {service} {--folder=?}';
16
    protected $description = 'Interactively create a new service.';
17
18
    protected $filesystem;
19
    protected $composer;
20
21
    protected $serviceGroup;
22
    protected $serviceFolder;
23
    protected $serviceBasePath;
24
    protected $serviceNamespace;
25
    protected $serviceInterfaceName;
26
    protected $serviceClassPath;
27
    protected $serviceClassName;
28
    protected $validatorBasePath;
29
    protected $validatorInterfaceNamespace;
30
    protected $validatorInterfaceName;
31
    protected $validatorClassPath;
32
    protected $validatorClassName;
33
    protected $repositoryFullName;
34
    protected $repositoryName;
35
36
37
    /**
38
     * @param Filesystem $filesystem
39
     */
40
    public function __construct(
41
        Filesystem $filesystem
42
    )
43
    {
44
        parent::__construct();
45
        $this->filesystem = $filesystem;
46
        $this->composer = app()['composer'];
0 ignored issues
show
Bug introduced by
The function app was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

46
        $this->composer = /** @scrutinizer ignore-call */ app()['composer'];
Loading history...
47
    }
48
49
    /**
50
     * Execute the console command.
51
     *
52
     * @return mixed
53
     */
54
    public function handle()
55
    {
56
        $service = $this->argument('service');
57
        $folder = $this->option('folder');
58
59
        if ( $service )
60
        {
61
            $groups = config('service-generator.groups');
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

61
            $groups = /** @scrutinizer ignore-call */ config('service-generator.groups');
Loading history...
62
63
            $groupKeys = array_keys( $groups );
64
65
            $group = $this->choice('For which group do you want to create the service?', $groupKeys );
66
67
            $repository = $this->confirm('Do you want to inject a repository to this service?', false);
68
69
            if ( $repository ) $repository = $this->ask('Please specify the full interface (with namespace) for the repository that you want to inject (ie: MyApp\Repositories\MyRepositoryInterface)');
70
            else $repository = FALSE;
71
72
            $validator = $this->confirm('Do you want to create and inject a validator for this service?', true);
73
74
            $this->populateValuesForProperties( $service, $folder, $group, $repository, $validator );
75
76
            // Create validator, if it proceeds.
77
            if ( $validator ) $this->createValidatorWithInterface();
78
79
            // Create service.
80
            $this->createServiceWithInterface();
81
82
            // And lastly, service provide.
83
            $this->createServiceProvider();
84
85
        } else
86
        {
87
            $this->error('Please introduce a name for this service.');
88
        }
89
    }
90
91
    /**
92
     * @param $service
93
     * @param $group
94
     * @param $repository
95
     * @param $validator
96
     */
97
    protected function populateValuesForProperties( $service, $folder, $group, $repository, $validator )
98
    {
99
        $groups = config('service-generator.groups');
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

99
        $groups = /** @scrutinizer ignore-call */ config('service-generator.groups');
Loading history...
100
101
        $serviceName = $service.'Service';
102
103
        $this->serviceFolder = $folder;
104
        $this->serviceGroup = $group;
105
        $this->serviceBasePath = $this->serviceFolder ? $groups[ $group ].'/'.$this->serviceFolder : $groups[ $group ].'/'.$service;
106
        $this->serviceNamespace = $this->serviceFolder ? $group.'\\'.$this->serviceFolder : $group.'\\'.$service;
107
        $this->serviceInterfaceName = $serviceName.'Interface';
108
        $this->serviceClassPath = rtrim($this->serviceBasePath, '/').'/src';
109
        $this->serviceClassName = $serviceName;
110
111
        if ( $validator )
112
        {
113
            $this->validatorBasePath = rtrim($this->serviceBasePath, '/').'/Validation';
114
            $this->validatorClassPath = rtrim($this->validatorBasePath, '/').'/src';
115
            $this->validatorInterfaceNamespace = $this->serviceNamespace.'\Validation';
116
            $this->validatorInterfaceName = $service.'ValidatorInterface';
117
            $this->validatorClassName = $service.'LaravelValidator';
118
        }
119
120
        if ( $repository )
121
        {
122
            $rplc = str_replace( '\\', '/', $repository );
123
            $this->repositoryFullName = $repository;
124
            $this->repositoryName = pathinfo( $rplc, PATHINFO_FILENAME );
125
        }
126
    }
127
128
    /**
129
     *
130
     */
131 View Code Duplication
    protected function createValidatorWithInterface()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
132
    {
133
        $validatorInterfaceFullPath = $this->validatorBasePath.'/'.$this->validatorInterfaceName.'.php';
134
        if ( !$this->filesystem->exists( $validatorInterfaceFullPath ) )
135
        {
136
            // Read the stub and replace
137
            $this->makeDirectory( $this->validatorBasePath );
138
            $this->filesystem->put( $validatorInterfaceFullPath, $this->compileValidatorInterface() );
139
            $this->info("Validator interface created successfully for '$this->serviceClassName'.");
140
            $this->composer->dumpAutoloads();
141
        } else
142
        {
143
            $this->error("The interface '$this->validatorInterfaceName' already exists, so it was skipped.");
144
        }
145
146
        // Now create the class.
147
        $validatorClassFullPath = $this->validatorClassPath.'/'.$this->validatorClassName.'.php';
148
        if ( !$this->filesystem->exists( $validatorClassFullPath ) )
149
        {
150
            $this->makeDirectory( $this->validatorClassPath );
151
            $this->filesystem->put( $validatorClassFullPath, $this->compileValidator() );
152
            $this->info("Validator created successfully for '$this->serviceClassName'.");
153
            $this->composer->dumpAutoloads();
154
        } else
155
        {
156
            $this->error("The validator '$this->validatorClassName' already exists, so it was skipped.");
157
        }
158
    }
159
160
    /**
161
     *
162
     */
163 View Code Duplication
    protected function createServiceWithInterface()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
164
    {
165
        $serviceInterfaceFullPath = $this->serviceBasePath.'/'.$this->serviceInterfaceName.'.php';
166
        if ( !$this->filesystem->exists( $serviceInterfaceFullPath ) )
167
        {
168
            // Read the stub and replace
169
            $this->makeDirectory( $this->serviceBasePath );
170
            $this->filesystem->put( $serviceInterfaceFullPath, $this->compileServiceInterface() );
171
            $this->info("Service interface created successfully for '$this->serviceClassName'.");
172
            $this->composer->dumpAutoloads();
173
        } else
174
        {
175
            $this->error("The interface '$this->serviceInterfaceName' already exists, so it was skipped.");
176
        }
177
178
        $serviceClassFullPath = $this->serviceClassPath.'/'.$this->serviceClassName.'.php';
179
        if ( !$this->filesystem->exists( $serviceClassFullPath ) )
180
        {
181
            $this->makeDirectory( $this->serviceClassPath );
182
            $this->filesystem->put( $serviceClassFullPath, $this->compileService() );
183
            $this->info("Service '$this->serviceClassName' created successfully.");
184
            $this->composer->dumpAutoloads();
185
        } else
186
        {
187
            $this->error("The service '$this->serviceClassName' already exists, so it was skipped.");
188
        }
189
    }
190
191
    /**
192
     *
193
     */
194
    protected function createServiceProvider()
195
    {
196
        $serviceProviderClassName = $this->getServiceProviderName();
197
198
        $classFilePath = $this->serviceBasePath.'/'.$serviceProviderClassName.'.php';
199
200
        if ( !$this->filesystem->exists( $classFilePath ) )
201
        {
202
            $this->makeDirectory( $this->serviceBasePath );
203
            $this->filesystem->put( $classFilePath, $this->compileServiceProvider() );
204
            $this->info("Service provider created successfully for '$this->serviceClassName'.");
205
            $this->composer->dumpAutoloads();
206
        } else
207
        {
208
            $this->error("The service provider '$serviceProviderClassName' already exists, so it was skipped.");
209
        }
210
    }
211
212
    /**
213
     * @return mixed|string
214
     */
215
    protected function compileServiceInterface()
216
    {
217
        $stub = $this->filesystem->get(__DIR__ . '/../stubs/service-interface.stub');
218
219
        $stub = str_replace('{{serviceInterfaceNamespace}}', $this->serviceNamespace, $stub);
220
        $stub = str_replace('{{serviceInterfaceName}}', $this->serviceInterfaceName, $stub);
221
222
        return $stub;
223
    }
224
225
    /**
226
     * @return mixed|string
227
     */
228
    protected function compileService()
229
    {
230
        if ( $this->repositoryName && !$this->validatorClassName )
231
        {
232
            $stub = $this->filesystem->get(__DIR__ . '/../stubs/service-w-repo.stub');
233
        } elseif ( $this->repositoryName && $this->validatorClassName  )
234
        {
235
            $stub = $this->filesystem->get(__DIR__ . '/../stubs/service-w-repo-validator.stub');
236 View Code Duplication
        } else if ( !$this->repositoryName && $this->validatorClassName )
237
        {
238
            $stub = $this->filesystem->get(__DIR__ . '/../stubs/service-w-validator.stub');
239
        } else
240
            {
241
            $stub = $this->filesystem->get(__DIR__ . '/../stubs/service.stub');
242
        }
243
244
        $stub = str_replace('{{serviceInterfaceNamespace}}', $this->serviceNamespace, $stub);
245
        $stub = str_replace('{{serviceInterfaceName}}', $this->serviceInterfaceName, $stub);
246
        $stub = str_replace('{{serviceClassName}}', $this->serviceClassName, $stub);
247
248 View Code Duplication
        if ( $this->repositoryName )
249
        {
250
            // Load the values for repository.
251
            $stub = str_replace('{{repositoryInterfaceFullName}}', $this->repositoryFullName, $stub);
252
            $stub = str_replace('{{repositoryInterfaceName}}', $this->repositoryName, $stub);
253
            $stub = str_replace('{{repositoryName}}', lcfirst( str_replace( 'Interface', '', $this->repositoryName ) ), $stub);
254
        }
255
256 View Code Duplication
        if ( $this->validatorClassName )
257
        {
258
            // Load the values for repository.
259
            $stub = str_replace('{{validatorInterfaceNamespace}}', $this->validatorInterfaceNamespace, $stub);
260
            $stub = str_replace('{{validatorInterface}}', $this->validatorInterfaceName, $stub);
261
            $stub = str_replace('{{validatorName}}', lcfirst( str_replace( 'Interface', '', $this->validatorInterfaceName ) ), $stub);
262
        }
263
264
        return $stub;
265
    }
266
267
    /**
268
     * @return mixed|string
269
     */
270
    protected function compileServiceProvider()
271
    {
272 View Code Duplication
        if ( $this->validatorClassName )
273
        {
274
            $stub = $this->filesystem->get(__DIR__ . '/../stubs/service-provider-w-validator.stub');
275
        } else
276
        {
277
            $stub = $this->filesystem->get(__DIR__ . '/../stubs/service-provider.stub');
278
        }
279
280
        $serviceProviderClassName = $this->getServiceProviderName();
281
282
        $stub = str_replace('{{serviceProviderClassName}}', $serviceProviderClassName, $stub);
283
        $stub = str_replace('{{serviceInterfaceNamespace}}', $this->serviceNamespace, $stub);
284
        $stub = str_replace('{{serviceInterfaceName}}', $this->serviceInterfaceName, $stub);
285
        $stub = str_replace('{{serviceClassName}}', $this->serviceClassName, $stub);
286
287
        if ( $this->validatorClassName )
288
        {
289
            // Load the values for repository.
290
            $stub = str_replace('{{validatorInterfaceNamespace}}', $this->validatorInterfaceNamespace, $stub);
291
            $stub = str_replace('{{validatorInterface}}', $this->validatorInterfaceName, $stub);
292
            $stub = str_replace('{{validatorClass}}', $this->validatorClassName, $stub);
293
        }
294
295
        return $stub;
296
    }
297
298
    /**
299
     * @return mixed|string
300
     */
301
    protected function compileValidatorInterface()
302
    {
303
        $stub = $this->filesystem->get(__DIR__ . '/../stubs/validator-interface.stub');
304
305
        $stub = str_replace('{{validatorInterfaceNamespace}}', $this->validatorInterfaceNamespace, $stub);
306
        $stub = str_replace('{{validatorInterface}}', $this->validatorInterfaceName, $stub);
307
308
        return $stub;
309
    }
310
311
    /**
312
     * @return mixed|string
313
     */
314
    protected function compileValidator()
315
    {
316
        $stub = $this->filesystem->get(__DIR__ . '/../stubs/validator.stub');
317
318
        $stub = str_replace('{{validatorInterfaceNamespace}}', $this->validatorInterfaceNamespace, $stub);
319
        $stub = str_replace('{{validatorInterface}}', $this->validatorInterfaceName, $stub);
320
        $stub = str_replace('{{validatorClass}}', $this->validatorClassName, $stub);
321
322
        return $stub;
323
    }
324
325
326
    /**
327
     * @param $path
328
     */
329
    protected function makeDirectory( $path )
330
    {
331
        if ( !$this->filesystem->isDirectory( $path ) )
332
        {
333
            $this->filesystem->makeDirectory( $path, 0775, true, true);
334
        }
335
    }
336
337
    /**
338
     * @return string
339
     */
340
    public function getServiceProviderName()
341
    {
342
        return $this->serviceClassName.'ServiceProvider';
343
    }
344
}