[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> また、見出し部分をクリックするとアラートが表示されることも確認。
Kentaro Nishiguchi
もしかして: Laravel
© Xzxzyzyz