Account and permission manager and security log viewer. https://netsyms.biz/apps/managepanel
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FormBuilder.lib.php 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. <?php
  2. /*
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. */
  7. class FormBuilder {
  8. private $items = [];
  9. private $hiddenitems = [];
  10. private $title = "";
  11. private $icon = "";
  12. private $buttons = [];
  13. private $action = "action.php";
  14. private $method = "POST";
  15. private $id = "editform";
  16. /**
  17. * Create a form with autogenerated HTML.
  18. *
  19. * @param string $title Form title/heading
  20. * @param string $icon FontAwesone icon next to the title.
  21. * @param string $action URL to submit the form to.
  22. * @param string $method Form submission method (POST, GET, etc.)
  23. */
  24. public function __construct(string $title = "Untitled Form", string $icon = "fas fa-file-alt", string $action = "action.php", string $method = "POST") {
  25. $this->title = $title;
  26. $this->icon = $icon;
  27. $this->action = $action;
  28. $this->method = $method;
  29. }
  30. /**
  31. * Set the title of the form.
  32. * @param string $title
  33. */
  34. public function setTitle(string $title) {
  35. $this->title = $title;
  36. }
  37. /**
  38. * Set the icon for the form.
  39. * @param string $icon FontAwesome icon (example: "fas fa-toilet-paper")
  40. */
  41. public function setIcon(string $icon) {
  42. $this->icon = $icon;
  43. }
  44. /**
  45. * Set the URL the form will submit to.
  46. * @param string $action
  47. */
  48. public function setAction(string $action) {
  49. $this->action = $action;
  50. }
  51. /**
  52. * Set the form submission method (GET, POST, etc)
  53. * @param string $method
  54. */
  55. public function setMethod(string $method = "POST") {
  56. $this->method = $method;
  57. }
  58. /**
  59. * Set the form ID.
  60. * @param string $id
  61. */
  62. public function setID(string $id = "editform") {
  63. $this->id = $id;
  64. }
  65. /**
  66. * Add an input to the form.
  67. *
  68. * @param string $name Element name
  69. * @param string $value Element value
  70. * @param string $type Input type (text, number, date, select, tel...)
  71. * @param bool $required If the element is required for form submission.
  72. * @param string $id Element ID
  73. * @param array $options Array of [value => text] pairs for a select element
  74. * @param string $label Text label to display near the input
  75. * @param string $icon FontAwesome icon (example: "fas fa-toilet-paper")
  76. * @param int $width Bootstrap column width for the input, out of 12.
  77. * @param int $minlength Minimum number of characters for the input.
  78. * @param int $maxlength Maximum number of characters for the input.
  79. * @param string $pattern Regex pattern for custom client-side validation.
  80. * @param string $error Message to show if the input doesn't validate.
  81. */
  82. public function addInput(string $name, string $value = "", string $type = "text", bool $required = true, string $id = null, array $options = null, string $label = "", string $icon = "", int $width = 4, int $minlength = 1, int $maxlength = 100, string $pattern = "", string $error = "") {
  83. $item = [
  84. "name" => $name,
  85. "value" => $value,
  86. "type" => $type,
  87. "required" => $required,
  88. "label" => $label,
  89. "icon" => $icon,
  90. "width" => $width,
  91. "minlength" => $minlength,
  92. "maxlength" => $maxlength
  93. ];
  94. if (!empty($id)) {
  95. $item["id"] = $id;
  96. }
  97. if (!empty($options) && $type == "select") {
  98. $item["options"] = $options;
  99. }
  100. if (!empty($pattern)) {
  101. $item["pattern"] = $pattern;
  102. }
  103. if (!empty($error)) {
  104. $item["error"] = $error;
  105. }
  106. $this->items[] = $item;
  107. }
  108. /**
  109. * Add a text input.
  110. *
  111. * @param string $name Element name
  112. * @param string $value Element value
  113. * @param bool $required If the element is required for form submission.
  114. * @param string $id Element ID
  115. * @param string $label Text label to display near the input
  116. * @param string $icon FontAwesome icon (example: "fas fa-toilet-paper")
  117. * @param int $width Bootstrap column width for the input, out of 12.
  118. * @param int $minlength Minimum number of characters for the input.
  119. * @param int $maxlength Maximum number of characters for the input.
  120. * @param string $pattern Regex pattern for custom client-side validation.
  121. * @param string $error Message to show if the input doesn't validate.
  122. */
  123. public function addTextInput(string $name, string $value = "", bool $required = true, string $id = "", string $label = "", string $icon = "", int $width = 4, int $minlength = 1, int $maxlength = 100, string $pattern = "", string $error = "") {
  124. $this->addInput($name, $value, "text", $required, $id, null, $label, $icon, $width, $minlength, $maxlength, $pattern, $error);
  125. }
  126. /**
  127. * Add a select dropdown.
  128. *
  129. * @param string $name Element name
  130. * @param string $value Element value
  131. * @param bool $required If the element is required for form submission.
  132. * @param string $id Element ID
  133. * @param array $options Array of [value => text] pairs for a select element
  134. * @param string $label Text label to display near the input
  135. * @param string $icon FontAwesome icon (example: "fas fa-toilet-paper")
  136. * @param int $width Bootstrap column width for the input, out of 12.
  137. */
  138. public function addSelect(string $name, string $value = "", bool $required = true, string $id = null, array $options = null, string $label = "", string $icon = "", int $width = 4) {
  139. $this->addInput($name, $value, "select", $required, $id, $options, $label, $icon, $width);
  140. }
  141. /**
  142. * Add a button to the form.
  143. *
  144. * @param string $text Text string to show on the button.
  145. * @param string $icon FontAwesome icon to show next to the text.
  146. * @param string $href If not null, the button will actually be a hyperlink.
  147. * @param string $type Usually "button" or "submit". Ignored if $href is set.
  148. * @param string $id The element ID.
  149. * @param string $name The element name for the button.
  150. * @param string $value The form value for the button. Ignored if $name is null.
  151. * @param string $class The CSS classes for the button, if a standard success-colored one isn't right.
  152. */
  153. public function addButton(string $text, string $icon = "", string $href = null, string $type = "button", string $id = null, string $name = null, string $value = "", string $class = "btn btn-success") {
  154. $button = [
  155. "text" => $text,
  156. "icon" => $icon,
  157. "class" => $class,
  158. "type" => $type,
  159. "id" => $id,
  160. "href" => $href,
  161. "name" => $name,
  162. "value" => $value
  163. ];
  164. $this->buttons[] = $button;
  165. }
  166. /**
  167. * Add a hidden input.
  168. * @param string $name
  169. * @param string $value
  170. */
  171. public function addHiddenInput(string $name, string $value) {
  172. $this->hiddenitems[$name] = $value;
  173. }
  174. /**
  175. * Generate the form HTML.
  176. * @param bool $echo If false, returns HTML string instead of outputting it.
  177. */
  178. public function generate(bool $echo = true) {
  179. $html = <<<HTMLTOP
  180. <form action="$this->action" method="$this->method" id="$this->id">
  181. <div class="card">
  182. <h3 class="card-header d-flex">
  183. <div>
  184. <i class="$this->icon"></i> $this->title
  185. </div>
  186. </h3>
  187. <div class="card-body">
  188. <div class="row">
  189. HTMLTOP;
  190. foreach ($this->items as $item) {
  191. $required = $item["required"] ? "required" : "";
  192. $id = empty($item["id"]) ? "" : "id=\"$item[id]\"";
  193. $pattern = empty($item["pattern"]) ? "" : "pattern=\"$item[pattern]\"";
  194. if (empty($item['type'])) {
  195. $item['type'] = "text";
  196. }
  197. $itemhtml = "";
  198. $itemlabel = "";
  199. if ($item['type'] == "textarea") {
  200. $itemlabel = "<label class=\"mb-0\"><i class=\"$item[icon]\"></i> $item[label]:</label>";
  201. } else if ($item['type'] != "checkbox") {
  202. $itemlabel = "<label class=\"mb-0\">$item[label]:</label>";
  203. }
  204. $strippedlabel = strip_tags($item['label']);
  205. $itemhtml .= <<<ITEMTOP
  206. \n\n <div class="col-12 col-md-$item[width]">
  207. <div class="form-group mb-3">
  208. $itemlabel
  209. ITEMTOP;
  210. $inputgrouptop = <<<INPUTG
  211. \n <div class="input-group">
  212. <div class="input-group-prepend">
  213. <span class="input-group-text"><i class="$item[icon]"></i></span>
  214. </div>
  215. INPUTG;
  216. switch ($item['type']) {
  217. case "select":
  218. $itemhtml .= $inputgrouptop;
  219. $itemhtml .= <<<SELECT
  220. \n <select class="form-control" name="$item[name]" aria-label="$strippedlabel" $required>
  221. SELECT;
  222. foreach ($item['options'] as $value => $label) {
  223. $selected = "";
  224. if (!empty($item['value']) && $value == $item['value']) {
  225. $selected = " selected";
  226. }
  227. $itemhtml .= "\n <option value=\"$value\"$selected>$label</option>";
  228. }
  229. $itemhtml .= "\n </select>";
  230. break;
  231. case "checkbox":
  232. $itemhtml .= $inputgrouptop;
  233. $itemhtml .= <<<CHECKBOX
  234. \n <div class="form-group form-check">
  235. <input type="checkbox" name="$item[name]" $id class="form-check-input" value="$item[value]" $required aria-label="$strippedlabel">
  236. <label class="form-check-label">$item[label]</label>
  237. </div>
  238. CHECKBOX;
  239. break;
  240. case "textarea":
  241. $val = htmlentities($item['value']);
  242. $itemhtml .= <<<TEXTAREA
  243. \n <textarea class="form-control" id="info" name="$item[name]" aria-label="$strippedlabel" minlength="$item[minlength]" maxlength="$item[maxlength]" $required>$val</textarea>
  244. TEXTAREA;
  245. break;
  246. default:
  247. $itemhtml .= $inputgrouptop;
  248. $itemhtml .= <<<INPUT
  249. \n <input type="$item[type]" name="$item[name]" $id class="form-control" aria-label="$strippedlabel" minlength="$item[minlength]" maxlength="$item[maxlength]" $pattern value="$item[value]" $required />
  250. INPUT;
  251. break;
  252. }
  253. if (!empty($item["error"])) {
  254. $itemhtml .= <<<ERROR
  255. \n <div class="invalid-feedback">
  256. $item[error]
  257. </div>
  258. ERROR;
  259. }
  260. if ($item["type"] != "textarea") {
  261. $itemhtml .= "\n </div>";
  262. }
  263. $itemhtml .= <<<ITEMBOTTOM
  264. \n </div>
  265. </div>\n
  266. ITEMBOTTOM;
  267. $html .= $itemhtml;
  268. }
  269. $html .= <<<HTMLBOTTOM
  270. </div>
  271. </div>
  272. HTMLBOTTOM;
  273. if (!empty($this->buttons)) {
  274. $html .= "\n <div class=\"card-footer d-flex\">";
  275. foreach ($this->buttons as $btn) {
  276. $btnhtml = "";
  277. $inner = "<i class=\"$btn[icon]\"></i> $btn[text]";
  278. $id = empty($btn['id']) ? "" : "id=\"$btn[id]\"";
  279. if (!empty($btn['href'])) {
  280. $btnhtml = "<a href=\"$btn[href]\" class=\"$btn[class]\" $id>$inner</a>";
  281. } else {
  282. $name = empty($btn['name']) ? "" : "name=\"$btn[name]\"";
  283. $value = (!empty($btn['name']) && !empty($btn['value'])) ? "value=\"$btn[value]\"" : "";
  284. $btnhtml = "<button type=\"$btn[type]\" class=\"$btn[class]\" $id $name $value>$inner</button>";
  285. }
  286. $html .= "\n $btnhtml";
  287. }
  288. $html .= "\n </div>";
  289. }
  290. $html .= "\n </div>";
  291. foreach ($this->hiddenitems as $name => $value) {
  292. $value = htmlentities($value);
  293. $html .= "\n <input type=\"hidden\" name=\"$name\" value=\"$value\" />";
  294. }
  295. $html .= "\n</form>\n";
  296. if ($echo) {
  297. echo $html;
  298. }
  299. return $html;
  300. }
  301. }