参照
ソース
Laravel5.3
php artisan route:list
routes/web.php
web.php
<?php
Route::get('/', function () {
return view('home');
})->name('home');
Route::resource('users', 'UserController', ['only' => ['create', 'store', 'edit', 'update']]);
Route::resource('posts', 'PostController', ['only' => ['index', 'create', 'store', 'show', 'destroy']]);
Route::resource('posts.comments', 'CommentController', ['only' => ['create', 'store']]);
Route::get('/login', [
'uses' => 'SessionController@getLogin',
'as' => 'login'
]);
Route::post('/login', [
'uses' => 'SessionController@postLogin',
'as' => 'login'
]);
Route::get('/logout', [
'uses' => 'SessionController@getLogout',
'as' => 'logout'
]);
/var/www/html/myblog/app/Http/Controllers
CommentController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Comment;
class CommentController extends Controller
{
public function __construct() {
$this->middleware('auth');
}
public function create($postId)
{
return view('comments.create')->with('postId', $postId);
}
public function store(Request $request, $postId)
{
$this->validate($request, array(
'message' => 'required',
));
$comment = new Comment();
$comment->message = $request->message;
//CommentとPostデータを関連付ける
$comment->post_id = $postId;
//CommentとUserデータを関連付ける
$comment->user_id = Auth::user()->id;
$comment->save();
return redirect()->route('posts.show', $postId);
}
}
PostController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Post;
class PostController extends Controller
{
//middlewareメソッドを呼び出す PostControllerの全アクションは認証済みユーザーのみがアクセスを許される
public function __construct() {
$this->middleware('auth');
}
public function index(Request $request)
{
if ($request->has('word'))
{
$word = $request->word;
$posts = Post::where('message', 'LIKE', '%'.$word.'%')
->orderBy('created_at', 'desc')->get();
} else {
//ソート(新しい投稿が上に)
$posts = Post::orderBy('created_at', 'desc')->get();
}
return view('posts.index')->with('posts', $posts);
}
public function show($id)
{
$post = Post::find($id);
return view('posts.show')->with('post', $post);
}
public function create()
{
return view('posts.create');
}
//アップロードされた画像ファイルをサーバーのimagesフォルダに置く処理
//データベースにファイル名を登録する処理
public function store(Request $request)
{
$this->validate($request, array(
'message' => 'required',
'file' => 'image'
));
$post = new Post();
$post->message = $request->message;
//PostとUserのデータを関連付ける
$post->user_id = Auth::user()->id;
//新しいプロフィール画像ファイルが設定されたら古い画像を削除
if($request->hasFile('file')) {
$file = $request->file('file');
$images_path = public_path()."/images";
$newfilename = time().$file->getClientOriginalName();
$file->move($images_path, $newfilename);
$post->image = $newfilename;
} else {
$post->image = "no image";
}
$post->save();
return redirect()->route('posts.index');
}
//選択された投稿を削除するための処理
public function destroy($id)
{
$post = Post::find($id);
$post->delete();
return redirect()->route('posts.index');
}
}
SessionController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class SessionController extends Controller
{
public function getLogin()
{
return view('sessions.login');
}
public function postLogin(Request $request)
{
//ログイン処理(第1引数に認証対象の値を連想配列で指定。成功すればtrue,失敗すればfalseを返す)
//ログイン画面で入力されたemailとpasswordを使って認証
if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
return redirect()->route('posts.index');
}
return view('sessions.login');
}
public function getLogout()
{
//ログアウト
Auth::logout();
//ホームへリダイレクト
return redirect()->route('home');
}
}
UserController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
//認証
use Illuminate\Support\Facades\Auth;
use App\User;
//ファイル
use File;
class UserController extends Controller
{
//middlewareメソッドを呼び出す UserControllerの「edit」と「update」は認証済みユーザーのみがアクセスを許される
public function __construct() {
$this->middleware('auth')->only('edit', 'update');
}
//createはアクセスが許されている
public function create()
{
return view('users.create');
}
//登録のバリデーション
public function store(Request $request)
{
$this->validate($request, array(
//requiredは必須
'name' => 'required|unique:users',
'email' => 'required|email|unique:users',
'password' => 'required|min:4',
'file' => 'required|image'
));
$user = new User();
$user->name = $request->name;
$user->email = $request->email;
//bcryptを使ってハッシュ化
$user->password = bcrypt($request->password);
$file = $request->file('file');
$images_path = public_path()."/images";
//時間情報をファイル名につける
$newfilename = time().$file->getClientOriginalName();
$file->move($images_path, $newfilename);
$user->image = $newfilename;
$user->save();
Auth::login($user);
return redirect()->route('posts.index');
}
public function edit($id)
{
$user = User::find($id);
return view('users.edit')->with('user', $user);
}
//updateのバリデーション
public function update(Request $request, $id)
{
$this->validate($request, array(
'name' => 'unique:users',
'email' => 'email|unique:users',
'password' => 'min:4',
'file' => 'image'
));
$user = User::find($id);
if($request->has('name')) {
$user->name = $request->name;
}
if($request->has('email')) {
$user->email = $request->email;
}
if($request->has('password')) {
$user->password = bcrypt($request->password);
}
if($request->hasFile('file')) {
$old_image_file = public_path()."/images/".$user->image;
//削除処理
File::delete($old_image_file);
$file = $request->file('file');
$images_path = public_path()."/images";
$newfilename = time().$file->getClientOriginalName();
$file->move($images_path, $newfilename);
$user->image = $newfilename;
}
$user->save();
return redirect()->route('posts.index');
}
}
http://stackoverflow.com/questions/33842735/how-to-delete-file-from-public-folder-in-laravel-5-1
バリデーション
https://readouble.com/laravel/5.3/ja/validation
/var/www/html/myblog/app
Comment.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
Post.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
}
User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
/var/www/html/myblog/database/migrations
2014_10_12_000000_create_users_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->string('image');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
2014_10_12_100000_create_password_resets_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePasswordResetsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token')->index();
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('password_resets');
}
}
2017_02_15_091507_create_posts_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->text('message');
$table->string('image');
$table->integer('user_id')->unsigned();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
2017_02_15_101047_create_comments_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCommentsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->text('message');
$table->integer('post_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamps();
$table->foreign('post_id')
->references('id')
->on('posts')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('comments');
}
}
/var/www/html/myblog/resources/views/
/comments/create.blade.php
@extends('layouts.base')
@section('title')
コメント作成
@endsection
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1>コメント作成</h1>
//post.commentsのstoreメソッドに $postIdを渡す
<form action="{{ route('posts.comments.store', $postId) }}" method="post">
<div class="form-group">
<label for="Message">メッセージ</label>
<textarea class="form-control" name="message" id="Message" rows="5" placeholder="Your Comment"></textarea>
</div>
<button type="submit" class="btn btn-primary">送信</button>
{{ csrf_field() }}
</form>
</div>
</div>
@endsection
/layouts/base.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@yield('title')</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="{{ asset("css/mystyle.css") }}">
</head>
<body>
@include('layouts.navbar')
@include('layouts.message')
<div class="container">
@yield('content')
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script>@yield('script')</script>
</body>
</html>
/layouts/message.blade.php
@if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Errors:</strong>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if (Session::has('success'))
<div class="alert alert-success">
<strong>Success:</strong> {{ Session::get('success') }}
</div>
@endif
@if (Session::has('failure'))
<div class="alert alert-danger">
<strong>Failure:</strong> {{ Session::get('failure') }}
</div>
@endif
/layouts/navbar.blade.php
<nav class="navbar navbar-fixed-top navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{ route('home') }}">ホーム</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
//ログインチェック
@if(Auth::check())
<ul class="nav navbar-nav">
<li><a href="{{ route('posts.index') }}">投稿一覧</a></li>
</ul>
<form action="{{ route('posts.index') }}" class="navbar-form navbar-left">
<div class="form-group">
<input type="text" name="word" class="form-control" placeholder="Search Messages">
</div>
<button type="submit" class="btn btn-default">投稿検索</button>
</form>
@endif
<ul class="nav navbar-nav navbar-right">
//ログインチェック
@if(Auth::check())
<li><a href="{{ route('users.edit', Auth::user()->id) }}">{{ Auth::user()->name }}さんようこそ</a></li>
<li><a href="{{ route('logout') }}">ログアウト</a></li>
@else
<li><a href="{{ route('login') }}">ログイン</a></li>
@endif
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
/posts/create.blade.php
@extends('layouts.base')
@section('title')
メッセージ作成
@endsection
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1>メッセージ作成</h1>
<form action="{{ route('posts.store') }}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="Message">メッセージ</label>
<textarea class="form-control" name="message" id="Message" rows="5" placeholder="Your Post"></textarea>
</div>
<div class="form-group">
<label for="ImageFile">画像ファイル</label>
<input type="file" name="file" id="ImageFile">
</div>
<button type="submit" class="btn btn-primary">送信</button>
{{ csrf_field() }}
</form>
</div>
</div>
@endsection
/posts/index.blade.php
@extends('layouts.base')
@section('title')
投稿一覧
@endsection
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2 col-xs-10 col-xs-offset-1">
<div class="row">
<div class="col-xs-6">
<h2>投稿一覧</h2>
</div>
<div class="col-xs-6">
<a href="{{ route('posts.create') }}" class="btn btn-primary btn-space-20 pull-right">新しい投稿</a>
</div>
</div>
@foreach($posts as $post)
<div class="row well">
<div class="col-xs-9">
<div class="media">
<div class="media-left">
<a href="#">
//PostとUserはリレーションを持っている
<img class="media-object img-circle" src="{{ asset("images/".$post->user->image) }}" width=64 height=64>
</a>
</div>
<div class="media-body">
<h5 class="media-heading">{{ $post->user->name }} <small>{{ $post->created_at }}</small></h5>
<p>{{ $post->message }}</p>
</div>
</div>
</div>
<div class="col-xs-3">
<a href="{{ route('posts.show', $post->id) }}" class="btn btn-info btn-xs pull-right">表示</a>
//ログインしたユーザーと投稿したユーザーが同じ場合のみ削除ボタンが表示される
@if ($post->user->id === Auth::user()->id)
//destroyアクションにパラメータとして$post->idを渡している
<form action="{{ route('posts.destroy', $post->id) }}" method="post">
<input name="_method" type="hidden" value="DELETE">
<button type="submit" class="btn btn-danger btn-xs pull-right">削除</button>
{{ csrf_field() }}
</form>
@endif
</div>
</div>
@endforeach
</div>
</div>
@endsection
@section('script')
$(document).ready(function(){
$(".btn-danger").click(function(e){
if(!confirm("本当に削除しますか?")){
e.preventDefault();
return false;
}
return true;
});
});
@endsection
/posts/show.blade.php
@extends('layouts.base')
@section('title')
投稿内容
@endsection
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2 col-xs-10 col-xs-offset-1">
<div class="row">
<div class="col-xs-6">
<h2>投稿内容</h2>
</div>
<div class="col-xs-6">
//post.comments.createに $post->idを渡す
<a href="{{ route('posts.comments.create', $post->id) }}" class="btn btn-primary btn-space-20 pull-right">コメント</a>
</div>
</div>
<div class="media well">
<div class="media-left">
<a href="#">
<img class="media-object img-circle" src="{{ asset("images/".$post->user->image) }}" width=64 height=64>
</a>
</div>
<div class="media-body">
<h5 class="media-heading">{{ $post->user->name }} <small>{{ $post->created_at }}</small></h5>
<p>{{ $post->message }}</p>
@if ($post->image !== "no image")
<img src="{{ asset("images/".$post->image) }}" class="img-responsive">
@endif
<hr>
@foreach ($post->comments as $comment)
<div class="media">
<div class="media-left">
<a href="#">
<img class="media-object img-circle" src="{{ asset("images/".$comment->user->image) }}" width=64 height=64>
</a>
</div>
<div class="media-body">
<h5 class="media-heading">{{ $comment->user->name }} <small>{{ $comment->created_at }}</small></h5>
<p>{{ $comment->message }}</p>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
@endsection
/sessions/login.blade.php
@extends('layouts.base')
@section('title')
ログイン
@endsection
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1>ログイン</h1>
<form action="{{ route('login') }}" method="post">
<div class="form-group">
<label for="Email">Eメール</label>
<input type="text" name="email" class="form-control" id="Email" placeholder="Email">
</div>
<div class="form-group">
<label for="Password">パスワード</label>
<input type="password" name="password" class="form-control" id="Password" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary">ログイン</button>
{{ csrf_field() }}
</form>
</div>
</div>
@endsection
/users/create.blade.php
@extends('layouts.base')
@section('title')
登録
@endsection
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1>登録</h1>
<form action="{{ route('users.store') }}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="Name">名前</label>
<input type="text" name="name" class="form-control" id="Name" placeholder="Name">
</div>
<div class="form-group">
<label for="Email">Eメール</label>
<input type="text" name="email" class="form-control" id="Email" placeholder="Email">
</div>
<div class="form-group">
<label for="Password">パスワード</label>
<input type="password" name="password" class="form-control" id="Password" placeholder="Password">
</div>
<div class="form-group">
<label for="ImageFile">プロフィール画像ファイル</label>
<input type="file" name="file" id="ImageFile">
</div>
<button type="submit" class="btn btn-primary">登録</button>
{{ csrf_field() }}
</form>
</div>
</div>
@endsection
/users/edit.blade.php
@extends('layouts.base')
@section('title')
登録情報修正
@endsection
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1>登録情報修正</h1>
<p><strong>修正する箇所のみ入力してください</strong></p>
<form action="{{ route('users.update', $user->id) }}" method="post" enctype="multipart/form-data">
<input name="_method" type="hidden" value="PUT">
<div class="form-group">
<label for="Name">名前</label>
<input type="text" name="name" class="form-control" id="Name">
</div>
<div class="form-group">
<label for="Email">Eメール</label>
<input type="text" name="email" class="form-control" id="Email">
</div>
<div class="form-group">
<label for="Password">パスワード</label>
<input type="password" name="password" class="form-control" id="Password">
</div>
<div class="form-group">
<label for="ImageFile">新しいプロフィール画像ファイル</label>
<input type="file" name="file" id="ImageFile">
</div>
<button type="submit" class="btn btn-primary">修正</button>
{{ csrf_field() }}
</form>
</div>
</div>
@endsection
home.blade.php
@extends('layouts.base')
@section('title')
グループ交流アプリ
@endsection
@section('content')
<div class="jumbotron">
<h1>Demo APP</h1>
<p>未登録の方は下記のボタンを押して登録をお願いします。</p>
<a class="btn btn-primary" href="{{ route('users.create') }}">登録画面へ</a>
</div>
@endsection