本記事では、独自に作成したフォームからデータを送信する際に、そのデータが適切な形式かチェックする仕組み(バリデーション)を設ける方法について紹介します。
このチェック機能を実装することで、入力してほしくない形式でのデータ送信を防ぐことができます。データベースに値を登録する場合においては、無用なエラーを阻止することにも繋がりますね。
なお、上記画像のようなメーカー情報登録ページ(およびメーカー情報を保存するためのテーブル)は以下記事にて作成しています。
- 【EC-CUBE 4】オリジナルテーブルをデータベースに新規で追加する方法
(メーカー情報を保存できるテーブル・『dtb_Maker』を作成します。) - 【EC-CUBE 4】オリジナルテーブルに新規データ(レコード)を追加する方法
(上記で作成した『dtb_Maker』に、Webページからフォームを送信してレコードを追加できるようにします。) - 【EC-CUBE 4】フォーム生成を別ファイル(FormType)に切り分ける
(フォームを生成するためのFormType・『MakerType.php』を作成します。)
本記事では、これらの記事で作成したFormType(MakerType.php)とController(MakerRegisterController.php)を修正する形で解説しています。
デバッグモードを設定しておくと、エラーが起きたときに詳細情報が表示されるようになります。
エラー箇所を探しやすくなるので、開発前に設定しておくのをオススメします。
デバッグモードの設定方法については 以下記事 で解説しています。
カスタマイズ後は、デバッグモードの解除を忘れないように。
未入力の場合、デフォルトでフォームが送信されないようになっている
そもそもEC-CUBEが採用しているPHPフレームワーク(Symfony 4)では、フォームが未入力の場合には値が送信されないような設定になっています。
お問い合わせなどのデフォルトで用意されたページを除き、自作したフォームを未入力で送信しようとすると、以下のような画面が表示されます。
なぜこのようになるのかというと、フォームを生成する段階(addメソッドで項目を追加するとき)に、そのフィールドを必須項目として設定するためです。
この必須機能をオフにしたい場合は、対象フィールドのaddメソッドを以下のように修正します。
add('name', TextType::class, array(
'label' => 'メーカー名',
'required' => false,
))
3行目の ‘required’ というキーワードが、入力必須機能のオン・オフを制御しています。
デフォルトでは「’required’ => true」なので、未入力OKにする場合はこれをfalseにします。
EC-CUBEがはじめから用意しているフォームで必須機能を実装する場合は少し特殊なので、以下記事に別で纏めています。
より複雑な入力規制を設定する
入力が必須かどうかは ‘required’ というキーワードで制御できますが、文字数制限をかけたりエラーメッセージを変えたりする場合は、’constraints’ というキーワードを使います。
このキーワードを使うと、フォーム送信時に設定したルールに従う場合と従わない場合で条件分岐ができるので、表示内容やデータベースへの反映を制御できるようになります。
‘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文字以下で入力してください。',
]),
]
‘message’、’minMessage’、’maxMessage’ にセットされたテキストが、エラーメッセージとして表示されます。
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 Customize\Form\Type\MakerType;
class MakerRegisterController extends AbstractController
{
/**
* @Route("/maker_register", name="maker_register")
* @Template("maker_register.twig")
*/
public function create(Request $request)
{
$maker = new Maker();
$form = $this->createForm(MakerType::class, $maker);
$form->handleRequest($request);
if ($request->getMethod() == 'GET') {
return [
'message' => 'メーカー情報を新規登録します。',
'form' => $form->createView(),
];
}
// $form->isValid()には、constraintsでセットしたルールに従う場合はtrue、従わない場合はfalseが返る。
if ($request->getMethod() == 'POST' && $form->isValid()) {
// ルールに従う場合の処理
$maker = $form->getData();
$manager = $this->getDoctrine()->getManager();
$manager->persist($maker);
$manager->flush();
return [
'message' => '登録が完了しました!',
'form' => $form->createView(),
];
} else {
// ルールに従わない場合の処理
return [
'message' => '登録に失敗しました。',
'form' => $form->createView(),
];
}
}
}
31行目からの記述が、フォームを送信した際の条件分岐です。
入力した内容が ‘constraints’ で設定したルールに合う場合、「$form->isValid()」にtrueが代入され、ルールに合わない場合はfalseが代入されます。
したがって、『フォームが送信され($request->getMethod() == ‘POST’)かつ入力ルールに合う($form->isValid())』場合に、データベースへの反映処理を記述してあげればOKです。
まとめ
以上、フォームにバリデーションを設定する方法について紹介しました。
入力内容が不適切な場合に処理を変えたい場合には、ぜひ使ってみてください。