ModelMakeCommand.php
TLDR
This file, located at src/Illuminate/Foundation/Console/ModelMakeCommand.php
, contains the ModelMakeCommand
class, which is responsible for creating a new Eloquent model class. It extends the GeneratorCommand
class and also uses the CreatesMatchingTest
trait.
Methods
handle
This method is responsible for executing the console command. It creates various files based on the options provided. It calls other methods to create the model factory, migration, seeder, controller, and policy.
createFactory
This method creates a model factory for the model. It calls the make:factory
command.
createMigration
This method creates a migration file for the model. It calls the make:migration
command.
createSeeder
This method creates a seeder file for the model. It calls the make:seeder
command.
createController
This method creates a controller for the model. It calls the make:controller
command.
createPolicy
This method creates a policy file for the model. It calls the make:policy
command.
getStub
This method returns the stub file for the generator based on the options provided.
resolveStubPath
This method resolves the fully-qualified path to the stub file.
getDefaultNamespace
This method returns the default namespace for the class.
getOptions
This method returns the console command options.
afterPromptingForMissingArguments
This method interacts further with the user if they were prompted for missing arguments.
Classes
ModelMakeCommand
This class is responsible for creating a new Eloquent model class. It extends the GeneratorCommand
class and uses the CreatesMatchingTest
trait. It has methods to create a model factory, migration, seeder, controller, and policy. It also has methods to get the stub file, resolve the stub path, get the default namespace, and get the console command options.
<?php
namespace Illuminate\Foundation\Console;
use Illuminate\Console\Concerns\CreatesMatchingTest;
use Illuminate\Console\GeneratorCommand;
use Illuminate\Support\Str;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use function Laravel\Prompts\multiselect;
#[AsCommand(name: 'make:model')]
class ModelMakeCommand extends GeneratorCommand
{
use CreatesMatchingTest;
/**
* The console command name.
*
* @var string
*/
protected $name = 'make:model';
/**
* 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 void
*/
public function handle()
{
if (parent::handle() === false && ! $this->option('force')) {
return false;
}
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();
}
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 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;
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['all', 'a', InputOption::VALUE_NONE, 'Generate a migration, seeder, factory, policy, resource controller, and form request classes for the model'],
['controller', 'c', InputOption::VALUE_NONE, 'Create a new controller for the model'],
['factory', 'f', InputOption::VALUE_NONE, 'Create a new factory for the model'],
['force', null, InputOption::VALUE_NONE, 'Create the class even if the model already exists'],
['migration', 'm', InputOption::VALUE_NONE, 'Create a new migration file for the model'],
['morph-pivot', null, InputOption::VALUE_NONE, 'Indicates if the generated model should be a custom polymorphic intermediate table model'],
['policy', null, InputOption::VALUE_NONE, 'Create a new policy for the model'],
['seed', 's', InputOption::VALUE_NONE, 'Create a new seeder for the model'],
['pivot', 'p', InputOption::VALUE_NONE, 'Indicates if the generated model should be a custom intermediate table model'],
['resource', 'r', InputOption::VALUE_NONE, 'Indicates if the generated controller should be a resource controller'],
['api', null, InputOption::VALUE_NONE, 'Indicates if the generated controller should be an API resource controller'],
['requests', 'R', InputOption::VALUE_NONE, 'Create new form request classes and use them in the resource controller'],
];
}
/**
* 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;
}
collect(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));
}
}