LoginSignup
14
11

More than 1 year has passed since last update.

【CakePHP4】CakePHPで知ってると便利なコードまとめ

Last updated at Posted at 2020-11-11

CakePHPで知ってると便利なコードまとめ の4.x版です。
3.xと違うものだけまとめています。随時更新。
※最新版では変更になっている場合があります。

CakePHP:ver4.1.6
PHP:7.4.11

Cookbook
https://book.cakephp.org/4/ja/

Controller

ログイン中のユーザーを取得

※ cakephp/authentication使用

$this->request->getAttribute('identity'); // ユーザー情報のオブジェクト
$this->request->getAttribute('identity')->id; // ID

JSONを出力する

jsonOptionsでjson_encodeのオプションを指定できる
https://book.cakephp.org/4/ja/views/json-and-xml-views.html
※2020/12/17修正

Controller/JsonController.php
class JsonController extends AppController
{
    public function initialize(): void
    {
        parent::initialize();
        $this->loadComponent('RequestHandler');
        $this->viewBuilder()->setClassName('Json');
    }

    public function index()
    {
        $this->loadModel('Products');
        $products = $this->Products->find()
            ->where(['enabled' => 1])
            ->order(['id' => 'desc'])
            ->toArray();

        $this->set(compact('products'));

        // 配列を出力
        // $this->viewBuilder()
        //     ->setOption('serialize', ['products']);
        $this->set('_serialize', ['products']);

        // オブジェクトを出力
        // $this->viewBuilder()
        //    ->setOption('serialize', ['products'])
        //    ->setOption('jsonOptions', JSON_FORCE_OBJECT);
        $this->set('_jsonOptions', JSON_FORCE_OBJECT);
        $this->set('_serialize', ['products']);
    }
}

Model

仮想フィールド(virtualFields)

$this->_properties[field]から$this->fieldになりました

Model/Entity/User.php
class User extends Entity {
    protected $_virtual = ['name'];

    protected function _getName() {
        // last_name、first_nameをひとつにまとめてセット
        if (!$this->last_name || !$this->first_name) {
            return null;
        }
        return $this->last_name . ' ' . $this->first_name;
    }
}

認証(cakephp/authentication)

以下の手順で設定した状態です
https://book.cakephp.org/4/ja/tutorials-and-examples/cms/authentication.html

メールアドレスまたはアカウントでログイン

複数のカラムを参照したい場合は配列で指定

src/Application.php
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
    ...
    $authenticationService->loadIdentifier('Authentication.Password', [
        'fields' => [
            'username' => ['username', 'email'], // usernameまたはemailを参照
            'password' => 'password',
        ]
    ]);
}
templates/Users/login.php
<div class="users form">
    <?= $this->Flash->render() ?>
    <h3>Login</h3>
    <?= $this->Form->create() ?>
    <fieldset>
        <legend><?= __('Please enter your username and password') ?></legend>
        <?php /* フォームの名前を「username」にしておく */ ?>
        <?= $this->Form->control('username', ['required' => true]) ?>
        <?= $this->Form->control('password', ['required' => true]) ?>
    </fieldset>
    <?= $this->Form->submit(__('Login')); ?>
    <?= $this->Form->end() ?>
    <?= $this->Html->link("Add User", ['action' => 'add']) ?>
</div>

ModelとFinderを指定

認証時にFinderを通すことが出来ます

src/Application.php
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
    ...
    $authenticationService->loadIdentifier('Authentication.Password', [
        'resolver' => [
            'className' => 'Authentication.Orm',
            'userModel' => 'Users',
            'finder' => 'auth',
        ]
    ]);
}
src/Model/Table/UsersTable.php
public function findAuth($query, $options)
{
    // enabledの値が「1」のユーザーのみ許可
    $query->where([
        'enabled' => 1,
    ]);
    return $query;
}

ミドルウェア

一部でCSRF保護を無効にする

CSRF保護をある条件下でのみ無効にします。
CSFRについてはこちら
https://book.cakephp.org/4/ja/controllers/middleware.html#csrf-middleware

src/Application.php
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
    $csrf = new CsrfProtectionMiddleware(['httpOnly' => true]);
    $csrf->skipCheckCallback(function ($request) {
        // prefixが「Api」の場合無効にする
        if ($request->getParam('prefix')=='Api') {
            return true;
        }
    });
    ...
    $middlewareQueue->add($csrf);
    return $middlewareQueue;
}

プラグイン

DebugKitを強制的に表示

localじゃないけどDebugKit出したい人:raised_hand:

config/bootstrap.php
if (Configure::read('debug')) {
    ...
    Configure::write('DebugKit.forceEnable', true); //追加
}
src/Application.php
public function bootstrap(): void
{
    ...
    if (Configure::read('debug')) {
        $this->addPlugin('DebugKit');
    }
}

app.phpまたはapp_local.phpでデバッグを切り替えれば表示されます。

config/app_local.php
// trueにすると表示される
'debug' => filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN),

その他

定数設定

3.x版の書き方だとエラー出ます(当然といえば当然ですね…)
読み込み方は3.xと一緒。

※行末が「,」になっていました。正しくは「;」です

config/const.php
use Cake\Core\Configure;

define('YEAR_MIN', 1980);
define('YEAR_MAX', date('Y', strtotime('+1 year')));
define('VERSION', Configure::version());

return []; // 必ず配列を返す

メモ

  • initializeはvoid関数
  • Helperのoptionが変わっている
14
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
11