20200101のlaravelに関する記事は3件です。

Laravel 5.5 で remember_tokenカラムを使わない方法

Laravel5.5でremember_tokenカラムがない状態ログアウトすると、`remember_token'カラムがないとエラーでました。

User.php
<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    protected $rememberTokenName = false; //ここ

                                                                           
AuthenticatableトレイトにrememberTokenNameという、カラム名を指定できるものがあるのでこれをオーバーライドしてfalseに設定します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel5.8+fullcalendar v4+ajaxでDBと接続しeventを表示・操作

前置き

Fullcalendarをlaravelで実装している記事がネット上に少なかったように感じたので紹介します。

フロント側だけでのイベント操作は、ほとんどコード書かなくてもできますが、それだけではページを更新するたびにリセットされてしまいます。したがって今記事では、ajaxでデータを受送信し、DBの値を取得・操作してみます。

具体的には
・DBから値を取得してカレンダーにイベントを表示
・日付をクリックするとイベント追加
・イベントをドラックアンドドロップで日付変更
を実現します。

スクリーンショット 2020-01-01 0.43.04.png
↑完成イメージ↑

環境

環境を紹介

各バージョン

OS : macOS Catalina 10.15.1
PHP : 7.3.1
mysql : Ver 14.14 Distrib 5.6.42, for osx10.14 (x86_64) using EditLine wrapper
Laravel : 5.8.35
Fullcalendar : v4

Fullcalendarはバージョンが違うと動かないので気をつけてください。ネット上はにいろんな記事が落ちてると思いますが、まず最初にバージョンを確認するといいです。

データベース設計

今記事で扱うデータベースの設計です。

2019_12_30_144053_create_events_table.php
class CreateEventsTable extends Migration
{
    public function up()
    {
        Schema::create('events', function (Blueprint $table) {
            $table->string('event_id', 34)->primary();
            //僕はuuidにしてます
            $table->date('date');
            $table->string('title');
            $table->timestamps();
        });
    }
    public function down()
    {
        Schema::dropIfExists('events');
    }
}

今回はid,title,dateと最小限のカラムだけ用意しました。

js側のeventObjectのstart,endはそれぞれイベントの開始時間と終了時間を示しますが、今回、内容を簡潔化するために
・日付のみで、時間のデータは持たない
・日付は1日のみ。複数日を跨がない
ため、js側のeventObjectからはstartだけを受け取り、dateとしてテーブルに入れます。

具体的にはそれぞれ
・event_id => EV20e0e2cde562b0c8cdfad8b975dab7c6
・date => 2019-12-22
・title => 友達と遊ぶ
といったデータを想定しています。

手順

ファイル読み込み

まずfullcalendarを読み込みたいと思います。

いくつかやり方はありますが、zipファイルをダウンロードしてlaravelプロジェクトに追加する方法でやりました。
下のリンクの"Download"ってところからファイルを解凍してください。
https://fullcalendar.io/docs/getting-started

いろいろファイルがありますが、必要なのはpackage下の各ディレクトリのmain.jsとmain.cssです。(cssファイルはディレクトリによってはないこともある??)

daygridとかinteraction,timegridみたいのはプラグインの名前です。みなさんが使いたいものを選んで読み込んでください。
https://fullcalendar.io/docs/plugin-index

僕は今回、coreに加えてdaygrid,interactionを読み込みました。
概要は以下です。
core →Calendarクラスを提供
daygrid →カレンダーを月別か日別に表示
interaction → dateClick, selectableアクションが使え、eventをドラックアンドドロップ、リサイズができる

僕はこんな感じで設置しました。
スクリーンショット 2019-12-28 4.13.56.png

んでbladeファイルの方でこれらを読み込んで行きます。

resources/views/layouts/app.blade.php
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<script src='/js/fullcalendar/core/main.js'></script>
<script src='/js/fullcalendar/daygrid/main.js'></script>
<script src='/js/fullcalendar/interaction/main.js'></script>

<script src="/js/ajax-setup.js"></script>
<script src='/js/fullcalendar.js'></script>
<script src='/js/event-control.js'></script>
ここ上の3個はあとで使います。ファイルを作成した後、あらかじめ読み込んでおきます。

<link href='/css/fullcalendar/core/main.css' type="text/css" rel='stylesheet' />
<link href='/css/fullcalendar/daygrid/main.css' type="text/css" rel='stylesheet' />

カレンダー表示まで

んで次に任意のbladeファイルを用意して、そこに書いてください。viewはこれだけで大丈夫です。

calendar.blade.php
@extends('layouts.app')
@section('content')
    <div id="calendar"></div>
@endsection

次にjsです。さっきapp.blade.phpに読み込んだファイルに、カレンダーの設定等を書き込みます。
scriptタグで囲ってあげて、calendar.blade.phpの下に書いてもいいと思います。

public/js/fullcalendar.js
document.addEventListener('DOMContentLoaded', function() {
    var calendarEl = document.getElementById('calendar');

    var calendar = new FullCalendar.Calendar(calendarEl, {
        plugins: [ 'interaction', 'dayGrid' ],
        //プラグイン読み込み
        defaultView: 'dayGridMonth',
        //カレンダーを月ごとに表示
        editable: true,
        //イベント編集
        firstDay : 1,
        //秋の始まりを設定。1→月曜日。defaultは0(日曜日)
        eventDurationEditable : false,
        //イベントの期間変更
        selectLongPressDelay:0,
        // スマホでタップしたとき即反応
        events: [
            {
                title: 'イベント',
                start: '2019-01-01'
            }
        ],
        //一旦イベントのサンプルを表示。動作確認用。

        eventDrop: function(info){
        //eventをドラッグしたときの処理
             //editEventDate(info);
            //あとで使う関数
        },

        dateClick: function(info) {
        //日付をクリックしたときの処理
            //addEvent(calendar,info);
            //あとで使う関数
        },
    });
    calendar.render();
});

今回使用しているプロパティは一部です。他にもたくさんあるのでドキュメンや別の記事を見るといいです。
用意した関数の中に、これから処理を書いていって、ajax通信をします。
ここまででひとまずフロント側は動きました。

DBの値からeventを表示

web.php
Route::get('/setEvents', 'EventController@setEvents')

setEventsというURLにいくとEventController@setEventsが動くようrouteを設定しました。

public/js/fullcalendar.js
        events: "/setEvents";
        // eventObjectsを取得するJSONフィードのURLを指定

先ほど書いたサンプルデータではなく、上のようにDBの値を呼び出すためのURLに書き換えます。

EventController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Event;

class EventController extends Controller
{
    public function setEvents(Request $request){

        $start = $this->formatDate($request->all()['start']);
        $end = $this->formatDate($request->all()['end']);
        //表示した月のカレンダーの始まりの日を終わりの日をそれぞれ取得。

        $events = Event::select('id', 'title', 'date')->whereBetween('date', [$start, $end])->get();
        //カレンダーの期間内のイベントを取得

        $newArr = [];
        foreach($events as $item){
            $newItem["id"] = $item["event_id"];
            $newItem["title"] = $item["title"];
            $newItem["start"] = $item["date"];
            $newArr[] = $newItem;
        }
        //新たな配列を用意し、 EventsObjectが対応している配列にキーの名前を変更する

        echo json_encode($newArr);
        //json形式にして出力
    }

    public function formatDate($date){
        return str_replace('T00:00:00+09:00', '', $date);
    }
    // "2019-12-12T00:00:00+09:00"のようなデータを今回のDBに合うように"2019-12-12"に整形

}

ドキュメント( https://fullcalendar.io/docs/events-json-feed )を日本語訳すると、以下のような説明があります。

FullCalendarは、新しいイベントデータが必要になるたびにURLにアクセスします。これは、ユーザーがprev / nextをクリックするか、ビューを変更すると発生します。FullCalendarは、イベントが必要な日付範囲を決定し、GETパラメーターでその情報を渡します。

今回のコードでは、"/setEvents?start=2013-12-01T00:00:00-05:00&end=2014-01-12T00:00:00-05:00"といったURLにアクセスします。ですので、controllerのアクションのRequestで、カレンダーの月別の始まりと終わりの日付が受け取れます。

これでデータベースの値を表示できました。

event操作

ajaxでCSRF保護をしてあげないと419 (unknown status)になっちゃいます。laravelのドキュメントに載ってるのをまんま書きます。
https://readouble.com/laravel/5.8/ja/csrf.html

public/js/ajax-setup.js
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

次に、fullcalendar.jsにて、もうすでに関数を書いておいたので、それらをコメントアウトを解除して、その中身を書きます。

public/js/event-control.js
function addEvent(calendar,info){
    //addEvent()を使うためにfullcalendar.jsで定義したcalendarを引数で受け取る

    var title = "サンプルイベント";
    //ホントはjsでformのvalue取得とかするんだと思いますが、説明を簡潔にするために割愛します。
    $.ajax({
        url: '/ajax/addEvent',
        type: 'POST',
        dataTape: 'json',
        data:{
            "title":title,
            "date":info.dateStr
            //日程取得
        }
    }).done(function(result) {
        calendar.addEvent({
            id:result['event_id'],
            //php側から受け取ったevent_idをeventObjectのidにセット
            title:title,
            start: info.dateStr,
        });
        //ajaxに成功したらフロント側にeventを追加で表示
    });
}

function editEventDate(info){
    var event_id = info.event.id;
    var date = formatDate(info.event.start);

    $.ajax({
        url: '/ajax/editEventDate',
        type: 'POST',
        data:{
            "id":event_id,
            "newDate":date
            //ドロップしたあとの日付をphp側に渡す
        }
    })
}

function formatDate(date) {
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();
    var newDate = year + '-' + month + '-' + day;
    return newDate;
}
//info.event.startの日付を"2019-12-12"のように整形する関数

使用したプロパティ、関数のドキュメントです。
eventClick → https://fullcalendar.io/docs/eventClick
dateClick → https://fullcalendar.io/docs/dateClick
addEvent() → https://fullcalendar.io/docs/Calendar-addEvent

web.php
Route::post('/ajax/addEvent', 'EventController@addEvent');
Route::post('/ajax/editEventDate', 'EventController@editEventDate');

各ajaxのroute設定をします。

EventController.php
public function addEvent(Request $request)
    {
        $data = $request->all();
        $event = new Event();
        $event->event_id = $this->generateId();
        //僕はmodel.phpでuuidを作成する関数を書いていましたが、みなさんはご自由に。
        $event->date = $data['date'];
        $event->title = $data['title'];
        $event->save();

        return response()->json(['event_id' => $event->event_id ]);
    }
    // ajaxで受け取ったデータをデータベースに追加し、今度はidを返す。

    public function editEventDate(Request $request){
        $data = $request->all();
        $event = Event::find($data['id']);
        $event->date = $data['newDate'];
        $event->save();
        return null;
    }
    // ajaxで受け取ったデータからデータベースの日付データを変更。

これで終わりです

参考

https://tech.arms-soft.co.jp/entry/2017/02/14/154000
https://teratail.com/questions/189446
https://github.com/oclean66/prolygon
https://teratail.com/questions/170934
https://qiita.com/SOJO/items/bb24e7d09320ea96cfc3

終わりに

いろいろググったりしましたが、結局一番ドキュメントを読みました。ある程度人の記事を読んで概要を掴んだらドキュメントをたくさん読んで自分の作りたいもの
fullcalendarのv3とv4で結構違うっぽいので気をつけてください。

自分が実際に書いたコードを記事ように整形しただけなので、厳密に動作確認できてるわけじゃないので、変なところや間違ってたりしたらコメントください。
ちなみに自分の奴はこれです (https://github.com/shlia34/MyTraining )

やる気になるんで、いいねとかストックもください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel開発時に便利なmake(Makefile)コマンド集

2020年最速の記事です?

Laravel で開発する際、よく実行する docker-compose のように長いコマンドや環境構築時に多数のコマンドを実行する機会が多くあるかと思います。

各個人でalias定義したりshellの補完機能を設定しても良いですが、共有するのは手間です。

そんな時に Makefile を用意しておくと複数のコマンドを一度に実行するようにタスク登録できて便利です。 Makefile をGitで管理しておけば共有もとても楽になります。

make コマンド

$ make --version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-apple-darwin11.3.0

make コマンドが使える環境ならokです。

Makefile 使い方

コマンドを実行するディレクトリに Makefile という名前で配置すればokです。

$ make up
# docker-compose up -d # このコマンドが実行される

Makefile 例

参照ファイル: ucan-lab/docker-laravel/Makefile

あくまでも例なので参考程度にしてください。

Makefile
up:
    docker-compose up -d
build:
    docker-compose build
create-project:
    docker-compose up -d --build
    docker-compose exec app composer create-project --prefer-dist laravel/laravel .
    docker-compose exec app composer require predis/predis
install:
    docker-compose up -d --build
    docker-compose exec app composer install
    docker-compose exec app cp .env.example .env
    docker-compose exec app php artisan key:generate
    docker-compose exec app php artisan migrate:fresh --seed
reinstall:
    @make destroy
    @make install
stop:
    docker-compose stop
restart:
    docker-compose restart
down:
    docker-compose down
destroy:
    docker-compose down --rmi all --volumes
ps:
    docker-compose ps
app:
    docker-compose exec app ash -l
fresh:
    docker-compose exec app php artisan migrate:fresh
seed:
    docker-compose exec app php artisan db:seed
tinker:
    docker-compose exec app php artisan tinker
dump:
    docker-compose exec app php artisan dump-server
test:
    docker-compose exec app php ./vendor/bin/phpunit
cache:
    docker-compose exec app composer dump-autoload -o
    docker-compose exec app php artisan optimize:clear
    docker-compose exec app php artisan optimize
cache-clear:
    docker-compose exec app php artisan optimize:clear
cs:
    docker-compose exec app ./vendor/bin/phpcs
cbf:
    docker-compose exec app ./vendor/bin/phpcbf
db:
    docker-compose exec db bash
db-testing:
    docker-compose exec db-testing bash
mysql:
    docker-compose exec db bash -c 'mysql -u $$MYSQL_USER -p$$MYSQL_PASSWORD $$MYSQL_DATABASE'
mysql-testing:
    docker-compose exec db-testing bash -c 'mysql -u $$MYSQL_USER -p$$MYSQL_PASSWORD $$MYSQL_DATABASE'
node:
    docker-compose exec node ash
npm:
    docker-compose exec node npm install
    docker-compose exec node npm run dev
yarn:
    docker-compose exec node yarn
    docker-compose exec node yarn run dev

これをベースに各プロジェクト用のコマンドを追加して使うと良い感じかなと思います。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む