From 3a0fc1530afaca7af05cb0ce80f4ab601b9ca390 Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Tue, 6 Oct 2026 12:02:54 +0200 Subject: [PATCH 1/6] SystemCheck: wip table to kitchensink --- .../classes/I/Table/FactoryInterface.php | 31 +++ .../I/Table/Group/DataRetrievalInterface.php | 27 +++ .../I/Table/Group/FactoryInterface.php | 30 +++ .../I/Table/Group/HandlerInterface.php | 26 +++ .../I/Table/Task/DataRetrievalInterface.php | 32 +++ .../classes/I/Table/Task/FactoryInterface.php | 33 +++ .../classes/I/Table/Task/HandlerInterface.php | 27 +++ .../SystemCheck/classes/Table/Factory.php | 72 +++++++ .../classes/Table/Group/DataRetrieval.php | 144 +++++++++++++ .../classes/Table/Group/Factory.php | 62 ++++++ .../classes/Table/Group/Handler.php | 93 +++++++++ .../classes/Table/Task/DataRetrieval.php | 163 +++++++++++++++ .../classes/Table/Task/Factory.php | 60 ++++++ .../classes/Table/Task/Handler.php | 190 ++++++++++++++++++ .../classes/class.ilObjSystemCheckGUI.php | 29 +-- .../classes/class.ilSCGroupTableGUI.php | 122 ----------- .../default/tpl.syscheck_groups_row.html | 24 --- 17 files changed, 1006 insertions(+), 159 deletions(-) create mode 100644 components/ILIAS/SystemCheck/classes/I/Table/FactoryInterface.php create mode 100644 components/ILIAS/SystemCheck/classes/I/Table/Group/DataRetrievalInterface.php create mode 100644 components/ILIAS/SystemCheck/classes/I/Table/Group/FactoryInterface.php create mode 100644 components/ILIAS/SystemCheck/classes/I/Table/Group/HandlerInterface.php create mode 100644 components/ILIAS/SystemCheck/classes/I/Table/Task/DataRetrievalInterface.php create mode 100644 components/ILIAS/SystemCheck/classes/I/Table/Task/FactoryInterface.php create mode 100644 components/ILIAS/SystemCheck/classes/I/Table/Task/HandlerInterface.php create mode 100644 components/ILIAS/SystemCheck/classes/Table/Factory.php create mode 100644 components/ILIAS/SystemCheck/classes/Table/Group/DataRetrieval.php create mode 100644 components/ILIAS/SystemCheck/classes/Table/Group/Factory.php create mode 100644 components/ILIAS/SystemCheck/classes/Table/Group/Handler.php create mode 100644 components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php create mode 100644 components/ILIAS/SystemCheck/classes/Table/Task/Factory.php create mode 100644 components/ILIAS/SystemCheck/classes/Table/Task/Handler.php delete mode 100755 components/ILIAS/SystemCheck/classes/class.ilSCGroupTableGUI.php delete mode 100755 components/ILIAS/SystemCheck/templates/default/tpl.syscheck_groups_row.html diff --git a/components/ILIAS/SystemCheck/classes/I/Table/FactoryInterface.php b/components/ILIAS/SystemCheck/classes/I/Table/FactoryInterface.php new file mode 100644 index 000000000000..6cae8cbe34a2 --- /dev/null +++ b/components/ILIAS/SystemCheck/classes/I/Table/FactoryInterface.php @@ -0,0 +1,31 @@ +data_factory = new DataFactory(); + $this->ui = $DIC->ui(); + $this->lng = $DIC->language(); + $this->http = $DIC->http(); + $this->ctrl = $DIC->ctrl(); + } + + final public function group(): GroupFactoryInterface + { + return new GroupFactory( + $this->data_factory, + $this->ui, + $this->lng, + $this->http, + $this->ctrl + ); + } + + final public function task(): TaskFactoryInterface + { + return new TaskFactory( + $this->data_factory, + $this->ui, + $this->lng, + $this->http + ); + } +} diff --git a/components/ILIAS/SystemCheck/classes/Table/Group/DataRetrieval.php b/components/ILIAS/SystemCheck/classes/Table/Group/DataRetrieval.php new file mode 100644 index 000000000000..610d70486371 --- /dev/null +++ b/components/ILIAS/SystemCheck/classes/Table/Group/DataRetrieval.php @@ -0,0 +1,144 @@ +groups)) { + $this->groups = ilSCGroups::getInstance()->getGroups(); + } + foreach ($this->groups as $group) { + $task_gui = ilSCComponentTaskFactory::getComponentTaskGUIForGroup($group->getId()); + $this->titles[$group->getId()] = $task_gui->getGroupTitle(); + $this->descriptions[$group->getId()] = $task_gui->getGroupDescription(); + $this->complete[$group->getId()] = ilSCTasks::lookupCompleted($group->getId()); + $this->failed[$group->getId()] = ilSCTasks::lookupFailed($group->getId()); + $this->last_updates[$group->getId()] = ilSCTasks::lookupLastUpdate($group->getId()); + } + return $this->groups; + } + + final public function getRows( + DataRowBuilder $row_builder, + array $visible_column_ids, + Range $range, + Order $order, + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters + ): Generator { + [$column_name, $direction] = $order->join([], fn($ret, $key, $value) => [$key, $value]); + $titles = $this->titles; + $descriptions = $this->descriptions; + $last_updates = $this->last_updates; + $complete = $this->complete; + $failed = $this->failed; + $comparator = match ($column_name) { + Handler::TABLE_COL_TITLE => function (ilSCGroup $f1, ilSCGroup $f2) use ($titles) { + return strcasecmp($titles[$f1->getId()], $titles[$f2->getId()]); + }, + Handler::TABLE_COL_DESCRIPTION => function (ilSCGroup $f1, ilSCGroup $f2) use ($descriptions) { + return strcasecmp($descriptions[$f1->getId()], $descriptions[$f2->getId()]); + }, + Handler::TABLE_COL_LAST_UPDATE => function (ilSCGroup $f1, ilSCGroup $f2) use ($last_updates) { + if (ilDateTime::_equals($last_updates[$f1->getId()], $last_updates[$f2->getId()])) { + return 0; + } + return ilDateTime::_before($last_updates[$f1->getId()], $last_updates[$f2->getId()]) ? -1 : 1; + }, + Handler::TABLE_COL_SOLVED_TASKS => function (ilSCGroup $f1, ilSCGroup $f2) use ($complete) { + return $complete[$f1->getId()] - $complete[$f2->getId()]; + }, + Handler::TABLE_COL_UNSOLVED_TASKS => function (ilSCGroup $f1, ilSCGroup $f2) use ($failed) { + return $failed[$f1->getId()] - $failed[$f2->getId()]; + }, + default => fn(ilSCGroup $f1, ilSCGroup $f2) => 0 + }; + $sc_groups = $this->getSCGroups(); + uasort($sc_groups, $comparator); + if ($direction === "DESC") { + $sc_groups = array_reverse($sc_groups, true); + } + $sc_groups = array_slice($sc_groups, $range->getStart(), $range->getLength(), true); + foreach ($sc_groups as $sc_group) { + $this->ctrl->setParameterByClass(ilObjSystemCheckGUI::class, 'grp_id', $sc_group->getId()); + $link = $this->ctrl->getLinkTargetByClass(ilObjSystemCheckGUI::class, 'showGroup'); + $this->ctrl->clearParameterByClass(ilObjSystemCheckGUI::class, 'grp_id'); + yield $row_builder->buildDataRow( + $sc_group->getId() . '', + [ + Handler::TABLE_COL_TITLE => $this->ui->factory()->link()->standard($titles[$sc_group->getId()], $link), + Handler::TABLE_COL_DESCRIPTION => $descriptions[$sc_group->getId()], + Handler::TABLE_COL_LAST_UPDATE => ilDatePresentation::formatDate($this->last_updates[$sc_group->getId()]), + Handler::TABLE_COL_SOLVED_TASKS => $complete[$sc_group->getId()], + Handler::TABLE_COL_UNSOLVED_TASKS => $failed[$sc_group->getId()], + ] + ); + } + } + + final public function getTotalRowCount( + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters + ): ?int { + return count($this->getSCGroups()); + } +} diff --git a/components/ILIAS/SystemCheck/classes/Table/Group/Factory.php b/components/ILIAS/SystemCheck/classes/Table/Group/Factory.php new file mode 100644 index 000000000000..44afec276047 --- /dev/null +++ b/components/ILIAS/SystemCheck/classes/Table/Group/Factory.php @@ -0,0 +1,62 @@ +data_factory, + $this->ui, + $this->lng, + $this->http, + $data_retrieval ?? $this->dataRetrieval(), + ); + } + + final public function dataRetrieval(): DataRetrievalInterface + { + return new DataRetrieval( + $this->ui, + $this->ctrl + ); + } +} diff --git a/components/ILIAS/SystemCheck/classes/Table/Group/Handler.php b/components/ILIAS/SystemCheck/classes/Table/Group/Handler.php new file mode 100644 index 000000000000..5c7b7d95343b --- /dev/null +++ b/components/ILIAS/SystemCheck/classes/Table/Group/Handler.php @@ -0,0 +1,93 @@ + $this->ui->factory()->table()->column()->link( + $this->lng->txt(self::LNG_TABLE_COL_TITLE) + )->withHighlight(true)->withIsSortable(true), + self::TABLE_COL_DESCRIPTION => $this->ui->factory()->table()->column()->text( + $this->lng->txt(self::LNG_TABLE_COL_DESCRIPTION) + )->withHighlight(true)->withIsSortable(true), + self::TABLE_COL_LAST_UPDATE => $this->ui->factory()->table()->column()->text( + $this->lng->txt(self::LNG_TABLE_COL_LAST_UPDATE) + )->withHighlight(true)->withIsSortable(true), + self::TABLE_COL_SOLVED_TASKS => $this->ui->factory()->table()->column()->number( + $this->lng->txt(self::LNG_TABLE_COL_SOLVED_TASKS) + )->withHighlight(true)->withIsSortable(true), + self::TABLE_COL_UNSOLVED_TASKS => $this->ui->factory()->table()->column()->number( + $this->lng->txt(self::LNG_TABLE_COL_UNSOLVED_TASKS) + )->withHighlight(true)->withIsSortable(true) + ]; + } + + final protected function getTable(): DataTable + { + if (!isset($this->table)) { + $this->table = $this->ui->factory()->table()->data( + $this->data_retrieval, + $this->lng->txt(self::LNG_TABLE_TITLE), + $this->getColumns(), + )->withId(self::TABLE_ID)->withRequest($this->http->request()); + } + return $this->table; + } + + final public function getHTML(): string + { + return $this->ui->renderer()->render([$this->getTable()]); + } +} diff --git a/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php b/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php new file mode 100644 index 000000000000..194303fba318 --- /dev/null +++ b/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php @@ -0,0 +1,163 @@ +sc_tasks)) { + return $this->sc_tasks; + } + + $this->sc_tasks = []; + + foreach (ilSCTasks::getInstanceByGroupId($this->group_id)->getTasks() as $task) { + if (!$task->isActive()) { + continue; + } + $task_handler = ilSCComponentTaskFactory::getComponentTask($task->getId()); + $this->sc_tasks[$task->getId()] = $task; + $this->titles[$task->getId()] = $task_handler->getTitle(); + $this->descriptions[$task->getId()] = $task_handler->getDescription(); + $this->last_updates[$task->getId()] = $task->getLastUpdate(); + $this->status[$task->getId()] = $task->getStatus(); + } + return $this->sc_tasks; + } + + final public function getRows( + DataRowBuilder $row_builder, + array $visible_column_ids, + Range $range, + Order $order, + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters + ): Generator { + [$column_name, $direction] = $order->join([], fn($ret, $key, $value) => [$key, $value]); + $titles = $this->titles; + $descriptions = $this->descriptions; + $last_updates = $this->last_updates; + $status = $this->status; + $comparator = match ($column_name) { + Handler::TABLE_COL_TITLE => function (ilSCTask $f1, ilSCTask $f2) use ($titles) { + return strcasecmp($titles[$f1->getId()], $titles[$f2->getId()]); + }, + Handler::TABLE_COL_DESCRIPTION => function (ilSCTask $f1, ilSCTask $f2) use ($descriptions) { + return strcasecmp($descriptions[$f1->getId()], $descriptions[$f2->getId()]); + }, + Handler::TABLE_COL_LAST_UPDATE => function (ilSCTask $f1, ilSCTask $f2) use ($last_updates) { + if (ilDateTime::_equals($last_updates[$f1->getId()], $last_updates[$f2->getId()])) { + return 0; + } + return ilDateTime::_before($last_updates[$f1->getId()], $last_updates[$f2->getId()]) ? -1 : 1; + }, + Handler::TABLE_COL_STATUS => function (ilSCTask $f1, ilSCTask $f2) use ($status) { + return $status[$f1->getId()] - $status[$f2->getId()]; + }, + default => fn(ilSCTask $f1, ilSCTask $f2) => 0 + }; + $sc_tasks = $this->getSCTasks(); + uasort($sc_tasks, $comparator); + if ($direction === "DESC") { + $sc_tasks = array_reverse($sc_tasks, true); + } + $sc_tasks = array_slice($sc_tasks, $range->getStart(), $range->getLength(), true); + foreach ($sc_tasks as $sc_task) { + $data_row = $row_builder->buildDataRow( + $sc_task->getId() . '', + [ + Handler::TABLE_COL_TITLE => $titles[$sc_task->getId()], + Handler::TABLE_COL_DESCRIPTION => $descriptions[$sc_task->getId()], + Handler::TABLE_COL_LAST_UPDATE => ilDatePresentation::formatDate($this->last_updates[$sc_task->getId()]), + Handler::TABLE_COL_STATUS => ilSCUtils::taskStatus2Text($status[$sc_task->getId()]) + ] + ); + $inactive_actions = $this->getInactiveActions( + $sc_task, + Handler::ACTION_VALIDATE_DUPLICATES, + Handler::ACTION_REPAIR_DUPLICATES, + Handler::ACTION_SHOW_TREE, + Handler::ACTION_LIST_TREE, + Handler::ACTION_FIND_MISSING, + Handler::ACTION_REPAIR_MISSING, + Handler::ACTION_FIND_MISSING_TREE_ENTRIES, + Handler::ACTION_REPAIR_MISSING_TREE_ENTRIES, + Handler::ACTION_ANALYZE_STRUCTURE, + Handler::ACTION_REPAIR_STRUCTURE + ); + foreach ($inactive_actions as $action_name) { + $data_row = $data_row->withDisabledAction($action_name); + } + yield $data_row; + } + } + + final public function getTotalRowCount( + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters + ): ?int { + return count($this->getSCTasks()); + } + + final protected function getInactiveActions( + ilSCTask $task, + string ...$all_actions + ): array { + $task_gui = new ilSCTreeTasksGUI($task); + $active_actions = array_map(fn($action) => $action['command'], $task_gui->getActions()); + return array_diff($all_actions, $active_actions); + } +} diff --git a/components/ILIAS/SystemCheck/classes/Table/Task/Factory.php b/components/ILIAS/SystemCheck/classes/Table/Task/Factory.php new file mode 100644 index 000000000000..9463d3fd47c5 --- /dev/null +++ b/components/ILIAS/SystemCheck/classes/Table/Task/Factory.php @@ -0,0 +1,60 @@ +data_factory, + $this->ui, + $this->lng, + $this->http, + $data_retrieval, + $actions_permitted + ); + } + + final public function dataRetrieval( + int $group_id + ): DataRetrievalInterface { + return new DataRetrieval($group_id); + } +} diff --git a/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php b/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php new file mode 100644 index 000000000000..a28c9a9015f3 --- /dev/null +++ b/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php @@ -0,0 +1,190 @@ + $this->ui->factory()->table()->column()->text( + $this->lng->txt(self::LNG_TABLE_COL_TITLE) + )->withHighlight(true)->withIsSortable(true), + self::TABLE_COL_DESCRIPTION => $this->ui->factory()->table()->column()->text( + $this->lng->txt(self::LNG_TABLE_COL_DESCRIPTION) + )->withHighlight(true)->withIsSortable(true), + self::TABLE_COL_LAST_UPDATE => $this->ui->factory()->table()->column()->text( + $this->lng->txt(self::LNG_TABLE_COL_LAST_UPDATE) + )->withHighlight(true)->withIsSortable(true), + self::TABLE_COL_STATUS => $this->ui->factory()->table()->column()->text( + $this->lng->txt(self::LNG_TABLE_COL_STATUS) + )->withHighlight(true)->withIsSortable(true) + ]; + } + + final protected function getActions(): array + { + if (!$this->actions_permitted) { + return []; + } + $this->url_builder = new URLBuilder($this->data_factory->uri($this->http->request()->getUri()->__toString())); + list($this->url_builder, $this->action_parameter_token, $this->row_id_token) = + $this->url_builder->acquireParameters( + ['datatable', self::TABLE_ID], + self::TABLE_ACTION_ID, + self::ROW_ID + ); + return [ + self::ACTION_VALIDATE_DUPLICATES => $this->ui->factory()->table()->action()->single( + $this->lng->txt(self::LNG_ACTION_VALIDATE_DUPLICATES), + $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_VALIDATE_DUPLICATES), + $this->row_id_token + ), + self::ACTION_REPAIR_DUPLICATES => $this->ui->factory()->table()->action()->single( + $this->lng->txt(self::LNG_ACTION_REPAIR_DUPLICATES), + $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_REPAIR_DUPLICATES), + $this->row_id_token + ), + self::ACTION_SHOW_TREE => $this->ui->factory()->table()->action()->single( + $this->lng->txt(self::LNG_ACTION_SHOW_TREE), + $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_SHOW_TREE), + $this->row_id_token + ), + self::ACTION_LIST_TREE => $this->ui->factory()->table()->action()->single( + $this->lng->txt(self::LNG_ACTION_LIST_TREE), + $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_LIST_TREE), + $this->row_id_token + ), + self::ACTION_FIND_MISSING => $this->ui->factory()->table()->action()->single( + $this->lng->txt(self::LNG_ACTION_FIND_MISSING), + $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_FIND_MISSING), + $this->row_id_token + ), + self::ACTION_REPAIR_MISSING => $this->ui->factory()->table()->action()->single( + $this->lng->txt(self::LNG_ACTION_REPAIR_MISSING), + $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_REPAIR_MISSING), + $this->row_id_token + ), + self::ACTION_FIND_MISSING_TREE_ENTRIES => $this->ui->factory()->table()->action()->single( + $this->lng->txt(self::LNG_ACTION_FIND_MISSING_TREE_ENTRIES), + $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_FIND_MISSING_TREE_ENTRIES), + $this->row_id_token + ), + self::ACTION_REPAIR_MISSING_TREE_ENTRIES => $this->ui->factory()->table()->action()->single( + $this->lng->txt(self::LNG_ACTION_REPAIR_MISSING_TREE_ENTRIES), + $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_REPAIR_MISSING_TREE_ENTRIES), + $this->row_id_token + ), + self::ACTION_ANALYZE_STRUCTURE => $this->ui->factory()->table()->action()->single( + $this->lng->txt(self::LNG_ACTION_ANALYZE_STRUCTURE), + $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_ANALYZE_STRUCTURE), + $this->row_id_token + ), + self::ACTION_REPAIR_STRUCTURE => $this->ui->factory()->table()->action()->single( + $this->lng->txt(self::LNG_ACTION_REPAIR_STRUCTURE), + $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_REPAIR_STRUCTURE), + $this->row_id_token + ) + ]; + } + + final protected function getTable(): DataTable + { + if (!isset($this->table)) { + $this->table = $this->ui->factory()->table()->data( + $this->data_retrieval, + $this->lng->txt(self::LNG_TABLE_TITLE), + $this->getColumns(), + ) + ->withActions($this->getActions()) + ->withId(self::TABLE_ID)->withRequest($this->http->request()); + } + return $this->table; + } + + final public function getHTML(): string + { + return $this->ui->renderer()->render([$this->getTable()]); + } + + final public function handleTableActions(): void + { + $table = $this->getTable(); + } +} diff --git a/components/ILIAS/SystemCheck/classes/class.ilObjSystemCheckGUI.php b/components/ILIAS/SystemCheck/classes/class.ilObjSystemCheckGUI.php index 6d309cb30936..0d20af59b217 100755 --- a/components/ILIAS/SystemCheck/classes/class.ilObjSystemCheckGUI.php +++ b/components/ILIAS/SystemCheck/classes/class.ilObjSystemCheckGUI.php @@ -17,8 +17,10 @@ *********************************************************************/ declare(strict_types=1); -use ILIAS\HTTP\GlobalHttpState; -use ILIAS\Refinery\Factory; + +use ILIAS\Repository\ExternalGUIService; +use ILIAS\SystemCheck\I\Table\FactoryInterface as TableFactoryInterface; +use ILIAS\SystemCheck\Table\Factory as TableFactory; /** * @author Stefan Meyer @@ -27,9 +29,10 @@ */ class ilObjSystemCheckGUI extends ilObjectGUI { - protected const SECTION_MAIN = 'main'; - protected const SECTION_GROUP = 'group'; - protected \ILIAS\Repository\ExternalGUIService $repo_gui_service; + protected const string SECTION_MAIN = 'main'; + protected const string SECTION_GROUP = 'group'; + protected readonly ExternalGUIService $repo_gui_service; + protected readonly TableFactoryInterface $table_factory; public function __construct($a_data, $a_id, $a_call_by_reference, $a_prepare_output = true) { @@ -38,6 +41,7 @@ public function __construct($a_data, $a_id, $a_call_by_reference, $a_prepare_out parent::__construct($a_data, $a_id, $a_call_by_reference, $a_prepare_output); $this->lng->loadLanguageModule('sysc'); $this->repo_gui_service = $DIC->repository()->gui(); + $this->table_factory = new TableFactory(); } protected function getGrpIdFromRequest(): int @@ -88,7 +92,7 @@ public function executeCommand(): void case 'ilobjsystemfoldergui': - $sys_folder = new ilObjSystemFolderGUI('', SYSTEM_FOLDER_ID, true); + $sys_folder = new ilObjSystemFolderGUI(0, SYSTEM_FOLDER_ID, true); $this->ctrl->forwardCommand($sys_folder); $this->tabs_gui->clearTargets(); @@ -150,9 +154,7 @@ protected function overview(): bool $this->setSubTabs(self::SECTION_MAIN, 'overview'); $this->tabs_gui->activateTab('overview'); - $table = new ilSCGroupTableGUI($this, 'overview'); - $table->init(); - $table->parse(); + $table = $this->table_factory->group()->handler(); $this->tpl->setContent($table->getHTML()); return true; @@ -163,10 +165,11 @@ protected function showGroup(): bool $this->setSubTabs(self::SECTION_GROUP, ''); $this->ctrl->saveParameter($this, 'grp_id'); - - $table = new ilSCTaskTableGUI($this->getGrpIdFromRequest(), $this, 'showGroup'); - $table->init(); - $table->parse(); + $data_retrieval = $this->table_factory->task()->dataRetrieval($this->getGrpIdFromRequest()); + $table = $this->table_factory->task()->handler( + $data_retrieval, + $this->access->checkAccess('write', '', $this->getObject()->getRefId()) + ); $this->tpl->setContent($table->getHTML()); return true; diff --git a/components/ILIAS/SystemCheck/classes/class.ilSCGroupTableGUI.php b/components/ILIAS/SystemCheck/classes/class.ilSCGroupTableGUI.php deleted file mode 100755 index c366429b644d..000000000000 --- a/components/ILIAS/SystemCheck/classes/class.ilSCGroupTableGUI.php +++ /dev/null @@ -1,122 +0,0 @@ - - */ -class ilSCGroupTableGUI extends ilTable2GUI -{ - private UIRenderer $renderer; - private UIFactory $uiFactory; - - public function __construct(object $a_parent_obj, string $a_parent_cmd = '') - { - $this->setId('sc_groups'); - parent::__construct($a_parent_obj, $a_parent_cmd); - - global $DIC; - $this->renderer = $DIC->ui()->renderer(); - $this->uiFactory = $DIC->ui()->factory(); - } - - public function init(): void - { - $this->lng->loadLanguageModule('sysc'); - $this->addColumn($this->lng->txt('title'), 'title', '60%'); - $this->addColumn($this->lng->txt('last_update'), 'last_update_sort', '20%'); - $this->addColumn($this->lng->txt('sysc_completed_num'), 'completed', '10%'); - $this->addColumn($this->lng->txt('sysc_failed_num'), 'failed', '10%'); - $this->addColumn($this->lng->txt('actions'), '', '10%'); - - $this->setTitle($this->lng->txt('sysc_overview')); - - $this->setRowTemplate('tpl.syscheck_groups_row.html', 'components/ILIAS/SystemCheck'); - $this->setFormAction($this->ctrl->getFormAction($this->getParentObject())); - } - - protected function fillRow(array $a_set): void - { - $this->tpl->setVariable('VAL_TITLE', (string) ($a_set['title'] ?? '')); - - $id = (int) ($a_set['id'] ?? 0); - $this->ctrl->setParameter($this->getParentObject(), 'grp_id', $id); - $this->tpl->setVariable( - 'VAL_LINK', - $this->ctrl->getLinkTarget($this->getParentObject(), 'showGroup') - ); - - $this->tpl->setVariable('VAL_DESC', (string) ($a_set['description'] ?? '')); - $this->tpl->setVariable('VAL_LAST_UPDATE', (string) ($a_set['last_update'] ?? '')); - $this->tpl->setVariable('VAL_COMPLETED', (int) ($a_set['completed'] ?? 0)); - $this->tpl->setVariable('VAL_FAILED', (int) ($a_set['failed'] ?? 0)); - - switch ($a_set['status']) { - case ilSCTask::STATUS_COMPLETED: - $this->tpl->setVariable('STATUS_CLASS', 'smallgreen'); - break; - case ilSCTask::STATUS_FAILED: - $this->tpl->setVariable('STATUS_CLASS', 'warning'); - break; - } - - // Actions - $this->ctrl->setParameter($this->getParentObject(), 'grp_id', $id); - $dropDownItems = array( - $this->uiFactory->button()->shy( - $this->lng->txt('show'), - $this->ctrl->getLinkTarget($this->getParentObject(), 'showGroup') - ) - ); - $dropDown = $this->uiFactory->dropdown()->standard($dropDownItems) - ->withLabel($this->lng->txt('actions')); - - $this->tpl->setVariable('ACTIONS', $this->renderer->render($dropDown)); - } - - public function parse(): void - { - $data = array(); - - foreach (ilSCGroups::getInstance()->getGroups() as $group) { - $item = array(); - $item['id'] = $group->getId(); - - $task_gui = ilSCComponentTaskFactory::getComponentTaskGUIForGroup($group->getId()); - - $item['title'] = $task_gui->getGroupTitle(); - $item['description'] = $task_gui->getGroupDescription(); - $item['status'] = $group->getStatus(); - - $item['completed'] = ilSCTasks::lookupCompleted($group->getId()); - $item['failed'] = ilSCTasks::lookupFailed($group->getId()); - - $last_update = ilSCTasks::lookupLastUpdate($group->getId()); - $item['last_update'] = ilDatePresentation::formatDate($last_update); - $item['last_update_sort'] = $last_update->get(IL_CAL_UNIX); - $data[] = $item; - } - - $this->setData($data); - } -} diff --git a/components/ILIAS/SystemCheck/templates/default/tpl.syscheck_groups_row.html b/components/ILIAS/SystemCheck/templates/default/tpl.syscheck_groups_row.html deleted file mode 100755 index fead13445897..000000000000 --- a/components/ILIAS/SystemCheck/templates/default/tpl.syscheck_groups_row.html +++ /dev/null @@ -1,24 +0,0 @@ - - - {VAL_TITLE} - -
- {VAL_DESC} -
- - - - {VAL_LAST_UPDATE} - - - {VAL_COMPLETED} - - - {VAL_FAILED} - - -
- {ACTIONS} -
- - \ No newline at end of file From 8b7858baa6b3d56bb6cf2515c97fde62efaf9cf7 Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Tue, 6 Oct 2026 12:17:45 +0200 Subject: [PATCH 2/6] SystemCheck: wip table to kitchensink --- .../SystemCheck/classes/Table/Factory.php | 7 +++- .../classes/Table/Task/Factory.php | 6 ++++ .../classes/Table/Task/Handler.php | 32 +++++++++++++++++-- .../classes/class.ilObjSystemCheckGUI.php | 2 +- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/components/ILIAS/SystemCheck/classes/Table/Factory.php b/components/ILIAS/SystemCheck/classes/Table/Factory.php index fcd4c40f238c..4bfc5a070f4a 100644 --- a/components/ILIAS/SystemCheck/classes/Table/Factory.php +++ b/components/ILIAS/SystemCheck/classes/Table/Factory.php @@ -24,6 +24,7 @@ use ILIAS\Data\Factory as DataFactory; use ILIAS\DI\UIServices; use ILIAS\HTTP\Services as HTTPServices; +use ILIAS\Refinery\Factory as RefineryFactory; use ILIAS\SystemCheck\I\Table\FactoryInterface; use ILIAS\SystemCheck\I\Table\Group\FactoryInterface as GroupFactoryInterface; use ILIAS\SystemCheck\I\Table\Task\FactoryInterface as TaskFactoryInterface; @@ -38,6 +39,7 @@ protected ilLanguage $lng; protected HTTPServices $http; protected ilCtrl $ctrl; + protected RefineryFactory $refinery; public function __construct() { @@ -47,6 +49,7 @@ public function __construct() $this->lng = $DIC->language(); $this->http = $DIC->http(); $this->ctrl = $DIC->ctrl(); + $this->refinery = $DIC->refinery(); } final public function group(): GroupFactoryInterface @@ -66,7 +69,9 @@ final public function task(): TaskFactoryInterface $this->data_factory, $this->ui, $this->lng, - $this->http + $this->http, + $this->refinery, + $this->ctrl ); } } diff --git a/components/ILIAS/SystemCheck/classes/Table/Task/Factory.php b/components/ILIAS/SystemCheck/classes/Table/Task/Factory.php index 9463d3fd47c5..1e3c82671458 100644 --- a/components/ILIAS/SystemCheck/classes/Table/Task/Factory.php +++ b/components/ILIAS/SystemCheck/classes/Table/Task/Factory.php @@ -20,9 +20,11 @@ namespace ILIAS\SystemCheck\Table\Task; +use ilCtrl; use ILIAS\Data\Factory as DataFactory; use ILIAS\DI\UIServices; use ILIAS\HTTP\Services as HTTPServices; +use ILIAS\Refinery\Factory as RefineryFactory; use ILIAS\SystemCheck\I\Table\Task\DataRetrievalInterface; use ILIAS\SystemCheck\I\Table\Task\FactoryInterface; use ILIAS\SystemCheck\I\Table\Task\HandlerInterface; @@ -35,6 +37,8 @@ public function __construct( protected UIServices $ui, protected ilLanguage $lng, protected HTTPServices $http, + protected RefineryFactory $refinery, + protected ilCtrl $ctrl ) { } @@ -48,6 +52,8 @@ final public function handler( $this->lng, $this->http, $data_retrieval, + $this->refinery, + $this->ctrl, $actions_permitted ); } diff --git a/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php b/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php index a28c9a9015f3..47bad287d3c6 100644 --- a/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php +++ b/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php @@ -20,6 +20,7 @@ namespace ILIAS\SystemCheck\Table\Task; +use ilCtrl; use ILIAS\Data\Factory as DataFactory; use ILIAS\DI\UIServices; use ILIAS\HTTP\Services as HTTPServices; @@ -29,6 +30,8 @@ use ILIAS\UI\URLBuilder; use ILIAS\UI\URLBuilderToken as ilURLBuilderToken; use ilLanguage; +use ILIAS\Refinery\Factory as RefineryFactory; +use ilSCComponentTaskFactory; class Handler implements HandlerInterface { @@ -76,8 +79,11 @@ public function __construct( protected readonly ilLanguage $lng, protected readonly HTTPServices $http, protected readonly DataRetrievalInterface $data_retrieval, + protected readonly RefineryFactory $refinery, + protected readonly ilCtrl $ctrl, protected readonly bool $actions_permitted = false ) { + $this->initTable(); } final protected function getColumns(): array @@ -164,7 +170,7 @@ final protected function getActions(): array ]; } - final protected function getTable(): DataTable + final protected function initTable(): void { if (!isset($this->table)) { $this->table = $this->ui->factory()->table()->data( @@ -175,6 +181,10 @@ final protected function getTable(): DataTable ->withActions($this->getActions()) ->withId(self::TABLE_ID)->withRequest($this->http->request()); } + } + + final protected function getTable(): DataTable + { return $this->table; } @@ -185,6 +195,24 @@ final public function getHTML(): string final public function handleTableActions(): void { - $table = $this->getTable(); + if (!$this->http->wrapper()->query()->has($this->action_parameter_token->getName())) { + return; + } + if (!$this->actions_permitted) { + return; + } + $action = $this->http->wrapper()->query()->retrieve( + $this->action_parameter_token->getName(), + $this->refinery->to()->string() + ); + $tokens = $this->http->wrapper()->query()->retrieve( + $this->row_id_token->getName(), + $this->refinery->custom()->transformation(fn($v) => $v) + ); + $task_id = (int) $tokens[0]; + $task_handler = ilSCComponentTaskFactory::getComponentTask($task_id); + $this->ctrl->setParameterByClass(get_class($task_handler), 'task_id', $task_id); + $this->ctrl->redirectByClass(get_class($task_handler), $action); + $this->ctrl->clearParameterByClass(get_class($task_handler), 'task_id'); } } diff --git a/components/ILIAS/SystemCheck/classes/class.ilObjSystemCheckGUI.php b/components/ILIAS/SystemCheck/classes/class.ilObjSystemCheckGUI.php index 0d20af59b217..7a6ba692f61c 100755 --- a/components/ILIAS/SystemCheck/classes/class.ilObjSystemCheckGUI.php +++ b/components/ILIAS/SystemCheck/classes/class.ilObjSystemCheckGUI.php @@ -170,7 +170,7 @@ protected function showGroup(): bool $data_retrieval, $this->access->checkAccess('write', '', $this->getObject()->getRefId()) ); - + $table->handleTableActions(); $this->tpl->setContent($table->getHTML()); return true; } From 048f6016147d8c0ceda0f2f9982d28ab700f2d21 Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Tue, 6 Oct 2026 12:19:25 +0200 Subject: [PATCH 3/6] SystemCheck: wip table to kitchensink --- .../classes/class.ilSCTaskTableGUI.php | 140 ------------------ .../default/tpl.syscheck_tasks_row.html | 29 ---- 2 files changed, 169 deletions(-) delete mode 100755 components/ILIAS/SystemCheck/classes/class.ilSCTaskTableGUI.php delete mode 100755 components/ILIAS/SystemCheck/templates/default/tpl.syscheck_tasks_row.html diff --git a/components/ILIAS/SystemCheck/classes/class.ilSCTaskTableGUI.php b/components/ILIAS/SystemCheck/classes/class.ilSCTaskTableGUI.php deleted file mode 100755 index 2bb6ef33a9f2..000000000000 --- a/components/ILIAS/SystemCheck/classes/class.ilSCTaskTableGUI.php +++ /dev/null @@ -1,140 +0,0 @@ - - */ -class ilSCTaskTableGUI extends ilTable2GUI -{ - private int $group_id = 0; - - private ilAccess $access; - private UIRenderer $renderer; - private UIFactory $uiFactory; - - public function __construct(int $a_group_id, object $a_parent_obj, string $a_parent_cmd = '') - { - global $DIC; - $this->group_id = $a_group_id; - $this->setId('sc_groups'); - $this->access = $DIC->access(); - parent::__construct($a_parent_obj, $a_parent_cmd); - - $this->renderer = $DIC->ui()->renderer(); - $this->uiFactory = $DIC->ui()->factory(); - } - - public function getGroupId(): int - { - return $this->group_id; - } - - public function init(): void - { - $this->lng->loadLanguageModule('sysc'); - $this->addColumn($this->lng->txt('title'), 'title', '60%'); - $this->addColumn($this->lng->txt('last_update'), 'last_update_sort', '20%'); - $this->addColumn($this->lng->txt('status'), 'status', '10%'); - $this->addColumn($this->lng->txt('actions'), '', '10%'); - - $this->setTitle($this->lng->txt('sysc_task_overview')); - - $this->setRowTemplate('tpl.syscheck_tasks_row.html', 'components/ILIAS/SystemCheck'); - $this->setFormAction($this->ctrl->getFormAction($this->getParentObject())); - } - - /** - * @param array $a_set - */ - protected function fillRow(array $a_set): void - { - $this->tpl->setVariable('VAL_TITLE', (string) ($a_set['title'] ?? '')); - $this->tpl->setVariable('VAL_DESC', (string) ($a_set['description'] ?? '')); - - $status = (int) ($a_set['status'] ?? 0); - $text = ilSCUtils::taskStatus2Text($status); - switch ($status) { - case ilSCTask::STATUS_COMPLETED: - $this->tpl->setVariable('VAL_STATUS_SUCCESS', $text); - break; - - case ilSCTask::STATUS_FAILED: - $this->tpl->setCurrentBlock('warning'); - $this->tpl->setVariable('VAL_STATUS_WARNING', $text); - $this->tpl->parseCurrentBlock(); - break; - - default: - $this->tpl->setVariable('VAL_STATUS_STANDARD', $text); - break; - } - - $this->tpl->setVariable('VAL_LAST_UPDATE', (string) ($a_set['last_update'] ?? '')); - - // Actions - if ($this->access->checkAccess('write', '', $this->parent_obj->getObject()->getRefId())) { - $id = (int) ($a_set['id'] ?? 0); - - $dropDownItems = array(); - - $task_handler = ilSCComponentTaskFactory::getComponentTask($id); - - $this->ctrl->setParameterByClass(get_class($task_handler), 'task_id', $id); - foreach ($task_handler->getActions() as $actions) { - $dropDownItems[] = $this->uiFactory->button()->shy( - (string) ($actions['txt'] ?? ''), - $this->ctrl->getLinkTargetByClass(get_class($task_handler), (string) ($actions['command'] ?? '')) - ); - } - $dropDown = $this->uiFactory->dropdown()->standard($dropDownItems) - ->withLabel($this->lng->txt('actions')); - $this->tpl->setVariable('ACTIONS', $this->renderer->render($dropDown)); - } - } - - public function parse(): void - { - $data = array(); - - foreach (ilSCTasks::getInstanceByGroupId($this->getGroupId())->getTasks() as $task) { - $task_handler = ilSCComponentTaskFactory::getComponentTask($task->getId()); - - if (!$task->isActive()) { - continue; - } - - $item = array(); - $item['id'] = $task->getId(); - $item['title'] = $task_handler->getTitle(); - $item['description'] = $task_handler->getDescription(); - $item['last_update'] = ilDatePresentation::formatDate($task->getLastUpdate()); - $item['last_update_sort'] = $task->getLastUpdate()->get(IL_CAL_UNIX); - $item['status'] = $task->getStatus(); - - $data[] = $item; - } - - $this->setData($data); - } -} diff --git a/components/ILIAS/SystemCheck/templates/default/tpl.syscheck_tasks_row.html b/components/ILIAS/SystemCheck/templates/default/tpl.syscheck_tasks_row.html deleted file mode 100755 index 5b61e87f2485..000000000000 --- a/components/ILIAS/SystemCheck/templates/default/tpl.syscheck_tasks_row.html +++ /dev/null @@ -1,29 +0,0 @@ - - - {VAL_TITLE} - -
- {VAL_DESC} -
- - - - {VAL_LAST_UPDATE} - - - - {VAL_STATUS_WARNING} - - - {VAL_STATUS_SUCCESS} - - - {VAL_STATUS_STANDARD} - - - -
- {ACTIONS} -
- - \ No newline at end of file From bfbf23f63ce204b5b216c35b415ce3cbf9791a75 Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Wed, 7 Oct 2026 16:50:23 +0200 Subject: [PATCH 4/6] fix structure --- .../I/Table/Task/DataRetrievalInterface.php | 7 +- .../classes/Table/Task/DataRetrieval.php | 45 ++++++----- .../classes/Table/Task/Handler.php | 81 +++---------------- 3 files changed, 39 insertions(+), 94 deletions(-) diff --git a/components/ILIAS/SystemCheck/classes/I/Table/Task/DataRetrievalInterface.php b/components/ILIAS/SystemCheck/classes/I/Table/Task/DataRetrievalInterface.php index 9f049a5ccb06..4c8896800ca9 100644 --- a/components/ILIAS/SystemCheck/classes/I/Table/Task/DataRetrievalInterface.php +++ b/components/ILIAS/SystemCheck/classes/I/Table/Task/DataRetrievalInterface.php @@ -25,8 +25,9 @@ interface DataRetrievalInterface extends DataRetrieval { - /** - * @return ilSCTask[] - */ + /** @return ilSCTask[] */ public function getSCTasks(): array; + + /** @return array */ + public function getAllActions(): array; } diff --git a/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php b/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php index 194303fba318..3a7190a1224b 100644 --- a/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php +++ b/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php @@ -45,6 +45,8 @@ class DataRetrieval implements DataRetrievalInterface protected array $last_updates; /** @var int[] */ protected array $status; + /** @var string[] */ + protected array $actions; public function __construct( protected readonly int $group_id @@ -124,20 +126,7 @@ final public function getRows( Handler::TABLE_COL_STATUS => ilSCUtils::taskStatus2Text($status[$sc_task->getId()]) ] ); - $inactive_actions = $this->getInactiveActions( - $sc_task, - Handler::ACTION_VALIDATE_DUPLICATES, - Handler::ACTION_REPAIR_DUPLICATES, - Handler::ACTION_SHOW_TREE, - Handler::ACTION_LIST_TREE, - Handler::ACTION_FIND_MISSING, - Handler::ACTION_REPAIR_MISSING, - Handler::ACTION_FIND_MISSING_TREE_ENTRIES, - Handler::ACTION_REPAIR_MISSING_TREE_ENTRIES, - Handler::ACTION_ANALYZE_STRUCTURE, - Handler::ACTION_REPAIR_STRUCTURE - ); - foreach ($inactive_actions as $action_name) { + foreach ($this->getInactiveActions($sc_task) as $action_name) { $data_row = $data_row->withDisabledAction($action_name); } yield $data_row; @@ -152,12 +141,30 @@ final public function getTotalRowCount( return count($this->getSCTasks()); } + /** @return array */ + final public function getAllActions(): array + { + if (isset($this->actions)) { + return $this->actions; + } + $this->actions = []; + foreach ($this->getSCTasks() as $task) { + $task_gui = ilSCComponentTaskFactory::getComponentTask($task->getId()); + foreach ($task_gui->getActions() as $action) { + $this->actions[$action['command']] = $action['txt']; + } + } + return $this->actions; + } + final protected function getInactiveActions( - ilSCTask $task, - string ...$all_actions + ilSCTask $task ): array { - $task_gui = new ilSCTreeTasksGUI($task); - $active_actions = array_map(fn($action) => $action['command'], $task_gui->getActions()); - return array_diff($all_actions, $active_actions); + $active_actions = []; + $task_gui = ilSCComponentTaskFactory::getComponentTask($task->getId()); + foreach ($task_gui->getActions() as $action) { + $active_actions[$action['command']] = $action['txt']; + } + return array_diff(array_keys($this->getAllActions()), array_keys($active_actions)); } } diff --git a/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php b/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php index 47bad287d3c6..71b8372137f0 100644 --- a/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php +++ b/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php @@ -47,26 +47,6 @@ class Handler implements HandlerInterface protected const string LNG_TABLE_COL_DESCRIPTION = 'description'; protected const string LNG_TABLE_COL_LAST_UPDATE = 'last_update'; protected const string LNG_TABLE_COL_STATUS = 'status'; - public const string ACTION_VALIDATE_DUPLICATES = 'validateDuplicates'; - public const string ACTION_REPAIR_DUPLICATES = 'repairDuplicates'; - public const string ACTION_SHOW_TREE = 'showTree'; - public const string ACTION_LIST_TREE = 'listTree'; - public const string ACTION_FIND_MISSING = 'findMissing'; - public const string ACTION_REPAIR_MISSING = 'confirmRepairMissing'; - public const string ACTION_FIND_MISSING_TREE_ENTRIES = 'findMissingTreeEntries'; - public const string ACTION_REPAIR_MISSING_TREE_ENTRIES = 'confirmRepairMissingTreeEntries'; - public const string ACTION_ANALYZE_STRUCTURE = 'analyzeStructure'; - public const string ACTION_REPAIR_STRUCTURE = 'confirmRepairStructure'; - protected const string LNG_ACTION_VALIDATE_DUPLICATES = 'sysc_action_validate'; - protected const string LNG_ACTION_REPAIR_DUPLICATES = 'sysc_action_repair'; - protected const string LNG_ACTION_SHOW_TREE = 'sysc_action_show_tree'; - protected const string LNG_ACTION_LIST_TREE = 'sysc_action_list_tree'; - protected const string LNG_ACTION_FIND_MISSING = 'sysc_action_validate'; - protected const string LNG_ACTION_REPAIR_MISSING = 'sysc_action_repair'; - protected const string LNG_ACTION_FIND_MISSING_TREE_ENTRIES = 'sysc_action_validate'; - protected const string LNG_ACTION_REPAIR_MISSING_TREE_ENTRIES = 'sysc_action_repair'; - protected const string LNG_ACTION_ANALYZE_STRUCTURE = 'sysc_action_validate'; - protected const string LNG_ACTION_REPAIR_STRUCTURE = 'sysc_action_repair'; protected DataTable $table; protected URLBuilder $url_builder; @@ -116,58 +96,15 @@ final protected function getActions(): array self::TABLE_ACTION_ID, self::ROW_ID ); - return [ - self::ACTION_VALIDATE_DUPLICATES => $this->ui->factory()->table()->action()->single( - $this->lng->txt(self::LNG_ACTION_VALIDATE_DUPLICATES), - $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_VALIDATE_DUPLICATES), - $this->row_id_token - ), - self::ACTION_REPAIR_DUPLICATES => $this->ui->factory()->table()->action()->single( - $this->lng->txt(self::LNG_ACTION_REPAIR_DUPLICATES), - $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_REPAIR_DUPLICATES), - $this->row_id_token - ), - self::ACTION_SHOW_TREE => $this->ui->factory()->table()->action()->single( - $this->lng->txt(self::LNG_ACTION_SHOW_TREE), - $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_SHOW_TREE), - $this->row_id_token - ), - self::ACTION_LIST_TREE => $this->ui->factory()->table()->action()->single( - $this->lng->txt(self::LNG_ACTION_LIST_TREE), - $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_LIST_TREE), - $this->row_id_token - ), - self::ACTION_FIND_MISSING => $this->ui->factory()->table()->action()->single( - $this->lng->txt(self::LNG_ACTION_FIND_MISSING), - $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_FIND_MISSING), - $this->row_id_token - ), - self::ACTION_REPAIR_MISSING => $this->ui->factory()->table()->action()->single( - $this->lng->txt(self::LNG_ACTION_REPAIR_MISSING), - $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_REPAIR_MISSING), - $this->row_id_token - ), - self::ACTION_FIND_MISSING_TREE_ENTRIES => $this->ui->factory()->table()->action()->single( - $this->lng->txt(self::LNG_ACTION_FIND_MISSING_TREE_ENTRIES), - $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_FIND_MISSING_TREE_ENTRIES), + $actions = []; + foreach ($this->data_retrieval->getAllActions() as $command => $txt) { + $actions[$command] = $this->ui->factory()->table()->action()->single( + $txt, + $this->url_builder->withParameter($this->action_parameter_token, $command), $this->row_id_token - ), - self::ACTION_REPAIR_MISSING_TREE_ENTRIES => $this->ui->factory()->table()->action()->single( - $this->lng->txt(self::LNG_ACTION_REPAIR_MISSING_TREE_ENTRIES), - $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_REPAIR_MISSING_TREE_ENTRIES), - $this->row_id_token - ), - self::ACTION_ANALYZE_STRUCTURE => $this->ui->factory()->table()->action()->single( - $this->lng->txt(self::LNG_ACTION_ANALYZE_STRUCTURE), - $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_ANALYZE_STRUCTURE), - $this->row_id_token - ), - self::ACTION_REPAIR_STRUCTURE => $this->ui->factory()->table()->action()->single( - $this->lng->txt(self::LNG_ACTION_REPAIR_STRUCTURE), - $this->url_builder->withParameter($this->action_parameter_token, self::ACTION_REPAIR_STRUCTURE), - $this->row_id_token - ) - ]; + ); + } + return $actions; } final protected function initTable(): void @@ -207,7 +144,7 @@ final public function handleTableActions(): void ); $tokens = $this->http->wrapper()->query()->retrieve( $this->row_id_token->getName(), - $this->refinery->custom()->transformation(fn($v) => $v) + $this->refinery->kindlyTo()->listOf($this->refinery->to()->int()) ); $task_id = (int) $tokens[0]; $task_handler = ilSCComponentTaskFactory::getComponentTask($task_id); From 772457bb57cdf99f2044baad7b73b05b74eede4f Mon Sep 17 00:00:00 2001 From: Christoph Ludolf Date: Wed, 7 Oct 2026 18:40:53 +0200 Subject: [PATCH 5/6] SystemCheck: table, remove unused highlights --- .../ILIAS/SystemCheck/classes/Table/Task/Handler.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php b/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php index 71b8372137f0..7432ad86a8e8 100644 --- a/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php +++ b/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php @@ -71,16 +71,16 @@ final protected function getColumns(): array return [ self::TABLE_COL_TITLE => $this->ui->factory()->table()->column()->text( $this->lng->txt(self::LNG_TABLE_COL_TITLE) - )->withHighlight(true)->withIsSortable(true), + )->withIsSortable(true), self::TABLE_COL_DESCRIPTION => $this->ui->factory()->table()->column()->text( $this->lng->txt(self::LNG_TABLE_COL_DESCRIPTION) - )->withHighlight(true)->withIsSortable(true), + )->withIsSortable(true), self::TABLE_COL_LAST_UPDATE => $this->ui->factory()->table()->column()->text( $this->lng->txt(self::LNG_TABLE_COL_LAST_UPDATE) - )->withHighlight(true)->withIsSortable(true), + )->withIsSortable(true), self::TABLE_COL_STATUS => $this->ui->factory()->table()->column()->text( $this->lng->txt(self::LNG_TABLE_COL_STATUS) - )->withHighlight(true)->withIsSortable(true) + )->withIsSortable(true) ]; } From b89df2030f53d71eb2c9683765d9c08328642f2a Mon Sep 17 00:00:00 2001 From: Tim Schmitz Date: Thu, 8 Oct 2026 15:31:59 +0200 Subject: [PATCH 6/6] small fix, a bit of cleanup --- .../classes/Table/Group/DataRetrieval.php | 39 ++++++------------- .../classes/Table/Group/Handler.php | 11 +++--- .../classes/Table/Task/DataRetrieval.php | 30 +++++--------- .../classes/Table/Task/Handler.php | 7 +++- 4 files changed, 32 insertions(+), 55 deletions(-) diff --git a/components/ILIAS/SystemCheck/classes/Table/Group/DataRetrieval.php b/components/ILIAS/SystemCheck/classes/Table/Group/DataRetrieval.php index 610d70486371..6ffe87bbd0c7 100644 --- a/components/ILIAS/SystemCheck/classes/Table/Group/DataRetrieval.php +++ b/components/ILIAS/SystemCheck/classes/Table/Group/DataRetrieval.php @@ -39,16 +39,6 @@ class DataRetrieval implements DataRetrievalInterface { /* @var ilSCGroup[] */ protected array $groups; - /* @var string[] */ - protected array $titles; - /* @var string[] */ - protected array $descriptions; - /* @var int[] */ - protected array $complete; - /* @var int[] */ - protected array $failed; - /* @var ilDateTime[] */ - protected array $last_updates; public function __construct( protected readonly UIServices $ui, @@ -61,18 +51,7 @@ public function __construct( */ final protected function getSCGroups(): array { - if (!isset($this->groups)) { - $this->groups = ilSCGroups::getInstance()->getGroups(); - } - foreach ($this->groups as $group) { - $task_gui = ilSCComponentTaskFactory::getComponentTaskGUIForGroup($group->getId()); - $this->titles[$group->getId()] = $task_gui->getGroupTitle(); - $this->descriptions[$group->getId()] = $task_gui->getGroupDescription(); - $this->complete[$group->getId()] = ilSCTasks::lookupCompleted($group->getId()); - $this->failed[$group->getId()] = ilSCTasks::lookupFailed($group->getId()); - $this->last_updates[$group->getId()] = ilSCTasks::lookupLastUpdate($group->getId()); - } - return $this->groups; + return $this->groups ??= ilSCGroups::getInstance()->getGroups(); } final public function getRows( @@ -85,11 +64,15 @@ final public function getRows( mixed $additional_parameters ): Generator { [$column_name, $direction] = $order->join([], fn($ret, $key, $value) => [$key, $value]); - $titles = $this->titles; - $descriptions = $this->descriptions; - $last_updates = $this->last_updates; - $complete = $this->complete; - $failed = $this->failed; + $titles = $descriptions = $last_updates = $complete = $failed = []; + foreach ($this->getSCGroups() as $group) { + $task_gui = ilSCComponentTaskFactory::getComponentTaskGUIForGroup($group->getId()); + $titles[$group->getId()] = $task_gui->getGroupTitle(); + $descriptions[$group->getId()] = $task_gui->getGroupDescription(); + $complete[$group->getId()] = ilSCTasks::lookupCompleted($group->getId()); + $failed[$group->getId()] = ilSCTasks::lookupFailed($group->getId()); + $last_updates[$group->getId()] = ilSCTasks::lookupLastUpdate($group->getId()); + } $comparator = match ($column_name) { Handler::TABLE_COL_TITLE => function (ilSCGroup $f1, ilSCGroup $f2) use ($titles) { return strcasecmp($titles[$f1->getId()], $titles[$f2->getId()]); @@ -126,7 +109,7 @@ final public function getRows( [ Handler::TABLE_COL_TITLE => $this->ui->factory()->link()->standard($titles[$sc_group->getId()], $link), Handler::TABLE_COL_DESCRIPTION => $descriptions[$sc_group->getId()], - Handler::TABLE_COL_LAST_UPDATE => ilDatePresentation::formatDate($this->last_updates[$sc_group->getId()]), + Handler::TABLE_COL_LAST_UPDATE => ilDatePresentation::formatDate($last_updates[$sc_group->getId()]), Handler::TABLE_COL_SOLVED_TASKS => $complete[$sc_group->getId()], Handler::TABLE_COL_UNSOLVED_TASKS => $failed[$sc_group->getId()], ] diff --git a/components/ILIAS/SystemCheck/classes/Table/Group/Handler.php b/components/ILIAS/SystemCheck/classes/Table/Group/Handler.php index 5c7b7d95343b..b89626336ff7 100644 --- a/components/ILIAS/SystemCheck/classes/Table/Group/Handler.php +++ b/components/ILIAS/SystemCheck/classes/Table/Group/Handler.php @@ -42,6 +42,7 @@ protected const string LNG_TABLE_COL_SOLVED_TASKS = 'sysc_completed_num'; protected const string LNG_TABLE_COL_UNSOLVED_TASKS = 'sysc_failed_num'; protected const string LNG_TABLE_TITLE = 'sysc_overview'; + protected DataTable $table; public function __construct( @@ -58,19 +59,19 @@ final protected function getColumns(): array return [ self::TABLE_COL_TITLE => $this->ui->factory()->table()->column()->link( $this->lng->txt(self::LNG_TABLE_COL_TITLE) - )->withHighlight(true)->withIsSortable(true), + )->withIsSortable(true), self::TABLE_COL_DESCRIPTION => $this->ui->factory()->table()->column()->text( $this->lng->txt(self::LNG_TABLE_COL_DESCRIPTION) - )->withHighlight(true)->withIsSortable(true), + )->withIsSortable(true), self::TABLE_COL_LAST_UPDATE => $this->ui->factory()->table()->column()->text( $this->lng->txt(self::LNG_TABLE_COL_LAST_UPDATE) - )->withHighlight(true)->withIsSortable(true), + )->withIsSortable(true), self::TABLE_COL_SOLVED_TASKS => $this->ui->factory()->table()->column()->number( $this->lng->txt(self::LNG_TABLE_COL_SOLVED_TASKS) - )->withHighlight(true)->withIsSortable(true), + )->withIsSortable(true), self::TABLE_COL_UNSOLVED_TASKS => $this->ui->factory()->table()->column()->number( $this->lng->txt(self::LNG_TABLE_COL_UNSOLVED_TASKS) - )->withHighlight(true)->withIsSortable(true) + )->withIsSortable(true) ]; } diff --git a/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php b/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php index 3a7190a1224b..b820ecc283f8 100644 --- a/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php +++ b/components/ILIAS/SystemCheck/classes/Table/Task/DataRetrieval.php @@ -38,14 +38,6 @@ class DataRetrieval implements DataRetrievalInterface /** @var ilSCTask[] */ protected array $sc_tasks; /** @var string[] */ - protected array $titles; - /** @var string[] */ - protected array $descriptions; - /** @var ilDateTime[] */ - protected array $last_updates; - /** @var int[] */ - protected array $status; - /** @var string[] */ protected array $actions; public function __construct( @@ -63,17 +55,11 @@ final public function getSCTasks(): array } $this->sc_tasks = []; - foreach (ilSCTasks::getInstanceByGroupId($this->group_id)->getTasks() as $task) { if (!$task->isActive()) { continue; } - $task_handler = ilSCComponentTaskFactory::getComponentTask($task->getId()); $this->sc_tasks[$task->getId()] = $task; - $this->titles[$task->getId()] = $task_handler->getTitle(); - $this->descriptions[$task->getId()] = $task_handler->getDescription(); - $this->last_updates[$task->getId()] = $task->getLastUpdate(); - $this->status[$task->getId()] = $task->getStatus(); } return $this->sc_tasks; } @@ -88,10 +74,14 @@ final public function getRows( mixed $additional_parameters ): Generator { [$column_name, $direction] = $order->join([], fn($ret, $key, $value) => [$key, $value]); - $titles = $this->titles; - $descriptions = $this->descriptions; - $last_updates = $this->last_updates; - $status = $this->status; + $titles = $descriptions = $last_updates = $status = []; + foreach ($this->getSCTasks() as $task) { + $task_handler = ilSCComponentTaskFactory::getComponentTask($task->getId()); + $titles[$task->getId()] = $task_handler->getTitle(); + $descriptions[$task->getId()] = $task_handler->getDescription(); + $last_updates[$task->getId()] = $task->getLastUpdate(); + $status[$task->getId()] = $task->getStatus(); + } $comparator = match ($column_name) { Handler::TABLE_COL_TITLE => function (ilSCTask $f1, ilSCTask $f2) use ($titles) { return strcasecmp($titles[$f1->getId()], $titles[$f2->getId()]); @@ -118,11 +108,11 @@ final public function getRows( $sc_tasks = array_slice($sc_tasks, $range->getStart(), $range->getLength(), true); foreach ($sc_tasks as $sc_task) { $data_row = $row_builder->buildDataRow( - $sc_task->getId() . '', + (string) $sc_task->getId(), [ Handler::TABLE_COL_TITLE => $titles[$sc_task->getId()], Handler::TABLE_COL_DESCRIPTION => $descriptions[$sc_task->getId()], - Handler::TABLE_COL_LAST_UPDATE => ilDatePresentation::formatDate($this->last_updates[$sc_task->getId()]), + Handler::TABLE_COL_LAST_UPDATE => ilDatePresentation::formatDate($last_updates[$sc_task->getId()]), Handler::TABLE_COL_STATUS => ilSCUtils::taskStatus2Text($status[$sc_task->getId()]) ] ); diff --git a/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php b/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php index 7432ad86a8e8..c4ec2186470a 100644 --- a/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php +++ b/components/ILIAS/SystemCheck/classes/Table/Task/Handler.php @@ -135,16 +135,19 @@ final public function handleTableActions(): void if (!$this->http->wrapper()->query()->has($this->action_parameter_token->getName())) { return; } + if (!$this->http->wrapper()->query()->has($this->row_id_token->getName())) { + return; + } if (!$this->actions_permitted) { return; } $action = $this->http->wrapper()->query()->retrieve( $this->action_parameter_token->getName(), - $this->refinery->to()->string() + $this->refinery->kindlyTo()->string() ); $tokens = $this->http->wrapper()->query()->retrieve( $this->row_id_token->getName(), - $this->refinery->kindlyTo()->listOf($this->refinery->to()->int()) + $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int()) ); $task_id = (int) $tokens[0]; $task_handler = ilSCComponentTaskFactory::getComponentTask($task_id);