前回前々回のレスポンスのマクロの定義は、app/Providers/AppServiceProvider.phpのアプリのサービスプロバイダーに入れましたが、マクロの定義が増えてくると整理した方が良いのと、コントローラ以外では必要もないので、単独のサービスに移します。

まず、app/Providers/ResponseMacroServiceProvider.phpを作成して、2つのマクロを定義します。


namespace App\Providers;

use Illuminate\Routing\ResponseFactory;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class ResponseMacroServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @param ResponseFactory $response
     * @return void
     */
    public function boot(ResponseFactory $response) //レスポンスのオブジェクトを渡すこと可能
    {
        $response->macro('viewWithS3', function ($view, $data) {
            $host = '//example.s3.amazonaws.com';
            $html = View::make($view)->with($data)->render();
            $output = preg_replace('#/user/images/#', $host . '/user/images/, $html);
            return $this->make($output); 
        });

        $response->macro('downloadNoCache', function ($path) {
            return $this->download($path, basename($path), [
                'Cache-Control' => 'no-store',
            ])->setPrivate();   // Cache-Controlにpublicが追加されるのを回避
        });
    }
}

上のboot()の関数の定義では、引数にレスポンスのオブジェクトを渡すことが可能です。以下に説明あります。

https://laravel.com/docs/5.5/providers#the-boot-method

この新しいサービスプロバイダーを使うには、以下のようにconfig/app.phpで登録が必要です。

return [
...
    'providers' => [
...

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\ResponseMacroServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
    ],
...
];

これで以下のように、コントローラでこれらのマクロの使用が可能となります。

return response()->viewWithS3('user/product', compact('page', 'product'));
return response()->downloadNoCache($pathToFile);

By khino