1: <?php
2: /**
3: * This file contains the implementation of the auxiliary functions
4: * for placement of the form fields values of which can be automatically bound to
5: * the request variables with the corresponding name.
6: *
7: * Furthermore, it provides the function for creating a table from an array.
8: *
9: * @package HTML Utils
10: *
11: * @author Oleg Schildt
12: */
13:
14: namespace SmartFactory;
15:
16: /**
17: * Function for getting value of a request variable.
18: *
19: * This function checks wether the request variable exists and
20: * returns its value. If the request variable does not exist,
21: * an empty value is returned.
22: *
23: * @param string $name
24: * Name of the request variable how it is written in the form fields.
25: *
26: * @return mixed
27: * The value of the request variable or an empty string.
28: *
29: * @author Oleg Schildt
30: */
31: function reqvar_value(string $name): mixed
32: {
33: if (empty($name)) {
34: return "";
35: }
36:
37: $name = preg_replace("/([^\[\]]+)(.*)/i", "\$_REQUEST[\\1]\\2", $name);
38: $name = preg_replace("/\[([^\[\]]+)\]/i", "[\"\\1\"]", $name);
39: $name = str_replace("[]", "", $name);
40:
41: $val = "";
42: // protection against the php injection
43: $name = preg_replace("/[;,\\(\\)\\?]+/", "", $name);
44:
45: eval("\$val = isset($name) ? $name : '';");
46:
47: return $val;
48: } // reqvar_value
49:
50: /**
51: * Function for rendering the text input field.
52: *
53: * This function renders a text input field that is bound to
54: * the request variable with the corresponding name.
55: *
56: * @param array $parameters
57: * The array of parameters as an associative array in the form key => value:
58: *
59: * - $parameters["id"] - id of the field.
60: *
61: * - $parameters["name"] - name of the field.
62: *
63: * - $parameters["value"] - value that should be set for the field. If it is not specified,
64: * the value of the corresponding request variable is taken.
65: *
66: * Any other attributes may be specified.
67: *
68: * Example:
69: * ```php
70: * input_text(["id" => "data_input_text",
71: * "name" => "data[input_text]",
72: * "class" => "my_class",
73: * "style" => "width: 300px",
74: * "placeholder" => "enter the data",
75: * "title" => "enter the data",
76: * "data-prop" => "some-prop",
77: * "onblur" => "alert('Hello & Buy!')"
78: * ]);
79: * ```
80: *
81: * @param boolean $echo
82: * If the value of $echo is true, the html code of the field is directly echoed.
83: * Otherwise it is returned as string. It might be useful to pass this code to
84: * other rendering functions instead of echoing.
85: *
86: * @return string|null
87: * If the paramter $echo is true, the string of the field html
88: * code is returned, otherwise null.
89: *
90: * @see \SmartFactory\input_password()
91: * @see \SmartFactory\input_hidden()
92: * @see \SmartFactory\textarea()
93: * @see \SmartFactory\select()
94: * @see \SmartFactory\checkbox()
95: * @see \SmartFactory\radiobutton()
96: *
97: * @author Oleg Schildt
98: */
99: function input_text(array $parameters, bool $echo = true): string|null
100: {
101: $val = "";
102:
103: $html = "<input type=\"text\"";
104:
105: $sys_fields = ["id", "name", "value", "formatter"];
106:
107: if (!empty($parameters["id"])) {
108: $html .= " id=\"" . escape_html($parameters["id"]) . "\"";
109: }
110: if (!empty($parameters["name"])) {
111: $html .= " name=\"" . escape_html($parameters["name"]) . "\"";
112: $val = reqvar_value($parameters["name"]);
113: }
114:
115: // Value setting logic:
116: //
117: // If explicitely set in value, than take it, otherwise take it from the request variable with that name.
118:
119: if (!empty($parameters["value"])) {
120: $val = $parameters["value"];
121: }
122:
123: if (!empty($parameters["formatter"]) && is_callable($parameters["formatter"])) {
124: $val = call_user_func($parameters["formatter"], $val);
125: }
126:
127: $html .= " value=\"" . escape_html($val) . "\"";
128:
129: foreach ($parameters as $name => $data) {
130: if (in_array($name, $sys_fields)) {
131: continue;
132: }
133:
134: $html .= " " . escape_html($name) . "=\"" . escape_html($data) . "\"";
135: }
136:
137: $html .= ">";
138:
139: if (!$echo) {
140: return $html;
141: }
142:
143: //echo("<pre>" . escape_html($html) . "</pre>");
144: echo($html);
145:
146: return null;
147: } // input_text
148:
149: /**
150: * Function for rendering the password input field.
151: *
152: * This function renders a password input field that is bound to
153: * the request variable with the corresponding name.
154: *
155: * @param array $parameters
156: * The array of parameters as an associative array in the form key => value:
157: *
158: * - $parameters["id"] - id of the field.
159: *
160: * - $parameters["name"] - name of the field.
161: *
162: * Any other attributes may be specified.
163: *
164: * Example:
165: * ```php
166: * input_password(["id" => "data_input_password",
167: * "name" => "data[input_password]",
168: * "class" => "my_class",
169: * "style" => "width: 300px",
170: * "placeholder" => "enter the password",
171: * "title" => "enter the password",
172: * "data-prop" => "some-prop"
173: * ]);
174: * ```
175: *
176: * @param boolean $echo
177: * If the value of $echo is true, the html code of the field is directly echoed.
178: * Otherwise it is returned as string. It might be useful to pass this code to
179: * other rendering functions instead of echoing.
180: *
181: * @return string|null
182: * If the paramter $echo is true, the string of the field html
183: * code is returned, otherwise null.
184: *
185: * @see \SmartFactory\input_text()
186: * @see \SmartFactory\input_hidden()
187: * @see \SmartFactory\textarea()
188: * @see \SmartFactory\select()
189: * @see \SmartFactory\checkbox()
190: * @see \SmartFactory\radiobutton()
191: *
192: * @author Oleg Schildt
193: */
194: function input_password(array $parameters, bool $echo = true): string|null
195: {
196: $val = "";
197:
198: $html = "<input type=\"password\"";
199:
200: $sys_fields = ["id", "name", "value", "formatter"];
201:
202: if (!empty($parameters["id"])) {
203: $html .= " id=\"" . escape_html($parameters["id"]) . "\"";
204: }
205: if (!empty($parameters["name"])) {
206: $html .= " name=\"" . escape_html($parameters["name"]) . "\"";
207: $val = reqvar_value($parameters["name"]);
208: }
209:
210: // Value setting logic:
211: //
212: // If explicitely set in value, than take it, otherwise take it from the request variable with that name.
213:
214: if (!empty($parameters["value"])) {
215: $val = $parameters["value"];
216: }
217:
218: if (!empty($parameters["formatter"]) && is_callable($parameters["formatter"])) {
219: $val = call_user_func($parameters["formatter"], $val);
220: }
221:
222: $html .= " value=\"" . escape_html($val) . "\"";
223:
224: foreach ($parameters as $name => $data) {
225: if (in_array($name, $sys_fields)) {
226: continue;
227: }
228:
229: $html .= " " . escape_html($name) . "=\"" . escape_html($data) . "\"";
230: }
231:
232: $html .= ">";
233:
234: if (!$echo) {
235: return $html;
236: }
237:
238: //echo("<pre>" . escape_html($html) . "</pre>");
239: echo($html);
240:
241: return null;
242: } // input_password
243:
244: /**
245: * Function for rendering the hidden input field.
246: *
247: * This function renders a text hidden field that is bound to
248: * the request variable with the corresponding name.
249: *
250: * @param array $parameters
251: * The array of parameters as an associative array in the form key => value:
252: *
253: * - $parameters["id"] - id of the field.
254: *
255: * - $parameters["name"] - name of the field.
256: *
257: * - $parameters["value"] - value that should be set for the field. If it is not specified,
258: * the value of the corresponding request variable is taken.
259: *
260: * Any other attributes may be specified.
261: *
262: * Example:
263: * ```php
264: * input_hidden(["id" => "data_input_hidden",
265: * "name" => "data[input_hidden]",
266: * "data-prop" => "some-prop"
267: * ]);
268: * ```
269: *
270: * @param boolean $echo
271: * If the value of $echo is true, the html code of the field is directly echoed.
272: * Otherwise it is returned as string. It might be useful to pass this code to
273: * other rendering functions instead of echoing.
274: *
275: * @return string|null
276: * If the paramter $echo is true, the string of the field html
277: * code is returned, otherwise null.
278: *
279: * @see \SmartFactory\input_text()
280: * @see \SmartFactory\input_password()
281: * @see \SmartFactory\textarea()
282: * @see \SmartFactory\select()
283: * @see \SmartFactory\checkbox()
284: * @see \SmartFactory\radiobutton()
285: *
286: * @author Oleg Schildt
287: */
288: function input_hidden(array $parameters, bool $echo = true): string|null
289: {
290: $val = "";
291:
292: $html = "<input type=\"hidden\"";
293:
294: $sys_fields = ["id", "name", "value", "formatter"];
295:
296: if (!empty($parameters["id"])) {
297: $html .= " id=\"" . escape_html($parameters["id"]) . "\"";
298: }
299: if (!empty($parameters["name"])) {
300: $html .= " name=\"" . escape_html($parameters["name"]) . "\"";
301: $val = reqvar_value($parameters["name"]);
302: }
303:
304: // Value setting logic:
305: //
306: // If explicitely set in value, than take it, otherwise take it from the request variable with that name.
307:
308: if (!empty($parameters["value"])) {
309: $val = $parameters["value"];
310: }
311:
312: if (!empty($parameters["formatter"]) && is_callable($parameters["formatter"])) {
313: $val = call_user_func($parameters["formatter"], $val);
314: }
315:
316: $html .= " value=\"" . escape_html($val) . "\"";
317:
318: foreach ($parameters as $name => $data) {
319: if (in_array($name, $sys_fields)) {
320: continue;
321: }
322:
323: $html .= " " . escape_html($name) . "=\"" . escape_html($data) . "\"";
324: }
325:
326: $html .= ">";
327:
328: if (!$echo) {
329: return $html;
330: }
331:
332: echo($html);
333:
334: return null;
335: } // input_hidden
336:
337: /**
338: * Function for rendering the text area field.
339: *
340: * This function renders a text area field that is bound to
341: * the request variable with the corresponding name.
342: *
343: * @param array $parameters
344: * The array of parameters as an associative array in the form key => value:
345: *
346: * - $parameters["id"] - id of the field.
347: *
348: * - $parameters["name"] - name of the field.
349: *
350: * - $parameters["value"] - value that should be set for the field. If it is not specified,
351: * the value of the corresponding request variable is taken.
352: *
353: * Any other attributes may be specified.
354: *
355: * Example:
356: * ```php
357: * textarea(["id" => "data_textarea",
358: * "name" => "data[textarea]",
359: * "class" => "my_class",
360: * "style" => "width: 300px; height: 150px;",
361: * "placeholder" => "enter the text",
362: * "title" => "enter the text",
363: * "data-prop" => "some-prop",
364: * "onblur" => "alert('Hello & Buy!')"
365: * ]);
366: * ```
367: *
368: * @param boolean $echo
369: * If the value of $echo is true, the html code of the field is directly echoed.
370: * Otherwise it is returned as string. It might be useful to pass this code to
371: * other rendering functions instead of echoing.
372: *
373: * @return string|null
374: * If the paramter $echo is true, the string of the field html
375: * code is returned, otherwise null.
376: *
377: * @see \SmartFactory\input_text()
378: * @see \SmartFactory\input_password()
379: * @see \SmartFactory\input_hidden()
380: * @see \SmartFactory\select()
381: * @see \SmartFactory\checkbox()
382: * @see \SmartFactory\radiobutton()
383: *
384: * @author Oleg Schildt
385: */
386: function textarea(array $parameters, bool $echo = true): string|null
387: {
388: $val = "";
389:
390: $html = "<textarea";
391:
392: $sys_fields = ["id", "name", "value", "formatter"];
393:
394: if (!empty($parameters["id"])) {
395: $html .= " id=\"" . escape_html($parameters["id"]) . "\"";
396: }
397: if (!empty($parameters["name"])) {
398: $html .= " name=\"" . escape_html($parameters["name"]) . "\"";
399: $val = reqvar_value($parameters["name"]);
400: }
401:
402: // Value setting logic:
403: //
404: // If explicitely set in value, than take it, otherwise take it from the request variable with that name.
405:
406: if (!empty($parameters["value"])) {
407: $val = $parameters["value"];
408: }
409:
410: if (!empty($parameters["formatter"]) && is_callable($parameters["formatter"])) {
411: $val = call_user_func($parameters["formatter"], $val);
412: }
413:
414: foreach ($parameters as $name => $data) {
415: if (in_array($name, $sys_fields)) {
416: continue;
417: }
418:
419: $html .= " " . escape_html($name) . "=\"" . escape_html($data) . "\"";
420: }
421:
422: $html .= ">" . escape_html($val);
423: $html .= "</textarea>";
424:
425: if (!$echo) {
426: return $html;
427: }
428:
429: echo($html);
430:
431: return null;
432: } // textarea
433:
434: /**
435: * Function for rendering the select field.
436: *
437: * This function renders a select field that is bound to
438: * the request variable with the corresponding name.
439: *
440: * @param array $parameters
441: * The array of parameters as an associative array in the form key => value:
442: *
443: * - $parameters["id"] - id of the field.
444: *
445: * - $parameters["name"] - name of the field.
446: *
447: * - $parameters["value"] - value that should be set for the field. If it is not specified,
448: * the value of the corresponding request variable is taken.
449: *
450: * - $parameters["options"] - an associative array of list options in the form "option value" => "option text".
451: *
452: * - $parameters["multiple"] - set this key "multiple" => "multiple" if the list should support multichoice.
453: *
454: * Any other attributes may be specified.
455: *
456: * Example:
457: * ```php
458: * $options = [
459: * "yellow" => "Yellow",
460: * "blue" => "Blue",
461: * "red" => "Red",
462: * "brown" => "Brown",
463: * "black" => "Black",
464: * "white" => "White",
465: * "green" => "Green"
466: * ];
467: *
468: * select(["id" => "data_multiselect",
469: * "name" => "data[multiselect][]",
470: * "multiple" => "multiple",
471: * "class" => "my_class",
472: * "style" => "width: 300px; height: 180px",
473: * "title" => "select multi value",
474: * "data-prop" => "some-prop",
475: * "options" => $options
476: * ]);
477: * ```
478: *
479: * @param boolean $echo
480: * If the value of $echo is true, the html code of the field is directly echoed.
481: * Otherwise it is returned as string. It might be useful to pass this code to
482: * other rendering functions instead of echoing.
483: *
484: * @return string|null
485: * If the paramter $echo is true, the string of the field html
486: * code is returned, otherwise null.
487: *
488: * @see \SmartFactory\input_text()
489: * @see \SmartFactory\input_password()
490: * @see \SmartFactory\input_hidden()
491: * @see \SmartFactory\textarea()
492: * @see \SmartFactory\checkbox()
493: * @see \SmartFactory\radiobutton()
494: *
495: * @author Oleg Schildt
496: */
497: function select(array $parameters, bool $echo = true): string|null
498: {
499: $val = "";
500:
501: $html = "<select";
502:
503: $sys_fields = ["id", "name", "value", "options", "multiple"];
504:
505: if (!empty($parameters["id"])) {
506: $html .= " id=\"" . escape_html($parameters["id"]) . "\"";
507: }
508: if (!empty($parameters["name"])) {
509: $html .= " name=\"" . escape_html($parameters["name"]) . "\"";
510: $val = reqvar_value($parameters["name"]);
511: }
512:
513: // Value setting logic:
514: //
515: // If explicitely set in value, than take it, otherwise take it from the request variable with that name.
516:
517: if (!empty($parameters["value"])) {
518: $val = $parameters["value"];
519: }
520:
521: foreach ($parameters as $name => $data) {
522: if (in_array($name, $sys_fields)) {
523: continue;
524: }
525:
526: $html .= " " . escape_html($name) . "=\"" . escape_html($data) . "\"";
527: }
528:
529: if (isset($parameters["multiple"])) {
530: $html .= " multiple";
531: }
532:
533: $html .= ">\n";
534:
535: if (!empty($parameters["options"])) {
536: if (!is_array($parameters["options"])) {
537: trigger_error("The parameter options must be an array val => text!", E_USER_ERROR);
538: } else {
539: foreach ($parameters["options"] as $optval => $text) {
540: $selected = "";
541:
542: if (!is_array($val) && $optval == $val) {
543: $selected = "selected";
544: }
545: if (is_array($val) && in_array($optval, $val)) {
546: $selected = "selected";
547: }
548:
549: $html .= "<option value=\"" . escape_html($optval) . "\" $selected>" . escape_html($text) . "</option>\n";
550: }
551: }
552: }
553:
554: $html .= "</select>";
555:
556: if (!$echo) {
557: return $html;
558: }
559:
560: //echo("<pre>" . escape_html($html) . "</pre>");
561: echo($html);
562:
563: return null;
564: } // select
565:
566: /**
567: * Function for rendering the checkbox field.
568: *
569: * This function renders a checkbox field that is bound to
570: * the request variable with the corresponding name.
571: *
572: * @param array $parameters
573: * The array of parameters as an associative array in the form key => value:
574: *
575: * - $parameters["id"] - id of the field.
576: *
577: * - $parameters["name"] - name of the field.
578: *
579: * - $parameters["value"] - the value of the request variable that should be submitted
580: * if the checkbox is checked.
581: *
582: * - $parameters["checked"] - checked state that should be set for the field. If it is not specified,
583: * the value of the corresponding request variable is used to set the checked state.
584: *
585: * Any other attributes may be specified.
586: *
587: * Example:
588: * ```php
589: * checkbox(["id" => "data_checkbox",
590: * "name" => "data[checkbox]",
591: * "class" => "my_class",
592: * "value" => "1",
593: * "title" => "select checkbox",
594: * "data-prop" => "some-prop"
595: * ]);
596: * ```
597: *
598: * @param boolean $echo
599: * If the value of $echo is true, the html code of the field is directly echoed.
600: * Otherwise it is returned as string. It might be useful to pass this code to
601: * other rendering functions instead of echoing.
602: *
603: * @return string|null
604: * If the paramter $echo is true, the string of the field html
605: * code is returned, otherwise null.
606: *
607: * @see \SmartFactory\input_text()
608: * @see \SmartFactory\input_password()
609: * @see \SmartFactory\input_hidden()
610: * @see \SmartFactory\textarea()
611: * @see \SmartFactory\select()
612: * @see \SmartFactory\radiobutton()
613: *
614: * @author Oleg Schildt
615: */
616: function checkbox(array $parameters, bool $echo = true): string|null
617: {
618: $val = "";
619:
620: $html = "<input type=\"checkbox\"";
621:
622: $sys_fields = ["id", "name", "value", "checked"];
623:
624: if (!empty($parameters["id"])) {
625: $html .= " id=\"" . escape_html($parameters["id"]) . "\"";
626: }
627: if (!empty($parameters["name"])) {
628: $html .= " name=\"" . escape_html($parameters["name"]) . "\"";
629: $val = reqvar_value($parameters["name"]);
630: }
631:
632: if (!empty($parameters["value"])) {
633: $html .= " value=\"" . escape_html($parameters["value"]) . "\"";
634: }
635:
636: // Checked setting logic:
637: //
638: // If explicitely set in checked, than take it, otherwise take it from the request variable with that name.
639:
640: $checked = "";
641:
642: if (!is_array($val) && !empty($val)) {
643: $checked = " checked";
644: }
645: if (is_array($val) && in_array($parameters["value"] ?? "", $val)) {
646: $checked = " checked";
647: }
648:
649: if (!empty($parameters["checked"])) {
650: $checked = " checked";
651: }
652:
653: $html .= $checked;
654:
655: foreach ($parameters as $name => $data) {
656: if (in_array($name, $sys_fields)) {
657: continue;
658: }
659:
660: $html .= " " . escape_html($name) . "=\"" . escape_html($data) . "\"";
661: }
662:
663: $html .= ">";
664:
665: if (!$echo) {
666: return $html;
667: }
668:
669: //echo("<pre>" . escape_html($html) . "</pre>");
670: echo($html);
671:
672: return null;
673: } // checkbox
674:
675: /**
676: * Function for rendering the radiobutton field.
677: *
678: * This function renders a radiobutton field that is bound to
679: * the request variable with the corresponding name.
680: *
681: * @param array $parameters
682: * The array of parameters as an associative array in the form key => value:
683: *
684: * - $parameters["id"] - id of the field.
685: *
686: * - $parameters["name"] - name of the field.
687: *
688: * - $parameters["value"] - the value of the request variable that should be submitted
689: * if the radiobutton is checked.
690: *
691: * - $parameters["checked"] - checked state that should be set for the field. If it is not specified,
692: * the value of the corresponding request variable is used to set the checked state.
693: *
694: * Any other attributes may be specified.
695: *
696: * Example:
697: * ```php
698: * radiobutton(["id" => "data_radiocolor_red",
699: * "name" => "data[radiocolor]",
700: * "value" => "red"
701: * ]);
702: *
703: * radiobutton(["id" => "data_radiocolor_green",
704: * "name" => "data[radiocolor]",
705: * "value" => "green"
706: * ]);
707: * ```
708: *
709: * @param boolean $echo
710: * If the value of $echo is true, the html code of the field is directly echoed.
711: * Otherwise it is returned as string. It might be useful to pass this code to
712: * other rendering functions instead of echoing.
713: *
714: * @return string|null
715: * If the paramter $echo is true, the string of the field html
716: * code is returned, otherwise null.
717: *
718: * @see \SmartFactory\input_text()
719: * @see \SmartFactory\input_password()
720: * @see \SmartFactory\input_hidden()
721: * @see \SmartFactory\textarea()
722: * @see \SmartFactory\select()
723: * @see \SmartFactory\checkbox()
724: *
725: * @author Oleg Schildt
726: */
727: function radiobutton(array $parameters, bool $echo = true): string|null
728: {
729: $val = "";
730:
731: $html = "<input type=\"radio\"";
732:
733: $sys_fields = ["id", "name", "value", "checked"];
734:
735: if (!empty($parameters["id"])) {
736: $html .= " id=\"" . escape_html($parameters["id"]) . "\"";
737: }
738: if (!empty($parameters["name"])) {
739: $html .= " name=\"" . escape_html($parameters["name"]) . "\"";
740: $val = reqvar_value($parameters["name"]);
741: }
742:
743: if (!empty($parameters["value"])) {
744: $html .= " value=\"" . escape_html($parameters["value"]) . "\"";
745: }
746:
747: // Checked setting logic:
748: //
749: // If explicitely set in checked, than take it, otherwise take it from the request variable with that name.
750:
751: $checked = "";
752:
753: if (!empty($val) && ($parameters["value"] ?? "") == $val) {
754: $checked = " checked";
755: }
756:
757: if (!empty($parameters["checked"])) {
758: $checked = " checked";
759: }
760:
761: $html .= $checked;
762:
763: foreach ($parameters as $name => $data) {
764: if (in_array($name, $sys_fields)) {
765: continue;
766: }
767:
768: $html .= " " . escape_html($name) . "=\"" . escape_html($data) . "\"";
769: }
770:
771: $html .= ">";
772:
773: if (!$echo) {
774: return $html;
775: }
776:
777: //echo("<pre>" . escape_html($html) . "</pre>");
778: echo($html);
779:
780: return null;
781: } // radiobutton
782:
783: /**
784: * Function for rendering tables.
785: *
786: * This function renders a tables based on the values of an array.
787: *
788: * @param array &$array
789: * The array of the rows.
790: *
791: * @param array $parameters
792: * The array of parameters as an associative array in the form key => value:
793: *
794: * - $parameters["captions"] - the associative array of column captions. If
795: * it is not specified, the table is rendered without captions.
796: *
797: * - $parameters["col_class_from_keys"] - if it is specified and set to true,
798: * the keys of the captions are used as the class names.
799: *
800: * - $parameters["no_escape_html"] - if it is specified and set to true,
801: * the values of the data array are not escaped and passed as is. It is useful
802: * when html codes of other elements are passed. Per default, the table data
803: * is escaped for html.
804: *
805: * - $parameters["formatter"] - this function is used for the value formatting
806: * if specified. It is called for evelry cell of the table. The signature of
807: * this function is:
808: *
809: * ```php
810: * function ($rownum, $colnum, $colname, $val) : string;
811: * ```
812: *
813: * - $rownum - the row number.
814: *
815: * - $colnum - the colnum number.
816: *
817: * - $colname - the column name if the $parameters["captions"] are provided.
818: * The keys of the cpation array are used. If the $parameters["captions"]
819: * are not provided, $colname is equal to $colnum.
820: *
821: * - $val - original value of the table cell.
822: *
823: * If necessary, format the original value and return it. Otherwise,
824: * return the original value without changes.
825: *
826: * Any other attributes may be specified.
827: *
828: * Example:
829: * ```php
830: * $rows = [
831: * ["name" => "DB design", "employee" => "Alex", ... ],
832: * ["name" => "Mask implementation", "employee" => "Boris", ... ],
833: * ["name" => "Validation", "employee" => "Alex", ... ],
834: * ["name" => "Settings", "employee" => "Boris", ... ],
835: * ["name" => "About", "employee" => "Robert", ... ],
836: * ["name" => "Initialization", "employee" => "Alon", ... ]
837: * ];
838: *
839: * $captions = [
840: * "name" => "Task name",
841: * "employee" => "Employee",
842: * "time_estimation" => "Time estimation",
843: * "deadline" => "Deadline",
844: * "comments" => "Conmments"
845: * ];
846: *
847: * $formatter = function ($rownum, $colnum, $colname, $val) {
848: * if($colname == "time_estimation") return format_number($val, 2);
849: * if($colname == "deadline") return date("Y-m-d H:i", $val);
850: * return $val;
851: * };
852: *
853: * table($rows,
854: * ["captions" => $captions,
855: * "class" => "my_table",
856: * "style" => "background-color: #dddddd",
857: * "col_class_from_keys" => true,
858: * "no_escape_html" => false,
859: * "formatter" => $formatter
860: * ]);
861: * ```
862: *
863: * @param boolean $echo
864: * If the value of $echo is true, the html code of the table is directly echoed.
865: * Otherwise it is returned as string. It might be useful to pass this code to
866: * other rendering functions instead of echoing.
867: *
868: * @return string|null
869: * If the paramter $echo is true, the string of the table html
870: * code is returned, otherwise null.
871: *
872: * @author Oleg Schildt
873: */
874: function table(array &$array, array $parameters = [], bool $echo = true): string|null
875: {
876: if (!is_array($array)) {
877: trigger_error("An array expected!", E_WARNING);
878: }
879:
880: $html = "<table";
881:
882: if (!empty($parameters["class"])) {
883: $html .= " class=\"" . escape_html($parameters["class"]) . "\"";
884: }
885: if (!empty($parameters["style"])) {
886: $html .= " style=\"" . escape_html($parameters["style"]) . "\"";
887: }
888:
889: $html .= ">\n";
890:
891: if (!empty($parameters["captions"])) {
892: $html .= "<tr>\n";
893:
894: foreach ($parameters["captions"] as $key => $value) {
895: $html .= "<th";
896:
897: if (!empty($parameters["col_class_from_keys"])) {
898: $html .= " class=\"" . escape_html($key) . "\"";
899: }
900:
901: $html .= ">\n";
902:
903: if (empty($parameters["no_escape_html"])) {
904: $value = escape_html($value);
905: }
906:
907: $html .= $value;
908:
909: $html .= "\n</th>\n";
910: }
911:
912: $html .= "</tr>\n";
913: }
914:
915: $rownum = 0;
916: foreach ($array as &$row) {
917: $rownum++;
918:
919: $html .= "<tr>\n";
920:
921: $colnum = 0;
922: foreach ($row as $key => $value) {
923: $colnum++;
924:
925: $html .= "<td";
926:
927: if (!empty($parameters["col_class_from_keys"])) {
928: $html .= " class=\"" . escape_html($key) . "\"";
929: }
930:
931: $html .= ">\n";
932:
933: if (!empty($parameters["formatter"]) && is_callable($parameters["formatter"])) {
934: $value = call_user_func($parameters["formatter"], $rownum, $colnum, $key, $value);
935: }
936:
937: if (empty($parameters["no_escape_html"])) {
938: $value = escape_html($value);
939: }
940:
941: $html .= $value;
942:
943: $html .= "\n</td>\n";
944: }
945:
946: $html .= "</tr>\n";
947: }
948:
949: $html .= "</table>";
950:
951: if (!$echo) {
952: return $html;
953: }
954:
955: echo($html);
956:
957: return null;
958: } // table