Laravel view  composerでロジックを一箇所にまとめよう！

# この記事について
## あらすじ
自社サービス開発の中で共通でuser情報を使い回している箇所があり、その部分が煩雑な書き方になっていたので、処理をどこか一つにまとめたいと思っていました。

# やりたい事
- 共通でuser情報を使い回しているを共通化する。
- ヘッダーのbladeファイル以外でサイドバーなどの箇所でもuser情報を使いたい。

# やってみた事
- Laravel view composerを使って、処理を共通化する。

# view composerとは？
ビューコンポーザはビューがレンダーされる時に呼び出される、コールバックかクラスメソッドのことです。  ビューがレンダーされるたびに結合したい情報があるなら、ビューコンポーザがロジックを一箇所にまとめるのに役立ちます。

## 処理イメージ図
<img width="492" alt="スクリーンショット 2019-12-05 17.40.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85181/da684121-5ede-83d8-e84c-6108fb718e5a.png">

## どんな時に使うのか？
- サイドバーなどすべてのページで共通するデータを表示したい時。

- ビューロジックはできればコントローラーに書きたくないし、テンプレートもできるだけロジックを入れず、綺麗なhtmlのままでありたい。

- コントローラーの肥大化を防ぎたい。

# 実装方法
## 実装手順
- ①サービスプロバイダーの用意
- ②app/config.phpに登録
- ③Composerクラスの作成
- ④SeriviceProviderへの設定
- ⑤bladeファイルの修正  

### ①サービスプロバイダーの用意
`$ php artisan make:provider ViewComposerServiceProvider` を実行して、サービスプロバイダーを生成する。

```php5

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use View;

/**
 * Class ViewComposerServiceProvider
 * @package App\Providers
 */
class ViewComposerServiceProvider extends ServiceProvider
{
    /**
     *
     */
    public function boot()
    {
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}
```
## ②app/config.phpに登録
「config/app.php」へ下記のようにSeriviceProviderを登録する  

```php5
<?php

'providers' => [
        App\Providers\ViewComposerServiceProvider::class,
    ],

```

## ③Composerクラスの作成
「app/Http/ViewComposers」という形でディレクトリを作成し、ViewComposersディレクトリの中に「LayoutComposer.php」を作成します。


```php5
<?php

namespace App\Http\ViewComposers\User\Worker;

use Auth;
use Illuminate\View\View;

/**
 * Class LayoutComposer
 * @package App\Http\ViewComposers\User\Worker
 */
class LayoutComposer
{
    /**
     * @param View $view
     */
    public function compose(View $view)
    {
        $view->with([
            'loginUser' => Auth::user(),
        ]);
    }

}
```

## ④SeriviceProviderへの設定
bootメソッドにViewComposerが値を渡すviewを、View::composersメソッドを使って指定します。

```php5
<?php

namespace App\Providers;

use App\Http\ViewComposers\User\Agent as Agent;
use App\Http\ViewComposers\User\FriendRecommendComposer;
use App\Http\ViewComposers\User\Worker as Worker;
use Illuminate\Support\ServiceProvider;
use View;

/**
 * Class ViewComposerServiceProvider
 * @package App\Providers
 */
class ViewComposerServiceProvider extends ServiceProvider
{
    /**
     *
     */
    public function boot()
    {
        View::composers([
            Agent\LayoutComposer::class => 'agent.*',
            Worker\LayoutComposer::class => 'worker.*',
            FriendRecommendComposer::class => 'user.friend_recommend.block',
        ]);
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

```

## ⑤bladeファイルの修正
$loginUserの変数を該当箇所に書く  

```php5
<?php
                <div class="user-block">
                    <div class="img-wrap">
                        <img src="{{ $loginUser->userProfile->image->url }}" alt="">
                    </div>
                    <div class="user-name">{{ $loginUser->userProfile->display_name }}</div>
                    <div class="user-type">{{ \App\Enums\UserRole::toJapanese($loginUser->userProfile->role) }}</div>
                </div>

```
<img width="773" alt="スクリーンショット 2019-12-05 18.01.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85181/9923c22b-4196-8a1c-15d2-bd8423f9f3c6.png">


# まとめ
- 共通で使うような変数やロジックがあればview composerにまとめよう！

# 参考記事
- https://readouble.com/laravel/5.5/ja/views.html