イントロダクション

パッケージは、Laravelに機能を追加する一番重要な方法です。パッケージとして、何でも動作させることができます。たとえば、日付ライブラリーであるCarbonや、振る舞い駆動開発(BDD)テストフレームワークのBehatなどです。

もちろん、パッケージには色々な種類が存在しています。スタンドアローンで動作するパッケージがあります。動作させるのにLaravelに限らず、どんなフレームワークも必要としません。CarbonもBehatもスタンドアローンパッケージの例です。Laravelと一緒に使用するには、composer.jsonファイルでシンプルに使用を指定します。

逆に、Laravelと一緒に使用することを意図したパッケージもあります。こうしたパッケージは、Laravelアプリケーションを高めることを特に意図した、ルート、コントローラー、ビュー、設定を持つことでしょう。このガイドは、Laravelに特化したパッケージの開発を主に説明します。

Laravelのパッケージは、全てPackagistComposerにより配布されます。ですから、これらの素晴らしいPHPパッケージ配布ツールについて学ぶことは、大切です。

ビュー

パッケージの内部構造は完全に皆さんへ委ねられています。しかし、通常各パッケージは、一つ以上のサービスプロバイダーを含むでしょう。サービスプロバイダーはサービスコンテナ結合を含み、同時にパッケージの設定、ビュー、言語ファイルの設置場所も指定します。

ビューファイル

パッケージのビューは通常、二重のコロンによる「名前空間」で指定します。

return view('package::view.name');

Laravelに対し、指定された名前空間のビューはどこに存在するのかを伝える必要があります。例えば、パッケージに"courier"という名前がついているなら、サービスパッケージのbootメソッドに、以下のコードを指定します。

public function boot()
{
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}

これで、以下の記法を使用し、パッケージのビューをロードできます。

return view('courier::view.name');

loadViewsFromメソッドを使用する場合、Laravelはビューの2つの場所を実際には登録します。一つは、アプリケーションのresources/views/vendorディレクトリーで、もう一つは皆さんが指定したディレクトリーです。では、courierの例を使って見ましょう。パッケージのビューがリクエストされると、Laravelは最初にresources/views/vendor/courierの中にカスタムバージョンのビューが開発者により用意されていないかチェックします。カスタムビューが用意されていなければ、次にloadViewsFromの呼び出しで指定したパッケージビューディレクトリーを探します。この仕組みにより、パッケージのビューがエンドユーザーにより、簡単にカスタマイズ/オーバーライドできるようになっています。

ビューの公開

パッケージのビューをresources/views/vendorディレクトリーで(ユーザーに対し)公開するには、サービスプロバイダーのbootメソッドで、publishesメソッドを使用する必要があります。

public function boot()
{
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');

    $this->publishes([
        __DIR__.'/path/to/views' => base_path('resources/views/vendor/courier'),
    ]);
}

あなたのパッケージの利用者が、Laravelのvendor:publishコマンドを実行すると、指定された場所へビューディレクトリーがコピーされます。

既存のファイルをオーバーライトしたい場合は、--forceスイッチを使用します。

php artisan vendor:publish --force

注目: publishesメソッドにより、どんなタイプのファイルでも、好きな場所へ公開できます。

言語ファイル

パッケージの言語ファイルは、通常二重コロン記法を使用し指定されます。

return trans('package::file.line');

指定された名前空間の言語ファイルがどこに存在するかをLaravelへ伝える必要があります。例えば、パッケージ名が"courier"ならば、サービスプロバイダーのbootメソッドに以下の行を追加する必要があるでしょう。

public function boot()
{
    $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
}

言語ファイルのフォルダーは、それぞれの言語のサブディレクトリーにわけられている必要があることに注意してください。例えば、enesruなどです。

これで、以下の記法を使用し、パッケージの言語ファイルをロードできます。

return trans('courier::file.line');

設定

通常、あなたのパッケージの設定ファイルをアプリケーション自身のconfigディレクトリーへ公開する必要があることでしょう。これにより、あなたのデフォルト設定オプションをユーザーに簡単にオーバーライドしてもらえるようになります。

設定ファイルを公開するには、サービスプロバイダーのbootメソッドで、publishesメソッドを使用するだけです。

$this->publishes([
    __DIR__.'/path/to/config/courier.php' => config_path('courier.php'),
]);

これで、あなたのパッケージのユーザーが、Laravelのvendor:publishコマンドを実行すると、ファイルが指定された場所へコピーされます。もちろん、設定ファイルが一度公開されると、他の設定ファイル同様に、設定内容にアクセスできるようになります。

$value = config('courier.option');

もしくは、あなたのパッケージ設定ファイルをアプリケーションのファイルへマージすることを選ぶこともできます。これにより、設定の公開済ファイルの中で、実際にオーバーライドしたいオプションだけをユーザーに含めてもらう指定方法を取ってもらうことができます。設定ファイルをマージする場合は、サービスプロバイダーのregisterメソッドで、mergeConfigFromメソッドを使います。

$this->mergeConfigFrom(
    __DIR__.'/path/to/config/courier.php', 'courier'
);

公開アセット

パッケージにはJavascriptやCSS、画像などのアセットを含むと思います。アセットを公開するには、サービスプロバイダーのbootメソッドでpublishesメソッドを使用してください。次の例では、"public"アセットグループタグも追加指定しています。

$this->publishes([
    __DIR__.'/path/to/assets' => public_path('vendor/courier'),
], 'public');

これにより、皆さんのパッケージのユーザーは、vendor:publishコマンドを実行できるようになりました。実行すれば皆さんのファイルは指定された場所へコピーされます。通常、パッケージがアップデートされる度に、アセットを上書きする必要があります。--forceフラッグが使用できます。

php artisan vendor:publish --tag=public --force

公開アセットをいつも確実にアップデートしたい場合は、このコマンドをcomposer.jsonファイルのpost-update-cmdリストへ追加します。

ファイルグループの公開

ファイルのグループごとに分割して公開したい場合もあります。例えば、ユーザーにパッケージの設定ファイルとアセットファイルを別々に公開できるようにさせたい場合です。

// 設定ファイルの公開
$this->publishes([
    __DIR__.'/../config/package.php' => config_path('package.php')
], 'config');

// マイグレーションの公開
$this->publishes([
    __DIR__.'/../database/migrations/' => database_path('/migrations')
], 'migrations');

これでタグを指定してもらえば、分割してファイルを公開できます。

php artisan vendor:publish --provider="Vendor\Providers\PackageServiceProvider" --tag="config"

ルート

パッケージのルートファイルをロードするには、サービスプロバイダーのbootメソッドの中で、シンプルにincludeしてください。

サービスプロバイダー中でルート定義ファイルの読み込み

public function boot()
{
    include __DIR__.'/../../routes.php';
}

注意: パッケージでコントローラーを使用している場合、ファイルをロードできるように、composer.jsonで確実に設定してください。