• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

RonasIT / laravel-entity-generator / 13687345998

05 Mar 2025 11:07PM UTC coverage: 96.94%. Remained the same
13687345998

Pull #138

github

web-flow
Merge c3e6f790d into 9f146920e
Pull Request #138: chore(deps): bump laravel/framework from 11.31.0 to 11.44.1

887 of 915 relevant lines covered (96.94%)

5.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.12
/src/Commands/MakeEntityCommand.php
1
<?php
2

3
namespace RonasIT\Support\Commands;
4

5
use Illuminate\Console\Command;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Facades\Config;
8
use Illuminate\Support\Str;
9
use RonasIT\Support\Events\SuccessCreateMessage;
10
use RonasIT\Support\Events\WarningEvent;
11
use RonasIT\Support\Exceptions\ClassNotExistsException;
12
use RonasIT\Support\Exceptions\EntityCreateException;
13
use RonasIT\Support\Generators\ControllerGenerator;
14
use RonasIT\Support\Generators\EntityGenerator;
15
use RonasIT\Support\Generators\FactoryGenerator;
16
use RonasIT\Support\Generators\MigrationGenerator;
17
use RonasIT\Support\Generators\ModelGenerator;
18
use RonasIT\Support\Generators\NovaResourceGenerator;
19
use RonasIT\Support\Generators\NovaTestGenerator;
20
use RonasIT\Support\Generators\RepositoryGenerator;
21
use RonasIT\Support\Generators\RequestsGenerator;
22
use RonasIT\Support\Generators\ResourceGenerator;
23
use RonasIT\Support\Generators\ServiceGenerator;
24
use RonasIT\Support\Generators\TestsGenerator;
25
use RonasIT\Support\Generators\TranslationsGenerator;
26
use RonasIT\Support\Generators\SeederGenerator;
27
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
28
use UnexpectedValueException;
29

30
/**
31
 * @property ControllerGenerator $controllerGenerator
32
 * @property MigrationGenerator $migrationGenerator
33
 * @property ModelGenerator $modelGenerator
34
 * @property RepositoryGenerator $repositoryGenerator
35
 * @property RequestsGenerator $requestsGenerator
36
 * @property ServiceGenerator $serviceGenerator
37
 * @property FactoryGenerator $factoryGenerator
38
 * @property TestsGenerator $testGenerator
39
 * @property TranslationsGenerator $translationsGenerator
40
 * @property SeederGenerator $seederGenerator
41
 * @property ResourceGenerator $resourceGenerator
42
 * @property NovaResourceGenerator $novaResourceGenerator
43
 * @property NovaTestGenerator $novaTestGenerator
44
 * @property EventDispatcher $eventDispatcher
45
 */
46
class MakeEntityCommand extends Command
47
{
48
    const CRUD_OPTIONS = [
49
        'C', 'R', 'U', 'D'
50
    ];
51

52
    /**
53
     * The name and signature of the console command.
54
     *
55
     * @var string
56
     */
57
    protected $signature = 'make:entity {name : The name of the entity. This name will use as name of models class.}
58
        
59
        {--only-api : Set this flag if you want to create resource, controller, route, requests, tests.}
60
        {--only-entity : Set this flag if you want to create migration, model, repository, service, factory, seeder.}
61
        {--only-model : Set this flag if you want to create only model. This flag is a higher priority than --only-migration, --only-tests and --only-repository.} 
62
        {--only-repository : Set this flag if you want to create only repository. This flag is a higher priority than --only-tests and --only-migration.}
63
        {--only-service : Set this flag if you want to create only service.}
64
        {--only-resource : Set this flag if you want to create only resource.}
65
        {--only-controller : Set this flag if you want to create only controller.}
66
        {--only-requests : Set this flag if you want to create only requests.}
67
        {--only-migration : Set this flag if you want to create only repository. This flag is a higher priority than --only-tests.}
68
        {--only-factory : Set this flag if you want to create only factory.}
69
        {--only-tests : Set this flag if you want to create only tests.}
70
        {--only-seeder : Set this flag if you want to create only seeder.}
71
        {--only-nova-resource : Set this flag if you want to create only nova resource.}
72
        {--only-nova-tests : Set this flag if you want to create only nova resource tests.}
73

74
        {--methods=CRUD : Set types of methods to create. Affect on routes, requests classes, controller\'s methods and tests methods.} 
75

76
        {--i|integer=* : Add integer field to entity.}
77
        {--I|integer-required=* : Add required integer field to entity. If you want to specify default value you have to do it manually.}
78
        {--f|float=* : Add float field to entity.}
79
        {--F|float-required=* : Add required float field to entity. If you want to specify default value you have to do it manually.}
80
        {--s|string=* : Add string field to entity. Default type is VARCHAR(255) but you can change it manually in migration.}
81
        {--S|string-required=* : Add required string field to entity. If you want to specify default value ir size you have to do it manually.}
82
        {--b|boolean=* : Add boolean field to entity.}
83
        {--B|boolean-required=* : Add boolean field to entity. If you want to specify default value you have to do it manually.}
84
        {--t|timestamp=* : Add timestamp field to entity.}
85
        {--T|timestamp-required=* : Add timestamp field to entity. If you want to specify default value you have to do it manually.}
86
        {--j|json=* : Add json field to entity.}
87
        
88
        {--a|has-one=* : Set hasOne relations between you entity and existed entity.}
89
        {--A|has-many=* : Set hasMany relations between you entity and existed entity.}
90
        {--e|belongs-to=* : Set belongsTo relations between you entity and existed entity.}
91
        {--E|belongs-to-many=* : Set belongsToMany relations between you entity and existed entity.}';
92

93
    /**
94
     * The console command description.
95
     *
96
     * @var string
97
     */
98
    protected $description = 'Make entity with Model, Repository, Service, Migration, Controller, Resource and Nova Resource.';
99

100
    protected $controllerGenerator;
101
    protected $migrationGenerator;
102
    protected $modelGenerator;
103
    protected $repositoryGenerator;
104
    protected $requestsGenerator;
105
    protected $serviceGenerator;
106
    protected $factoryGenerator;
107
    protected $testGenerator;
108
    protected $translationsGenerator;
109
    protected $seederGenerator;
110
    protected $resourceGenerator;
111
    protected $novaResourceGenerator;
112
    protected $novaTestGenerator;
113
    protected $eventDispatcher;
114

115
    protected $rules = [
116
        'only' => [
117
            'only-api' => [ResourceGenerator::class, ControllerGenerator::class, RequestsGenerator::class, TestsGenerator::class],
118
            'only-entity' => [MigrationGenerator::class, ModelGenerator::class, ServiceGenerator::class, RepositoryGenerator::class, FactoryGenerator::class, SeederGenerator::class],
119
            'only-model' => [ModelGenerator::class],
120
            'only-repository' => [RepositoryGenerator::class],
121
            'only-service' => [ServiceGenerator::class],
122
            'only-resource' => [ResourceGenerator::class],
123
            'only-controller' => [ControllerGenerator::class],
124
            'only-requests' => [RequestsGenerator::class],
125
            'only-migration' => [MigrationGenerator::class],
126
            'only-factory' => [FactoryGenerator::class],
127
            'only-tests' => [FactoryGenerator::class, TestsGenerator::class],
128
            'only-seeder' => [SeederGenerator::class],
129
            'only-nova-resource' => [NovaResourceGenerator::class],
130
            'only-nova-tests' => [NovaTestGenerator::class]
131
        ]
132
    ];
133

134
    public $generators = [
135
        ModelGenerator::class, RepositoryGenerator::class, ServiceGenerator::class, RequestsGenerator::class,
136
        ResourceGenerator::class, ControllerGenerator::class, MigrationGenerator::class, FactoryGenerator::class,
137
        TestsGenerator::class, TranslationsGenerator::class, SeederGenerator::class, NovaResourceGenerator::class,
138
        NovaTestGenerator::class
139
    ];
140

141
    public function __construct()
142
    {
143
        parent::__construct();
5✔
144

145
        $this->controllerGenerator = app(ControllerGenerator::class);
5✔
146
        $this->migrationGenerator = app(MigrationGenerator::class);
5✔
147
        $this->modelGenerator = app(ModelGenerator::class);
5✔
148
        $this->repositoryGenerator = app(RepositoryGenerator::class);
5✔
149
        $this->requestsGenerator = app(RequestsGenerator::class);
5✔
150
        $this->serviceGenerator = app(ServiceGenerator::class);
5✔
151
        $this->factoryGenerator = app(FactoryGenerator::class);
5✔
152
        $this->testGenerator = app(TestsGenerator::class);
5✔
153
        $this->translationsGenerator = app(TranslationsGenerator::class);
5✔
154
        $this->seederGenerator = app(SeederGenerator::class);
5✔
155
        $this->resourceGenerator = app(ResourceGenerator::class);
5✔
156
        $this->novaResourceGenerator = app(NovaResourceGenerator::class);
5✔
157
        $this->novaTestGenerator = app(NovaTestGenerator::class);
5✔
158
        $this->eventDispatcher = app(EventDispatcher::class);
5✔
159
    }
160

161
    /**
162
     * Execute the console command.
163
     *
164
     * @return void
165
     */
166
    public function handle(): void
167
    {
168
        $this->validateInput();
4✔
169
        $this->checkConfigs();
2✔
170

171
        $this->eventDispatcher->listen(
2✔
172
            events: SuccessCreateMessage::class,
2✔
173
            listener: fn (SuccessCreateMessage $event) => $this->info($event->message),
2✔
174
        );
2✔
175

176
        $this->eventDispatcher->listen(
2✔
177
            events: WarningEvent::class,
2✔
178
            listener: fn (WarningEvent $event) => $this->warn($event->message),
2✔
179
        );
2✔
180

181
        try {
182
            $this->generate();
2✔
183
        } catch (EntityCreateException $e) {
×
184
            $this->error($e->getMessage());
×
185
        }
186
    }
187

188
    protected function checkConfigs()
189
    {
190
        $packageConfigPath = __DIR__ . '/../../config/entity-generator.php';
2✔
191
        $packageConfigs = require $packageConfigPath;
2✔
192

193
        $projectConfigs = config('entity-generator');
2✔
194

195
        $newConfig = $this->outputNewConfig($packageConfigs, $projectConfigs);
2✔
196

197
        if ($newConfig !== $projectConfigs) {
2✔
198
            $this->comment('Config has been updated');
×
199
            Config::set('entity-generator', $newConfig);
×
200
            file_put_contents(config_path('entity-generator.php'), "<?php\n\nreturn" . $this->customVarExport($newConfig) . ';');
×
201
        }
202
    }
203

204
    protected function outputNewConfig($packageConfigs, $projectConfigs)
205
    {
206
        $flattenedPackageConfigs = Arr::dot($packageConfigs);
2✔
207
        $flattenedProjectConfigs = Arr::dot($projectConfigs);
2✔
208

209
        $newConfig = array_merge($flattenedPackageConfigs, $flattenedProjectConfigs);
2✔
210

211
        $differences = array_diff_key($newConfig, $flattenedProjectConfigs);
2✔
212

213
        foreach ($differences as $differenceKey => $differenceValue) {
2✔
214
            $this->comment("Key '{$differenceKey}' was missing in your config, we added it with the value '{$differenceValue}'");
×
215
        }
216

217
        return array_undot($newConfig);
2✔
218
    }
219

220
    protected function customVarExport($expression)
221
    {
222
        $defaultExpression = var_export($expression, true);
×
223

224
        $patterns = [
×
225
            '/array/' => '',
×
226
            '/\(/' => '[',
×
227
            '/\)/' => ']',
×
228
            '/=> \\n/' => '=>',
×
229
            '/=>.+\[/' => '=> [',
×
230
            '/^ {8}/m' => str_repeat(' ', 10),
×
231
            '/^ {6}/m' => str_repeat(' ', 8),
×
232
            '/^ {4}/m' => str_repeat(' ', 6),
×
233
            '/^ {2}/m' => str_repeat(' ', 4),
×
234
        ];
×
235

236
        return preg_replace(array_keys($patterns), array_values($patterns), $defaultExpression);
×
237
    }
238

239
    protected function classExists($path, $name)
240
    {
241
        $paths = config('entity-generator.paths');
1✔
242

243
        $entitiesPath = $paths[$path];
1✔
244

245
        $classPath = base_path("{$entitiesPath}/{$name}.php");
1✔
246

247
        return file_exists($classPath);
1✔
248
    }
249

250
    protected function validateInput()
251
    {
252
        $this->validateOnlyApiOption();
4✔
253
        $this->validateCrudOptions();
3✔
254
    }
255

256
    protected function generate()
257
    {
258
        foreach ($this->rules['only'] as $option => $generators) {
2✔
259
            if ($this->option($option)) {
2✔
260
                foreach ($generators as $generator) {
1✔
261
                    $this->runGeneration($generator);
1✔
262
                }
263

264
                return;
1✔
265
            }
266
        }
267

268
        foreach ($this->generators as $generator) {
1✔
269
            $this->runGeneration($generator);
1✔
270
        }
271
    }
272

273
    protected function runGeneration($generator)
274
    {
275
        app($generator)
2✔
276
            ->setModel($this->argument('name'))
2✔
277
            ->setFields($this->getFields())
2✔
278
            ->setRelations($this->getRelations())
2✔
279
            ->setCrudOptions($this->getCrudOptions())
2✔
280
            ->generate();
2✔
281
    }
282

283
    protected function getCrudOptions()
284
    {
285
        return str_split($this->option('methods'));
3✔
286
    }
287

288
    protected function getRelations()
289
    {
290
        return [
2✔
291
            'hasOne' => $this->option('has-one'),
2✔
292
            'hasMany' => $this->option('has-many'),
2✔
293
            'belongsTo' => $this->option('belongs-to'),
2✔
294
            'belongsToMany' => $this->option('belongs-to-many')
2✔
295
        ];
2✔
296
    }
297

298
    protected function getFields()
299
    {
300
        return Arr::only($this->options(), EntityGenerator::AVAILABLE_FIELDS);
2✔
301
    }
302

303
    protected function validateCrudOptions()
304
    {
305
        $crudOptions = $this->getCrudOptions();
3✔
306

307
        foreach ($crudOptions as $crudOption) {
3✔
308
            if (!in_array($crudOption, MakeEntityCommand::CRUD_OPTIONS)) {
3✔
309
                throw new UnexpectedValueException("Invalid method {$crudOption}.");
1✔
310
            }
311
        }
312
    }
313

314
    protected function validateOnlyApiOption()
315
    {
316
        if ($this->option('only-api')) {
4✔
317
            $modelName = Str::studly($this->argument('name'));
1✔
318
            if (!$this->classExists('services', "{$modelName}Service")) {
1✔
319
                throw new ClassNotExistsException('Cannot create API without entity.');
1✔
320
            }
321
        }
322
    }
323
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc