Example #1
0
 /**
  * Validate by processing pre-filters, rules, callbacks, and post-filters.
  * All fields that have filters, rules, or callbacks will be initialized if
  * they are undefined. Validation will only be run if there is data already
  * in the array.
  *
  * @return bool
  */
 public function validate()
 {
     // All the fields that are being validated
     $all_fields = array_unique(array_merge(array_keys($this->pre_filters), array_keys($this->rules), array_keys($this->callbacks), array_keys($this->post_filters)));
     // Copy the array from the object, to optimize multiple sets
     $object_array = $this->getArrayCopy();
     foreach ($all_fields as $i => $field) {
         if ($field === $this->any_field) {
             // Remove "any field" from the list of fields
             unset($all_fields[$i]);
             continue;
         }
         if (substr($field, -2) === '.*') {
             // Set the key to be an array
             Kohana::key_string_set($object_array, substr($field, 0, -2), array());
         } else {
             // Set the key to be NULL
             Kohana::key_string_set($object_array, $field, NULL);
         }
     }
     // Swap the array back into the object
     $this->exchangeArray($object_array);
     // Reset all fields to ALL defined fields
     $all_fields = array_keys($this->getArrayCopy());
     foreach ($this->pre_filters as $field => $calls) {
         foreach ($calls as $func) {
             if ($field === $this->any_field) {
                 foreach ($all_fields as $f) {
                     // Process each filter
                     $this[$f] = is_array($this[$f]) ? arr::map_recursive($func, $this[$f]) : call_user_func($func, $this[$f]);
                 }
             } else {
                 // Process each filter
                 $this[$field] = is_array($this[$field]) ? arr::map_recursive($func, $this[$field]) : call_user_func($func, $this[$field]);
             }
         }
     }
     if ($this->submitted === FALSE) {
         return FALSE;
     }
     foreach ($this->rules as $field => $calls) {
         foreach ($calls as $call) {
             // Split the rule into function and args
             list($func, $args) = $call;
             if ($field === $this->any_field) {
                 foreach ($all_fields as $f) {
                     if (isset($this->array_fields[$f])) {
                         // Use the field key
                         $f_key = $this->array_fields[$f];
                         // Prevent other rules from running when this field already has errors
                         if (!empty($this->errors[$f_key])) {
                             break;
                         }
                         // Don't process rules on empty fields
                         if (!in_array($func[1], $this->empty_rules, TRUE) and $this[$f_key] == NULL) {
                             continue;
                         }
                         foreach ($this[$f_key] as $k => $v) {
                             if (!call_user_func($func, $this[$f_key][$k], $args)) {
                                 // Run each rule
                                 $this->errors[$f_key] = is_array($func) ? $func[1] : $func;
                             }
                         }
                     } else {
                         // Prevent other rules from running when this field already has errors
                         if (!empty($this->errors[$f])) {
                             break;
                         }
                         // Don't process rules on empty fields
                         if (!in_array($func[1], $this->empty_rules, TRUE) and $this[$f] == NULL) {
                             continue;
                         }
                         if (!call_user_func($func, $this[$f], $args)) {
                             // Run each rule
                             $this->errors[$f] = is_array($func) ? $func[1] : $func;
                         }
                     }
                 }
             } else {
                 if (isset($this->array_fields[$field])) {
                     // Use the field key
                     $field_key = $this->array_fields[$field];
                     // Prevent other rules from running when this field already has errors
                     if (!empty($this->errors[$field_key])) {
                         break;
                     }
                     // Don't process rules on empty fields
                     if (!in_array($func[1], $this->empty_rules, TRUE) and $this[$field_key] == NULL) {
                         continue;
                     }
                     foreach ($this[$field_key] as $k => $val) {
                         if (!call_user_func($func, $this[$field_key][$k], $args)) {
                             // Run each rule
                             $this->errors[$field_key] = is_array($func) ? $func[1] : $func;
                             // Stop after an error is found
                             break 2;
                         }
                     }
                 } else {
                     // Prevent other rules from running when this field already has errors
                     if (!empty($this->errors[$field])) {
                         break;
                     }
                     // Don't process rules on empty fields
                     if (!in_array($func[1], $this->empty_rules, TRUE) and $this[$field] == NULL) {
                         continue;
                     }
                     if (!call_user_func($func, $this[$field], $args)) {
                         // Run each rule
                         $this->errors[$field] = is_array($func) ? $func[1] : $func;
                         // Stop after an error is found
                         break;
                     }
                 }
             }
         }
     }
     foreach ($this->callbacks as $field => $calls) {
         foreach ($calls as $func) {
             if ($field === $this->any_field) {
                 foreach ($all_fields as $f) {
                     // Execute the callback
                     call_user_func($func, $this, $f);
                     // Stop after an error is found
                     if (!empty($errors[$f])) {
                         break 2;
                     }
                 }
             } else {
                 // Execute the callback
                 call_user_func($func, $this, $field);
                 // Stop after an error is found
                 if (!empty($errors[$field])) {
                     break;
                 }
             }
         }
     }
     foreach ($this->post_filters as $field => $calls) {
         foreach ($calls as $func) {
             if ($field === $this->any_field) {
                 foreach ($all_fields as $f) {
                     if (isset($this->array_fields[$f])) {
                         // Use the field key
                         $f = $this->array_fields[$f];
                     }
                     // Process each filter
                     $this[$f] = is_array($this[$f]) ? array_map($func, $this[$f]) : call_user_func($func, $this[$f]);
                 }
             } else {
                 if (isset($this->array_fields[$field])) {
                     // Use the field key
                     $field = $this->array_fields[$field];
                 }
                 // Process each filter
                 $this[$field] = is_array($this[$field]) ? array_map($func, $this[$field]) : call_user_func($func, $this[$field]);
             }
         }
     }
     // Return TRUE if there are no errors
     return count($this->errors) === 0;
 }
Example #2
0
 /**
  * Validate by processing pre-filters, rules, callbacks, and post-filters.
  * All fields that have filters, rules, or callbacks will be initialized if
  * they are undefined. Validation will only be run if there is data already
  * in the array.
  *
  * @param bool $validate_csrf When TRUE, performs CSRF token validation
  * @return bool
  */
 public function validate($validate_csrf = TRUE)
 {
     // CSRF token field
     $csrf_token_key = 'form_auth_token';
     if (array_key_exists($csrf_token_key, $this)) {
         unset($this[$csrf_token_key]);
     }
     // Delete the CSRF token field if it's in the validation
     // rules
     if (array_key_exists($csrf_token_key, $this->callbacks)) {
         unset($this->callbacks[$csrf_token_key]);
     } elseif (array_key_exists($csrf_token_key, $this->rules)) {
         unset($this->rules[$csrf_token_key]);
     }
     // Disable CSRF for XHR
     // Same method as django CSRF protection:
     //     http://michael-coates.blogspot.co.nz/2010/12/djangos-built-in-csrf-defense-for-ajax.html
     if (request::is_ajax()) {
         $validate_csrf = FALSE;
     }
     // Perform CSRF validation for all HTTP POST requests
     // where CSRF validation is enabled and the request
     // was not submitted via the API
     if ($_POST and $validate_csrf and !Validation::$is_api_request) {
         // Check if CSRF module is loaded
         if (in_array(MODPATH . 'csrf', Kohana::config('config.modules'))) {
             // Check for presence of CSRF token in HTTP POST payload
             $form_auth_token = isset($_POST[$csrf_token_key]) ? $_POST[$csrf_token_key] : text::random('alnum', 10);
             // Validate the token
             if (!csrf::valid($form_auth_token)) {
                 Kohana::log('debug', 'Invalid CSRF token: ' . $form_auth_token);
                 Kohana::log('debug', 'Actual CSRF token: ' . csrf::token());
                 // Flag CSRF validation as having failed
                 $this->csrf_validation_failed = TRUE;
                 // Set the error message
                 $this->errors[$csrf_token_key] = Kohana::lang('csrf.form_auth_token.error');
                 return FALSE;
             }
         }
     }
     // All the fields that are being validated
     $all_fields = array_unique(array_merge(array_keys($this->pre_filters), array_keys($this->rules), array_keys($this->callbacks), array_keys($this->post_filters)));
     // Copy the array from the object, to optimize multiple sets
     $object_array = $this->getArrayCopy();
     foreach ($all_fields as $i => $field) {
         if ($field === $this->any_field) {
             // Remove "any field" from the list of fields
             unset($all_fields[$i]);
             continue;
         }
         if (substr($field, -2) === '.*') {
             // Set the key to be an array
             Kohana::key_string_set($object_array, substr($field, 0, -2), array());
         } else {
             // Set the key to be NULL
             Kohana::key_string_set($object_array, $field, NULL);
         }
     }
     // Swap the array back into the object
     $this->exchangeArray($object_array);
     // Reset all fields to ALL defined fields
     $all_fields = array_keys($this->getArrayCopy());
     foreach ($this->pre_filters as $field => $calls) {
         foreach ($calls as $func) {
             if ($field === $this->any_field) {
                 foreach ($all_fields as $f) {
                     // Process each filter
                     $this[$f] = is_array($this[$f]) ? arr::map_recursive($func, $this[$f]) : call_user_func($func, $this[$f]);
                 }
             } else {
                 // Process each filter
                 $this[$field] = is_array($this[$field]) ? arr::map_recursive($func, $this[$field]) : call_user_func($func, $this[$field]);
             }
         }
     }
     if ($this->submitted === FALSE) {
         return FALSE;
     }
     foreach ($this->rules as $field => $calls) {
         foreach ($calls as $call) {
             // Split the rule into function and args
             list($func, $args) = $call;
             if ($field === $this->any_field) {
                 foreach ($all_fields as $f) {
                     if (isset($this->array_fields[$f])) {
                         // Use the field key
                         $f_key = $this->array_fields[$f];
                         // Prevent other rules from running when this field already has errors
                         if (!empty($this->errors[$f_key])) {
                             break;
                         }
                         // Don't process rules on empty fields
                         if (!in_array($func[1], $this->empty_rules, TRUE) and $this[$f_key] == NULL) {
                             continue;
                         }
                         foreach ($this[$f_key] as $k => $v) {
                             if (!call_user_func($func, $this[$f_key][$k], $args)) {
                                 // Run each rule
                                 $this->errors[$f_key] = is_array($func) ? $func[1] : $func;
                             }
                         }
                     } else {
                         // Prevent other rules from running when this field already has errors
                         if (!empty($this->errors[$f])) {
                             break;
                         }
                         // Don't process rules on empty fields
                         if (!in_array($func[1], $this->empty_rules, TRUE) and $this[$f] == NULL) {
                             continue;
                         }
                         if (!call_user_func($func, $this[$f], $args)) {
                             // Run each rule
                             $this->errors[$f] = is_array($func) ? $func[1] : $func;
                         }
                     }
                 }
             } else {
                 if (isset($this->array_fields[$field])) {
                     // Use the field key
                     $field_key = $this->array_fields[$field];
                     // Prevent other rules from running when this field already has errors
                     if (!empty($this->errors[$field_key])) {
                         break;
                     }
                     // Don't process rules on empty fields
                     if (!in_array($func[1], $this->empty_rules, TRUE) and $this[$field_key] == NULL) {
                         continue;
                     }
                     foreach ($this[$field_key] as $k => $val) {
                         if (!call_user_func($func, $this[$field_key][$k], $args)) {
                             // Run each rule
                             $this->errors[$field_key] = is_array($func) ? $func[1] : $func;
                             // Stop after an error is found
                             break 2;
                         }
                     }
                 } else {
                     // Prevent other rules from running when this field already has errors
                     if (!empty($this->errors[$field])) {
                         break;
                     }
                     // Don't process rules on empty fields
                     if (!in_array($func[1], $this->empty_rules, TRUE) and $this[$field] == NULL) {
                         continue;
                     }
                     if (!call_user_func($func, $this[$field], $args)) {
                         // Run each rule
                         $this->errors[$field] = is_array($func) ? $func[1] : $func;
                         // Stop after an error is found
                         break;
                     }
                 }
             }
         }
     }
     foreach ($this->callbacks as $field => $calls) {
         foreach ($calls as $func) {
             if ($field === $this->any_field) {
                 foreach ($all_fields as $f) {
                     // Execute the callback
                     call_user_func($func, $this, $f);
                     // Stop after an error is found
                     if (!empty($errors[$f])) {
                         break 2;
                     }
                 }
             } else {
                 // Execute the callback
                 call_user_func($func, $this, $field);
                 // Stop after an error is found
                 if (!empty($errors[$field])) {
                     break;
                 }
             }
         }
     }
     foreach ($this->post_filters as $field => $calls) {
         foreach ($calls as $func) {
             if ($field === $this->any_field) {
                 foreach ($all_fields as $f) {
                     if (isset($this->array_fields[$f])) {
                         // Use the field key
                         $f = $this->array_fields[$f];
                     }
                     // Process each filter
                     $this[$f] = is_array($this[$f]) ? array_map($func, $this[$f]) : call_user_func($func, $this[$f]);
                 }
             } else {
                 if (isset($this->array_fields[$field])) {
                     // Use the field key
                     $field = $this->array_fields[$field];
                 }
                 // Process each filter
                 $this[$field] = is_array($this[$field]) ? array_map($func, $this[$field]) : call_user_func($func, $this[$field]);
             }
         }
     }
     // Return TRUE if there are no errors
     return count($this->errors) === 0;
 }
Example #3
0
 /**
  * Because PHP does not have this function, and array_walk_recursive creates
  * references in arrays and is not truly recursive.
  *
  * @param   mixed  callback to apply to each member of the array
  * @param   array  array to map to
  * @return  array
  */
 public static function map_recursive($callback, array $array)
 {
     foreach ($array as $key => $val) {
         // Map the callback to the key
         $array[$key] = is_array($val) ? arr::map_recursive($callback, $val) : call_user_func($callback, $val);
     }
     return $array;
 }
 /**
  * Tests the arr::map_recursive() function.
  * @dataProvider map_recursive_provider
  * @group core.helpers.arr.map_recursive
  * @test
  */
 public function map_recursive($input_callback, $input_array, $expected_result)
 {
     $result = arr::map_recursive($input_callback, $input_array);
     $this->assertEquals($expected_result, $result);
 }