ScaffoldController::store()   F
last analyzed

Complexity

Conditions 20
Paths > 20000

Size

Total Lines 159
Code Lines 100

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 20
eloc 100
nc 94840
nop 1
dl 0
loc 159
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: sheldon
5
 * Date: 18-4-25
6
 * Time: 下午3:25.
7
 */
8
9
namespace Yeelight\Http\Controllers\Backend\Tools\Scaffold;
10
11
use Illuminate\Filesystem\Filesystem;
12
use Illuminate\Http\Request;
13
use Illuminate\Support\Facades\Artisan;
14
use Illuminate\Support\Facades\URL;
15
use Illuminate\Support\MessageBag;
16
use Illuminate\Support\Str;
17
use Yeelight\Http\Controllers\BaseController;
18
19
/**
20
 * Class ScaffoldController
21
 *
22
 * @category Yeelight
23
 *
24
 * @package Yeelight\Http\Controllers\Backend\Tools\Scaffold
25
 *
26
 * @author Sheldon Lee <[email protected]>
27
 *
28
 * @license https://opensource.org/licenses/MIT MIT
29
 *
30
 * @link https://www.yeelight.com
31
 */
32
class ScaffoldController extends BaseController
33
{
34
    /**
35
     * 主页.
36
     *
37
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
38
     */
39
    public function index()
40
    {
41
        $dbTypes = [
42
            'string',
43
            'integer',
44
            'text',
45
            'float',
46
            'double',
47
            'decimal',
48
            'boolean',
49
            'date',
50
            'time',
51
            'dateTime',
52
            'timestamp',
53
            'char',
54
            'mediumText',
55
            'longText',
56
            'tinyInteger',
57
            'smallInteger',
58
            'mediumInteger',
59
            'bigInteger',
60
            'unsignedTinyInteger',
61
            'unsignedSmallInteger',
62
            'unsignedMediumInteger',
63
            'unsignedInteger',
64
            'unsignedBigInteger',
65
            'enum',
66
            'json',
67
            'jsonb',
68
            'dateTimeTz',
69
            'timeTz',
70
            'timestampTz',
71
            'nullableTimestamps',
72
            'binary',
73
            'ipAddress',
74
            'macAddress',
75
        ];
76
        $action = URL::current();
77
78
        return view('backend.tools.scaffold.index', [
79
            'header_description' => '脚手架',
80
            'dbTypes'            => $dbTypes,
81
            'action'             => $action,
82
        ]);
83
    }
84
85
    public function store(Request $request)
86
    {
87
        $paths = [];
88
        $message = '';
89
90
        try {
91
            $model_name = Str::camel(
92
                ucfirst(str_singular(lcfirst(ucwords($request->get('model_name')))))
93
            );
94
95
            $force = false;
96
            if (in_array('force', $request->get('create'))) {
97
                $force = true;
98
            }
99
100
            $presenter = $validator = 'no';
101
            $fillable = $rules = '';
102
            $fields = $request->get('fields');
103
104
            if (!empty($fields)) {
105
                foreach ($fields as $index => $field) {
106
                    if ($field['name'] && $field['type']) {
107
                        $fillable .= $field['name'].':'.$field['type'];
108
                        if (isset($field['nullable'])) {
109
                            $fillable .= ':nullable()';
110
                        }
111
                        if ($field['key']) {
112
                            $fillable .= ':'.$field['key'];
113
                        }
114
                        if ($field['default']) {
115
                            $fillable .= ':default'."('{$field['default']}')";
116
                        }
117
                        if ($field['comment']) {
118
                            $fillable .= ':comment'."('{$field['comment']}')";
119
                        }
120
                        $fillable .= ',';
121
                        if ($field['rule']) {
122
                            $rules .= $field['name'].'=>'.$field['rule'].',';
123
                        }
124
                    }
125
                }
126
            }
127
128
            $fillable = rtrim($fillable, ',');
129
130
            $rules = rtrim($rules, ',');
131
132
            // 1. Create presenter.
133
            if (in_array('presenter', $request->get('create'))) {
134
                Artisan::call('yl:presenter', [
135
                    'name'    => $model_name,
136
                    '--force' => $force,
137
                ]);
138
                $paths['presenters'] = $this->getBasePath().'/'.$this->getConfigGeneratorClassPath('presenters', true).'/'.$this->getName($model_name).'Presenter.php';
139
140
                Artisan::call('yl:transformer', [
141
                    'name'     => $model_name,
142
                    '--fields' => $fields,
143
                    '--force'  => $force,
144
                ]);
145
                $paths['transformers'] = $this->getBasePath().'/'.$this->getConfigGeneratorClassPath('transformers', true).'/'.$this->getName($model_name).'Transformer.php';
146
147
                $presenter = 'yes';
148
            }
149
150
            // 2. Create validator.
151
            if (in_array('validator', $request->get('create'))) {
152
                Artisan::call('yl:validator', [
153
                    'name'    => $model_name,
154
                    '--rules' => $rules,
155
                    '--force' => $force,
156
                ]);
157
                $paths['validators'] = $this->getBasePath().'/'.$this->getConfigGeneratorClassPath('validators', true).'/'.$this->getName($model_name).'Validator.php';
158
                $validator = 'yes';
159
            }
160
161
            // 3. Create controller.
162
            if (in_array('controller', $request->get('create'))) {
163
                Artisan::call('yl:controller', [
164
                    'name'     => $model_name,
165
                    '--fields' => $fields,
166
                    '--force'  => $force,
167
                ]);
168
                $paths['controllers'] = $this->getBasePath().'/'.$this->getConfigGeneratorClassPath('controllers', true).'/'.Str::plural($this->getName($model_name)).'Controller.php';
169
                $paths['create_request'] = $this->getBasePath().'/Http/Requests/'.$this->getName($model_name).'CreateRequest.php';
170
                $paths['update_request'] = $this->getBasePath().'/Http/Requests/'.$this->getName($model_name).'UpdateRequest.php';
171
            }
172
173
            // 4. Create views.
174
            if (in_array('views', $request->get('create'))) {
175
                Artisan::call('yl:views', [
176
                    'name'     => $model_name,
177
                    '--fields' => $fields,
178
                    '--force'  => $force,
179
                ]);
180
                $paths['views_index'] = resource_path($this->getConfigGeneratorClassPath('views', true)).'/'.$this->getSnakeName($model_name).'/index.blade.php';
181
                $paths['views_create'] = resource_path($this->getConfigGeneratorClassPath('views', true)).'/'.$this->getSnakeName($model_name).'/create.blade.php';
182
                $paths['views_edit'] = resource_path($this->getConfigGeneratorClassPath('views', true)).'/'.$this->getSnakeName($model_name).'/edit.blade.php';
183
            }
184
185
            // 5. Create language package.
186
            if (in_array('lang', $request->get('create'))) {
187
                Artisan::call('yl:lang', [
188
                    'name'     => $model_name,
189
                    '--fields' => $fields,
190
                    '--force'  => $force,
191
                ]);
192
                $filesystem = new Filesystem();
193
                $directories = $filesystem->directories(resource_path($this->getConfigGeneratorClassPath('lang', true)));
194
                foreach ($directories as $index => $directory) {
195
                    $paths['lang_'.$index] = $directory.'/'.$this->getSnakeName($model_name).'.php';
196
                }
197
            }
198
199
            // 6. Create api controller.
200
            if (in_array('api_controller', $request->get('create'))) {
201
                Artisan::call('yl:api_controller', [
202
                    'name'     => $model_name,
203
                    '--fields' => $fields,
204
                    '--force'  => $force,
205
                ]);
206
                $paths['api_controllers'] = $this->getBasePath().'/'.$this->getConfigGeneratorClassPath('api_controllers', true).'/'.Str::plural($this->getName($model_name)).'Controller.php';
207
                $paths['api_create_request'] = $this->getBasePath().'/Http/Requests/Api/'.$this->getName($model_name).'CreateRequest.php';
208
                $paths['api_update_request'] = $this->getBasePath().'/Http/Requests/Api/'.$this->getName($model_name).'UpdateRequest.php';
209
            }
210
211
            //7. Create repository
212
            Artisan::call('yl:repository', [
213
                'name'        => $model_name,
214
                '--fillable'  => $fillable,
215
                '--rules'     => $rules,
216
                '--fields'    => $fields,
217
                '--validator' => $validator,
218
                '--presenter' => $presenter,
219
                '--force'     => $force,
220
            ]);
221
            $paths['repositories'] = $this->getBasePath().'/'.$this->getConfigGeneratorClassPath('repositories', true).'/'.$this->getName($model_name).'RepositoryEloquent.php';
222
            $paths['interfaces'] = $this->getBasePath().'/'.$this->getConfigGeneratorClassPath('interfaces', true).'/'.$this->getName($model_name).'Repository.php';
223
            $paths['models'] = $this->getBasePath().'/'.$this->getConfigGeneratorClassPath('models', true).'/'.($model_name).'.php';
224
225
            //8. Bind repository
226
            Artisan::call('yl:bindings', [
227
                'name'    => $model_name,
228
                '--force' => $force,
229
            ]);
230
231
            // 9. Run migrate.
232
            if (in_array('migrate', $request->get('create'))) {
233
                Artisan::call('migrate');
234
                $message = Artisan::output();
235
            }
236
        } catch (\Exception $exception) {
237
            // Delete generated files if exception thrown.
238
            app('files')->delete($paths);
239
240
            return $this->backWithException($exception);
241
        }
242
243
        return $this->backWithSuccess($model_name, $paths, $message);
244
    }
245
246
    protected function backWithException(\Exception $exception)
247
    {
248
        $error = new MessageBag([
249
            'title'   => 'Error',
250
            'message' => $exception->getMessage()."\n Please delete the migration files",
251
        ]);
252
253
        return back()->withInput()->with(compact('error'));
254
    }
255
256
    protected function backWithSuccess($model_name, $paths, $message)
257
    {
258
        $messages = [];
259
        foreach ($paths as $name => $path) {
260
            $messages[] = ucfirst($name).": $path";
261
        }
262
        $messages[] = 'Migrations: '.database_path('migrations').'/'.date('Y_m_d').'_xxxxxx_create_'.$this->getSnakeName($model_name).'.php';
263
        $messages[] = "<br />$message";
264
        $success = new MessageBag([
265
            'title'   => 'Success',
266
            'message' => implode('<br />', $messages),
267
        ]);
268
269
        return back()->with(compact('success'));
270
    }
271
272
    /**
273
     * Get base path of destination file.
274
     *
275
     * @return string
276
     */
277
    public function getBasePath()
278
    {
279
        return config('repository.generator.basePath', app_path());
280
    }
281
282
    /**
283
     * Get name input.
284
     *
285
     * @param $name
286
     *
287
     * @return string
288
     */
289
    public function getName($name)
290
    {
291
        if (str_contains($name, '\\')) {
292
            $name = str_replace('\\', '/', $name);
293
        }
294
        if (str_contains($name, '/')) {
295
            $name = str_replace('/', '/', $name);
296
        }
297
298
        return Str::studly(str_replace(' ', '/', ucwords(str_replace('/', ' ', $name))));
299
    }
300
301
    /**
302
     * Get name input.
303
     *
304
     * @param $name
305
     *
306
     * @return string
307
     */
308
    public function getSnakeName($name)
309
    {
310
        if (str_contains($name, '\\')) {
311
            $name = str_replace('\\', '/', $name);
312
        }
313
        if (str_contains($name, '/')) {
314
            $name = str_replace('/', '/', $name);
315
        }
316
317
        return Str::plural(Str::snake(str_replace(' ', '/', ucwords(str_replace('/', ' ', $name)))));
318
    }
319
320
    /**
321
     * Get class-specific output paths.
322
     *
323
     * @param $class
324
     *
325
     * @return string
326
     */
327
    private function getConfigGeneratorClassPath($class, $directoryPath = false)
328
    {
329
        switch ($class) {
330
            case 'models' === $class:
331
                $path = config('repository.generator.paths.models', 'Entities');
332
                break;
333
            case 'repositories' === $class:
334
                $path = config('repository.generator.paths.repositories', 'Repositories');
335
                break;
336
            case 'interfaces' === $class:
337
                $path = config('repository.generator.paths.interfaces', 'Repositories');
338
                break;
339
            case 'presenters' === $class:
340
                $path = config('repository.generator.paths.presenters', 'Presenters');
341
                break;
342
            case 'transformers' === $class:
343
                $path = config('repository.generator.paths.transformers', 'Transformers');
344
                break;
345
            case 'validators' === $class:
346
                $path = config('repository.generator.paths.validators', 'Validators');
347
                break;
348
            case 'controllers' === $class:
349
                $path = config('repository.generator.paths.controllers', 'Http\Controllers');
350
                break;
351
            case 'api_controllers' === $class:
352
                $path = config('repository.generator.paths.api_controllers', 'Http/Controllers/Api/Controllers');
353
                break;
354
            case 'provider' === $class:
355
                $path = config('repository.generator.paths.provider', 'RepositoryServiceProvider');
356
                break;
357
            case 'criteria' === $class:
358
                $path = config('repository.generator.paths.criteria', 'Criteria');
359
                break;
360
            case 'views' === $class:
361
                $path = config('repository.generator.paths.views', 'views');
362
                break;
363
            case 'lang' === $class:
364
                $path = config('repository.generator.paths.criteria', 'lang');
365
                break;
366
            default:
367
                $path = '';
368
        }
369
370
        if ($directoryPath) {
371
            $path = str_replace('\\', '/', $path);
372
        } else {
373
            $path = str_replace('/', '\\', $path);
374
        }
375
376
        return $path;
377
    }
378
}
379