【EC-CUBE 4】フォームにバリデーションルールを設定する

本記事では、独自に作成したフォームからデータを送信する際に、そのデータが適切な形式かチェックする仕組み(バリデーション)を設ける方法について紹介します。

required=trueのときにフォームを送信した場合の画面
未入力でフォームを送信しようとすると、エラーメッセージが表示されて送信が却下される。
13文字以上を入力してフォームを送信した場合のエラー画面
設定した文字数以上でフォームを送信すると、エラー画面が表示される。

このチェック機能を実装することで、入力してほしくない形式でのデータ送信を防ぐことができます。データベースに値を登録する場合においては、無用なエラーを阻止することにも繋がりますね。

なお、上記画像のようなメーカー情報登録ページ(およびメーカー情報を保存するためのテーブル)は以下記事にて作成しています。

本記事では、これらの記事で作成したフォームタイプ(MakerType.php)とコントローラ(MakerRegisterController.php)を修正する形で解説しています。

開発前にデバッグモードの設定をお薦めします

デバッグモードを設定しておくと、エラーが起きたときに詳細情報が表示されるようになります。
エラー箇所を探しやすくなるので、開発前に設定しておくのをオススメします。
デバッグモードの設定方法については 以下記事 で解説しています。

カスタマイズ後は、デバッグモードの解除を忘れないように。

【動作環境】
EC CUBEのバージョン:4.3.0
サーバー:XServer

目次

未入力の場合、デフォルトでフォームが送信されないようになっている

そもそもEC-CUBEが採用しているPHPフレームワーク(Symfony)では、フォームが未入力の場合には値が送信されないような設定になっています。

お問い合わせなどのデフォルトで用意されたページを除き、自作したフォームを未入力で送信しようとすると、以下のような画面が表示されます。

required=trueのときにフォームを送信した場合の画面
初期設定で、未入力フォームはアラートが表示される

なぜこのようになるのかというと、フォームを生成する段階(addメソッドで項目を追加するとき)に、そのフィールドを必須項目として設定するためです。

この必須機能をオフにしたい場合は、対象フィールドのaddメソッドを以下のように修正します。

add('name', TextType::class, [
  'label' => 'メーカー名',
  'required' => false,
)]

3行目の'required'というオプションが、入力必須機能のオン・オフを制御しています。デフォルトでは'required' => trueなので、未入力OKにする場合はこれをfalseにします。

requiredオプションについて

required オプションはHTMLのrequired属性に対応しており、ブラウザのクライアントサイドで未入力を制御します(JavaScriptが有効な場合)。ただし、あくまでクライアントサイドの制御なので、サーバーサイドでバリデーションを設定している場合(@Assert\NotBlank() など)は別途考慮が必要です。

お問い合わせや会員登録など、EC-CUBEデフォルトのフォームで実装する場合

EC-CUBEがはじめから用意しているフォームで必須機能を実装する場合は少し特殊なので、以下記事に別で纏めています。

複雑な入力規制を設定できるconstraints

入力が必須かどうかは'required'オプションで制御できますが、文字数制限をかけたりエラーメッセージを変えたりする場合は、'constraints'オプションを使います。

このオプションを使うと、フォーム送信時に設定したルールに従う場合と従わない場合で条件分岐ができるので、表示内容やデータベースへの反映を制御できるようになります。

required

クライアントサイド(ブラウザ側) の必須入力を制御し、HTMLの required 属性を設定する。

constraints

サーバーサイド(Symfonyのバリデーション) で適用され、PHPのバリデーションルールとして動作する。

'constraints'の基本的な使い方

'required'と同様に、対象フィールドのaddメソッドに'constraints'を設定するのですが、事前に以下のクラスをuseで読み込み、Assertで使えるようにしておきます。

use Symfony\Component\Validator\Constraints as Assert;

addメソッドへの記述は、ルールに以下のように行います。

->add('name', TextType::class, [
    'label' => 'メーカー名',
    'constraints' => [
        // 未入力のときにエラー(false)を返す
        new Assert\NotBlank([
            'message' => '入力してください。'
        ]),

        // 入力文字数が少ない(2文字以下) もしくは 多いとき(13文字以上)にエラー(false)を返す
        new Assert\Length([
            'min' => 3, 'max' => 12,
            'minMessage' => '3文字以上で入力してください。',
            'maxMessage' => '12文字以下で入力してください。',
        ]),
    ]
])

new Assert\Length()最小・最大文字数を制限できるようになります。また、messageminMessage などを指定することで、エラーメッセージのカスタマイズもできます。

Constraintsの代表的なバリデーション一覧

NotBlank / 空の値を許容しない(空白のみの入力もNG)
new Assert\NotBlank([
    'message' => 'この項目は必須です。'
])
NotNull / null を許容しない(空文字はOK)
new Assert\NotNull([
    'message' => 'この項目は空にできません。'
])
Length / 最小・最大文字数を制限
new Assert\Length([
    'min' => 5, 'max' => 50,
    'minMessage' => '5文字以上で入力してください。',
    'maxMessage' => '50文字以下で入力してください。'
])
Regex / 正規表現でチェック
new Assert\Regex([
    'pattern' => '/^[a-zA-Z0-9]+$/',
    'message' => '英数字のみ入力してください。'
])
Email / メールアドレスの形式チェック
new Assert\Email([
    'message' => '有効なメールアドレスを入力してください。'
])
Url / URLの形式チェック
new Assert\Url([
    'message' => '有効なURLを入力してください。'
])
Date / 正しい日付かどうかをチェック
new Assert\Date([
    'message' => '有効な日付を入力してください。'
])
Positive / 正の数のみ許可
new Assert\Positive([
    'message' => '正の数を入力してください。'
])
Integer / 整数のみ許可
new Assert\Type([
    'type' => 'integer',
    'message' => '整数を入力してください。'
])
入力必須NotBlank, NotNull
文字列Length, Regex, Email, Url
数値Range, GreaterThan, LessThan, Positive, Negative, Integer
配列Choice, Count
日時Date, DateTime, Time
ネットワークIp, Uuid
カスタムCallback
バリデーションルールの一覧

他にも様々なルールを適用できる constraints が用意されているので、ぜひ調べてみてください!

Controllerで条件分岐を行い、ルールに合わない場合の処理を記述

フォーム側(MakerType.php)の記述が完了したら、Controller(MakerRegisterController.php)で条件分岐を行います。こちらの記事 で作成した、以下Controllerを改めて確認します。

<?php

namespace Customize\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Eccube\Controller\AbstractController;
use Customize\Entity\Maker;
use Doctrine\ORM\EntityManagerInterface;
use Customize\Form\Type\MakerType;

class MakerRegisterController extends AbstractController
{
  /**
   * @Route("/maker_register", name="maker_register")
   * @Template("maker_register.twig")
   */
  public function create(Request $request, EntityManagerInterface $entityManager)
  {
    $maker = new Maker();
    $form = $this->createForm(MakerType::class, $maker);

    if ($request->isMethod('POST')) {
      $form->handleRequest($request);

      // $form->isValid()には、constraintsでセットしたルールに従う場合はtrue、従わない場合はfalseが返る。
      if ($form->isSubmitted() && $form->isValid()) {
        // ルールに従う場合の処理
        $entityManager->persist($maker);
        $entityManager->flush();
        return [
          'message' => '登録完了しました!',
          'form' => $form->createView(),
        ];
      } else {
        // ルールに従わない場合の処理
        return [
          'message' => '入力に誤りがあります。',
          'form' => $form->createView(),
        ];
      }
    }

    return [
    'message' => 'メーカー情報を新規登録します。',
    'form' => $form->createView(),
    ];
  }
}

if ($form->isSubmitted() && $form->isValid()) {以降の記述が、フォームを送信した際の条件分岐です。

$form->isValid()には、constraintsでセットしたルールに従う場合はtrue、従わない場合はfalseが返ります。

したがって、『フォームが送信され($form->isSubmitted())かつ入力ルールに合う($form->isValid())』場合に、データベースへの反映処理を記述してあげればOKです。

まとめ

以上、フォームにバリデーションを設定する方法について紹介しました。
入力内容が不適切な場合に処理を変えたい場合には、ぜひ使ってみてください。


よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次