# Laravel授業1回目
## 授業資料
[ダウンロードリンク](https://drive.google.com/drive/u/0/folders/1-tcm0fWYLFEx5kFrHt0rwLYLlvg_PGOH)
## 環境構築
### 【環境構築(bashコマンド)】
#### 1. PHPセットアップ
`sudo amazon-linux-extras install php7.2=stable`
`sudo yum install php-mbstring php-pecl-memcached php-gd php-apcu php-xml`
#### 2. データベースの準備
MaryaDB 構築
`sudo amazon-linux-extras install -y lamp-mariadb10.2-php7.2`
MariaDBのインストール
`sudo yum install -y mariadb-server`
#### 3. MariaDBの起動&初期設定
`sudo systemctl start mariadb`
`sudo mysql_secure_installation`
MaridaDBの自動起動を有効化
`sudo systemctl enable mariadb`
`sudo systemctl is-enabled mariadb`
#### 4. Composerインストール
`curl -sS https://getcomposer.org/installer | php`
`sudo mv composer.phar /usr/bin/composer`
`composer`
#### 5. Laravelインストール
`composer create-project laravel/laravel cms 6.* --prefer-dist`
#### 6. サーバーの起動とLaravelプロジェクトの起動チェック
#ディレクトリ移動
`cd cms`
#BuiltInサーバーを起動:動作確認
`php artisan serve --port=8080`
*Cloud9の画面上部の緑の起動ボタンの左側Previewボタン>Preview Running Applicationをクリック
右下に画面が起動してLaravelの文字が確認できたらOK (編集済み)
### 【データベースの作成】
`mysql -u root -p`
`root [Enterキー]`
`create database c9;`
`show databases; `
`exit;`
### 【Laravelプロジェクト初期設定】
#### 1. env(ファイル内の同じ箇所を上書き)
```
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=c9
DB_USERNAME=root
DB_PASSWORD=root
```
#### 2. Composerアップデートコマンド実行
`sudo composer update`
#### 3. /app/Providers/ AppServiceProvider.php ファイルを修正
```
use Illuminate\Support\Facades\Schema; //この行を追加
use Illuminate\Support\Facades\URL; //この行を追加
public function boot() {
Schema::defaultStringLength(191); //この行を追加
URL::forceScheme('https'); //この行を追加
}
```
#### 4. 表示の仕組みをチェックしてみる!
#4-1 /resouces/views/welcome.blade.php を編集して見よう!
#4-2 ブラウザ・更新で確認 → 変更確認できればOK
### 【phpMyAdmin設定】
#### 1. cms階層からpublicフォルダに移動
`cd public`
#### 2. phpMyAdminのzipをダウンロード
`wget https://files.phpmyadmin.net/phpMyAdmin/4.8.3/phpMyAdmin-4.8.3-all-languages.zip`
#### 3. zipファイルを解凍
`unzip phpMyAdmin-4.8.3-all-languages.zip`
#### 4. cms階層に戻る
`cd ..`
> <手順解説>
> 1 publicフォルダ内に「phpMyAdmin-4.8.3-all-languages」フォルダが作成される
> 2 フォルダ名が長いので「phpMyAdmin」に変更
> 3「Preview」でサイトを開き、URLの最後に「phpMyAdmin/index.php」をつけてEnterキーを押す
> 4 URL例: https://******.cloud9.us-east-1.amazonaws.com/phpMyAdmin/index.php
> 5 phpMyAdmin画面が表示されたら: ユーザー名・パスワードともに「root」を入力してログイン
> 6 ログインできればOK
## ログイン認証
### 【ログイン認証実装】
#### 1. マイグレーションを実行
`php artisan migrate`
#### 2. laravel/ui パッケージをインストール
`composer require laravel/ui:^1.0 --dev`
#### 3. artisan コマンドを実行
`php artisan ui vue --auth`
#### 4. npmパッケージをインストール
`npm install`
#### 5. パッケージをビルド
`npm run dev`
## 本管理アプリ実装(簡単なCRUDの実装)
### 【データベースにbooksテーブルを作成する為にマイグレーション を作成】
#### 1. artisanコマンドでマイグレーション 作成
`php artisan make:migration create_books_table --create=books`
#### 2. database/migrationsの直下のbooks_table.phpに以下追記
```
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->increments('id');
$table->string('item_name');
$table->integer('item_number');
$table->integer('item_amount');
$table->datetime('published');
$table->timestamps();
});
}
```
#### 3. マイグレーション実行(テーブルの作成)
`php artisan migrate`
### 【モデルの作成】
artisanコマンドでモデル作成
`php artisan make:model Book`
#### 2.web.phpに以下二行を追記してモデルを呼び出す
```
use App\Book;
use Illuminate\Http\Request;
```
### 【ルーティングとviewの準備】
#### 1. web.phpに以下の記述を追加
```
// 本のダッシュボード表示(books.blade.php)
Route::get('/', function () {
return view('welcome');
});
// 新「本」を追加
Route::post('/books', function (Request $request) {
//
});
// 本を削除
Route::delete('/book/{book}', function (Book $book) {
//
});
```
#### 2. books.blade.php を作成して以下を追記
```
<!-- resources/views/books.blade.php -->
@extends('layouts.app')
@section('content')
<!-- Bootstrapの定形コード… -->
<div class="card-body">
<div class="card-title">
本のタイトル
</div>
<!-- バリデーションエラーの表示に使用-->
@include('common.errors')
<!-- バリデーションエラーの表示に使用-->
<!-- 本登録フォーム -->
<form action="{{ url('books') }}" method="POST" class="form-horizontal">
{{ csrf_field() }}
<!-- 本のタイトル -->
<div class="form-group">
<div class="col-sm-6">
<input type="text" name="item_name" class="form-control">
</div>
</div>
<!-- 本 登録ボタン -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-primary">
Save
</button>
</div>
</div>
</form>
</div>
<!-- Book: 既に登録されてる本のリスト -->
@endsection
```
#### 3. /resources/views/common/errors.blade.php を作成 し以下を追記
```
<!-- resources/views/common/errors.blade.php -->
@if (count($errors) > 0)
<!-- Form Error List -->
<div class="alert alert-danger">
<div><strong>入力した文字を修正してください。</strong></div>
<div>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
@endif
```
### 【登録&表示処理の実装】
#### 1. web.phpに本追加処理の基本を作成
```
Route::post('/books', function (Request $request) {
//バリデーション
$validator = Validator::make($request->all(), [
'item_name' => 'required|max:255',
]);
//バリデーション:エラー
if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}
//以下に登録処理を記述(Eloquentモデル)
});
```
#### 2. Eloquentモデルの直下に以下追記
```
// Eloquent モデル
$books = new Book;
$books->item_name = $request->item_name;
$books->item_number = '1';
$books->item_amount = '1000';
$books->published = '2017-03-07 00:00:00';
$books->save();
return redirect('/');
```
#### 3. web.php の本のダッシュボード表示を以下にアップデート
```
Route::get('/', function () {
$books = Book::orderBy('created_at', 'asc')->get();
return view('books', [
'books' => $books
]);
//return view('books',compact('books')); //も同じ意味
});
```
#### 4. /resources/views/books.blade.phpの</form>タグの下行に追記
```
<!-- 現在の本 -->
@if (count($books) > 0)
<div class="card-body">
<div class="card-body">
<table class="table table-striped task-table">
<!-- テーブルヘッダ -->
<thead>
<th>本一覧</th>
<th> </th>
</thead>
<!-- テーブル本体 -->
<tbody>
@foreach ($books as $book)
<tr>
<!-- 本タイトル -->
<td class="table-text">
<div>{{ $book->item_name }}</div>
</td>
<!-- 本: 削除ボタン -->
<td>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
```
### 【削除処理の実装】
#### 1. /resources/views/books.blade.phpの<!-- 本: 削除ボタン -->下の<td></td>要素内に追加
```
<form action="{{ url('book/'.$book->id) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="btn btn-danger">
削除
</button>
</form>
```
#### 2. web.phpにて本を削除』のルート定義を追加編集
```
Route::delete('/book/{book}', function (Book $book) {
$book->delete(); //追加
return redirect('/'); //追加
});
```
### 【更新画面表示の処理を作成】
#### 1. web.phpに更新画面表示と更新処理を追記
```
//「本」を更新画面表示
Route::get('/booksedit/{book}',function(Book $book){
return view('booksedit', ['book' => $book]);
});
//「本」を更新処理
Route::post('books/update',function(Request $request){
});
```
#### 2. books.blade.phpに更新ボタンを追記
```
<td>
<form action="{{ url('booksedit/'.$book->id) }}" method="GET"> {{ csrf_field() }}
<button type="submit" class="btn btn-primary">更新 </button>
</form>
</td>
```
#### 3. booksedit.blade.phpをviewの配下に新規作成し以下追記
```
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-md-12">
@include('common.errors')
<form action="{{ url('books/update') }}" method="POST">
<!-- item_name -->
<div class="form-group">
<label for="item_name">Title</label>
<input type="text" name="item_name" class="form-control" value="{{$book->item_name}}">
</div>
<!--/ item_name -->
<!-- Save ボタン/Back ボタン -->
<div class="well well-sm">
<button type="submit" class="btn btn-primary">Save</button>
<a class="btn btn-link pull-right" href="{{ url('/') }}"> Back</a>
</div>
<!--/ Save ボタン/Back ボタン -->
<!-- id 値を送信 -->
<input type="hidden" name="id" value="{{$book->id}}" /> <!--/ id 値を送信 -->
<!-- CSRF -->
{{ csrf_field() }}
<!--/ CSRF -->
</form>
</div>
</div>
@endsection
```
### 【更新処理の実装】
#### 1. web.phpの更新処理を以下に上書き
```
Route::post('books/update',function(Request $request){
//バリデーション
$validator = Validator::make($request->all(), [
'item_name' => 'required|max:255',
]);
//バリデーション:エラー
if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}
// Eloquent モデル
$books = Book::find($request->id);
$books->item_name = $request->item_name;
$books->item_number = '1';
$books->item_amount = '1000';
$books->published = '2017-03-07 00:00:00';
$books->save();
return redirect('/');
});
```
### 【処理をコントローラーにまとめる】
#### 1. artisanコマンドでコントローラー作成
`php artisan make:controller BooksController --resource`
#### 2. BooksController内の6行目から以下2行を追加
```
use App\Book;
use Validator;
```
#### 3. 処理を移行する
web.phpの本のダッシュボード表示処理の中身をコピー
```
Route::get('/', function () {
↓↓↓↓↓↓↓↓ここから↓↓↓↓↓↓↓↓
$books = Book::orderBy('created_at', 'asc')->get();
return view('books', [
'books' => $books
]);
//return view('books',compact('books')); //も同じ意味
↑↑↑↑↑↑↑↑ここまで↑↑↑↑↑↑↑↑
});
```
#### 4. BooksController内のindexメソッドにコピーした処理を貼り付け
```
public function index()
{
↓↓↓↓↓↓↓↓ここから貼り付け↓↓↓↓↓↓↓↓
$books = Book::orderBy('created_at', 'asc')->paginate(3);
return view('books', [
'books' => $books
]);
//return view('books',compact('books')); //も同じ意味
↑↑↑↑↑↑↑↑ここまで貼り付け↑↑↑↑↑↑↑↑
}
```
#### 5. web.phpのさっき切り取ったルーティングを以下に変更
`Route::get('/','BooksController@index');`
#### 6. その他も同様に処理を移行してweb.phpの最終完成形
```
//本 ダッシュボード表示
Route::get('/', 'BooksController@index');
//登録処理
Route::post('/books','BooksController@store');
//更新画面
Route::post('/booksedit/{books}','BooksController@edit');
//更新処理
Route::post('/books/update','BooksController@update');
//本を削除
Route::delete('/book/{book}','BooksController@destroy');
```
### 【ページネーション実装】
#### 1. BooksControllerのindexの処理を以下に変更
```
public function index() {
$books = Book::orderBy('created_at', 'asc')->paginate(3);
}
```
#### 2. books.blade.phpの@endsectionの上に以下をコピペ
```
<div class="row">
<div class="col-md-4 offset-md-4">
{{ $books->links()}}
</div>
</div>
```
#### 3. App\Http\Middleware\TrustProxiesの以下の部分を変更
```
protected $proxies; //変更前
↓
protected $proxies = '*'; //変更後
```