<header class="contentHeader">
<div class="contentHeaderTitle">
- <h1 class="contentTitle">{lang}wcf.acp.sessionLog.list{/lang} <span class="badge badgeInverse">{#$items}</span></h1>
+ <h1 class="contentTitle">{lang}wcf.acp.sessionLog.list{/lang} <span class="badge badgeInverse">{#$gridView->countRows()}</span></h1>
</div>
{hascontent}
{/hascontent}
</header>
-{hascontent}
- <div class="paginationTop">
- {content}{pages print=true assign=pagesLinks controller="ACPSessionLogList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}{/content}
- </div>
-{/hascontent}
-
-{if $objects|count}
- <div class="section tabularBox">
- <table class="table">
- <thead>
- <tr>
- <th class="columnSessionLogID{if $sortField == 'sessionLogID'} active {@$sortOrder}{/if}"><a href="{link controller='ACPSessionLogList'}pageNo={@$pageNo}&sortField=sessionLogID&sortOrder={if $sortField == 'sessionLogID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
- <th class="columnTitle columnUsername{if $sortField == 'username'} active {@$sortOrder}{/if}"><a href="{link controller='ACPSessionLogList'}pageNo={@$pageNo}&sortField=username&sortOrder={if $sortField == 'username' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.user.username{/lang}</a></th>
- <th class="columnURL columnIpAddress{if $sortField == 'ipAddress'} active {@$sortOrder}{/if}"><a href="{link controller='ACPSessionLogList'}pageNo={@$pageNo}&sortField=ipAddress&sortOrder={if $sortField == 'ipAddress' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.user.ipAddress{/lang}</a></th>
- <th class="columnText columnUserAgent{if $sortField == 'userAgent'} active {@$sortOrder}{/if}"><a href="{link controller='ACPSessionLogList'}pageNo={@$pageNo}&sortField=userAgent&sortOrder={if $sortField == 'userAgent' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.user.userAgent{/lang}</a></th>
- <th class="columnDate columnTime{if $sortField == 'time'} active {@$sortOrder}{/if}"><a href="{link controller='ACPSessionLogList'}pageNo={@$pageNo}&sortField=time&sortOrder={if $sortField == 'time' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.sessionLog.time{/lang}</a></th>
- <th class="columnDate columnLastActivityTime{if $sortField == 'lastActivityTime'} active {@$sortOrder}{/if}"><a href="{link controller='ACPSessionLogList'}pageNo={@$pageNo}&sortField=lastActivityTime&sortOrder={if $sortField == 'lastActivityTime' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.sessionLog.lastActivityTime{/lang}</a></th>
- <th class="columnDigits columnAccesses{if $sortField == 'accesses'} active {@$sortOrder}{/if}"><a href="{link controller='ACPSessionLogList'}pageNo={@$pageNo}&sortField=accesses&sortOrder={if $sortField == 'accesses' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.sessionLog.actions{/lang}</a></th>
-
- {event name='columnHeads'}
- </tr>
- </thead>
-
- <tbody>
- {foreach from=$objects item=sessionLog}
- <tr>
- <td class="columnID columnSessionLogID">{@$sessionLog->sessionLogID}</td>
- <td class="columnTitle columnUsername"><a href="{link controller='ACPSessionLog' id=$sessionLog->sessionLogID}{/link}">{$sessionLog->username}</a></td>
- <td class="columnSmallText columnIpAddress"><a href="{link controller='ACPSessionLog' id=$sessionLog->sessionLogID}{/link}">{$sessionLog->getIpAddress()}</a>{if $sessionLog->hostname != $sessionLog->ipAddress}<br><a href="{link controller='ACPSessionLog' id=$sessionLog->sessionLogID}{/link}">{$sessionLog->hostname}</a>{/if}</td>
- <td class="columnSmallText columnUserAgent" title="{$sessionLog->userAgent}"><a href="{link controller='ACPSessionLog' id=$sessionLog->sessionLogID}{/link}">{$sessionLog->userAgent|truncate:75|tableWordwrap}</a></td>
- <td class="columnDate columnTime">{@$sessionLog->time|time}</td>
- <td class="columnDate columnLastActivityTime">{@$sessionLog->lastActivityTime|time}</td>
- <td class="columnDigits columnAccesses">{#$sessionLog->accesses}</td>
-
- {event name='columns'}
- </tr>
- {/foreach}
- </tbody>
- </table>
- </div>
-
- <footer class="contentFooter">
- {hascontent}
- <div class="paginationBottom">
- {content}{@$pagesLinks}{/content}
- </div>
- {/hascontent}
-
- {hascontent}
- <nav class="contentFooterNavigation">
- <ul>
- {content}{event name='contentFooterNavigation'}{/content}
- </ul>
- </nav>
- {/hascontent}
- </footer>
-{/if}
+<div class="section">
+ {unsafe:$gridView->render()}
+</div>
{include file='footer'}
namespace wcf\acp\page;
-use wcf\data\acp\session\log\ACPSessionLogList;
-use wcf\page\SortablePage;
+use wcf\page\AbstractGridViewPage;
+use wcf\system\gridView\AbstractGridView;
+use wcf\system\gridView\ACPSessionLogGridView;
/**
- * Shows a list of log sessions.
+ * Shows a list of logged sessions.
*
- * @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 ACPSessionLogList $objectList
+ * @property ACPSessionLogGridView $gridView
*/
-class ACPSessionLogListPage extends SortablePage
+class ACPSessionLogListPage extends AbstractGridViewPage
{
/**
* @inheritDoc
*/
public $neededPermissions = ['admin.management.canViewLog'];
- /**
- * @inheritDoc
- */
- public $defaultSortField = 'lastActivityTime';
-
- /**
- * @inheritDoc
- */
- public $defaultSortOrder = 'DESC';
-
- /**
- * @inheritDoc
- */
- public $validSortFields = [
- 'sessionLogID',
- 'username',
- 'ipAddress',
- 'userAgent',
- 'time',
- 'lastActivityTime',
- 'accesses',
- ];
-
- /**
- * @inheritDoc
- */
- public $objectListClassName = ACPSessionLogList::class;
-
- /**
- * @inheritDoc
- */
- public function readObjects()
+ #[\Override]
+ protected function createGridViewController(): AbstractGridView
{
- $this->sqlOrderBy = (($this->sortField != 'accesses' && $this->sortField != 'username') ? 'acp_session_log.' : '') . $this->sortField . " " . $this->sortOrder;
-
- parent::readObjects();
+ return new ACPSessionLogGridView();
}
}
$this->sqlSelects .= ',';
}
$this->sqlSelects .= "
- user_table.username,
+ (
+ SELECT username
+ FROM wcf1_user
+ WHERE userID = " . $this->getDatabaseTableAlias() . ".userID
+ ) AS username,
0 AS active,
(
SELECT COUNT(*)
WHERE sessionLogID = " . $this->getDatabaseTableAlias() . ".sessionLogID
) AS accesses";
- $this->sqlJoins .= "
- LEFT JOIN wcf1_user user_table
- ON user_table.userID = " . $this->getDatabaseTableAlias() . ".userID";
-
parent::readObjects();
}
}
--- /dev/null
+<?php
+
+namespace wcf\event\gridView;
+
+use wcf\event\IPsr14Event;
+use wcf\system\gridView\ACPSessionLogGridView;
+
+/**
+ * Indicates that the acp session log grid view has been initialized.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2024 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @since 6.2
+ */
+final class ACPSessionLogGridViewInitialized implements IPsr14Event
+{
+ public function __construct(public readonly ACPSessionLogGridView $gridView) {}
+}
--- /dev/null
+<?php
+
+namespace wcf\system\gridView;
+
+use wcf\acp\page\ACPSessionLogPage;
+use wcf\data\acp\session\log\ACPSessionLogList;
+use wcf\data\DatabaseObjectList;
+use wcf\event\gridView\ACPSessionLogGridViewInitialized;
+use wcf\event\IPsr14Event;
+use wcf\system\gridView\filter\IpAddressFilter;
+use wcf\system\gridView\filter\TextFilter;
+use wcf\system\gridView\filter\TimeFilter;
+use wcf\system\gridView\filter\UserFilter;
+use wcf\system\gridView\renderer\IpAddressColumnRenderer;
+use wcf\system\gridView\renderer\NumberColumnRenderer;
+use wcf\system\gridView\renderer\TimeColumnRenderer;
+use wcf\system\gridView\renderer\TruncatedTextColumnRenderer;
+use wcf\system\gridView\renderer\UserColumnRenderer;
+use wcf\system\WCF;
+
+/**
+ * Grid view for the list of logged admin session.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2024 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @since 6.2
+ */
+final class ACPSessionLogGridView extends DatabaseObjectListGridView
+{
+ public function __construct()
+ {
+ $this->addColumns([
+ GridViewColumn::for('sessionLogID')
+ ->label('wcf.global.objectID')
+ ->renderer(new NumberColumnRenderer())
+ ->sortable(),
+ GridViewColumn::for('userID')
+ ->label('wcf.user.username')
+ ->sortable()
+ ->sortById('username')
+ ->renderer(new UserColumnRenderer())
+ ->filter(new UserFilter()),
+ GridViewColumn::for('ipAddress')
+ ->label('wcf.user.ipAddress')
+ ->sortable()
+ ->renderer(new IpAddressColumnRenderer())
+ ->filter(new IpAddressFilter()),
+ GridViewColumn::for('userAgent')
+ ->label('wcf.user.userAgent')
+ ->sortable()
+ ->renderer(new TruncatedTextColumnRenderer())
+ ->filter(new TextFilter()),
+ GridViewColumn::for('time')
+ ->label('wcf.acp.sessionLog.time')
+ ->sortable()
+ ->renderer(new TimeColumnRenderer())
+ ->filter(new TimeFilter()),
+ GridViewColumn::for('lastActivityTime')
+ ->label('wcf.acp.sessionLog.lastActivityTime')
+ ->sortable()
+ ->renderer(new TimeColumnRenderer())
+ ->filter(new TimeFilter()),
+ GridViewColumn::for('accesses')
+ ->label('wcf.acp.sessionLog.actions')
+ ->sortable()
+ ->renderer(new NumberColumnRenderer()),
+ ]);
+
+ $this->addRowLink(new GridViewRowLink(ACPSessionLogPage::class));
+ $this->setSortField('lastActivityTime');
+ $this->setSortOrder('DESC');
+ }
+
+ #[\Override]
+ public function isAccessible(): bool
+ {
+ return WCF::getSession()->getPermission('admin.management.canViewLog');
+ }
+
+ #[\Override]
+ protected function createObjectList(): DatabaseObjectList
+ {
+ return new ACPSessionLogList();
+ }
+
+ #[\Override]
+ protected function getInitializedEvent(): ?IPsr14Event
+ {
+ return new ACPSessionLogGridViewInitialized($this);
+ }
+}