CakePHP3を触ってみました 〜届け愛のエラーメッセージ〜

今にして思えば良い歌多かったなぁ

おまとめ三行

ロウで固めた鳥の羽を両手に持って飛び立ったのも、今は遠い昔の記憶
Formヘルパーには、エラーメッセージを表示する機能がちゃんとある
この記事書きながら、久しぶりにいろいろ聞き込んじゃったよ

とどけ〜あい〜のめ〜っせ〜じ〜♪

中学の時の文化祭で、マイバラードっていう歌を歌ったんですけど、あの歌、結構好きでした。

俺の中で、「〇〇バラード」っていうタイトルの歌は、良い歌が多いという印象がありますね。怪獣のバラードとか、虹と雪のバラードとか。

っていうか、バラードに関係なく、音楽の授業でやった歌って、良い歌多かったよなぁ……夢の世界を、瑠璃色の地球、翼をください、グリーングリーン……何もかもみな懐かしい。ロウで固めた鳥の羽を両手に持って飛び立ったのも、今は遠い昔の記憶。



まあそんなことはともかく、以前、バリデーションの処理について書いたことがありました。

バリデーションのバリエーション

あの時、バリデーションに引っかかった時のエラーメッセージは、CakePHP2と3で、それぞれ以下の部分に格納されているってなことを言いました。

//CakePHP2
$this->validationErrors

//CakePHP3
$entity->errors()

だからビューでエラーメッセージを表示する場合は、この変数からメッセージを取り出して使おうってな感じの言い方をしました。実際僕もそうやって使ってたんですが、Formヘルパーには、エラーメッセージを表示する機能がちゃんとあるんですよね。使ったことなかったんで、すっかり忘れてたわ。

なので、今日はそれでエラーメッセージを表示してみましょう。2でも3でも使い方は一緒なのですが、ほんのちょっ〜ち、フォームの書き方が異なるので、注意が必要っす。



CakePHP2

とりあえずコードを書いてみます。usersというテーブルにnameというカラムがあると思ってください。そこに名前を入れたいのだけど、未入力だとエラーになるっていう感じ。

//UsersController.php
class UsersController extends AppController {
  public function index() {
    if($this->request->is('post')) {
      $this->User->create($this->request->data);
      if($this->User->validates()) {
        //エラーなし、登録処理
      }
    }
  }
}

//User.php
class User extends AppModel {
  $validate = array(
    'name' => array(
      'rule' => 'notEmpty',
      'message' => '未入力です',
    ),
  );
}

//index.ctp
<?php echo $this->Form->create('User') ?>
  <?php echo $this->Form->text('name') ?>
  <?php echo $this->Form->error('name') ?>
<?php echo $this->Form->end() ?>

だいたいこんな感じ?

ビューの中に「$this->Form->error(‘name’)」というのがありますが、こいつを書いとけば、エラーがある場合に、メッセージを表示してくれます。今回はエラーの条件がnotEmptyの一つだけですが、もちろん複数書いた場合も、条件に該当するエラーメッセージを出してくれます。

<input name="data[User][name]" class="form-error" type="text" value="" id="UserName" />
<div class="error-message">未入力です</div>

デフォルトの設定だと、divで囲われたメッセージが表示されます。なので、CSSでerror-messageクラスのstyleを書いとけば、赤文字で表示したりできます。

もしdivタグを出したくないときや、div以外のタグで表示したいってときは、第三引数でwrapというオプションを設定すれば良い。

//divタグを出さない場合
<?php echo $this->Form->error('name', null, array('wrap' => false)) ?>

//divタグをpタグに変える場合
<?php echo $this->Form->error('name', null, array('wrap' => 'p')) ?>

ついでに言うと、エラー時はテキストボックスの方にも「form-error」というクラスが自動で付与されるので、そっちにもCSSを書いとけば、ボックスを赤く囲ったりできる。



CakePHP3

CakePHP3でも、基本は一緒です。ただし、フォームヘルパーのcreate()の書き方に、ちょい気をつけるべし。

//UsersController.php
namespace App\Controller;
use Cake\ORM\TableRegistry;

class UsersController extends AppController {
  public function index() {
    $table = TableRegistry::get('Users');
    $entity = $table->newEntity($this->request->data);

    if($this->request->is('post')) {
      if(!$entity->errors()) {
        //エラーなし、登録処理
      }
    }

    $this->set(compact('entity'));
  }
}

//UsersTable.php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;

class UsersTable extends Table {
  public function validationDefault(Validator $validator) {
    $validator->notEmpty('name', '未入力です');
    return $validator;
  }
}

//index.ctp
<?= $this->Form->create($entity) ?>
  <?= $this->Form->text('name') ?>
  <?= $this->Form->error('name') ?>
<?= $this->Form->end() ?>

CakePHP3でerror()を使う場合は、create()の第一引数にエンティティを渡してあげないといけないようです。CakePHP2のようにモデル名などを入れてると、メッセージが出てこない。そのためには、データがPOSTされてない状態でも、エンティティを作成しておかないといけませんね。

2の場合と同様、エラーメッセージはdivタグで囲われますが、3にはwrapというオプションがありません。divタグを消したかったりpタグに変えたい場合、一番簡単なのは、Viewフォルダの中にあるAppView.phpで設定することかな。

//AppView.php
public function initialize() {
  $this->loadHelper('Form', [
    'templates' => [
       'error' => '{{content}}',
    ]
  ]);
}

これでdivタグが出なくなります。

FormHelper.phpの中を見てみると、「$_defaultConfig」という変数の中に、初期設定が書かれています。エラーメッセージの初期設定もある。この中で変えたい部分を、AppView.phpに書けばオッケーってことですね。

//pタグに変える
public function initialize() {
  $this->loadHelper('Form', [
    'templates' => [
       'error' => '<p class="error-message">{{content}}</p>',
    ]
  ]);
}

//クラス名を変更する
public function initialize() {
  $this->loadHelper('Form', [
    'templates' => [
       'error' => '<div class="error">{{content}}</div>',
    ]
  ]);
}

//テキストボックスに付与されるform-errorクラス名を変える
public function initialize() {
  $this->loadHelper('Form', [
    'errorClass' => 'error',
  ]);
}

他にもいろいろありますが、それについては各自確認ってことでよろしくよろしこ。



input()を使った場合

text()の代わりにinput()を使った場合、error()を使わなくても、input()メソッドがエラーメッセージの表示までやってくれます。ただ強制的にエラーメッセージが出てしまうので、逆に出したくない場合はオプションで指定する必要があります。

//エラーメッセージが出る
<?php echo $this->Form->input('name') ?>

//エラーメッセージが出ない
<?php echo $this->Form->input('name', array('error' => false)) ?>






こんなとこでしょうか。

それにしても、マイバラードとか怪獣のバラードとか、音楽の授業でやった曲って、ほとんどyoutubeに上がってるんだね。この記事書きながら、久しぶりにいろいろ聞き込んじゃったよ。

今はほんとに、何でもネットで見つかる時代だな。CakePHP3に関する情報も、これからどんどん増えて行くと思います。その数ある中の一つとして、ここに書いてある情報がお役に立てば幸いです。



その他のCakePHP3を触ってみましたの記事はこちら
まとめという名の箸休め

まだコメントはいただけてないみたい……
もしかしたら何か関連しているかも?