2012年11月9日金曜日

Fieldsetクラスを久しぶりに #fuelphp

はじめに参考記事
上の記事を参考にするとある程度わかるとは思いますが、自分なりに試してみた事を。


まずFieldset クラスを使うことで何ができるかというとFormのHTMLを自動生成してくれます。それだけではなくバリデーションも一緒に定義できるし、バリデーションエラーがあった場合、元の入力画面に戻る処理とかも簡潔にかけるようになります。

適当に新規作成の例
以下はコントローラのソース
public function action_create()
{
    // カテゴリの定義
    $categories = array(
                '機能' => '機能',
                'バグ' => 'バグ',
                'その他' => 'その他',
            );

    // Fieldsetの定義
    $fieldset = Fieldset::forge();

    $fieldset->add('title', '件名')
            ->add_rule('required');

    $fieldset->add('description', '概要',
            array(
                'type' => 'textarea',
                'cols' => '80',
                'rows' => '5',
            ));

    $fieldset->add('category', 'カテゴリ',
            array(
                'type' => 'select',
                'options' => $categories,
            ))
            ->add_rule('in_array', $categories);

    $fieldset->add('limited', '期限日',
            array(
                'class' => 'datepicker',
            ));

    $fieldset->add('progress', '進捗率')
            ->add_rule('required')
            ->add_rule('valid_string', array('numeric'))
            ->add_rule('numeric_min', '0')
            ->add_rule('numeric_max', '100');

    $fieldset->add('submit', '', array('type' => 'submit', 'value' => '登録'));

    // POSTの場合は登録処理を行う
    if (Input::method() === 'POST') {
        // バリデーションチェック
        $val = $fieldset->validation();
        if ($val->run()) {
            $fields = $val->validated();
            unset($fields['submit']);

            $ticket = Model_Ticket::forge();
            $ticket->set($fields);
            if ($ticket->save()) {
                Response::redirect('ticket/index');
            }
        } else {
            // 入力エラーがある場合は元の入力画面にもどるため
            // 入力した内容をそのまま引き継ぐ
            $fieldset->repopulate();
        }
    }

    $this->template->title = 'Create';
    $this->template->content = View::forge('ticket/create');
    $this->template->content->set('fieldset', $fieldset->build(), false);
}

ビューのソースは
<?php echo $fieldset; ?>

これでFormのHTMLの自動生成およびバリデーションの実行・表示、登録が出来上がります。
ビューのソースは設定にあるので変更する場合は、fuel/core/Config/form.phpをfuel/app/Config/form.phpにコピーして修正すると出力方法を変更することができます。


もうひとつFieldsetの使い方としてモデルのファイルに定義をするやり方もあります。
モデルのソースは
    protected static $_properties = array(
        'id',
        'title' => array(
                    'data_type' => 'varchar',
                    'label' => '件名',
                    'validation' => array(
                                'required'
                            ),
                    'form' => array(
                                'type' => 'text',
                            ),
                ),
        'description' => array(
                    'data_tpe' => 'text',
                    'label' => '概要',
                    'form' => array(
                                'type' => 'textarea',
                                'cols' => '80',
                                'rows' => '5'
                            ),
                ),
        'category' => array(
                    'data_type' => 'varchar',
                    'label' => 'カテゴリ',
                    'form' => array(
                                'type' => 'select',
                            ),
                ),
        'limited' => array(
                    'data_type' => 'datetime',
                    'label' => '期限日',
                    'form' => array(
                                'type' => 'text',
                            ),
                ),
        'progress' => array(
                    'data_type' => 'int',
                    'label' => '進捗率',
                    'validation' => array(
                                'required',
                                'valid_string' => array('numeric'),
                                'numeric_min' => array('1'),
                                'numeric_max' => array('100'),
                            ),
                    'form' => array(
                                'type' => 'text'
                            ),
                ),
        'created_at' => array(
                    'form' => array(
                                'type' => false,
                            ),
                ),
        'updated_at' => array(
                    'form' => array(
                                'type' => false,
                            ),
                ),
    );
テーブルのフィールド情報はあらかじめ定義されていると思うのでそこにフィールドの型やラベル、バリデーションを追加していくようなイメージです。

これを使った場合のコントローラのソースは
    public function action_create()
    {
        // カテゴリの定義
        $categories = array(
                    '機能' => '機能',
                    'バグ' => 'バグ',
                    'その他' => 'その他',
                );
        
         $fieldset = Fieldset::forge();

//--- 以下、コメントアウト ---
//         $fieldset->add('title', '件名')
//                 ->add_rule('required');

//         $fieldset->add('description', '概要',
//                 array(
//                     'type' => 'textarea',
//                     'cols' => '80',
//                     'rows' => '5',
//                 ));
        
//         $fieldset->add('category', 'カテゴリ',
//                 array(
//                     'type' => 'select',
//                     'options' => $categories,
//                 ))
//                 ->add_rule('in_array', $categories);
        
//         $fieldset->add('limited', '期限日',
//                 array(
//                     'class' => 'datepicker',
//                 ));
        
//         $fieldset->add('progress', '進捗率')
//                 ->add_rule('required')
//                 ->add_rule('valid_string', array('numeric'))
//                 ->add_rule('numeric_min', '0')
//                 ->add_rule('numeric_max', '100');
//--- ここまで ---
        
//--- モデルを使う場合 ---
        $ticket = Model_Ticket::forge();
        
        $fieldset->add_model($ticket);
        $fieldset->field('category')
            ->set_options($categories)
            ->add_rule('in_array', $categories);
//--- ここまで ---
        
        $fieldset->add('submit', '', array('type' => 'submit', 'value' => '登録'));
        
        // POSTの場合は登録処理を行う
        if (Input::method() === 'POST') {
            // バリデーションチェック
            $val = $fieldset->validation();
            if ($val->run()) {
                $fields = $val->validated();
                unset($fields['submit']);
                
                $ticket = Model_Ticket::forge();
                $ticket->set($fields);
                if ($ticket->save()) {
                    Response::redirect('ticket/index');
                }
            } else {
                // 入力エラーがある場合は元の入力画面にもどるため
                // 入力した内容をそのまま引き継ぐ
                $fieldset->repopulate();
            }
        }
        
        $this->template->title = 'Create';
        $this->template->content = View::forge('ticket/create');
        $this->template->content->set_global('fieldset', $fieldset->build(), false);
    }

コメントしている部分が変更した部分です。
基本的にはモデル情報をadd_modelとしてやるだけです。
今回のサンプルではカテゴリのセレクトとしたため、その情報を追加してます(set_optionsとadd_ruleの部分)がそれ以外は特に難しいことはないと思います。

どちらがいいかはその時々だとは思いますが、実際に使ってみると思ったよりも便利だしビューのソースも普通にできます。(設定で変えれるというのもあって)

中のコードの説明とかははじめに書いた参考記事に詳しくかいてますのでそちらを見てもらえればと思います。



0 件のコメント:

コメントを投稿