- 投稿日:2022-02-24T22:15:02+09:00
Laravelのeloquentでjoinしたときに同じカラム名でバグる可能性
aテーブルのid=1 と bテーブルのid=2でa_id=1だとして、 これをjoinすると $a = A::join('b', 'a.id', '=', 'b.a_id')->first(); とする。 このとき $a->id; // 2 となる現象が起きました。 同じidというカラム名だからっぽいです。 このままだとidをキーにするのでリレーションで辿るデータなどがうまくとれないなど発生します。 知らないと結構やらかしそうな内容です。 回避は $a = A::select('*', 'a.id as id')->join('b', 'a.id', '=', 'b.a_id')->first(); とかですね。 あとはこれを起こさないためのグローバルスコープなんかもissueに書かれてました。 trait OnlyMyColumnsTrait { public static function bootOnlyMyColumnsTrait() { static::addGlobalScope('only_my_columns', function (Builder $builder) { $builder->select($builder->getModel()->getTable().'.*'); }); } }
- 投稿日:2022-02-24T21:02:20+09:00
【Laravel】laravel-adminの導入から初期設定まで
概要 laravel-adminを利用して、インストールから初期設定までを行います。 実務でLaravelを使う機会があればlaravel-adminを使用する場面があるかもしれないのでこの機会にまずは設定をしていきます。 ※Laravelプロジェクトがインストール済みの前提で進めます。 laravel-adminとは Laravelで簡単に管理画面が構築できるライブラリです。 ドキュメントやデモサイトなど使用するために必要な資料が充実しており、難しいカスタムを行う必要がなければものすごく簡単に管理画面が構築できます。 公式ドキュメント demoサイト 実際にインストール 1. インストール $ composer require encore/laravel-admin 2. laravel-adminのファイルをプロジェクトに追加 $ php artisan vendor:publish --provider="Encore\Admin\AdminServiceProvider" 3. laravel-Adminの標準テーブルを生成 $ php artisan admin:install 4. もし管理者ログインデータが消えてしまった場合 こちらは管理者ログインデータが消えた場合に備えて、シーダーファイルを作成します。 laravel adminを実行した後にphp artisan migrate:freshなどをやると、管理者用ログインデータが消えてしまいます。 万が一に備えて、以下の記事に沿ってシーダーファイルを作成します。 管理者画面用のコントローラーを作成する 1. コントローラーの作成 公式ドキュメントには php artisan admin:make UserController --model=App\\User と記載がありますが、Laravel8系からはモデルのディレクトリがapp/Modelsになっていますので、以下コマンドを実行してコントローラーを作成します。 php artisan admin:make UserController --model=App\\Models\\User ####2. ルーティングを追記 /app/Admin/routes.php <?php use Illuminate\Routing\Router; Admin::routes(); Route::group([ 'prefix' => config('admin.route.prefix'), 'namespace' => config('admin.route.namespace'), 'middleware' => config('admin.route.middleware'), 'as' => config('admin.route.prefix') . '.', ], function (Router $router) { $router->get('/', 'HomeController@index')->name('home'); $router->resource('/users', UserController::class); //追記内容 }); これで/admin/usersにアクセスするとユーザーの一覧画面が閲覧できるようになります。 他にも/config/admin.phpで設定の変更、Admin / bootstrap.phpでコンポーネントを拡張または削除したり、フロントエンドリソースを導入したりできますが、ここでは特に設定の変更はせず、またの機会に記事にしようと思います。 最後に 今回は初期設定からほぼコードをいじらずにインストールから初期設定するという内容でした。 まだまだ勉強中ですが、色々使い方を知って記事にしていきます。
- 投稿日:2022-02-24T20:14:40+09:00
LaravelBreeze viewに至るまでの流れ
はじめに 今回は、LaravelBreeze編のpart4になっている。 ただ、part表記する意味もあまり感じなくなってきたので、今回からpart表記をなくそうと思った。 なので、partを活用していたリスナーの皆さんには、申し訳なく思っている。 ↓前回の記事 復習(part1の範囲) 最初に、PCやスマホでアクセスされると、index.phpに飛ぶ。 indexファイルは、public/index.phpの場所にある。 その後、ミドルウェアに飛び、認証されているかの確認が行われる。 認証しているかの確認をしつつ、ルーティングに飛ぶ。 ルーティングでURLのふりわけが行われ、指定された場所に飛ぶ。 コントローラ、モデル、Viewは、MVCモデル。 Laravel6の学習でも行ったが、軽く説明をすると、 モデル・・DBとのやり取りをする場所 View・・ウィンドウに、表示をする場所 コントローラ・・モデルとViewの中継点 今回の範囲 今回は、前回やったルーティングから、コントローラにアクセスする流れから入っていく。 その後、コントローラから、viewにアクセスする所までを学ぶ。 routeから、controllerへ routeであるauth.phpには、沢山のコントローラへアクセスする文が書いてある。 全て見ていてもきりがないので、今回は、AuthenticatedSessionControllerを見ていく。 ↓auth.phpの記載内容 use App\Http\Controllers\Auth\AuthenticatedSessionController; Route::get('login', [AuthenticatedSessionController::class, 'create']) ->name('login'); Route::post('login', [AuthenticatedSessionController::class, 'store']); AuthenticatedSessionControllerにあるcreate or store に送るという意味。 今回は、createの方を見ていく。 ↓AuthenticatedSessionControllerの内容 public function create() { return view('auth.login'); } viewにあるauth.loginに飛ばすといった指示が書かれている事が確認できる 画像を見たらわかる通り、controllerから、viewに飛んでいる訳である。 auth.loginは、Login画面を表示するView。 こうして、login処理が実行されると、ルート>コントローラ>Viewに渡っていき、Login画面が呼び出されている訳である。
- 投稿日:2022-02-24T19:04:44+09:00
【Laravel】論理削除(softDelete)するときにリレーション先のデータも削除する方法
概要 Laravelでは、マイグレーションファイルに外部キー制約の設定を記述しておくと、親テーブルのデータを削除したときに子テーブルのデータも同時に削除することができます。 但しこれは、DBから実際にデータを削除する「物理削除」の場合の話です。 DBからレコードを削除するわけではなく削除フラグを立てて削除したとみなす「論理削除」の場合は、マイグレーションファイルへの記述だけではリレーション先のデータを一緒に削除してくれません。 このような場合に、 モデルの boot メソッド(もしくは booted メソッド)を使って初期設定を行えば、あるテーブルのデータを論理削除したときにリレーション先のテーブルのデータも削除することができます。 業務でこの方法を使う機会があったので、 モデル boot メソッドについて勉強したこととあわせて、備忘録を書いておきたいと思います。 論理削除(softDelete)の設定方法 まず事前準備としてソフトデリートの設定をします。 ソフトデリート機能を組み込む手順は以下の2つです。 1. マイグレーションファイルにソフトデリートの設定を記述する 2. EloquentモデルにSoftDeletesトレイトを組み込む 例として users テーブルにソフトデリート機能を設定してみます。 1. マイグレーションファイルにソフトデリートの設定を記述する Laravelの論理削除ではテーブルの deleted_atカラムに値が入っている場合はデータは削除されたとみなすので、 deleted_atカラムを追加する必要があります。 deleted_atカラムを追加するため、マイグレーションファイルに以下の1行を追記します。 publicfunction up() { Schema::table('user',function (Blueprint $table) { $table->softDeletes(); // 追記 }); } これでマイグレーションを実行すると、DBのテーブルに deleted_atカラムが作成されていることが確認できます。 2. EloquentモデルにSoftDeletesトレイトを組み込む User モデルファイルに以下のように追記します。 use Illuminate\Database\Eloquent\SoftDeletes; // 追記 class User extends Model { use SoftDeletes; // 追記 } この記述により、deleteメソッドでモデルを削除した際はソフトデリートが実行されるようになります。 Laravelでソフトデリートを行うための設定は以上です。 モデルのbootedメソッドとは 本題の「ソフトデリートするときにリレーション先のデータも削除する」ための実装にあたり、先に今回使用する boooted メソッドについて少し勉強しておきます。 Laravel のモデルでは、初期起動時に boot メソッドを走らせて初期設定をしています。 booted メソッドはモデルの初期起動後に実行されるメソッドで、モデルに対して行いたい初期設定は booted メソッドに書くよう readouble にも説明があります。 【補足】bootedメソッドとbootメソッドについて 今回実装方法をググっているとbootメソッドを使っている記事が見つかり、自分としても初期起動時のメソッドといえばbootメソッドのイメージがあったので、bootedメソッドとbootメソッドについて少し調べてみました。 readouble の説明では、モデルの初期設定を行う方法としてLaravel6までは boot メソッドが使われていますが、Laravel7以降では booted メソッドが使われていました。 ・Laravel8の該当箇所 ・Laravel6の該当箇所 試しにモデルファイルに以下のように書き、 booted() のところにマウスをホバーさせてVSCodeのヒントを表示してみます。 // モデルファイルに記述 /** * @return void */ public static function booted(): void { // } // booted() にマウスをホバーさせると、以下の説明が表示される Illuminate\Database\Eloquent\Model::booted Perform any actions required after the model boots. <?php protected static function booted() { } bootedメソッドについては、 Perform any actions required after the model boots. と説明されています。 boot() を書いた場合も確認します。 // モデルファイルに記述 /** * @return void */ public static function boot(): void { // } // boot() にマウスをホバーさせると、以下の説明が出る Illuminate\Database\Eloquent\Model::boot Bootstrap the model and its traits. <?php protected static function boot() { } @return void boot メソッドは Bootstrap the model and its traits. と説明がありました。 ※実際のLaravelのソースコードだと、以下のファイルに boot メソッドも booted メソッドもありました。 興味のある方はこちらもご覧ください。 メソッド名の通りですが、 bootedメソッドはモデルの初期起動後に実行されているということですね。 私は業務ではLaravel8を使っており、 boot メソッドでも booted メソッドでも同じように設定を行うことは出来ましたが、現在の readouble の説明に従って bootedメソッドを使っていきたいと思います。 Modelのbootedメソッドにクロージャを書く 前置きが長くなりましたが、実際にモデルの booted メソッドに「データを論理削除したらリレーション先のデータも削除する」設定を記述します。 前提 users テーブル(親)と1対多で紐づく posts テーブルがあるとします。 users テーブルからレコードを論理削除したら、 リレーション先のposts テーブルからもレコードを論理削除するように設定します。 実装方法 User.phpにリレーションと bootedメソッドを追記します。 class User extends Model { use HasFactory, SoftDeletes; /** * @return HasMany */ public function posts(): HasMany { return $this->hasMany(Post::class); } /** * @return void */ public static function booted(): void { static::deleted(function ($user) { $user->posts()->delete(); }); } } これにより、 users テーブルのデータ削除時に、リレーション先の posts テーブルからも同時に削除してくれます。 ※ posts テーブルに対してもソフトデリートの設定を行っている場合は posts テーブルも論理削除、何も設定していなければ posts テーブルからは物理削除になります。 最後に 論理削除はDBのレコードを削除するわけでは無く、SQLの命令文でいうと UPDATE にあたるので、論理削除の場合はDB的には削除と見なされないということは、よく考えると当たり前でもありますが改めて勉強になりました。 またモデルの boot メソッドや booted メソッドの使い方や、これらが出来ることについても良い学びになりました。 Laravelのライフサイクルの理解を深めれば、もっともっと実装の引き出しが増えるんだろうなと思うので、コツコツ勉強していきたいと思います。 参考記事
- 投稿日:2022-02-24T18:59:09+09:00
[Laravel] HTTPS での接続を強制する
Laravel を使ったサイトをさっき検証環境、本番環境にリリースしたらHTTPとHTTPSが混在してるよ!!という事でうまく動きませんでした。 {!! Form::open(array('url' => '/login', 'role' => 'form', 'name' => 'loginForm', 'id' => 'loginForm', 'class' => 'login')) !!} こういう記述があるとHTTPSページ内にあるフォームのPOST先がHTTPになってエラーになったりします。 こちらの解決方法を以下に記します。 結論 web.php に以下を記述します。 if (App::environment('production') || App::environment('staging')) { URL::forceScheme('https'); } App::environment('production')は本番環境の.envファイルにAPP_ENV=productionと記述されている前提で動きます。 App::environment('staging')は検証環境の.envファイルにAPP_ENV=stagingと記述されている前提で動きます。 これで全てのリクエストはHTTPSに統一されます。 以上
- 投稿日:2022-02-24T15:26:35+09:00
Laravel9.x変更点
はじめに LaravelのUpgrade Guideをもとに影響度がミディアム以上のものを日本語訳もといDeepLにつっこんでみたものです。 明らかに変な日本語になってると感じたとこは自力で頑張ります。 目次 依存関係の更新 PHPの戻り値の型 アプリケーション Flysystem_3.x ヘルパー関数 HTTP Client Symfony_Mailer Packages Test Validation 依存関係の更新 PHPのバージョンは 8.0.2以上を必要とします。 composer.jsonで以下の依存関係を更新する必要があります。 laravel/framework to ^9.0 nunomaduro/collision to ^6.1 また、facade/ignitionをspatie/laravel-ignition: "^1.0"に置き換えてください。 さらに、以下のファーストパーティパッケージは、Laravel 9.x をサポートするために新しいメジャーリリースを受け取りました。 Vonage Notification Channel (v3.0)(Replaces Nexmo) 最後に、アプリケーションで利用される他のサードパーティパッケージを調べ、Laravel 9のサポートに適切なバージョンを使用しているかどうかを確認します。 PHPの戻り値の型 PHP では、offsetGet、offsetSet などの PHP メソッドに戻り値の型定義が必要になるように移行し始めています。これを踏まえて、Laravel9では、コードベースにこれらの戻り値の型を実装しています。通常、ユーザーが書いたコードには影響しませんが、Laravelのコアクラスを拡張してこれらのメソッドをオーバーライドしている場合は、これらの戻り値の型を自分のアプリケーションやパッケージのコードに追加する必要があります。 count(): int getIterator(): Traversable getSize(): int jsonSerialize(): array offsetExists($key): bool offsetGet($key): mixed offsetSet($key, $value): void offsetUnset($key): void さらに、PHP の SessionHandlerInterface を実装したメソッドに戻り値の型が追加されました。繰り返しますが、この変更があなた自身のアプリケーションやパッケージのコードに 影響を与えることはまずありません。 open($savePath, $sessionName): bool close(): bool read($sessionId): string|false write($sessionId, $data): bool destroy($sessionId): bool gc($lifetime): int アプリケーション Eloquent Custom Casts & null Laravelの以前のリリースでは、カスタムキャストクラスのsetメソッドは、キャスト属性がNULLに設定されている場合は呼び出されませんでした。しかし、この動作はLaravelのドキュメントと矛盾していました。Laravel 9.xでは、キャストクラスのsetメソッドは、提供された$value引数としてnullで呼び出されます。したがって、カスタムキャストがこのシナリオを十分に処理できるようにする必要があります。 /** * Prepare the given value for storage. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param AddressModel $value * @param array $attributes * @return array */ public function set($model, $key, $value, $attributes) { if (! $value instanceof AddressModel) { throw new InvalidArgumentException('The given value is not an Address instance.'); } return [ 'address_line_one' => $value->lineOne, 'address_line_two' => $value->lineTwo, ]; } Belongs To Many firstOrNew, firstOrCreate, updateOrCreate 関数 belongsToMany リレーションの firstOrNew、firstOrCreate、および updateOrCreate メソッドはすべて、その最初の引数として属性の配列を受け取ります。Laravelの以前のリリースでは、この属性の配列は、既存のレコードの「ピボット」/中間テーブルと比較されました。 しかし、この動作は予期しないものであり、一般的には望まれないものでした。代わりに、これらのメソッドは、関連するモデルのテーブルに対して、属性の配列を比較するようになりました。 $user->roles()->updateOrCreate([ 'name' => 'Administrator', ]); さらに、firstOrCreate メソッドの第二引数に $values 配列を指定することができるようになりました。この配列は、関連するモデルがまだ存在しない場合、作成時にメソッドの最初の引数 ($attributes) とマージされます。この変更により、このメソッドは他のリレーションシップタイプによって提供される firstOrCreate メソッドと一致するようになります。 $user->roles()->firstOrCreate([ 'name' => 'Administrator', ], [ 'created_by' => $user->id, ]); Flysystem_3.x Laravel 9.x は Flysystem 1.x から 3.x に移行しました。Flysystem は、Storage ファサードが提供するすべてのファイル操作メソッドを提供します。これを踏まえて、アプリケーション内でいくつかの変更が必要になるかもしれませんが、可能な限りシームレスに移行できるようにしました。 ドライバの前提条件 S3、FTP、またはSFTPドライバーを使用する前に、Composerパッケージ・マネージャーで適切なパッケージをインストールする必要があります。 Amazon S3: composer require -W league/flysystem-aws-s3-v3 "^3.0" FTP: composer require league/flysystem-ftp "^3.0" SFTP: composer require league/flysystem-sftp-v3 "^3.0" 既存ファイルの上書き put, write, writeStream などの書き込み操作は、デフォルトで既存のファイルを上書きするようになりました。既存のファイルを上書きしたくない場合は、書き込み操作を行う前に、手動でファイルの存在を確認する必要があります。 消えたファイルの読み込み 存在しないファイルから読み込もうとすると、null を返すようになりました。Laravelの以前のリリースでは、IlluminateContracts\Filesystem\FileNotFoundExceptionがスローされていました。 消えたファイルの削除 存在しないファイルを削除しようとすると、trueを返すようになりました。 キャッシュされたアダプタ Flysystem は、「キャッシュされたアダプタ」をサポートしなくなりました。したがって、Laravelから削除され、関連する設定(ディスク設定内のキャッシュキーなど)は削除することができます。 カスタムファイルシステム カスタムファイルシステムドライバの登録に必要な手順が若干変更されました。したがって、もしあなたが独自のカスタムファイルシステムドライバを定義していたり、カスタムドライバを定義しているパッケージを使用していた場合は、あなたのコードと依存関係を更新する必要があります。 例えば、Laravel8.xの場合、カスタムファイルシステムドライバは、以下のように登録します。 use Illuminate\Support\Facades\Storage; use League\Flysystem\Filesystem; use Spatie\Dropbox\Client as DropboxClient; use Spatie\FlysystemDropbox\DropboxAdapter; Storage::extend('dropbox', function ($app, $config) { $client = new DropboxClient( $config['authorization_token'] ); return new Filesystem(new DropboxAdapter($client)); }); ただし、Laravel 9.xでは、Storage::extendメソッドに与えられるコールバックは、IlluminateFilesystemAdapterのインスタンスを直接返す必要があります。 use Illuminate\Filesystem\FilesystemAdapter; use Illuminate\Support\Facades\Storage; use League\Flysystem\Filesystem; use Spatie\Dropbox\Client as DropboxClient; use Spatie\FlysystemDropbox\DropboxAdapter; Storage::extend('dropbox', function ($app, $config) { $adapter = new DropboxAdapter(new DropboxClient( $config['authorization_token'] );); return new FilesystemAdapter( new Filesystem($adapter, $config), $adapter, $config ); }); ヘルパー関数 when/unless関数 ご存知のように、フレームワークの様々なクラスでwhenやunlessメソッドが提供されています。これらのメソッドは、メソッドの最初の引数のブール値が true または false と評価された場合に、条件付きでアクションを実行するために使うことができます。 $collection->when(true, function ($collection) { $collection->merge([1, 2, 3]); }); したがって、Laravelの以前のリリースでは、クロージャーオブジェクト(または他のオブジェクト)に対する緩い比較は常に真と評価されるので、クロージャーをwhenまたはunlessメソッドに渡すと、条件操作が常に実行されることを意味しました。開発者は、クロージャの結果が、条件付きアクションが実行されるかどうかを決定するブール値として使用されることを期待しているので、これはしばしば予期しない結果につながりました。 そのため、Laravel9.xでは、whenやunlessメソッドに渡されたクロージャが実行され、クロージャが返す値がwhenやunlessメソッドが使用するBoolean値とみなされることになります。 $collection->when(function ($collection) { // This closure is executed... return false; }, function ($collection) { // Not executed since first closure returned "false"... $collection->merge([1, 2, 3]); }); HTTP_Client デフォルトのタイムアウト HTTPクライアントのデフォルトのタイムアウトが30秒になりました。つまり、30秒以内にサーバーから応答がない場合、例外が発生します。以前は、HTTP クライアントにデフォルトのタイムアウト長が設定されていなかったため、リクエストが無限に "hang" することがありました。 特定のリクエストに対してより長いタイムアウトを指定したい場合は、timeoutメソッドを使用して指定することができます。 $response = Http::timeout(120)->get(...); Symfony_Mailer Laravel 9.xの最大の変更点は、2021年12月をもってメンテナンスが終了したSwiftMailerから、Symfony Mailerへの移行です。しかし、この移行はお客様のアプリケーションにとって可能な限りシームレスに行えるようにしました。とはいえ、以下の変更点のリストを十分に確認し、アプリケーションが完全に互換性を持っていることを確認してください。 ドライバーの前提条件 Mailgun トランスポートを使い続けるには、アプリケーションに symfony/mailgun-mailer と symfony/http-client Composer パッケージが必要です。 composer require symfony/mailgun-mailer symfony/http-client wildbit/swiftmailer-postmark Composer パッケージは、アプリケーションから削除する必要があります。代わりに、アプリケーションは symfony/postmark-mailer と symfony/http-client のコンポーザーパッケージを必要とするはずです。 composer require symfony/postmark-mailer symfony/http-client 戻り値型の更新 send、html、text、plainの各メソッドは、メッセージを受信した受信者の数を返さなくなりました。代わりに、IlluminateMailのインスタンスが返されます。このオブジェクトは、getSymfonySentMessageメソッドまたはオブジェクトのメソッドを動的に呼び出すことによってアクセス可能なSymfonyのIntemptMailerのインスタンスを含んでいます。 Swift関数に改名 SwiftMailer に関連する様々なメソッドのうち、文書化されていないものは、Symfony Mailer に対応するものに名前が変更されました。たとえば、withSwiftMessage メソッドは withSymfonyMessage に名前が変更されました。 laravel8.x $this->withSwiftMessage(function ($message) { $message->getHeaders()->addTextHeader( 'Custom-Header', 'Header Value' ); }); laravel9.x use Symfony\Component\Mime\Email; $this->withSymfonyMessage(function (Email $message) { $message->getHeaders()->addTextHeader( 'Custom-Header', 'Header Value' ); }); Symfony Mailerのドキュメントで、SymfonyComponentのMimeEmailオブジェクトとのすべての可能なインタラクションを十分に確認してください。 Packages lang ディレクトリ 新しいLaravelアプリケーションでは、resources/langディレクトリは、プロジェクトのルートディレクトリ(lang)に配置されるようになりました。パッケージがこのディレクトリに言語ファイルを発行している場合、パッケージがハードコードされたパスではなく、app()->langPath()に発行していることを確認する必要があります。 Test assertDeleted関数 assertDeleted メソッドのすべての呼び出しを assertModelMissing に更新する必要があります。 Validation パスワードルール 与えられた入力値が認証されたユーザーの現在のパスワードと一致するかどうかを検証するパスワードルールは、current_passwordに名前が変更されました。 無効な配列キー Laravelの以前のリリースでは、Laravelのバリデータが返す「検証済み」データから検証されていない配列キーを除外するように手動で指示する必要がありました。特に、許可されるキーのリストを指定しない配列ルールと組み合わせた場合です。 しかし、Laravel 9.xでは、配列ルールで許容キーが指定されていない場合でも、検証されていない配列キーは常に「検証済み」データから除外されます。通常、この動作は最も期待される動作であり、以前のexcludeUnvalidatedArrayKeysメソッドは、後方互換性を保つために一時的な措置としてLaravel 8.xに追加されただけでした。 推奨はしませんが、アプリケーションのサービスプロバイダーのブートメソッド内で新しいincludeUnvalidatedArrayKeysメソッドを呼び出すことで、以前のLaravel 8.xの動作にオプトインすることができます。 use Illuminate\Support\Facades\Validator; /** * Register any application services. * * @return void */ public function boot() { Validator::includeUnvalidatedArrayKeys(); }
- 投稿日:2022-02-24T10:30:11+09:00
LaravelでGoogle reCAPTUREを実装するときどれを使えばいいの?
ざっくり探した使えそうなLaravel用reCAPTUREライブラリ ライブラリ GitHub⭐ 数 buzz/laravel-google-captcha 175 josiasmontag/laravel-recaptchav3 77 arcanedev/no-captcha 325 biscolab/laravel-recaptcha 345 GitHubスター数でarcanedevかbiscolabが使えそうな感じです。 arcanedevとbiscolabのどっちが良いか、検証中。 分かったら追記します。
- 投稿日:2022-02-24T10:27:51+09:00
LaravelBreeze part3 routeに書いてあることの説明
はじめに 今回は、LaravelBreeze編のpart3になっている。 part3では、routeに書いてあることの説明がメインになってくる part2をまだ見ていない人は、下記リンクから確認をしてみよう。 復習(part1の範囲) 最初に、PCやスマホでアクセスされると、index.phpに飛ぶ。 indexファイルは、public/index.phpの場所にある。 その後、ミドルウェアに飛び、認証されているかの確認が行われる。 認証しているかの確認をしつつ、ルーティングに飛ぶ。 ルーティングでURLのふりわけが行われ、指定された場所に飛ぶ。 コントローラ、モデル、Viewは、MVCモデル。 Laravel6の学習でも行ったが、軽く説明をすると、 モデル・・DBとのやり取りをする場所 View・・ウィンドウに、表示をする場所 コントローラ・・モデルとViewの中継点 今回の範囲 ルートの書き方 8.xは、前回勉強したLaravel6.xから、ルートの書き方が変化している。 まずは、新しくなった書き方を確認していこう。 Routeの読み込み use llluminate\Support\Facade\Route; ####コントローラの読み込み use App\Http\Controllers\Auth\RegisterdUserController; Routeの定義 Route::get or post('/アクセスしたいURL',[コントローラ名、メソッド名]) 例文 Route::post('register', [RegisteredUserController::class, 'store']); これは、post形式で、registerとアクセスされたときに、classというコントローラーの中にある、storeという名前のメソッドに飛ばすという意味 ->機能について Route::get or post('/アクセスしたいURL',[コントローラ名、メソッド名])の後に、 ->で文をつなげる機能も変わっているので紹介する。 ->middleware('guest') ログインしていなかったらという条件 ->name('名前') 名前付きのルートにする事が出来る。 また、認証に関しての詳しい説明は、readdoubleの方で乗っているので、参考にするとよい。
- 投稿日:2022-02-24T09:10:27+09:00
LaravelBreeze ブラウザに表示されるまでの流れ part2
はじめに 今回は、前回やったLaravelBreeze ブラウザに表示されるまでの流れを、よりくわしく見ていく。 part1をまだ見ていない人は、下記リンクから確認をしてみよう。 復習 最初に、PCやスマホでアクセスされると、index.phpに飛ぶ。 indexファイルは、public/index.phpの場所にある。 その後、ミドルウェアに飛び、認証されているかの確認が行われる。 認証しているかの確認をしつつ、ルーティングに飛ぶ。 ルーティングでURLのふりわけが行われ、指定された場所に飛ぶ。 コントローラ、モデル、Viewは、MVCモデル。 Laravel6の学習でも行ったが、軽く説明をすると、 モデル・・DBとのやり取りをする場所 View・・ウィンドウに、表示をする場所 コントローラ・・モデルとViewの中継点 今回の範囲 サービスプロバイダ・・config/app.php内の、provider, aliasesに、記載されている。 'providers' => [ /* * Laravel Framework Service Providers... */ Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, ...長いため、省略 サービスプロバイダの後に、ミドルウェアでログインしているかを確認して、確認が終わったらルーティングにわたる。 ルーティング 場所 route/web.php route/auth.php web.phpに、初期で以下の物が記載されている。 Route::get('/dashboard', function () { return view('dashboard'); })->middleware(['auth'])->name('dashboard'); require __DIR__.'/auth.php'; この文の意味は、authで、認証されている事を確認出来たら、dashboardに飛ばすという意味。 require DIR.'/auth.php'は、auth.phpの内容を読み込むといった意味になっている。 Auth・・認証(Ahthentication)や認可(Ahthorization)のこと。(サービスプロバイダでも、よく使われている) auth.php auth.phpの中身をざっくりとみていく。 use App\Http\Controllers\Auth\NewPasswordController; use App\Http\Controllers\Auth\PasswordResetLinkController; use App\Http\Controllers\Auth\RegisteredUserController; use App\Http\Controllers\Auth\VerifyEmailController; use Illuminate\Support\Facades\Route; ...長いため、省略 最初の数行は、沢山のuse文で、controllerを読み込んでいる。 その後に、Route文が続いていくが、loginだったり、forgot-passwordという文字を見て取るに、ログイン情報と、ユーザーの登録機能について書かれている事が見て取れる。 (use Illuminate\Support\Facades\Route;と打つことで、Routeが使えるようになる) Route::get('login', [AuthenticatedSessionController::class, 'create']) ->name('login'); Route::get('forgot-password', [PasswordResetLinkController::class, 'create']) 今回はここまで。 続きはpart3の方で記述していく。
- 投稿日:2022-02-24T06:34:38+09:00
Laravelでユーザー登録のVerificationNotificationメールをHTMLメールじゃなくてtextメールにして日本語化する
HTMLメールは到達率が低い HTMLメールよりテキストメールの方が一般ユーザーには到達率が高い。 しかし、Laravelの通知メールはHTMLが基本になっている。 ユーザー登録時に送信するverification noticeのメールをテキスト形式にして、日本語化する。 備考:HTMLメールがすごく嫌いな人がたまにいる。(私じゃないです) VerificationNotificationをカスタマイズ User.phpのimplementsにMustVerifyEmailを指定 class User extends Authenticatable implements MustVerifyEmail User.phpにsendEmailVerificationNotification()関数を追加 /** * メール確認通知の送信 * * @return void */ public function sendEmailVerificationNotification() { $customVerifyEmail = new CustomVerifyEmail(); $this->notify($customVerifyEmail); $customVerifyEmail->toMail($this); } 確認メールを送りたいタイミングで $user->sendEmailVerificationNotification()を呼ぶ。 CustomVerifyEmail.phpを変更 public function via($notifiable) { return ['mail']; } /** * Get the mail representation of the notification. * * @param mixed $notifiable * @return MailMessage */ public function toMail($notifiable) { $myActionText = __('Verify Email Address'); // $myActionText = "Verify Email Address" $myActionUrl = $this->verificationUrl($notifiable); $mailMessage = (new MailMessage) ->subject(__('【初回】ご登録ありがとうございます')) // ->view('emails.verify', ['myActionUrl' => $myActionUrl]) // HTMLメール化したい場合はこのコメントを外す resources/views/emails.verify.blade.phpの内容がHTMLメールで送られる ->action($myActionText, $myActionUrl); return $mailMessage; } 案内するテキストを変更する toMail関数でview('emails.verify'...)の箇所を無効化したので、 デフォルトの文面のメールが届く。 [DummyDep](http://dummydep.jp) Verify Email Address: http://dummydep.jp/email/verify/880000002/4bfd564145610aacdfd3274ebbd150ba1fbef2cf?expires=1643955584&signature=3dffc5bb10e11d1a2b5e2e3b156ee3041a272b45914a7f3e2e27c925dc9349b4 Regards, DummyDep If you’re having trouble clicking the "Verify Email Address" button, copy and paste the URL below into your web browser: [http://dummydep.jp/email/verify/880000002/4bfd564145610aacdfd3274ebbd150ba1fbef2cf?expires=1643955584&signature=3dffc5bb10e11d1a2b5e2e3b156ee3041a272b45914a7f3e2e27c925dc9349b4](http://dummydep.jp/email/verify/880000002/4bfd564145610aacdfd3274ebbd150ba1fbef2cf?expires=1643955584&signature=3dffc5bb10e11d1a2b5e2e3b156ee3041a272b45914a7f3e2e27c925dc9349b4) © 2022 DummyDep. All rights reserved. メール文をカスタマイズ メール文はこんなところにあった。vendor以下にあった。でもvendor直下を直接書き換えちゃだめ。 vendor/laravel/framework/src/Illuminate/Notifications/resources/views/email.blade.php php artisan vendor:publish --tag=laravel-mail vendor:publishでvendor以下にあるテンプレートを /resources/views/vendor/mail に持ってきてこっちを編集する。 @component('mail::message') {{-- Greeting --}} @if (! empty($greeting)) # {{ $greeting }} @else @if ($level === 'error') # @lang('Whoops!') @else # @lang('Hello!') @endif @endif {{-- Intro Lines --}} @foreach ($introLines as $line) {{ $line }} @endforeach {{-- Action Button --}} @isset($actionText) <?php switch ($level) { case 'success': case 'error': $color = $level; break; default: $color = 'primary'; } ?> @component('mail::button', ['url' => $actionUrl, 'color' => $color]) {{ $actionText }} @endcomponent @endisset {{-- Outro Lines --}} @foreach ($outroLines as $line) {{ $line }} @endforeach {{-- Salutation --}} @if (! empty($salutation)) {{ $salutation }} @else @lang('Regards'),<br> {{ config('app.name') }} @endif {{-- Subcopy --}} @isset($actionText) @slot('subcopy') @lang( "If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\n". 'into your web browser:', [ 'actionText' => $actionText, ] ) <span class="break-all">[{{ $displayableActionUrl }}]({{ $actionUrl }})</span> @endslot @endisset @endcomponent