depage-forms v1.4.1
html forms made easy
Loading...
Searching...
No Matches
HtmlForm.php
Go to the documentation of this file.
1<?php
2
14
64
65namespace Depage\HtmlForm;
66
67
73function autoload($class)
74{
75 $class = str_replace('\\', '/', str_replace(__NAMESPACE__ . '\\', '', $class));
76 $filePath = __DIR__ . '/' . $class . '.php';
77 $filePath = str_replace('..', '', $filePath);
78
79 $resolved = realpath($filePath);
80 if ($resolved !== false && file_exists($resolved)) {
81 require_once($resolved);
82 }
83}
84
85spl_autoload_register(__NAMESPACE__ . '\autoload');
86
126{
127 public const priorityCountries = [
128 'en' => ['us','gb','ie','au','nz'],
129 'de' => ['de','at','ch'],
130 'fr' => ['fr','ch','be','lu','ca'],
131 'it' => ['it','ch'],
132 ];
136 protected $method;
137
141 protected $url;
142
146 protected $submitURL;
147
151 protected $successURL;
152
156 protected $cancelURL;
157
161 protected $label;
162
166 protected $backLabel;
167
171 protected $cancelLabel;
172
176 protected $class;
177
181 protected $validator;
182
186 protected $jsValidation;
187
191 protected $jsAutosave;
192
197
201 protected $sessionSlot;
202
206 private $currentStepId;
207
211 private $steps = [];
212
216 protected $ttl;
217
221 public $valid;
222
226 public $isAutoSaveRequest = false;
227
231 protected $internalFields = [
232 'formIsValid',
233 'formIsAutosaved',
234 'formName',
235 'formTimestamp',
236 'formStep',
237 'formFinalPost',
238 'formCsrfToken',
239 'formCaptcha',
240 ];
241
245 protected $namespaces = ['\\Depage\\HtmlForm\\Elements'];
254 public function __construct(string $name, array $parameters = [], HtmlForm|null $form = null)
255 {
256 $this->isAutoSaveRequest = isset($_POST['formAutosave']) && $_POST['formAutosave'] === "true";
257
258 parent::__construct($name, $parameters, $this);
259
260 $this->url = parse_url($this->submitURL);
261 if (!empty($this->successURL)) {
262 $this->validateRedirectUrl($this->successURL, true);
263 }
264 if (!empty($this->cancelURL)) {
265 $this->validateRedirectUrl($this->cancelURL, true);
266 }
267 if (empty($this->successURL)) {
268 $this->successURL = $this->submitURL;
269 }
270 if (empty($this->cancelURL)) {
271 $this->cancelURL = $this->submitURL;
272 }
273
274 $this->currentStepId = isset($_GET['step']) ? $_GET['step'] : 0;
275
276 $this->startSession();
277
278 $this->valid = (isset($this->sessionSlot['formIsValid'])) ? $this->sessionSlot['formIsValid'] : null;
279
280 // set CSRF Token
281 if (!isset($this->sessionSlot['formCsrfToken'])) {
282 $this->sessionSlot['formCsrfToken'] = $this->getNewCsrfToken();
283 }
284
285 if (!isset($this->sessionSlot['formFinalPost'])) {
286 $this->sessionSlot['formFinalPost'] = false;
287 }
288
289 // create a hidden input to tell forms apart
290 $this->addHidden('formName')->setValue($this->name);
291
292 // create hidden input for submitted step
293 $this->addHidden('formStep')->setValue($this->currentStepId);
294
295 // create hidden input for CSRF token
296 $this->addHidden('formCsrfToken')->setValue($this->sessionSlot['formCsrfToken']);
297
298 $this->addChildElements();
299 }
300
309 protected function setDefaults(): void
310 {
311 parent::setDefaults();
312
313 $this->defaults['label'] = 'submit';
314 $this->defaults['cancelLabel'] = '';
315 $this->defaults['backLabel'] = '';
316 $this->defaults['class'] = '';
317 $this->defaults['method'] = 'post';
318 // @todo adjust submit url for steps when used
319 $this->defaults['submitURL'] = $_SERVER['REQUEST_URI'];
320 $this->defaults['successURL'] = null;
321 $this->defaults['cancelURL'] = null;
322 $this->defaults['validator'] = null;
323 $this->defaults['ttl'] = 60 * 60; // 60 minutes
324 $this->defaults['jsValidation'] = 'blur';
325 $this->defaults['jsAutosave'] = 'false';
326 }
327
336 private function startSession(): void
337 {
338 // check if there's an open session
339 if (!session_id()) {
340 $params = session_get_cookie_params();
341 $sessionName = session_name();
342
343 session_set_cookie_params(
344 $this->ttl,
345 $params['path'],
346 $params['domain'],
347 $params['secure'],
348 $params['httponly'],
349 null,
350 ['SameSite' => 'Lax'],
351 );
352 session_start();
353
354 // Extend the expiration time upon page load
355 if (isset($_COOKIE[$sessionName])) {
356 setcookie(
357 $sessionName,
358 $_COOKIE[$sessionName],
359 time() + $this->ttl,
360 $params['path'],
361 $params['domain'],
362 $params['secure'],
363 $params['httponly'],
364 );
365 }
366 }
367 $this->sessionSlotName = 'htmlform-' . $this->name . '-data';
368 $this->sessionSlot = & $_SESSION[$this->sessionSlotName];
369
370 $this->sessionExpiry();
371 }
380 private function sessionExpiry(): void
381 {
382 if (isset($this->ttl) && is_numeric($this->ttl)) {
383 $timestamp = time();
384
385 if (
386 isset($this->sessionSlot['formTimestamp'])
387 && ($timestamp - $this->sessionSlot['formTimestamp'] > $this->ttl)
388 ) {
389 $this->clearSession();
390 $this->sessionSlot = & $_SESSION[$this->sessionSlotName];
391 }
392
393 $this->sessionSlot['formTimestamp'] = $timestamp;
394 }
395 }
401 public function isEmpty()
402 {
403 return !isset($this->sessionSlot['formName']);
404 }
405
411 protected function getNewCsrfToken(): string
412 {
413 return base64_encode(openssl_random_pseudo_bytes(16));
414 }
415
427 protected function addElement(string $type, string $name, array $parameters): Abstracts\Element
428 {
429 $this->checkElementName($name);
430
431 $newElement = parent::addElement($type, $name, $parameters);
432
433 if ($newElement instanceof Elements\Step) {
434 $this->steps[] = $newElement;
435 }
436 if ($newElement instanceof Abstracts\Input) {
437 $this->updateInputValue($name);
438 }
439
440 return $newElement;
441 }
442
451 public function checkElementName(string $name): void
452 {
453 foreach ($this->getElements(true) as $element) {
454 if ($element->getName() === $name) {
455 throw new Exceptions\DuplicateElementNameException("Element name \"{$name}\" already in use.");
456 }
457 }
458 }
459
464 private function getCurrentElements(): array
465 {
466 $currentElements = [];
467
468 foreach ($this->elements as $element) {
469 if ($element instanceof Abstracts\Container) {
470 if (
471 !($element instanceof Elements\Step)
472 || (isset($this->steps[$this->currentStepId]) && ($element == $this->steps[$this->currentStepId]))
473 ) {
474 $currentElements = array_merge($currentElements, $element->getElements());
475 }
476 } else {
477 $currentElements[] = $element;
478 }
479 }
480
481 return $currentElements;
482 }
489 public function registerNamespace(string $namespace): void
490 {
491 $this->namespaces[] = $namespace;
492 }
493
498 public function getNamespaces(): array
499 {
500 return $this->namespaces;
501 }
502
509 private function inCurrentStep(string $name): bool
510 {
511 return in_array($this->getElement($name), $this->getCurrentElements());
512 }
523 public function setCurrentStep(int|null $step = null): void
524 {
525 if (!is_null($step)) {
526 $this->currentStepId = $step;
527 }
528 if (!is_numeric($this->currentStepId)
529 || ($this->currentStepId > count($this->steps) - 1)
530 || ($this->currentStepId < 0)
531 ) {
532 $this->currentStepId = $this->getFirstInvalidStep();
533 }
534 }
535 public function getUrl(): array
536 {
537 return $this->url;
538 }
539
544 public function getSteps(): array
545 {
546 return $this->steps;
547 }
548
553 public function getCurrentStepId(): int
554 {
555 return $this->currentStepId;
556 }
557
566 public function getFirstInvalidStep(): int
567 {
568 if (count($this->steps) > 0) {
569 foreach ($this->steps as $stepNumber => $step) {
570 if (!$step->validate()) {
571 return $stepNumber;
572 }
573 }
580 return count($this->steps) - 1;
581 } else {
582 return 0;
583 }
584 }
585
592 public function buildUrl(array $args = []): string
593 {
594 $url = isset($this->url['scheme']) ? $this->url['scheme'] . '://' : '';
595 $url .= $this->url['host'] ?? '';
596 $url .= isset($this->url['port']) ? ':' . $this->url['port'] : '';
597 $url .= $this->url['path'] ?? '';
598 $url .= $this->buildUrlQuery($args);
599
600 return $url;
601 }
602
608 public function buildUrlQuery(array $args = []): string
609 {
610 $query = '';
611 $queryParts = [];
612
613 if (isset($this->url['query']) && $this->url['query'] != "") {
614 //decoding query string
615 $query = html_entity_decode($this->url['query']);
616
617 //parsing the query into an array
618 parse_str($query, $queryParts);
619 }
620
621 foreach ($args as $name => $value) {
622 if ($value != "") {
623 $queryParts[$name] = $value;
624 } elseif (isset($queryParts[$name])) {
625 unset($queryParts[$name]);
626 }
627 }
628
629 // build the query again
630 $query = http_build_query($queryParts);
631
632 if ($query == "") {
633 return "";
634 }
635
636 return "?" . $query;
637 }
638
650 public function updateInputValue(string $name): void
651 {
652 $element = $this->getElement($name);
653
654 // handle captcha phrase
655 if ($this->getElement($name) instanceof Elements\Captcha) {
656 $element->setSessionSlot($this->sessionSlot);
657 }
658
659 // if it's a post, take the value from there and save it to the session
660 if (
661 isset($_POST['formName']) && ($_POST['formName'] === $this->name)
662 && $this->inCurrentStep($name)
663 && isset($_POST['formCsrfToken']) && $_POST['formCsrfToken'] === $this->sessionSlot['formCsrfToken']
664 ) {
665 if ($this->getElement($name) instanceof Elements\File) {
666 // handle uploaded file
667 $oldValue = isset($this->sessionSlot[$name]) ? $this->sessionSlot[$name] : null;
668 $this->sessionSlot[$name] = $element->handleUploadedFiles($oldValue);
669 } elseif (!$element->getDisabled()) {
670 // save value
671 $value = isset($_POST[$name]) ? $_POST[$name] : null;
672 $this->sessionSlot[$name] = $element->setValue($value);
673 } elseif (!isset($this->sessionSlot[$name])) {
674 // set default value for disabled elements
675 $this->sessionSlot[$name] = $element->setValue($element->getDefaultValue());
676 }
677 }
678 // if it's not a post, try to get the value from the session
679 elseif (isset($this->sessionSlot[$name])) {
680 $element->setValue($this->sessionSlot[$name]);
681 }
682 }
683
689 public function clearInputValue(string $name): void
690 {
691 $element = $this->getElement($name);
692
693 $this->sessionSlot[$name] = $element->clearValue();
694 }
695
705 public function populate(array|object $data = []): void
706 {
707 foreach ($this->getElements() as $element) {
708 $name = $element->name;
709 if (!in_array($name, $this->internalFields)) {
710 if (is_array($data) && isset($data[$name])) {
711 $value = $data[$name];
712 } elseif (is_object($data) && isset($data->$name)) {
713 $value = $data->$name;
714 }
715
716 if (isset($value)) {
717 $element->setDefaultValue($value);
718 if ($element->getDisabled() && !isset($this->sessionSlot[$name])) {
719 $this->sessionSlot[$name] = $value;
720 }
721 }
722
723 unset($value);
724 }
725 }
726 }
727
738 public function process(): void
739 {
740 $this->setCurrentStep();
741 // if there's post-data from this form
742 if (isset($_POST['formName']) && ($_POST['formName'] === $this->name)) {
743 // save in session if submission was from last step
744 $this->sessionSlot['formFinalPost'] = count($this->steps) == 0 || $_POST['formStep'] + 1 == count($this->steps)
746
747 if (!empty($this->cancelLabel) && isset($_POST['formSubmit']) && $_POST['formSubmit'] === $this->cancelLabel) {
748 // cancel button was pressed
749 $this->clearSession();
750 $this->redirect($this->cancelURL);
751 } elseif ($this->isAutoSaveRequest) {
752 // do not redirect -> is autosave
753 $this->onPost();
754 } elseif (!empty($this->backLabel) && isset($_POST['formSubmit']) && $_POST['formSubmit'] === $this->backLabel) {
755 // back button was pressed
756 $this->onPost();
757
758 $this->sessionSlot['formFinalPost'] = false;
759 $prevStep = $this->currentStepId - 1;
760 if ($prevStep < 0) {
761 $prevStep = 0;
762 }
763 $this->redirect($this->buildUrl(['step' => ($prevStep <= 0) ? '' : $prevStep]));
764 } elseif ($this->validate()) {
765 // form was successfully submitted
766 $this->onPost();
767
768 $this->redirect($this->successURL);
769 } else {
770 // goto to next step or display first invalid step
771 $this->onPost();
772
773 $nextStep = $this->currentStepId + 1;
774 $firstInvalidStep = $this->getFirstInvalidStep();
775 if ($nextStep > $firstInvalidStep) {
776 $nextStep = $firstInvalidStep;
777 }
778 if ($nextStep > count($this->steps)) {
779 $nextStep = count($this->steps) - 1;
780 }
781 $this->redirect($this->buildUrl(['step' => ($nextStep == 0) ? '' : $nextStep]));
782 }
783 }
784 }
785
795 public function validate(): bool
796 {
797 // onValidate hook for custom required/validation rules
798 $this->valid = $this->onValidate();
799
800 $this->valid = $this->valid && $this->validateAutosave();
801
802 if ($this->valid && !is_null($this->validator)) {
803 if (is_callable($this->validator)) {
804 $this->valid = call_user_func($this->validator, $this, $this->getValues());
805 } else {
806 throw new exceptions\validatorNotCallable("The validator paramater must be callable");
807 }
808 }
809 $this->valid = $this->valid && $this->sessionSlot['formFinalPost'];
810
811 // save validation-state in session
812 $this->sessionSlot['formIsValid'] = $this->valid;
813
814 return $this->valid;
815 }
816
825 protected function onPost(): bool
826 {
827 return true;
828 }
829
838 protected function onValidate(): bool
839 {
840 return true;
841 }
842
851 public function validateAutosave(): bool
852 {
853 parent::validate();
854
855 if (isset($_POST['formCsrfToken'])) {
856 $hasCorrectToken = $_POST['formCsrfToken'] === $this->sessionSlot['formCsrfToken'];
857 $this->valid = $this->valid && $hasCorrectToken;
858
859 if (!$hasCorrectToken) {
860 $this->httpResponseCode(400);
861 $this->log("HtmlForm: Requst invalid because of incorrect CsrfToken");
862 }
863 }
864
865 $partValid = $this->valid;
866
867 // save data in session when autosaving but don't validate successfully
868 if ($this->isAutoSaveRequest
869 || (isset($this->sessionSlot['formIsAutosaved'])
870 && $this->sessionSlot['formIsAutosaved'] === true)
871 ) {
872 $this->valid = false;
873 }
874
875 // save whether form was autosaved the last time
876 $this->sessionSlot['formIsAutosaved'] = $this->isAutoSaveRequest;
877
878 return $partValid;
879 }
880
885 public function getValues(): ?array
886 {
887 if (isset($this->sessionSlot)) {
888 // remove internal attributes from values
889 return array_diff_key($this->sessionSlot, array_fill_keys($this->internalFields, ''));
890 } else {
891 return null;
892 }
893 }
894
899 public function getValuesWithLabel(): ?array
900 {
901 //get values first
902 $values = $this->getValues();
903 $valuesWithLabel = [];
904 if (isset($values)) {
905 foreach ($values as $element => $value) {
906 $elem = $this->getElement($element);
907
908 if ($elem) {
909 $valuesWithLabel[$element] = [
910 "value" => $value,
911 "label" => $elem->getLabel(),
912 ];
913 }
914 }
915
916 return $valuesWithLabel;
917 } else {
918 return null;
919 }
920 }
921
929 private function validateRedirectUrl(string $url, $allowExternal = false): void
930 {
931 if (empty($url)) {
932 return;
933 }
934
935 $parsed = parse_url($url);
936
937 if ($parsed === false) {
938 throw new \InvalidArgumentException("Invalid redirect URL.");
939 }
940
941 if (isset($parsed['scheme']) && $parsed['scheme'] !== 'https') {
942 //throw new \InvalidArgumentException("Only HTTPS redirects are allowed.");
943 }
944
945 if (!isset($parsed['host'])) {
946 return;
947 }
948
949 if (!$allowExternal) {
950 $allowedHosts = $_SERVER['HTTP_HOST'] ?? '';
951 $allowedHosts = array_map('trim', explode(',', $allowedHosts));
952 if (!in_array($parsed['host'], $allowedHosts, true)) {
953 throw new \InvalidArgumentException("Redirect to external host not allowed.");
954 }
955 }
956 }
964 private function validateRedirect(string $url): void
965 {
966 if (empty($url)) {
967 throw new \InvalidArgumentException("Empty URL.");
968 }
969
970 if (preg_match('/[\r\n]/', $url)) {
971 throw new \InvalidArgumentException("Invalid URL: newline characters detected.");
972 }
973
974 $parsed = parse_url($url);
975 if ($parsed === false) {
976 throw new \InvalidArgumentException("Invalid URL format.");
977 }
978
979 if (isset($parsed['scheme'])) {
980 $allowedSchemes = ['http', 'https'];
981 if (!in_array(strtolower($parsed['scheme']), $allowedSchemes, true)) {
982 throw new \InvalidArgumentException("Invalid URL scheme.");
983 }
984 }
985 }
991 public function redirect(string $url): void
992 {
993 $this->validateRedirect($url);
994 $safeUrl = htmlspecialchars($url, ENT_QUOTES | FILTER_FLAG_NO_ENCODE_QUOTES, 'UTF-8');
995 header('Location: ' . $safeUrl);
996 exit;
997 }
998
1003 public function httpResponseCode(int $code): void
1004 {
1005 http_response_code($code);
1006 }
1007
1014 public function clearSession(bool $clearCsrfToken = true): void
1015 {
1016 if ($clearCsrfToken) {
1017 // clear everything
1018 $this->clearValue();
1019
1020 unset($_SESSION[$this->sessionSlotName]);
1021 unset($this->sessionSlot);
1022 } else {
1023 // clear everything except internal fields
1024 foreach ($this->getElements(false) as $element) {
1025 if (!$element->getDisabled() && !in_array($element->name, $this->internalFields)) {
1026 unset($this->sessionSlot[$element->name]);
1027 }
1028 }
1029 }
1030 }
1031
1037 public static function clearOldSessions(int $ttl = 3600, string $pattern = "/^htmlform-.*/"): void
1038 {
1039 $timestamp = time();
1040
1041 if (empty($_SESSION)) {
1042 return;
1043 }
1044 foreach ($_SESSION as $key => &$val) {
1045 if (preg_match($pattern, $key)
1046 && isset($val['formTimestamp'])
1047 && ($timestamp - $val['formTimestamp'] > $ttl)
1048 ) {
1049 unset($_SESSION[$key]);
1050 }
1051 }
1052 }
1053
1057 protected function htmlDataAttributes(): string
1058 {
1059 $this->dataAttr['jsvalidation'] = $this->jsValidation;
1060 $this->dataAttr['jsautosave'] = $this->jsAutosave === true ? "true" : $this->jsAutosave;
1061
1062 return parent::htmlDataAttributes();
1063 }
1064
1067 protected function htmlSubmitURL(): string
1068 {
1069 $step = $this->currentStepId != 0 ? $this->currentStepId : '';
1070
1071 return $this->htmlEscape($this->buildUrl(['step' => $step]));
1072 }
1073
1081 public function __toString(): string
1082 {
1083 $renderedElements = '';
1084 $submit = '';
1085 $cancel = '';
1086 $back = '';
1087 $label = $this->htmlLabel();
1088 $cancellabel = $this->htmlCancelLabel();
1089 $backlabel = $this->htmlBackLabel();
1090 $class = $this->htmlClass();
1091 $method = $this->htmlMethod();
1092 $submitURL = $this->htmlSubmitURL();
1093 $dataAttr = $this->htmlDataAttributes();
1094 $disabledAttr = $this->disabled ? " disabled=\"disabled\"" : "";
1095
1096 foreach ($this->elementsAndHtml as $element) {
1097 // leave out inactive step elements
1098 if (!($element instanceof elements\step)
1099 || (isset($this->steps[$this->currentStepId]) && $this->steps[$this->currentStepId] == $element)
1100 ) {
1101 $renderedElements .= $element;
1102 }
1103 }
1104
1105 if (!empty($this->cancelLabel)) {
1106 $cancel = "<p id=\"{$this->name}-cancel\" class=\"cancel\"><input type=\"submit\" name=\"formSubmit\" value=\"{$cancellabel}\"$disabledAttr></p>\n";
1107 }
1108 if (!empty($this->backLabel) && $this->currentStepId > 0) {
1109 $back = "<p id=\"{$this->name}-back\" class=\"back\"><input type=\"submit\" name=\"formSubmit\" value=\"{$backlabel}\"$disabledAttr></p>\n";
1110 }
1111 if (!empty($this->label)) {
1112 $submit = "<p id=\"{$this->name}-submit\" class=\"submit\"><input type=\"submit\" name=\"formSubmit\" value=\"{$label}\"$disabledAttr></p>\n";
1113 }
1114
1115
1116 return "<form id=\"{$this->name}\" name=\"{$this->name}\" class=\"depage-form {$class}\" method=\"{$method}\" action=\"{$submitURL}\"{$dataAttr} enctype=\"multipart/form-data\">" . "\n" .
1117 $renderedElements .
1118 $submit .
1119 $cancel .
1120 $back .
1121 "</form>";
1122 }
1123}
1124
1152
1162
1173
1183
1194
1204
1216
1227
1238
1251
1260
1271
1272/* vim:set ft=php sw=4 sts=4 fdm=marker et : */
container element base class
Definition Container.php:60
addChildElements()
Sub-element generator hook.
$form
Parent form object reference.
Definition Container.php:72
clearValue()
Deletes values of all child elements.
getElement(string $name, bool $includeFieldsets=false)
Gets subelement by name.
getElements(bool $includeFieldsets=false)
Returns containers subelements.
log(string $argument, ?string $type=null)
error & warning logger
Definition Element.php:236
$dataAttr
Extra information about the data that is saved inside the element.
Definition Element.php:77
htmlEscape(array|string $options=[])
Escapes HTML in strings and arrays of strings.
Definition Element.php:261
main interface to users
Definition HtmlForm.php:126
$valid
Form validation result/status.
Definition HtmlForm.php:221
$isAutoSaveRequest
true if form request is from autosave call
Definition HtmlForm.php:226
registerNamespace(string $namespace)
Stores element namespaces for adding.
Definition HtmlForm.php:489
clearInputValue(string $name)
clearInputValue
Definition HtmlForm.php:689
$method
HTML form method attribute.
Definition HtmlForm.php:136
getCurrentStepId()
Returns the current step id.
Definition HtmlForm.php:553
$label
Contains the submit button label of the form.
Definition HtmlForm.php:161
validate()
Validates the forms subelements.
Definition HtmlForm.php:795
httpResponseCode(int $code)
Sets the HTTP response code.
$jsAutosave
Contains the javascript autosave type of the form.
Definition HtmlForm.php:191
$class
Contains the additional class value of the form.
Definition HtmlForm.php:176
$cancelURL
Specifies where the user is redirected to, once the form-data is cancelled.
Definition HtmlForm.php:156
getSteps()
Returns an array of steps.
Definition HtmlForm.php:544
__construct(string $name, array $parameters=[], HtmlForm|null $form=null)
HtmlForm class constructor.
Definition HtmlForm.php:254
$jsValidation
Contains the javascript validation type of the form.
Definition HtmlForm.php:186
getFirstInvalidStep()
Returns first step that didn't pass validation.
Definition HtmlForm.php:566
htmlDataAttributes()
Returns dataAttr escaped as attribute string.
$namespaces
Namespace strings for addible element classes.
Definition HtmlForm.php:245
onValidate()
Validation hook.
Definition HtmlForm.php:838
validateAutosave()
If the form is autosaving the validation property is defaulted to false.
Definition HtmlForm.php:851
$ttl
Time until session expiry (seconds)
Definition HtmlForm.php:216
getValues()
Gets form-data from current PHP session.
Definition HtmlForm.php:885
static clearOldSessions(int $ttl=3600, string $pattern="/^htmlform-.*/")
clearOldSessions
__toString()
Renders form to HTML.
process()
Calls form validation and handles redirects.
Definition HtmlForm.php:738
$submitURL
HTML form action attribute.
Definition HtmlForm.php:146
redirect(string $url)
Redirects Browser to a different URL.
Definition HtmlForm.php:991
checkElementName(string $name)
Checks for duplicate subelement names.
Definition HtmlForm.php:451
buildUrlQuery(array $args=[])
Adding step parameter to already existing query.
Definition HtmlForm.php:608
$successURL
Specifies where the user is redirected to, once the form-data is valid.
Definition HtmlForm.php:151
updateInputValue(string $name)
Updates the value of an associated input element.
Definition HtmlForm.php:650
$sessionSlot
PHP session handle.
Definition HtmlForm.php:201
clearSession(bool $clearCsrfToken=true)
Deletes the current forms' PHP session data.
$internalFields
List of internal fieldnames that are not part of the results.
Definition HtmlForm.php:231
$validator
Contains the validator function of the form.
Definition HtmlForm.php:181
$cancelLabel
Contains the cancel button label of the form.
Definition HtmlForm.php:171
populate(array|object $data=[])
Fills subelement values.
Definition HtmlForm.php:705
setCurrentStep(int|null $step=null)
Validates step number of GET request.
Definition HtmlForm.php:523
htmlSubmitURL()
Returns form url escaped as attribute string.
getValuesWithLabel()
Gets form-data from current PHP session but also contain elemnt labels.
Definition HtmlForm.php:899
setDefaults()
Collects initial values across subclasses.
Definition HtmlForm.php:309
$sessionSlotName
Contains the name of the array in the PHP session, holding the form-data.
Definition HtmlForm.php:196
$url
url of the current page
Definition HtmlForm.php:141
$backLabel
Contains the back button label of the form.
Definition HtmlForm.php:166
getNamespaces()
Returns list of registered namespaces.
Definition HtmlForm.php:498
isEmpty()
Returns wether form has been submitted before or not.
Definition HtmlForm.php:401
buildUrl(array $args=[])
Builds URL from parts.
Definition HtmlForm.php:592
getNewCsrfToken()
Returns new XSRF token.
Definition HtmlForm.php:411
addElement(string $type, string $name, array $parameters)
Adds input or fieldset elements to htmlform.
Definition HtmlForm.php:427
Abstract element classes.
Definition Container.php:11
Classes for HTML input-elements.
Definition Address.php:10
htmlform class and autoloader
autoload($class)
PHP autoloader.
Definition HtmlForm.php:73