CakePHP3:テンプレートからjsファイルを設定する

もし、デフォルトのレイアウト(default.ctp)を使っている場合はレイアウトにこの記述があります:

<?= $this->fetch('script') ?>

便利なことに、ここにスクリプトを動的に追加できます:

<?= $this->Html->script('filename', ['block' => 'script']); ?>

これでfilename.jsが読み込まれます。

CakePHP3:パスワードが現在のパスワードと同一かチェックする

これはしびれました:

stackoverflow.com

$validator
            ->add('current_password','custom',[
                'rule'=>  function($value, $context){
                    $user = $this->get($context['data']['id']);
                    if ($user) {
                        if ((new DefaultPasswordHasher)->check($value, $user->password)) {
                            return true;
                        }
                    }
                    return false;
                },
                'message'=>'The old password does not match the current password!',
            ])
            ->notEmpty('current_password');

なんでここでgetでユーザのエンティティ取れるの!?と思ったんですがよく考えたらここは UsersTable.phpなので当然、getを使えるんですよね…

CakePHP3:メールアドレスのバリデーションエラーのメッセージを変更する

Usersテーブルをbakeすると、emailのバリデーションは次のように自動生成されます:

$validator
->email('email')

バリデーションに失敗した場合はThe provided value is invalidと出ます。 これを変更するときに

$validator
->email('email','メールの形式が間違っています')

とやっても効かないのを不思議に思っていました。ドキュメントを見たら、2つ目の引数はMXレコードをチェックするか否か! よって、

$validator
->email('email',false,'メールの形式が間違っています')

であります。

CakePHP3:beforeSaveとbeforeFindにオプションを渡す

beforeSaveの場合

    public function beforeSave($event, $entity, $options)
    {
        // 何らかの処理
        return true;
    }

saveの第2引数を指定します:

if ($this->Users->save($user, ['key' => 'value'])) {

参考URL:

https://api.cakephp.org/3.6/class-Cake.ORM.Table.html#_save

beforeFindの場合

    public function beforeFind(Event $event, Query $query, $options, $primary)
    {
        // 何らかの処理
    }

applyOptionsで指定します:

this->Users->find()->applyOptions(['key' => 'value'])

CakePHP3:login.ctpをbakeする

usersテーブルを作り、./cake bake all usersと実行するとadd/edit/view/index.ctpが生成されます。 しかし先日、何かのきっかけでlogin.ctpが生成されるのを目撃してしまいました。 login.ctpを作るのは難しくないですがなぜ、生成されるときとそうでないときがあるのが気になりました。

結論ですが、UsersController.phpにloginアクションを定義後、./cake bake template usersとするとlogin.ctpが生成されます。 ./cake bake all usersの時点でloginアクションも作ってくれると便利なのに…