-<div class="paginationTop">
- <woltlab-core-pagination id="{$view->getID()}_topPagination" page="{$view->getPageNo()}" count="{$view->countPages()}"></woltlab-core-pagination>
-</div>
+{if $view->countRows()}
+ <div class="paginationTop">
+ <woltlab-core-pagination id="{$view->getID()}_topPagination" page="{$view->getPageNo()}" count="{$view->countPages()}"></woltlab-core-pagination>
+ </div>
-<div class="section tabularBox">
- <table class="table" id="{$view->getID()}_table">
- <thead>
- <tr>
- {unsafe:$view->renderHeader()}
- </td>
- </thead>
- <tbody>
- {unsafe:$view->renderRows()}
- </tbody>
- </table>
-</div>
+ <div class="section tabularBox">
+ <table class="table" id="{$view->getID()}_table">
+ <thead>
+ <tr>
+ {unsafe:$view->renderHeader()}
+ </td>
+ </thead>
+ <tbody>
+ {unsafe:$view->renderRows()}
+ </tbody>
+ </table>
+ </div>
-<div class="paginationBottom">
- <woltlab-core-pagination id="{$view->getID()}_bottomPagination" page="{$view->getPageNo()}" count="{$view->countPages()}"></woltlab-core-pagination>
-</div>
+ <div class="paginationBottom">
+ <woltlab-core-pagination id="{$view->getID()}_bottomPagination" page="{$view->getPageNo()}" count="{$view->countPages()}"></woltlab-core-pagination>
+ </div>
-<script data-relocate="true">
- require(['WoltLabSuite/Core/Component/GridView'], ({ GridView }) => {
- new GridView(
- '{unsafe:$view->getID()|encodeJs}',
- '{unsafe:$view->getClassName()|encodeJS}',
- {$view->getPageNo()},
- '{unsafe:$view->getBaseUrl()|encodeJS}',
- '{unsafe:$view->getSortField()|encodeJS}',
- '{unsafe:$view->getSortOrder()|encodeJS}'
- );
- });
-</script>
+ <script data-relocate="true">
+ require(['WoltLabSuite/Core/Component/GridView'], ({ GridView }) => {
+ new GridView(
+ '{unsafe:$view->getID()|encodeJs}',
+ '{unsafe:$view->getClassName()|encodeJS}',
+ {$view->getPageNo()},
+ '{unsafe:$view->getBaseUrl()|encodeJS}',
+ '{unsafe:$view->getSortField()|encodeJS}',
+ '{unsafe:$view->getSortOrder()|encodeJS}'
+ );
+ });
+ </script>
+{else}
+ <woltlab-core-notice type="info">{lang}wcf.global.noItems{/lang}</woltlab-core-notice>
+{/if}
<header class="contentHeader">
<div class="contentHeaderTitle">
- <h1 class="contentTitle">{lang}wcf.acp.user.rank.list{/lang} <span class="badge badgeInverse">{#$items}</span></h1>
+ <h1 class="contentTitle">{lang}wcf.acp.user.rank.list{/lang} <span class="badge badgeInverse">{#$gridView->countRows()}</span></h1>
</div>
<nav class="contentHeaderNavigation">
</nav>
</header>
-{hascontent}
- <div class="paginationTop">
- {content}{pages print=true assign=pagesLinks controller="UserRankList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}{/content}
- </div>
-{/hascontent}
-
-{if $objects|count}
- {unsafe:$view->render()}
-
- {*<div class="section tabularBox">
- <table class="table jsObjectActionContainer" data-object-action-class-name="wcf\data\user\rank\UserRankAction">
- <thead>
- <tr>
- <th class="columnID columnRankID{if $sortField == 'rankID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='UserRankList'}pageNo={@$pageNo}&sortField=rankID&sortOrder={if $sortField == 'rankID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
- <th class="columnTitle columnRankTitle{if $sortField == 'rankTitleI18n'} active {@$sortOrder}{/if}"><a href="{link controller='UserRankList'}pageNo={@$pageNo}&sortField=rankTitleI18n&sortOrder={if $sortField == 'rankTitleI18n' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.user.rank.title{/lang}</a></th>
- <th class="columnText columnRankImage{if $sortField == 'rankImage'} active {@$sortOrder}{/if}"><a href="{link controller='UserRankList'}pageNo={@$pageNo}&sortField=rankImage&sortOrder={if $sortField == 'rankImage' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.user.rank.image{/lang}</a></th>
- <th class="columnText columnGroupID{if $sortField == 'groupID'} active {@$sortOrder}{/if}"><a href="{link controller='UserRankList'}pageNo={@$pageNo}&sortField=groupID&sortOrder={if $sortField == 'groupID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.user.group{/lang}</a></th>
- <th class="columnText columnRequiredGender{if $sortField == 'requiredGender'} active {@$sortOrder}{/if}"><a href="{link controller='UserRankList'}pageNo={@$pageNo}&sortField=requiredGender&sortOrder={if $sortField == 'requiredGender' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.user.option.gender{/lang}</a></th>
- <th class="columnDigits columnRequiredPoints{if $sortField == 'requiredPoints'} active {@$sortOrder}{/if}"><a href="{link controller='UserRankList'}pageNo={@$pageNo}&sortField=requiredPoints&sortOrder={if $sortField == 'requiredPoints' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.user.rank.requiredPoints{/lang}</a></th>
-
- {event name='columnHeads'}
- </tr>
- </thead>
-
- <tbody class="jsReloadPageWhenEmpty">
- {foreach from=$objects item=userRank}
- <tr class="jsUserRankRow jsObjectActionObject" data-object-id="{@$userRank->getObjectID()}">
- <td class="columnIcon">
- <a href="{link controller='UserRankEdit' id=$userRank->rankID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip">{icon name='pencil'}</a>
- {objectAction action="delete" objectTitle=$userRank->getTitle()}
-
- {event name='rowButtons'}
- </td>
- <td class="columnID columnRankID">{@$userRank->rankID}</td>
- <td class="columnTitle columnRankTitle"><a href="{link controller='UserRankEdit' id=$userRank->rankID}{/link}" title="{lang}wcf.acp.user.rank.edit{/lang}" class="badge label{if $userRank->cssClassName} {$userRank->cssClassName}{/if}">{$userRank->getTitle()}</a></td>
- <td class="columnText columnRankImage">{if $userRank->rankImage}{@$userRank->getImage()}{/if}</td>
- <td class="columnText columnGroupID">{$userRank->groupName|phrase}</td>
- <td class="columnText columnRequiredGender">
- {if $userRank->requiredGender}
- {if $userRank->requiredGender == 1}
- {lang}wcf.user.gender.male{/lang}
- {elseif $userRank->requiredGender == 2}
- {lang}wcf.user.gender.female{/lang}
- {else}
- {lang}wcf.user.gender.other{/lang}
- {/if}
- {/if}
- </td>
- <td class="columnDigits columnRequiredPoints">{#$userRank->requiredPoints}</td>
-
- {event name='columns'}
- </tr>
- {/foreach}
- </tbody>
- </table>
- </div>*}
-
- <footer class="contentFooter">
- {hascontent}
- <div class="paginationBottom">
- {content}{@$pagesLinks}{/content}
- </div>
- {/hascontent}
-
- <nav class="contentFooterNavigation">
- <ul>
- <li><a href="{link controller='UserRankAdd'}{/link}" class="button">{icon name='plus'} <span>{lang}wcf.acp.user.rank.add{/lang}</span></a></li>
-
- {event name='contentFooterNavigation'}
- </ul>
- </nav>
- </footer>
-{else}
- <woltlab-core-notice type="info">{lang}wcf.global.noItems{/lang}</woltlab-core-notice>
-{/if}
+{unsafe:$gridView->render()}
{include file='footer'}
namespace wcf\acp\page;
-use wcf\data\user\rank\I18nUserRankList;
-use wcf\page\SortablePage;
-use wcf\system\request\LinkHandler;
+use wcf\page\AbstractGridViewPage;
use wcf\system\view\grid\UserRankGridView;
-use wcf\system\WCF;
/**
* Lists available user ranks.
*
- * @author Marcel Werk
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @author Marcel Werk
+ * @copyright 2001-2024 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
*
- * @property I18nUserRankList $objectList
+ * @property UserRankGridView $gridView
*/
-class UserRankListPage extends SortablePage
+class UserRankListPage extends AbstractGridViewPage
{
/**
* @inheritDoc
/**
* @inheritDoc
*/
- public $objectListClassName = I18nUserRankList::class;
-
- /**
- * @inheritDoc
- */
- public $defaultSortField = 'rankTitleI18n';
-
- /**
- * @inheritDoc
- */
- public $validSortFields = ['rankID', 'groupID', 'requiredPoints', 'rankTitleI18n', 'rankImage', 'requiredGender'];
-
- /**
- * @inheritDoc
- */
- protected function initObjectList()
- {
- parent::initObjectList();
-
- $this->objectList->sqlSelects .= (!empty($this->objectList->sqlSelects) ? ', ' : '') . 'user_group.groupName';
- $this->objectList->sqlJoins .= '
- LEFT JOIN wcf' . WCF_N . '_user_group user_group
- ON user_group.groupID = user_rank.groupID';
- }
-
- public function assignVariables()
- {
- parent::assignVariables();
-
- $view = new UserRankGridView(isset($_GET['pageNo']) ? \intval($_GET['pageNo']) : 1);
- $view->setBaseUrl(LinkHandler::getInstance()->getControllerLink(self::class));
-
- WCF::getTPL()->assign([
- 'view' => $view,
- ]);
- }
+ protected string $gridViewClassName = UserRankGridView::class;
}
--- /dev/null
+<?php
+
+namespace wcf\page;
+
+use wcf\system\exception\ParentClassException;
+use wcf\system\exception\SystemException;
+use wcf\system\request\LinkHandler;
+use wcf\system\view\grid\AbstractGridView;
+use wcf\system\WCF;
+
+abstract class AbstractGridViewPage extends AbstractPage
+{
+ protected string $gridViewClassName;
+ protected AbstractGridView $gridView;
+ protected int $pageNo = 1;
+ protected string $sortField = '';
+ protected string $sortOrder = 'ASC';
+
+ #[\Override]
+ public function readParameters()
+ {
+ parent::readParameters();
+
+ if (isset($_REQUEST['pageNo'])) {
+ $this->pageNo = \intval($_REQUEST['pageNo']);
+ }
+ if (isset($_REQUEST['sortField'])) {
+ $this->sortField = $_REQUEST['sortField'];
+ }
+ if (isset($_REQUEST['sortOrder']) && ($_REQUEST['sortOrder'] === 'ASC' || $_REQUEST['sortOrder'] === 'DESC')) {
+ $this->sortOrder = $_REQUEST['sortOrder'];
+ }
+ }
+
+ #[\Override]
+ public function readData()
+ {
+ parent::readData();
+
+ $this->initGridView();
+ }
+
+ #[\Override]
+ public function assignVariables()
+ {
+ parent::assignVariables();
+
+ WCF::getTPL()->assign([
+ 'gridView' => $this->gridView,
+ ]);
+ }
+
+ protected function initGridView(): void
+ {
+ if (!isset($this->gridViewClassName)) {
+ throw new SystemException('Grid view class name not specified.');
+ }
+
+ if (!\is_subclass_of($this->gridViewClassName, AbstractGridView::class)) {
+ throw new ParentClassException($this->gridViewClassName, AbstractGridView::class);
+ }
+
+ $this->gridView = new $this->gridViewClassName;
+
+ if ($this->sortField) {
+ $this->gridView->setSortField($this->sortField);
+ }
+ $this->gridView->setSortOrder($this->sortOrder);
+ $this->gridView->setPageNo($this->pageNo);
+ $this->gridView->setBaseUrl(LinkHandler::getInstance()->getControllerLink(static::class));
+ }
+}
throw new UserInputException('gridView', 'invalid');
}
- $view = new $parameters->gridView($parameters->pageNo);
+ $view = new $parameters->gridView();
\assert($view instanceof AbstractGridView);
if (!$view->isAccessible()) {
throw new PermissionDeniedException();
}
+ $view->setPageNo($parameters->pageNo);
if ($parameters->sortField) {
$view->setSortField($parameters->sortField);
}
private string $baseUrl = '';
private string $sortField = '';
private string $sortOrder = 'ASC';
+ private int $pageNo = 1;
- public function __construct(private readonly int $pageNo = 1)
+ public function __construct()
{
$this->init();
}
{
$result = '';
- foreach ($this->getRows($this->rowsPerPage, ($this->pageNo - 1) * $this->rowsPerPage) as $row) {
+ foreach ($this->getRows() as $row) {
$result .= <<<EOT
<tr>
EOT;
return $row[$identifer] ?? '';
}
- public abstract function getRows(int $limit, int $offset = 0): array;
+ protected abstract function getRows(): array;
-
- public function getPageNo(): int
- {
- return $this->pageNo;
- }
+ public abstract function countRows(): int;
public function countPages(): int
{
- return 3;
+ return \ceil($this->countRows() / $this->getRowsPerPage());
}
public function getClassName(): string
{
return $this->sortOrder;
}
+
+ public function getPageNo(): int
+ {
+ return $this->pageNo;
+ }
+
+ public function setPageNo(int $pageNo): void
+ {
+ $this->pageNo = $pageNo;
+ }
+
+ public function getRowsPerPage(): int
+ {
+ return $this->rowsPerPage;
+ }
+
+ public function setRowsPerPage(int $rowsPerPage): void
+ {
+ $this->rowsPerPage = $rowsPerPage;
+ }
}
--- /dev/null
+<?php
+
+namespace wcf\system\view\grid;
+
+use wcf\data\DatabaseObject;
+use wcf\data\DatabaseObjectList;
+use wcf\system\exception\ParentClassException;
+use wcf\system\exception\SystemException;
+
+abstract class DatabaseObjectListGridView extends AbstractGridView
+{
+ protected string $objectListClassName;
+ protected DatabaseObjectList $objectList;
+ private int $objectCount;
+
+ protected function getRows(): array
+ {
+ $this->getObjectList()->readObjects();
+
+ return $this->getObjectList()->getObjects();
+ }
+
+ public function countRows(): int
+ {
+ if (!isset($this->objectCount)) {
+ $this->objectCount = $this->getObjectList()->countObjects();
+ }
+
+ return $this->objectCount;
+ }
+
+ protected function getData(mixed $row, string $identifer): mixed
+ {
+ \assert($row instanceof DatabaseObject);
+
+ return $row->__get($identifer);
+ }
+
+ protected function initObjectList(): void
+ {
+ if (!isset($this->objectListClassName)) {
+ throw new SystemException('Database object list class name not specified.');
+ }
+
+ if (!\is_subclass_of($this->objectListClassName, DatabaseObjectList::class)) {
+ throw new ParentClassException($this->objectListClassName, DatabaseObjectList::class);
+ }
+
+ $this->objectList = new $this->objectListClassName;
+ $this->objectList->sqlLimit = $this->getRowsPerPage();
+ $this->objectList->sqlOffset = ($this->getPageNo() - 1) * $this->getRowsPerPage();
+ //wcfDebug($this->objectList->sqlLimit, $this->objectList->sqlOffset);
+ if ($this->getSortField()) {
+ $this->objectList->sqlOrderBy = $this->getSortField() . ' ' . $this->getSortOrder();
+ }
+ }
+
+ public function getObjectList(): DatabaseObjectList
+ {
+ if (!isset($this->objectList)) {
+ $this->initObjectList();
+ }
+
+ return $this->objectList;
+ }
+}
namespace wcf\system\view\grid;
use wcf\acp\form\UserRankEditForm;
-use wcf\data\DatabaseObject;
use wcf\data\user\group\UserGroup;
use wcf\data\user\rank\UserRank;
use wcf\data\user\rank\UserRankList;
use wcf\system\WCF;
use wcf\util\StringUtil;
-final class UserRankGridView extends AbstractGridView
+final class UserRankGridView extends DatabaseObjectListGridView
{
+ protected string $objectListClassName = UserRankList::class;
+
#[\Override]
protected function init(): void
{
$this->setSortField('rankTitle');
}
- public function getRows(int $limit, int $offset = 0): array
- {
- $list = new UserRankList();
- $list->sqlLimit = $limit;
- $list->sqlOffset = $offset;
- if ($this->getSortField()) {
- $list->sqlOrderBy = $this->getSortField() . ' ' . $this->getSortOrder();
- }
- $list->readObjects();
-
- return $list->getObjects();
- }
-
- protected function getData(mixed $row, string $identifer): mixed
- {
- \assert($row instanceof DatabaseObject);
-
- return $row->__get($identifer);
- }
-
public function isAccessible(): bool
{
return \MODULE_USER_RANK && WCF::getSession()->getPermission('admin.user.rank.canManageRank');