Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@Nash-BETA

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

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

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文で分岐を作るときれいにおさまる。

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Nash-BETA
2020年1月からPHPerやってます。主にCakePHPとjQueryを使う職場なのでその辺の技術を見ることが多いかな? 以前はWEBマーケターとして広告運用やサイト内改善、キュレーションメディアの運営、娯楽サービスのサイト責任者をしておりました。リーダーやマネージメント業務をやっていたりと多種多様です。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?