From cbeb046967fecc00b285a7d0d34ad48c84597725 Mon Sep 17 00:00:00 2001 From: mjansen Date: Wed, 18 Dec 2024 14:16:53 +0100 Subject: [PATCH] Badges: Fix missing table id and sorting issues (cherry picked from commit 62a51da21ca63d16bcc04c137659e44a7480b48a) --- .../class.ilBadgeImageTemplateTableGUI.php | 26 ++-- .../Badge/classes/class.ilBadgeTableGUI.php | 142 ++++++++++-------- .../classes/class.ilObjectBadgeTableGUI.php | 38 ++--- 3 files changed, 115 insertions(+), 91 deletions(-) diff --git a/components/ILIAS/Badge/classes/class.ilBadgeImageTemplateTableGUI.php b/components/ILIAS/Badge/classes/class.ilBadgeImageTemplateTableGUI.php index c04fcf5f87e6..fe0b71d87939 100755 --- a/components/ILIAS/Badge/classes/class.ilBadgeImageTemplateTableGUI.php +++ b/components/ILIAS/Badge/classes/class.ilBadgeImageTemplateTableGUI.php @@ -70,7 +70,7 @@ public function __construct( } /** - * @return list + * @return list */ private function getBadgeImageTemplates(): array { @@ -78,25 +78,24 @@ private function getBadgeImageTemplates(): array $rows = []; foreach (ilBadgeImageTemplate::getInstances() as $template) { - $badge_template_image = $template->getImageFromResourceId($template->getImageRid()); - $image = ''; $title = $template->getTitle(); - if ($badge_template_image !== '') { + $image_src = $template->getImageFromResourceId($template->getImageRid()); + if ($image_src !== '') { $image_component = $this->ui_factory->image()->responsive( - $badge_template_image, + $image_src, $template->getTitle() ); $image_html = $this->ui_renderer->render($image_component); - $badge_template_image_large = $template->getImageFromResourceId( + $image_src_large = $template->getImageFromResourceId( $template->getImageRid(), null, ilBadgeImage::IMAGE_SIZE_XL ); $large_image_component = $this->ui_factory->image()->responsive( - $badge_template_image_large, + $image_src_large, $template->getTitle() ); @@ -112,7 +111,10 @@ private function getBadgeImageTemplates(): array $rows[] = [ 'id' => $template->getId(), 'image' => $image, + // Just an boolean-like indicator for sorting + 'image_sortable' => $image ? 'A' . $template->getId() : 'Z' . $template->getId(), 'title' => $title, + 'title_sortable' => $template->getTitle(), ]; } @@ -142,7 +144,7 @@ public function getTotalRowCount( } /** - * @return list + * @return list */ private function getRecords(Range $range = null, Order $order = null): array { @@ -156,10 +158,10 @@ private function getRecords(Range $range = null, Order $order = null): array usort( $rows, static function (array $left, array $right) use ($order_field): int { - if ($order_field === 'title') { + if (\in_array($order_field, ['image', 'title'], true)) { return \ilStr::strCmp( - $left[$order_field], - $right[$order_field] + $left[$order_field . '_sortable'], + $right[$order_field . '_sortable'] ); } @@ -212,7 +214,7 @@ public function renderTable(): void $df = new \ILIAS\Data\Factory(); $columns = [ - 'image' => $f->table()->column()->text($this->lng->txt('image'))->withIsSortable(false), + 'image' => $f->table()->column()->text($this->lng->txt('image')), 'title' => $f->table()->column()->text($this->lng->txt('title')), ]; diff --git a/components/ILIAS/Badge/classes/class.ilBadgeTableGUI.php b/components/ILIAS/Badge/classes/class.ilBadgeTableGUI.php index b4a6167e08cc..1a9ae26311fc 100755 --- a/components/ILIAS/Badge/classes/class.ilBadgeTableGUI.php +++ b/components/ILIAS/Badge/classes/class.ilBadgeTableGUI.php @@ -77,7 +77,7 @@ private function buildColumns(): array $lng = $this->lng; return [ - 'image_rid' => $column->text($lng->txt('image')), + 'image' => $column->text($lng->txt('image')), 'title' => $column->text($lng->txt('title')), 'type' => $column->text($lng->txt('type')), 'active' => $column->boolean($lng->txt('active'), $lng->txt('yes'), $lng->txt('no')), @@ -87,21 +87,17 @@ private function buildColumns(): array private function buildDataRetrievalObject(Factory $f, Renderer $r, int $p, string $type): DataRetrieval { return new class ($f, $r, $p, $type) implements DataRetrieval { - private int $parent_obj_id; - private string $parent_obj_type; private ilBadgeImage $badge_image_service; private Factory $factory; private Renderer $renderer; public function __construct( - private Factory $ui_factory, - private Renderer $ui_renderer, - private int $parent_id, - private string $parent_type + private readonly Factory $ui_factory, + private readonly Renderer $ui_renderer, + private readonly int $parent_id, + private readonly string $parent_type ) { global $DIC; - $this->parent_obj_id = $parent_id; - $this->parent_obj_type = $parent_type; $this->badge_image_service = new ilBadgeImage( $DIC->resourceStorage(), $DIC->upload(), @@ -118,71 +114,76 @@ public function __construct( * active: bool, * type: string, * manual: bool, - * image_rid: string, + * image: string, + * image_sortable: string, * title: string, - * renderer: string}> + * title_sortable: string + * }> */ - private function getBadges(Container $DIC): array + private function getBadges(): array { - $data = []; - $badge_img_large = null; + $rows = []; $modal_container = new ModalBuilder(); foreach (ilBadge::getInstancesByParentId($this->parent_id) as $badge) { - $title = $badge->getTitle(); - $image_html = ''; - $badge_rid = $badge->getImageRid(); - $image_src = $this->badge_image_service->getImageFromResourceId($badge, $badge_rid); - $badge_image_large = $this->badge_image_service->getImageFromResourceId( - $badge, - $badge_rid, - ilBadgeImage::IMAGE_SIZE_XL - ); - if ($badge_rid != '') { - $badge_template_image = $image_src; - if ($badge_template_image !== '') { - $badge_img = $this->factory->image()->responsive( - $badge_template_image, + $images = [ + 'rendered' => null, + 'large' => null, + ]; + $image_src = $this->badge_image_service->getImageFromResourceId($badge, $badge->getImageRid()); + if ($image_src !== '') { + $images['rendered'] = $this->renderer->render( + $this->factory->image()->responsive( + $image_src, + $badge->getTitle() + ) + ); + + $image_src_large = $this->badge_image_service->getImageFromResourceId( + $badge, + $badge->getImageRid(), + ilBadgeImage::IMAGE_SIZE_XL + ); + if ($image_src_large !== '') { + $images['large'] = $this->ui_factory->image()->responsive( + $image_src_large, $badge->getTitle() ); - $image_html = $this->renderer->render($badge_img); } } - if ($badge_img_large !== '') { - $badge_img_large = $DIC->ui()->factory()->image()->responsive( - $badge_image_large, - $badge->getTitle() - ); - $badge_information = [ + $modal = $modal_container->constructModal( + $images['large'], + $badge->getTitle(), + [ 'description' => $badge->getDescription(), 'badge_criteria' => $badge->getCriteria(), - ]; + ] + ); - $modal = $modal_container->constructModal( - $badge_img_large, - $badge->getTitle(), - $badge_information - ); - } - $data[] = [ + $rows[] = [ 'id' => $badge->getId(), 'badge' => $badge, 'active' => $badge->isActive(), - 'type' => ($this->parent_type !== 'bdga') + 'type' => $this->parent_type !== 'bdga' ? ilBadge::getExtendedTypeCaption($badge->getTypeInstance()) : $badge->getTypeInstance()->getCaption(), - 'manual' => (!$badge->getTypeInstance() instanceof ilBadgeAuto), - 'image_rid' => $modal_container->renderShyButton( - $image_html, + 'manual' => !$badge->getTypeInstance() instanceof ilBadgeAuto, + 'image' => $images['rendered'] ? ($modal_container->renderShyButton( + $images['rendered'], $modal - ) . ' ' . $modal_container->renderModal($modal), - 'title' => $modal_container->renderShyButton($title, $modal), - 'renderer' => '' + ) . ' ') : '', + // Just an boolean-like indicator for sorting + 'image_sortable' => $images['rendered'] ? 'A' . $badge->getId() : 'Z' . $badge->getId(), + 'title' => implode('', [ + $modal_container->renderShyButton($badge->getTitle(), $modal), + $modal_container->renderModal($modal) + ]), + 'title_sortable' => $badge->getTitle() ]; } - return $data; + return $rows; } public function getRows( @@ -214,31 +215,47 @@ public function getTotalRowCount( * active: bool, * type: string, * manual: bool, - * image_rid: string, + * image: string, + * image_sortable: string, * title: string, - * renderer: string}> + * title_sortable: string}> */ private function getRecords(Range $range = null, Order $order = null): array { - global $DIC; - $data = $this->getBadges($DIC); + $rows = $this->getBadges(); if ($order) { [$order_field, $order_direction] = $order->join( [], fn($ret, $key, $value) => [$key, $value] ); - usort($data, fn($a, $b) => $a[$order_field] <=> $b[$order_field]); - if ($order_direction === 'DESC') { - $data = array_reverse($data); + usort( + $rows, + static function (array $left, array $right) use ($order_field): int { + if (\in_array($order_field, ['title', 'type', 'image'], true)) { + if (\in_array($order_field, ['title', 'image'], true)) { + $order_field .= '_sortable'; + } + + return \ilStr::strCmp( + $left[$order_field], + $right[$order_field] + ); + } + + return $left[$order_field] <=> $right[$order_field]; + } + ); + if ($order_direction === Order::DESC) { + $rows = array_reverse($rows); } } if ($range) { - $data = \array_slice($data, $range->getStart(), $range->getLength()); + $rows = \array_slice($rows, $range->getStart(), $range->getLength()); } - return $data; + return $rows; } }; } @@ -313,7 +330,10 @@ public function renderTable(): void $data_retrieval = $this->buildDataRetrievalObject($f, $r, $this->parent_id, $this->parent_type); $actions = $this->getActions($url_builder, $action_parameter_token, $row_id_token); - $table = $f->table()->data($this->lng->txt('obj_bdga'), $columns, $data_retrieval) + $table = $f->table() + ->data($this->lng->txt('obj_bdga'), $columns, $data_retrieval) + ->withId(self::class . '_' . $this->parent_id) + ->withOrder(new Order('title', Order::ASC)) ->withActions($actions) ->withRequest($request); $out = [$table]; diff --git a/components/ILIAS/Badge/classes/class.ilObjectBadgeTableGUI.php b/components/ILIAS/Badge/classes/class.ilObjectBadgeTableGUI.php index a6db06deecf7..2324913760e8 100755 --- a/components/ILIAS/Badge/classes/class.ilObjectBadgeTableGUI.php +++ b/components/ILIAS/Badge/classes/class.ilObjectBadgeTableGUI.php @@ -158,8 +158,8 @@ private function getRecords(Range $range = null, Order $order = null): array $type_caption = ilBadge::getExtendedTypeCaption($types[$badge_item['type_id']]); $images = [ - 'rendered' => '', - 'rendered_large' => '', + 'rendered' => null, + 'large' => null, ]; $image_src = $this->badge_image_service->getImageFromResourceId( $badge_item, @@ -173,14 +173,14 @@ private function getRecords(Range $range = null, Order $order = null): array ) ); - $image_html_large = $this->badge_image_service->getImageFromResourceId( + $image_src_large = $this->badge_image_service->getImageFromResourceId( $badge_item, $badge_item['image_rid'], ilBadgeImage::IMAGE_SIZE_XL ); - if ($image_html_large !== '') { - $images['rendered_large'] = $this->ui_factory->image()->responsive( - $image_html_large, + if ($image_src_large !== '') { + $images['large'] = $this->ui_factory->image()->responsive( + $image_src_large, $badge_item['title'] ); } @@ -216,16 +216,14 @@ private function getRecords(Range $range = null, Order $order = null): array } } - $badge_information = [ - 'active' => $badge_item['active'] ? $this->lng->txt('yes') : $this->lng->txt('no'), - 'type' => $type_caption, - 'container' => implode(' ', \array_slice($container_title_parts, 1, null, true)), - ]; - $modal = $modal_container->constructModal( - $images['rendered_large'] ?: null, + $images['large'], $badge_item['title'], - $badge_information + [ + 'active' => $badge_item['active'] ? $this->lng->txt('yes') : $this->lng->txt('no'), + 'type' => $type_caption, + 'container' => implode(' ', \array_slice($container_title_parts, 1, null, true)), + ] ); $rows[] = [ @@ -237,7 +235,7 @@ private function getRecords(Range $range = null, Order $order = null): array $modal ) . ' ') : '', // Just an boolean-like indicator for sorting - 'image_sortable' => $images['rendered'] ? 'A' : 'Z', + 'image_sortable' => $images['rendered'] ? 'A' . $badge_item['id'] : 'Z' . $badge_item['id'], 'title' => implode('', [ $modal_container->renderShyButton($badge_item['title'], $modal), $modal_container->renderModal($modal) @@ -256,10 +254,14 @@ private function getRecords(Range $range = null, Order $order = null): array usort( $rows, static function (array $left, array $right) use ($order_field): int { - if (\in_array($order_field, ['image', 'container', 'title'], true)) { + if (\in_array($order_field, ['image', 'container', 'title', 'type'], true)) { + if (\in_array($order_field, ['image', 'container', 'title'], true)) { + $order_field .= '_sortable'; + } + return \ilStr::strCmp( - $left[$order_field . '_sortable'], - $right[$order_field . '_sortable'] + $left[$order_field], + $right[$order_field] ); }