How to customize controllers generated by Artisan in Laravel

I’m porting a web-based application I built in the office from CodeIgniter to Laravel, and I’m relying a lot on Artisan to generate REST controllers. I’m not doing anything terribly fancy with the generated controllers, so I end up copying and pasting a lot of code.

Yes, I could probably design this application to prevent all that copying and pasting, but it’s for a system that I intend to retire in the next 18 months. So I’m not hung up on cleverness.

Instead, I wanted to find a way to generate as much code as possible so the refactoring work concentrates mostly on refinement.

Artisan make commands generate very minimal scaffolds for models and controllers. What if you wanted Artisan to generate something with more meat on the bones?

That’s where the ControllerMakeCommand class comes in.

I found this class by performing a search of the Laravel vendor folder for one of the help strings in the php artisan list command. The class itself extends GeneratorCommand. By studying these classes, I could see extending ControllerMakeCommand and overriding a few methods could get me on my way to creating my own controllers.

Of course, you need to know a little bit about how to create your own Artisan commands before you can create your own controllers. I won’t go over that since the Laravel documentation does a good job of it already.

Here’s an example of an extended ControllerMakeCommand

<?php namespace App\Console\Commands; use Illuminate\Routing\Console\ControllerMakeCommand;


class CustomControllerMakeCommand extends ControllerMakeCommand {
     protected $name = 'example:controller';
     protected $description = 'Create a customized controller in Laravel.';

     protected function getStub()
     {
         return __DIR__.'/stubs/controller.custom.stub';
     }

     protected function buildClass($name)
     {
         $stub = $this->files->get($this->getStub());

        return $this->replaceNamespace($stub, $name)->replaceScaffold($stub)->replaceClass($stub, $name);
     }

    protected function replaceScaffold(&$stub)
    {
        // Parse input name.
        $name = str_replace('Controller', '', $this->getNameInput());

        // Create replacements
        $viewPathName = strtolower(str_replace('\\', '.', $name) );

        // Apply replacements
        $stub = str_replace('dummyViewPath', $viewPathName, $stub);

        return $this;
    }
}

ControllerMakeCommand reads a text file and substitutes strings in the file with values based on the namespace. To customize our controllers, we want our Artisan command to use our own text file instead of the one used by the parent class. So we override the getStub method in CustomControllerMakeCommand to point to a text file we prefer. In this example, it’s the directory in which our customized class resides, i.e. app/Console/Commands.

The controller.custom.stub file, then, contains your customized controller code.

The overridden buildClass method reads the .stub file and performs string processing. It usually processes the namespace (replaceNamespace) and the class name (replaceClass). You can inject additional string processing between these method calls, which is what replaceScaffold does. Note that the method returns the object reference ($this), not the processed string. Returning the object reference allows for chaining. replaceClass returns the final processed string.

The fire method in the grandparent GeneratorCommand class then generates the actual controller files with the string created by CustomControllerMakeCommand. All that’s left to use your custom command is to register it.

Models can also be customized in a similar fashion by extending the ModelMakeCommand class. Since it too extends GeneratorCommand, the same methods, particularly getStub, can be overridden.