# Laravel授業1回目(PaizaCloud版)
## 授業資料
[ダウンロードリンク](https://drive.google.com/drive/u/0/folders/1-tcm0fWYLFEx5kFrHt0rwLYLlvg_PGOH)
## 環境構築
### 【アカウント取得】
#### 1. 以下のリンクからアカウントを作成
https://paiza.cloud/ja/
`sudo yum install php-mbstring php-pecl-memcached php-gd php-apcu php-xml`
#### 2. プランの設定
授業ではクーポンコードを使って1ヶ月間だけライトプランが使えるようになります。
無料プランでは24時間でサーバーが初期化されるので書いていたコードが消えてしまいます。
とりあえずLaravelをチュートリアル的に使ってみたい→無料プラン
本格的に開発をする場合→ライトプラン(月額980円〜)
paizaCloud上でデプロイまでしたい場合→ベーシックプラン(月額1980円〜)
### 【サーバーの立ち上げ】
#### 1. ログインが完了したら新規サーバ作成をクリックするボタンが表示されます。以下の設定でサーバー作成
```
サーバ名:デフォルトでOK
web開発:PHP,Laravel
データベース:MySQL,phpMyAdmin
その他は設定不要
```
新規作成ボタンをクリック
### 【Laravelプロジェクトの立ち上げ】
#### 1. ターミナルを立ち上げてLaravelプロジェクト作成コマンドを入力
`composer create-project laravel/laravel cms 6.* --prefer-dist`
#### 2. cms(プロジェクトディレクトリ)にターミナル上で移動
`cd cms`
#### 3. ターミナル上CMS階層でComposerコマンド実行
`sudo composer update`
#### 4. ターミナル上CMS階層でBuiltInサーバーを起動:動作確認
`php artisan serve`
server startedと表示されてURLが生成されればOKです。
左側に地球で8000番ポートでプロジェクトが立ち上がっているはずです。
ブラウザで確認までいきましょう。
### 【Laravelプロジェクト初期設定】
#### 1. データベースを作成
エディタ左側の一番上に🔽ボタンをクリックすると下の方にMySQLがあるのでStart MySQLをクリックしてMySQlを起動
phpMyAdminのタブ内のOpen phpMyAdminをクリックして起動
phpMyAdminの管理画面からc9というデータベースを作成。
```
DB名:c9
照合順:utf8mb4_general_ci
```
#### 2. env(ファイル内の同じ箇所を上書き)
*隠しファイル表示はエディタ左側ファイル階層で右クリック
```
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=c9
DB_USERNAME=root
DB_PASSWORD=
```
#### 3. /app/Providers/AppServiceProvider.php ファイルを修正
```
use Illuminate\Support\Facades\URL; //この行を追加
public function boot() {
URL::forceScheme('https'); //この行を追加
}
```
#### 4. サーバーの再起動
envファイルなどの設定を書き換えたときは必ず再起動!!
サーバー起動後のターミナル上で
`Ctrl + C`
#### 5. 表示の仕組みをチェックしてみる!
#4-1 /resouces/views/welcome.blade.php を編集して見よう!
#4-2 ブラウザ・更新で確認 → 変更確認できれば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->bigIncrements('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./routes/web.phpに以下二行を追記してモデルを呼び出す
```
use App\Book;
use Illuminate\Http\Request;
```
### 【ルーティングとviewの準備】
#### 1. /routes/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. resources/views/の直下に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::get('/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 = '*';//変更後
```