作成にあたって、参考にしたサイト
laravle学習帳
要件定義
ユーザー管理機能(新規登録、ログイン)を実装。
ログインしたら
画像投稿、投稿画像一覧の機能が使えるようにする。
その他
・ログインしているユーザーidと投稿画像のidを紐つけて、どのユーザーが投稿したか管理する。
データベース設計
- プロジェクト名:laravel_fileup
- 画像投稿のモデル、テーブルはPost、postsとする
postsテーブルのカラム設計
- id
- tile:画像のタイトル
- path:画像の保存先のパス
- user_id:どのユーザーが投稿したかのため
usersテーブルのカラム設計
こちらは自動で作成されるので割愛
プロジェクトの作成
$ composer create-project --prefer-dist laravel/laravel='5.8' laravel_fileup
.envファイルの編集
database.sqliteの作成
ログイン機能の実装
make::authを使う
$ php artisan make:auth
ログイン時とログアウト時の遷移先を変更する
参考記事:https://qiita.com/LowSE01/items/ffa256439f665740cc8f
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
+ use Illuminate\Http\Request;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
+ protected $redirectTo = '/posts/create';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
+ public function logout(Request $request)
+ {
+ $this->guard()->logout();
+ $request->session()->flush();
+ $request->session()->regenerate();
+ return redirect('/login');//ログアウト時の遷移先
+ }
}
fileのアップロード用モデルとマイグレーションを作成
$ php artisan make:model Post -m
Model created successfully.
Created Migration: 2019_12_30_005951_create_posts_table
migrationファイルの修正(タイトルとパスのカラムを作成)
$table->bigIncrements('id');
+ $table->unsignedInteger('user_id');
+ $table->string('title');
+ $table->text('path');
$table->timestamps();
+ $table->foreign('user_id')->references('id')->on('users');
マイグレーションの実行
$ php artisan migrate
Post.php(ポストモデルの修正)
postsテーブルへの書き込み権限を付与
Userモデルとの紐付けを記載
class Post extends Model
{
+ protected $fillable = ['title','path'];
+ public function user() {
+ return $this->belongTo('App\User');}
Userモデルの修正
Postモデルとの紐付けを記載
+ public function posts() {
+ return $this->hasMany('App\Post');
+ }
ファイルのアップロード等を管理するコントローラーの作成
$ php artisan make:controller PostsController
Controller created successfully.
ファイル操作に関連するroutesを作成
参考記事
https://qiita.com/sympe/items/9297f41d5f7a9d91aa11
// Route::get('/', function () {return view('welcome');});
Auth::routes();
// Route::get('/home', 'HomeController@index')->name('home');
+ Route::resources('posts','PostsController');
新規投稿〜画像保存までの流れを作成
ファイルアップロード用のフォームを作成
@extends('layouts.app')
@section('content')
<div class="container">
<form method="post" action="/posts" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group">
<label>投稿する画像のタイトルを入力してください</label>
<input type="text" name="title" class="form-control col-sm-4" value="{{ old('title')}}">
</div>
<div class="form-group">
<label>投稿する画像を選んでください</label>
<input type="file" id="file" name="file" class="form-control col-sm-4">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">アップロード</button>
</div>
</form>
@if ($errors->has('title'))
<div class="alert alert-danger" role="alert">{{$errors->first('title')}}</div>
@endif
@if ($errors->has('file'))
<div class="alert alert-danger" role="alert">{{$errors->first('file')}}</div>
@endif
@if (session('flash_message'))
<div class="alert alert-success" role="alert">{{ session('flash_message')}}</div>
@endif
</div>
@endsection
コントローラーの設定
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Post;
use App\User;
use App\Http\Requests\CreatePostRequest;
use Carbon\Carbon;
class PostsController extends Controller
{
//ログインしていないと、PostsController内の処理ができないようにする。
public function __construct() {
$this->middleware('auth');
}
public function index() {
$posts = Post::all();
return view('posts.index')->with('posts',$posts);
}
public function create() {
return view('posts.create');
}
public function store(CreatePostRequest $request) {
$nowtime = Carbon::now();
//ログインしているユーザーを取得
$user = Auth::user();
//ファイル名取得
$filename = $user->id . "_".$nowtime."_". $request->file('file')->getClientOriginalName();
//storage/app/publicにファイルを保存する
$request->file('file')->storeAs('public',$filename);
$post = new Post();
$post->title = $request->title;
$post->path = '/storage/'.$filename;
$user->posts()->save($post);
session()->flash('flash_message', '投稿が完了しました');
return redirect('posts/create');
}
}
バリデーションの設定をする。
バリデーション用のファイルを作成する。
$ php artisan make:request CreatePostRequest
Request created successfully.
CreatePostRequestを編集する。
public function rules()
{
return [
+ 'title' => 'required',
+ 'file' => 'required|image',
];
}
+ public function messages() {
+ return [
+ 'title.required' => 'タイトルが入力されていません',
+ 'file.required' => '画像を選択してください',
+ 'file.image' => '画像ファイルを選択してください',
+ ];
コントローラーに適用する
作成したCreatePostRequestを読み込む
store()メソッドの引数に入れる。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Post;
use App\User;
+ use App\Http\Requests\CreatePostRequest;
use Carbon\Carbon;
・
・
・
+ public function store(CreatePostRequest $request) {
シンボリックリンクの作成
$ php artisan storage:link
The [public/storage] directory has been linked.
取得した画像をの一覧表示を実装する。
・やりたいこと画像のタイトルと画像の表示
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
@foreach($posts as $post)
<div class="col-md-3" style="margin-top:10px;">
<img src="{{$post->path}}" width="95%">
<h3 style="margin-top:3px;text-align:center;">タイトル:{{ $post->title}}</h3>
</div>
@endforeach
</div>
@endsection
編集モードにて削除コマンドをつける
editメソッドの作成
index.blade.phpに編集モードへのリンクを作成
@foreach($posts as $post)
<div class="col-md-3" style="margin-top:10px;">
+ <a href="{{ action('PostsController@edit',$post) }}"><img src="{{$post->path}}" width="95%"></a>
<h3 style="margin-top:3px;text-align:center;">「{{ $post->title}}」</h3>
</div>
@endforeach
PostsControlerのeditメソッドを作成
public function edit(Post $post) {
return view('posts.edit')->with('post',$post);
}
編集ビューの作成
編集ビューに削除ボタン作成
@extends('layouts.app')
@section('content')
<div class="container">
<div>
<img src="{{$post->path}}" width="80%">
</div>
<form action="{{ action('PostsController@destroy',$post)}}" method="post">
{{csrf_field()}}
{{method_field('delete')}}
<div class="row" style="margin-top:30px;">
<button type="submit" class="btn btn-danger col-sm-3">削除する</button>
</div>
</form>
</div>
@endsection
PostsControllerにdestroyメソッド(削除メソッド)作成
public function destroy(Post $post) {
$post->delete();
session()->flash('flash_message', '投稿画像を削除しました');
return redirect('/');
}
auth関連で作成したビューを日本語化する
参考記事
https://qiita.com/miya-krow/items/05170462b2f092c95dfa
config/appを変更する
'locale' => 'ja',
'fallback_locale' => 'ja',
en:Engilish
ja:Japanese
ja.jsonファイルを作成して対応する
$ vi resources/lang/ja.json
{ "Login" :"ログイン",
"Register" :"新規登録",
"Password" : "パスワード",
"E-Mail Address": "メールアドレス",
"Logout":"ログアウト",
"Name": "ニックネーム",
"Confirm Password": "パスワード(もう一度入力)"
}
その他
パスワードリセット機能は実装しないので、使えないようにする。
対象部をコメントアウトする
<!-- <div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label" for="remember">
{{ __('Remember Me') }}
</label>
</div>
</div>
</div> -->
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
<!-- @if (Route::has('password.request'))
<a class="btn btn-link" href="{{ route('password.request') }}">
{{ __('Forgot Your Password?') }}
</a>
@endif -->
</div>
urlに直接入力してら、indexに飛ばすようにする。
Route::get('/', 'PostsController@index');
Auth::routes();
+ Route::get('/password/email', function() {return redirect('/');});
+ Route::get('/password/reset', function() {return redirect('/');});
// Route::get('/home', 'HomeController@index')->name('home');
Route::resource('posts','PostsController');
以上です。