Skip to content

Commit a5de0cc

Browse files
committed
make discord webhook to grid view
1 parent 1ad8b35 commit a5de0cc

9 files changed

Lines changed: 193 additions & 128 deletions

File tree

acptemplates/discordBotList.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
</header>
1515

1616
<div class="section">
17-
{unsafe:$gridView->render()}
17+
{unsafe:$gridView->render()}
1818
</div>
1919

2020
{include file='footer'}

acptemplates/discordWebhookList.tpl

Lines changed: 3 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -6,91 +6,8 @@
66
</div>
77
</header>
88

9-
{hascontent}
10-
<div class="paginationTop">
11-
{content}
12-
{pages print=true assign=pagesLinks controller='DiscordWebhookList' link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}
13-
{/content}
14-
</div>
15-
{/hascontent}
16-
17-
{if $objects|count}
18-
<div class="section tabularBox">
19-
<table class="table jsObjectActionContainer" data-object-action-class-name="wcf\data\discord\webhook\DiscordWebhookAction">
20-
<thead>
21-
<tr>
22-
<th class="columnIcon"></th>
23-
<th class="columnText columnWebhookID{if $sortField == 'webhookID'} active {$sortOrder}{/if}"><a href="{link controller='DiscordWebhookList'}pageNo={$pageNo}&sortField=webhookID&sortOrder={if $sortField == 'webhookID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
24-
<th class="columnText columnChannelID{if $sortField == 'channelID'} active {$sortOrder}{/if}"><a href="{link controller='DiscordWebhookList'}pageNo={$pageNo}&sortField=channelID&sortOrder={if $sortField == 'channelID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.discordWebhookList.channelID{/lang}</a></th>
25-
<th class="columnText columnWebhookTitle{if $sortField == 'webhookTitle'} active {$sortOrder}{/if}"><a href="{link controller='DiscordWebhookList'}pageNo={$pageNo}&sortField=webhookTitle&sortOrder={if $sortField == 'webhookTitle' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.discordWebhookList.webhookTitle{/lang}</a></th>
26-
<th class="columnText columnWebhook-Name{if $sortField == 'webhookName'} active {$sortOrder}{/if}"><a href="{link controller='DiscordWebhookList'}pageNo={$pageNo}&sortField=webhookName&sortOrder={if $sortField == 'webhookName' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.discordWebhookList.webhookName{/lang}</a></th>
27-
<th class="columnText columnBotID{if $sortField == 'botID'} active {$sortOrder}{/if}"><a href="{link controller='DiscordWebhookList'}pageNo={$pageNo}&sortField=botID&sortOrder={if $sortField == 'botID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.discordBotList.server{/lang}</a></th>
28-
<th class="columnDate columnWebhookTime{if $sortField == 'webhookTime'} active {$sortOrder}{/if}"><a href="{link controller='DiscordWebhookList'}pageNo={$pageNo}&sortField=webhookTime&sortOrder={if $sortField == 'webhookTime' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.date{/lang}</a></th>
29-
30-
{event name='columns'}
31-
</tr>
32-
</thead>
33-
34-
<tbody>
35-
{foreach from=$objects item=webhook}
36-
<tr class="jsObjectActionObject" data-object-id="{$webhook->webhookID}">
37-
<td class="columnIcon">
38-
{objectAction action="delete" objectTitle=$webhook->webhookName}
39-
40-
{event name='icons'}
41-
</td>
42-
<td class="webhookID">
43-
{$webhook->webhookID}
44-
</td>
45-
<td class="webhookID">
46-
{if $channels[$webhook->botID][$webhook->channelID]|isset}
47-
{$channels[$webhook->botID][$webhook->channelID]['name']}<br>({$webhook->channelID})
48-
{else}
49-
{$webhook->channelID}
50-
{/if}
51-
</td>
52-
<td class="columnText">
53-
{$webhook->webhookTitle}
54-
</td>
55-
<td class="columnText">
56-
{$webhook->webhookName}
57-
</td>
58-
<td class="columnText">
59-
{if !$webhook->getDiscordBot()->guildIcon|empty}
60-
<img src="https://cdn.discordapp.com/icons/{$webhook->getDiscordBot()->guildID}/{$webhook->getDiscordBot()->guildIcon}.png" style="max-width: 32px; border-radius: 50%; margin-right: 10px;">
61-
{/if}
62-
{$webhook->getDiscordBot()->guildName}
63-
</td>
64-
<td class="columnDate">
65-
{time time=$webhook->webhookTime}
66-
</td>
67-
68-
{event name='columnsItem'}
69-
</tr>
70-
{/foreach}
71-
</tbody>
72-
</table>
73-
</div>
74-
75-
<footer class="contentFooter">
76-
{hascontent}
77-
<div class="paginationBottom">
78-
{content}{unsafe:$pagesLinks}{/content}
79-
</div>
80-
{/hascontent}
81-
82-
{hascontent}
83-
<nav class="contentFooterNavigation">
84-
<ul>
85-
{content}
86-
{event name='contentFooterNavigation'}
87-
{/content}
88-
</ul>
89-
</nav>
90-
{/hascontent}
91-
</footer>
92-
{else}
93-
<p class="info">{lang}wcf.global.noItems{/lang}</p>
94-
{/if}
9+
<div class="section">
10+
{unsafe:$gridView->render()}
11+
</div>
9512

9613
{include file='footer'}

files/lib/acp/page/DiscordBotListPage.class.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@
1717
*/
1818
final class DiscordBotListPage extends AbstractGridViewPage
1919
{
20+
/**
21+
* @inheritDoc
22+
*/
23+
public $neededPermissions = ['admin.discord.canManageConnection'];
24+
25+
/**
26+
* @inheritDoc
27+
*/
2028
public $activeMenuItem = 'wcf.acp.menu.link.configuration.discord.discordBotList';
2129

2230
#[Override]

files/lib/acp/page/DiscordWebhookListPage.class.php

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
namespace wcf\acp\page;
44

55
use Override;
6-
use wcf\data\discord\webhook\DiscordWebhookList;
7-
use wcf\page\SortablePage;
8-
use wcf\system\cache\builder\DiscordGuildChannelsCacheBuilder;
9-
use wcf\system\WCF;
6+
use wcf\page\AbstractGridViewPage;
7+
use wcf\system\gridView\AbstractGridView;
8+
use wcf\system\gridView\admin\DiscordWebhookGridView;
109

1110
/**
1211
* Übersicht der erstellten Discord-Webhooks
@@ -16,7 +15,7 @@
1615
* @license Freie Lizenz (https://hanashi.dev/freie-lizenz/)
1716
* @package WoltLabSuite\Core\Acp\Page
1817
*/
19-
class DiscordWebhookListPage extends SortablePage
18+
final class DiscordWebhookListPage extends AbstractGridViewPage
2019
{
2120
/**
2221
* @inheritDoc
@@ -28,43 +27,9 @@ class DiscordWebhookListPage extends SortablePage
2827
*/
2928
public $activeMenuItem = 'wcf.acp.menu.link.configuration.discord.discordWebhookList';
3029

31-
/**
32-
* @inheritDoc
33-
*/
34-
public $objectListClassName = DiscordWebhookList::class;
35-
36-
/**
37-
* @inheritDoc
38-
*/
39-
public $defaultSortField = 'webhookID';
40-
41-
/**
42-
* @inheritDoc
43-
*/
44-
public $defaultSortOrder = 'ASC';
45-
46-
/**
47-
* @inheritDoc
48-
*/
49-
public $validSortFields = ['channelID', 'botID', 'webhookID', 'webhookName', 'webhookTitle', 'webhookTime'];
50-
51-
protected array $channels = [];
52-
5330
#[Override]
54-
public function readData()
31+
protected function createGridView(): AbstractGridView
5532
{
56-
parent::readData();
57-
58-
$this->channels = DiscordGuildChannelsCacheBuilder::getInstance()->getData();
59-
}
60-
61-
#[Override]
62-
public function assignVariables()
63-
{
64-
parent::assignVariables();
65-
66-
WCF::getTPL()->assign([
67-
'channels' => $this->channels,
68-
]);
33+
return new DiscordWebhookGridView();
6934
}
7035
}

files/lib/bootstrap/dev.hanashi.wsc.discord-api.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use wcf\event\endpoint\ControllerCollecting;
99
use wcf\event\worker\RebuildWorkerCollecting;
1010
use wcf\system\endpoint\controller\hanashi\discord\bot\DeleteBot;
11+
use wcf\system\endpoint\controller\hanashi\discord\webhook\DeleteWebhook;
1112
use wcf\system\event\EventHandler;
1213
use wcf\system\menu\acp\AcpMenuItem;
1314
use wcf\system\request\LinkHandler;
@@ -84,6 +85,7 @@ static function (RebuildWorkerCollecting $event) {
8485
ControllerCollecting::class,
8586
static function (ControllerCollecting $event) {
8687
$event->register(new DeleteBot());
88+
$event->register(new DeleteWebhook());
8789
}
8890
);
8991
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace wcf\event\interaction\admin;
4+
5+
use wcf\event\IPsr14Event;
6+
use wcf\system\interaction\admin\DiscordWebhookInteractions;
7+
8+
final class DiscordWebhookInteractionCollecting implements IPsr14Event
9+
{
10+
public function __construct(public readonly DiscordWebhookInteractions $provider)
11+
{
12+
}
13+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace wcf\system\endpoint\controller\hanashi\discord\webhook;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Override;
7+
use Psr\Http\Message\ResponseInterface;
8+
use Psr\Http\Message\ServerRequestInterface;
9+
use wcf\data\discord\webhook\DiscordWebhook;
10+
use wcf\data\discord\webhook\DiscordWebhookAction;
11+
use wcf\http\Helper;
12+
use wcf\system\endpoint\DeleteRequest;
13+
use wcf\system\endpoint\IController;
14+
use wcf\system\WCF;
15+
16+
#[DeleteRequest('/hanashi/discord/webhook/{id:\d+}')]
17+
final class DeleteWebhook implements IController
18+
{
19+
#[Override]
20+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
21+
{
22+
$bot = Helper::fetchObjectFromRequestParameter($variables['id'], DiscordWebhook::class);
23+
24+
WCF::getSession()->checkPermissions(['admin.discord.canManageWebhooks']);
25+
26+
$action = new DiscordWebhookAction([$bot], 'delete');
27+
$action->executeAction();
28+
29+
return new JsonResponse([]);
30+
}
31+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
namespace wcf\system\gridView\admin;
4+
5+
use Override;
6+
use wcf\data\DatabaseObjectList;
7+
use wcf\data\discord\webhook\DiscordWebhook;
8+
use wcf\data\discord\webhook\DiscordWebhookList;
9+
use wcf\system\cache\builder\DiscordGuildChannelsCacheBuilder;
10+
use wcf\system\gridView\AbstractGridView;
11+
use wcf\system\gridView\filter\TextFilter;
12+
use wcf\system\gridView\filter\TimeFilter;
13+
use wcf\system\gridView\GridViewColumn;
14+
use wcf\system\gridView\renderer\DefaultColumnRenderer;
15+
use wcf\system\gridView\renderer\TimeColumnRenderer;
16+
use wcf\system\interaction\admin\DiscordWebhookInteractions;
17+
18+
final class DiscordWebhookGridView extends AbstractGridView
19+
{
20+
public function __construct()
21+
{
22+
$this->addColumns([
23+
GridViewColumn::for('webhookID')
24+
->label('wcf.global.objectID')
25+
->sortable(),
26+
GridViewColumn::for('channelID')
27+
->label('wcf.acp.discordWebhookList.channelID')
28+
->renderer([
29+
new class extends DefaultColumnRenderer {
30+
public function render(mixed $value, mixed $context = null): string
31+
{
32+
\assert($context instanceof DiscordWebhook);
33+
34+
$channels = DiscordGuildChannelsCacheBuilder::getInstance()->getData();
35+
36+
if (!isset($channels[$context->botID][$value])) {
37+
return $value;
38+
}
39+
40+
return \sprintf('%s<br>(%s)', $channels[$context->botID][$value]['name'], $value);
41+
}
42+
},
43+
])
44+
->sortable(),
45+
GridViewColumn::for('webhookTitle')
46+
->label('wcf.acp.discordWebhookList.webhookTitle')
47+
->titleColumn()
48+
->sortable()
49+
->filter(new TextFilter()),
50+
GridViewColumn::for('webhookName')
51+
->label('wcf.acp.discordWebhookList.webhookName')
52+
->sortable()
53+
->filter(new TextFilter()),
54+
GridViewColumn::for('botID')
55+
->label('wcf.acp.discordBotList.server')
56+
->renderer([
57+
new class extends DefaultColumnRenderer {
58+
public function render(mixed $value, mixed $context = null): string
59+
{
60+
\assert($context instanceof DiscordWebhook);
61+
62+
$bot = $context->getDiscordBot();
63+
64+
$content = '';
65+
if (!empty($bot->guildIcon)) {
66+
$content = \sprintf(
67+
'<img
68+
src="https://cdn.discordapp.com/icons/%s/%s.png"
69+
style="max-width: 32px; border-radius: 50%%; margin-right: 10px;"
70+
>',
71+
$bot->guildID,
72+
$bot->guildIcon
73+
);
74+
}
75+
76+
return $content . $bot->guildName;
77+
}
78+
},
79+
]),
80+
GridViewColumn::for('webhookTime')
81+
->label('wcf.global.date')
82+
->renderer(new TimeColumnRenderer())
83+
->sortable()
84+
->filter(new TimeFilter()),
85+
]);
86+
87+
$provider = new DiscordWebhookInteractions();
88+
$this->setInteractionProvider($provider);
89+
90+
$this->setSortField('webhookID');
91+
$this->setSortOrder('ASC');
92+
}
93+
94+
#[Override]
95+
protected function createObjectList(): DatabaseObjectList
96+
{
97+
return new DiscordWebhookList();
98+
}
99+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace wcf\system\interaction\admin;
4+
5+
use Override;
6+
use wcf\data\discord\bot\DiscordBot;
7+
use wcf\event\interaction\admin\DiscordWebhookInteractionCollecting;
8+
use wcf\system\event\EventHandler;
9+
use wcf\system\interaction\AbstractInteractionProvider;
10+
use wcf\system\interaction\DeleteInteraction;
11+
12+
final class DiscordWebhookInteractions extends AbstractInteractionProvider
13+
{
14+
public function __construct()
15+
{
16+
$this->addInteractions([
17+
new DeleteInteraction('hanashi/discord/webhook/%s'),
18+
]);
19+
20+
EventHandler::getInstance()->fire(
21+
new DiscordWebhookInteractionCollecting($this)
22+
);
23+
}
24+
25+
#[Override]
26+
public function getObjectClassName(): string
27+
{
28+
return DiscordBot::class;
29+
}
30+
}

0 commit comments

Comments
 (0)