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 $file = __DIR__ . '/' . $class . '.php';
77
78 if (file_exists($file)) {
79 require_once($file);
80 }
81}
82
83spl_autoload_register(__NAMESPACE__ . '\autoload');
84
124{
125 public const priorityCountries = [
126 'en' => ['us','gb','ie','au','nz'],
127 'de' => ['de','at','ch'],
128 'fr' => ['fr','ch','be','lu','ca'],
129 'it' => ['it','ch'],
130 ];
134 protected $method;
135
139 protected $url;
140
144 protected $submitURL;
145
149 protected $successURL;
150
154 protected $cancelURL;
155
159 protected $label;
160
164 protected $backLabel;
165
169 protected $cancelLabel;
170
174 protected $class;
175
179 protected $validator;
180
184 protected $jsValidation;
185
189 protected $jsAutosave;
190
195
199 protected $sessionSlot;
200
204 private $currentStepId;
205
209 private $steps = [];
210
214 protected $ttl;
215
219 public $valid;
220
224 public $isAutoSaveRequest = false;
225
229 protected $internalFields = [
230 'formIsValid',
231 'formIsAutosaved',
232 'formName',
233 'formTimestamp',
234 'formStep',
235 'formFinalPost',
236 'formCsrfToken',
237 'formCaptcha',
238 ];
239
243 protected $namespaces = ['\\Depage\\HtmlForm\\Elements'];
252 public function __construct(string $name, array $parameters = [], HtmlForm|null $form = null)
253 {
254 $this->isAutoSaveRequest = isset($_POST['formAutosave']) && $_POST['formAutosave'] === "true";
255
256 $this->url = parse_url($_SERVER['REQUEST_URI']);
257
258 parent::__construct($name, $parameters, $this);
259
260 $this->url = parse_url($this->submitURL);
261 if (empty($this->successURL)) {
262 $this->successURL = $this->submitURL;
263 }
264 if (empty($this->cancelURL)) {
265 $this->cancelURL = $this->submitURL;
266 }
267
268 $this->currentStepId = isset($_GET['step']) ? $_GET['step'] : 0;
269
270 $this->startSession();
271
272 $this->valid = (isset($this->sessionSlot['formIsValid'])) ? $this->sessionSlot['formIsValid'] : null;
273
274 // set CSRF Token
275 if (!isset($this->sessionSlot['formCsrfToken'])) {
276 $this->sessionSlot['formCsrfToken'] = $this->getNewCsrfToken();
277 }
278
279 if (!isset($this->sessionSlot['formFinalPost'])) {
280 $this->sessionSlot['formFinalPost'] = false;
281 }
282
283 // create a hidden input to tell forms apart
284 $this->addHidden('formName')->setValue($this->name);
285
286 // create hidden input for submitted step
287 $this->addHidden('formStep')->setValue($this->currentStepId);
288
289 // create hidden input for CSRF token
290 $this->addHidden('formCsrfToken')->setValue($this->sessionSlot['formCsrfToken']);
291
292 $this->addChildElements();
293 }
294
303 protected function setDefaults(): void
304 {
305 parent::setDefaults();
306
307 $this->defaults['label'] = 'submit';
308 $this->defaults['cancelLabel'] = '';
309 $this->defaults['backLabel'] = '';
310 $this->defaults['class'] = '';
311 $this->defaults['method'] = 'post';
312 // @todo adjust submit url for steps when used
313 $this->defaults['submitURL'] = $_SERVER['REQUEST_URI'];
314 $this->defaults['successURL'] = null;
315 $this->defaults['cancelURL'] = null;
316 $this->defaults['validator'] = null;
317 $this->defaults['ttl'] = 60 * 60; // 60 minutes
318 $this->defaults['jsValidation'] = 'blur';
319 $this->defaults['jsAutosave'] = 'false';
320 }
321
330 private function startSession()
331 {
332 // check if there's an open session
333 if (!session_id()) {
334 $params = session_get_cookie_params();
335 $sessionName = session_name();
336
337 session_set_cookie_params(
338 $this->ttl,
339 $params['path'],
340 $params['domain'],
341 $params['secure'],
342 $params['httponly'],
343 );
344 session_start();
345
346 // Extend the expiration time upon page load
347 if (isset($_COOKIE[$sessionName])) {
348 setcookie(
349 $sessionName,
350 $_COOKIE[$sessionName],
351 time() + $this->ttl,
352 $params['path'],
353 $params['domain'],
354 $params['secure'],
355 $params['httponly'],
356 );
357 }
358 }
359 $this->sessionSlotName = 'htmlform-' . $this->name . '-data';
360 $this->sessionSlot = & $_SESSION[$this->sessionSlotName];
361
362 $this->sessionExpiry();
363 }
372 private function sessionExpiry()
373 {
374 if (isset($this->ttl) && is_numeric($this->ttl)) {
375 $timestamp = time();
376
377 if (
378 isset($this->sessionSlot['formTimestamp'])
379 && ($timestamp - $this->sessionSlot['formTimestamp'] > $this->ttl)
380 ) {
381 $this->clearSession();
382 $this->sessionSlot = & $_SESSION[$this->sessionSlotName];
383 }
384
385 $this->sessionSlot['formTimestamp'] = $timestamp;
386 }
387 }
393 public function isEmpty()
394 {
395 return !isset($this->sessionSlot['formName']);
396 }
397
403 protected function getNewCsrfToken()
404 {
405 return base64_encode(openssl_random_pseudo_bytes(16));
406 }
407
419 protected function addElement(string $type, string $name, array $parameters): Abstracts\Element
420 {
421 $this->checkElementName($name);
422
423 $newElement = parent::addElement($type, $name, $parameters);
424
425 if ($newElement instanceof Elements\Step) {
426 $this->steps[] = $newElement;
427 }
428 if ($newElement instanceof Abstracts\Input) {
429 $this->updateInputValue($name);
430 }
431
432 return $newElement;
433 }
434
443 public function checkElementName(string $name): void
444 {
445 foreach ($this->getElements(true) as $element) {
446 if ($element->getName() === $name) {
447 throw new Exceptions\DuplicateElementNameException("Element name \"{$name}\" already in use.");
448 }
449 }
450 }
451
456 private function getCurrentElements(): array
457 {
458 $currentElements = [];
459
460 foreach ($this->elements as $element) {
461 if ($element instanceof Abstracts\Container) {
462 if (
463 !($element instanceof Elements\Step)
464 || (isset($this->steps[$this->currentStepId]) && ($element == $this->steps[$this->currentStepId]))
465 ) {
466 $currentElements = array_merge($currentElements, $element->getElements());
467 }
468 } else {
469 $currentElements[] = $element;
470 }
471 }
472
473 return $currentElements;
474 }
481 public function registerNamespace(string $namespace): void
482 {
483 $this->namespaces[] = $namespace;
484 }
485
490 public function getNamespaces(): array
491 {
492 return $this->namespaces;
493 }
494
501 private function inCurrentStep(string $name): bool
502 {
503 return in_array($this->getElement($name), $this->getCurrentElements());
504 }
515 public function setCurrentStep(int|null $step = null): void
516 {
517 if (!is_null($step)) {
518 $this->currentStepId = $step;
519 }
520 if (!is_numeric($this->currentStepId)
521 || ($this->currentStepId > count($this->steps) - 1)
522 || ($this->currentStepId < 0)
523 ) {
524 $this->currentStepId = $this->getFirstInvalidStep();
525 }
526 }
527 public function getUrl(): array
528 {
529 return $this->url;
530 }
531
536 public function getSteps(): array
537 {
538 return $this->steps;
539 }
540
545 public function getCurrentStepId(): int
546 {
547 return $this->currentStepId;
548 }
549
558 public function getFirstInvalidStep(): int
559 {
560 if (count($this->steps) > 0) {
561 foreach ($this->steps as $stepNumber => $step) {
562 if (!$step->validate()) {
563 return $stepNumber;
564 }
565 }
572 return count($this->steps) - 1;
573 } else {
574 return 0;
575 }
576 }
577
583 public function buildUrl(array $args = []): string
584 {
585 $url = isset($this->url['scheme']) ? $this->url['scheme'] . '://' : '';
586 $url .= $this->url['host'] ?? '';
587 $url .= isset($this->url['port']) ? ':' . $this->url['port'] : '';
588 $url .= $this->url['path'] ?? '';
589 $url .= $this->buildUrlQuery($args);
590
591 return $url;
592 }
593
598 public function buildUrlQuery(array $args = []): string
599 {
600 $query = '';
601 $queryParts = [];
602
603 if (isset($this->url['query']) && $this->url['query'] != "") {
604 //decoding query string
605 $query = html_entity_decode($this->url['query']);
606
607 //parsing the query into an array
608 parse_str($query, $queryParts);
609 }
610
611 foreach ($args as $name => $value) {
612 if ($value != "") {
613 $queryParts[$name] = $value;
614 } elseif (isset($queryParts[$name])) {
615 unset($queryParts[$name]);
616 }
617 }
618
619 // build the query again
620 $query = http_build_query($queryParts);
621
622 if ($query == "") {
623 return "";
624 }
625
626 return "?" . $query;
627 }
628
640 public function updateInputValue(string $name): void
641 {
642 $element = $this->getElement($name);
643
644 // handle captcha phrase
645 if ($this->getElement($name) instanceof Elements\Captcha) {
646 $element->setSessionSlot($this->sessionSlot);
647 }
648
649 // if it's a post, take the value from there and save it to the session
650 if (
651 isset($_POST['formName']) && ($_POST['formName'] === $this->name)
652 && $this->inCurrentStep($name)
653 && isset($_POST['formCsrfToken']) && $_POST['formCsrfToken'] === $this->sessionSlot['formCsrfToken']
654 ) {
655 if ($this->getElement($name) instanceof Elements\File) {
656 // handle uploaded file
657 $oldValue = isset($this->sessionSlot[$name]) ? $this->sessionSlot[$name] : null;
658 $this->sessionSlot[$name] = $element->handleUploadedFiles($oldValue);
659 } elseif (!$element->getDisabled()) {
660 // save value
661 $value = isset($_POST[$name]) ? $_POST[$name] : null;
662 $this->sessionSlot[$name] = $element->setValue($value);
663 } elseif (!isset($this->sessionSlot[$name])) {
664 // set default value for disabled elements
665 $this->sessionSlot[$name] = $element->setValue($element->getDefaultValue());
666 }
667 }
668 // if it's not a post, try to get the value from the session
669 elseif (isset($this->sessionSlot[$name])) {
670 $element->setValue($this->sessionSlot[$name]);
671 }
672 }
673
679 public function clearInputValue(string $name): void
680 {
681 $element = $this->getElement($name);
682
683 $this->sessionSlot[$name] = $element->clearValue();
684 }
685
695 public function populate(array|object $data = []): void
696 {
697 foreach ($this->getElements() as $element) {
698 $name = $element->name;
699 if (!in_array($name, $this->internalFields)) {
700 if (is_array($data) && isset($data[$name])) {
701 $value = $data[$name];
702 } elseif (is_object($data) && isset($data->$name)) {
703 $value = $data->$name;
704 }
705
706 if (isset($value)) {
707 $element->setDefaultValue($value);
708 if ($element->getDisabled() && !isset($this->sessionSlot[$name])) {
709 $this->sessionSlot[$name] = $value;
710 }
711 }
712
713 unset($value);
714 }
715 }
716 }
717
728 public function process(): void
729 {
730 $this->setCurrentStep();
731 // if there's post-data from this form
732 if (isset($_POST['formName']) && ($_POST['formName'] === $this->name)) {
733 // save in session if submission was from last step
734 $this->sessionSlot['formFinalPost'] = count($this->steps) == 0 || $_POST['formStep'] + 1 == count($this->steps)
736
737 if (!empty($this->cancelLabel) && isset($_POST['formSubmit']) && $_POST['formSubmit'] === $this->cancelLabel) {
738 // cancel button was pressed
739 $this->clearSession();
740 $this->redirect($this->cancelURL);
741 } elseif ($this->isAutoSaveRequest) {
742 // do not redirect -> is autosave
743 $this->onPost();
744 } elseif (!empty($this->backLabel) && isset($_POST['formSubmit']) && $_POST['formSubmit'] === $this->backLabel) {
745 // back button was pressed
746 $this->onPost();
747
748 $this->sessionSlot['formFinalPost'] = false;
749 $prevStep = $this->currentStepId - 1;
750 if ($prevStep < 0) {
751 $prevStep = 0;
752 }
753 $this->redirect($this->buildUrl(['step' => ($prevStep <= 0) ? '' : $prevStep]));
754 } elseif ($this->validate()) {
755 // form was successfully submitted
756 $this->onPost();
757
758 $this->redirect($this->successURL);
759 } else {
760 // goto to next step or display first invalid step
761 $this->onPost();
762
763 $nextStep = $this->currentStepId + 1;
764 $firstInvalidStep = $this->getFirstInvalidStep();
765 if ($nextStep > $firstInvalidStep) {
766 $nextStep = $firstInvalidStep;
767 }
768 if ($nextStep > count($this->steps)) {
769 $nextStep = count($this->steps) - 1;
770 }
771 $this->redirect($this->buildUrl(['step' => ($nextStep == 0) ? '' : $nextStep]));
772 }
773 }
774 }
775
785 public function validate(): bool
786 {
787 // onValidate hook for custom required/validation rules
788 $this->valid = $this->onValidate();
789
790 $this->valid = $this->valid && $this->validateAutosave();
791
792 if ($this->valid && !is_null($this->validator)) {
793 if (is_callable($this->validator)) {
794 $this->valid = call_user_func($this->validator, $this, $this->getValues());
795 } else {
796 throw new exceptions\validatorNotCallable("The validator paramater must be callable");
797 }
798 }
799 $this->valid = $this->valid && $this->sessionSlot['formFinalPost'];
800
801 // save validation-state in session
802 $this->sessionSlot['formIsValid'] = $this->valid;
803
804 return $this->valid;
805 }
806
815 protected function onPost(): bool
816 {
817 return true;
818 }
819
828 protected function onValidate(): bool
829 {
830 return true;
831 }
832
841 public function validateAutosave(): bool
842 {
843 parent::validate();
844
845 if (isset($_POST['formCsrfToken'])) {
846 $hasCorrectToken = $_POST['formCsrfToken'] === $this->sessionSlot['formCsrfToken'];
847 $this->valid = $this->valid && $hasCorrectToken;
848
849 if (!$hasCorrectToken) {
850 $this->httpResponseCode(400);
851 $this->log("HtmlForm: Requst invalid because of incorrect CsrfToken");
852 }
853 }
854
855 $partValid = $this->valid;
856
857 // save data in session when autosaving but don't validate successfully
858 if ($this->isAutoSaveRequest
859 || (isset($this->sessionSlot['formIsAutosaved'])
860 && $this->sessionSlot['formIsAutosaved'] === true)
861 ) {
862 $this->valid = false;
863 }
864
865 // save whether form was autosaved the last time
866 $this->sessionSlot['formIsAutosaved'] = $this->isAutoSaveRequest;
867
868 return $partValid;
869 }
870
875 public function getValues(): ?array
876 {
877 if (isset($this->sessionSlot)) {
878 // remove internal attributes from values
879 return array_diff_key($this->sessionSlot, array_fill_keys($this->internalFields, ''));
880 } else {
881 return null;
882 }
883 }
884
889 public function getValuesWithLabel(): ?array
890 {
891 //get values first
892 $values = $this->getValues();
893 $valuesWithLabel = [];
894 if (isset($values)) {
895 foreach ($values as $element => $value) {
896 $elem = $this->getElement($element);
897
898 if ($elem) {
899 $valuesWithLabel[$element] = [
900 "value" => $value,
901 "label" => $elem->getLabel(),
902 ];
903 }
904 }
905
906 return $valuesWithLabel;
907 } else {
908 return null;
909 }
910 }
911
916 public function redirect(string $url): void
917 {
918 header('Location: ' . $url);
919 die("Tried to redirect you to <a href=\"$url\">$url</a>");
920 }
921
926 public function httpResponseCode(int $code): void
927 {
928 http_response_code($code);
929 }
930
937 public function clearSession(bool $clearCsrfToken = true): void
938 {
939 if ($clearCsrfToken) {
940 // clear everything
941 $this->clearValue();
942
943 unset($_SESSION[$this->sessionSlotName]);
944 unset($this->sessionSlot);
945 } else {
946 // clear everything except internal fields
947 foreach ($this->getElements(false) as $element) {
948 if (!$element->getDisabled() && !in_array($element->name, $this->internalFields)) {
949 unset($this->sessionSlot[$element->name]);
950 }
951 }
952 }
953 }
954
960 public static function clearOldSessions(int $ttl = 3600, string $pattern = "/^htmlform-.*/"): void
961 {
962 $timestamp = time();
963
964 if (empty($_SESSION)) {
965 return;
966 }
967 foreach ($_SESSION as $key => &$val) {
968 if (preg_match($pattern, $key)
969 && isset($val['formTimestamp'])
970 && ($timestamp - $val['formTimestamp'] > $ttl)
971 ) {
972 unset($_SESSION[$key]);
973 }
974 }
975 }
976
980 protected function htmlDataAttributes(): string
981 {
982 $this->dataAttr['jsvalidation'] = $this->jsValidation;
983 $this->dataAttr['jsautosave'] = $this->jsAutosave === true ? "true" : $this->jsAutosave;
984
985 return parent::htmlDataAttributes();
986 }
987
990 protected function htmlSubmitURL(): string
991 {
992 $step = $this->currentStepId != 0 ? $this->currentStepId : '';
993
994 return $this->htmlEscape($this->buildUrl(['step' => $step]));
995 }
996
1004 public function __toString(): string
1005 {
1006 $renderedElements = '';
1007 $submit = '';
1008 $cancel = '';
1009 $back = '';
1010 $label = $this->htmlLabel();
1011 $cancellabel = $this->htmlCancelLabel();
1012 $backlabel = $this->htmlBackLabel();
1013 $class = $this->htmlClass();
1014 $method = $this->htmlMethod();
1015 $submitURL = $this->htmlSubmitURL();
1016 $dataAttr = $this->htmlDataAttributes();
1017 $disabledAttr = $this->disabled ? " disabled=\"disabled\"" : "";
1018
1019 foreach ($this->elementsAndHtml as $element) {
1020 // leave out inactive step elements
1021 if (!($element instanceof elements\step)
1022 || (isset($this->steps[$this->currentStepId]) && $this->steps[$this->currentStepId] == $element)
1023 ) {
1024 $renderedElements .= $element;
1025 }
1026 }
1027
1028 if (!empty($this->cancelLabel)) {
1029 $cancel = "<p id=\"{$this->name}-cancel\" class=\"cancel\"><input type=\"submit\" name=\"formSubmit\" value=\"{$cancellabel}\"$disabledAttr></p>\n";
1030 }
1031 if (!empty($this->backLabel) && $this->currentStepId > 0) {
1032 $back = "<p id=\"{$this->name}-back\" class=\"back\"><input type=\"submit\" name=\"formSubmit\" value=\"{$backlabel}\"$disabledAttr></p>\n";
1033 }
1034 if (!empty($this->label)) {
1035 $submit = "<p id=\"{$this->name}-submit\" class=\"submit\"><input type=\"submit\" name=\"formSubmit\" value=\"{$label}\"$disabledAttr></p>\n";
1036 }
1037
1038
1039 return "<form id=\"{$this->name}\" name=\"{$this->name}\" class=\"depage-form {$class}\" method=\"{$method}\" action=\"{$submitURL}\"{$dataAttr} enctype=\"multipart/form-data\">" . "\n" .
1040 $renderedElements .
1041 $submit .
1042 $cancel .
1043 $back .
1044 "</form>";
1045 }
1046}
1047
1075
1085
1096
1106
1117
1127
1139
1150
1161
1174
1183
1194
1195/* 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:124
$valid
Form validation result/status.
Definition HtmlForm.php:219
$isAutoSaveRequest
true if form request is from autosave call
Definition HtmlForm.php:224
registerNamespace(string $namespace)
Stores element namespaces for adding.
Definition HtmlForm.php:481
clearInputValue(string $name)
clearInputValue
Definition HtmlForm.php:679
$method
HTML form method attribute.
Definition HtmlForm.php:134
getCurrentStepId()
Returns the current step id.
Definition HtmlForm.php:545
$label
Contains the submit button label of the form.
Definition HtmlForm.php:159
validate()
Validates the forms subelements.
Definition HtmlForm.php:785
httpResponseCode(int $code)
Sets the HTTP response code.
Definition HtmlForm.php:926
$jsAutosave
Contains the javascript autosave type of the form.
Definition HtmlForm.php:189
$class
Contains the additional class value of the form.
Definition HtmlForm.php:174
$cancelURL
Specifies where the user is redirected to, once the form-data is cancelled.
Definition HtmlForm.php:154
getSteps()
Returns an array of steps.
Definition HtmlForm.php:536
__construct(string $name, array $parameters=[], HtmlForm|null $form=null)
HtmlForm class constructor.
Definition HtmlForm.php:252
$jsValidation
Contains the javascript validation type of the form.
Definition HtmlForm.php:184
getFirstInvalidStep()
Returns first step that didn't pass validation.
Definition HtmlForm.php:558
htmlDataAttributes()
Returns dataAttr escaped as attribute string.
Definition HtmlForm.php:980
$namespaces
Namespace strings for addible element classes.
Definition HtmlForm.php:243
onValidate()
Validation hook.
Definition HtmlForm.php:828
validateAutosave()
If the form is autosaving the validation property is defaulted to false.
Definition HtmlForm.php:841
$ttl
Time until session expiry (seconds)
Definition HtmlForm.php:214
getValues()
Gets form-data from current PHP session.
Definition HtmlForm.php:875
static clearOldSessions(int $ttl=3600, string $pattern="/^htmlform-.*/")
clearOldSessions
Definition HtmlForm.php:960
__toString()
Renders form to HTML.
process()
Calls form validation and handles redirects.
Definition HtmlForm.php:728
$submitURL
HTML form action attribute.
Definition HtmlForm.php:144
redirect(string $url)
Redirects Browser to a different URL.
Definition HtmlForm.php:916
checkElementName(string $name)
Checks for duplicate subelement names.
Definition HtmlForm.php:443
buildUrlQuery(array $args=[])
Adding step parameter to already existing query.
Definition HtmlForm.php:598
$successURL
Specifies where the user is redirected to, once the form-data is valid.
Definition HtmlForm.php:149
updateInputValue(string $name)
Updates the value of an associated input element.
Definition HtmlForm.php:640
$sessionSlot
PHP session handle.
Definition HtmlForm.php:199
clearSession(bool $clearCsrfToken=true)
Deletes the current forms' PHP session data.
Definition HtmlForm.php:937
$internalFields
List of internal fieldnames that are not part of the results.
Definition HtmlForm.php:229
$validator
Contains the validator function of the form.
Definition HtmlForm.php:179
$cancelLabel
Contains the cancel button label of the form.
Definition HtmlForm.php:169
populate(array|object $data=[])
Fills subelement values.
Definition HtmlForm.php:695
setCurrentStep(int|null $step=null)
Validates step number of GET request.
Definition HtmlForm.php:515
htmlSubmitURL()
Returns form url escaped as attribute string.
Definition HtmlForm.php:990
getValuesWithLabel()
Gets form-data from current PHP session but also contain elemnt labels.
Definition HtmlForm.php:889
setDefaults()
Collects initial values across subclasses.
Definition HtmlForm.php:303
$sessionSlotName
Contains the name of the array in the PHP session, holding the form-data.
Definition HtmlForm.php:194
$url
url of the current page
Definition HtmlForm.php:139
$backLabel
Contains the back button label of the form.
Definition HtmlForm.php:164
getNamespaces()
Returns list of registered namespaces.
Definition HtmlForm.php:490
isEmpty()
Returns wether form has been submitted before or not.
Definition HtmlForm.php:393
buildUrl(array $args=[])
Builds URL from parts.
Definition HtmlForm.php:583
getNewCsrfToken()
Returns new XSRF token.
Definition HtmlForm.php:403
addElement(string $type, string $name, array $parameters)
Adds input or fieldset elements to htmlform.
Definition HtmlForm.php:419
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