73    $class = str_replace(
'\\', 
'/', str_replace(__NAMESPACE__ . 
'\\', 
'', $class));
 
   74    $file = __DIR__ . 
'/' .  $class . 
'.php';
 
   76    if (file_exists($file)) {
 
 
   81spl_autoload_register(__NAMESPACE__ . 
'\autoload');
 
  122        'en' => [
'us',
'gb',
'ie',
'au',
'nz'],
 
  123        'de' => [
'de',
'at',
'ch'],
 
  124        'fr' => [
'fr',
'ch',
'be',
'lu',
'ca'],
 
  200    private $currentStepId;
 
  205    private $steps = array();
 
  250        $this->isAutoSaveRequest = isset($_POST[
'formAutosave']) && $_POST[
'formAutosave'] === 
"true";
 
  252        $this->url = parse_url($_SERVER[
'REQUEST_URI']);
 
  254        parent::__construct(
$name, $parameters, $this);
 
  256        $this->url = parse_url($this->submitURL);
 
  257        if (empty($this->successURL)) {
 
  260        if (empty($this->cancelURL)) {
 
  264        $this->currentStepId = isset($_GET[
'step']) ? $_GET[
'step'] : 0;
 
  266        $this->startSession();
 
  268        $this->valid = (isset($this->sessionSlot[
'formIsValid'])) ? $this->sessionSlot[
'formIsValid'] : 
null;
 
  271        if (!isset($this->sessionSlot[
'formCsrfToken'])) {
 
  275        if (!isset($this->sessionSlot[
'formFinalPost'])) {
 
  276            $this->sessionSlot[
'formFinalPost'] = 
false;
 
  280        $this->addHidden(
'formName')->setValue($this->name);
 
  283        $this->addHidden(
'formStep')->setValue($this->currentStepId);
 
  286        $this->addHidden(
'formCsrfToken')->setValue($this->sessionSlot[
'formCsrfToken']);
 
 
  301        parent::setDefaults();
 
  303        $this->defaults[
'label']        = 
'submit';
 
  304        $this->defaults[
'cancelLabel']  = 
null;
 
  305        $this->defaults[
'backLabel']    = 
null;
 
  306        $this->defaults[
'class']        = 
'';
 
  307        $this->defaults[
'method']       = 
'post';
 
  309        $this->defaults[
'submitURL']    = $_SERVER[
'REQUEST_URI'];
 
  310        $this->defaults[
'successURL']   = 
null;
 
  311        $this->defaults[
'cancelURL']    = 
null;
 
  312        $this->defaults[
'validator']    = 
null;
 
  313        $this->defaults[
'ttl']          = 60 * 60; 
 
  314        $this->defaults[
'jsValidation'] = 
'blur';
 
  315        $this->defaults[
'jsAutosave']   = 
'false';
 
 
  326    private function startSession()
 
  330            $params = session_get_cookie_params();
 
  331            $sessionName = session_name();
 
  333            session_set_cookie_params(
 
  343            if (isset($_COOKIE[$sessionName])) {
 
  346                    $_COOKIE[$sessionName],
 
  355        $this->sessionSlotName  = 
'htmlform-' . $this->name . 
'-data';
 
  358        $this->sessionExpiry();
 
  368    private function sessionExpiry()
 
  370        if (isset($this->ttl) && is_numeric($this->ttl)) {
 
  374                isset($this->sessionSlot[
'formTimestamp'])
 
  375                && ($timestamp - $this->sessionSlot[
'formTimestamp'] > $this->ttl)
 
  381            $this->sessionSlot[
'formTimestamp'] = $timestamp;
 
  391        return !isset($this->sessionSlot[
'formName']);
 
 
  401        return base64_encode(openssl_random_pseudo_bytes(16));
 
 
  419        $newElement = parent::addElement($type, 
$name, $parameters);
 
  421        if ($newElement instanceof Elements\Step) { $this->steps[] = $newElement; }
 
 
  438            if ($element->getName() === 
$name) {
 
 
  448    private function getCurrentElements()
 
  450        $currentElements = array();
 
  452        foreach ($this->elements as $element) {
 
  453            if ($element instanceof Abstracts\Container) {
 
  455                    !($element instanceof Elements\Step)
 
  456                    || (isset($this->steps[$this->currentStepId]) && ($element == $this->steps[$this->currentStepId]))
 
  458                    $currentElements = array_merge($currentElements, $element->getElements());
 
  461                $currentElements[] = $element;
 
  465        return $currentElements;
 
  475        $this->namespaces[] = $namespace;
 
 
  493    private function inCurrentStep(
$name)
 
  495        return in_array($this->
getElement(
$name), $this->getCurrentElements());
 
  509        if (!is_null($step)) {
 
  510            $this->currentStepId = $step;
 
  512        if (!is_numeric($this->currentStepId)
 
  513            || ($this->currentStepId > count($this->steps) - 1)
 
  514            || ($this->currentStepId < 0)
 
 
  535        return $this->currentStepId;
 
 
  548        if (count($this->steps) > 0) {
 
  549            foreach ($this->steps as $stepNumber => $step) {
 
  550                if (!$step->validate()) {
 
  560            return count($this->steps) - 1;
 
 
  573        $queryParts = array();
 
  575        if (isset($this->url[
'query']) && $this->url[
'query'] != 
"") {
 
  577            $query = html_entity_decode($this->url[
'query']);
 
  580            parse_str($query, $queryParts);
 
  583        foreach ($args as 
$name => $value) {
 
  585                $queryParts[
$name] = $value;
 
  586            } elseif (isset($queryParts[
$name])) {
 
  587                unset($queryParts[
$name]);
 
  592        $query = http_build_query($queryParts);
 
  595            $query = 
"?" . $query;
 
 
  618            $element->setSessionSlot($this->sessionSlot);
 
  623            isset($_POST[
'formName']) && ($_POST[
'formName'] === $this->name)
 
  624            && $this->inCurrentStep(
$name)
 
  625            && isset($_POST[
'formCsrfToken']) && $_POST[
'formCsrfToken'] === $this->sessionSlot[
'formCsrfToken']
 
  629                $oldValue = isset($this->sessionSlot[
$name]) ? $this->sessionSlot[
$name] : 
null;
 
  630                $this->sessionSlot[
$name] = $element->handleUploadedFiles($oldValue);
 
  631            } 
else if (!$element->getDisabled()) {
 
  633                $value = isset($_POST[
$name]) ? $_POST[
$name] : 
null;
 
  634                $this->sessionSlot[
$name] = $element->setValue($value);
 
  635            } 
else if (!isset($this->sessionSlot[
$name])) {
 
  637                $this->sessionSlot[
$name] = $element->setValue($element->getDefaultValue());
 
  641        else if (isset($this->sessionSlot[
$name])) {
 
  642            $element->setValue($this->sessionSlot[
$name]);
 
 
  655        $this->sessionSlot[
$name] = $element->clearValue();
 
 
  670            $name = $element->name;
 
  671            if (!in_array(
$name, $this->internalFields)) {
 
  672                if (is_array($data) && isset($data[
$name])) {
 
  673                    $value = $data[
$name];
 
  674                } 
else if (is_object($data) && isset($data->$name)) {
 
  675                    $value = $data->$name;
 
  679                    $element->setDefaultValue($value);
 
  680                    if ($element->getDisabled() && !isset($this->sessionSlot[
$name])) {
 
  681                        $this->sessionSlot[
$name] = $value;
 
 
  704        if (isset($_POST[
'formName']) && ($_POST[
'formName'] === $this->name)) {
 
  706            $this->sessionSlot[
'formFinalPost'] = count($this->steps) == 0 || $_POST[
'formStep'] + 1 == count($this->steps)
 
  709            if (!empty($this->cancelLabel) && isset($_POST[
'formSubmit']) && $_POST[
'formSubmit'] === $this->cancelLabel) {
 
  713            } elseif ($this->isAutoSaveRequest) {
 
  716            } elseif (!empty($this->backLabel) && isset($_POST[
'formSubmit']) && $_POST[
'formSubmit'] === $this->backLabel) {
 
  720                $this->sessionSlot[
'formFinalPost'] = 
false;
 
  721                $prevStep = $this->currentStepId - 1;
 
  725                $urlStepParameter = ($prevStep <= 0) ? $this->
buildUrlQuery(array(
'step' => 
'')) : $this->
buildUrlQuery(array(
'step' => $prevStep));
 
  726                $this->
redirect($this->url[
'path'] . $urlStepParameter);
 
  736                $nextStep = $this->currentStepId + 1;
 
  738                if ($nextStep > $firstInvalidStep) {
 
  739                    $nextStep = $firstInvalidStep;
 
  741                if ($nextStep > count($this->steps)) {
 
  742                    $nextStep = count($this->steps) - 1;
 
  744                $urlStepParameter = ($nextStep == 0) ? $this->
buildUrlQuery(array(
'step' => 
'')) : $this->
buildUrlQuery(array(
'step' => $nextStep));
 
  745                $this->
redirect($this->url[
'path'] . $urlStepParameter);
 
 
  766        if ($this->valid && !is_null($this->validator)) {
 
  767            if (is_callable($this->validator)) {
 
  768                $this->valid = call_user_func($this->validator, $this, $this->
getValues());
 
  770                throw new exceptions\validatorNotCallable(
"The validator paramater must be callable");
 
  773        $this->valid = $this->valid && $this->sessionSlot[
'formFinalPost'];
 
 
  819        if (isset($_POST[
'formCsrfToken'])) {
 
  820            $hasCorrectToken = $_POST[
'formCsrfToken'] === $this->sessionSlot[
'formCsrfToken'];
 
  821            $this->valid = $this->valid && $hasCorrectToken;
 
  823            if (!$hasCorrectToken) {
 
  824                http_response_code(400);
 
  825                $this->
log(
"HtmlForm: Requst invalid because of incorrect CsrfToken");
 
  832        if ($this->isAutoSaveRequest
 
  833            || (isset($this->sessionSlot[
'formIsAutosaved'])
 
  834            && $this->sessionSlot[
'formIsAutosaved'] === 
true)
 
  836            $this->valid = 
false;
 
 
  851        if (isset($this->sessionSlot)) {
 
  853            return array_diff_key($this->sessionSlot, array_fill_keys($this->internalFields, 
''));
 
 
  867        $valuesWithLabel = array();
 
  868        if (isset($values)) {
 
  869            foreach ($values as $element => $value) {
 
  872                if ($elem) $valuesWithLabel[$element] = array(
 
  874                    "label" => $elem->getLabel()
 
  878            return $valuesWithLabel;
 
 
  890        header(
'Location: ' . 
$url);
 
  891        die( 
"Tried to redirect you to <a href=\"$url\">$url</a>");
 
 
  902        if ($clearCsrfToken) {
 
  906            unset($_SESSION[$this->sessionSlotName]);
 
  907            unset($this->sessionSlot);
 
  911                if (!$element->getDisabled() && !in_array($element->name, $this->internalFields)) {
 
  912                    unset($this->sessionSlot[$element->name]);
 
 
  927        if (empty($_SESSION)) {
 
  930        foreach ($_SESSION as $key => &$val) {
 
  931            if (preg_match($pattern, $key)
 
  932                && isset($val[
'formTimestamp'])
 
  933                && ($timestamp - $val[
'formTimestamp'] > 
$ttl)
 
  935                unset($_SESSION[$key]);
 
 
  946        $this->dataAttr[
'jsautosave'] = $this->jsAutosave === 
true ? 
"true" : 
$this->jsAutosave;
 
  948        return parent::htmlDataAttributes();
 
 
  955        $scheme   = isset($this->form->url[
'scheme']) ? $this->form->url[
'scheme'] . 
'://' : 
'';
 
  956        $host     = isset($this->form->url[
'host']) ? $this->form->url[
'host'] : 
'';
 
  957        $port     = isset($this->form->url[
'port']) ? 
':' . $this->form->url[
'port'] : 
'';
 
  958        $path     = isset($this->form->url[
'path']) ? $this->form->url[
'path'] : 
'';
 
  959        $baseUrl  = 
"$scheme$host$port$path";
 
  960        $step     = $this->currentStepId != 0 ? $this->currentStepId : 
'';
 
  962        return $this->
htmlEscape($baseUrl . $this->form->buildUrlQuery([
'step' => $step]));
 
 
  974        $renderedElements = 
'';
 
  978        $label            = $this->htmlLabel();
 
  979        $cancellabel      = $this->htmlCancelLabel();
 
  980        $backlabel        = $this->htmlBackLabel();
 
  981        $class            = $this->htmlClass();
 
  985        $disabledAttr     = $this->disabled ? 
" disabled=\"disabled\"" : 
"";
 
  987        foreach ($this->elementsAndHtml as $element) {
 
  989            if (!($element instanceof elements\step)
 
  990                || (isset($this->steps[$this->currentStepId]) && $this->steps[$this->currentStepId] == $element)
 
  992                $renderedElements .= $element;
 
  996        if (!is_null($this->cancelLabel)) {
 
  997            $cancel = 
"<p id=\"{$this->name}-cancel\" class=\"cancel\"><input type=\"submit\" name=\"formSubmit\" value=\"{$cancellabel}\"$disabledAttr></p>\n";
 
  999        if (!is_null($this->backLabel) && $this->currentStepId > 0) {
 
 1000            $back = 
"<p id=\"{$this->name}-back\" class=\"back\"><input type=\"submit\" name=\"formSubmit\" value=\"{$backlabel}\"$disabledAttr></p>\n";
 
 1002        if (!empty($this->label)) {
 
 1003            $submit = 
"<p id=\"{$this->name}-submit\" class=\"submit\"><input type=\"submit\" name=\"formSubmit\" value=\"{$label}\"$disabledAttr></p>\n";
 
 1007        return "<form id=\"{$this->name}\" name=\"{$this->name}\" class=\"depage-form {$class}\" method=\"{$method}\" action=\"{$submitURL}\"{$dataAttr} enctype=\"multipart/form-data\">" . 
"\n" .
 
 
 
container element base class
 
getElements($includeFieldsets=false)
Returns containers subelements.
 
addChildElements()
Sub-element generator hook.
 
$form
Parent form object reference.
 
clearValue()
Deletes values of all child elements.
 
getElement($name, $includeFieldsets=false)
Gets subelement by name.
 
log($argument, $type=null)
error & warning logger
 
$dataAttr
Extra information about the data that is saved inside the element.
 
htmlEscape($options=array())
Escapes HTML in strings and arrays of strings.
 
thrown when there are duplicate element names
 
$valid
Form validation result/status.
 
$isAutoSaveRequest
true if form request is from autosave call
 
addElement($type, $name, $parameters)
Adds input or fieldset elements to htmlform.
 
$method
HTML form method attribute.
 
getCurrentStepId()
Returns the current step id.
 
$label
Contains the submit button label of the form.
 
validate()
Validates the forms subelements.
 
setCurrentStep($step=null)
Validates step number of GET request.
 
$jsAutosave
Contains the javascript autosave type of the form.
 
$class
Contains the additional class value of the form.
 
$cancelURL
Specifies where the user is redirected to, once the form-data is cancelled.
 
updateInputValue($name)
Updates the value of an associated input element.
 
__construct($name, $parameters=array(), $form=null)
HtmlForm class constructor.
 
getSteps()
Returns an array of steps.
 
$jsValidation
Contains the javascript validation type of the form.
 
getFirstInvalidStep()
Returns first step that didn't pass validation.
 
checkElementName($name)
Checks for duplicate subelement names.
 
htmlDataAttributes()
Returns dataAttr escaped as attribute string.
 
clearInputValue($name)
clearInputValue
 
$namespaces
Namespace strings for addible element classes.
 
onValidate()
Validation hook.
 
validateAutosave()
If the form is autosaving the validation property is defaulted to false.
 
$ttl
Time until session expiry (seconds)
 
getValues()
Gets form-data from current PHP session.
 
__toString()
Renders form to HTML.
 
populate($data=array())
Fills subelement values.
 
process()
Calls form validation and handles redirects.
 
$submitURL
HTML form action attribute.
 
$successURL
Specifies where the user is redirected to, once the form-data is valid.
 
$sessionSlot
PHP session handle.
 
$internalFields
List of internal fieldnames that are not part of the results.
 
$validator
Contains the validator function of the form.
 
registerNamespace($namespace)
Stores element namespaces for adding.
 
$cancelLabel
Contains the cancel button label of the form.
 
htmlSubmitURL()
Returns dataAttr escaped as attribute string.
 
getValuesWithLabel()
Gets form-data from current PHP session but also contain elemnt labels.
 
setDefaults()
Collects initial values across subclasses.
 
static clearOldSessions($ttl=3600, $pattern="/^htmlform-.*/")
clearOldSessions
 
$sessionSlotName
Contains the name of the array in the PHP session, holding the form-data.
 
redirect($url)
Redirects Browser to a different URL.
 
$url
url of the current page
 
buildUrlQuery($args=array())
Adding step parameter to already existing query.
 
$backLabel
Contains the back button label of the form.
 
getNamespaces()
Returns list of registered namespaces.
 
isEmpty()
Returns wether form has been submitted before or not.
 
getNewCsrfToken()
Returns new XSRF token.
 
clearSession($clearCsrfToken=true)
Deletes the current forms' PHP session data.
 
htmlform class and autoloader
 
autoload($class)
PHP autoloader.