assign_libs ('uri', 'load'); $this->load->helper (array('url', 'security', 'inflector', 'string', 'form', 'tab', 'forge')); // Let's go! $this->initialize($params); // Why not... log_message('debug', "Forge Class Initialized"); } public function initialize ($params = array()) { // Reset defaults $this->action = ''; $this->form_name = ''; $this->template = ''; $this->upload_path = ''; $this->max_size = ''; $this->rules = array(); $this->upload_rules = array(); $this->errors = array(); // Unset disallowed params $disallowed = array ('CI'); foreach ($disallowed as $param) unset ($params[$param]); // Set params if (count ($params) > 0) { foreach ($params as $param => $value) if (isset($this->$param)) $this->$param = $value; } // We can't allow the following variables to be set by the user $this->group_name = '[default]'; $this->last_group = '[default]'; $this->tab_index = 1; $this->validated = false; $this->has_upload = false; $this->has_error = false; $this->tree = array(); $this->uploads = array(); $this->elements = array(); $this->attributes = array ( 'type', 'maxlength', 'value', 'options', 'rows', 'cols', 'size', 'selected', 'checked', 'disabled', 'label', 'id', 'style', 'before', 'after'); // Make sure action is set if ($this->action == false) $this->set_action(); // Check upload path if ($this->upload_path != false) $this->set_upload_path ($this->upload_path); // Max size must be set if ($this->max_size == false) { // Cache the size static $size; // Fetch the size, if not cached if ($size == false) { // Use php.ini to set the size $size = @ini_get ('upload_max_filesize'); // Check if the last character of the string is a number $byte = strtolower (substr ($size, -1, 1)); if (! is_numeric ($byte)) { $size = substr ($size, 0, (strlen($size)-1)); switch ($byte) { case 'g': $size *= 1024; // to MB case 'm': $size *= 1024; // to KB default: break; // Done } } else // The size in php.ini is set in bytes, we need kilobytes $size /= 1024; } // Set maximum size $this->max_size = $size; } // Create our default group $this->new_group ('default'); $this->groups['default']['legend'] = $this->form_name; } public function form_name ($name = false) { if ($name == false) $name = $this->form_name; return $name; } public function form_open ($data = false) { if ($data == false) $data = array(); $form_open = $this->has_upload ? 'form_open_multipart' : 'form_open'; return $form_open ($this->action, $data); } public function form_close() { return form_close(); } // INPUT CREATION --------------------------------------------------------- public function set_action ($action = false) { if ($action == false) { if ($this->action != false) return false; $action = $this->uri->uri_string(); } $this->action = $action; return true; } public function set_upload_path ($path) { // Make sure the upload path is writable if (! is_writable ($path)) show_error ("The file upload path \"$path\" must be server writable."); $this->upload_path = $path; return true; } public function new_group ($name, $legend = false, $cols = false) { // If name is false, we can't continue if ($name == false) return false; // Create index array $index = explode ('-', $name); if ($name != 'default') array_unshift ($index, 'default'); // Compile index location $index = "['". implode ("']['", $index) ."']"; // Save last group $this->last_group = $this->group_name; $this->groups[$name]['legend'] = $legend; $this->groups[$name]['type'] = 'list'; if (is_array ($cols)) { // This is a table type $this->groups[$name]['type'] = 'table'; // Check each column for valid data and add it foreach ($cols as $_name => $_data) { $this->filter_data ($_name, $_data); $this->groups[$name]['cols'][$_name] = $_data; } } return $this->switch_group ($index); } public function prev_group() { $index = $this->last_group; // Save the last group, if not default if ($index != '[default]') { $offset = strrpos ($index, '['); $this->last_group = substr ($index, 0, $offset); } return $this->switch_group ($index); } public function set_group_text ($name, $text) { $text = trim ($text); if ($text != false) $this->groups[$name]['text'] = $text; } public function get ($name, $key = false) { if ($key == false) $return = isset ($this->elements[$name]) ? $this->elements[$name] : false; else $return = isset ($this->elements[$name][$key]) ? $this->elements[$name][$key] : false; return $return; } public function set ($name, $key, $value = false) { if (! isset ($this->elements[$name])) return false; $this->elements[$name][$key] = $value; return true; } public function set_rules ($name, $rule) { if ($rule == false) return false; if (is_array ($rule)) { // Recursive ftw foreach ($rule as $r) $this->set_rules ($name, $r); return true; } $pipe = (isset ($this->rules[$name]) && @strlen($this->rules[$name]) > 1) ? '|' : ''; $offset = strpos ($rule, '['); $offset = ($offset === false) ? strlen ($rule) : $offset; switch (substr ($rule, 0, $offset)) { case 'required': $this->rules[$name] .= "{$pipe}required"; // Check if we are using meta-arrays if ($size = strtoarray ($rule)) { // Make min an integer $min = (int) $size[0]; // Max is an integer if the format was [2,3], otherwise false $max = (isset ($size[1])) ? (int) $size[1] : false; // No max and a min means exact length if ($max === false && $min > 0) $this->set_rules ($name, "exact_length[$min]"); // If min and max are the same, exact length elseif (($min == $max) && $min > 0) $this->set_rules ($name, "exact_length[$min]"); // Min and max are not both zero else { if ($min > 0) $this->set_rules ($name, "min_length[$min]"); if ($max > $min) $this->set_rules ($name, "max_length[$max]"); } } break; case 'allow': $types = strtoarray ($rule); $this->upload_rules[$name] = implode ('|', $types); break; default: $this->rules[$name] .= $pipe.$rule; break; } return true; } public function add ($name, $data = false) { if ($name == false) return false; // Filter our data $this->filter_data ($name, $data); // Set upload status if ($data['type'] == 'file') $this->has_upload = true; // Add the input to the current group $this->group[] = $name; $this->elements[$name] = $data; return true; } public function remove ($name) { if ($name == false) return false; // Unset known variables unset ( $this->elements[$name], $this->rules[$name], $this->upload_rules[$name]); // Remove it from the tree $this->tree_remove ($name, $this->tree); return true; } public function add_error ($name, $error) { // Get current errors $e = @$this->elements[$name]['error']; // Set new error $this->elements[$name]['error'] = $e.sprintf('

%s

%s', $error, "\n"); return true; } public function build ($template = false, $data = false) { if ($data == false) $data = array(); // Data used for every type $data['name'] = $this->form_name(); $data['open'] = $this->form_open(); $data['close'] = $this->form_close(); $data['tree'] = $this->tree; $data['groups'] = $this->groups; foreach ($this->elements as $name => $elem) { $type = array_remove ('type', $elem); $data['elements'][$name] = $this->input ($type, $name, $elem); } // Return array of elements if ($template === true) return $data; // Build with no template if ($template == false) { if (! is_object ($this->table)) { $this->load->library ('table'); $this->assign_libs ('table'); } // Clear table and go $this->table->clear(); $this->table->set_template (array('table_open' => '')); ob_start(); print $data['open']."\n"; $this->build_fieldset($data['tree'], $data['elements'], $data['groups'], true); print $data['close']."\n"; $output = ob_get_contents(); ob_end_clean(); return $output; } return $this->load->view ("forge/$template", $data, true); } public function label ($name, $label) { // If the name is false, it would return an invalid label if ($name == false) return ''; // Check if the input is required $required = $this->is_required ($name); // Compile label $label = ($label == false) ? humanize ($name) : ucfirst ($label); $label = $required ? "$label *" : $label; $label = sprintf ('', $name, $label); return $label; } public function input ($type, $name, $data, $extra = false) { // Need a valid name if ($name == false) return false; $data['name'] = $name; // The name for the label must not be an array type $_name = preg_replace ('@\[.*\]@', '', $name); // Add id to the beginning of data if ($_name == $name) $data = array_unshift_assoc ($data, 'id', $_name); // Get a label $label = array_remove ('label', $data); $label = ($type != 'submit' && $type != 'hidden') ? $this->label ($_name, $label) : ''; // Remove error if it exists $error = array_remove ('error', $data); // Remove before and after strings $before = (string) array_remove ('before', $data); $after = (string) array_remove ('after', $data); // Create the input, using CI form_helper switch ($type) { case 'tablerow': $table = array_remove ('cols', $data); // This defines our inputs, so we need it if (! isset ($this->groups[$table]['cols'])) show_error ("Tablerow type inputs required the cols attribute to be set."); // Fetch input data $inputs = $this->groups[$table]['cols']; // Remove label column array_shift ($inputs); // Loop through inputs and build foreach ($inputs as $_key => $_data) { unset ($_data['label']); $_type = array_remove ('type', $_data); $_name = sprintf ('%s[%s]', $name, $_key); $input[$_key] = array_remove ('input', $this->input ($_type, $_name, $_data)); } break; case 'telephone': $value = array_remove ('value', $data); $input = $this->telephone ($name, $value); break; case 'citystatezip': $value = array_remove ('value', $data); $input = $this->citystatezip ($name, $value); break; case 'dateselect': $value = array_remove ('value', $data); $input = $this->dateselect ($name, $value); break; case 'dropdown': $options = array_remove ('options', $data); $options = is_array ($options) ? $options : array(); $selected = array_remove ('selected', $data); $input = form_dropdown ($name, $options, $selected, $extra); break; case 'radio': $options = array_remove ('options', $data); $options = is_array ($options) ? $options : array(); $selected = array_remove ('selected', $data); foreach ($options as $opt => $title) { $checked = ($opt == $selected) ? true : false; $out[] = trim (form_radio ($name, $opt, $checked, $extra)).$title; } $input = implode (' ', $out); break; case 'checkbox': $value = array_remove ('value', $data); $value = ($value == false) ? '1' : $value; $checked = array_remove ('checked', $data); $input = form_checkbox ($name, $value, $checked, $extra); break; case 'submit': $value = array_remove ('value', $data); $input = form_submit ($name, $value); break; case 'hidden': $value = array_remove ('value', $data); $input = form_hidden ($name, $value); break; case 'text': $data['size'] = isset ($data['size']) ? $data['size'] : 20; $input = form_input ($data); break; case 'password': $data['size'] = isset ($data['size']) ? $data['size'] : 20; $input = form_password ($data, $extra); break; case 'file': unset ($data['value']); $this->has_upload = true; $data['size'] = isset ($data['size']) ? $data['size'] : 20; $input = form_upload ($data, $extra); break; default: $func = "form_$type"; // Bad input type request if (! function_exists ($func)) show_error ("Invalid form input type \"$type\" requested for $name."); $input = $func ($data, $extra); break; } // The form helper adds a newline, we don't want it if (! is_array ($input)) $input = trim($input); // Add error if one exists if ($this->validated) { $e = "{$name}_error"; $e = (isset ($this->validation->$e)) ? $this->validation->$e : ''; $error = "$error$e"; } // Compile our return if (is_array ($input)) { $return['label'] = $label.$error; $return['input'] = $input; } else { $return['label'] = $label; $return['input'] = $before.$input.$after.$error; } return $return; } // VALIDATION AND POST RETREVAL FUNCTIONS --------------------------------- public function validate() { // We have validated! $this->validated = true; // Validate uploads $this->validate_uploads(); // No need to validate if there are no rules if (count ($this->rules) < 1) return true; // Import the rules $rules = $this->rules; // Set the fields foreach (array_keys ($rules) as $e) { $field = (isset ($this->elements[$e]['label'])) ? $this->elements[$e]['label'] : humanize ($e); $fields[$e] = strtolower ($field); } // Load Validation library $this->load->library ('validation'); $this->assign_libs ('validation'); $this->validation->set_error_delimiters ('

', '

'); $this->validation->set_rules ($rules); $this->validation->set_fields ($fields); // Run validation $return = $this->validation->run(); // Set error state if ($return == false) $this->has_error = true; return $return; } public function validate_uploads() { // No rules, no reason to continue if (count ($this->upload_rules) < 1) return true; if ($this->upload_path == false) $this->set_upload_path ('./upload/'); // Load Upload class $this->load->library ('upload'); $this->assign_libs ('upload'); // Default configuration $conf['max_size'] = $this->max_size; $conf['upload_path'] = $this->upload_path; $conf['allowed_types'] = ''; $conf['xss_clean'] = false; $conf['remove_space'] = true; // Run all uploads $uploads = array(); foreach ($this->upload_rules as $name => $allow) { $conf['allowed_types'] = $allow; $this->upload->initialize ($conf); if ($this->upload->do_upload ($name)) $this->uploads[$name] = $this->upload->data(); elseif ($this->is_required ($name)) { $this->has_error = true; $error = $this->upload->display_errors ('

', '

'); $this->elements[$name]['error'] = $error; } } $this->has_error = isset($error) ? true : false; return (! $this->has_error); } public function populate ($return = false) { $this->assign_libs ('input'); $return = (bool) $return; $values = array(); foreach (array_keys($this->elements) as $name) { // The key we will set $key = 'value'; // Retrieve value for this input if ($this->validated) $value = $this->input->post ($name); else $value = $this->elements[$name]['value']; // Some elements require a different key to be set switch ($this->elements[$name]['type']) { // This one is strange because we have to return the value of checkbox, // but set the "checked" status checking the POST against the set value case 'checkbox': $retval = $this->elements[$name]['value']; // Set checked only if the POST is the same as value if ($this->validated) $this->elements[$name]['checked'] = ($value === $retval) ? true : false; // We always set the value to the previous value $value = $retval; // If the element is not checked, we return false if ($this->elements[$name]['checked'] == false) $retval = false; break; case 'dropdown': $key = 'selected'; break; case 'radio': $key = 'selected'; break; case 'submit': $value = $this->elements[$name]['value']; break; case 'file': $retval = $this->uploads[$name]; break; } // If specific return is set, use $value if (! isset ($retval)) $retval = $value; // Set the value of this input $this->elements[$name][$key] = $value; $values[$name] = $retval; // Don't leave garbage around unset($retval); } return ($return ? $values : true); } public function post_data ($print = false) { // Run validation if it hasn't already if ($this->validated == false) $this->validate(); // Fetch POST data $post = $this->populate (true); // Print request outputs the POST data if ($print == true) { $pre = ''; foreach ($post as $key => $val) $pre .= sprintf ("%20s: %s \n", $key, print_r($val,true)); return sprintf ("
POST DATA (debug)
\n
\n%s
\n", $pre); } // If validation causes an error, return nothing if ($this->has_error == true) return false; return $this->populate (true); } // XML FORM PARSING FUNCTIONS --------------------------------------------- public function load ($name) { // We can't load XML via load_class, because it prefixes it with CI_ $obj =& get_instance(); $obj->load->library ('xml'); // Load the form if (! $obj->xml->load ("forms/$name")) show_error ("Requested form does not exist: $name."); // Parse the XMl into an array $data = $obj->xml->parse(); if (! is_array($data)) show_error ("Requested form could not be parsed: $name."); $data = $data['form'][0]; // Set up our configuration $conf['action'] = $data['__attrs']['action']; $conf['form_name'] = $data['fieldset'][0]['__attrs']['name']; // Initialize our shiny form $this->initialize ($conf); // Build the tree, extract inputs $this->get_fields ($data['fieldset'][0]); return true; } private function get_fields ($array) { foreach ($array as $name => $val) { if ($name == 'fieldset') { // Add fieldsets into the tree foreach ($val as $set) { // Get a name and a legend for recursion $legend = ucfirst ($set['__attrs']['name']); $text = @$set['__attrs']['text']; $name = url_title ($legend, 'underscore'); // Create new fieldset and build it $this->new_group ($name, $legend); $this->set_group_text ($name, $text); $this->get_fields ($set); // Switch to previous fieldset $this->prev_group(); } } elseif (! is_numeric ($key) && $key != '__attrs') { // Add inputs foreach ($val as $data) { if (! is_array ($data)) continue; // Parse attributes if ($attrs = array_remove ('__attrs', $data)) { $rules = array_remove ('rules', $attrs); $allow = array_remove ('allow', $attrs); // Add allowed file types into rules if ($allow != false) { $pipe = (strlen ($rules) > 1) ? '|' : ''; $allow = str_replace ('|', ',', $allow); $rules = "{$rules}{$pipe}allow[{$allow}]"; } // Have to use an zero index because of next fix if ($rules != false) $data['rules'][0] = $rules; } // Fix indexing foreach ($data as $k => $v) { $val = $v[0]; // Options need to be to shifted if ($k == 'options') $val = array_map('array_shift', $val); $data[$k] = $val; } // Add the input $this->add ($name, $data); } } } } // LEGACY ALIASES public function disable ($name) { return $this->remove($name); } // PRIVATE HELPER FUNCTIONS ----------------------------------------------- private function assign_libs() { static $loaded; $libs = func_get_args(); if (count ($libs) > 0) { $obj =& get_instance(); foreach ($libs as $lib) { if (isset ($loaded[$lib])) continue; if (isset ($obj->$lib) && is_object($obj->$lib)) { $this->$lib =& $obj->$lib; $loaded[$lib] = true; } } } } private function filter_data ($name, &$data) { if (! is_array($data)) $data = array(); if (! isset ($data['type'])) $data['type'] = 'text'; if ($rules = array_remove ('rules', $data)) { $rules = explode ('|', $rules); $this->set_rules ($name, $rules); } $filter = array(); foreach ($this->attributes as $a) if (isset ($data[$a])) $filter[$a] = $data[$a]; $data = $filter; } private function is_required ($name) { // No rules? Not required. if (! isset ($this->rules[$name])) return false; // Check if required return ((strpos ($this->rules[$name], 'required') !== false) ? true : false); } private function switch_group ($index) { if ($index == false) return; // Compile selection $switch = '$this->group =& $this->tree'.$index.';'; // Unset current group unset ($this->group); // Make our switch @eval($switch); // Save group name $this->group_name = $index; } private function tree_remove ($name, &$array) { foreach ($array as $key => $val) { // Recursive FTW! if (is_array ($val)) { $this->tree_remove ($name, $array[$key]); // No elements means we can remove the group if (count ($array[$key]) < 1) unset ($array[$key], $this->tree[$key]); continue; } // Kill it! if ($val == $name) unset ($array[$key]); } } private function build_fieldset ($set, $elements, $groups, $first = false) { // Recursive for the win! static $tabs; if ($tabs === null) $tabs = 1; foreach ($set as $g => $e) { if (is_array ($e)) { if ($first == false) printf ('%s
  • %s', repeater ("\t", $tabs++), "\n"); printf ('%s
    %s%s', repeater ("\t", $tabs++), $g, $groups[$g]['legend'], "\n"); if (isset($groups[$g]['text'])) printf ('%s

    %s

    %s', repeater ("\t", $tabs+1), $groups[$g]['text'], "\n"); } if ($groups[$g]['type'] == 'table') { $table = array(); foreach ($groups[$g]['cols'] as $group) $cols[] = $group['label']; $table[] = $cols; foreach ($e as $_e) { $t = array(); $row = $elements[$_e]; $t[] = $row['label']; foreach ($row['input'] as $col) $t[] = $col; $table[] = $t; } printf ('%s%s%s', repeater ("\t", $tabs), indent ($tabs, $this->table->generate($table)), "\n"); } else { if (is_array ($e)) { printf ('%s
      %s', repeater ("\t", $tabs), "\n"); $tabs++; $this->build_fieldset ($e, $elements, $groups, $obj); $tabs--; printf ('%s
    %s', repeater ("\t", $tabs), "\n"); } else { $label = $elements[$e]['label']; $input = $elements[$e]['input']; if (strpos ($input, 'type="hidden"') === false) printf ('%s
  • %s %s
  • %s', repeater ("\t", $tabs), $label, $input, "\n"); else printf ('%s%s%s', repeater ("\t", $tabs), $input, "\n"); } } if (is_array ($e)) { $tabs--; printf ('%s
    %s', repeater ("\t", $tabs), "\n"); if ($first == false) { $tabs--; printf ('%s
  • %s', repeater ("\t", $tabs), "\n"); } } } } // META FUNCTIONS --------------------------------------------------------- public function citystatezip ($name = false, $data = false, $label = false) { // These variables will need to be defined $required = array ('city', 'state', 'zip', 'plus4'); foreach ($required as $req) if (! isset ($data[$req])) $data[$req] = ''; // Sanity checks $name = ($name == false) ? 'location' : $name; // Create a label if ($label !== false) $label = $this->label ($name, $label); // Set the basename of the input $bname = "{$name}[%s]"; extract ($data, EXTR_OVERWRITE); list ($zip, $plus4) = explode ('-', valid_zip ($zip, (bool)$plus4)); // Create City input $input = array(); $input['size'] = 20; $input['value'] = valid_city ($city); $input['label'] = ($label == false) ? 'City/State/Zip' : $label; $city = $this->input ('text', sprintf($bname, 'city'), $input); // Create State dropdown $input = array(); $state = valid_state ($state); $input['options'] = array_keys (valid_states()); $input['options'] = array_combine ($input['options'], $input['options']); $input['selected'] = valid_state ($state); $state = $this->input ('dropdown', sprintf($bname, 'state'), $input); // Create ZIP code input $input = array(); $input['size'] = 5; $input['value'] = $zip; $input['maxlength'] = 5; $zip = $this->input ('text', sprintf($bname, 'zip'), $input); // Create plus4 input and append it to the zip input if ($zip != false && $plus4 != false) { $input = array(); $input['size'] = 4; $input['value'] = $plus4; $input['maxlength'] = 4; $plus4 = $this->input ('text', sprintf($bname, 'plus4'), $input); $plus4 = $plus4['input']; $zip['input'] .= "-$plus4"; } // Compile our label and input $return = $city['input'].' '.$state['input'].' '.$zip['input']; if ($label !== false) { $r['label'] = $city['label']; $r['input'] = $return; $return = $r; } return $return; } public function telephone ($name = false, $number = false, $label = false) { // Sanity checks $name = ($name == false) ? 'telephone' : $name; $number = ($number == true) ? valid_phone ($number, '-') : '--'; // Create the label if ($label !== false) $label = $this->label ($name, $label); // Set our basename for the inputs $bname = "{$name}[%s]"; // Extract the area code, prefix, and digits list ($area, $prefix, $digits) = explode ('-', $number); // Create the area, prefix, and digit inputs $inputs = array('area' => 3, 'prefix' => 3, 'digits' => 4); foreach ($inputs as $name => $size) { $input['size'] = $size; $input['value'] = $$name; $input['maxlength'] = $size; // We only want the input part $$name = array_remove ('input', $this->input ('text', sprintf ($bname, $name), $input)); } // Compile a label and input $return = "($area) $prefix-$digits"; if ($label !== false) { $r['label'] = $label; $r['input'] = $return; $return = $r; } return $return; } public function dateselect ($name = false, $data = false, $label = false) { // These variables will need to be defined $required = array ('month', 'day', 'year'); foreach ($required as $req) if (! isset ($data[$req])) $data[$req] = ''; // Sanity checks $name = ($name == false) ? 'yearmonthday' : $name; // Create a label if ($label !== false) $label = $this->label ($name, $label); // Set the basename of the input $bname = "{$name}[%s]"; extract ($data, EXTR_OVERWRITE); // Valid month if ($month !== '') { $month = (int) substr($month, 0, 2); $month = ($month > 12 || $month < 1) ? 1 : $month; } else $month = date('n'); // This month // Valid year if ($year !== '') { $year = (int) substr($year, 0, 4); // If the year is only two digits long, and greater than the current last two // digits of this year, we make the year 19XX, if not, 20XX $year = (strlen ($year) < 4) ? ((substr ($year, -2, 2) > date('y')) ? "19$year" : "20$year") : $year; } else $year = date('Y'); // This year // Valid day if ($day !== '') { $day = (int) substr($day, 0, 2); // If the day is greater than the possible number of days for $month, // we change the day to the maximum possible date for $month $max = date('t', mktime(1, 0, 0, $month, 1, $year)); $day = ($day > $max) ? $max : $day; } else $day = date('j'); // This day // Create dropdown options // Months for ($i=1;$i<13;$i++) $months[$i] = date('F', mktime(1, 0, 0, $i, 1, $year)); // Years for ($i=date('Y');$i>1900;$i--) $years[$i] = $i; // Days for ($i=1;$i<32;$i++) $days[$i] = $i; // Create month dropdown $input['options'] = $months; $input['selected'] = $month; $input['label'] = ($label == false) ? 'Month/Day/Year' : $label; $month = $this->input ('dropdown', sprintf($bname, 'month'), $input); $input = array(); // Create day dropdown $input['options'] = $days; $input['selected'] = $day; $day = $this->input ('dropdown', sprintf($bname, 'day'), $input); // Create year dropdown $input['options'] = $years; $input['selected'] = $year; $year = $this->input ('dropdown', sprintf($bname, 'year'), $input); // Compile our label and input $return['input'] = $month['input'].' '.$day['input'].' '.$year['input']; $return['label'] = $month['label']; // No label? Then just return the input if ($label == false) $return = $return['input']; return $return; } public function submit_cancel ($submit = false, $cancel = false) { $input = array(); $input['value'] = ($submit == false) ? 'Submit' : $submit; $name = url_title ($submit, 'underscore'); $submit = $this->input ('submit', $name, $input); $input = array(); $input['value'] = ($cancel == false) ? 'Cancel' : $cancel; $name = url_title ($submit, 'underscore'); $cancel = $this->input ('submit', $name, $input); return "$submit $cancel"; } } if (! function_exists ('array_remove')) { function array_remove ($key, &$array) { // @variable: string $key // @variable: array &$array // @return: value of $array[$key] if (! is_array ($array)) return false; if (! isset ($array[$key])) return false; $return = $array[$key]; unset ($array[$key]); return $return; } } if (! function_exists ('array_unshift_assoc')) { function array_unshift_assoc ($array, $key, $val = false) { $array = array_reverse ($array, true); $array[$key] = $val; $array = array_reverse ($array, true); // Return array return $array; } } if (! function_exists ('strtoarray')) { function strtoarray ($string) { $return = false; // Matches a string "like[this]" or "maybe[7,h,1,5]" if (preg_match ('@(\w+)\[([\w\d,]+)\]@', $string, $matches)) { $vars = explode (',', $matches[2]); // Compile array while ($var = array_shift ($vars)) $array[] = $var; // Valid return $return = $array; } return $return; } } ?>