本記事でやること
php artisan make:model コマンドに以下の改造を加えます。
- デフォルトの生成対象ディレクトリと名前空間を変更する
- stubを弄って生成される初期クラスの様相を変える
対象環境
Laravel 5.4.11
CentOS 6.5
make:model 改造の前準備
まずmake:modelを改造できるようにクラスを準備してコマンドとして登録します。
以下の手順を全て終わらせてください。
1. make:command を実行
app/Console/Commands/ModelMakeCommand.php
が生成されます。
php artisan make:command ModelMakeCommand
2. クラスをConsole/Kernelに登録
app/Console/Kernel.php を編集して、ModelMakeCommandを登録します。
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
'App\Console\Commands\ModelMakeCommand', # add make:model
];
...
3. ModelMakeCommand のメソッドとプロパティを全て削除
クラスの中身を削除してこの形にします。
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class ModelMakeCommand extends Command
{
}
4. 継承先を変更
継承先をフレームワークコアのModelMakeCommandに変更します。
これで準備は完了です。
<?php
namespace App\Console\Commands;
class ModelMakeCommand extends \Illuminate\Foundation\Console\ModelMakeCommand
{
}
デフォルトの生成対象ディレクトリと名前空間を変更する
前提
make:modelの対象位置はコマンド指定できる
make:modelは以下のようにパスまで含めたモデル名を渡すことで、
クラスが生成されるディレクトリと名前空間を変更することが出来ます。
php artisan make:model Tables/Test
それを、以下のように打つだけでクラスの生成ディレクトリと名前空間を変えてしまおうという試みとなります。
php artisan make:model Test
なぜデフォルトディレクトリを変更するのか
毎回ディレクトリの位置を指定するのが面倒だから。
打ち間違えで変なディレクトリ作るくらいなら最初から決め打ちしましょう。
実装手順
1. メソッドをオーバーライド
getDefaultNamespace
をオーバーライドして返却する名前空間に好きな階層を追加するだけです。
ここではTablesとしています。
<?php
namespace App\Console\Commands;
class ModelMakeCommand extends \Illuminate\Foundation\Console\ModelMakeCommand
{
/**
* Get the default namespace for the class.
*
* @param string $rootNamespace
* @return string
*/
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace . '\Tables';
}
}
2. 実行
特にパスを指定せずにmake:modelを実行します。
$ php artisan make:model Test
Model created successfully.
Tablesディレクトリにモデルが生成されています。
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: app/Tables/Test.php
#
名前空間も正しく変更されています。
<?php
namespace App\Tables;
use Illuminate\Database\Eloquent\Model;
class Test extends Model
{
//
}
stubを弄って生成される初期クラスの様相を変える
前提
生成されるモデルの継承元は常に同じ
常にmake:modelされるモデルは継承元として、Illuminate\Database\Eloquent\Model
を指します。
AppModelを作って共通メソッドを作るといったCakePHP的なやり方に対応するためには、
毎回生成後のモデルのextends以降を書き換えなければいけません。
それを解決するために今回は 「stub」 を書き換えます。
stubとは
artisanのジェネレート系コマンドで利用される、クラスのひな型です。
フレームワークコアのこちらのディレクトリに格納されています。
$ ls
console.stub event.stub listener-queued.stub markdown-mail.stub model.stub policy.stub routes.stub
event-handler-queued.stub job-queued.stub listener.stub markdown-notification.stub notification.stub provider.stub test.stub
event-handler.stub job.stub mail.stub markdown.stub policy.plain.stub request.stub unit-test.stub
<?php
namespace DummyNamespace;
use Illuminate\Database\Eloquent\Model;
class DummyClass extends Model
{
//
}
実装
1. model.stub をアプリケーションへコピー
vendor/laravel/framework/src/Illuminate/Foundation/Console/stubs
からmodel.stubをコピーします。
コピー先は app/Console/Commands/stubs
です。
例はアプリケーションルートで叩いている想定です。
パスは適宜読み替えてください。
$ mkdir app/Console/Commands/stubs
$ cp vendor/laravel/framework/src/Illuminate/Foundation/Console/stubs/model.stub app/Console/Commands/stubs
2. model.stub を ModelMakeCommand に登録
getStub
メソッドをオーバーライドしてstubの位置を返します。
今回は ModelMakeCommand.php
と同じ階層にある stubs
ディレクトリに model.stub
を配置したので、
このような指定にしてください。
<?php
namespace App\Console\Commands;
class ModelMakeCommand extends \Illuminate\Foundation\Console\ModelMakeCommand
{
/**
* Get the stub file for the generator.
*
* @return string
*/
protected function getStub()
{
return __DIR__ . '/stubs/model.stub';
}
}
3. stubを改造
今回は共通処理をAppModelに纏めて全てのモデルで継承することにします。
model.stubの継承元クラスを、 AppModel
に変更します。
「DummyNamespace」 と 「DummyClass」 以外はすべて書き換え可能です。
これらについては名前空間とクラス名がstr_replaceで置き換えられているので、変更しないでください。
<?php
namespace DummyNamespace;
class DummyClass extends AppModel
{
//
}
4. 実行
make:modelを実行します。
$ php artisan make:model Test
Model created successfully.
生成されたクラスにAppModelがextendsされています。
あとはこのクラスを実装して共通処理を記述するだけです。
<?php
namespace App;
class Test extends AppModel
{
//
}
備考
更にいろいろ動的に弄りたい場合は、
こちらのメソッドをオーバーライドしてstubをひたすらstr_replaceすると良いでしょう。
protected function buildClass($name) {}
詳しくはこのあたりを参照してください。
ModelMakeCommand.php
GeneratorCommand.php
まとめ
今回はModelMakeCommandを編集することでmake:modelを改造しました。
その他のmake系コマンドもすべて改造可能なので、そちらも記事にしていく予定です。
またmodel.stubをbladeテンプレート化してみようと試みたこともあったのですが、
エスケープ記述が煩雑になってファイル全体の見通しが地獄になったので、あまりオススメできません。