diff --git a/src/bootstrap/safer_io.php b/src/bootstrap/safer_io.php index 88f870e..2b4736b 100644 --- a/src/bootstrap/safer_io.php +++ b/src/bootstrap/safer_io.php @@ -44,6 +44,8 @@ final class use_io { public string $field_description; public FORM_INPUT_TYPES $form_type; public array $form_data_list = []; + public ?string $form_check_or_radio_value = null; + public ?string $form_check_or_radio_name = null; public bool $show_label = true; public ?string $div_class = null; public ?string $label_class = null; @@ -102,46 +104,6 @@ final class safer_io { protected function __construct() { } - - public static function build_html(array $input): array { - $html_output = []; - $errors = []; - $headers = []; - $show_labels =[]; - $form_type = []; - $required = []; - $form_data_list = []; - $classes = []; - foreach(self::esv($input['html']) as $html) { - $key = $html['name'] ?? ""; - $html_output[$key] = $html['html']; - $headers[$key] = $html['meta']['field_desc'][$key] ?? ""; - $show_labels[$key] = $html['meta']['show_label'][$key] ?? true; - $form_type[$key] = $html['meta']['form_type'][$key] ?? FORM_TYPE::text->value; - $form_data_list[$key] = $html['meta']['form_data_list'][$key] ?? []; - $classes['label'][$key] = $html['meta']['label_class'][$key] ?? null; - $classes['div'][$key] = $html['meta']['div_class'][$key] ?? null; - $classes['ctrl'][$key] = $html['meta']['form_control_class'][$key] ?? null; - $required[$key] = $html['meta']['required'][$key] ?? false; - if (\CodeHydrater\common::get_count($html['errors'])) { - $errors[$key] = $html['errors'][$key]; - } -// dump($html); - } - return [ - 'div-class' => $input['classes']['div-class'] ?? "mb-3", - 'form-control-class' => $input['classes']['form-control-class'] ?? "", - 'label-class' => $input['classes']['label-class'] ?? "", - 'classes'=>$classes, - 'html'=>$html_output, - 'errors'=>$errors, - 'headers'=>$headers, - 'show_labels'=>$show_labels, - 'form_type'=>$form_type, - 'form_data_list'=>$form_data_list, - 'required'=>$required - ]; - } /** * Get raw data for inputs, to be used by filters @@ -532,6 +494,15 @@ final class safer_io { if (isset($a->form_data_list)) { $meta['form_data_list'][$input_field_name] = $a->form_data_list; } + + if (isset($a->form_check_or_radio_name)) { + $alt_name = $a->form_check_or_radio_name; + $meta['form_ctrl']['name'][$input_field_name] = $alt_name; + } + + if (isset($a->form_check_or_radio_value)) { + $meta['form_ctrl']['value'][$input_field_name] = $a->form_check_or_radio_value; + } if (isset($a->show_label)) { $meta['show_label'][$input_field_name] = $a->show_label; @@ -553,6 +524,7 @@ final class safer_io { if (str_contains($a->validation_rule, "required")) { $meta['required'][$input_field_name] = true; } + $meta['validation_rules'][$input_field_name] = $a->validation_rule; } if (isset($a->form_type)) { @@ -568,7 +540,11 @@ final class safer_io { if (isset($a->input_var)) { $user_text = $a->input_var; } elseif (isset($a->input_type) && $a->input_type instanceof \UnitEnum) { - $user_text = self::get_input_by_type($input_field_name, $a->input_type); + if (empty($alt_name)) { + $user_text = self::get_input_by_type($input_field_name, $a->input_type); + } else { + $user_text = self::get_input_by_type($alt_name, $a->input_type); + } } else { $ret['name'] = $input_field_name; $ret['meta']['missing'][] = $input_field_name; diff --git a/src/classes/form_builder/html_form.php b/src/classes/form_builder/html_form.php index c024727..2d5e64d 100644 --- a/src/classes/form_builder/html_form.php +++ b/src/classes/form_builder/html_form.php @@ -11,7 +11,8 @@ declare(strict_types = 1); namespace CodeHydrater\form_builder; use \CodeHydrater\form_builder\html_helper as Helper; -use CodeHydrater\enums\form_input_types as FORM_TYPE; +use \CodeHydrater\enums\form_input_types as FORM_TYPE; +use \CodeHydrater\bootstrap\safer_io as SafeIO; class html_form { private $output = ""; @@ -85,45 +86,126 @@ class html_form { return $this->input($name, $options); } - public function build_group(array $a): void { - foreach($a['html'] as $name => $v) { + private function get_validation_rules(?string $rule_options): array { + if ($rule_options === null) { + return []; + } + + // Split the array by a separator, trim each element + // and return the array + $split = fn($str, $separator) => array_map('trim', explode($separator, $str)); + + $rules = $split($rule_options, '|'); + $ret = []; + foreach ($rules as $rule) { + // get rule name params + $params = []; + // if the rule has parameters e.g., min: 1 + if (strpos($rule, ':')) { + [$rule_name, $param_str] = $split($rule, ':'); + $params = $split($param_str, ','); + } else { + $rule_name = trim($rule); + } + switch($rule_name) { + case "number_range": + return [ 'min' => $params[0], 'max' => $params[1] ]; + case "between": + return [ 'min' => $params[0], 'max' => $params[1] ]; + case "min": + $ret['min'] = $params[0]; + case "max": + $ret['max'] = $params[0]; + } + } + return $ret; + } + + public function build_group(array $input): array { + $html_output = []; + $errors = []; + $headers = []; + foreach(SafeIO::esv($input['html']) as $html) { + $key = $html['name'] ?? ""; + $html_output[$key] = $html['html']; + $headers[$key] = $html['meta']['field_desc'][$key] ?? ""; + $show_labels = $html['meta']['show_label'][$key] ?? true; + $form_type = $html['meta']['form_type'][$key] ?? FORM_TYPE::text; + $form_data_list = $html['meta']['form_data_list'][$key] ?? []; + $classes['label'] = $html['meta']['label_class'][$key] ?? null; + $classes['div'] = $html['meta']['div_class'][$key] ?? null; + $classes['ctrl'] = $html['meta']['form_control_class'][$key] ?? null; + $fkn = $html['meta']['form_ctrl']['name'][$key] ?? null; + $fkv = $html['meta']['form_ctrl']['value'][$key] ?? null; + switch($form_type->value) { + case "checkbox": + case "radio": + $form_ctrl['name'] = $fkn; + $form_ctrl['value'] = $fkv; + } + + $required = $html['meta']['required'][$key] ?? false; + if (\CodeHydrater\common::get_count($html['errors'])) { + $errors[$key] = $html['errors'][$key]; + } + // Fix Values, so they are always a String! - $value = ($v === false || $v === null) ? "" : $v; - $type_of_form_input = $a['form_type'][$name]->value ?? FORM_TYPE::text->value; + $value = ($html['html'] === false || $html['html'] === null) ? "" : $html['html']; + + $type_of_form_input = $form_type->value ?? FORM_TYPE::text->value; if ($type_of_form_input === "none") { continue; // Skip none controls } - $is_required = $a['required'][$name] ?? false; + $is_required = $html['meta']['required'][$key] ?? false; $r_a = ($is_required) ? ['required' => ""] : []; + + $rule = $html['meta']['validation_rules'][$key] ?? null; + $rules = $this->get_validation_rules($rule); + if (! empty($rules)) { + $r_a = array_merge($rules, $r_a); + } - $my_classes = $a['classes'] ?? []; - $my_div_class = $my_classes['div'][$name] ?? null; - $my_label_class = $my_classes['label'][$name] ?? null; - $my_ctrl_class = $my_classes['ctrl'][$name] ?? null; - - $form_control_class = $my_ctrl_class ?? $a['form-control-class'] ?? "form-control"; + $form_control_class = $classes['ctrl'] ?? $input['classes']['form_control_class'] ?? "form-control"; $fc = ['class'=> $form_control_class]; - $div_class = $my_div_class ?? $a['div-class'] ?? "mb-3"; - $label_class = $my_label_class ?? $a['label-class'] ?? ""; + $div_class = $classes['div'] ?? $input['classes']['div_class'] ?? "mb-3"; + $label_class = $classes['label'] ?? $input['classes']['label_class'] ?? ""; - $data_lists = $a['form_data_list'][$name] ?? []; - if (count($data_lists)) { - $r_a['options'] = $data_lists; + if (count($form_data_list)) { + $r_a['options'] = $form_data_list; + } + + if (isset($form_ctrl['value'])) { + if ($form_ctrl['value'] === $value) { + $r_a['checked'] = "1"; + } else { + $value = $form_ctrl['value']; + } } $this->open_div(['class' => $div_class]); - $label = $a['headers'][$name] ?? null; - $show_label = $a['show_labels'][$name] ?? true; + $label = $headers[$key] ?? null; + if ($label !== null) { + $label = strip_tags($label); + } + if ($is_required) { + $label = "* " . $label; + } + + $show_label = $input['show_labels'][$key] ?? true; if (! empty($label) && $show_label) { - $this->label($label, array_merge(['class' => $label_class], ['for'=>$name])); + $this->label($label, array_merge(['class' => $label_class], ['for'=>$key])); } else { - $label_name = $label ?? $name; + $label_name = $label ?? $key; $r_a['placeholder'] = $label_name; } - $this->$type_of_form_input($name, array_merge($fc, ['id'=>$name, 'value'=>$value], $r_a)); + + $input_name = (isset($form_ctrl['name'])) ? $form_ctrl['name'] : $key; + + $this->$type_of_form_input($input_name, array_merge($fc, ['id'=>$key, 'value'=>$value], $r_a)); $this->close_div(); } + return ['html_output'=>$html_output, 'headers'=>$headers, 'errors'=>$errors]; } private function do_escape(string $content, array & $options): ?string { diff --git a/src/classes/form_builder/html_helper.php b/src/classes/form_builder/html_helper.php index a8e1d38..e83909e 100644 --- a/src/classes/form_builder/html_helper.php +++ b/src/classes/form_builder/html_helper.php @@ -46,6 +46,7 @@ class html_helper { 'charset', 'style', 'selected', + 'checked', ]; protected string $charset = 'UTF-8';