diff --git a/components/ILIAS/Membership/classes/Export/Table/DataRetrieval.php b/components/ILIAS/Membership/classes/Export/Table/DataRetrieval.php new file mode 100644 index 000000000000..9de0f1a44560 --- /dev/null +++ b/components/ILIAS/Membership/classes/Export/Table/DataRetrieval.php @@ -0,0 +1,115 @@ +fss_export = $fss_export; + $this->lng = $lng; + } + + 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 { + $data = $this->getRawData(); + + $order_field = array_keys($order->get())[0] ?? TableBuilder::COL_DATE; + $order_direction = $order->get()[$order_field] ?? Order::DESC; + + uasort($data, function ($a, $b) use ($order_field) { + if ($order_field === TableBuilder::COL_SIZE || $order_field === TableBuilder::COL_DATE) { + return $a[$order_field] <=> $b[$order_field]; + } + return strnatcasecmp((string) $a[$order_field], (string) $b[$order_field]); + }); + + if ($order_direction === Order::DESC) { + $data = array_reverse($data, true); + } + + $data = array_slice($data, $range->getStart(), $range->getLength() ?? 50, true); + + foreach ($data as $id => $row) { + $row_copy = $row; + $row_copy[TableBuilder::COL_SIZE] = ilUtil::formatSize((int) $row[TableBuilder::COL_SIZE]); + $row_copy[TableBuilder::COL_DATE] = new DateTimeImmutable('@' . $row[TableBuilder::COL_DATE]); + + yield $row_builder->buildDataRow((string) $id, $row_copy); + } + } + + public function getTotalRowCount( + mixed $additional_viewcontrol_data, + mixed $filter_data, + mixed $additional_parameters + ): ?int { + return count($this->getRawData()); + } + + public function getAllIDs(): array + { + return array_keys($this->getRawData()); + } + + protected function getRawData(): array + { + if ($this->raw_data !== null) { + return $this->raw_data; + } + $data = []; + foreach ($this->fss_export->getMemberExportFiles() as $exp_file) { + $id = md5($exp_file['name']); + $data[$id] = [ + TableBuilder::COL_ID => $id, + TableBuilder::COL_NAME => $exp_file['name'], + TableBuilder::COL_TYPE => strtoupper((string) $exp_file["type"]), + TableBuilder::COL_DATE => $exp_file['timest'], + TableBuilder::COL_SIZE => $exp_file['size'] + ]; + } + return $this->raw_data = $data; + } +} diff --git a/components/ILIAS/Membership/classes/Export/Table/TableBuilder.php b/components/ILIAS/Membership/classes/Export/Table/TableBuilder.php new file mode 100644 index 000000000000..ff41b34c6bbb --- /dev/null +++ b/components/ILIAS/Membership/classes/Export/Table/TableBuilder.php @@ -0,0 +1,96 @@ +user->getDateFormat(); + if ($this->user->getTimeFormat() == ilCalendarSettings::TIME_FORMAT_24) { + $date_format = $this->data_factory->dateFormat()->withTime24($date_format); + } else { + $date_format = $this->data_factory->dateFormat()->withTime12($date_format); + } + + $columns = []; + $columns[self::COL_TYPE] = $this->ui_factory->table()->column()->text( + $this->lng->txt('type') + )->withIsSortable(true); + $columns[self::COL_SIZE] = $this->ui_factory->table()->column()->text( + $this->lng->txt('ps_size') + )->withIsSortable(true); + $columns[self::COL_DATE] = $this->ui_factory->table()->column()->date( + $this->lng->txt('date'), + $date_format + )->withIsSortable(true); + + $actions = []; + $actions[self::ACTION_DOWNLOAD] = $this->ui_factory->table()->action()->single( + $this->lng->txt('download'), + $url_builder->withParameter($action_token, self::ACTION_DOWNLOAD), + $id_token + ); + $actions[self::ACTION_DELETE] = $this->ui_factory->table()->action()->standard( + $this->lng->txt('delete'), + $url_builder->withParameter($action_token, self::ACTION_DELETE), + $id_token + ); + + return $this->ui_factory->table()->data( + $this->data_retrieval, + $this->lng->txt('ps_export_files'), + $columns + )->withActions($actions)->withRequest($this->http->request()); + } +} diff --git a/components/ILIAS/Membership/classes/Export/class.ilMemberExportFileTableGUI.php b/components/ILIAS/Membership/classes/Export/class.ilMemberExportFileTableGUI.php deleted file mode 100755 index 9320d9125cc9..000000000000 --- a/components/ILIAS/Membership/classes/Export/class.ilMemberExportFileTableGUI.php +++ /dev/null @@ -1,91 +0,0 @@ - - */ -class ilMemberExportFileTableGUI extends ilTable2GUI -{ - public function __construct(object $a_parent_obj, string $a_parent_cmd, ilFileSystemAbstractionStorage $a_fss_export) - { - $this->setId('memexp'); - parent::__construct($a_parent_obj, $a_parent_cmd); - - $this->setTitle($this->lng->txt('ps_export_files')); - $this->addColumn('', '', '1'); - $this->addColumn($this->lng->txt('type'), 'type'); - $this->addColumn($this->lng->txt('ps_size'), 'size'); - $this->addColumn($this->lng->txt('date'), 'date'); - $this->addColumn($this->lng->txt('action'), ''); - - $this->setDefaultOrderField('date'); - $this->setDefaultOrderDirection('desc'); - - $this->setRowTemplate('tpl.mem_export_file_row.html', 'components/ILIAS/Membership'); - $this->setFormAction($this->ctrl->getFormAction($this->getParentObject(), $this->getParentCmd())); - $this->addMultiCommand('confirmDeleteExportFile', $this->lng->txt('delete')); - $this->setSelectAllCheckbox('id[]'); - $this->getFiles($a_fss_export); - } - - public function numericOrdering(string $a_field): bool - { - return in_array($a_field, array('size', 'date')); - } - - protected function getFiles(ilFileSystemAbstractionStorage $a_fss_export): void - { - $data = []; - foreach ($a_fss_export->getMemberExportFiles() as $exp_file) { - $data[] = [ - 'id' => md5($exp_file['name']), - 'type' => strtoupper($exp_file["type"]), - 'date' => $exp_file['timest'], - 'size' => $exp_file['size'] - ]; - } - - $this->setData($data); - } - - protected function fillRow(array $a_set): void - { - global $DIC; - - $ilCtrl = $DIC['ilCtrl']; - - $this->tpl->setVariable('VAL_ID', $a_set['id']); - $this->tpl->setVariable('VAL_TYPE', $a_set['type']); - $this->tpl->setVariable('VAL_SIZE', ilUtil::formatSize($a_set['size'])); - $this->tpl->setVariable( - 'VAL_DATE', - ilDatePresentation::formatDate(new ilDateTime($a_set['date'], IL_CAL_UNIX)) - ); - - $ilCtrl->setParameter($this->getParentObject(), 'fl', $a_set['id']); - $url = $ilCtrl->getLinkTarget($this->getParentObject(), 'downloadExportFile'); - $ilCtrl->setParameter($this->getParentObject(), 'fl', ''); - - $this->tpl->setVariable('URL_DOWNLOAD', $url); - $this->tpl->setVariable('TXT_DOWNLOAD', $this->lng->txt('download')); - } -} diff --git a/components/ILIAS/Membership/classes/Export/class.ilMemberExportGUI.php b/components/ILIAS/Membership/classes/Export/class.ilMemberExportGUI.php index f2cfa653b6a2..4f095bc81ff0 100755 --- a/components/ILIAS/Membership/classes/Export/class.ilMemberExportGUI.php +++ b/components/ILIAS/Membership/classes/Export/class.ilMemberExportGUI.php @@ -22,6 +22,13 @@ use ILIAS\Refinery\Factory; use ILIAS\User\Profile\Profile; use ILIAS\User\Context; +use ILIAS\UI\URLBuilder; +use ILIAS\UI\URLBuilderToken; +use ILIAS\Data\Factory as DataFactory; +use ILIAS\Membership\Export\Table\TableBuilder; +use ILIAS\Membership\Export\Table\DataRetrieval; +use ILIAS\UI\Renderer as UIRenderer; +use ILIAS\UI\Factory as UIFactory; /** * @author Stefan Meyer @@ -40,7 +47,11 @@ class ilMemberExportGUI protected ilGlobalTemplateInterface $tpl; protected ilLanguage $lng; protected ilToolbarGUI $toolbar; + protected ilObjUser $user; protected Profile $profile; + protected UIRenderer $ui_renderer; + protected UIFactory $ui_factory; + protected DataFactory $data_factory; protected ?ilMemberExport $export = null; protected ?ilExportFieldsInfo $fields_info = null; @@ -62,9 +73,13 @@ public function __construct(int $a_ref_id) $this->ctrl = $DIC->ctrl(); $this->tpl = $DIC->ui()->mainTemplate(); $this->toolbar = $DIC->toolbar(); + $this->user = $DIC->user(); $this->profile = $DIC['user']->getProfile(); $this->lng = $DIC->language(); $this->lng->loadLanguageModule('ps'); + $this->ui_factory = $DIC->ui()->factory(); + $this->ui_renderer = $DIC->ui()->renderer(); + $this->data_factory = new DataFactory(); $this->ref_id = $a_ref_id; $this->obj_id = ilObject::_lookupObjId($this->ref_id); $this->type = ilObject::_lookupType($this->obj_id); @@ -174,7 +189,7 @@ protected function initSettingsForm(bool $a_is_excel = false): ilPropertyFormGUI } // consultation hours - if (ilBookingEntry::hasObjectBookingEntries($this->obj_id, $GLOBALS['DIC']['ilUser']->getId())) { + if (ilBookingEntry::hasObjectBookingEntries($this->obj_id, $this->user->getId())) { $this->lng->loadLanguageModule('dateplaner'); $chours = new ilCheckboxInputGUI($this->lng->txt('cal_ch_field_ch'), 'export_members[]'); $chours->setValue('consultation_hour'); @@ -296,25 +311,81 @@ public function deliverData(): void */ public function showFileList(): void { - $tbl = new ilMemberExportFileTableGUI($this, 'show', $this->fss_export); - $this->tpl->setContent($tbl->getHTML()); + $table = new TableBuilder( + new DataRetrieval($this->fss_export, $this->lng), + $this->lng, + $this->ui_factory, + $this->http, + $this->user, + $this->data_factory + ); + + $this->tpl->setContent( + $this->ui_renderer->render( + $table->get(...$this->getTableActionURLBuilder()) + ) + ); } /** - * Download export file + * @return array{0: URLBuilder, 1: URLBuilderToken, 2: URLBuilderToken} */ - public function downloadExportFile(): void + protected function getTableActionURLBuilder(): array + { + $link = ILIAS_HTTP_PATH . '/' . $this->ctrl->getLinkTarget( + $this, + 'handleTableAction' + ); + $url_builder = new URLBuilder($this->data_factory->uri($link)); + return $url_builder->acquireParameters(['mem_exp_tbl'], 'table_ids', 'table_action'); + } + + protected function handleTableAction(): void { - $fl = ''; - if ($this->http->wrapper()->query()->has('fl')) { - $fl = $this->http->wrapper()->query()->retrieve( - 'fl', - $this->refinery->kindlyTo()->string() + list($url_builder, $id_token, $action_token) = $this->getTableActionURLBuilder(); + + if (!$this->http->wrapper()->query()->has($action_token->getName())) { + return; + } + + $action = $this->http->wrapper()->query()->retrieve( + $action_token->getName(), + $this->refinery->kindlyTo()->string() + ); + + $ids = []; + if ($this->http->wrapper()->query()->has($id_token->getName())) { + $ids = $this->http->wrapper()->query()->retrieve( + $id_token->getName(), + $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string()) ); + + if ($ids === ['ALL_OBJECTS']) { + $data_retrieval = new DataRetrieval($this->fss_export, $this->lng); + $ids = $data_retrieval->getAllIDs(); + } } - $hash = trim($fl); + switch ($action) { + case TableBuilder::ACTION_DOWNLOAD: + $this->downloadExportFile($ids); + break; + + case TableBuilder::ACTION_DELETE: + $this->confirmDeleteExportFile($ids); + break; + } + } + + /** + * Download export file + * @param string[] $ids + */ + public function downloadExportFile(array $ids): void + { + $hash = $ids[0] ?? ''; if (!$hash) { + $this->tpl->setOnScreenMessage('failure', $this->lng->txt('ps_select_one'), true); $this->ctrl->redirect($this, 'show'); } @@ -377,16 +448,17 @@ protected function initFileIdsFromPost(): array ) ); } + return $ids; } /** * Confirm deletion of export files + * @param string[] $ids */ - public function confirmDeleteExportFile(): void + public function confirmDeleteExportFile(array $ids): void { - $file_ids = $this->initFileIdsFromPost(); - if (!count($file_ids)) { + if (!count($ids)) { $this->tpl->setOnScreenMessage('failure', $this->lng->txt('ps_select_one'), true); $this->ctrl->redirect($this, 'show'); } @@ -396,7 +468,7 @@ public function confirmDeleteExportFile(): void $confirmation_gui->setCancel($this->lng->txt('cancel'), 'show'); $confirmation_gui->setConfirm($this->lng->txt('delete'), 'deleteExportFile'); foreach ($this->fss_export->getMemberExportFiles() as $file) { - if (!in_array(md5($file['name']), $file_ids)) { + if (!in_array(md5($file['name']), $ids)) { continue; } $confirmation_gui->addItem( diff --git a/components/ILIAS/Membership/templates/default/tpl.mem_export_file_row.html b/components/ILIAS/Membership/templates/default/tpl.mem_export_file_row.html deleted file mode 100755 index 21ef2d5e5968..000000000000 --- a/components/ILIAS/Membership/templates/default/tpl.mem_export_file_row.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - {VAL_TYPE} - - - {VAL_SIZE} - - - {VAL_DATE} - - - {TXT_DOWNLOAD} - - diff --git a/components/ILIAS/StudyProgramme/classes/memberexport/class.ilPRGMembersExportGUI.php b/components/ILIAS/StudyProgramme/classes/memberexport/class.ilPRGMembersExportGUI.php index eceff51901b8..592694b4bfbf 100755 --- a/components/ILIAS/StudyProgramme/classes/memberexport/class.ilPRGMembersExportGUI.php +++ b/components/ILIAS/StudyProgramme/classes/memberexport/class.ilPRGMembersExportGUI.php @@ -174,7 +174,7 @@ public function deleteExportFile(): void } foreach ($this->fss_export->getMemberExportFiles() as $file) { - if (!in_array(md5($file['name']), $_POST['id'])) { + if (!in_array(md5($file['name']), $file_ids)) { continue; } $this->fss_export->deleteMemberExportFile($file['name']); @@ -184,18 +184,14 @@ public function deleteExportFile(): void $this->ctrl->redirect($this, 'show'); } - public function downloadExportFile(): void + /** + * @param string[] $ids + */ + public function downloadExportFile(array $ids): void { - $fl = ''; - if ($this->http->wrapper()->query()->has('fl')) { - $fl = $this->http->wrapper()->query()->retrieve( - 'fl', - $this->refinery->kindlyTo()->string() - ); - } - - $hash = trim($fl); + $hash = $ids[0] ?? ''; if (!$hash) { + $this->tpl->setOnScreenMessage('failure', $this->lng->txt('ps_select_one'), true); $this->ctrl->redirect($this, 'show'); } @@ -203,7 +199,7 @@ public function downloadExportFile(): void if (md5($file['name']) == $hash) { $contents = $this->fss_export->getMemberExportFile($file['name']); $fts = $file['timest']; - $dat = date('Y_m_d_H-i', (int)$fts); + $dat = date('Y_m_d_H-i', (int) $fts); $down_name = str_replace($fts, $dat, $file['name']); $mime = 'text/csv';