Skip to content

Commit cd9946f

Browse files
authored
Merge pull request #6202 from WoltLab/6.2-PackageUpdateServerListPage-to-grid-view
Migrate `PackageUpdateServerListPage` to grid view
2 parents 6bbb107 + feb800d commit cd9946f

File tree

12 files changed

+434
-117
lines changed

12 files changed

+434
-117
lines changed

wcfsetup/install/files/acp/templates/packageUpdateServerList.tpl

Lines changed: 4 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<header class="contentHeader">
44
<div class="contentHeaderTitle">
5-
<h1 class="contentTitle">{lang}wcf.acp.updateServer.list{/lang}{if $items} <span class="badge badgeInverse">{#$items}</span>{/if}</h1>
5+
<h1 class="contentTitle">{lang}wcf.acp.updateServer.list{/lang} <span class="badge badgeInverse">{#$gridView->countRows()}</span></h1>
66
</div>
77

88
<nav class="contentHeaderNavigation">
@@ -14,84 +14,8 @@
1414
</nav>
1515
</header>
1616

17-
{hascontent}
18-
<div class="paginationTop">
19-
{content}{pages print=true assign=pagesLinks controller="PackageUpdateServerList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}{/content}
20-
</div>
21-
{/hascontent}
22-
23-
{if $objects|count}
24-
<div class="section tabularBox">
25-
<table class="table jsObjectActionContainer" data-object-action-class-name="wcf\data\package\update\server\PackageUpdateServerAction">
26-
<thead>
27-
<tr>
28-
<th class="columnID columnPackageUpdateServerID{if $sortField == 'packageUpdateServerID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=packageUpdateServerID&sortOrder={if $sortField == 'packageUpdateServerID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
29-
<th class="columnTitle columnServerURL{if $sortField == 'serverURL'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=serverURL&sortOrder={if $sortField == 'serverURL' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.serverURL{/lang}</a></th>
30-
<th class="columnLoginUsername{if $sortField == 'loginUsername'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=loginUsername&sortOrder={if $sortField == 'loginUsername' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.loginUsername{/lang}</a></th>
31-
<th class="columnDigits columnPackages{if $sortField == 'packages'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=packages&sortOrder={if $sortField == 'packages' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.packages{/lang}</a></th>
32-
<th class="columnStatus{if $sortField == 'status'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=status&sortOrder={if $sortField == 'status' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.status{/lang}</a></th>
33-
<th class="columnText columnErrorText{if $sortField == 'errorMessage'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=errorMessage&sortOrder={if $sortField == 'errorMessage' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.errorMessage{/lang}</a></th>
34-
<th class="columnDate columnTimestamp{if $sortField == 'lastUpdateTime'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=lastUpdateTime&sortOrder={if $sortField == 'lastUpdateTime' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.lastUpdateTime{/lang}</a></th>
35-
36-
{event name='columnHeads'}
37-
</tr>
38-
</thead>
39-
40-
<tbody class="jsReloadPageWhenEmpty">
41-
{foreach from=$objects item=updateServer}
42-
<tr class="jsUpdateServerRow jsObjectActionObject" data-object-id="{@$updateServer->getObjectID()}">
43-
<td class="columnIcon">
44-
{if $updateServer->canDisable()}
45-
{objectAction action="toggle" isDisabled=$updateServer->isDisabled}
46-
{else}
47-
<span class="disabled" title="{lang}wcf.global.button.disable{/lang}">
48-
{icon name='square-check'}
49-
</span>
50-
{/if}
51-
<a href="{link controller='PackageUpdateServerEdit' id=$updateServer->packageUpdateServerID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip">{icon name='pencil'}</a>
52-
{if $updateServer->canDelete()}
53-
{objectAction action="delete" objectTitle=$updateServer->serverURL}
54-
{else}
55-
<span class="disabled" title="{lang}wcf.global.button.delete{/lang}">
56-
{icon name='xmark'}
57-
</span>
58-
{/if}
59-
60-
{event name='itemButtons'}
61-
</td>
62-
<td class="columnID columnPackageUpdateServerID">{@$updateServer->packageUpdateServerID}</td>
63-
<td class="columnTitle columnServerURL"><a href="{link controller='PackageUpdateServerEdit' id=$updateServer->packageUpdateServerID}{/link}" title="{lang}wcf.acp.updateServer.edit{/lang}">{$updateServer->serverURL}</a></td>
64-
<td class="columnLoginUsername">{$updateServer->loginUsername}</td>
65-
<td class="columnDigits columnPackages">{#$updateServer->packages}</td>
66-
<td class="columnStatus"><span class="badge{if $updateServer->status == 'online'} green{else} red{/if}">{@$updateServer->status}</span></td>
67-
<td class="columnText columnErrorText" title="{$updateServer->errorMessage}">{$updateServer->errorMessage|truncate:"30"}</td>
68-
<td class="columnDate columnTimestamp">{if $updateServer->lastUpdateTime}{@$updateServer->lastUpdateTime|time}{/if}</td>
69-
70-
{event name='columns'}
71-
</tr>
72-
{/foreach}
73-
</tbody>
74-
</table>
75-
76-
</div>
77-
78-
<footer class="contentFooter">
79-
{hascontent}
80-
<div class="paginationBottom">
81-
{content}{@$pagesLinks}{/content}
82-
</div>
83-
{/hascontent}
84-
85-
<nav class="contentFooterNavigation">
86-
<ul>
87-
<li><a href="{link controller='PackageUpdateServerAdd'}{/link}" class="button">{icon name='plus'} <span>{lang}wcf.acp.updateServer.add{/lang}</span></a></li>
88-
89-
{event name='contentFooterNavigation'}
90-
</ul>
91-
</nav>
92-
</footer>
93-
{else}
94-
<woltlab-core-notice type="info">{lang}wcf.global.noItems{/lang}</woltlab-core-notice>
95-
{/if}
17+
<div class="section">
18+
{unsafe:$gridView->render()}
19+
</div>
9620

9721
{include file='footer'}

wcfsetup/install/files/lib/acp/page/PackageUpdateServerListPage.class.php

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22

33
namespace wcf\acp\page;
44

5-
use wcf\data\package\update\server\PackageUpdateServerList;
6-
use wcf\page\SortablePage;
5+
use wcf\page\AbstractGridViewPage;
6+
use wcf\system\gridView\AbstractGridView;
7+
use wcf\system\gridView\admin\PackageUpdateServerGridView;
78

89
/**
910
* Shows information about available update package servers.
1011
*
11-
* @author Marcel Werk
12-
* @copyright 2001-2019 WoltLab GmbH
13-
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
12+
* @author Olaf Braun, Marcel Werk
13+
* @copyright 2001-2025 WoltLab GmbH
14+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
1415
*
15-
* @property PackageUpdateServerList $objectList
16+
* @property PackageUpdateServerGridView $gridView
1617
*/
17-
class PackageUpdateServerListPage extends SortablePage
18+
class PackageUpdateServerListPage extends AbstractGridViewPage
1819
{
1920
/**
2021
* @inheritDoc
@@ -26,36 +27,9 @@ class PackageUpdateServerListPage extends SortablePage
2627
*/
2728
public $neededPermissions = ['admin.configuration.package.canEditServer'];
2829

29-
/**
30-
* @inheritDoc
31-
*/
32-
public $defaultSortField = 'serverURL';
33-
34-
/**
35-
* @inheritDoc
36-
*/
37-
public $validSortFields = [
38-
'packageUpdateServerID',
39-
'serverURL',
40-
'loginUsername',
41-
'status',
42-
'errorMessage',
43-
'lastUpdateTime',
44-
'packages',
45-
];
46-
47-
/**
48-
* @inheritDoc
49-
*/
50-
public $objectListClassName = PackageUpdateServerList::class;
51-
52-
/**
53-
* @inheritDoc
54-
*/
55-
public function readObjects()
30+
#[\Override]
31+
protected function createGridViewController(): AbstractGridView
5632
{
57-
$this->sqlOrderBy = ($this->sortField != 'packages' ? 'package_update_server.' : '') . $this->sortField . ' ' . $this->sortOrder;
58-
59-
parent::readObjects();
33+
return new PackageUpdateServerGridView();
6034
}
6135
}

wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ static function (\wcf\event\endpoint\ControllerCollecting $event) {
190190
$event->register(new \wcf\system\endpoint\controller\core\pages\DisablePage());
191191
$event->register(new \wcf\system\endpoint\controller\core\pages\EnablePage());
192192
$event->register(new \wcf\system\endpoint\controller\core\templates\groups\DeleteTemplateGroup());
193+
$event->register(new \wcf\system\endpoint\controller\core\packages\updates\servers\DisableServer());
194+
$event->register(new \wcf\system\endpoint\controller\core\packages\updates\servers\DeleteServer());
195+
$event->register(new \wcf\system\endpoint\controller\core\packages\updates\servers\EnableServer());
193196
}
194197
);
195198

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace wcf\event\gridView\admin;
4+
5+
use wcf\event\IPsr14Event;
6+
use wcf\system\gridView\admin\PackageUpdateServerGridView;
7+
8+
/**
9+
* Indicates that the provider for package update server grid view has been initialized.
10+
*
11+
* @author Olaf Braun
12+
* @copyright 2001-2025 WoltLab GmbH
13+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
14+
* @since 6.2
15+
*/
16+
final class PackageUpdateServerGridViewInitialized implements IPsr14Event
17+
{
18+
public function __construct(public readonly PackageUpdateServerGridView $gridView)
19+
{
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace wcf\event\interaction\admin;
4+
5+
use wcf\event\IPsr14Event;
6+
use wcf\system\interaction\admin\PackageUpdateServerInteractions;
7+
8+
/**
9+
* Indicates that the provider for package update server interactions is collecting interactions.
10+
*
11+
* @author Olaf Braun
12+
* @copyright 2001-2025 WoltLab GmbH
13+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
14+
* @since 6.2
15+
*/
16+
final class PackageUpdateServerInteractionCollecting implements IPsr14Event
17+
{
18+
public function __construct(public readonly PackageUpdateServerInteractions $provider)
19+
{
20+
}
21+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace wcf\system\endpoint\controller\core\packages\updates\servers;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use wcf\data\package\update\server\PackageUpdateServer;
9+
use wcf\data\package\update\server\PackageUpdateServerAction;
10+
use wcf\http\Helper;
11+
use wcf\system\endpoint\DeleteRequest;
12+
use wcf\system\endpoint\IController;
13+
use wcf\system\exception\PermissionDeniedException;
14+
use wcf\system\WCF;
15+
16+
/**
17+
* API endpoint for the deletion of package update servers.
18+
*
19+
* @author Olaf Braun
20+
* @copyright 2001-2025 WoltLab GmbH
21+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
22+
* @since 6.2
23+
*/
24+
#[DeleteRequest('/core/packages/updates/servers/{id}')]
25+
final class DeleteServer implements IController
26+
{
27+
#[\Override]
28+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
29+
{
30+
$server = Helper::fetchObjectFromRequestParameter($variables['id'], PackageUpdateServer::class);
31+
32+
$this->assertServerCanBeDeleted($server);
33+
34+
(new PackageUpdateServerAction([$server], 'delete'))->executeAction();
35+
36+
return new JsonResponse([]);
37+
}
38+
39+
private function assertServerCanBeDeleted(PackageUpdateServer $server): void
40+
{
41+
WCF::getSession()->checkPermissions(['admin.configuration.package.canEditServer']);
42+
43+
if (!$server->canDelete()) {
44+
throw new PermissionDeniedException();
45+
}
46+
}
47+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace wcf\system\endpoint\controller\core\packages\updates\servers;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use wcf\data\package\update\server\PackageUpdateServer;
9+
use wcf\data\package\update\server\PackageUpdateServerAction;
10+
use wcf\http\Helper;
11+
use wcf\system\endpoint\IController;
12+
use wcf\system\endpoint\PostRequest;
13+
use wcf\system\exception\PermissionDeniedException;
14+
use wcf\system\WCF;
15+
16+
/**
17+
* API endpoint for disabling package update servers.
18+
*
19+
* @author Olaf Braun
20+
* @copyright 2001-2025 WoltLab GmbH
21+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
22+
* @since 6.2
23+
*/
24+
#[PostRequest('/core/packages/updates/servers/{id}/disable')]
25+
final class DisableServer implements IController
26+
{
27+
#[\Override]
28+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
29+
{
30+
$server = Helper::fetchObjectFromRequestParameter($variables['id'], PackageUpdateServer::class);
31+
32+
$this->assertServerCanBeDisabled($server);
33+
34+
(new PackageUpdateServerAction([$server], 'toggle'))->executeAction();
35+
36+
return new JsonResponse([]);
37+
}
38+
39+
private function assertServerCanBeDisabled(PackageUpdateServer $server): void
40+
{
41+
WCF::getSession()->checkPermissions(['admin.configuration.package.canEditServer']);
42+
43+
if (!$server->canDisable()) {
44+
throw new PermissionDeniedException();
45+
}
46+
if ($server->isDisabled) {
47+
throw new PermissionDeniedException();
48+
}
49+
}
50+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace wcf\system\endpoint\controller\core\packages\updates\servers;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use wcf\data\package\update\server\PackageUpdateServer;
9+
use wcf\data\package\update\server\PackageUpdateServerAction;
10+
use wcf\http\Helper;
11+
use wcf\system\endpoint\IController;
12+
use wcf\system\endpoint\PostRequest;
13+
use wcf\system\exception\PermissionDeniedException;
14+
use wcf\system\WCF;
15+
16+
/**
17+
* API endpoint for enabling package update servers.
18+
*
19+
* @author Olaf Braun
20+
* @copyright 2001-2025 WoltLab GmbH
21+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
22+
* @since 6.2
23+
*/
24+
#[PostRequest('/core/packages/updates/servers/{id}/enable')]
25+
final class EnableServer implements IController
26+
{
27+
#[\Override]
28+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
29+
{
30+
$server = Helper::fetchObjectFromRequestParameter($variables['id'], PackageUpdateServer::class);
31+
32+
$this->assertServerCanBeEnabled($server);
33+
34+
(new PackageUpdateServerAction([$server], 'toggle'))->executeAction();
35+
36+
return new JsonResponse([]);
37+
}
38+
39+
private function assertServerCanBeEnabled(PackageUpdateServer $server): void
40+
{
41+
WCF::getSession()->checkPermissions(['admin.configuration.package.canEditServer']);
42+
43+
if (!$server->canDisable()) {
44+
throw new PermissionDeniedException();
45+
}
46+
if (!$server->isDisabled) {
47+
throw new PermissionDeniedException();
48+
}
49+
}
50+
}

0 commit comments

Comments
 (0)