function validate()
{
// reference to the form submission method
global ${'_' . $this->form_properties['method']};
$method =& ${'_' . $this->form_properties['method']};
$this->proxies_cache = array();
// we assume the form is not valid (or it was not submitted)
$form_is_valid = false;
// continue only if form was submitted
if (isset($method[$this->form_properties['identifier']]) && $method[$this->form_properties['identifier']] == $this->form_properties['name']) {
// if
if (isset($method[$this->form_properties['honeypot']]) && $method[$this->form_properties['honeypot']] == '' && ($csrf_status = $this->_csrf_validate())) {
// remove the honeypot and csrf entries so that we don't polute the $_POST array
unset($method[$this->form_properties['honeypot']]);
unset($method[$this->form_properties['csrf_token_name']]);
// by default, we assume that the form is valid
$form_is_valid = true;
// iterate through the controls
foreach (array_keys($this->controls) as $key) {
// reference to control
$control =& $this->controls[$key];
// get some attributes of the control
$attribute = $control->get_attributes(array('type'));
// validate the control
$valid = $this->validate_control($key);
// do some extra checkings and cleanup
if ($attribute['type'] == 'password' || $attribute['type'] == 'text' && isset($control->rules['captcha'])) {
$control->set_attributes(array('value' => ''));
}
// if control is not valid, the form is not valid
if (!$valid) {
// unless the element is a file upload control, add the "error" class to it so we can apply
// custom styles to erroneous fields
if ($attribute['type'] != 'file') {
$control->set_attributes(array('class' => 'error'), false);
}
$form_is_valid = false;
}
}
// after iterating through all the controls,
// check if the form is still valid
if ($form_is_valid) {
// if there are any actions to be performed when the form is valid
// (file upload, resize, convert)
if (isset($this->actions) && !empty($this->actions)) {
// iterate through the actions
foreach ($this->actions as $actions) {
// if the respective action (method) exists
if (method_exists($this, $actions[0])) {
// if the method was erroneous
if (!call_user_func_array(array(&$this, $actions[0]), array_slice($actions, 1))) {
// add error message to indicated error block
$this->add_error($actions['block'], $actions['message']);
// set the form as not being valid
$form_is_valid = false;
}
// if the task (method) could not be found, trigger an error message
} else {
_zebra_form_show_error('Method ' . $actions[0] . ' does not exist!', E_USER_ERROR);
}
}
}
}
// else if
} elseif (!isset($method[$this->form_properties['honeypot']]) || $method[$this->form_properties['honeypot']] != '') {
$this->add_error('zf_error_spam', $this->form_properties['language']['spam_detected']);
} elseif (!$csrf_status) {
$this->add_error('zf_error_csrf', $this->form_properties['language']['csrf_detected']);
}
// if
if ($form_is_valid || !isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
$this->_csrf_generate_token(true);
}
// here's a special error check:
// due to a bug (?) when the POST/GET data is larger than allowed by upload_max_filesize/post_max_size the
// $_POST/$_GET/$_FILES superglobals are empty (see http://bugs.php.net/bug.php?id=49570)
// but still, we need to present the user with some error message...
} elseif (empty($method) && isset($_SERVER['CONTENT_LENGTH']) && (int) $_SERVER['CONTENT_LENGTH'] > 0) {
$form_is_valid = false;
} elseif ($this->form_properties['auto_fill'] !== false) {
// we'll use this variable to keep track of groups of radio buttons/checkboxes
// where we've randomly selected a value
$checked = array();
// iterate through the form's controls
foreach ($this->controls as $key => $control) {
// get some attributes for each control
$attributes = $control->get_attributes(array('type', 'name', 'value'));
// sanitize controls' name (remove square brackets)
$attributes['name'] = preg_replace('/\\[\\]$/', '', $attributes['name']);
// if we need to select predefined values for specific controls
if (isset($this->form_properties['auto_fill'][0][$attributes['name']])) {
// the value/values that is/are to be preselected
$value = $this->form_properties['auto_fill'][0][$attributes['name']];
// if control is a radio button or a checkbox
if ($attributes['type'] == 'checkbox' || $attributes['type'] == 'radio') {
// if
if (!is_array($value) && $value == $attributes['value'] || is_array($value) && $attributes['type'] != 'radio' && in_array($attributes['value'], $value)) {
$control->set_attributes(array('checked' => 'checked'));
}
// for the other controls, simply set the value
} else {
$control->set_attributes(array('value' => $value));
}
// if no predefined value was given for the control and we don't auto-fill only specific controls
} elseif (!$this->form_properties['auto_fill'][1]) {
// if control is a radio button or a checkbox
if ($attributes['type'] == 'checkbox' || $attributes['type'] == 'radio') {
// if we've not already selected a random value for the group of radio buttons/checkboxes
// the current element is part of
if (!isset($checked[$attributes['name']])) {
// this will hold the randomly selected elements
$tmp_checked = array();
// iterate through all the form's controls
foreach ($this->controls as $element) {
// if control is of the same type and has the same name
if ($element->attributes['type'] == $attributes['type'] && $element->attributes['name'] == $attributes['name']) {
// if element is checked by default, from when creating the form
if (isset($element->attributes['checked'])) {
// we will consider this group as checked
$checked[$attributes['name']] = true;
// ...and look no further
break;
// if element is not checked by default and we should select the current value,
// save it for later as we first need to check if an element of the group is not
// already checked
// (also, for radio buttons make sure we select a single option)
} elseif (rand(0, 1) == 1 && !($attributes['type'] == 'radio' && !empty($tmp_checked))) {
$tmp_checked[] = $element;
}
}
}
// if no element of the group was selected
if (!isset($checked[$attributes['name']])) {
// if there are any randomly selected elements
if (!empty($tmp_checked)) {
// iterate through the selected elements and mark them as "checked"
foreach ($tmp_checked as $element) {
$element->set_attributes(array('checked' => 'checked'));
}
}
// if there are no randomly selected elements then select the current (first) element
$control->set_attributes(array('checked' => 'checked'));
}
// flag this group of elements so we're only doing this once
$checked[$attributes['name']] = true;
}
// if control is a drop-down or a multiple select box and does not already has a value
} elseif ($attributes['type'] == 'select' && $attributes['value'] === '') {
// select a random value
// (if "multiple" attribute is set, select from all the values, or select starting from the second value otherwise)
$keys = array_slice(array_keys($control->attributes['options']), isset($control->attributes['multiple']) && strtolower(trim($control->attributes['multiple'])) == 'multiple' ? 0 : 1);
// if the select has any values, set a random value
if (!empty($keys)) {
$control->set_attributes(array('value' => $keys[array_rand($keys)]));
}
// if control is "password"
} elseif ($attributes['type'] == 'password') {
// set the value to "12345678"
$control->set_attributes(array('value' => '12345678'));
// if control is "text" or "textarea" and does not already have a value
} elseif (in_array($attributes['type'], array('text', 'textarea', 'email', 'number')) && $attributes['value'] === '') {
// if this is a "date" control
if (strtolower(get_class($control)) == 'zebra_form_date') {
// get the date control's starting/ending date
$limits = $control->_init();
// set the value to the first selectabel date
$control->set_attributes(array('value' => date($control->attributes['format'], $limits[0] > 0 ? $limits[0] : time())));
// continue only if the control doesn't have the "regexp" or the "captcha" rule set
} elseif (!isset($control->rules['regexp']) && !isset($control->rules['captcha'])) {
unset($value);
// default character set to choose from
$characters = 'abcdefghijklmnopqrstuvwxyz';
// for controls having the "alphabet", "email" or "emails" rule set
if (isset($control->rules['alphabet']) || isset($control->rules['email']) || isset($control->rules['emails'])) {
// use these characters in the random string
$characters = 'abcdefghijklmnopqrstuvwxyz';
}
// for controls having the "alphanumeric" rule set
if (isset($control->rules['alphanumeric'])) {
// use these characters in the random string
$characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
}
// for controls having the "digits" or "number" rule set
if (isset($control->rules['digits']) || isset($control->rules['number'])) {
// use these characters for the random value
$characters = '0123456789';
}
// for controls having the "float" rule set
if (isset($control->rules['float'])) {
// generate a random value
$value = number_format(mt_rand(0, 99999) / 100, 2);
}
// if a value was not yet generated
if (!isset($value)) {
$value = '';
// get a random length for our value
$length = rand(isset($control->rules['length']) && $control->rules['length'][0] != 0 ? $control->rules['length'][0] : 10, isset($control->rules['length']) && $control->rules['length'][1] != 0 ? $control->rules['length'][1] : ($attributes['type'] == 'textarea' ? 100 : 10));
// get a random character until we get to the length defined above
// for textareas include a space every once in a while
for ($i = 0; $i < $length; $i++) {
$value .= $attributes['type'] == 'textarea' && in_array(rand(0, 10), array(4, 6)) ? ' ' : $characters[rand(0, strlen($characters) - 1)];
}
// if control has the "email" or "emails" rule set
if (isset($control->rules['email']) || isset($control->rules['emails'])) {
// append an "@" to the already generated value
$value .= '@';
// and then generate six more random characters
for ($i = 0; $i < 6; $i++) {
$value .= $characters[rand(0, strlen($characters) - 1)];
}
// finish up with a ".com"
$value .= '.com';
// if control has the "url" rule set add the "http://" prefix (if required) and the ".com" suffix
} elseif (isset($control->rules['url'])) {
$value = ($control->rules['url'][0] ? 'http://' : '') . $value . '.com';
}
}
// finally, if we have a random value for the control, set it
if (isset($value)) {
$control->set_attributes(array('value' => trim($value)));
}
}
// if control is "time"
} elseif ($attributes['type'] == 'time' && $attributes['value'] === '') {
// select random values, from the exiting ones
$control->set_attributes(array('value' => $control->attributes['hours'][array_rand($control->attributes['hours'])] . ':' . $control->attributes['minutes'][array_rand($control->attributes['minutes'])] . ':' . $control->attributes['seconds'][array_rand($control->attributes['seconds'])]));
}
}
}
}
// return the state of the form
return $form_is_valid;
}