/** * Generates the control's HTML code. * * <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i> * * @return string The control's HTML code */ function toHTML() { // all file upload controls must have the "upload" rule set or we trigger an error if (!isset($this->rules['upload'])) { _zebra_form_show_error('The control named <strong>"' . $this->attributes['name'] . '"</strong> in form <strong>"' . $this->form_properties['name'] . '"</strong> must have the <em>"upload"</em> rule set', E_USER_ERROR); } // if the "image" rule is set if (isset($this->rules['image'])) { // these are the allowed file extensions $allowed_file_types = array('jpe', 'jpg', 'jpeg', 'png', 'gif'); } elseif (isset($this->rules['filetype'])) { // get the array of allowed file extensions $allowed_file_types = array_map(create_function('$value', 'return trim($value);'), explode(',', $this->rules['filetype'][0])); } // if file selection should be restricted to certain file types if (isset($allowed_file_types)) { $mimes = array(); // iterate through allowed extensions foreach ($allowed_file_types as $extension) { // get the mime type for each extension if (isset($this->form_properties['mimes'][$extension])) { $mimes = array_merge($mimes, (array) $this->form_properties['mimes'][$extension]); } } // set the "accept" attribute // see http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#file-upload-state-%28type=file%29 // at the time of writing, on December 30, 2012, this was only working on Chrome 23 and IE 10 $this->set_attributes(array('accept' => '.' . implode(',.', $allowed_file_types) . ',' . implode(',', $mimes))); } // show the file upload control $output = '<input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '>'; // return the generated output return $output; }
/** * Checks if all the conditions set by the "dependencies" rule are met or not. * * @param string $id The ID of the element to check. * * @param array $referer (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 */ 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 { $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]) && ($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 (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; }
/** * Generates the control's HTML code. * * <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i> * * @return string The control's HTML code */ function toHTML() { // all date controls must have the "date" rule set or we trigger an error if (!isset($this->rules['date'])) { _zebra_form_show_error('The control named <strong>"' . $this->attributes['name'] . '"</strong> in form <strong>"' . $this->form_properties['name'] . '"</strong> must have the <em>"date"</em> rule set', E_USER_ERROR); } return ' <div> <input ' . $this->_render_attributes() . ($this->form_properties['doctype'] == 'xhtml' ? '/' : '') . '> <div class="clear"></div> </div> '; }
/** * Adds options to the select box control * * <b>If the "multiple" attribute is not set, the first option will be always considered as the "nothing is selected" * state of the control!</b> * * @param array $options An associative array of options where the key is the value of the option and the * value is the actual text to be displayed for the option. * * <b>Option groups</b> can be set by giving an array of associative arrays as argument: * * <code> * // add as groups: * $obj->add_options(array( * 'group' => array('option 1', 'option 2') * )); * </code> * * @param boolean $overwrite (Optional) By default, succesive calls of this method will appended the options * given as arguments to the already existing options. * * Setting this argument to TRUE will instead overwrite the previously existing options. * * Default is FALSE * * @return void */ function add_options($options, $overwrite = false) { // continue only if parameter is an array if (is_array($options)) { // get some properties of the select control $attributes = $this->get_attributes(array('options', 'multiple')); // if there are no options so far AND // we're not overwriting existing options AND // the "multiple" attribute is not set if (empty($attributes['options']) && $overwrite === false && !isset($attributes['multiple'])) { // add the default value // we'll replace the value with the appropriate language $options = array('' => $this->form_properties['language']['select']) + $options; } // set the options attribute of the control $this->set_attributes(array('options' => $overwrite ? $options : $attributes['options'] + $options)); // if options are not specified as an array } else { // trigger an error message _zebra_form_show_error(' Selectable values for the <strong>' . $this->attributes['id'] . '</strong> control must be specified as an array '); } }