Generator::makeRepositoryPatternFiles()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 1 Features 1
Metric Value
cc 1
eloc 21
c 8
b 1
f 1
nc 1
nop 1
dl 0
loc 27
rs 9.584
1
<?php
2
3
namespace Shamaseen\Repository\Generator\Commands;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Support\Facades\Config;
8
use Illuminate\Support\Str;
9
use ReflectionClass;
10
use ReflectionException;
11
use Shamaseen\Repository\Generator\Forms\FormGenerator;
12
13
/**
14
 * Class RepositoryGenerator.
15
 */
16
class Generator extends Command
17
{
18
    /**
19
     * The name and signature of the console command.
20
     *
21
     * @var string
22
     */
23
    protected $signature = 'make:repository
24
    {name : Class (singular) for example User} {--only-view}';
25
26
    /**
27
     * The console command description.
28
     *
29
     * @var string
30
     */
31
    protected $description = 'Create repository generator';
32
33
    /**
34
     * The repository name.
35
     *
36
     * @var string
37
     */
38
    protected $repoName;
39
    /**
40
     * The repository name space.
41
     *
42
     * @var FormGenerator
43
     */
44
    private $FormGenerator;
45
46
    /**
47
     * Create a new command instance.
48
     */
49
    public function __construct()
50
    {
51
        parent::__construct();
52
        $this->FormGenerator = new FormGenerator();
53
    }
54
55
    /**
56
     * Execute the console command.
57
     *
58
     * @throws ReflectionException
59
     */
60
    public function handle()
61
    {
62
        $file = preg_split(' ([/\\\]) ', (string)$this->argument('name')) ?? [];
63
64
        if (!$file) {
65
            return 'Something wrong with the inputs !';
66
        }
67
68
        $this->repoName = $file[count($file) - 1];
69
70
        unset($file[count($file) - 1]);
71
        $path = implode('\\', $file);
72
73
        if ($this->option('only-view')) {
74
            $this->makeViewsAndLanguage($path);
75
            $this->dumpAutoload();
76
            return true;
77
        }
78
79
        return $this->makeRepositoryPatternFiles($path);
80
    }
81
82
    public function makeRepositoryPatternFiles($path): bool
83
    {
84
        $model = Str::plural(Config::get('repository.model', 'Entity'));
85
        $interface = Str::plural(Config::get('repository.interface', 'Interface'));
86
        $repository = Str::plural(Config::get('repository.repository', 'Repository'));
87
        $controller = Config::get('repository.controllers_folder', 'Http\Controllers');
88
        $request = Config::get('repository.requests_folder', 'Http\Requests');
89
        $resource = Config::get('repository.resources_folder', 'Http\Resources');
90
91
        $base = "Shamaseen\Repository\Generator\Utility";
92
        $modelBase = Config::get('repository.base_model', "$base\Entity");
93
        $interfaceBase = Config::get('repository.base_interface', "$base\ContractInterface");
94
        $repositoryBase = Config::get('repository.base_repository', "$base\AbstractRepository");
95
        $controllerBase = Config::get('repository.base_controller', "$base\Controller");
96
        $requestBase = Config::get('repository.base_request', "$base\Request");
97
        $resourceBase = Config::get('repository.base_resource', "$base\JsonResource");
98
99
        $this->generate($path, $controller, 'Controller', '', $controllerBase);
100
        $this->generate($path, $resource, 'Resource', '', $resourceBase);
101
        $this->generate($path, $model, 'Entity', '', $modelBase);
102
        $this->generate($path, $request, 'Request', '', $requestBase);
103
        $this->generate($path, $interface, 'Interface', '', $interfaceBase);
104
        $this->generate($path, $repository, 'Repository', '', $repositoryBase);
105
106
        $this->dumpAutoload();
107
108
        return true;
109
    }
110
111
    /**
112
     * @param $path
113
     *
114
     * @throws ReflectionException
115
     */
116
    public function makeViewsAndLanguage($path)
117
    {
118
        $entity = $this->getEntity($path);
119
120
        $createHtml = '';
121
        $editHtml = '';
122
        if ($entity instanceof Model) {
123
            $createHtml = $this->FormGenerator->generateForm($entity);
124
            $editHtml = $this->FormGenerator->generateForm($entity, 'put');
125
        } else {
126
            $message = "There is no entity for $this->repoName, 
127
                        do you want to continue (this will disable form generator) ?";
128
            if (!$this->confirm($message)) {
129
                echo 'Dispatch ..';
130
                die;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
131
            }
132
        }
133
        $repositoryName = lcfirst($this->repoName);
134
        $viewsPath = Config::get('repository.resources_path') . '/views';
135
        $languagePath = Config::get('repository.lang_path');
136
137
        foreach (Config::get('repository.languages') as $lang) {
138
            $this->generate($repositoryName, $languagePath . $lang, 'lang');
139
        }
140
141
        $this->generate($repositoryName, $viewsPath, 'create', $createHtml);
142
        $this->generate($repositoryName, $viewsPath, 'edit', $editHtml);
143
        $this->generate($repositoryName, $viewsPath, 'index');
144
        $this->generate($repositoryName, $viewsPath, 'show');
145
    }
146
147
    /**
148
     * @param $path
149
     *
150
     * @return bool|object
151
     * @throws ReflectionException
152
     *
153
     */
154
    public function getEntity($path)
155
    {
156
        $myClass = 'App\Entities\\' . $path . '\\' . $this->repoName;
157
        if (!class_exists($myClass)) {
158
            return false;
159
        }
160
161
        $reflect = new ReflectionClass($myClass);
162
163
        return $reflect->newInstance();
164
    }
165
166
    /**
167
     * Get stub content to generate needed files.
168
     *
169
     * @param string $type determine which stub should choose to get content
170
     *
171
     * @return false|string
172
     */
173
    protected function getStub(string $type)
174
    {
175
        return file_get_contents(Config::get('repository.stubs_path') . "/$type.stub");
176
    }
177
178
    /**
179
     * @param string $path Class path
180
     * @param string $folder default path to generate in
181
     * @param string $type define which kind of files should generate
182
     * @param string $form
183
     * @param string $base
184
     *
185
     * @return bool
186
     */
187
    protected function generate(string $path, string $folder, string $type, string $form = '', string $base = ''): bool
188
    {
189
        $path = $path ? '\\' . $path : '';
190
        $content = $this->getStub($type);
191
192
        if (false === $content) {
193
            echo 'file ' . $type . '.stub is not exist !';
194
195
            return false;
196
        }
197
198
        $template = str_replace(
199
            [
200
                '{{base}}',
201
                '{{modelName}}',
202
                '{{lcPluralModelName}}',
203
                '{{folder}}',
204
                '{{path}}',
205
                '{{modelBaseFolderName}}',
206
                '{{interfaceBaseFolderName}}',
207
                '{{form}}',
208
            ],
209
            [
210
                $base,
211
                $this->repoName,
212
                Str::plural(lcfirst($this->repoName)),
213
                Str::plural($folder),
214
                $path,
215
                Str::plural(Config::get('repository.model', 'Entity')),
216
                Str::plural(Config::get('repository.interface', 'Interface')),
217
                $form,
218
            ],
219
            $content
220
        );
221
222
        $folder = str_replace('\\', '/', $folder);
223
        $path = str_replace('\\', '/', $path);
224
        $this->type($type, $folder, $path, $template);
225
226
        return true;
227
    }
228
229
    /**
230
     * Check if folder exist.
231
     *
232
     * @param string $path class path
233
     *
234
     * @return string
235
     */
236
    public function getFolderOrCreate(string $path): string
237
    {
238
        if (!file_exists($path)) {
239
            mkdir($path, 0777, true);
240
        }
241
242
        return $path;
243
    }
244
245
    /**
246
     * @param string $path Class path
247
     * @param string $folder default path to generate in
248
     * @param string $type define which kind of files should generate
249
     * @param string $template temple file
250
     *
251
     */
252
    private function type(string $type, string $folder, string $path, string $template)
253
    {
254
        switch ($type) {
255
            case 'Entity':
256
                $filePath = $this->getFolderOrCreate(Config::get('repository.app_path') . "/$folder/$path");
257
                $filePath = rtrim($filePath, '/');
258
                $content = "$filePath/$this->repoName.php";
259
260
                break;
261
            case 'Controller':
262
            case 'Resource':
263
            case 'Request':
264
            case 'Repository':
265
            case 'Interface':
266
                $filePath = $this->getFolderOrCreate(Config::get('repository.app_path') . "/$folder/$path");
267
                $filePath = rtrim($filePath, '/');
268
                $content = "$filePath/{$this->repoName}$type.php";
269
                break;
270
            case 'create':
271
            case 'edit':
272
            case 'index':
273
            case 'show':
274
                $filePath = $this->getFolderOrCreate($folder . '/' . Str::plural($path)) . '/';
275
                $repoName = lcfirst($type);
276
                $content = $filePath . $repoName . '.blade.php';
277
                break;
278
            default:
279
                $filePath = $this->getFolderOrCreate($folder) . '/';
280
                $repoName = lcfirst($this->repoName);
281
                $content = $filePath . $repoName . '.php';
282
        }
283
284
        if (is_dir($filePath) && file_exists($content)) {
285
            // Ask to replace exiting file
286
            if (!$this->confirm("This file, $content already exit, do you want to replace?")) {
287
                $this->line('File Not Replaced');
288
                return;
289
            }
290
        }
291
292
        file_put_contents($content, $template);
293
    }
294
295
    private function dumpAutoload()
296
    {
297
        shell_exec('composer dump-autoload');
298
    }
299
}
300