LoginSignup
15

More than 5 years have passed since last update.

Laravel 5.4 make:model コマンド改造入門

Last updated at Posted at 2017-02-12

本記事でやること

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を登録します。

app/Console/Kernel.php
<?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 のメソッドとプロパティを全て削除

クラスの中身を削除してこの形にします。

app/Console/Commands/ModelMakeCommand.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class ModelMakeCommand extends Command
{
}

4. 継承先を変更

継承先をフレームワークコアのModelMakeCommandに変更します。
これで準備は完了です。

app/Console/Commands/ModelMakeCommand.php
<?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としています。

app/Console/Commands/ModelMakeCommand.php
<?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
#

名前空間も正しく変更されています。

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のジェネレート系コマンドで利用される、クラスのひな型です。
フレームワークコアのこちらのディレクトリに格納されています。

vendor/laravel/framework/src/Illuminate/Foundation/Console/stubs
$ 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
model.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 を配置したので、
このような指定にしてください。

app/Console/Commands/ModelMakeCommand.php
<?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:app/Console/Commands/stubs/model.stub
<?php

namespace DummyNamespace;

class DummyClass extends AppModel
{
    //
}

4. 実行

make:modelを実行します。

$ php artisan make:model Test
Model created successfully.

生成されたクラスにAppModelがextendsされています。
あとはこのクラスを実装して共通処理を記述するだけです。

app/Test.php
<?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テンプレート化してみようと試みたこともあったのですが、
エスケープ記述が煩雑になってファイル全体の見通しが地獄になったので、あまりオススメできません。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15