Zebra_Form::_validate_dependencies PHP Method

_validate_dependencies() private method

@param string $id The ID of the element to check.
private _validate_dependencies ( string $id, array $referer = [] ) : boolean
$id string
$referer array (Private) Used by the library to prevent entering an infinite loop of dependencies. @return boolean Returns TRUE if all the conditions are met or FALSE otherwise. @access private
return boolean
    private function _validate_dependencies($id, $referer = array())
    {
        // reference to the form submission method
        global ${'_' . $this->form_properties['method']};
        $method =& ${'_' . $this->form_properties['method']};
        // if the rule is applied to a radio button group or a checkbox group
        // there will be no entry with the given id as all group's elements will have their ID in the form of [name]_[value]
        if (!isset($this->controls[$id])) {
            // ...therefore, we have to iterate over all the form's controls
            foreach ($this->controls as $control) {
                // and if we find the control we're looking for
                if (preg_replace('/\\[\\]$/', '', $control->attributes['name']) == $id) {
                    // get the ID of the control
                    $id = $control->attributes['id'];
                    // don't look any further
                    break;
                }
            }
        }
        // if there are more than 2 entries in the referer array, remove the first one
        if (count($referer) > 2) {
            array_shift($referer);
        }
        // if current element is the referer array
        if (in_array($id, $referer)) {
            // we're having a recursion and we're stopping execution
            _zebra_form_show_error('Infinite recursion detected. The loop of dependencies is created by the following elements: "' . implode('", "', $referer) . '"', E_USER_ERROR);
        }
        // add current element to the stack
        array_push($referer, $id);
        $result = true;
        // if the control exists
        if (isset($this->controls[$id])) {
            // if we're checking if a proxy depends on another proxy, but it doesn't, return TRUE now
            if (!isset($this->controls[$id]->rules['dependencies'])) {
                return true;
            }
            // get all the conditions needed to validate the element
            $conditions = $this->controls[$id]->rules['dependencies'];
            // if the name of a callback function is also given
            // the actual conditions are in the first entry of the array
            if (isset($conditions[1])) {
                $conditions = $conditions[0];
            }
            // iterate through the elements the validation of the current element depends on (proxies)
            foreach ($conditions as $proxy => $required_values) {
                // if we have a cached result of the result
                if (isset($this->proxies_cache[$proxy][serialize($required_values)])) {
                    // get the result from cache
                    $result = $this->proxies_cache[$proxy][serialize($required_values)];
                } else {
                    $is_radio_or_checkbox = false;
                    // $this->controls[$proxy] will never be set for radio or checkbox controls (as $proxy is the ID, not the name)
                    if (!isset($this->controls[$proxy])) {
                        // iterate through all the controls
                        foreach ($this->controls as $control_properties) {
                            // if we found a control radio/checkbox element with the sought name
                            if ($control_properties->attributes['name'] == $proxy && ($control_properties->attributes['type'] == 'radio' || $control_properties->attributes['name'] == 'checkbox')) {
                                // set this flag
                                $is_radio_or_checkbox = true;
                                // don't look further
                                break;
                            }
                        }
                    }
                    $found = false;
                    // a proxy may also depend on the values of or or more other proxies
                    // therefore, continue only if those conditions are met
                    if ((isset($this->controls[$proxy]) || $is_radio_or_checkbox) && (!$is_radio_or_checkbox && $this->controls[$proxy]->attributes['type'] == 'image' && isset($method[$proxy . '_x']) && isset($method[$proxy . '_y']) || isset($method[$proxy])) && $this->_validate_dependencies($proxy, $referer)) {
                        // if proxy is a submit or an image submit button
                        if (!$is_radio_or_checkbox && in_array($this->controls[$proxy]->attributes['type'], array('image', 'submit'))) {
                            $current_values = array('click');
                        } else {
                            $current_values = !is_array($method[$proxy]) ? array($method[$proxy]) : $method[$proxy];
                        }
                        // if condition is not an array
                        if (!is_array($required_values)) {
                            // iterate through the proxy's values
                            // (remember, we store it as an array even if there's a single value)
                            foreach ($current_values as $current_value) {
                                // if the value of the condition is amongst the proxy's values, flag it
                                if ($current_value == $required_values) {
                                    $found = true;
                                }
                            }
                            // if condition is given as an array
                        } else {
                            // iterate through all the conditions
                            foreach ($required_values as $required_value) {
                                $matches = 0;
                                // iterate through the values of the proxy element
                                // (remember, we store it as an array even if there's a single value)
                                foreach ($current_values as $current_value) {
                                    // if current entry in the conditions list is not an array
                                    // and its value is equal to the current value
                                    if (!is_array($required_value) && $current_value == $required_value) {
                                        $found = true;
                                    } else {
                                        if (is_array($required_value) && in_array($current_value, $required_value)) {
                                            $matches++;
                                        }
                                    }
                                }
                                // if all conditions are met
                                if (!$found && $matches == count($required_values)) {
                                    $result = true;
                                }
                            }
                        }
                        // if not all conditions are met, don't check any further
                        if (!$found) {
                            $result = false;
                            break;
                        }
                        // if proxy is not submitted, or proxy's dependendecies are not ok, don't check the other conditions
                    } else {
                        $result = false;
                    }
                }
                // cache the result
                if (!isset($this->proxies_cache[$proxy][serialize($required_values)])) {
                    $this->proxies_cache[$proxy][serialize($required_values)] = $result;
                }
            }
        }
        // if script gets this far, consider all the conditions are met, and validate the other rules
        return $result;
    }