/**
  * Form::valid()
  * check if the form is
  * - submitted
  * - valid
  * 
  * then:
  * - get errors
  * - distribute errors over elements
  * 
  * @return boolean
  */
 public function valid()
 {
     $this->init();
     // set valid to false
     $valid = FALSE;
     // check if submitted
     if ($this->submitted()) {
         // get parsed valeus
         $values = $this->values();
         /**
          * collect values
          */
         // values to validate
         $validateValues = array();
         foreach ($this->_fields as $key => $field) {
             // set the whole field value (group or not)
             // to test rules set on form
             $validateValues[$key] = $values[$key];
             // set element values separately,
             // to test for rules set on element
             for ($i = 0; $i < count($field['elements']); $i++) {
                 $validateValues[$key . '__element__' . $i] = $field['elements'][$i]->value();
             }
         }
         /**
          * create validator
          */
         $validator = Kohana_Validation::factory($validateValues);
         /**
          * collect rules
          */
         foreach ($this->_fields as $key => $field) {
             // add rules to the whole field, group or not
             foreach ($field['rules'] as $rule) {
                 $validator->rule($key, $rule['rule'], $rule['params']);
             }
             // add element rules separately
             // for the separate values declared earlier
             for ($i = 0; $i < count($field['elements']); $i++) {
                 $rules = $field['elements'][$i]->rules();
                 foreach ($rules as $rule) {
                     $validator->rule($key . '__element__' . $i, $rule['rule'], $rule['params']);
                 }
             }
         }
         /**
          * validate
          */
         $valid = $validator->check();
         /**
          * distribute errors
          */
         if ($valid === FALSE) {
             $errors = $validator->errors();
             foreach ($errors as $key => $error) {
                 // key parts
                 $explode = explode('__', $key);
                 if (isset($explode[1]) && $explode[1] == 'element') {
                     // if it is an error on an element only
                     $this->_fields[$explode[0]]['elements'][$explode[2]]->error($error[0]);
                 } else {
                     // set field errors on the first element
                     $this->_fields[$key]['elements'][0]->error($error[0]);
                 }
             }
         }
     }
     return $valid;
 }
Exemplo n.º 2
0
 /**
  * Validates data. If no data supplied, uses current data in document. Checks embedded_documents as well.
  *
  * @throws  Validation_Exception  when an error is found
  * @param   subject  specify what part of $data should be subjected to validation, Mango::CHECK_FULL, Mango::CHECK_LOCAL, Mango::CHECK_ONLY
  * @param   array    data to check, defaults to current document data (including embedded documents)
  * @return  Mango    $this
  */
 public function check(array $data = NULL, $subject = 0)
 {
     if ($data !== NULL) {
         // create a new object with data, and validate
         Mango::factory($this->_model, $data)->check(NULL, $subject);
         return $this;
     }
     $local = array();
     foreach ($this->_fields as $field_name => $field_data) {
         if (!in_array($field_data['type'], array('has_one', 'has_many'))) {
             // by not checking if the field has been set, we also include default values (if any)
             $local[$field_name] = Mango::normalize($this->__get($field_name));
         }
     }
     if ($subject !== Mango::CHECK_ONLY || count($local)) {
         // validate local data
         $array = Kohana_Validation::factory($local)->bind(':model', $this);
         // add validation rules
         $array = $this->_check($array);
         if ($subject === Mango::CHECK_ONLY) {
             foreach ($this->_fields as $field_name => $field_data) {
                 if (!$this->__isset($field_name)) {
                     // do not validate this field
                     unset($array[$field_name]);
                 }
             }
         }
         //$validation = Validation::factory(get_class($this));
         //foreach ($this->_fields AS $field_name => $field_data) {
         //	if ( $subject === Mango::CHECK_ONLY && ! $this->__isset($field_name))
         //		continue;
         //
         //	$field = $validation->add($field_name);
         //
         //	if ( $field_data['type'] === 'email')
         //	{
         //		$field->add_rule('valid_email');
         //	}
         //
         //	if ( Arr::element($field_data,'required'))
         //	{
         //		$field->add_rule('required');
         //	}
         //
         //	if ( Arr::element($field_data,'unique'))
         //	{
         //		$field->add_rule($field_name, array($this,'_is_unique'),array(':validation', $name));
         //	}
         //
         //	foreach ( array('min_value','max_value','min_length','max_length') as $rule)
         //	{
         //		if ( Arr::element($field, $rule) !== NULL)
         //		{
         //			$data->rule($name, $rule, array(':value', $field[$rule]));
         //		}
         //	}
         //}
         if (!$array->check()) {
             throw new Mango_Validation_Exception($this->_model, $array);
         }
     }
     if ($subject !== Mango::CHECK_LOCAL) {
         // validate embedded documents
         foreach ($this->_fields as $field_name => $field_data) {
             if ($this->__isset($field_name) && in_array($field_data['type'], array('has_one', 'has_many'))) {
                 if ($field_data['type'] === 'has_one') {
                     $this->__get($field_name)->check(NULL, $subject);
                 } else {
                     foreach ($this->__get($field_name) as $seq => $hm) {
                         try {
                             $hm->check(NULL, $subject);
                         } catch (Mango_Validation_Exception $e) {
                             // add sequence number of failed object to exception
                             $e->seq = $seq;
                             throw $e;
                         }
                     }
                 }
             }
         }
     }
     return $this;
 }