Edited at

Laravelサンプル2

More than 1 year has passed since last update.


参照

http://amzn.to/2lX8gAS


ソース

https://github.com/takezawahiroshi/laravel8

Laravel5.3

1.png

2.png

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');
}
}


Like検索

http://stackoverflow.com/questions/13386774/using-eloquent-orm-in-laravel-to-perform-search-of-database-using-like


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