Laravelサンプル2

#参照
http://amzn.to/2lX8gAS

#ソース
https://github.com/takezawahiroshi/laravel8


Laravel5.3

![1.png](https://qiita-image-store.s3.amazonaws.com/0/62264/ace095bf-89e3-bebb-0337-1ac4469e44c6.png)

![2.png](https://qiita-image-store.s3.amazonaws.com/0/62264/2eb58907-05d4-1720-2a54-9ba4862bf986.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
```