CakePHP多步骤表单验证

时间:2015-08-13 01:41:38

标签: php validation cakephp

我正在实施此多步form

在表单的第一步中,某些字段需要从另一个表中具有hasMany关系的Model进行验证。

Post hasMany Student

第一步中的字段:

  • Post.contact_person
  • Post.mobile
  • Post.email
  • Student.0.grade
  • Student.0.gender

Post.字段的验证很好,但是Student.0.grade这样的字段没有正确验证,验证总是在不应该返回时返回true。

我必须强调,验证在单页表单中完美无缺。

我尝试手动加载学生模型并进行验证,但似乎无关紧要。我怀疑是数组结构使学生模型无法找到要验证的值。但我只是不确定如何解决它。

控制器(仅处理部分):

public function msf_step($stepNumber) {

    $this->set('stepNumber', $stepNumber);

    /**
     * check if a view file for this step exists, otherwise redirect to index
     */
    if (!file_exists(APP.'View'.DS.'Posts'.DS.'msf_step_'.$stepNumber.'.ctp')) {
            $this->redirect('/posts/msf_index');
    }
    /**
     * determines the max allowed step (the last completed + 1)
     * if choosen step is not allowed (URL manually changed) the user gets redirected
     * otherwise we store the current step value in the session
     */
    $maxAllowed = $this->Session->read('form.params.maxProgress') + 1;
    if ($stepNumber > $maxAllowed) {
        $this->redirect('/posts/msf_step/'.$maxAllowed);
    } else {
        $this->Session->write('form.params.currentStep', $stepNumber);
    }

    /**
     * check if some data has been submitted via POST
     * if not, sets the current data to the session data, to automatically populate previously saved fields
     */
    if ($this->request->is('post')) {
        /**
         * set passed data to the model, so we can validate against it without saving
         */
        $this->Post->set($this->request->data);
        //debug($this->request->data);
        //$this->loadModel('Student');
        //$this->Post->Student->validates();
        //debug($this->request->data);
        //debug($this->Post->Student->validates());
        /**
         * if data validates we merge previous session data with submitted data, using CakePHP powerful Hash class (previously called Set)
         */
        if ($this->Post->validates()) {
            $prevSessionData = $this->Session->read('form.data');
            $currentSessionData = Hash::merge( (array) $prevSessionData, $this->request->data);

            /**
             * if this is not the last step we replace session data with the new merged array
             * update the max progress value and redirect to the next step
             */
            if ($stepNumber < $this->Session->read('form.params.steps')) {
                $this->Session->write('form.data', $currentSessionData);
                $this->Session->write('form.params.maxProgress', $stepNumber);
                $this->redirect(array('action' => 'msf_step', $stepNumber+1));
            } else {
                /**
                 * otherwise, this is the final step, so we have to save the data to the database
                 */
                $this->Post->create();
                $currentSessionData['Post']['user_id'] = AuthComponent::user('id');
                //print_r($currentSessionData);
                //die;
                unset($this->Post->Student->validate['post_id']);


                if ($this->Post->saveAssociated($currentSessionData)) {
                    $this->Session->setFlash(__('The post has been saved.'), 'alert_box', array('class' => 'alert-success'));
                    //$this->Session->delete('form');
                    return $this->redirect(array('action' => 'index'));
                } else {
                    $this->Session->setFlash(__('The post could not be saved. Please, try again.'), 'alert_box', array('class' => 'alert-danger'));
                }
            }
        }
    } else {
        $this->request->data = $this->Session->read('form.data');
    }

    /**
     * here we load the proper view file, depending on the stepNumber variable passed via GET
     */
    $this->render('msf_step_'.$stepNumber);
}

步骤1中的视图(为简单起见,未显示详细信息):

echo $this->Form->create('Post');
echo $this->Form->input('contact_person');
echo $this->Form->input('mobile');
echo $this->Form->input('email');
echo $this->Form->input('Student.0.grade', array(
    'options' => array(
        __('1') => __('Grade 1'),               
        __('2') => __('Grade 2'),
        __('3') => __('Grade 3')
    ),
    'empty' => __('Please Select'),
    'div' => 'form-group',
    'class' => 'form-control',
    'label' => __('Grade')
));
echo $this->Form->input('Student.0.gender');
echo $this->Form->end('Next step');

$this->request->is('post')为真时传递的数组:

array(
    'Post' => array(
        'contact_person' => 'ABC',
        'mobile' => '123',
        'email' => '123@example.com'
    ),
    'Student' => array(
        (int) 0 => array(
            'grade' => 'Male',
            'gender' => 'Boy'
        )
    )
)

1 个答案:

答案 0 :(得分:0)

我在cakephp官方网站上找到了答案:

if ($this->ModelName->saveAll(
    $this->request->data, array('validate' => 'only')
)) {
    // validates
} else {
    // does not validate
}

我将$this->Post->Validates()替换为上述代码以验证多个模型