Completed
Push — master ( 08375c...9f214f )
by Mohamed
11:05
created

ResourceCommand::buildDatatableColumns()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
cc 3
nc 3
nop 0
1
<?php
2
3
namespace Microboard\Commands;
4
5
use Illuminate\Contracts\Filesystem\FileNotFoundException;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Str;
8
use Facades\Microboard\Factory;
9
use Microboard\Models\Role;
10
11
class ResourceCommand extends WorkingWithStubs
12
{
13
    /**
14
     * The name and signature of the console command.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'microboard:resource
19
                            {model : The name of resource class}
20
                            {--views-directory=admin}
21
                            {--view-namespace=}
22
                            {--abilities=}';
23
24
    /**
25
     * The console command description.
26
     *
27
     * @var string
28
     */
29
    protected $description = 'Command description';
30
31
    protected $abilities = [
32
        'viewAny', 'view', 'create', 'update', 'delete'
33
    ];
34
35
    /**
36
     * Execute the console command.
37
     *
38
     * @return mixed
39
     */
40
    public function handle()
41
    {
42
        $model = $this->qualifyClass($this->getNameInput());
43
        $this->setVariables($model);
44
45
        // Create permissions for this resource.
46
        if ($this->hasOption('abilities')) {
47
            $this->abilities = explode(',', $this->option('abilities'));
48
        }
49
50
        Factory::createResourcesPermissionsFor(Role::first(), [
51
            $this->variables['%RESOURCE_NAME_PLURAL%'] => $this->abilities
52
        ]);
53
54
        try {
55
            $this->createPolicy();
56
            $this->createLanguageFiles();
57
            $this->createDatatable();
58
            $this->createController();
59
            $this->createFormRequests();
60
            $this->createResourceViews();
61
        } catch (FileNotFoundException $e) {
62
            $this->error($e->getMessage());
63
        }
64
    }
65
66
    /**
67
     * Get the desired class name from the input.
68
     *
69
     * @return string
70
     */
71
    protected function getNameInput()
72
    {
73
        return trim($this->argument('model'));
74
    }
75
76
    /**
77
     * Set model variables
78
     *
79
     * @var string $model
80
     */
81
    public function setVariables($model)
82
    {
83
        $base_name = class_basename($model);
84
85
        $this->variables = [
86
            '%NAMESPACE%' => $this->rootNamespace(),
87
            '%RESOURCE_MODEL%' => $model,
88
            '%RESOURCE_MODEL_BASE%' => class_basename($model),
89
            '%RESOURCE_NAME_PLURAL%' => (string)Str::of($base_name)->snake()->plural(),
90
            '%RESOURCE_NAME_SINGULAR%' => (string)Str::of($base_name)->snake()->singular(),
91
            '%VIEW_NAMESPACE%' => $this->option('view-namespace'),
92
            '%VIEW_DIRECTORY%' => $this->option('views-directory') . '/' . ((string)Str::of($base_name)->snake()->plural()) . '/',
93
            '%BLADE_VIEW_DIRECTORY%' => ($this->hasOption('views-directory') ? ($this->option('views-directory') . '.') : '') .
94
                ((string)Str::of($base_name)->snake()->plural()),
95
        ];
96
    }
97
98
    /**
99
     * Create resource views
100
     *
101
     * @throws FileNotFoundException
102
     */
103
    private function createResourceViews()
104
    {
105
        $directory = 'resources/views/' . $this->variables['%VIEW_DIRECTORY%'];
106
107 View Code Duplication
        foreach (['index', 'show', 'edit', 'create'] as $view) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
108
            $this->createFromStub(
109
                __DIR__ . '/../../stubs/resource/' . $view . '.stub',
110
                $directory,
111
                $view . '.blade.php',
112
                array_merge($this->variables, ['%COLUMNS%' => $this->buildShowViewColumns()])
113
            );
114
        }
115
116
        $this->createFromStub(
117
            __DIR__ . '/../../stubs/resource/form.stub',
118
            $directory,
119
            'form.blade.php',
120
            array_merge($this->variables, ['%COLUMNS%' => $this->buildFormInputs()])
121
        );
122
123
        $this->info(sprintf(
124
            'Resource views created successfully, [%s]',
125
            $directory
126
        ));
127
    }
128
129
    /**
130
     * Create lang file for this model
131
     *
132
     * TODO:: Support multiple languages
133
     */
134 View Code Duplication
    private function createLanguageFiles()
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...
135
    {
136
        $this->createFromStub(
137
            __DIR__ . '/../../stubs/resource.stub',
138
            $directory = 'resources/lang/' . (config('app.locale')),
139
            $file = $this->variables['%RESOURCE_NAME_PLURAL%'] . '.php',
140
            array_merge($this->variables, ['%COLUMNS%' => $this->buildLanguageFilesColumns()])
141
        );
142
143
        $this->info(sprintf(
144
            'Resource languages file created successfully, [%s/%s]',
145
            $directory, $file
146
        ));
147
    }
148
149
    /**
150
     * Create datatable class
151
     */
152 View Code Duplication
    private function createDatatable()
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...
153
    {
154
        $this->createFromStub(
155
            __DIR__ . '/../../stubs/resource-datatable.stub',
156
            $directory = 'app/DataTables/',
157
            $file = Str::studly($this->variables['%RESOURCE_NAME_SINGULAR%'] . 'DataTable') . '.php',
158
            array_merge($this->variables, ['%COLUMNS%' => $this->buildDatatableColumns()])
159
        );
160
161
        $this->info(sprintf(
162
            'Datatable class created successfully, [%s%s]',
163
            $directory, $file
164
        ));
165
    }
166
167
    /**
168
     * Create controller class
169
     */
170
    private function createController()
171
    {
172
        $this->createFromStub(
173
            __DIR__ . '/../../stubs/resource-controller.stub',
174
            $directory = 'app/Http/Controllers/',
175
            $file = Str::studly($this->variables['%RESOURCE_NAME_SINGULAR%'] . 'Controller') . '.php',
176
            $this->variables
177
        );
178
179
        $this->info(sprintf(
180
            'Controller created successfully, [%s%s]',
181
            $directory, $file
182
        ));
183
    }
184
185
    /**
186
     * Create form request classes
187
     */
188
    private function createFormRequests()
189
    {
190
        $directory = 'app/Http/Requests/' . $this->variables['%RESOURCE_MODEL_BASE%'] . '/';
191
192 View Code Duplication
        foreach (['store', 'update'] as $method) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
193
            $this->createFromStub(
194
                __DIR__ . '/../../stubs/' . $method . '-resource-form-request.stub',
195
                $directory,
196
                Str::studly($method . 'FormRequest') . '.php',
197
                array_merge($this->variables, ['%COLUMNS%' => $this->buildFormRequestColumns()])
198
            );
199
        }
200
201
        $this->info(sprintf(
202
            'Form requests created successfully, [%s]',
203
            $directory
204
        ));
205
    }
206
207
    /**
208
     * Create policy class
209
     */
210
    private function createPolicy()
211
    {
212
        $this->createFromStub(
213
            __DIR__ . '/../../stubs/resource-policy.stub',
214
            $directory = 'app/Policies/',
215
            $file = Str::studly($this->variables['%RESOURCE_MODEL_BASE%'] . 'Policy') . '.php',
216
            $this->variables
217
        );
218
219
        $this->info(sprintf(
220
            'Form requests created successfully, [%s%s]',
221
            $directory, $file
222
        ));
223
    }
224
225
    /**
226
     * get fillable columns from given model
227
     *
228
     * @return array
229
     */
230
    private function getModelColumns()
231
    {
232
        return (new $this->variables['%RESOURCE_MODEL%'])->getFillable();
233
    }
234
235
    /**
236
     * build resource's columns as html from form-input.stub
237
     *
238
     * @return string
239
     *
240
     * @throws FileNotFoundException
241
     */
242
    private function buildFormInputs()
243
    {
244
        $columns = '';
245
246
        foreach ($this->getModelColumns() as $column) {
247
            if (in_array($column, (new $this->variables['%RESOURCE_MODEL%'])->getHidden())) {
248
                continue;
249
            }
250
251
            $this->variables['%COLUMN_NAME%'] = $column;
252
253
            $variables = Arr::only($this->variables, [
254
                '%RESOURCE_NAME_SINGULAR%', '%VIEW_NAMESPACE%', '%RESOURCE_NAME_PLURAL%', '%COLUMN_NAME%'
255
            ]);
256
257
            $columns .= str_replace(
258
                array_keys($variables),
259
                array_values($variables),
260
                $this->files->get(__DIR__ . '/../../stubs/resource/form-input.stub')
261
            );
262
        }
263
264
        return $columns;
265
    }
266
267
    /**
268
     * build resource's columns as html table's tr
269
     *
270
     * @return string
271
     */
272
    private function buildShowViewColumns()
273
    {
274
        $transPrefix = $this->variables['%VIEW_NAMESPACE%'] . $this->variables['%RESOURCE_NAME_PLURAL%'];
275
        $columns = '';
276
277
        foreach ($this->getModelColumns() as $column) {
278
            if (in_array($column, (new $this->variables['%RESOURCE_MODEL%'])->getHidden())) {
279
                continue;
280
            }
281
282
            $columns .= "\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th style=\"width: 25%;\">@lang('{$transPrefix}.fields.{$column}')</th>" .
283
                "\n\t\t\t\t\t\t\t\t<td>{{ \${$this->variables['%RESOURCE_NAME_SINGULAR%']}->{$column} }}</td>".
284
                "\n\t\t\t\t\t\t\t</tr>";
285
        }
286
287
        return $columns;
288
    }
289
290
    /**
291
     * build resource's columns as key => [validations]
292
     * TODO:: Guess the input validations
293
     *
294
     * @return string
295
     */
296
    private function buildFormRequestColumns()
297
    {
298
        $columns = '';
299
300
        foreach ($this->getModelColumns() as $column) {
301
            $columns .= "\n\t\t\t'{$column}' => ['required'],";
302
        }
303
304
        return $columns;
305
    }
306
307
    /**
308
     * build resource's columns as DataTables's Column::make() api
309
     *
310
     * @return string
311
     */
312
    private function buildDatatableColumns()
313
    {
314
        $transPrefix = $this->variables['%VIEW_NAMESPACE%'] . $this->variables['%RESOURCE_NAME_PLURAL%'];
315
        $columns = "\n\t\t\tColumn::make('id')->title(trans('{$transPrefix}.fields.id'))->width('1%'),";
316
317
        foreach ($this->getModelColumns() as $column) {
318
            if (in_array($column, (new $this->variables['%RESOURCE_MODEL%'])->getHidden())) {
319
                continue;
320
            }
321
322
            $columns .= "\n\t\t\tColumn::make('{$column}')->title(trans('{$transPrefix}.fields.{$column}')),";
323
        }
324
325
        return $columns;
326
    }
327
328
    /**
329
     * build resource's columns as key => Value
330
     *
331
     * @return string
332
     */
333
    private function buildLanguageFilesColumns()
334
    {
335
        $columns = '';
336
337
        foreach ($this->getModelColumns() as $column) {
338
            if (in_array($column, (new $this->variables['%RESOURCE_MODEL%'])->getHidden())) {
339
                continue;
340
            }
341
342
            $title = Str::of($column)->title()->replace('_', ' ');
343
            $columns .= "\n\t\t'{$column}' => '{$title}',";
344
        }
345
346
        return $columns;
347
    }
348
}
349