Files
DomFramework/form.php
2014-05-20 17:03:44 +00:00

446 lines
17 KiB
PHP

<?php
/** DomFramework
@package domframework
@author Dominique Fournier <dominique@fournier38.fr> */
error_reporting (E_ALL);
/** This class permit to create easily some forms to HTML (or text mode in
future).
Each field can be checked in AJAX or HTML. */
class form
{
/** All the fields */
private $fields = NULL;
/** The name of the form */
private $formName;
/** Allow to debug the PHP */
public $debug=0;
/** Create a form
@param string|null $formName The form name
*/
public function __construct ($formName = "form")
{
$this->formName = $formName;
}
/** Save the fields into the structure.
Available :
- name : name of the field in the HTML page
- label : label written to the describe the field
- [titles] : text written in radio/checkboxes
- [defaults] : default values. Must be array for checkbox/select, and
string for others
- [type] : text, password, hidden, checkbox, select, radio, submit
text by default
- [multiple] : Multiple selection are possible (if the type supports it)
- [group] : define a fieldset and define the title with groupe name
Warning : all the elements of the same group must be
consecutive !
- [readonly] : put a read-only flag on the field (the user see it but
can't interract on it. The value will be sent to next
page
- [verify] : Tests to verify with error priority and associated
message (%s is replaced by field selected value). Order
test from main tests to minor tests.
\$tmpfield can be used as a copy of the current field,
to check the defaults per example
- [error] : array containing (error|warning) => message
@param array $fields The fields to be displayed
*/
public function fields ($fields)
{
$this->fields = $fields;
}
/** Return TRUE if the value associated to a field is correct. Return an
array with a severity and a message to explain why a field is not
correct.
Fields can be an array with just one element, then only this element is
checked
@param array $fieldsVerify The fields to verify
@param array|null $valuesVerify The values of the fields to verify
*/
public function verify (&$fieldsVerify, $valuesVerify = NULL)
{
$ret = array ();
if ($this->debug)
echo "<pre>";
foreach ($fieldsVerify as $field)
{
if (!isset ($field->verify))
continue;
if (!isset ($valuesVerify[$field->name]))
throw new Exception ("No value provided for $field->name", 500);
foreach ($field->verify as $test => $message)
{
$func = sprintf ($test, addslashes ($valuesVerify[$field->name]));
if ($this->debug)
echo "VERIFY: \"$func\" => ";
$tmpfield = $field;
$res = addslashes (serialize ($tmpfield));
// TODO : http://fr2.php.net/manual/en/reflectionfunction.invokeargs.php
// to remove eval ?
$rc = eval ("\$tmpfield=unserialize(stripslashes('$res'));".
"return $func;");
if ($this->debug)
var_dump ($rc);
if ($rc !== FALSE)
{
$ret[$field->name] = $message;
$field->error = $message;
break;
}
}
}
if ($this->debug)
{
echo "RESULT: ";
var_dump ($ret);
echo "</pre>";
}
return $ret;
}
/** Return the fields in HTML code. If $values is provided, use it in place
of default values. In case of select boxes, $values are the selected
elements
$method is the method written in method field of <form>
@param string|null $method The method to use to transmit the form (POST,
GET)
@param array|null $values The default values of the fields */
public function printHTML ($method = 'post', $values = NULL,
$errors = array())
{
// TODO : textarea, file
$res = "";
$res = "<form action='#' method='$method'";
if ($this->formName != "")
$res .= " id='$this->formName'";
$res .= " class='form-horizontal'>\n";
$group = "";
foreach ($this->fields as $field)
{
if (isset ($field->group) && $field->group !== $group)
{
$res .= "<fieldset>\n";
$res .= " <legend>$field->group</legend>\n";
$group = $field->group;
}
$res .=" ";
switch ($field->type)
{
case "checkbox":
// No $field->multiple
// values !
$res .= "<div class='form-group";
if (isset ($errors[$field->name]))
$res .= " has-".$errors[$field->name][0];
$res .= "'>\n";
$res .= " <label class='col-sm-2 control-label' for='".
$this->formName."_".
htmlspecialchars ($field->name, ENT_QUOTES)."_0'>";
$res .= htmlspecialchars ($field->label)."</label>\n";
$res .= " <div class='col-sm-10'>\n";
if (is_string ($field->defaults))
$field->defaults = array ($field->defaults);
foreach ($field->titles as $key=>$val)
{
$res .= " <input type='hidden'";
$res .= " name='$this->formName"."[".
htmlspecialchars ($field->name, ENT_QUOTES)."][$key]'";
$res .= " value='unset'";
$res .= "/>";
$res .= "<input type='checkbox'";
$res .= " name='$this->formName"."[".
htmlspecialchars ($field->name, ENT_QUOTES)."][$key]'";
$res .= " id='$this->formName"."_".
htmlspecialchars ($field->name, ENT_QUOTES)."_$key'";
if (isset ($field->readonly) && $field->readonly !== FALSE)
$res .= " disabled='disabled'";
if (isset ($values[$field->name][$key]) &&
$values[$field->name][$key] !== "unset")
$res .= " checked='checked'";
elseif (isset ($field->defaults[$key]) &&
$field->defaults[$key] !== "")
$res .= " checked='checked'";
$res .= " class='form-control'";
$res .= "/>";
$res .= "$val\n";
}
if (isset ($errors[$field->name]))
$res .= " <span class='help-block'>".$errors[$field->name][1].
"</span>\n";
$res .= " </div>\n"; // End controls
$res .= " </div>\n"; // End form-group
break;
case "hidden":
// No $field->label, $field->multiple, $field->readonly
$res .= "<input type='hidden'";
$res .= " name='$this->formName"."[".
htmlspecialchars ($field->name, ENT_QUOTES)."]'";
$res .= " id='$this->formName"."_".
htmlspecialchars ($field->name, ENT_QUOTES)."'";
if (isset ($values[$field->name]))
$res .= " value='".htmlspecialchars ($values[$field->name])."'";
else
$res .= " value='".htmlspecialchars ($field->defaults)."'";
$res .= "/>\n";
break;
case "password":
// No $field->multiple
$res .= "<div class='form-group";
if (isset ($errors[$field->name]))
$res .= " has-".$errors[$field->name][0];
$res .= "'>\n";
$res .= " <label class='col-sm-2 control-label' for='".
$this->formName."_".
htmlspecialchars ($field->name, ENT_QUOTES)."'>";
$res .= htmlspecialchars ($field->label)."</label>\n";
$res .= " <div class='col-sm-10'>\n";
$res .= " <input type='password'";
$res .= " name='$this->formName"."[".
htmlspecialchars ($field->name, ENT_QUOTES)."]'";
$res .= " id='$this->formName"."_".
htmlspecialchars ($field->name, ENT_QUOTES)."'";
if (isset ($values[$field->name]))
$res .= " value='".htmlspecialchars ($values[$field->name],
ENT_QUOTES)."'";
else
$res .= " value='".htmlspecialchars ($field->defaults, ENT_QUOTES).
"'";
if (isset ($field->readonly) && $field->readonly !== FALSE)
$res .= " readonly='readonly'";
$res .= " class='form-control'";
$res .= "/>\n";
if (isset ($errors[$field->name]))
$res .= " <span class='help-block'>".$errors[$field->name][1].
"</span>\n";
$res .= " </div>\n"; // End controls
$res .= " </div>\n"; // End form-group
break;
case "radio":
// No $field->multiple
$res .= "<div class='form-group";
if (isset ($errors[$field->name]))
$res .= " has-".$errors[$field->name][0];
$res .= "'>\n";
$res .= " <label class='col-sm-2 control-label' for='".
$this->formName."_".
htmlspecialchars ($field->name, ENT_QUOTES)."_0'>";
$res .= htmlspecialchars ($field->label)."</label>\n";
$res .= " <div class='col-sm-10'>\n";
if (is_string ($field->defaults))
$field->defaults = array ($field->defaults);
$res .= " <input type='hidden'";
$res .= " name='$this->formName"."[".
htmlspecialchars ($field->name, ENT_QUOTES)."]'";
$res .= " value='unset'";
$res .= "/>\n";
foreach ($field->titles as $key=>$val)
{
$res .= " <label class='radio'>";
$res .= "<input type='radio'";
$res .= " name='$this->formName"."[".
htmlspecialchars ($field->name, ENT_QUOTES)."]'";
$res .= " id='$this->formName"."_".
htmlspecialchars ($field->name, ENT_QUOTES)."_$key'";
$res .= " value='".htmlspecialchars ($val, ENT_QUOTES)."'";
if (isset ($field->readonly) && $field->readonly !== FALSE)
$res .= " readonly='readonly'";
if (isset ($values[$field->name]) &&
$values[$field->name] === $val)
$res .= " checked='checked'";
elseif (isset ($field->defaults[0]) &&
$field->defaults[0] === $val)
$res .= " checked='checked'";
$res .= " class='form-control'";
$res .= "/>";
$res .= "$val";
$res .= "</label>\n"; // End label radio
}
if (isset ($errors[$field->name]))
$res .= " <span class='help-block'>".$errors[$field->name][1].
"</span>\n";
$res .= " </div>\n"; // End controls
$res .= " </div>\n"; // End form-group
break;
case "select":
// $values->$field
$res .= "<div class='form-group";
if (isset ($errors[$field->name]))
$res .= " has-".$errors[$field->name][0];
$res .= "'>\n";
$res .= " <label class='col-sm-2 control-label' for='".
$this->formName."_".
htmlspecialchars ($field->name, ENT_QUOTES)."'>";
$res .= htmlspecialchars ($field->label)."</label>\n";
$res .= " <div class='col-sm-10'>\n";
if (isset ($field->defaults) && is_array ($field->defaults))
{
if (isset ($field->readonly) && $field->readonly !== FALSE)
{
foreach ($field->defaults as $key=>$val)
{
$res .= "<input type='hidden'";
$res .= " name='$this->formName"."[".
htmlspecialchars ($field->name, ENT_QUOTES)."][".
htmlspecialchars ($key, ENT_QUOTES)."]'";
$res .= " value='";
$res .= htmlspecialchars ($val, ENT_QUOTES)."'";
$res .= "/>";
}
}
$res .= " <select";
$res .= " name='$this->formName"."[".
htmlspecialchars ($field->name, ENT_QUOTES)."]";
if (isset ($field->multiple) && $field->multiple !== FALSE)
$res .= "[]";
$res .= "'";
$res .= " id='$this->formName"."_".
htmlspecialchars ($field->name, ENT_QUOTES)."'";
if (isset ($field->multiple) && $field->multiple !== FALSE)
$res .= " multiple='multiple'";
if (isset ($field->readonly) && $field->readonly !== FALSE)
$res .= " disabled='disabled'";
$res .= " class='form-control'";
$res .= ">\n";
foreach ($field->defaults as $key=>$val)
{
$res .= " <option value='";
$res .= htmlspecialchars ($key, ENT_QUOTES)."'";
if (isset ($values[$field->name]) &&
is_string ($values[$field->name]) &&
$values[$field->name] == $key)
$res .= " selected='selected'";
elseif (isset ($values[$field->name]) &&
is_array ($values[$field->name]) &&
in_array ($key, $values[$field->name]))
$res .= " selected='selected'";
$res .= ">";
$res .= htmlspecialchars ($val);
$res .= "</option>\n";
}
$res .= " </select>\n";
if (isset ($errors[$field->name]))
$res .= " <span class='help-block'>".$errors[$field->name][1].
"</span>\n";
}
else
{
$res .= _("No value provided");
}
$res .= " </div>\n"; // End controls
$res .= " </div>\n"; // End form-group
break;
case "submit":
// No $field->label, $field->multiple, $field->error
$res .= "<input type='submit'";
$res .= " name='$this->formName"."[".
htmlspecialchars ($field->name, ENT_QUOTES)."]'";
$res .= " id='$this->formName"."_".
htmlspecialchars ($field->name, ENT_QUOTES)."'";
if (isset ($field->readonly) && $field->readonly !== FALSE)
$res .= " disabled='disabled'";
if (isset ($field->defaults))
$res .= " value='".htmlspecialchars ($field->defaults, ENT_QUOTES).
"'";
$res .= " class='form-control btn-primary'";
$res .= "/>\n";
break;
default:
// No $field->multiple, $field->titles
$res .= "<div class='form-group";
if (isset ($errors[$field->name]))
$res .= " has-".$errors[$field->name][0];
$res .= "'>\n";
$res .= " <label class='col-sm-2 control-label' for='".
$this->formName."_".
htmlspecialchars ($field->name, ENT_QUOTES)."'>";
$res .= htmlspecialchars ($field->label)."</label>\n";
$res .= " <div class='col-sm-10'>\n";
$res .= " <input type='text'";
$res .= " name='$this->formName"."[".
htmlspecialchars ($field->name, ENT_QUOTES)."]'";
$res .= " id='$this->formName"."_".
htmlspecialchars ($field->name, ENT_QUOTES)."'";
if (isset ($values[$field->name]))
$res .= " value='".htmlspecialchars ($values[$field->name],
ENT_QUOTES)."'";
else
$res .= " value='".htmlspecialchars ($field->defaults, ENT_QUOTES).
"'";
if (isset ($field->readonly) && $field->readonly !== FALSE)
$res .= " readonly='readonly'";
$res .= " class='form-control'";
$res .= "/>\n";
if (isset ($errors[$field->name]))
$res .= " <span class='help-block'>".$errors[$field->name][1].
"</span>\n";
$res .= " </div>\n"; // End controls
$res .= " </div>\n"; // End form-group
break;
}
if (isset ($field->group) && $field->group !== $group ||
!isset ($field->group) && $group !== "")
{
$res .="</fieldset>\n";
$group = "";
}
}
$res .= "</form>\n";
return $res;
}
}
/** the definition of a formfield */
class formfield
{
/** The name of the field */
public $name;
/** The label of the field */
public $label;
/** The titles of the field */
public $titles;
/** The defaults values of the field */
public $defaults;
/** The type of the field (text, password, checkbox, select)*/
public $type;
/** The multiplicity of selection of the field (available in select only)*/
public $multiple;
/** The name of group for the fields */
public $group;
/** The read-only feature of the field */
public $readonly;
/** The fonction used to verify the field by AJAX before submitting and
by PHP after submission*/
public $verify;
/** The statut of error of the field */
public $error;
/** When adding a field, the name and the label are the minimum mandatory
@param string $name Name of the field
@param string $label Label of the field */
function __construct ($name, $label)
{
$this->name = $name;
$this->label = $label;
}
}