Creating Artisan tasks that generate files
Published by Matthew Daly at 1st January 2018 4:06 pm
While the documentation for creating Artisan tasks is generally pretty good, it doesn't really touch on creating tasks that generate new files. The only way to figure it out was to go digging through the source code. In this case, I was building an Artisan command to create Fractal transformers as part of a package I'm working on.
There's a specialised class for generating files at Illuminate\Console\GeneratorCommand
, which your command class should extend instead of Illuminate\Console\Command
. In addition to the usual properties such as the signature and description, you also need to specify $type
to give the type of class being generated. Also, note that the constructor is different, so if you use php artisan make:console
to create the boilerplate for this command, you'll need to delete the constructor.
1<?php23namespace Matthewbdaly\MyPackage\Console\Commands;45use Illuminate\Console\GeneratorCommand;6use Symfony\Component\Console\Input\InputArgument;78class TransformerMakeCommand extends GeneratorCommand9{10 /**11 * The name and signature of the console command.12 *13 * @var string14 */15 protected $signature = 'make:transformer {name : The required name of the transformer class}';1617 /**18 * The console command description.19 *20 * @var string21 */22 protected $description = 'Create a Fractal transformer';2324 /**25 * The type of class being generated.26 *27 * @var string28 */29 protected $type = 'Fractal transformer';3031 /**32 * Get the stub file for the generator.33 *34 * @return string35 */36 protected function getStub()37 {38 return __DIR__.'/stubs/transformer.stub';39 }4041 /**42 * Get the console command arguments.43 *44 * @return array45 */46 protected function getArguments()47 {48 return [49 ['name', InputArgument::REQUIRED, 'The name of the command.'],50 ];51 }5253 /**54 * Get the default namespace for the class.55 *56 * @param string $rootNamespace57 * @return string58 */59 protected function getDefaultNamespace($rootNamespace)60 {61 return $rootNamespace.'\Transformers';62 }63}
Note the getDefaultNamespace()
method. If your class will live directly under the app
folder this is not necessary. Otherwise, it needs to return the root namespace, with the folder structure you want after it. Here my class will live under app\Transformers
, so I've set it to reflect that.
Also, note the getStub()
method. This tells Artisan that it should use the specified stub file as the basis for our class. Below you'll find the stub file I used for my transformer:
1<?php23namespace DummyNamespace;45use Matthewbdaly\MyPackage\Transformers\BaseTransformer;6use Illuminate\Database\Eloquent\Model;78class DummyClass extends BaseTransformer9{10 public function transform(Model $model)11 {12 return [13 'id' => (int) $model->id,14 ];15 }16}
Note that the DummyNamespace
and DummyClass
fields will be overwritten with the correct values.
Once this Artisan command is registered in the usual way, you can then run it as follows:
$ php artisan make:transformer Example
And it will generate a boilerplate class something like this:
1<?php23namespace App\Transformers;45use Matthewbdaly\MyPackage\Transformers\BaseTransformer;6use Illuminate\Database\Eloquent\Model;78class Example extends BaseTransformer9{10 public function transform(Model $model)11 {12 return [13 'id' => (int) $model->id,14 ];15 }16}
You can then replace the model with your own one as necessary, and add any further content to this class.