From c466bd4a8679fe42f15f1f5622dc1bfe5271baed Mon Sep 17 00:00:00 2001 From: Patrik Majer Date: Sun, 22 Jun 2025 18:44:22 +0200 Subject: [PATCH 1/4] adminator3: work: add item manually --- .../app/Controllers/Core/workController.php | 3 ++ adminator3/app/Core/work.php | 47 +++++++++++++++++++ adminator3/public/css/style.css | 10 ---- adminator3/templates/work/work-add-item.tpl | 24 ++++++++++ adminator3/templates/work/work.tpl | 2 + 5 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 adminator3/templates/work/work-add-item.tpl diff --git a/adminator3/app/Controllers/Core/workController.php b/adminator3/app/Controllers/Core/workController.php index 3c2ff5d81..a9eea2e77 100644 --- a/adminator3/app/Controllers/Core/workController.php +++ b/adminator3/app/Controllers/Core/workController.php @@ -57,6 +57,9 @@ public function work(ServerRequestInterface $request, ResponseInterface $respons $work = new work($this->container); + list($allItemsRs, $allItemsData) = $work->getAllItems(); + $assignData["items_list_select"] = $allItemsData; + $rs = $work->taskGroupList(); $assignData["p_bs_alerts"] = $work->p_bs_alerts; diff --git a/adminator3/app/Core/work.php b/adminator3/app/Core/work.php index 2afa45722..7ccdbe271 100644 --- a/adminator3/app/Core/work.php +++ b/adminator3/app/Core/work.php @@ -6,6 +6,7 @@ use SebastianBergmann\Type\VoidType; use Illuminate\Support\Facades\Redis; use HyssaDev\HibikenAsynqClient\Client; +use Exception; class work { @@ -16,6 +17,8 @@ class work protected \PgSql\Connection|\PDO|null $conn_pgsql; + public \PDO|null $pdoMysql; + protected $sentinel; protected Redis $redis; @@ -35,6 +38,7 @@ public function __construct(ContainerInterface $container) $this->logger = $container->get('logger'); $this->conn_mysql = $container->get('connMysql'); $this->conn_pgsql = $container->get('connPgsql'); + $this->pdoMysql = $container->get('pdoMysql'); $this->sentinel = $container->get('sentinel'); @@ -46,6 +50,49 @@ public function __construct(ContainerInterface $container) $this->logger->info(message: __CLASS__ . "\\" . __FUNCTION__ . " called"); } + public function callPdoQueryAndFetch($query): array + { + $rs_error = null; + try { + $rs = $this->pdoMysql->query($query); + } catch (Exception $e) { + $rs_error = $e->getMessage(); + } + + if (is_object($rs)) { + $rs_data = $rs->fetchAll(); + + } else { + $this->logger->error(__CLASS__ . "\\" . __FUNCTION__ . ": PDO result is not object"); + $rs_data = []; + } + + return [$rs_data, $rs_error]; + } + + public function getAllItems(): array + { + $q = "SELECT id, name FROM workitems_names ORDER BY id"; + list($data_rs, $dotaz_error) = $this->callPdoQueryAndFetch($q); + + if ($dotaz_error != null) { + $this->logger->error(__CLASS__ . "\\" . __FUNCTION__ . ": Caught Exception: " . var_export($dotaz_error, true)); + $this->p_bs_alerts["Nelze načíst data pro výpis akcí pro manuální restart.
(SQL error: $dotaz_error)"] = "danger"; + + return [false, []]; + + } elseif (count($data_rs) < 1) { + $this->p_bs_alerts["Žádné data pro výpis akcí pro manuální restart."] = "warning"; + + return [true, []]; + } else { + foreach ($data_rs as $key => $val) { + $itemsList[] = ["id" => $val["id"], "name" => $val["name"]]; + } + return [true, $itemsList]; + } + } + public function getItemName(int $id): string|null { $rs_item_name = $this->conn_mysql->query("SELECT name FROM workitems_names WHERE id = '$id' "); diff --git a/adminator3/public/css/style.css b/adminator3/public/css/style.css index 663d80a27..6ae36961e 100644 --- a/adminator3/public/css/style.css +++ b/adminator3/public/css/style.css @@ -458,16 +458,6 @@ input[type=submit] .work-ok { color: green; } .work-error { color: red; } -.work-main-window -{ - height: 75px; - width: 620px; - padding: 15px; - - text-align: center; - background-color: silver; -} - .work-result { width: 620px; diff --git a/adminator3/templates/work/work-add-item.tpl b/adminator3/templates/work/work-add-item.tpl new file mode 100644 index 000000000..0c3e035d6 --- /dev/null +++ b/adminator3/templates/work/work-add-item.tpl @@ -0,0 +1,24 @@ +
+ +
+
Manuální přidání akce pro restart:
+ +
+ + + +
+ +
+ + +
+
+
+ +
diff --git a/adminator3/templates/work/work.tpl b/adminator3/templates/work/work.tpl index bea76c3da..e9aaa6fc9 100644 --- a/adminator3/templates/work/work.tpl +++ b/adminator3/templates/work/work.tpl @@ -2,6 +2,8 @@
+{include file="work/work-add-item.tpl"} + {if $p_bs_alerts|default:'0' }
{include file="partials/bootstrap-alert-with-columns-array.tpl"} From ee7898c5e19806f181098abb356fd170bf7c2810 Mon Sep 17 00:00:00 2001 From: Patrik Majer Date: Sun, 22 Jun 2025 19:41:41 +0200 Subject: [PATCH 2/4] add csrf --- adminator3/app/Controllers/Core/workController.php | 4 ++++ adminator3/templates/work/work-add-item.tpl | 2 ++ 2 files changed, 6 insertions(+) diff --git a/adminator3/app/Controllers/Core/workController.php b/adminator3/app/Controllers/Core/workController.php index a9eea2e77..90e7e824e 100644 --- a/adminator3/app/Controllers/Core/workController.php +++ b/adminator3/app/Controllers/Core/workController.php @@ -49,10 +49,14 @@ public function work(ServerRequestInterface $request, ResponseInterface $respons return $this->response; }; + $csrf = $this->generateCsrfToken($request, $response, true); + // $this->logger->info("workController\work: csrf generated: ".var_export($csrf_name, true)); + // $this->smarty->assign("action", $_SERVER['SCRIPT_URL']); $assignData = [ "page_title" => "Adminator3 :: Work", + "csrf_html" => $csrf[0] ]; $work = new work($this->container); diff --git a/adminator3/templates/work/work-add-item.tpl b/adminator3/templates/work/work-add-item.tpl index 0c3e035d6..f799bd4a8 100644 --- a/adminator3/templates/work/work-add-item.tpl +++ b/adminator3/templates/work/work-add-item.tpl @@ -1,6 +1,8 @@
+ {$csrf_html} +
Manuální přidání akce pro restart:
From fbb450500c3572626ecfb18b39e39e2c3c1987f4 Mon Sep 17 00:00:00 2001 From: Patrik Majer Date: Sun, 22 Jun 2025 21:11:25 +0200 Subject: [PATCH 3/4] rework error handling --- .../app/Controllers/Core/workController.php | 9 +-- adminator3/app/Core/work.php | 64 +++++++++++++++---- adminator3/templates/global/no-csrf.tpl | 28 +++++--- adminator3/templates/global/no-level.tpl | 28 +++++--- .../templates/global/smarty-exception.tpl | 22 +++++-- adminator3/templates/work/work-add-item.tpl | 2 +- adminator3/tests/adminator/Work/WorkTest.php | 2 +- 7 files changed, 110 insertions(+), 45 deletions(-) diff --git a/adminator3/app/Controllers/Core/workController.php b/adminator3/app/Controllers/Core/workController.php index 90e7e824e..e11a407ab 100644 --- a/adminator3/app/Controllers/Core/workController.php +++ b/adminator3/app/Controllers/Core/workController.php @@ -52,11 +52,9 @@ public function work(ServerRequestInterface $request, ResponseInterface $respons $csrf = $this->generateCsrfToken($request, $response, true); // $this->logger->info("workController\work: csrf generated: ".var_export($csrf_name, true)); - // $this->smarty->assign("action", $_SERVER['SCRIPT_URL']); - $assignData = [ "page_title" => "Adminator3 :: Work", - "csrf_html" => $csrf[0] + "csrf_html" => $csrf[0], ]; $work = new work($this->container); @@ -65,12 +63,15 @@ public function work(ServerRequestInterface $request, ResponseInterface $respons $assignData["items_list_select"] = $allItemsData; $rs = $work->taskGroupList(); - $assignData["p_bs_alerts"] = $work->p_bs_alerts; if ($rs[0] === true) { $assignData["work_list_groups_items"] = $rs[1]; } + $work->handleSingleActionForm(); + + $assignData["p_bs_alerts"] = $work->p_bs_alerts; + return $this->renderer->template($request, $response, 'work/work.tpl', $assignData); } } diff --git a/adminator3/app/Core/work.php b/adminator3/app/Core/work.php index 7ccdbe271..26a08fd83 100644 --- a/adminator3/app/Core/work.php +++ b/adminator3/app/Core/work.php @@ -8,14 +8,14 @@ use HyssaDev\HibikenAsynqClient\Client; use Exception; -class work +class work extends adminator { // DI - protected \Monolog\Logger $logger; + public \Monolog\Logger $logger; - protected \mysqli|\PDO $conn_mysql; + public \mysqli|\PDO $conn_mysql; - protected \PgSql\Connection|\PDO|null $conn_pgsql; + public \PgSql\Connection|\PDO|null $conn_pgsql; public \PDO|null $pdoMysql; @@ -32,6 +32,10 @@ class work */ public array $p_bs_alerts = []; + public $action_form; + + public int $form_single_action; + public function __construct(ContainerInterface $container) { // $this->container = $container; @@ -72,7 +76,7 @@ public function callPdoQueryAndFetch($query): array public function getAllItems(): array { - $q = "SELECT id, name FROM workitems_names ORDER BY id"; + $q = "SELECT id, name FROM workitems_names WHERE id > 0 ORDER BY id"; list($data_rs, $dotaz_error) = $this->callPdoQueryAndFetch($q); if ($dotaz_error != null) { @@ -103,7 +107,43 @@ public function getItemName(int $id): string|null return $item_name; } - public function taskEnqueue(int $item_id): bool|int + public function handleSingleActionForm(): void + { + $this->logger->info(__CLASS__ . "\\" . __FUNCTION__ . " called"); + + // get form data + $this->action_form = $this->formInit(); + $form_data = $this->action_form->validate("single_action"); + $this->form_single_action = intval($form_data["single_action"]); + + $this->logger->debug(__CLASS__ . "\\" . __FUNCTION__ . ": " . var_export($this->form_single_action, true)); + + // check if form was sended + if ($this->form_single_action > 0) { + // test if we have valid ID + $item_name = $this->getItemName($this->form_single_action); + + if (is_null($item_name)) { + $this->logger->warning(message: __CLASS__ . "\\" . __FUNCTION__ . ": parsing item_name failed (item_id $this->form_single_action)"); + } else { + [$queue_rs, $queue_err] = $this->taskEnqueue($this->form_single_action); + if ($queue_rs) { + $this->p_bs_alerts["Manuální přidání akce pro restart bylo provedeno úspěšně"] = "success"; + } else { + $this->p_bs_alerts["Manuální přidání akce pro restart selhalo.
($queue_err)"] = "danger"; + $this->logger->error(message: __CLASS__ . "\\" . __FUNCTION__ . ": single_action failed ($queue_err)"); + } + } + } + } + + /** + * @return array [ + * bool, // false if something failed + * bool|int|string, // results from asynq_client or error message + * ] + */ + public function taskEnqueue(int $item_id): array { $this->logger->info(__CLASS__ . "\\" . __FUNCTION__ . " called"); @@ -126,10 +166,10 @@ public function taskEnqueue(int $item_id): bool|int } catch (\RedisException $ex) { $m = $ex->getMessage(); $this->logger->error(__CLASS__ . "\\" . __FUNCTION__ . ": Redis error: $m"); - return false; + return [false, "Redis error: $m"]; } - return $res; + return [true, $res]; } public function taskGroupList(): array @@ -198,10 +238,10 @@ public function work_handler($item_id): array } // asynqClient part - $rs_queue = $this->taskEnqueue($item_id); - $this->logger->debug(__CLASS__ . "\\" . __FUNCTION__ . ": rs_queue: " . var_export($rs_queue, true)); + [$queue_rs, $queue_err] = $this->taskEnqueue($item_id); + $this->logger->debug(__CLASS__ . "\\" . __FUNCTION__ . ": rs_queue: " . var_export($queue_rs, true)); - if ($rs_queue) { + if ($queue_rs) { $rs_write = 1; } else { $rs_write = 0; @@ -219,7 +259,7 @@ public function work_handler($item_id): array // generate output view $output .= "
Požadavek na restart \"".$item_name."\" (No. ".$item_id.")"; - if ($rs_queue) { + if ($queue_rs) { $output .= "
- úspěšně přidán do fronty
"; } else { $output .= "
- chyba při přidání požadavku do fronty
"; diff --git a/adminator3/templates/global/no-csrf.tpl b/adminator3/templates/global/no-csrf.tpl index f31f0d9b8..fd28399fa 100644 --- a/adminator3/templates/global/no-csrf.tpl +++ b/adminator3/templates/global/no-csrf.tpl @@ -1,14 +1,22 @@ {include file="base.tpl"} -

Nelze zobrazit požadovanou stránku !

- - Selhala kontrola CSRF tokenu. -

- -
- Vraťte se na předchozí stránku. -

- - Zpráva od systému: {$body} +
+
+
+ + + +
Selhala kontrola CSRF tokenu.
+

+ +
+ Vraťte se na předchozí stránku. +

+ + Zpráva od systému: {$body} + +
+
+
{include file="base-end.tpl"} diff --git a/adminator3/templates/global/no-level.tpl b/adminator3/templates/global/no-level.tpl index 4f7cd507b..ba342241d 100644 --- a/adminator3/templates/global/no-level.tpl +++ b/adminator3/templates/global/no-level.tpl @@ -1,16 +1,24 @@ {include file="base.tpl"} -

Nelze zobrazit požadovanou stránku !

- - Pro otevřetí této stránky nemáte dostatečné oprávnění (level). -

- -
- Vraťte se na předchozí stránku. -

- - Zpráva od systému: {$body} +
+
+
+ + + +
Pro otevřetí této stránky nemáte dostatečné oprávnění (level).
+

+ +
+ Vraťte se na předchozí stránku. +

+ + Zpráva od systému: {$body} + +
+
+
{include file="base-end.tpl"} diff --git a/adminator3/templates/global/smarty-exception.tpl b/adminator3/templates/global/smarty-exception.tpl index a4f18d5b5..2f3f695cb 100644 --- a/adminator3/templates/global/smarty-exception.tpl +++ b/adminator3/templates/global/smarty-exception.tpl @@ -1,14 +1,22 @@ {include file="base.tpl"} -

Nelze zobrazit požadovanou stránku !

+
+
+
- Selhal proces vykreslování. -

+ + +
Selhal proces vykreslování.
+

-
- Vraťte se na předchozí stránku. -

+
+ Vraťte se na předchozí stránku. +

+ + Zpráva od systému: {$body} - Zpráva od systému: {$body} +
+
+
{include file="base-end.tpl"} diff --git a/adminator3/templates/work/work-add-item.tpl b/adminator3/templates/work/work-add-item.tpl index f799bd4a8..250d8e521 100644 --- a/adminator3/templates/work/work-add-item.tpl +++ b/adminator3/templates/work/work-add-item.tpl @@ -1,6 +1,6 @@
- + {$csrf_html}
Manuální přidání akce pro restart:
diff --git a/adminator3/tests/adminator/Work/WorkTest.php b/adminator3/tests/adminator/Work/WorkTest.php index 580980974..5803aaa34 100644 --- a/adminator3/tests/adminator/Work/WorkTest.php +++ b/adminator3/tests/adminator/Work/WorkTest.php @@ -48,7 +48,7 @@ public function testTaskEnqueue() for ($i = 0; $i < 250; $i++) { - $task = $work->taskEnqueue($faker->numberBetween(1, 30)); + [$rs, $task] = $work->taskEnqueue($faker->numberBetween(1, 30)); $this->assertTrue($task); } From 172c66b1f1c0f45ef22cecd0baf2c88104f9d1f6 Mon Sep 17 00:00:00 2001 From: Patrik Majer Date: Sun, 22 Jun 2025 21:16:22 +0200 Subject: [PATCH 4/4] prep bootstrap --- adminator3/app/Core/work.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adminator3/app/Core/work.php b/adminator3/app/Core/work.php index 26a08fd83..7ceb652c0 100644 --- a/adminator3/app/Core/work.php +++ b/adminator3/app/Core/work.php @@ -231,7 +231,8 @@ public function work_handler($item_id): array $item_name = $this->getItemName($item_id); if (is_null($item_name)) { - //TODO: add warning over bootstrap.JS + // TODO: check/fix rendering in objekty/topology page(s) + $this->p_bs_alerts["Nepodařilo se načíst název WorkItem položky.
(item_id: $item_id)"] = "warning"; $this->logger->warning(message: __CLASS__ . "\\" . __FUNCTION__ . ": parsing item_name failed (item_id $item_id)"); } else { $this->logger->info(message: __CLASS__ . "\\" . __FUNCTION__ . ": parsed item_name: " . var_export($item_name, true));