Skip to content

Instantly share code, notes, and snippets.

@jaygaha
Created January 25, 2024 09:20
Show Gist options
  • Save jaygaha/aa90a89a04ead718e802834cf87d54c8 to your computer and use it in GitHub Desktop.
Save jaygaha/aa90a89a04ead718e802834cf87d54c8 to your computer and use it in GitHub Desktop.
Laravel Custom Stubs File

Laravel Custom Stubs File

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.

Custom Stubs

Using custom stubs, create your own starter template file in Laravel from scratch.

Step 1: Create a Stub File

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
}

Step 2: Create a Console Command

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment