From f323a67666bf182f8a19bfe3396b0fed5035777e Mon Sep 17 00:00:00 2001 From: Cyperghost Date: Mon, 17 Mar 2025 10:13:58 +0100 Subject: [PATCH 1/3] Migrate `TrophyList` to grid view --- .../files/acp/templates/trophyList.tpl | 69 +---------- .../lib/acp/page/TrophyListPage.class.php | 36 +++--- .../files/lib/bootstrap/com.woltlab.wcf.php | 3 + .../lib/data/trophy/I18nTrophyList.class.php | 34 ++++++ .../admin/TrophyGridViewInitialized.class.php | 21 ++++ .../TrophyInteractionCollecting.class.php | 21 ++++ .../TrophyBulkInteractionCollecting.class.php | 21 ++++ .../core/trophies/DeleteTrophy.class.php | 47 ++++++++ .../core/trophies/DisableTrophy.class.php | 51 ++++++++ .../core/trophies/EnableTrophy.class.php | 51 ++++++++ .../gridView/admin/TrophyGridView.class.php | 113 ++++++++++++++++++ .../admin/TrophyInteractions.class.php | 37 ++++++ .../admin/TrophyBulkInteractions.class.php | 37 ++++++ wcfsetup/install/files/style/ui/gridView.scss | 6 + 14 files changed, 460 insertions(+), 87 deletions(-) create mode 100644 wcfsetup/install/files/lib/data/trophy/I18nTrophyList.class.php create mode 100644 wcfsetup/install/files/lib/event/gridView/admin/TrophyGridViewInitialized.class.php create mode 100644 wcfsetup/install/files/lib/event/interaction/admin/TrophyInteractionCollecting.class.php create mode 100644 wcfsetup/install/files/lib/event/interaction/bulk/admin/TrophyBulkInteractionCollecting.class.php create mode 100644 wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/DeleteTrophy.class.php create mode 100644 wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/DisableTrophy.class.php create mode 100644 wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/EnableTrophy.class.php create mode 100644 wcfsetup/install/files/lib/system/gridView/admin/TrophyGridView.class.php create mode 100644 wcfsetup/install/files/lib/system/interaction/admin/TrophyInteractions.class.php create mode 100644 wcfsetup/install/files/lib/system/interaction/bulk/admin/TrophyBulkInteractions.class.php diff --git a/wcfsetup/install/files/acp/templates/trophyList.tpl b/wcfsetup/install/files/acp/templates/trophyList.tpl index 5b4c55f2033..6184d997f83 100644 --- a/wcfsetup/install/files/acp/templates/trophyList.tpl +++ b/wcfsetup/install/files/acp/templates/trophyList.tpl @@ -1,18 +1,8 @@ {include file='header' pageTitle='wcf.acp.menu.link.trophy.list'} - -
-

{lang}wcf.acp.menu.link.trophy.list{/lang}{if $items} {#$items}{/if}

+

{lang}wcf.acp.menu.link.trophy.list{/lang} {#$gridView->countRows()}

-{hascontent} -
- {content} - {pages print=true assign=pagesLinks controller='TrophyList' link="pageNo=%d"} - {/content} -
-{/hascontent} - -{if $objects|count} -
-
    - {foreach from=$objects item='trophy'} -
  1. - - {@$trophy->renderTrophy(32)} - {$trophy->getTitle()} - - - - {icon name='arrows-up-down-left-right'} - - {objectAction action="toggle" isDisabled=$trophy->isDisabled} - {icon name='pencil'} - {objectAction action="delete" objectTitle=$trophy->getTitle()} - - {event name='itemButtons'} - - -
  2. - {/foreach} -
-
- -
- -
- - -{else} - {lang}wcf.global.noItems{/lang} -{/if} +
+ {unsafe:$gridView->render()} +
{include file='footer'} diff --git a/wcfsetup/install/files/lib/acp/page/TrophyListPage.class.php b/wcfsetup/install/files/lib/acp/page/TrophyListPage.class.php index 716a5fe5bdb..93687e6817a 100644 --- a/wcfsetup/install/files/lib/acp/page/TrophyListPage.class.php +++ b/wcfsetup/install/files/lib/acp/page/TrophyListPage.class.php @@ -2,20 +2,21 @@ namespace wcf\acp\page; -use wcf\data\trophy\TrophyList; -use wcf\page\MultipleLinkPage; +use wcf\page\AbstractGridViewPage; +use wcf\system\gridView\AbstractGridView; +use wcf\system\gridView\admin\TrophyGridView; /** * Trophy list page. * - * @author Joshua Ruesweg - * @copyright 2001-2019 WoltLab GmbH - * @license GNU Lesser General Public License - * @since 3.1 + * @author Olaf Braun, Joshua Ruesweg + * @copyright 2001-2025 WoltLab GmbH + * @license GNU Lesser General Public License + * @since 3.1 * - * @extends MultipleLinkPage + * @extends AbstractGridViewPage */ -class TrophyListPage extends MultipleLinkPage +class TrophyListPage extends AbstractGridViewPage { /** * @inheritDoc @@ -32,18 +33,9 @@ class TrophyListPage extends MultipleLinkPage */ public $neededPermissions = ['admin.trophy.canManageTrophy']; - /** - * @inheritDoc - */ - public $sortField = 'trophy.showOrder'; - - /** - * @inheritDoc - */ - public $sortOrder = 'ASC'; - - /** - * @inheritDoc - */ - public $objectListClassName = TrophyList::class; + #[\Override] + protected function createGridView(): AbstractGridView + { + return new TrophyGridView(); + } } diff --git a/wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php b/wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php index 54820e7df46..cd58dbc9bea 100644 --- a/wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php +++ b/wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php @@ -211,6 +211,9 @@ static function (\wcf\event\endpoint\ControllerCollecting $event) { $event->register(new \wcf\system\endpoint\controller\core\users\groups\assignment\DisableAssignment()); $event->register(new \wcf\system\endpoint\controller\core\users\groups\DeleteGroup()); $event->register(new \wcf\system\endpoint\controller\core\menus\DeleteMenu()); + $event->register(new \wcf\system\endpoint\controller\core\trophies\EnableTrophy()); + $event->register(new \wcf\system\endpoint\controller\core\trophies\DisableTrophy()); + $event->register(new \wcf\system\endpoint\controller\core\trophies\DeleteTrophy()); } ); diff --git a/wcfsetup/install/files/lib/data/trophy/I18nTrophyList.class.php b/wcfsetup/install/files/lib/data/trophy/I18nTrophyList.class.php new file mode 100644 index 00000000000..7fd30c84b43 --- /dev/null +++ b/wcfsetup/install/files/lib/data/trophy/I18nTrophyList.class.php @@ -0,0 +1,34 @@ + + * @since 6.2 + * + * @method Trophy current() + * @method Trophy[] getObjects() + * @method Trophy|null getSingleObject() + * @method Trophy|null search($objectID) + * @property Trophy[] $objects + * + * @extends I18nDatabaseObjectList + */ +class I18nTrophyList extends I18nDatabaseObjectList +{ + /** + * @inheritDoc + */ + public $i18nFields = ['title' => 'titleI18n']; + + /** + * @inheritDoc + */ + public $className = Trophy::class; +} diff --git a/wcfsetup/install/files/lib/event/gridView/admin/TrophyGridViewInitialized.class.php b/wcfsetup/install/files/lib/event/gridView/admin/TrophyGridViewInitialized.class.php new file mode 100644 index 00000000000..258bb17fa12 --- /dev/null +++ b/wcfsetup/install/files/lib/event/gridView/admin/TrophyGridViewInitialized.class.php @@ -0,0 +1,21 @@ + + * @since 6.2 + */ +final class TrophyGridViewInitialized implements IPsr14Event +{ + public function __construct(public readonly TrophyGridView $param) + { + } +} diff --git a/wcfsetup/install/files/lib/event/interaction/admin/TrophyInteractionCollecting.class.php b/wcfsetup/install/files/lib/event/interaction/admin/TrophyInteractionCollecting.class.php new file mode 100644 index 00000000000..602c65d20c5 --- /dev/null +++ b/wcfsetup/install/files/lib/event/interaction/admin/TrophyInteractionCollecting.class.php @@ -0,0 +1,21 @@ + + * @since 6.2 + */ +final class TrophyInteractionCollecting implements IPsr14Event +{ + public function __construct(public readonly TrophyInteractions $param) + { + } +} diff --git a/wcfsetup/install/files/lib/event/interaction/bulk/admin/TrophyBulkInteractionCollecting.class.php b/wcfsetup/install/files/lib/event/interaction/bulk/admin/TrophyBulkInteractionCollecting.class.php new file mode 100644 index 00000000000..e0cd705b3f6 --- /dev/null +++ b/wcfsetup/install/files/lib/event/interaction/bulk/admin/TrophyBulkInteractionCollecting.class.php @@ -0,0 +1,21 @@ + + * @since 6.2 + */ +final class TrophyBulkInteractionCollecting implements IPsr14Event +{ + public function __construct(public readonly TrophyBulkInteractions $param) + { + } +} diff --git a/wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/DeleteTrophy.class.php b/wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/DeleteTrophy.class.php new file mode 100644 index 00000000000..4c6e27ed366 --- /dev/null +++ b/wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/DeleteTrophy.class.php @@ -0,0 +1,47 @@ + + * @since 6.2 + */ +#[DeleteRequest("/core/trophies/{id:\d+}")] +final class DeleteTrophy implements IController +{ + #[\Override] + public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface + { + $trophy = Helper::fetchObjectFromRequestParameter($variables['id'], Trophy::class); + + $this->assertTrophyCanBeDeleted(); + + (new TrophyAction([$trophy], 'delete'))->executeAction(); + + return new JsonResponse([]); + } + + private function assertTrophyCanBeDeleted(): void + { + if (!\MODULE_TROPHY) { + throw new IllegalLinkException(); + } + + WCF::getSession()->checkPermissions(['admin.trophy.canManageTrophy']); + } +} diff --git a/wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/DisableTrophy.class.php b/wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/DisableTrophy.class.php new file mode 100644 index 00000000000..1ce52c6507e --- /dev/null +++ b/wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/DisableTrophy.class.php @@ -0,0 +1,51 @@ + + * @since 6.2 + */ +#[PostRequest("/core/trophies/{id:\d+}/disable")] +final class DisableTrophy implements IController +{ + public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface + { + $trophy = Helper::fetchObjectFromRequestParameter($variables['id'], Trophy::class); + + $this->assertTrophyCanBeDisabled($trophy); + + (new TrophyAction([$trophy], 'toggle'))->executeAction(); + + return new JsonResponse([]); + } + + private function assertTrophyCanBeDisabled(Trophy $trophy): void + { + if (!\MODULE_TROPHY) { + throw new IllegalLinkException(); + } + + WCF::getSession()->checkPermissions(['admin.trophy.canManageTrophy']); + + if ($trophy->isDisabled) { + throw new PermissionDeniedException(); + } + } +} diff --git a/wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/EnableTrophy.class.php b/wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/EnableTrophy.class.php new file mode 100644 index 00000000000..454387c0551 --- /dev/null +++ b/wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/EnableTrophy.class.php @@ -0,0 +1,51 @@ + + * @since 6.2 + */ +#[PostRequest("/core/trophies/{id:\d+}/enable")] +final class EnableTrophy implements IController +{ + public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface + { + $trophy = Helper::fetchObjectFromRequestParameter($variables['id'], Trophy::class); + + $this->assertTrophyCanBeEnabled($trophy); + + (new TrophyAction([$trophy], 'toggle'))->executeAction(); + + return new JsonResponse([]); + } + + private function assertTrophyCanBeEnabled(Trophy $trophy): void + { + if (!\MODULE_TROPHY) { + throw new IllegalLinkException(); + } + + WCF::getSession()->checkPermissions(['admin.trophy.canManageTrophy']); + + if (!$trophy->isDisabled) { + throw new PermissionDeniedException(); + } + } +} diff --git a/wcfsetup/install/files/lib/system/gridView/admin/TrophyGridView.class.php b/wcfsetup/install/files/lib/system/gridView/admin/TrophyGridView.class.php new file mode 100644 index 00000000000..22308951bd7 --- /dev/null +++ b/wcfsetup/install/files/lib/system/gridView/admin/TrophyGridView.class.php @@ -0,0 +1,113 @@ + + * @since 6.2 + * + * @extends AbstractGridView + */ +final class TrophyGridView extends AbstractGridView +{ + public function __construct() + { + $this->addColumns([ + GridViewColumn::for("trophyID") + ->label("wcf.global.objectID") + ->renderer(new ObjectIdColumnRenderer()) + ->filter(new ObjectIdFilter()) + ->sortable(), + GridViewColumn::for("image") + ->label("wcf.acp.trophy") + ->renderer( + new class extends AbstractColumnRenderer { + #[\Override] + public function render(mixed $value, DatabaseObject $row): string + { + \assert($row instanceof Trophy); + + return $row->renderTrophy(); + } + + #[\Override] + public function getClasses(): string + { + return "gridView__column--icon"; + } + } + ), + GridViewColumn::for("title") + ->titleColumn() + ->label("wcf.global.title") + ->renderer(new PhraseColumnRenderer()) + ->filter(new I18nTextFilter()) + ->sortable(sortByDatabaseColumn: "titleI18n"), + GridViewColumn::for("showOrder") + ->label("wcf.global.showOrder") + ->renderer(new NumberColumnRenderer()) + ->filter(new NumericFilter()) + ->sortable(), + ]); + + $provider = new TrophyInteractions(); + $provider->addInteractions([ + new Divider(), + new EditInteraction(TrophyEditForm::class), + ]); + $this->setInteractionProvider($provider); + $this->setBulkInteractionProvider(new TrophyBulkInteractions()); + + $this->addQuickInteraction( + new ToggleInteraction("enable", "core/trophies/%s/enable", "core/trophies/%s/disable") + ); + + $this->setSortField("showOrder"); + $this->addRowLink(new GridViewRowLink(TrophyEditForm::class)); + } + + #[\Override] + public function isAccessible(): bool + { + return \MODULE_TROPHY + && WCF::getSession()->getPermission("admin.trophy.canManageTrophy"); + } + + #[\Override] + protected function createObjectList(): I18nTrophyList + { + return new I18nTrophyList(); + } + + #[\Override] + protected function getInitializedEvent(): TrophyGridViewInitialized + { + return new TrophyGridViewInitialized($this); + } +} diff --git a/wcfsetup/install/files/lib/system/interaction/admin/TrophyInteractions.class.php b/wcfsetup/install/files/lib/system/interaction/admin/TrophyInteractions.class.php new file mode 100644 index 00000000000..ab6eb7bacfa --- /dev/null +++ b/wcfsetup/install/files/lib/system/interaction/admin/TrophyInteractions.class.php @@ -0,0 +1,37 @@ + + * @since 6.2 + */ +final class TrophyInteractions extends AbstractInteractionProvider +{ + public function __construct() + { + $this->addInteractions([ + new DeleteInteraction('core/trophies/%s'), + ]); + + EventHandler::getInstance()->fire( + new TrophyInteractionCollecting($this) + ); + } + + #[\Override] + public function getObjectClassName(): string + { + return Trophy::class; + } +} diff --git a/wcfsetup/install/files/lib/system/interaction/bulk/admin/TrophyBulkInteractions.class.php b/wcfsetup/install/files/lib/system/interaction/bulk/admin/TrophyBulkInteractions.class.php new file mode 100644 index 00000000000..d63d2f53413 --- /dev/null +++ b/wcfsetup/install/files/lib/system/interaction/bulk/admin/TrophyBulkInteractions.class.php @@ -0,0 +1,37 @@ + + * @since 6.2 + */ +final class TrophyBulkInteractions extends AbstractBulkInteractionProvider +{ + public function __construct() + { + $this->addInteractions([ + new BulkDeleteInteraction('core/trophies/%s'), + ]); + + EventHandler::getInstance()->fire( + new TrophyBulkInteractionCollecting($this) + ); + } + + #[\Override] + public function getObjectListClassName(): string + { + return TrophyList::class; + } +} diff --git a/wcfsetup/install/files/style/ui/gridView.scss b/wcfsetup/install/files/style/ui/gridView.scss index f3f8d625540..0dbe1de10f2 100644 --- a/wcfsetup/install/files/style/ui/gridView.scss +++ b/wcfsetup/install/files/style/ui/gridView.scss @@ -92,6 +92,12 @@ word-wrap: normal; } + &.gridView__column--icon { + width: 32px; + white-space: nowrap; + word-wrap: normal; + } + &.gridView__column--date { text-align: right; width: 1px; From 82557ad12745472b57707a414eab79329319996b Mon Sep 17 00:00:00 2001 From: Cyperghost Date: Mon, 17 Mar 2025 10:33:28 +0100 Subject: [PATCH 2/3] Use new sort api for trophies --- .../files/acp/templates/trophyList.tpl | 18 +++++ .../lib/acp/page/TrophyListPage.class.php | 8 +- .../files/lib/bootstrap/com.woltlab.wcf.php | 2 + .../lib/data/trophy/I18nTrophyList.class.php | 14 +--- .../lib/data/trophy/TrophyAction.class.php | 45 +---------- .../admin/TrophyGridViewInitialized.class.php | 8 +- .../TrophyBulkInteractionCollecting.class.php | 8 +- .../core/trophies/ChangeShowOrder.class.php | 77 +++++++++++++++++++ .../core/trophies/GetShowOrder.class.php | 51 ++++++++++++ .../gridView/admin/TrophyGridView.class.php | 8 +- .../admin/TrophyInteractions.class.php | 8 +- .../admin/TrophyBulkInteractions.class.php | 8 +- 12 files changed, 177 insertions(+), 78 deletions(-) create mode 100644 wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/ChangeShowOrder.class.php create mode 100644 wcfsetup/install/files/lib/system/endpoint/controller/core/trophies/GetShowOrder.class.php diff --git a/wcfsetup/install/files/acp/templates/trophyList.tpl b/wcfsetup/install/files/acp/templates/trophyList.tpl index 6184d997f83..8ccceaaa82e 100644 --- a/wcfsetup/install/files/acp/templates/trophyList.tpl +++ b/wcfsetup/install/files/acp/templates/trophyList.tpl @@ -7,6 +7,11 @@