Source Code: html_utils_inc.php

  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