Skip to content

Commit 225c6cd

Browse files
authored
Merge pull request #6207 from WoltLab/6.2-PaidSubscriptionListPage-to-grid-view
Migrate `PaidSubscriptionListPage` to grid view
2 parents cd9946f + 8928530 commit 225c6cd

File tree

13 files changed

+429
-85
lines changed

13 files changed

+429
-85
lines changed

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

Lines changed: 4 additions & 64 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.paidSubscription.list{/lang}{if $items} <span class="badge badgeInverse">{#$items}</span>{/if}</h1>
5+
<h1 class="contentTitle">{lang}wcf.acp.paidSubscription.list{/lang} <span class="badge badgeInverse">{#$gridView->countRows()}</span></h1>
66
</div>
77

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

17-
{hascontent}
18-
<div class="paginationTop">
19-
{content}{pages print=true assign=pagesLinks controller='PaidSubscriptionList' 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\paid\subscription\PaidSubscriptionAction">
26-
<thead>
27-
<tr>
28-
<th class="columnID columnSubscriptionID{if $sortField == 'subscriptionID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='PaidSubscriptionList'}pageNo={@$pageNo}&sortField=subscriptionID&sortOrder={if $sortField == 'subscriptionID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
29-
<th class="columnTitle{if $sortField == 'title'} active {@$sortOrder}{/if}"><a href="{link controller='PaidSubscriptionList'}pageNo={@$pageNo}&sortField=title&sortOrder={if $sortField == 'title' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.title{/lang}</a></th>
30-
<th class="columnDigits columnCost{if $sortField == 'cost'} active {@$sortOrder}{/if}"><a href="{link controller='PaidSubscriptionList'}pageNo={@$pageNo}&sortField=cost&sortOrder={if $sortField == 'cost' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.paidSubscription.cost{/lang}</a></th>
31-
<th class="columnDigits columnSubscriptionLength{if $sortField == 'subscriptionLength'} active {@$sortOrder}{/if}"><a href="{link controller='PaidSubscriptionList'}pageNo={@$pageNo}&sortField=subscriptionLength&sortOrder={if $sortField == 'subscriptionLength' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.paidSubscription.subscriptionLength{/lang}</a></th>
32-
<th class="columnDigits columnShowOrder{if $sortField == 'showOrder'} active {@$sortOrder}{/if}"><a href="{link controller='PaidSubscriptionList'}pageNo={@$pageNo}&sortField=showOrder&sortOrder={if $sortField == 'showOrder' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.showOrder{/lang}</a></th>
33-
34-
{event name='columnHeads'}
35-
</tr>
36-
</thead>
37-
38-
<tbody class="jsReloadPageWhenEmpty">
39-
{foreach from=$objects item=subscription}
40-
<tr class="jsPaidSubscriptionRow jsObjectActionObject" data-object-id="{@$subscription->getObjectID()}">
41-
<td class="columnIcon">
42-
{objectAction action="toggle" isDisabled=$subscription->isDisabled}
43-
<a href="{link controller='PaidSubscriptionEdit' id=$subscription->subscriptionID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip">{icon name='pencil'}</a>
44-
{objectAction action="delete" objectTitle=$subscription->getTitle()}
45-
<a href="{link controller='PaidSubscriptionUserAdd' id=$subscription->subscriptionID}{/link}" title="{lang}wcf.acp.paidSubscription.user.add{/lang}" class="jsTooltip">{icon name='plus'}</a>
46-
47-
{event name='itemButtons'}
48-
</td>
49-
<td class="columnID columnSubscriptionID">{@$subscription->subscriptionID}</td>
50-
<td class="columnTitle"><a href="{link controller='PaidSubscriptionEdit' id=$subscription->subscriptionID}{/link}" title="{lang}wcf.acp.paidSubscription.edit{/lang}">{$subscription->getTitle()}</a></td>
51-
<td class="columnDigits columnCost">{@$subscription->currency} {$subscription->cost|currency}</td>
52-
<td class="columnDigits columnSubscriptionLength">{if $subscription->subscriptionLength}{@$subscription->subscriptionLength} {lang}wcf.acp.paidSubscription.subscriptionLengthUnit.{@$subscription->subscriptionLengthUnit}{/lang}{else}&infin;{/if}</td>
53-
<td class="columnDigits columnShowOrder">{@$subscription->showOrder}</td>
54-
55-
{event name='columns'}
56-
</tr>
57-
{/foreach}
58-
</tbody>
59-
</table>
60-
</div>
61-
62-
<footer class="contentFooter">
63-
{hascontent}
64-
<div class="paginationBottom">
65-
{content}{@$pagesLinks}{/content}
66-
</div>
67-
{/hascontent}
68-
69-
<nav class="contentFooterNavigation">
70-
<ul>
71-
<li><a href="{link controller='PaidSubscriptionAdd'}{/link}" class="button">{icon name='plus'} <span>{lang}wcf.acp.paidSubscription.add{/lang}</span></a></li>
72-
73-
{event name='contentFooterNavigation'}
74-
</ul>
75-
</nav>
76-
</footer>
77-
{else}
78-
<woltlab-core-notice type="info">{lang}wcf.global.noItems{/lang}</woltlab-core-notice>
79-
{/if}
17+
<div class="section">
18+
{unsafe:$gridView->render()}
19+
</div>
8020

8121
{include file='footer'}

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

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

33
namespace wcf\acp\page;
44

5-
use wcf\data\paid\subscription\PaidSubscriptionList;
6-
use wcf\page\SortablePage;
5+
use wcf\page\AbstractGridViewPage;
6+
use wcf\system\gridView\AbstractGridView;
7+
use wcf\system\gridView\admin\PaidSubscriptionGridView;
78

89
/**
910
* Shows the list of paid subscriptions.
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 PaidSubscriptionList $objectList
16+
* @property PaidSubscriptionGridView $gridView
1617
*/
17-
class PaidSubscriptionListPage extends SortablePage
18+
class PaidSubscriptionListPage extends AbstractGridViewPage
1819
{
1920
/**
2021
* @inheritDoc
@@ -31,18 +32,9 @@ class PaidSubscriptionListPage extends SortablePage
3132
*/
3233
public $neededPermissions = ['admin.paidSubscription.canManageSubscription'];
3334

34-
/**
35-
* @inheritDoc
36-
*/
37-
public $defaultSortField = 'showOrder';
38-
39-
/**
40-
* @inheritDoc
41-
*/
42-
public $validSortFields = ['subscriptionID', 'title', 'showOrder', 'cost', 'subscriptionLength'];
43-
44-
/**
45-
* @inheritDoc
46-
*/
47-
public $objectListClassName = PaidSubscriptionList::class;
35+
#[\Override]
36+
protected function createGridViewController(): AbstractGridView
37+
{
38+
return new PaidSubscriptionGridView();
39+
}
4840
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ static function (\wcf\event\endpoint\ControllerCollecting $event) {
193193
$event->register(new \wcf\system\endpoint\controller\core\packages\updates\servers\DisableServer());
194194
$event->register(new \wcf\system\endpoint\controller\core\packages\updates\servers\DeleteServer());
195195
$event->register(new \wcf\system\endpoint\controller\core\packages\updates\servers\EnableServer());
196+
$event->register(new \wcf\system\endpoint\controller\core\paid\subscriptions\DeleteSubscription());
197+
$event->register(new \wcf\system\endpoint\controller\core\paid\subscriptions\DisableSubscription());
198+
$event->register(new \wcf\system\endpoint\controller\core\paid\subscriptions\EnableSubscription());
196199
}
197200
);
198201

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace wcf\data\paid\subscription;
4+
5+
use wcf\data\I18nDatabaseObjectList;
6+
7+
/**
8+
* I18n implementation of paid subscriptions.
9+
*
10+
* @author Olaf Braun
11+
* @copyright 2001-2025 WoltLab GmbH
12+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
13+
*
14+
* @method PaidSubscription current()
15+
* @method PaidSubscription[] getObjects()
16+
* @method PaidSubscription|null getSingleObject()
17+
* @method PaidSubscription|null search($objectID)
18+
* @property PaidSubscription[] $objects
19+
*/
20+
class I18nPaidSubscriptionList extends I18nDatabaseObjectList
21+
{
22+
/**
23+
* @inheritDoc
24+
*/
25+
public $i18nFields = ['title' => 'titleI18n'];
26+
27+
/**
28+
* @inheritDoc
29+
*/
30+
public $className = PaidSubscription::class;
31+
}
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\PaidSubscriptionGridView;
7+
8+
/**
9+
* Indicates that the paid subscription 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 PaidSubscriptionGridViewInitialized implements IPsr14Event
17+
{
18+
public function __construct(public readonly PaidSubscriptionGridView $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\PaidSubscriptionInteractions;
7+
8+
/**
9+
* Indicates that the provider for paid subscription 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 PaidSubscriptionInteractionCollecting implements IPsr14Event
17+
{
18+
public function __construct(public readonly PaidSubscriptionInteractions $provider)
19+
{
20+
}
21+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace wcf\system\endpoint\controller\core\paid\subscriptions;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use wcf\data\paid\subscription\PaidSubscription;
9+
use wcf\data\paid\subscription\PaidSubscriptionAction;
10+
use wcf\http\Helper;
11+
use wcf\system\endpoint\DeleteRequest;
12+
use wcf\system\endpoint\IController;
13+
use wcf\system\WCF;
14+
15+
/**
16+
* API endpoint for deleting paid subscriptions.
17+
*
18+
* @author Olaf Braun
19+
* @copyright 2001-2025 WoltLab GmbH
20+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
21+
* @since 6.2
22+
*/
23+
#[DeleteRequest('/core/paid/subscriptions/{id:\d+}')]
24+
final class DeleteSubscription implements IController
25+
{
26+
#[\Override]
27+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
28+
{
29+
$subscription = Helper::fetchObjectFromRequestParameter($variables['id'], PaidSubscription::class);
30+
31+
$this->assertSubscriptionCanBeDeleted();
32+
33+
(new PaidSubscriptionAction([$subscription], 'delete'))->executeAction();
34+
35+
return new JsonResponse([]);
36+
}
37+
38+
private function assertSubscriptionCanBeDeleted(): void
39+
{
40+
WCF::getSession()->checkPermissions(['admin.paidSubscription.canManageSubscription']);
41+
}
42+
}
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\paid\subscriptions;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use wcf\data\paid\subscription\PaidSubscription;
9+
use wcf\data\paid\subscription\PaidSubscriptionAction;
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 paid subscriptions.
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/paid/subscriptions/{id:\d+}/disable')]
25+
final class DisableSubscription implements IController
26+
{
27+
#[\Override]
28+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
29+
{
30+
$subscription = Helper::fetchObjectFromRequestParameter($variables['id'], PaidSubscription::class);
31+
32+
$this->assertSubscriptionCanBeDisabled($subscription);
33+
34+
(new PaidSubscriptionAction([$subscription], 'toggle'))->executeAction();
35+
36+
return new JsonResponse([]);
37+
}
38+
39+
private function assertSubscriptionCanBeDisabled(PaidSubscription $subscription): void
40+
{
41+
WCF::getSession()->checkPermissions(['admin.paidSubscription.canManageSubscription']);
42+
43+
if ($subscription->isDisabled) {
44+
throw new PermissionDeniedException();
45+
}
46+
}
47+
}
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\paid\subscriptions;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use wcf\data\paid\subscription\PaidSubscription;
9+
use wcf\data\paid\subscription\PaidSubscriptionAction;
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 paid subscriptions.
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/paid/subscriptions/{id:\d+}/enable')]
25+
final class EnableSubscription implements IController
26+
{
27+
#[\Override]
28+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
29+
{
30+
$subscription = Helper::fetchObjectFromRequestParameter($variables['id'], PaidSubscription::class);
31+
32+
$this->assertSubscriptionCanBeEnabled($subscription);
33+
34+
(new PaidSubscriptionAction([$subscription], 'toggle'))->executeAction();
35+
36+
return new JsonResponse([]);
37+
}
38+
39+
private function assertSubscriptionCanBeEnabled(PaidSubscription $subscription): void
40+
{
41+
WCF::getSession()->checkPermissions(['admin.paidSubscription.canManageSubscription']);
42+
43+
if (!$subscription->isDisabled) {
44+
throw new PermissionDeniedException();
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)