/** * validates a single field submitted to the main database * * receives a validation pair and processes it, adding any error to the * validation status array * * @param string $value the submitted value of the field * @param string $name the name of the field * @param string $validation validation method to use: can be NULL (or absent), * 'no', 'yes', 'email', 'other' (for regex or match * another field value) * @param string $form_element the form element type of the field * @return NULL */ protected function _validate_field($value, $name, $validation = NULL, $form_element = false) { $error_type = false; $field = (object) compact('value', 'name', 'validation', 'form_element', 'error_type'); /* * this filter sends the $field object through a filter to allow a custom * validation to be inserted * * if a custom validation is implemented, the $field->error_type must be set * to a validation method key string. If the key string is a defined validation * method, that method will be applied. If $field->validation is set to false * by the filter callback, no further processing will be applied. * */ Participants_Db::set_filter('before_validate_field', $field); /* * if there is no validation method defined, exit here */ if (empty($field->validation) || $field->validation === NULL || $field->validation == 'no' || $field->validation === FALSE) { return; } /* * if the validation method is set and the field has not already been * validated (error_type == false) we test the submitted field for empty using * a defined method that allows 0, but no whitespace characters. * * a field that has any validation method and is empty will validate as empty first */ if ($field->error_type === false) { // we can validate each form element differently here if needed switch ($field->form_element) { case 'file-upload': case 'image-upload': /* * only "required" validation is allowed on this. Restricting file types * is done in the "values" field or in the settings */ $field->validation = 'yes'; if ($this->is_empty($field->value)) { $field->error_type = 'empty'; } break; case 'link': // a "link" field only needs the first element to be filled in if ($this->is_empty($field->value[0])) { $field->error_type = 'empty'; } break; default: if ($this->is_empty($field->value)) { $field->error_type = 'empty'; } } // if the field validation is 'yes' we're done if ($field->error_type === false && $field->validation == 'yes') { $field->error_type = 'valid'; } } /* * if the field has still not been validated, we process it with the remaining validation methods */ if ($field->error_type === false) { $regex = ''; $test_value = false; switch (true) { /* * the validation method key for an email address was formerly 'email' This * has been changed to 'email-regex' but will still come in as 'email' from * legacy databases. We test for that by looking for a field named 'email' * in the incoming values. */ case $field->validation == 'email-regex' || $field->validation == 'email' && $field->name == 'email': $regex = '#^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$#i'; break; case 'captcha' == strtolower($field->validation): $field->value = isset($field->value[1]) ? $field->value[1] : ''; // grab the value and the validation key list($info, $value) = isset($this->post_array[$field->name][1]) ? $this->post_array[$field->name] : array($this->post_array[$field->name][0], $field->value); $info = json_decode(urldecode($info)); /* * if we don't have a regex, assume it's a plugin CAPTCHA and decode it's validation regex */ if (empty($regex)) { $regex = $this->xcrypt($info->nonce, PDb_CAPTCHA::get_key()); } //error_log(__METHOD__.' $info:'.print_r($info,1).' $field->value:'.$field->value.' regex:'.$regex); break; case $this->_is_regex($field->validation): $regex = $field->validation; break; /* * if it's not a regex, test to see if it's a valid field name for a match test */ /* * if it's not a regex, test to see if it's a valid field name for a match test */ case isset($this->post_array[strtolower($field->validation)]): $test_value = $this->post_array[strtolower($field->validation)]; break; default: } if ($test_value !== false) { if ($field->value != $test_value) { $field->error_type = 'nonmatching'; } } elseif ($regex !== false) { $test_result = preg_match($regex, $field->value); if ($test_result === 0) { $field->error_type = $field->validation == 'captcha' ? 'captcha' : 'invalid'; } elseif ($test_result === false) { error_log(__METHOD__ . ' captcha regex error with regex: "' . $regex . '"'); } } } if ($field->error_type) { if ($field->error_type != 'valid') { $this->_add_error($name, $field->error_type, false); } $valid = $field->error_type; } else { $valid = 'valid'; } /* * the result of a captcha validation are stored in a session variable */ if (strtolower($validation) === 'captcha' || $field->form_element == 'captcha') { Participants_Db::$session->set('captcha_result', $valid); } if (false) { error_log(__METHOD__ . ' field: ' . $name . ' element: ' . $field->form_element . ' value: ' . (is_array($field->value) ? print_r($field->value, 1) : $field->value) . ' validation: ' . (is_bool($field->validation) ? $field->validation ? 'true' : 'false' : $field->validation) . ' submitted? ' . ($this->not_submitted($name) ? 'no' : 'yes') . ' empty? ' . ($this->is_empty($field->value) ? 'yes' : 'no') . ' error type: ' . $field->error_type); } }
/** * builds a captcha element * */ protected function _captcha() { $captcha = new PDb_CAPTCHA($this); $this->_addline($captcha->get_html()); }