Skip to content

Commit 95a98c6

Browse files
authored
Merge pull request #6201 from WoltLab/6.2-language-list-to-grid-view
Migrate `LanguageListPage` to grid view
2 parents 0bf4a3c + c34bbab commit 95a98c6

File tree

11 files changed

+497
-143
lines changed

11 files changed

+497
-143
lines changed

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

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

88
<nav class="contentHeaderNavigation">
@@ -15,92 +15,8 @@
1515
</nav>
1616
</header>
1717

18-
{hascontent}
19-
<div class="paginationTop">
20-
{content}{pages print=true assign=pagesLinks controller='LanguageList' link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}{/content}
21-
</div>
22-
{/hascontent}
23-
24-
{if $objects|count}
25-
<div id="userTableContainer" class="section tabularBox">
26-
<table class="table jsObjectActionContainer" data-object-action-class-name="wcf\data\language\LanguageAction">
27-
<thead>
28-
<tr>
29-
<th class="columnID columnLanguageID{if $sortField == 'languageID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='LanguageList'}pageNo={@$pageNo}&sortField=languageID&sortOrder={if $sortField == 'languageID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
30-
<th class="columnTitle columnLanguageName{if $sortField == 'languageName'} active {@$sortOrder}{/if}"><a href="{link controller='LanguageList'}pageNo={@$pageNo}&sortField=languageName&sortOrder={if $sortField == 'languageName' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.name{/lang}</a></th>
31-
<th class="columnDigits columnUsers{if $sortField == 'users'} active {@$sortOrder}{/if}"><a href="{link controller='LanguageList'}pageNo={@$pageNo}&sortField=users&sortOrder={if $sortField == 'users' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.language.users{/lang}</a></th>
32-
<th class="columnDigits columnVariables{if $sortField == 'variables'} active {@$sortOrder}{/if}"><a href="{link controller='LanguageList'}pageNo={@$pageNo}&sortField=variables&sortOrder={if $sortField == 'variables' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.language.variables{/lang}</a></th>
33-
<th class="columnDigits columnCustomVariables{if $sortField == 'customVariables'} active {@$sortOrder}{/if}"><a href="{link controller='LanguageList'}pageNo={@$pageNo}&sortField=customVariables&sortOrder={if $sortField == 'customVariables' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.language.customVariables{/lang}</a></th>
34-
35-
{event name='columnHeads'}
36-
</tr>
37-
</thead>
38-
39-
<tbody class="jsReloadPageWhenEmpty">
40-
{foreach from=$objects item=language}
41-
<tr class="jsLanguageRow jsObjectActionObject" data-object-id="{@$language->getObjectID()}">
42-
<td class="columnIcon">
43-
<a href="{link controller='LanguageExport' id=$language->languageID}{/link}" title="{lang}wcf.acp.language.export{/lang}" class="jsTooltip">{icon name='download'}</a>
44-
45-
{if !$language->isDefault}
46-
{objectAction action="toggle" isDisabled=$language->isDisabled}
47-
<button type="button" class="jsObjectAction jsTooltip" data-object-action="setAsDefault" data-object-action-success="reload" title="{lang}wcf.acp.language.setAsDefault{/lang}">
48-
{icon name='circle-check'}
49-
</button>
50-
{else}
51-
<span class="disabled" title="{lang}wcf.global.button.{if $language->isDisabled}enable{else}disable{/if}{/lang}">
52-
{if $language->isDisabled}
53-
{icon name='square'}
54-
{else}
55-
{icon name='square-check'}
56-
{/if}
57-
</span>
58-
<span class="disabled" title="{lang}wcf.acp.language.setAsDefault{/lang}">
59-
{icon name='circle-check'}
60-
</span>
61-
{/if}
62-
63-
<a href="{link controller='LanguageEdit' id=$language->languageID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip">{icon name='pencil'}</a>
64-
65-
{if $language->isDeletable()}
66-
{objectAction action="delete" objectTitle=$language->languageName}
67-
{else}
68-
<span class="disabled" title="{lang}wcf.global.button.delete{/lang}">
69-
{icon name='xmark'}
70-
</span>
71-
{/if}
72-
73-
{event name='rowButtons'}
74-
</td>
75-
<td class="columnID columnLanguageID">{@$language->languageID}</td>
76-
<td class="columnTitle columnLanguageName"><a href="{link controller='LanguageEdit' id=$language->languageID}{/link}">{$language->languageName} ({@$language->languageCode})</a></td>
77-
<td class="columnDigits columnUsers">{#$language->users}</td>
78-
<td class="columnDigits columnVariables"><a href="{link controller='LanguageItemList'}languageID={@$language->languageID}{/link}">{#$language->variables}</a></td>
79-
<td class="columnDigits columnCustomVariables">{if $language->customVariables > 0}<a href="{link controller='LanguageItemList'}languageID={@$language->languageID}&hasCustomValue=1{/link}">{#$language->customVariables}</a>{else}{#$language->customVariables}{/if}</td>
80-
81-
{event name='columns'}
82-
</tr>
83-
{/foreach}
84-
</tbody>
85-
</table>
86-
</div>
87-
88-
<footer class="contentFooter">
89-
{hascontent}
90-
<div class="paginationBottom">
91-
{content}{@$pagesLinks}{/content}
92-
</div>
93-
{/hascontent}
94-
95-
<nav class="contentFooterNavigation">
96-
<ul>
97-
<li><a href="{link controller='LanguageAdd'}{/link}" class="button">{icon name='plus'} <span>{lang}wcf.acp.language.add{/lang}</span></a></li>
98-
<li><a href="{link controller='LanguageImport'}{/link}" class="button">{icon name='upload'} <span>{lang}wcf.acp.language.import{/lang}</span></a></li>
99-
100-
{event name='contentFooterNavigation'}
101-
</ul>
102-
</nav>
103-
</footer>
104-
{/if}
18+
<div class="section">
19+
{unsafe:$gridView->render()}
20+
</div>
10521

10622
{include file='footer'}

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

Lines changed: 11 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,78 +2,34 @@
22

33
namespace wcf\acp\page;
44

5-
use wcf\data\language\LanguageList;
6-
use wcf\page\SortablePage;
7-
use wcf\system\WCF;
5+
use wcf\page\AbstractGridViewPage;
6+
use wcf\system\gridView\AbstractGridView;
7+
use wcf\system\gridView\admin\LanguageGridView;
88

99
/**
1010
* Shows a list of all installed languages.
1111
*
12-
* @author Marcel Werk
13-
* @copyright 2001-2019 WoltLab GmbH
14-
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
12+
* @author Olaf Brau, Marcel Werk
13+
* @copyright 2001-2025 WoltLab GmbH
14+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
1515
*
16-
* @property LanguageList $objectList
16+
* @property LanguageGridView $gridView
1717
*/
18-
class LanguageListPage extends SortablePage
18+
class LanguageListPage extends AbstractGridViewPage
1919
{
2020
/**
2121
* @inheritDoc
2222
*/
2323
public $activeMenuItem = 'wcf.acp.menu.link.language.list';
2424

25-
/**
26-
* @inheritDoc
27-
*/
28-
public $defaultSortField = 'languageName';
29-
3025
/**
3126
* @inheritDoc
3227
*/
3328
public $neededPermissions = ['admin.language.canManageLanguage'];
3429

35-
/**
36-
* @inheritDoc
37-
*/
38-
public $objectListClassName = LanguageList::class;
39-
40-
/**
41-
* @inheritDoc
42-
*/
43-
public $validSortFields = ['languageID', 'languageCode', 'languageName', 'users', 'variables', 'customVariables'];
44-
45-
/**
46-
* @inheritDoc
47-
*/
48-
public function initObjectList()
30+
#[\Override]
31+
protected function createGridViewController(): AbstractGridView
4932
{
50-
parent::initObjectList();
51-
52-
$this->objectList->sqlSelects = "(
53-
SELECT COUNT(*)
54-
FROM wcf1_user user
55-
WHERE languageID = language.languageID
56-
) AS users, (
57-
SELECT COUNT(*)
58-
FROM wcf1_language_item
59-
WHERE languageID = language.languageID
60-
) AS variables, (
61-
SELECT COUNT(*)
62-
FROM wcf1_language_item
63-
WHERE languageID = language.languageID
64-
AND languageCustomItemValue IS NOT NULL
65-
) AS customVariables";
66-
}
67-
68-
/**
69-
* @inheritDoc
70-
*/
71-
public function assignVariables()
72-
{
73-
parent::assignVariables();
74-
75-
WCF::getTPL()->assign([
76-
'languages' => $this->objectList->getObjects(),
77-
]);
33+
return new LanguageGridView();
7834
}
7935
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ static function (\wcf\event\endpoint\ControllerCollecting $event) {
180180
$event->register(new \wcf\system\endpoint\controller\core\bbcodes\media\providers\DisableProvider());
181181
$event->register(new \wcf\system\endpoint\controller\core\bbcodes\media\providers\EnableProvider());
182182
$event->register(new \wcf\system\endpoint\controller\core\bbCodes\DeleteBBCodes());
183+
$event->register(new \wcf\system\endpoint\controller\core\languages\DisableLanguage());
184+
$event->register(new \wcf\system\endpoint\controller\core\languages\DeleteLanguage());
185+
$event->register(new \wcf\system\endpoint\controller\core\languages\EnableLanguage());
186+
$event->register(new \wcf\system\endpoint\controller\core\languages\SetAsDefaultLanguage());
183187
$event->register(new \wcf\system\endpoint\controller\core\languages\items\DeleteItem());
184188
$event->register(new \wcf\system\endpoint\controller\core\labels\groups\DeleteGroup());
185189
}
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\LanguageGridView;
7+
8+
/**
9+
* Indicates that the language 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 LanguageGridViewInitialized implements IPsr14Event
17+
{
18+
public function __construct(public readonly LanguageGridView $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\LanguageInteractions;
7+
8+
/**
9+
* Indicates that the provider for language 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 LanguageInteractionCollecting implements IPsr14Event
17+
{
18+
public function __construct(public readonly LanguageInteractions $provider)
19+
{
20+
}
21+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace wcf\system\endpoint\controller\core\languages;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use wcf\data\language\Language;
9+
use wcf\data\language\LanguageAction;
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\language\LanguageFactory;
15+
use wcf\system\WCF;
16+
17+
/**
18+
* API endpoint for deleting languages.
19+
*
20+
* @author Olaf Braun
21+
* @copyright 2001-2025 WoltLab GmbH
22+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
23+
* @since 6.2
24+
*/
25+
#[DeleteRequest('/core/languages/{id:\d+}')]
26+
final class DeleteLanguage implements IController
27+
{
28+
#[\Override]
29+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
30+
{
31+
$language = Helper::fetchObjectFromRequestParameter($variables['id'], Language::class);
32+
33+
$this->assertLanguageCanBeDeleted($language);
34+
35+
(new LanguageAction([$language], 'delete'))->executeAction();
36+
37+
LanguageFactory::getInstance()->clearCache();
38+
LanguageFactory::getInstance()->deleteLanguageCache();
39+
40+
return new JsonResponse([]);
41+
}
42+
43+
private function assertLanguageCanBeDeleted(Language $language): void
44+
{
45+
WCF::getSession()->checkPermissions(['admin.language.canManageLanguage']);
46+
47+
if (!$language->isDeletable()) {
48+
throw new PermissionDeniedException();
49+
}
50+
}
51+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace wcf\system\endpoint\controller\core\languages;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use wcf\data\language\Language;
9+
use wcf\data\language\LanguageAction;
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 languages.
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/languages/{id:\d+}/disable')]
25+
final class DisableLanguage implements IController
26+
{
27+
#[\Override]
28+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
29+
{
30+
$language = Helper::fetchObjectFromRequestParameter($variables['id'], Language::class);
31+
32+
$this->assertLanguageCanBeDisabled($language);
33+
34+
(new LanguageAction([$language], 'toggle'))->executeAction();
35+
36+
return new JsonResponse([]);
37+
}
38+
39+
private function assertLanguageCanBeDisabled(Language $language): void
40+
{
41+
WCF::getSession()->checkPermissions(['admin.language.canManageLanguage']);
42+
43+
if ($language->isDefault) {
44+
throw new PermissionDeniedException();
45+
}
46+
47+
if ($language->isDisabled) {
48+
throw new PermissionDeniedException();
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)