Artisan make commands build stuff (models, jobs, etc.) from templates. Want to edit those templates? Use php artisan stub:publish
to copy them to your app for easy tweaks! This command will publish all the variety of classes available in Laravel inside stubs
directory.
Using custom stubs, create your own starter template file in Laravel from scratch.
Create the file name trait.stub
which will look like this:
<?php
declare(strict_types=1);
namespace {{ namespace }};
/**
* Trait {{ class }}
*
* @package App\Traits
*/
trait {{ class }}
{
// Do trait
}
Run the command php artisan make:command MakeTrait
, which will generate a console command in the relative directory app/Console/Commands
.
MakeTrait.php
file looks like:
<?php
namespace App\Console\Commands;
use Illuminate\Console\GeneratorCommand;
use Illuminate\Support\Pluralizer;
use Illuminate\Support\Str;
class MakeTrait extends GeneratorCommand
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'make:trait {name : Create a php trait}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new php trait';
/**
* The type of class being generated.
*
* @var string
*/
protected $type = 'Trait';
/**
* Get the stub file for the generator.
*/
protected function getStub(): string
{
return base_path('stubs/trait.stub');
}
/**
* Execute the console command.
*
* @return bool|null
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*
* @see \Illuminate\Console\GeneratorCommand
*/
public function handle(): bool
{
if ($this->isReservedName($this->getNameInput())) {
$this->newLine();
$this->error('The name "'.$this->getNameInput().'" is reserved by PHP.');
$this->newLine();
return false;
}
$name = $this->qualifyClass($this->getSingularClassName($this->getNameInput()).'Trait');
$path = $this->getPath($name);
if ($this->alreadyExists($this->getNameInput())) {
$this->newLine();
$this->error($this->type.' already exists!');
$this->newLine();
return false;
}
$this->makeDirectory($path);
$this->files->put(
$path,
$this->sortImports(
$this->buildTraitClass($name)
)
);
$this->newLine();
$this->info($this->type.' created successfully.');
$this->newLine();
return GeneratorCommand::SUCCESS;
}
/**
* Build the class with the given name.
*
* @param $isInterface
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
protected function buildTraitClass(string $name): string
{
$stub = $this->files->get(
$this->getStub()
);
return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);
}
/**
* Get the default namespace for the class.
*
* @param mixed $rootNamespace
*/
protected function getDefaultNamespace($rootNamespace): string
{
return $rootNamespace.'\Traits';
}
/**
* Return the Singular Capitalize Name
*/
protected function getSingularClassName(string $name): string
{
return Str::of(Pluralizer::singular($name))->ucfirst();
}
}
This allows you to extend the logic to construct the starting structure and files for your own custom module from a simple initial template.
Happy Coding!