
[Laravel] 5.6がリリースされました
先日laravel 5.6がリリースされました。新しい機能や修正点について確認しましょう。
General
Symponyのバージョン4を使うようアップデートしました
#22450
Bootstrapのバージョン4を使うようアップデートしました
#22754
#22494
25559cd
12d789d
ApplicationContractにrunningUnitTests()が追加されました
#2134
cron-expressionが2.xを使うようアップデートしました
#21637
Artisan Console
optimizeコマンドが廃止されました
#20851
queue:work実行時にJob IDが出力されるようになりました
#21204
migrate:statusコマンドが追加されました
#21391
migrate:statusを実行することで、現在のマイグレーションの情報を確認できます
call()メソッドの第3引数に$outputBufferが追加されました
#22463
migrateコマンドに--realpathオプションが追加されました
#22852
dcc6123453e792084d3eda186898ea7a1f536faa
--realpathオプションを使用することで、マイグレーションファイルを相対パスで指定できます
$ php artisan migrate --path=./tests/migrations --realpath
make:controllerコマンドに--apiオプションが追加されました
#22996
dcc6123453e792084d3eda186898ea7a1f536faa
--apiオプションを使用することで、API用のコントローラー(index, store, show, update, destroy)が作成できます
Authentication
ResetPassword::toMail()を使ってパスワードリセット時の送信メールをカスタマイズできるようになりました
6535186b0f71a6b0cc2d8a821f3de209c05bcf4f
AuthServiceProvider::policies()メソッドが追加されました
6d8e53082c188c89f765bf016d1e4bca7802b025
policies()メソッドを利用して、現在適用されているポリシーを取得できます
Blade Templates
@csrfと@methodディレクテブが追加されました
5f1984421af096ef21b7d2011949a233849d4ee3
#22912
今まで{{ csrf_field() }}や{{ method_field('PUT') }}と記述する必要があったものがディレクティブになりました。
Blade::component()メソッドを使ってカスタムディレクティブが登録できるようになりました
#22796
7c3ba0e61eae47d785d34448ca8d1e067dee6af7
より便利にコンポーネントを利用するためにcomponent()メソッドを利用してディレクティブとして名前をつけることができます。
// プロバイダなどで登録
Blade::component('components.alert', 'alert');
// Bladeでの使用例
@component('alert')
<p>This is an alert component</p>
@endcomponent
htmlspecialcharsのdouble_encodeがデフォルトで'true'になりました
7c82ff408432c56a324524712723a93df637936e
今まではdoubleEncode()メソッドがこの役割を果たしていましたが廃止され、withDoubleEncoding()メソッドとwithoutDoubleEncoding()メソッドが追加されました。
// src/Illuminate/View/Compilers/BladeCompiler.php
/**
* Set the "echo" format to double encode entities.
*
* @return void
*/
public function withDoubleEncoding()
{
$this->setEchoFormat('e(%s, true)');
}
/**
* Set the "echo" format to not double encode entities.
*
* @return void
*/
public function withoutDoubleEncoding()
{
$this->setEchoFormat('e(%s, false)');
}
Laravel5.6では、Bladeとe()ヘルパーがデフォルトで特殊文字を二重にエンコードします。これにより、基礎となるhtmlspecialcharsのデフォルトの動作に揃えられます。
以前のダブルエンコーデング防止の動作を維持したい場合はBlade::withoutDoubleEncodingを利用します。
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::withoutDoubleEncoding();
}
}
Broadcasting
購読するチャンネルをクラスとして渡せるようになりました
#22583
434b348c5dda1b04486ca6134671d83046bd5c96
043bd5e446cf737299476ea3a6498483282a9e41
Cache
RateLimiter::tooManyAttempts()から$decayMinutesの引数が削除されました
#22202
Collections
Collection@unique()メソッドにkeyを指定しなかった場合の挙動が修正されました
#21854
Collection@partition()メソッドにオペレーターの指定ができるようになりました
#22380
これによって、引数がcallbackから、keyとoperatorとvalueへ変更されました。
Collection::mapToDictionary()のパフォーマンスが改善されました
#22774
c09a0fdb92a4aa42552723b2238713bc9a9b1adb
Collection::except()がキーの配列のみで実行可能になりました
#22814
Database
マイグレーションのBlueprint@morphsとBlueprint@nullableMorphsメソッド実行時に作成されるインデックスの命名規則が変更されました
#21693
// 変更前
$this->index(["{$name}_id", "{$name}_type"], $indexName);
// 変更後
$this->index(["{$name}_type", "{$name}_id"], $indexName);
PostgreSQLでコメントが利用可能になりました
#21855
#22453
enumタイプのカラムを使用する際の挙動が変更されました
#22109
9a3d71da2278b5582d3a40857a97a905f26b901d
SQLiteGrammar::compileColumnListing()メソッドで重複したテーブルプレフィックスが防止されるよう修正されました
#22340
#22781
SQLiteで複数レコードに対するupdate()メソッドが利用可能になりました
#22366
SQLiteで実行された複数のクエリの中にサポートされていないメソッドがある場合に例外が発生するようになりました
#22364
#c877cb0cdc44243c691eb8507616a4c21a28599f
whereTime()メソッドでオペレーターが省略可能 (=) になりました
#22378
Queue利用時のデータベーストランザクションの挙動が変更されました
#22433
whereRowValues()メソッドが追加されました
#22446
whereRowValues()を使用して複数の条件を一度に指定することができます。
$builder->whereRowValues(['last_update', 'order_number'], '<', [1, 2]);
Pivot Modelのシリアライズが修正されました
#22786
8fad785de66ffaa18e7d8b9e9cd7c4465e60daac
351e3b7694a804e8d6a613288419ccabd22bc012
DetectsLostConnectionsでThrowableが投げられるようになりました
#22948
Eloquent
Queue登録時に関連モデルの内容もシリアライズ可能になりました
#21229
関連モデルがポリモーフィックの場合に内部キーを指定可能になりました
#21310
refresh()メソッド実行時に内容が同期されるようになりました
#21905
MassAssignmentException発生時のメッセージが変更されました
#22565
getDateFormat()がpublicに変更されました
#22618
BelongsToMany::getPivotClass()が追加されました
641d0875a25ff153c4b2b7292b1d6c4ea717cb66
Pivotレコード作成時に、自身の$dateFormatが正常に指定されるようになりました
a433ff8a9bcd88ddfe2335801a15c71b4d1a0a3a
BelongsToMany::withPivotValues()メソッドが追加されました
#22867
$pivotValuesが追加され、デフォルトの値を指定できます。
Eloquent EventにforceDeletedが追加されました
497a90749312b0b75fc185246c94e6150a502773
FactoryBuilder::getRawAttributes()メソッドが追加され、登録されていないfactoryが呼び出された場合に例外が発生するようになりました
#22936
一部のResourceクラスの命名が変更されました
#22969
aad6089702a2bbe89b6971b3feb3e202fea9f4d9
日付形式へのキャスティングフォーマットをカスタムできるようになりました
#22989
1f902c84b25f8799cc4f781ad549158db4167110
Eloquentのdateとdatetimeのキャストフォーマットを個別に指定することができます。
protected $casts = [
'birthday' => 'date:Y-m-d',
'joined_at' => 'datetime:Y-m-d H:00',
];
Hashing
暗号化方式にArgonが追加されました
#21885
68ac51a3c85d039799d32f53a045328e14debfea
#22087
9b4648523debeb6c8ef70811d778b9be64312bd3
Helpers
Arr::wrap()メソッドが引数がnullの場合に[]を返却するようになりました
#21745
class_uses_recursive()の戻り値のソート順が親クラスを優先するようになりました
#22537
Str::uuid()とStr::orderedUuid()メソッドが追加されました
3d39604bba72d45dab5b53951af42bbb21110cad
Str::orderedUuid()はタイムスタンプをベースとしたUUIDを生成し、データベースのインデックスキーなどに効率よく利用できます。
// The methods return a Ramsey\Uuid\Uuid object
return (string) Str::uuid();
return (string) Str::orderedUuid();
Logging
ログの出力方法が大幅に変更されました
#22635
106ac2a7a1b337afd9edd11367039e3511c85f81
7ba0c22133da7ca99d1ec1459630de01f95130c1
03f870cb0b0eefde363b8985843aba68446a407c
e691230578b010fe753f1973d5ab218a6510c0e9
新しくconfig/logging.phpが追加されました。
新しいLoggingはメッセージを複数のハンドラへ送信できるstackを用意しています。
syslogのラベルにアプリケーション名 (APP_ENV) になりました
#22267
Mail
MessageSendイベントのプロパティに$dataが追加されました
#21804
$dataに値を渡すことで、メッセージに追加の情報を付与することができるようになります。
メッセージ作成時のcallbacksの実行順序がattachmentsの前に変更されました
#22995
メール内容にHTMLの文字列を渡せるようになりました
#22809
Notifications
routeNotificationFor()メソッドを利用して通知クラスを指定可能になりました
#22289
Queues
Jobcontractにpayload()とgetJobId()メソッドが追加されました
#21303
Worker::raiseFailedJobEvent()メソッドが削除されました
#21901
RedisのQueueでblocking popが指定可能になりました
#22284
dbad05599b2d2059e45c480fac8817d1135d5da1
59234169c3b3b7a7164fda206778224311e06fe2
Requests
expectsJson()が明確なContent Typeでない場合にfalseを返すようになりました
#22506
3624d2702c783d13bd23b852ce35662bee9a8fea
Request::getSession()メソッドが追加されました
e546a5b83aa9fb5bbcb8e80db0c263c09b5d5dd6
Request::hasAny()メソッドの引数に配列が指定可能になりました
#22952
Responses
Cookie\Factoryクラスに$rawと$sameSiteのパラメーターが追加されました
#21553
Modelで新しいレコードが作成された時に201のステータスコードを返却するようになりました
#21625
ResourceクラスでオリジナルのJsonResponseを指定できるようになりました
#22455
streamDownload()メソッドが追加されました
#22777
session.secureがtrueの場合にセキュアなセッションが許可されるように変更されました
#22812
Routing
SetCacheHeadersミドルウェアが追加されました
#22389
f6f386ba6456894215b1314c0e33f956026dffec
df06357d78629a479d341329571136d21ae02f6f
ThrottleRequestsで任意の上限が指定可能になりました
#c9e61007d38f0cd5434551ebd7bf9c2a139f4e61
ミドルウェアの引数でrate_limitを直接指定することができます。
Route::middleware('auth:api', 'throttle:rate_limit,1')
->group(function () {
Route::get('/user', function () {
//
});
});
Service Container
登録時のサービスプロバイダにおけるバルクバインディングのサポート
#21961
81e29b1f09af7095df219efd18185f0818f5b698
Support
Manager::driver()メソッドが引数がnullの場合に例外を投げるようになりました
#22018
Bus\DispatchercontractにhasCommandHandler()とgetCommandHandler()とmap()メソッドが追加されました
#22958
#22986
PaginatoruseBootstrapThree()が追加されました
c919402d5847830c1b2a39529cac90251f838709
Bootstrap 3のページネーションを利用する場合はPaginator::useBootstrapThreeを使用します。
<?php
namespace App\Providers;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Paginator::useBootstrapThree();
}
}
Task Scheduling
マルチサーバーでのCron実行スケジュールが追加されました
#22216
6563ba65b65106198095f1d61f91e0ec542e98dd
この機能はCache Driverにmemcachedかredisを指定している場合にのみ利用できます。
$schedule->command('report:generate')
->fridays()
->at('17:00')
->onOneServer();
Validation
validateDimensions()メソッドでMimeTypeがimage/svg+xmlのSGVが許可されるようになりました
#21390
validate()メソッドがvalidateResolved()に名称変更されました
33d864240a770f821df419e2d16d841d94968415
Testing
PHPUnit 7を使用するようになりました
#23005
Json Helper使用時に特定のキーを指定可能になりました
#22489
RefreshDatabaseトレイトでDatabaseTransactionsトレイトを利用するようになりました
#22596
assertSeeInOrder()とassertSeeTextInOrder()メソッドが追加されました
#22915
#23038
https://github.com/laravel/framework/releases/tag/v5.6.0

[Laravel] パスワード変更時に他のデバイスでログインしているアカウントをログアウトさせる
Laravelの認証システムを利用していて、パスワード変更時に他のデバイスでログインしているアカウントを強制的にログアウトさせたいと思ったことはありませんか?
この問題を解決するために5.4移行のバージョンには\Illuminate\Session\Middleware\AuthenticateSessionミドルウェアが実装されています。
\App\Http\Kernelから抜粋 (デフォルトではコメントアウトされていて無効になっています)
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
使い方
\App\Http\Kernelのコメントアウトを外すだけです。
それだけでパスワード変更時に他のデバイスでログインしているアカウントを強制的にログアウトさせることができます。
仕組み
\Illuminate\Session\Middleware\AuthenticateSessionのhandleメソッドを見ていきましょう。
ユーザーがまだ認証されていない場合 ($request->user()メソッドでログインを試みる) や、セッションが無効な場合 (APIなど) にはミドルウェアを通過します。
if (! $request->user() || ! $request->session()) {
return $next($request);
}
Laravelの認証システムではremember meの機能が標準で用意されています。
この仕組みはブラウザのCookieを利用し、Cookie情報の中に暗号化したユーザーの認証情報を保持しています。
ユーザーの識別番号 (ユーザーID等)
rememberトークン
ユーザーのハッシュパスワード
ここではCookieからパスワードハッシュを取得し、現在のユーザーのパスワードハッシュと比較します。一致しない場合(ユーザーがパスワードを変更した)、認証されたユーザーをログアウトします。
if ($this->auth->viaRemember()) {
$passwordHash = explode('|', $request->cookies->get($this->auth->getRecallerName()))[2];
if ($passwordHash != $request->user()->getAuthPassword()) {
$this->logout($request);
}
}
セッションにパスワードハッシュがない場合、認証されたユーザーのパスワードハッシュがセッションに格納されます。次の部分ではなぜそれをするのか説明します。
if (! $request->session()->has('password_hash')) {
$this->storePasswordHashInSession($request);
}
セッションに保存されているパスワードハッシュが認証されたユーザーのパスワードハッシュと一致しない場合(ユーザーがパスワードを変更した)、認証されたユーザーをログアウトします。
ここでは、パスワードを変更した後でも、他のデバイスでのログインセッションは継続しています。
if ($request->session()->get('password_hash') !== $request->user()->getAuthPassword()) {
$this->logout($request);
}
最後に、リクエストが終了し結果を返す前に、セッションにパスワードハッシュを保存します。
もう一度やり直す理由は、ユーザーがそのリクエスト内でパスワードを変更した可能性があり、その結果新しいパスワードハッシュが生成される可能性があるからです。
パスワードハッシュを保存していないと、パスワードを変更した後にシステムからログアウトさせられます。
return tap($next($request), function () use ($request) {
$this->storePasswordHashInSession($request);
});
このように\Illuminate\Session\Middleware\AuthenticateSessionミドルウェアは、セッション認証を利用し、ユーザーのパスワードが変更されるたびにシステムからログアウトされます。
また、ブラウザに残っている古いCookie情報からのログインも無効になります。

[Laravel] Heroicons UIを使う
Heroicons UIには、Webサイトで利用するアイコンが揃っています。
今回はsvgのアイコンをLaravelのBladeで表示させます。
Heroicons UIのダウンロード
以下のリポジトリからソースコードをダウンロードして、public\vendor\heroicons-uiへ配置します。
sschoger/heroicons-ui
publicフォルダへ配置したので、以下のようなHTMLでアイコンの表示が可能になりました。
// ブラウザアイコンを表示
<img src="{{ asset('vendor/heroicons-ui/svg/icon-browser.svg') }}" />
Blade SVGのインストール
composerで以下のパッケージをインストールしてください。
adamwathan/blade-svg
Blade SVGパッケージは、インラインSVGまたはSVGスプライトを使用するための新しいディレクティブを追加します。
詳しい使い方については readme.md を参照してください。
# インストール
$ composer require nothingworks/blade-svg
# 設定ファイルの公開
$ php artisan vendor:publish --provider="BladeSvg\BladeSvgServiceProvider"
config/app.phpへ追記します。
// ...
'providers' => [
// ...
BladeSvg\BladeSvgServiceProvider::class,
// ...
],
// ...
config/blade-svg.phpを以下のように記述します。
<?php
return [
/*
|--------------------------------------------------------------------------
| SVG Path
|--------------------------------------------------------------------------
|
| This value is the path to the directory of individual SVG files. This
| path is then resolved internally. Please ensure that this value is
| set relative to the root directory and not the public directory.
|
*/
'svg_path' => 'public/vendor/heroicons-ui/svg',
/*
|--------------------------------------------------------------------------
| Spritesheet Path
|--------------------------------------------------------------------------
|
| If you would rather have one spritesheet than a lot of individual SVG
| files, you may specify a path to a spritesheet. The SVG images are
| extracted from this spritesheet to be rendered out individually.
|
*/
'spritesheet_path' => 'resources/assets/svg/spritesheet.svg',
/*
|--------------------------------------------------------------------------
| Spritesheet URL
|--------------------------------------------------------------------------
|
| If you don't want to embed the spritesheet directly in your markup and
| would rather reference an external URL, you can specify the path to
| the external spritesheet to use with this configuration option.
|
*/
'spritesheet_url' => '',
/*
|--------------------------------------------------------------------------
| Inline Rendering
|--------------------------------------------------------------------------
|
| This value will determine whether or not the SVG should be rendered inline
| or if it should reference a spritesheet through a <use> element.
|
| Default: true
|
*/
'inline' => true,
/*
|--------------------------------------------------------------------------
| Optional Class
|--------------------------------------------------------------------------
|
| If you would like to have CSS classes applied to your SVGs, you must
| specify them here. Much like how you would define multiple classes
| in an HTML attribute, you may separate each class using a space.
|
| Default: ''
|
*/
'class' => 'icon',
];
Bladeテンプレートを変更する
resources/views/welcome.blade.phpを変更します。
(Laravelインストール時にトップページで表示されるファイルです)
// 90行目あたりを変更
<div class="links">
<a href="https://laravel.com/docs">
@svg('icon-browser') Documentation
</a>
<a href="https://laracasts.com">
@svg('icon-video') Laracasts
</a>
<a href="https://laravel-news.com">
@svg('icon-news') News
</a>
<a href="https://forge.laravel.com">
@svg('icon-cog') Forge
</a>
<a href="https://github.com/laravel/laravel">
@svg('icon-code') GitHub
</a>
</div>
サーバーを起動して確認してみましょう。
SVGアイコンが表示されました!
また、以下のようなcssを追加してみましょう。
// 65行目あたりを変更
<style>
//...
.icon {
fill: red;
}
</style>
SVGアイコンの色が変わりました!
最後に
Heroicons UIのチートシートです。(画像)

[Laravel] リクエストされた複数の値をまとめて存在確認する
以前から可能だったようですが、公式ドキュメントが更新されたのでメモ。
When given an array, the has method will determine if all of the specified values are present:
if($request->has(['name','email'])) {
//
}
また、引数として複数渡しも可能なようです。
if($request->has('name','email')) {
//
}
Illuminate\Http\Concerns\InteractsWithInput@has
...
/**
* Determine if the request contains a non-empty value for an input item.
*
* @param string|array $key
* @return bool
*/
public function has($key)
{
$keys = is_array($key) ? $key : func_get_args();
foreach ($keys as $value) {
if ($this->isEmptyString($value)) {
return false;
}
}
return true;
}
...

[Laravel] withDefaultを使用した関連モデルの初期化
Eloquentモデルにおいて、belongsToでリレーションを行なっているモデルが存在しない場合にNULLが返却されていましたが、モデルのインスタンスを返却できるメソッドwithDefaultが追加されました。
関連するユーザーモデルが存在しない場合に、ユーザーモデルのインスタンスが返却されます。
/**
* Get the author of the post.
*/
public function user()
{
return $this->belongsTo('App\User')->withDefault();
}
また、初期値を代入することが可能です。
/**
* Get the author of the post.
*/
public function user()
{
return $this->belongsTo('App\User')->withDefault([
'name' => 'Guest Author',
]);
}
/**
* Get the author of the post.
*/
public function user()
{
return $this->belongsTo('App\User')->withDefault(function ($user) {
$user->name = 'Guest Author';
});
}

[Laravel] createManyを使用した複数代入
createManyメソッドの存在を知らなかったのでメモ。
LaravelのEloquentで1対多の関係にあるテーブルに対して複数件のレコードを挿入します。
ユーザーに対して複数のタスクを登録するサンプルです。
ユーザー周りは既存のものをそのまま利用し、タスクモデルとマイグレーションファイルを作成します。
$ php artisan make:model Task --migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTasksTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->string('title');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tasks');
}
}
$ php artisan migrate
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2017_06_25_000000_create_tasks_table
Migrated: 2017_06_25_000000_create_tasks_table
App/Task.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
protected $fillable = ['title'];
}
コントローラーを作成してルーティングを変更します。
$ php artisan make:controller CreateManyController
routes/web.php
...
Route::get('/', 'CreateManyController@index');
...
CreateManyController
<?php
namespace App\Http\Controllers;
use App\User;
class CreateManyController extends Controller
{
public function index()
{
$user = factory(\App\User::class)->create();
$user->tasks()->createMany([
['title' => 'First task.'],
['title' => 'Second task.'],
['title' => 'Third task.'],
]);
return view('create_many')->with('users', User::all());
}
}
resources/views/create_many.blade.php
<!doctype html>
<html>
<head>
<title>:CreateMany</title>
</head>
<body>
@foreach($users as $user)
<h2>{{ $user->name }}</h2>
<ul>
@foreach($user->tasks as $task)
<li>{{ $task->title }}</li>
@endforeach
</ul>
@endforeach
</body>
</html>
/へアクセスすると、新しいユーザーが作成され、ユーザーに紐づくタスクが追加されます。

[Laravel] updated_atの更新を無効化する方法
Laravelでのデータベース更新クエリでupdated_atを更新したくない、カラムが存在しない場合など。
既存のEloquentモデルでは下記の用に自動で挿入されます。
Illuminate\Database\Eloquent\Concerns\HasTimestamps
...
/**
* Update the creation and update timestamps.
*
* @return void
*/
protected function updateTimestamps()
{
$time = $this->freshTimestamp();
if (! $this->isDirty(static::UPDATED_AT)) {
$this->setUpdatedAt($time);
}
if (! $this->exists && ! $this->isDirty(static::CREATED_AT)) {
$this->setCreatedAt($time);
}
}
/**
* Set the value of the "created at" attribute.
*
* @param mixed $value
* @return $this
*/
public function setCreatedAt($value)
{
$this->{static::CREATED_AT} = $value;
return $this;
}
/**
* Set the value of the "updated at" attribute.
*
* @param mixed $value
* @return $this
*/
public function setUpdatedAt($value)
{
$this->{static::UPDATED_AT} = $value;
return $this;
}
...
updated_atを更新したくないモデルで以下のようにオーバーライドします。
/**
* `updated_at`の自動挿入の無効化
*
* @param mixed $value
* @return $this
*/
public function setUpdatedAt($value)
{
return $this;
}
created_atに関しても同じように対応可能です。

[Laravel] 認証周りのイベントまとめ
Laravel5.4での認証周りで発火されるイベントが変わっていたのでまとめ。
各プロパティへは $this->event->{プロパティ名}でアクセス出来る。
\Illuminate\Auth\Events\Registered
Illuminate/Auth/Events/Registered | Laravel API
ユーザーが作成された時に発火
\Illuminate\Foundation\Auth\RegistersUsers
...
/**
* Handle a registration request for the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
...
\Illuminate\Auth\Events\Attempting
Illuminate/Auth/Events/Attempting | Laravel API
ユーザーが認証を試みた場合に発火
Illuminate\Auth\SessionGuard
...
/**
* Attempt to authenticate a user using the given credentials.
*
* @param array $credentials
* @param bool $remember
* @return bool
*/
public function attempt(array $credentials = [], $remember = false)
{
$this->fireAttemptEvent($credentials, $remember);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials)) {
$this->login($user, $remember);
return true;
}
// If the authentication attempt fails we will fire an event so that the user
// may be notified of any suspicious attempts to access their account from
// an unrecognized user. A developer may listen to this event as needed.
$this->fireFailedEvent($user, $credentials);
return false;
}
...
\Illuminate\Auth\Events\Failed
Illuminate\Auth\Events\Failed | Laravel API
ユーザーが認証を試みたが、失敗した場合に発火
Illuminate\Auth\SessionGuard
...
/**
* Attempt to authenticate a user using the given credentials.
*
* @param array $credentials
* @param bool $remember
* @return bool
*/
public function attempt(array $credentials = [], $remember = false)
{
$this->fireAttemptEvent($credentials, $remember);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials)) {
$this->login($user, $remember);
return true;
}
// If the authentication attempt fails we will fire an event so that the user
// may be notified of any suspicious attempts to access their account from
// an unrecognized user. A developer may listen to this event as needed.
$this->fireFailedEvent($user, $credentials);
return false;
}
...
\Illuminate\Auth\Events\Login
Illuminate\Auth\Events\Login | Laravel API
ユーザーが認証を試みて、成功した場合に発火
Illuminate\Auth\SessionGuard
...
/**
* Log a user into the application.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param bool $remember
* @return void
*/
public function login(AuthenticatableContract $user, $remember = false)
{
$this->updateSession($user->getAuthIdentifier());
// If the user should be permanently "remembered" by the application we will
// queue a permanent cookie that contains the encrypted copy of the user
// identifier. We will then decrypt this later to retrieve the users.
if ($remember) {
$this->ensureRememberTokenIsSet($user);
$this->queueRecallerCookie($user);
}
// If we have an event dispatcher instance set we will fire an event so that
// any listeners will hook into the authentication events and run actions
// based on the login and logout events fired from the guard instances.
$this->fireLoginEvent($user, $remember);
$this->setUser($user);
}
...
\Illuminate\Auth\Events\Logout
Illuminate\Auth\Events\Logout | Laravel API
ログアウトした場合に発火
Illuminate\Auth\SessionGuard
...
/**
* Log the user out of the application.
*
* @return void
*/
public function logout()
{
$user = $this->user();
// If we have an event dispatcher instance, we can fire off the logout event
// so any further processing can be done. This allows the developer to be
// listening for anytime a user signs out of this application manually.
$this->clearUserDataFromStorage();
if (! is_null($this->user)) {
$this->cycleRememberToken($user);
}
if (isset($this->events)) {
$this->events->dispatch(new Events\Logout($user));
}
// Once we have fired the logout event we will clear the users out of memory
// so they are no longer available as the user is no longer considered as
// being signed into this application and should not be available here.
$this->user = null;
$this->loggedOut = true;
}
...
\Illuminate\Auth\Events\Authenticated
Illuminate\Auth\Events\Authenticated | Laravel API
クッキーから自動ログインした場合や、システム側でログイン状態にした場合に発火
Illuminate\Auth\SessionGuard
...
/**
* Set the current user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return $this
*/
public function setUser(AuthenticatableContract $user)
{
$this->user = $user;
$this->loggedOut = false;
$this->fireAuthenticatedEvent($user);
return $this;
}
...
/**
* Set the current user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return $this
*/
public function setUser(AuthenticatableContract $user)
{
$this->user = $user;
$this->loggedOut = false;
$this->fireAuthenticatedEvent($user);
return $this;
}
...
\Illuminate\Auth\Events\Lockout
Illuminate\Auth\Events\Lockout | Laravel API
ユーザーがロックされた場合に発火
Illuminate\Foundation\Auth\AuthenticatesUsers
...
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response
*/
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
...

nvmを利用したNode.jsのインストール
nvmを利用することで、複数のVersionのNode.jsを管理することができます。
※ Ubuntuへのインストール
ビルドに必要なパッケージのインストール
$ sudo apt-get update
$ sudo apt-get install build-essential libssl-dev
nvmのインストール
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.2/install.sh | bash
Git Hub ページからインストールスクリプトを取得して実行します。
完了後、に~/.bash_profile, ~/.zshrc, ~/.profileのいずれかにPathが追加されるので、ターミナルを再起動します。
nvmの使い方
インストール可能なNode.js を確認するには、nvm ls-remoteコマンドを実行します。
$ nvm ls-remote
......
v0.11.15
v0.11.16
v0.12.0
v0.12.1
v0.12.2
v0.12.3
iojs-v1.0.0
iojs-v1.0.1
.......
好きなVersionのNode.jsをインストールするには、nvm installコマンドを実行します。
$ nvm install v4.2.4
デフォルトでNode.jsのVersionは最新のものが使われます。
特定のVersionを使う場合は、nvm useコマンドを実行します。
$ nvm use 0.12.3
Now using node v0.12.3 (npm v2.9.1)
$ node -v
v0.12.3
node で管理されているれているNode.jsのVersionを確認するには、nvm lsコマンドを実行します。
$ nvm ls
-> v0.12.3
node -> stable (-> v0.12.3) (default)
stable -> 0.12 (-> v0.12.3) (default)
iojs -> iojs- (-> N/A) (default)
デフォルトで使用するnode のバージョンを指定するには、nvm alias defaultコマンドを実行します。
$ nvm alias default 0.12.3
default -> 0.12.3 (-> v0.12.3)
現在、デフォルトとして指定されているNode.js のVersion明示的に使用するように指定する場合は、nvm use defaultコマンドを実行します。
$ nvm use default
Now using node v0.12.3 (npm v2.9.1)
Ubuntu でapt を使用してNode.js をインストールする3 つの方法(Ubuntu 15.04, Ubuntu 14.04.2 LTS) - Qiita

[Laravel] Reactのサーバーサイドレンダリング
PHPでのJavascriptのServer Side Renderringの方法としては、
PHPで行う
Node.jsなどでパースしたものを受け取る
のどちらかで実装しているみたい。
今回は1.のPHPで行ってみます。
便利そうなパッケージがあったので使います。
react-laravel
Composerでインストール
Installationの項目にある"minimum-stability": "dev"をcomposer.jsonへ追記してreact-laravelをインストール。
$ composer require talyssonoc/react-laravel
$ php artisan vendor:publish
config/app.phpにReact\ReactServiceProviderのプロバイダーを追記します。
なお、PHPのExtenstionとしてv8jsが必要
NPMのインストール
Reactを利用するだけであれば必要なさそうでしたが、JSXを利用する為には1度コンパイルする必要があるので必要なものを入れます。
package.json
{
"private": true,
"devDependencies": {
"gulp": "^3.8.8"
},
"dependencies": {
"buble": "^0.12.5",
"buble-loader": "^0.2.2",
"laravel-elixir": "^6.0.0-9",
"laravel-elixir-webpack-official": "^1.0.2",
"react": "^15.3.0",
"react-dom": "^15.3.0",
"webpack": "^1.13.1"
}
}
$ npm install
gulpの設定
react-jsでのJavascriptの読み込みが、デフォルトではpublic/js/componentsなので、ここにJavascriptファイルがコンパイルされるよう追記します。
gulpfile.js
elixir(function(mix) {
mix.sass('app.scss')
.webpack('components.js');
});
コンポーネント作成
以下のファイルを作成してビルドします。
resources/js/components/WelcomeComponent.js
import React, { Component } from 'react';
class WelcomeComponent extends Component {
constructor(props, context) {
super(props, context);
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
alert(this.props.title);
}
render() {
return (
<div classname="title" onclick="{this.handleClick}">{this.props.title}</div>
);
}
}
export default WelcomeComponent;
resources/js/components.js
import WelcomeComponent from './components/WelcomeComponent';
var glob = typeof window !== "undefined" ? window : global;
glob['Welcome'] = WelcomeComponent;
作成後にコンパイル
$ gulp
Bladeファイルの編集
resources/view/welcome.blade.php
<title>Laravel</title>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"><style>
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
width: 100%;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
}
</style><div class="container">
<div class="content">
@react_component('Welcome', [ 'title' => 'Laravel 5' ])
</div>
</div>
<script src="%7B%7B%20asset('vendor/react-laravel/react.js')%20%7D%7D"></script><script src="%7B%7B%20asset('vendor/react-laravel/react-dom.js')%20%7D%7D"></script><script src="%7B%7B%20asset('js/components.js')%20%7D%7D"></script><script src="%7B%7B%20asset('vendor/react-laravel/react_ujs.js')%20%7D%7D"></script>
動作確認
HTMLソース上に表示されました!
<div data-react-class="Welcome" data-react-props='{"title":"Laravel 5"}'><div class="title" data-reactid=".28w8vglweoy" data-react-checksum="-1540418249">Laravel 5</div></div>
また、見出し部分をクリックするとアラートが表示されることも確認。



