rendered paste body<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Code Igniter
*
* An open source application development framework for PHP 4.3.2 or newer
*
* @package CodeIgniter
* @author Rick Ellis
* @copyright Copyright (c) 2006-2007, pMachine, Inc.
* @license http://www.codeignitor.com/user_guide/license.html
* @link http://www.codeigniter.com
* @since Version 1.0
* @filesource
*/
// ------------------------------------------------------------------------
/**
* Code Igniter FORm GEneration Class (Forge)
*
* @package CodeIgniter
* @subpackage Libraries
* @category Forms
* @author Woody Gilk
* @link http://wgilk.com/code_igniter/libraries/Forge.html
* @license http://creativecommons.org/licenses/by-sa/3.0/
*/
class Forge {
private $action;
private $form_name;
private $group_name;
private $last_group;
private $template;
private $rules;
private $table;
private $groups;
private $uploads;
private $errors;
private $elements;
private $attributes;
private $validated;
private $has_error;
private $has_upload;
public function __construct ($params = array()) {
// Load the necessary stuff
$this->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 <tt>\"$path\"</tt> 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('<p class="error">%s</p>%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' => '<table class="layout">'));
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 <em>*</em>" : $label;
$label = sprintf ('<label for="%s">%s</label>', $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 <tt>cols</tt> 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 <tt>\"$type\"</tt> 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 ('<p class="error">', '</p>');
$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 ('<p class="error">', '</p>');
$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 ("<h6>POST DATA (debug)</h6>\n<pre>\n%s</pre>\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<li>%s', repeater ("\t", $tabs++), "\n");
printf ('%s<fieldset class="%s"><legend>%s</legend>%s', repeater ("\t", $tabs++), $g, $groups[$g]['legend'], "\n");
if (isset($groups[$g]['text'])) printf ('%s<p>%s</p>%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<ol class="layout">%s', repeater ("\t", $tabs), "\n");
$tabs++; $this->build_fieldset ($e, $elements, $groups, $obj); $tabs--;
printf ('%s</ol>%s', repeater ("\t", $tabs), "\n");
} else {
$label = $elements[$e]['label'];
$input = $elements[$e]['input'];
if (strpos ($input, 'type="hidden"') === false)
printf ('%s<li class="row">%s %s</li>%s', repeater ("\t", $tabs), $label, $input, "\n");
else
printf ('%s%s%s', repeater ("\t", $tabs), $input, "\n");
}
}
if (is_array ($e)) {
$tabs--;
printf ('%s</fieldset>%s', repeater ("\t", $tabs), "\n");
if ($first == false) { $tabs--; printf ('%s</li>%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;
}
}
?>