Game server and admin dashboard for TerranQuest.
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

10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
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. }