Support the ongoing development of Laravel.io →

Create make:custom commands

5 Mar, 2022 3 min read

Photo by Nagara Oyodo on Unsplash

Laravel comes with a feature that allows us to scaffold some commonly used classes, like models, factories, notifications, etc. If we want to create a model, for example, we can do it by running:

php artisan make:model MyModel

But what if we could do this for our custom classes? Instead of copying and pasting code, why don't we automate that process with a simple command!?. In this article, I'll show you how to do that exactly.

Let's start at the end

Before we start, we need to think about what we are building. I want to make a command that creates an empty report class that extends a different imaginary Report class. I would like to run a command like this:

php artisan make:report MonthlyReport

That would then create a class under app/Reports/ with the following content:

<?php

namespace App\Reports;

class MontlyReport extends Report
{
    public function generate()
    {
        // TODO: add code..
    }
}

Of course, your classes don't have to be exactly like mine, you can use what I'm going to show you to make a generator command that fits your needs.

Generating a generator command

First, we need to create the command that will handle the generation of the classes. Make a new command with:

php artisan make:command MakeReport

I named my command MakeReport you can name it whatever you think fits better for your use case.

After that, we can find it under app/Console/Commands/. Open the file and change the extended class from Command to GeneratorCommand.

While we are here, we should also change the signature to make:report {name} (replace "report" with your type).

<?php

namespace App\Console\Commands;

use Illuminate\Console\GeneratorCommand;

class MakeReport extends GeneratorCommand
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'make:report {name}';
    ...
}

We'll come back to this command later. Before that, let's create the template for our class.

Adding the class template

To create the template for our classes, we need to create a new folder under app/Console/Commands named Stubs. Inside this folder, we need to create a new text file that contains the template for our class. I made a file with the name make-report.stub, and in that file, I added the template for the class:

<?php

namespace App\Reports;

class DummyReport extends Report
{
    public function generate()
    {
        // TODO: add code..
    }
}

The DummyReport name for the class is just a placeholder for the real class name. You can set it to whatever you want, but remember what it is since we'll replace it in the next step.

The generation logic

Now inside the get MakeReport command that we created earlier, I deleted every method and overwrote three new methods getStub getDefaultNamespace and replaceClass

class MakeReport extends GeneratorCommand
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'make:report {name}';

    //...
    
    public function getStub()
    {
        return app_path() . '/Console/Commands/Stubs/make-report.stub';
    } 

    public function getDefaultNamespace($rootNamespace)
    {
        return $rootNamespace . '\Reports';
    }

    public function replaceClass($stub, $name)
    {
        $stub = parent::replaceClass($stub, $name);

        return str_replace("DummyReport", $this->argument('name'), $stub);
    }
}

In the first method, we define the path to our stub file. In the second one, we add the namespace of the generated command, in this case, it will be App\Reports. The namespace will be used to calculate the correct path of the new class. And in the last method, we replace the DummyReport class name with the actual class name sent as an argument to the command.

The final result

And that is it. Now we have a command to generate our custom class by simply running this in the terminal:

php artisan make:report MyReport

And a new report will be created automatically.

If you liked this article follow me on Twitter, I post tips and other laravel content there.

Last updated 2 weeks ago.

brunoalfred, cosmeoes, yvan-burrie, suandedev liked this article

4
Like this article? Let the author know and give them a clap!
cosmeoes (Cosme Escobedo) Writing at https://cosme.dev

Other articles you might like

November 18th 2024

Laravel Custom Query Builders Over Scopes

Hello 👋 Alright, let's talk about Query Scopes. They're awesome, they make queries much easier to r...

Read article
November 19th 2024

Access Laravel before and after running Pest tests

How to access the Laravel ecosystem by simulating the beforeAll and afterAll methods in a Pest test....

Read article
November 11th 2024

🍣 Sushi — Your Eloquent model driver for other data sources

In Laravel projects, we usually store data in databases, create tables, and run migrations. But not...

Read article

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.