From fb08e66d55cbf15c9aa5a20b7d2583181d0fe6ca Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 17 Dec 2025 18:10:35 -0500 Subject: [PATCH] alt_val_test --- protected/src/controllers/app/home_ctrl.php | 9 ++- .../src/inputs/app/home/alt_val_tests_in.php | 64 +++++++++++++++ .../src/inputs/app/home/val_tests_in.php | 60 +++----------- .../outputs/app/home/alt_val_tests_out.php | 81 +++++++++++++++++++ .../src/outputs/app/home/val_tests_out.php | 63 ++++++++++++--- protected/src/routes/cli_routes.php | 16 ++++ protected/src/views/default/app/footer.php | 7 +- protected/src/views/default/app/header.php | 10 ++- protected/src/views/default/app/val_tests.php | 2 +- .../views/twig/app/alt_val_tests.html.twig | 22 +++++ .../src/views/twig/app/val_tests.html.twig | 26 +----- 11 files changed, 274 insertions(+), 86 deletions(-) create mode 100644 protected/src/inputs/app/home/alt_val_tests_in.php create mode 100644 protected/src/outputs/app/home/alt_val_tests_out.php create mode 100644 protected/src/routes/cli_routes.php create mode 100644 protected/src/views/twig/app/alt_val_tests.html.twig diff --git a/protected/src/controllers/app/home_ctrl.php b/protected/src/controllers/app/home_ctrl.php index 723b7b4..e327655 100644 --- a/protected/src/controllers/app/home_ctrl.php +++ b/protected/src/controllers/app/home_ctrl.php @@ -23,10 +23,10 @@ class home_ctrl extends base_controller { // Defined from: on_footer_banner.php in the configs folder... $this->set_footer_and_authors(); - $this->view->set('html', $this->html); - $this->view->set_php_template('main'); $this->view->include("app/header", ViewType::PHP); $this->view->include("app/footer", ViewType::PHP); + $this->view->set('html', $this->html); + $this->view->set_php_template('main'); } public function index() { @@ -56,6 +56,11 @@ class home_ctrl extends base_controller { IOL::auto_wire($this, "app/home", "val_tests", "entry", null); return $this->response; } + + public function alt_val_tests() { + IOL::auto_wire($this, "app/home", "alt_val_tests", "entry", null); + return $this->response; + } public function extra() { $loaded = \CodeHydrater\extras_booter::tryToEnableFeature("testing", refresh: true); diff --git a/protected/src/inputs/app/home/alt_val_tests_in.php b/protected/src/inputs/app/home/alt_val_tests_in.php new file mode 100644 index 0000000..09aee0f --- /dev/null +++ b/protected/src/inputs/app/home/alt_val_tests_in.php @@ -0,0 +1,64 @@ + + * @copyright (c) 2025, Robert Strutts + * @license MIT + */ + +namespace Project\inputs\app\home; + +use \CodeHydrater\attributes\validators as Assert; +use \CodeHydrater\enums as E; +use \CodeHydrater\bootstrap\use_io as IO; +use \CodeHydrater\bootstrap\safer_io as SafeIO; + +/** + * This is how to wire up using Attributes on a Class... + */ + +class alt_val_tests_in { + + public static function entry(object $app): array { + $posts_data = $app->request->get_post_data(); + + $i_age = intval($posts_data->get("age")); + $age = ($i_age > 0) ? $i_age : null; + + $user_test_data = new my_val_tests_form( + $posts_data->get("name"), + $age, + $posts_data->get("email") + ); + + unset($posts_data); // free it up... + $v = new \CodeHydrater\attributes\validators\my_validator(); + $v->validate($user_test_data); + $errors = $v->get_errors(); + + return [ + 'method' => $app->request->get_method(), + 'table_headers' => ['Full Name', 'Age', 'Email'], + 'post_data' => get_object_vars($user_test_data), + 'a_errors' => $errors, + ]; + } +} + +class my_val_tests_form { + public function __construct( + #[Assert\Required] + #[Assert\Max(70)] + public ?string $name = null, + #[Assert\Required] + #[Assert\Positive] + #[Assert\NumberRange(18, 130)] + public ?int $age = null, + #[Assert\Required] + #[Assert\Between(7, 255)] + #[Assert\Email] + public ?string $email = null + ) {} +} \ No newline at end of file diff --git a/protected/src/inputs/app/home/val_tests_in.php b/protected/src/inputs/app/home/val_tests_in.php index d77d29f..148a260 100644 --- a/protected/src/inputs/app/home/val_tests_in.php +++ b/protected/src/inputs/app/home/val_tests_in.php @@ -12,77 +12,41 @@ namespace Project\inputs\app\home; use \CodeHydrater\attributes\validators as Assert; use \CodeHydrater\enums as E; +use \CodeHydrater\enums\form_input_types as FORM_TYPE; use \CodeHydrater\bootstrap\use_io as IO; use \CodeHydrater\bootstrap\safer_io as SafeIO; class val_tests_in { - private static function define_io(string $v_rule = 'required|max: 70') { + private static function define_io(string $desc = "", string $v_rule = 'required|max: 70') { $required_post_string_field = new IO(); - $required_post_string_field->input_type = E\INPUTS::variable; + $required_post_string_field->input_type = E\INPUTS::post; + $required_post_string_field->field_description = $desc; + $required_post_string_field->form_type = FORM_TYPE::text; $required_post_string_field->field_filter = E\FIELD_FILTER::raw_string; - $required_post_string_field->escape_html = E\HTML_FLAG::escape; + $required_post_string_field->escape_html = E\HTML_FLAG::strip; $required_post_string_field->validation_rule = $v_rule; $required_post_string_field->use_db_filter = E\DB_FILTER::OFF; $required_post_string_field->skip_the_db = false; return $required_post_string_field; } - - private static function validate_tests_form_class(object $app): array { - $posts_data = $app->request->get_post_data(); - - $i_age = intval($posts_data->get("age")); - $age = ($i_age > 0) ? $i_age : null; - - $user_test_data = new my_val_tests_form( - $posts_data->get("name"), - $age, - $posts_data->get("email") - ); - unset($posts_data); // free it up... - $v = new \CodeHydrater\attributes\validators\my_validator(); - $v->validate($user_test_data); - $errors = $v->get_errors(); - return ['obj' => $user_test_data, 'err' => $errors]; - } - public static function entry(object $app): array { - $a = self::validate_tests_form_class($app); - SafeIO::set_data_from($a['obj']); - - $html['name'] = self::define_io(); - + $html['name'] = self::define_io("Full Name"); + $html['age'] = new IO(); - $html['age']->input_type = E\INPUTS::variable; + $html['age']->input_type = E\INPUTS::post; + $html['age']->field_description = "Age"; + $html['age']->form_type = FORM_TYPE::number; $html['age']->field_filter = E\FIELD_FILTER::integer_number; $html['age']->validation_rule = 'required|number_range: 18, 130'; $html['age']->validation_message = ['number_range' => 'The %s must be an Adult over %d and under %d!']; - $html['email'] = self::define_io('required|between: 7, 255|email'); + $html['email'] = self::define_io("Email Address", 'required|between: 7, 255|email'); return [ 'method' => $app->request->get_method(), - 'table_headers' => ['Full Name', 'Age', 'Email'], 'html' => $html, - 'post_data' => get_object_vars($a['obj']), - 'a_errors' => $a['err'], ]; } -} - -class my_val_tests_form { - public function __construct( - #[Assert\Required] - #[Assert\Max(70)] - public ?string $name = null, - #[Assert\Required] - #[Assert\Positive] - #[Assert\NumberRange(18, 130)] - public ?int $age = null, - #[Assert\Required] - #[Assert\Between(7, 255)] - #[Assert\Email] - public ?string $email = null - ) {} } \ No newline at end of file diff --git a/protected/src/outputs/app/home/alt_val_tests_out.php b/protected/src/outputs/app/home/alt_val_tests_out.php new file mode 100644 index 0000000..2668cb8 --- /dev/null +++ b/protected/src/outputs/app/home/alt_val_tests_out.php @@ -0,0 +1,81 @@ + + * @copyright (c) 2025, Robert Strutts + * @license MIT + */ + +namespace Project\outputs\app\home; + +use \CodeHydrater\bootstrap\safer_io as SafeIO; +use \CodeHydrater\enums\view_type as ViewType; +use \CodeHydrater\form_builder\html_form as Form; + +class alt_val_tests_out { + + private static function build_group(array $a, Form & $f, array $headers): void { + $i =0; + foreach($a as $name => $v) { + $o = ['class'=> 'form-control']; + $f->open_div(['class'=>'mb-3']); + $label = $headers[$i] ?? "Out of Bounds!"; + $f->label($label, array_merge($o, ['for'=>$name])); + $f->close_div(); + $f->open_div(['class'=>'mb-3']); + if ($name === "age") { + $f->number($name, array_merge($o, ['id'=>$name, 'value'=>$v, 'required'])); + } else { + $f->text($name, array_merge($o, ['id'=>$name, 'value'=>$v, 'required'])); + } + + $f->close_div(); + $i++; + } + } + + private static function build_form(array $a, array $headers): ?string { + $form_builder = new Form(); + $form_builder->set_escape(false); + $form_builder->open(options: ['autocomplete'=>'off']); + $form_builder->fieldset_open(['style'=>'width: 200px;']); + $form_builder->legend("News Letter"); + self::build_group($a, $form_builder, $headers); + $form_builder->open_div(['class'=>'mb-3']); + $form_builder->submit("go", ['class'=>'btn btn-primary']); + $form_builder->close_div(); + $form_builder->fieldset_close(); + $form_builder->close(); + return $form_builder->get_output(); + } + + public static function entry(object $app, array $input): array { + $did_submit = ($input['method'] === "POST"); + $name = $input['post_data']['name'] ?? "Anonymous"; + $data = [ + 'form_builder' => self::build_form($input['post_data'], $input['table_headers']), + 'table_options' => ['helper' => 'single-row','escape' => true], + 'did_submit' => $did_submit, + 'table_headers' => $input['table_headers'], + 'escaping' => ['escape' => false], + 'post_data' => $input['post_data'], + 'safe_name' => \CodeHydrater\bootstrap\safer_io::h($name), + 'a_errors' => $input['a_errors'], + ]; + + $app->view->set('twig_data', $data); + $app->view->set('twig_functions', [ + 'show_table' => '\CodeHydrater\html::show_table_from', + 'show_errors' => '\CodeHydrater\html::show_errors', + ]); + $content = $app->view->fetch($app, "app/alt_val_tests.html", ViewType::TWIG); + + $mem = \CodeHydrater\memory_usage::get_memory_stats(echo: false); + $content = \CodeHydrater\common::str_replace_first("", $mem, $content); + + $app->response->set_content($content); + return []; + } +} \ No newline at end of file diff --git a/protected/src/outputs/app/home/val_tests_out.php b/protected/src/outputs/app/home/val_tests_out.php index 9ef5c92..942535e 100644 --- a/protected/src/outputs/app/home/val_tests_out.php +++ b/protected/src/outputs/app/home/val_tests_out.php @@ -12,44 +12,87 @@ namespace Project\outputs\app\home; use \CodeHydrater\bootstrap\safer_io as SafeIO; use \CodeHydrater\enums\view_type as ViewType; +use \CodeHydrater\form_builder\html_form as Form; +use \CodeHydrater\enums\form_input_types as FORM_TYPE; class val_tests_out { - public static function entry(object $app, array & $input): array { + private static function build_group(array $a, Form & $f): void { + foreach($a['html'] as $name => $v) { + // 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; + if ($type_of_form_input === "none") { + continue; // Skip none controls + } + $is_required = $a['required'][$name] ?? false; + $r_a = ($is_required) ? ['required' => ""] : []; + $fc = ['class'=> 'form-control']; + $f->open_div(['class'=>'mb-3']); + $label = $a['headers'][$name] ?? "Header not set."; + $f->label($label, array_merge($fc, ['for'=>$name])); + $f->$type_of_form_input($name, array_merge($fc, ['id'=>$name, 'value'=>$value], $r_a)); + $f->close_div(); + } + } + + private static function build_form(array $a): ?string { + $form_builder = new Form(); + $form_builder->set_escape(false); + $form_builder->open(options: ['autocomplete'=>'off']); + $form_builder->fieldset_open(['style'=>'width: 200px;']); + $form_builder->legend("News Letter"); + self::build_group($a, $form_builder); + $form_builder->open_div(['class'=>'mb-3']); + $form_builder->submit("go", ['class'=>'btn btn-primary']); + $form_builder->close_div(); + $form_builder->fieldset_close(); + $form_builder->close(); + return $form_builder->get_output(); + } + + public static function entry(object $app, array $input): array { $html_output = []; $errors = []; - foreach(SafeIO::html_escape_and_sanitize($input['html']) as $html) { + $headers = []; + $form_type = []; + $required = []; + foreach(SafeIO::esv($input['html']) as $html) { $key = $html['name'] ?? ""; $html_output[$key] = $html['html']; + $headers[$key] = $html['meta']['field_desc'][$key] ?? "Unknown"; + $form_type[$key] = $html['meta']['form_type'][$key] ?? FORM_TYPE::text->value; + $required[$key] = $html['meta']['required'][$key] ?? false; if (\CodeHydrater\common::get_count($html['errors'])) { $errors[$key] = $html['errors'][$key]; } // dump($html); } + $a = ['html'=>$html_output, 'headers'=>$headers, 'form_type'=>$form_type, 'required'=>$required]; + $did_submit = ($input['method'] === "POST"); - $name = $input['post_data']['name'] ?? "Anonymous"; + $name = $html_output['name'] ?? "Anonymous"; + $data = [ + 'form_builder' => self::build_form($a), 'table_options' => ['helper' => 'single-row','escape' => false], 'safe_html' => $html_output, 'did_submit' => $did_submit, - 'table_headers' => $input['table_headers'], - 'escaping' => ['escape' => false], - 'post_data' => $input['post_data'], + 'table_headers' => $headers, 'safe_name' => \CodeHydrater\bootstrap\safer_io::h($name), - 'a_errors' => array_merge($input['a_errors'], $errors) + 'a_errors' => $errors, ]; - + unset($html_output, $errors, $headers, $form_type, $required); $app->view->set('twig_data', $data); $app->view->set('twig_functions', [ 'show_table' => '\CodeHydrater\html::show_table_from', 'show_errors' => '\CodeHydrater\html::show_errors', ]); // $app->view->set('table_cells', $input['html']); -// $app->view->set('table_headers', $input['table_headers']); +// $app->view->set('table_headers', $headers); // $app->view->include("app/val_tests", ViewType::PHP); $content = $app->view->fetch($app, "app/val_tests.html", ViewType::TWIG); - $mem = \CodeHydrater\memory_usage::get_memory_stats(echo: false); $content = \CodeHydrater\common::str_replace_first("", $mem, $content); diff --git a/protected/src/routes/cli_routes.php b/protected/src/routes/cli_routes.php new file mode 100644 index 0000000..2da8f94 --- /dev/null +++ b/protected/src/routes/cli_routes.php @@ -0,0 +1,16 @@ + [], +// "https://cdn.metroui.org.ua/v4/js/metro.min.js" => [], + "https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" + => [ + "integrity" => "sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy", + "crossorigin" => "anonymous", + ], ]; //const JS_TSR = [ "js/trouble_shooting_routes.js" =>[] ]; diff --git a/protected/src/views/default/app/header.php b/protected/src/views/default/app/header.php index 8fa396b..d7e50ba 100644 --- a/protected/src/views/default/app/header.php +++ b/protected/src/views/default/app/header.php @@ -3,7 +3,13 @@ declare(strict_types=1); const CSS_CDN_FILES = [ - 'https://cdn.metroui.org.ua/v4/css/metro-all.min.css' => ['media'=>'all'] + // 'https://cdn.metroui.org.ua/v4/css/metro-all.min.css' => ['media'=>'all'] + + "https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" => [ + 'media' => 'all', + 'integrity' => 'sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH', + 'crossorigin' => 'anonymous' + ], ]; const CSS_FILES = [ @@ -11,4 +17,4 @@ const CSS_FILES = [ ]; $html->set_assets_from_array(CSS_CDN_FILES, 'main_css', 'cdn'); -//$html->set_assets_from_array(CSS_FILES, 'css'); +//$html->set_assets_from_array(CSS_FILES, 'css'); \ No newline at end of file diff --git a/protected/src/views/default/app/val_tests.php b/protected/src/views/default/app/val_tests.php index a9d902a..406ec49 100644 --- a/protected/src/views/default/app/val_tests.php +++ b/protected/src/views/default/app/val_tests.php @@ -9,7 +9,7 @@ declare(strict_types=1); */ function show_table($headers, $s) { - $generator = \CodeHydrater\bootstrap\safer_io::html_escape_and_sanitize($s); + $generator = \CodeHydrater\bootstrap\safer_io::esv($s); $options = [ 'helper' => 'io', 'escape' => false, diff --git a/protected/src/views/twig/app/alt_val_tests.html.twig b/protected/src/views/twig/app/alt_val_tests.html.twig new file mode 100644 index 0000000..0142b34 --- /dev/null +++ b/protected/src/views/twig/app/alt_val_tests.html.twig @@ -0,0 +1,22 @@ +

Welcome!

+ + + + {% if did_submit and a_errors is empty %} + +

{{ safe_name }}, you Rock!

+ + {{ show_table(table_headers, post_data, table_options) }} + + {% else %} + + {% if did_submit and a_errors %} +

Errors Reporeted, are:

+
{{ show_errors(a_errors) }}
+
+ {% endif %} +
+ + {{ form_builder|raw }} + + {% endif %} \ No newline at end of file diff --git a/protected/src/views/twig/app/val_tests.html.twig b/protected/src/views/twig/app/val_tests.html.twig index d6ddf95..e88eed8 100644 --- a/protected/src/views/twig/app/val_tests.html.twig +++ b/protected/src/views/twig/app/val_tests.html.twig @@ -4,7 +4,7 @@ {% if did_submit and a_errors is empty %} -

{{ safe_name }}, you Rock!

+

{{ safe_name|raw }}, you Rock!

{{ show_table(table_headers, safe_html, table_options) }} @@ -16,25 +16,7 @@
{% endif %}
-
- - - - - - - - - - - - - - - - -
- -
-
+ + {{ form_builder|raw }} + {% endif %} \ No newline at end of file