2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CakePHP4のテーブルが無い場合のモデルの対処、書く方法

Last updated at Posted at 2021-05-04

コントローラーにビジネスロジックを書かずにモデルに書くための方法をまとめておきます(備忘録用)。

CakePHP2ならば...

Model/User.php

<?php
App::uses('AppModel', 'Model');
/**
 * User Model
 */
class User extends AppModel {

    public $useTable = false;
.
.
.

}

上記のようにpublic $useTable = false;と記述すればテーブルを持たないモノでもロジックを書く事ができましたが、CakePHP4では下記のように書いてもエラーが返ってくる。

Model/Table/User.php
<?php
declare(strict_types=1);

namespace App\Model\Table;

use Cake\ORM\Table;

/**
 * User Model
 */
class UsersTable extends Table
{
    /**
     * Initialize method
     */
    public function initialize(array $config): void
    {
        parent::initialize($config);
        $this->setTable(false);  //エラーになる
    }
}

(CakePHP2の経験者なら必ずやるエラー。)
コアな部分を読むとわかりますが$this->setTable()はStringしか入れられず、読み込むテーブルを無効化することができない仕様になっています。
色々と調べてみると、Model/Tableではテーブルが存在しないモデルは作れないみたいです。

How to do...?

CakePHP4では、モデルのないフォームを使用することで
対処することができます。

一例で写真のバリデーションをモデルのないフォームで記述してみます。
Formの記述

Form/PhotoForm.php

<?php
namespace App\Form;

use Cake\Form\Form;
use Cake\Form\Schema;
use Cake\Validation\Validator;

/**
 * PhotoForm
 */
class PhotoForm extends Form{

    protected function _buildSchema(Schema $schema): Schema{
        return $schema
            ->addField('img',['type' => 'img']);
    }


    public function validationDefault(Validator $validator): Validator
    {
        $validator
            ->add('img','validator_msg',[
                 //自作のバリデーションの読み込み
                'rule' => [$this,'uploadValidator'],
            ]);
        return $validator;
    }

    protected function _execute(array $data): bool
    {
         $result = true;
        if (!empty($errors)) {
            $this->setErrors($errors);
            $result = false;
        }

        return $result;
    }


    /**
     * uploadValidator - 画像のバリデーション
     */
    function uploadValidator($check, array $context){

        //PHPのアップロードのバリデーション
        $error = $check->getError();
        switch ($error) {
            case UPLOAD_ERR_OK:
                break;
            case UPLOAD_ERR_INI_SIZE:
                return '10MB以下のファイルをアップロードしてください。';
            case UPLOAD_ERR_FORM_SIZE:
                return 'ファイルが大きすぎます。';
            case UPLOAD_ERR_PARTIAL:
                return 'アップロードに失敗しました。もう一度アップロードをお試しください。';
            case UPLOAD_ERR_NO_TMP_DIR:
                return 'アップロードに失敗しました。もう一度アップロードをお試しください。';
            default:
                return 'エラーが発生しました。アップロードファイルをご確認ください。';
        }
        return true;
    }
}

Contorollerの記述。

Contoroller/PhotosContoroller.php
<?php
    $data = [];
    $data['img'] = $this->request->getData('data.Photo');

    //PhotoFormをインスタンス化してバリデーションを噛ませる
    $contact = new PhotoForm();

    pr($contact->getErrors());
    //アップロードした容量が多かった場合のエラー内容
    //Array
    //(
    //    [img] => Array
    //        (
    //            [validator_msg] => 10MB以下のファイルをアップロードしてください。
    //        )
    //)

    /* アップロードエラー検出時 ⇒ 次画像のアップロード状況調査処理を中断 */
    if ($contact->execute($data)) {
        $this->Flash->warning($contact->getErrors()['img']['validator_msg']);
        break;
    }

_executeメソッドが返せる値はbool値のみなので、バリデーションで弾かれた場合false、弾かれない場合はtrueを返すように書く。
そして、Controllerにif文で分岐を作るときれいにおさまる。

2
0
0

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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?