11
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

EC-CUBEAdvent Calendar 2015

Day 2

フォームイベントの実行タイミング

Posted at

EC-CUBE3.0ではフォームの入出力やバリデーションにはFormTypeで実装されています。
FormTypeの使い方はSymfonyのドキュメントにもありますが、その中でもちょっと理解するのが難しい、フォームイベントについてまとめてみます。

フォームイベントって?

フォームにかぎらずなのですが、symfonyではイベントという概念で、処理の途中で別の処理を差し込める仕組みが有ります。

FormTypeで用意されているイベントは、以下のとおりです。

  • PRE_SET_DATA
  • POST_SET_DATA
  • PRE_SUBMIT
  • SUBMIT
  • POST_SUBMIT

また、フォームイベントのフローも公式ドキュメントで提供されています。
http://symfony.com/doc/current/components/form/form_events.html

実際に動かしてみる

前述のSymfonyの公式ドキュメントを参照するのが一番手っ取り早いのですが、実際に動かしてみるのが一番理解しやすいかと思います。

EC-CUBE3.0のソースコードにフォームイベントを追加して、動かしてみましょう。

管理画面の特定商取引法の設定画面のソースコードを少しいじってみます。

src/Eccube/Controller/Admin/Shop/TradelawController.php

    public function index(Application $app)
    {
        $Help = $app['eccube.repository.help']->get();

        // ★ フォーム生成前
        echo "CONTROLLER: CREATE FORM BEFORE".PHP_EOL;

        $form = $app['form.factory']
            ->createBuilder('tradelaw', $Help)
            ->getForm();
        // ★ フォーム生成後
        echo "CREATE FORM AFTER".PHP_EOL;

        if ('POST' === $app['request']->getMethod()) {
            // ★ handleRequest実行前
            echo "CONTROLLER: HANDLE REQUEST BEFORE".PHP_EOL;

            $form->handleRequest($app['request']);

            // ★ handleRequest実行後
            echo "CONTROLLER: HANDLE REQUEST AFTER".PHP_EOL;

            if ($form->isValid()) {
                $Help = $form->getData();
                $app['orm.em']->persist($Help);
                $app['orm.em']->flush();
                $app->addSuccess('admin.register.complete', 'admin');
                return $app->redirect($app->url('admin_setting_shop_tradelaw'));
            } else {
                $app->addError('admin.register.failed', 'admin');
            }
        }

        return $app->render('Setting/Shop/tradelaw.twig', array(
                        'form' => $form->createView(),
        ));
    }

src/Eccube/Form/Type/Admin/TradelawType.php

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('law_company', 'text', array(
                'label' => '販売業者',
                'required' => true,
                'constraints' => array(
                    new Assert\NotBlank(),
                ),
            ))

  ...

            ->addEventSubscriber(new \Eccube\Event\FormEventSubscriber());

        // ★イベントを設定
        $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
            echo "FORM: PRE_SET_DATA".PHP_EOL;
        });

        $builder->addEventListener(FormEvents::POST_SET_DATA, function(FormEvent $event) {
            echo "FORM: POST_SET_DATA".PHP_EOL;
        });

        $builder->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
            echo "FORM: PRE_SUBMIT".PHP_EOL;
        });

        $builder->addEventListener(FormEvents::SUBMIT, function(FormEvent $event) {
            echo "FORM: SUBMIT".PHP_EOL;
        });

        $builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) {
            echo "FORM: POST_SUBMIT".PHP_EOL;
        });
    }

ソースコードを書き換えた状態で、特定商取引法の登録を実行すると、以下が出力されます。

CONTROLLER: CREATE FORM BEFORE
FORM      : PRE_SET_DATA
FORM      : POST_SET_DATA
CONTROLLER: CREATE FORM AFTER
CONTROLLER: HANDLE REQUEST BEFORE
FORM      : PRE_SUBMIT
FORM      : SUBMIT
FORM      : POST_SUBMIT
CONTROLLER: HANDLE REQUEST AFTER

SET_DATA系のイベントはフォーム生成時、SUBMIT系のイベントは、handleRequestが実行されたタイミングで実行されます。

PREとかPOSTとかはどう違うの?という点では、FormTypeのコードをみてみるのがよいかもしれません。

PRE_SET_DATA
https://github.com/symfony/form/blob/2.7/Form.php#L342

POST_SET_DATA
https://github.com/symfony/form/blob/2.7/Form.php#L391

PRE_SUBMIT
https://github.com/symfony/form/blob/2.7/Form.php#L546

SUBMIT
https://github.com/symfony/form/blob/2.7/Form.php#L633

POST_SUBMIT
https://github.com/symfony/form/blob/2.7/Form.php#L660

なにができるの?

主に動的にフォームを生成する必要がある場合によく使います。
EC-CUBE3.0では、このへんで利用されています。

ぜひ参考にしてみてください。

12/3は、 @shinichi-takahashi さんです!

11
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?