/
githubmirror
/
framework
Обзор
Документация
Войти
/
githubmirror
/
framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
13.x
src/Illuminate/Foundation/Console/ModelMakeCommand.php
320 строк
9 KB
Denys Finchenko
Fix ModelMakeCommand handle return type (#60989)
03 авг 2026, 00:16
Не верифицирован
03 авг 2026, 00:16
c9f5770
Код
Авторство
О чём код?
<?php namespace Illuminate\Foundation\Console; use Illuminate\Console\Concerns\CreatesMatchingTest; use Illuminate\Console\GeneratorCommand; use Illuminate\Support\Collection; use Illuminate\Support\Str; use Illuminate\Support\Stringable; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use function Laravel\Prompts\confirm; use function Laravel\Prompts\multiselect; #[AsCommand(name: 'make:model')] class ModelMakeCommand extends GeneratorCommand { use CreatesMatchingTest; /** * The name and signature of the console command. * * @var string */ protected $signature = 'make:model {name : The name of the model} {--a|all : Generate a migration, seeder, factory, policy, resource controller, and form request classes for the model} {--c|controller : Create a new controller for the model} {--f|factory : Create a new factory for the model} {--force : Create the class even if the model already exists} {--m|migration : Create a new migration file for the model} {--morph-pivot : Indicates if the generated model should be a custom polymorphic intermediate table model} {--policy : Create a new policy for the model} {--s|seed : Create a new seeder for the model} {--p|pivot : Indicates if the generated model should be a custom intermediate table model} {--r|resource : Indicates if the generated controller should be a resource controller} {--api : Indicates if the generated controller should be an API resource controller} {--R|requests : Create new form request classes and use them in the resource controller}'; /** * The console command description. * * @var string */ protected $description = 'Create a new Eloquent model class'; /** * The type of class being generated. * * @var string */ protected $type = 'Model'; /** * Execute the console command. * * @return bool|null */ public function handle() { if (parent::handle() === false && ! $this->option('force')) { if (! $this->alreadyExists($this->getNameInput())) { return false; } if (! confirm('Do you want to generate additional components for the model?')) { return false; } else { $this->afterPromptingForMissingArguments($this->input, $this->output); } } if ($this->option('all')) { $this->input->setOption('factory', true); $this->input->setOption('seed', true); $this->input->setOption('migration', true); $this->input->setOption('controller', true); $this->input->setOption('policy', true); $this->input->setOption('resource', true); } if ($this->option('factory')) { $this->createFactory(); } if ($this->option('migration')) { $this->createMigration(); } if ($this->option('seed')) { $this->createSeeder(); } if ($this->option('controller') || $this->option('resource') || $this->option('api')) { $this->createController(); } elseif ($this->option('requests')) { $this->createFormRequests(); } if ($this->option('policy')) { $this->createPolicy(); } } /** * Create a model factory for the model. * * @return void */ protected function createFactory() { $factory = Str::studly($this->argument('name')); $this->call('make:factory', [ 'name' => "{$factory}Factory", '--model' => $this->qualifyClass($this->getNameInput()), ]); } /** * Create a migration file for the model. * * @return void */ protected function createMigration() { $table = Str::snake(Str::pluralStudly(class_basename($this->argument('name')))); if ($this->option('pivot')) { $table = Str::singular($table); } $this->call('make:migration', [ 'name' => "create_{$table}_table", '--create' => $table, ]); } /** * Create a seeder file for the model. * * @return void */ protected function createSeeder() { $seeder = Str::studly(class_basename($this->argument('name'))); $this->call('make:seeder', [ 'name' => "{$seeder}Seeder", ]); } /** * Create a controller for the model. * * @return void */ protected function createController() { $controller = Str::studly(class_basename($this->argument('name'))); $modelName = $this->qualifyClass($this->getNameInput()); $this->call('make:controller', array_filter([ 'name' => "{$controller}Controller", '--model' => $this->option('resource') || $this->option('api') ? $modelName : null, '--api' => $this->option('api'), '--requests' => $this->option('requests') || $this->option('all'), '--test' => $this->option('test'), '--pest' => $this->option('pest'), ])); } /** * Create the form requests for the model. * * @return void */ protected function createFormRequests() { $request = Str::studly(class_basename($this->argument('name'))); $this->call('make:request', [ 'name' => "Store{$request}Request", ]); $this->call('make:request', [ 'name' => "Update{$request}Request", ]); } /** * Create a policy file for the model. * * @return void */ protected function createPolicy() { $policy = Str::studly(class_basename($this->argument('name'))); $this->call('make:policy', [ 'name' => "{$policy}Policy", '--model' => $this->qualifyClass($this->getNameInput()), ]); } /** * Get the stub file for the generator. * * @return string */ protected function getStub() { if ($this->option('pivot')) { return $this->resolveStubPath('/stubs/model.pivot.stub'); } if ($this->option('morph-pivot')) { return $this->resolveStubPath('/stubs/model.morph-pivot.stub'); } return $this->resolveStubPath('/stubs/model.stub'); } /** * Resolve the fully-qualified path to the stub. * * @param string $stub * @return string */ protected function resolveStubPath($stub) { return file_exists($customPath = $this->laravel->basePath(trim($stub, '/'))) ? $customPath : __DIR__.$stub; } /** * Get the default namespace for the class. * * @param string $rootNamespace * @return string */ protected function getDefaultNamespace($rootNamespace) { return is_dir(app_path('Models')) ? $rootNamespace.'\\Models' : $rootNamespace; } /** * Build the class with the given name. * * @param string $name * @return string * * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException */ protected function buildClass($name) { $replace = $this->buildFactoryReplacements(); return str_replace( array_keys($replace), array_values($replace), parent::buildClass($name) ); } /** * Build the replacements for a factory. * * @return array<string, string> */ protected function buildFactoryReplacements() { $replacements = []; if ($this->option('factory') || $this->option('all')) { $modelPath = (new Stringable($this->argument('name')))->studly()->replace('/', '\\')->toString(); $factoryNamespace = '\\Database\\Factories\\'.$modelPath.'Factory'; $factoryCode = <<<EOT /** @use HasFactory<$factoryNamespace> */ use HasFactory; EOT; $replacements['{{ factory }}'] = $factoryCode; $replacements['{{ factoryImport }}'] = 'use Illuminate\Database\Eloquent\Factories\HasFactory;'; } else { $replacements['{{ factory }}'] = '//'; $replacements["{{ factoryImport }}\n"] = ''; $replacements["{{ factoryImport }}\r\n"] = ''; } return $replacements; } /** * Interact further with the user if they were prompted for missing arguments. * * @param \Symfony\Component\Console\Input\InputInterface $input * @param \Symfony\Component\Console\Output\OutputInterface $output * @return void */ protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output) { if ($this->isReservedName($this->getNameInput()) || $this->didReceiveOptions($input)) { return; } (new Collection(multiselect('Would you like any of the following?', [ 'seed' => 'Database Seeder', 'factory' => 'Factory', 'requests' => 'Form Requests', 'migration' => 'Migration', 'policy' => 'Policy', 'resource' => 'Resource Controller', ])))->each(fn ($option) => $input->setOption($option, true)); } }