diff --git a/wcfsetup/install/files/acp/js/WCF.ACP.js b/wcfsetup/install/files/acp/js/WCF.ACP.js
index d559e5869da..b2d23e5a848 100644
--- a/wcfsetup/install/files/acp/js/WCF.ACP.js
+++ b/wcfsetup/install/files/acp/js/WCF.ACP.js
@@ -96,12 +96,6 @@ WCF.ACP.Cronjob.ExecutionHandler = Class.extend({
* Handles the cronjob log list.
*/
WCF.ACP.Cronjob.LogList = Class.extend({
- /**
- * error message dialog
- * @var jQuery
- */
- _dialog: null,
-
/**
* Initializes WCF.ACP.Cronjob.LogList object.
*/
@@ -123,29 +117,6 @@ WCF.ACP.Cronjob.LogList = Class.extend({
}
});
});
-
- // bind event listeners to error badges
- $('.jsCronjobError').click($.proxy(this._showError, this));
- },
-
- /**
- * Shows certain error message
- *
- * @param object event
- */
- _showError: function(event) {
- var $errorBadge = $(event.currentTarget);
-
- if (this._dialog === null) {
- this._dialog = $('
' + $errorBadge.next().html() + '
').hide().appendTo(document.body);
- this._dialog.wcfDialog({
- title: WCF.Language.get('wcf.acp.cronjob.log.error.details')
- });
- }
- else {
- this._dialog.html('' + $errorBadge.next().html() + '
');
- this._dialog.wcfDialog('open');
- }
}
});
diff --git a/wcfsetup/install/files/acp/templates/cronjobLogList.tpl b/wcfsetup/install/files/acp/templates/cronjobLogList.tpl
index af482fc14c2..980e7e5bf88 100644
--- a/wcfsetup/install/files/acp/templates/cronjobLogList.tpl
+++ b/wcfsetup/install/files/acp/templates/cronjobLogList.tpl
@@ -13,14 +13,14 @@
-
-
-{assign var='linkParameters' value=''}
-{if $cronjobID}{capture append=linkParameters}&cronjobID={@$cronjobID}{/capture}{/if}
-{if $success != -1}{capture append=linkParameters}&success={@$success}{/capture}{/if}
-
-{hascontent}
-
-{/hascontent}
-
-{if $objects|count}
-
-
-
-{else}
- {lang}wcf.global.noItems{/lang}
-{/if}
+{unsafe:$gridView->render()}
{include file='footer'}
diff --git a/wcfsetup/install/files/lib/acp/page/CronjobLogListPage.class.php b/wcfsetup/install/files/lib/acp/page/CronjobLogListPage.class.php
index c3d6f0f92e5..74548218b63 100755
--- a/wcfsetup/install/files/lib/acp/page/CronjobLogListPage.class.php
+++ b/wcfsetup/install/files/lib/acp/page/CronjobLogListPage.class.php
@@ -2,22 +2,20 @@
namespace wcf\acp\page;
-use wcf\data\cronjob\CronjobList;
-use wcf\data\cronjob\I18nCronjobList;
-use wcf\data\cronjob\log\CronjobLogList;
-use wcf\page\SortablePage;
-use wcf\system\WCF;
+use wcf\page\AbstractGridViewPage;
+use wcf\system\view\grid\AbstractGridView;
+use wcf\system\view\grid\CronjobLogGridView;
/**
* Shows cronjob log information.
*
- * @author Marcel Werk
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License
+ * @author Marcel Werk
+ * @copyright 2001-2024 WoltLab GmbH
+ * @license GNU Lesser General Public License
*
- * @property CronjobLogList $objectList
+ * @property CronjobLogGridView $gridView
*/
-class CronjobLogListPage extends SortablePage
+class CronjobLogListPage extends AbstractGridViewPage
{
/**
* @inheritDoc
@@ -29,114 +27,9 @@ class CronjobLogListPage extends SortablePage
*/
public $neededPermissions = ['admin.management.canManageCronjob'];
- /**
- * @inheritDoc
- */
- public $itemsPerPage = 100;
-
- /**
- * @inheritDoc
- */
- public $defaultSortField = 'execTime';
-
- /**
- * @inheritDoc
- */
- public $defaultSortOrder = 'DESC';
-
- /**
- * @inheritDoc
- */
- public $validSortFields = ['cronjobID', 'className', 'description', 'execTime', 'success'];
-
- /**
- * @inheritDoc
- */
- public $objectListClassName = CronjobLogList::class;
-
- /**
- * @var int
- */
- public $cronjobID = 0;
-
- /**
- * @var int
- */
- public $success = -1;
-
- /**
- * @var CronjobList
- */
- public $availableCronjobs;
-
- /**
- * @inheritDoc
- */
- public function readParameters()
- {
- parent::readParameters();
-
- if (!empty($_REQUEST['cronjobID'])) {
- $this->cronjobID = \intval($_REQUEST['cronjobID']);
- }
- if (isset($_REQUEST['success'])) {
- $this->success = \intval($_REQUEST['success']);
- }
- }
-
- /**
- * @inheritDoc
- */
- protected function initObjectList()
- {
- parent::initObjectList();
-
- $this->objectList->sqlSelects = "cronjob.*";
- $this->objectList->sqlJoins = "
- LEFT JOIN wcf" . WCF_N . "_cronjob cronjob
- ON cronjob.cronjobID = cronjob_log.cronjobID";
-
- if ($this->cronjobID) {
- $this->objectList->getConditionBuilder()->add('cronjob_log.cronjobID = ?', [$this->cronjobID]);
- }
- if ($this->success != -1) {
- $this->objectList->getConditionBuilder()->add('cronjob_log.success = ?', [$this->success]);
- }
- }
-
- /**
- * @inheritDoc
- */
- protected function readObjects()
+ #[\Override]
+ protected function createGridViewController(): AbstractGridView
{
- $this->sqlOrderBy = (($this->sortField == 'className' || $this->sortField == 'description') ? 'cronjob.' : 'cronjob_log.') . $this->sortField . " " . $this->sortOrder;
-
- parent::readObjects();
- }
-
- /**
- * @inheritDoc
- */
- public function readData()
- {
- parent::readData();
-
- $this->availableCronjobs = new I18nCronjobList();
- $this->availableCronjobs->sqlOrderBy = 'descriptionI18n';
- $this->availableCronjobs->readObjects();
- }
-
- /**
- * @inheritDoc
- */
- public function assignVariables()
- {
- parent::assignVariables();
-
- WCF::getTPL()->assign([
- 'cronjobID' => $this->cronjobID,
- 'success' => $this->success,
- 'availableCronjobs' => $this->availableCronjobs,
- ]);
+ return new CronjobLogGridView();
}
}
diff --git a/wcfsetup/install/files/lib/system/view/grid/CronjobLogGridView.class.php b/wcfsetup/install/files/lib/system/view/grid/CronjobLogGridView.class.php
new file mode 100644
index 00000000000..4060d49f44f
--- /dev/null
+++ b/wcfsetup/install/files/lib/system/view/grid/CronjobLogGridView.class.php
@@ -0,0 +1,118 @@
+getAvailableCronjobs();
+
+ $this->addColumns([
+ GridViewColumn::for('cronjobLogID')
+ ->label('wcf.global.objectID')
+ ->renderer(new NumberColumnRenderer())
+ ->sortable(),
+ GridViewColumn::for('cronjobID')
+ ->label('wcf.acp.cronjob')
+ ->sortable()
+ ->filter(new SelectFilter($availableCronjobs))
+ ->renderer([
+ new class($availableCronjobs) extends TitleColumnRenderer {
+ public function __construct(private readonly array $availableCronjobs) {}
+
+ public function render(mixed $value, mixed $context = null): string
+ {
+ return $this->availableCronjobs[$value];
+ }
+ },
+ ]),
+ GridViewColumn::for('execTime')
+ ->label('wcf.acp.cronjob.log.execTime')
+ ->sortable()
+ // TODO: Add some time frame filter.
+ ->renderer(new TimeColumnRenderer()),
+ GridViewColumn::for('success')
+ ->label('wcf.acp.cronjob.log.status')
+ ->sortable()
+ ->filter(new SelectFilter([
+ 1 => 'wcf.acp.cronjob.log.success',
+ 0 => 'wcf.acp.cronjob.log.error',
+ ]))
+ ->renderer([
+ new class extends DefaultColumnRenderer {
+ public function render(mixed $value, mixed $context = null): string
+ {
+ \assert($context instanceof CronjobLog);
+
+ if ($context->success) {
+ return '' . WCF::getLanguage()->get('wcf.acp.cronjob.log.success') . '';
+ }
+ if ($context->error) {
+ $label = WCF::getLanguage()->get('wcf.acp.cronjob.log.error');
+ $buttonId = 'cronjobLogErrorButton' . $context->cronjobLogID;
+ $id = 'cronjobLogError' . $context->cronjobLogID;
+ $error = StringUtil::encodeHTML($context->error);
+ $dialogTitle = StringUtil::encodeJS(WCF::getLanguage()->get('wcf.acp.cronjob.log.error.details'));
+
+ return <<
+ {$label}
+
+ {$error}
+
+ HTML;
+ }
+
+ return '';
+ }
+ },
+ ]),
+ ]);
+
+ $this->setSortField('execTime');
+ $this->setSortOrder('DESC');
+ }
+
+ #[\Override]
+ public function isAccessible(): bool
+ {
+ return WCF::getSession()->getPermission('admin.management.canManageCronjob');
+ }
+
+ #[\Override]
+ protected function createObjectList(): DatabaseObjectList
+ {
+ return new CronjobLogList();
+ }
+
+ private function getAvailableCronjobs(): array
+ {
+ $list = new I18nCronjobList();
+ $list->sqlOrderBy = 'descriptionI18n';
+ $list->readObjects();
+
+ return \array_map(fn(Cronjob $cronjob) => $cronjob->getDescription(), $list->getObjects());
+ }
+}
diff --git a/wcfsetup/install/lang/de.xml b/wcfsetup/install/lang/de.xml
index d478f069b30..0089665d32d 100644
--- a/wcfsetup/install/lang/de.xml
+++ b/wcfsetup/install/lang/de.xml
@@ -299,6 +299,7 @@
+
diff --git a/wcfsetup/install/lang/en.xml b/wcfsetup/install/lang/en.xml
index ca0f31be040..71d910723f0 100644
--- a/wcfsetup/install/lang/en.xml
+++ b/wcfsetup/install/lang/en.xml
@@ -277,6 +277,7 @@
+