ZendFramework3のzend-formのバリデーション結果を日本語で表示する

ZendFramework3でフォームのバリデート結果を日本語で表示する方法です。

zend-formを使ってログインフォームを作成

今回はログインフォームを仮定してフォームを作成します。フォームには下記のバリデーションを設定します。

  • ログインID・・・必須/6文字以上
  • パスワード・・・必須

先ずzend-formを有効にします。zend-formを有効すればフォーム用のビューヘルパが利用できるようになります。 /config/modules.config.phpにZend\Formを追加を追加します。

<?php
return [
    'Zend\Form', // ← Zend\Formを追加
    'Zend\Router',
    'Zend\Validator',
    'Application',
];

コントローラー内でフォームを作成します。

<?php
namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Validator;

class IndexController extends AbstractActionController
{
    public function indexAction()
    {
        // ログインフォームの作成
        $form = new \Zend\Form\Form('login_form');
        $form->setAttribute('method', 'post');
        // ログインID
        $form->add([
            'type' => 'text',
            'name' => 'login_id',
            'options' => [
                'label' => 'ログインID',
            ],
        ]);
        // パスワード
        $form->add([
            'type' => 'password',
            'name' => 'password',
            'options' => [
                'label' => 'パスワード',
            ],
        ]);
        // 送信ボタン
        $form->add([
            'type' => 'submit',
            'name' => 'submit',
            'attributes' => [
                'value' => 'ログイン'
            ],
        ]);

        // インプットフィルタ取得
        $inputFilter = $form->getInputFilter();

        // ログインIDのバリデーターを設定
        $inputFilter->add([
            'name'     => 'login_id',
            'required' => true,
            'validators' => [
                [
                    'name'    => Validator\StringLength::class,
                    'options' => [
                        'min' => 6,
                    ],
                ],
            ],
        ]);

        // パスワードのバリデーターを設定
        $inputFilter->add([
            'name'     => 'password',
            'required' => true,
        ]);


        // フォーム送信された場合
        if ($this->getRequest()->isPost()) {
            // フォームデータの取得
            $data = $this->params()->fromPost();

            // 入力フォームのバリデート
            $form->setData($data);
            $form->isValid();
        }

        return new ViewModel([
            'form' => $form,
        ]);
    }
}

ビューヘルパを使用してフォームを表示します。

<?= $this->form($form); ?>

こんなかんじで表示されるはずです。

「ログイン」ボタンをクリックするとバリデート処理が実行されます。このままだとバリデーション結果は英語のままです。

zend-mvc-i18nを有効にする

zend-mvc-i18nはzend-mvcアプリケーションに対して「MvcTranslator」という翻訳の機能を提供します。

<?php
return [
    'Zend\Form',
    'Zend\Mvc\I18n', // ← Zend\Mvc\I18nを追加
    'Zend\Router',
    'Zend\Validator',
    'Application',
];

次に「MvcTranslator」で使用する設定を行います。モジュールの設定ファイルに下記の設定を追加します。

<?php
return [
    'translator' => [
        'locale' => 'ja_JP',
        'translation_files' => [
            [
                'type' => 'phparray',
                'filename' => __DIR__.'/../../vendor/zendframework/zend-i18n-resources/languages/ja/Zend_Validate.php',
                'text_domain' => 'default',
                'locale' => 'ja_JP'
            ],
        ],
    ],
];

[‘translator’][‘locale’]で使用する翻訳ファイルを指定します。[‘translator’][‘translation_files’]は複数設定できますが今回は日本語のみ設定しております。日本語翻訳ファイルはzend-i18n-resourcesで提供されていますのでこちらを使用しています。

このままでもzend-formのビューヘルパの機能によってある程度は日本語化されますが、「6文字以上入力必須」の様なオプションの設定で動的に変更されるメッセージは日本語化されません。

これを回避するために、MvcTranslatorをバリデーターに設定する必要が有ります。

MvcTranslatorをバリデーターに設定

MvcTranslatorはサービスマネージャーで取得できます。ZendFramework3からはControllerクラスでServiceLocatorは使用できませんので、サービスマネージャのFactoryクラス等で取得し、設定します。

今回は翻訳ファイルはモジュール内で共通で使用するだろうということで、ApplicationモジュールのModule.phpで設定します。

<?php

namespace Application;

use Zend\Mvc\MvcEvent;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Validator\AbstractValidator;

class Module
{
    public function getConfig()
    {
        return include __DIR__ . '/../config/module.config.php';
    }

    /**
     * ブートストラップ処理時に呼び出される
     *
     * @param MvcEvent $event
     * @return void
     */
    public function onBootstrap(MvcEvent $event)
    {
        // イベントマネージャー取得
        $eventManager = $event->getApplication()->getEventManager();
        $sharedEventManager = $eventManager->getSharedManager();
        // イベントリスナーに登録
        $sharedEventManager->attach(
            AbstractActionController::class,
            MvcEvent::EVENT_DISPATCH,
            [$this, 'onDispatch'],
            100
        );
    }

    /**
     * ディスパッチ時に呼び出される
     *
     * @param MvcEvent $event
     * @return void
     */
    public function onDispatch(MvcEvent $event)
    {
        // MvcTranslator取得
        $translator = $event->getApplication()->getServiceManager()->get('MvcTranslator');
        // バリデータのデフォルトに設定
        AbstractValidator::setDefaultTranslator($translator);
    }
}

onDispatchをコントローラーがディスパッチされるタイミングで実行されるように、イベントマネージャーで登録しています。onDispatch内で実際にMvcTranslatorをバリデータに設定しています。

動的なメッセージも日本語で表示されるようになりました。

不自由な日本語を修正したい場合は翻訳ファイルを自作して、モジュール設定ファイルの[‘translator’][‘translation_files’]に設定することで対応できます。

コメントを残す