laravel8でログインしたユーザにのみファイルをダウンロードさせる。ついでに購入処理(NOT決済処理)も入れてみた。
前回の続き
1, 公開ディレクトリは止める。
1 2 |
# /public内にシンボリックリンクstorage(/storage/app/publicへのリンク)が作られる php artisan storage:link |
これだと公開ディレクトリになっちゃうので、とりあえずシンボリックリンクを外す。
artisanに削除コマンドはないので、手動で消す。
1 2 |
# linuxコマンド unlink public/storage |
2, ダウンロード処理を書く
UploadController.php
1 2 3 4 5 |
public function download($id){ $upload_file = Upload::findOrFail($id); // 第一引数がstorageファイルのパス。第二引数がダウンロードさせるファイル名 return \Storage::download('public/'. $upload_file->file_path, $upload_file->file_name); } |
3, 画面のリンク先を変更
user.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 |
@foreach($uploads as $upload) <tr> <td class="border px-4 py-2">{{$upload->title}}</td> <td class="border px-4 py-2">{{$upload->detail}}</td> <td class="border px-4 py-2"> <a href={{url("user/download/$upload->id")}}> {{$upload->file_name}} </a> </td> <td class="border px-4 py-2">{{$upload->created_at}}</td> </tr> @endforeach |
これでログインしていない一般ユーザがURLにアクセスしても、ログイン画面に飛ばされるだけ。
ここまで出来たら、購入済みファイルだけダウンロード出来るようにしたいね。
3, 購入機能を作る(NOT決済)
1 |
php artisan make:model Purchase --all |
1 2 3 4 5 6 7 8 9 10 |
Schema::create('purchases', function (Blueprint $table) { $table->id(); // 外部キーも制約もメソッドで指定できる! $table->foreignId('user_id')->constrained()->comment('購入者ユーザID'); $table->foreignId('upload_id')->constrained()->comment('購入されたアップロードファイルID'); // 独自idカラム名が使いたい時は、テーブル名を指定すればOK! user.id = user_codeで外部キー制約してくれる。 // $table->foreignId('user_code')->constrained('users')->comment('購入者ユーザID'); $table->timestamps(); }); |
routes/web.php
1 2 3 4 5 6 7 8 |
// ログインした一般ユーザ Route::group(['prefix' => '/user', 'middleware' => ['auth']], function () { // アップロードファイルの購入 Route::get('/purchase/{id}', [PurchaseController::class,'purchase' ]); // アップロードファイルのダウンロード Route::get('/download/{id}', [UploadController::class,'download' ]); Route::resource('/', UserController::class); }); |
app/Models/Purchase.php
1 2 3 4 5 6 7 8 9 10 |
class Upload extends Model { use HasFactory; public function purchase() { // アップロードファイルIDとログインしているユーザIDの組み合わせがあれば、購入済と判断する return $this->hasMany(Purchase::class)->where('user_id', \Auth::id()); } } |
まだ購入していなければ「購入する」
購入済みなら「ダウンロード」
user.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<table class="table-auto"> <thead> <tr> <th class="px-4 py-2">タイトル</th> <th class="px-4 py-2">詳細</th> <th class="px-4 py-2">ファイル名</th> <th class="px-4 py-2">公開日</th> <th class="px-4 py-2">購入</th> </tr> </thead> <tbody> @foreach($uploads as $upload) <tr> <td class="border px-4 py-2">{{$upload->title}}</td> <td class="border px-4 py-2">{{$upload->detail}}</td> <td class="border px-4 py-2">{{$upload->file_name}}</td> <td class="border px-4 py-2">{{$upload->created_at}}</td> <td class="border px-4 py-2"> @if($upload->purchase->isEmpty()) <a href={{url("user/purchase/$upload->id")}}> 購入する </a> @else <a href={{url("user/download/$upload->id")}}> ダウンロード </a> @endif </td> </tr> @endforeach </tbody> </table> |
5, 未購入のファイルをダウンロードしようとしたら、はじく処理を追加
UploadController.php
1 2 3 4 5 6 7 8 9 |
public function download($id){ $upload_file = Upload::findOrFail($id); // 未購入のファイルをダウンロードしようとしたら if($upload_file->purchase->isEmpty()){ return back(); } // 第一引数がstorageファイルのパス。第二引数がダウンロードさせるファイル名 return \Storage::download('public/'. $upload_file->file_path, $upload_file->file_name); } |
これで、購入したユーザでログインしていないとダウンロード出来ないようになった。
ここまで来たら、決済処理を入れたくなるよな~。