- Header: h1 + logo in a wrapping flex row, hr.wp-header-end before the tabs, aria-current on the active tab; own CSS/JS enqueued only on this screen. - Verbindung: ordered "So verbindest du Claude" steps, copy button (core clipboard.js + wp.a11y.speak), Site-Health-style status list, German details. - Zugriff: roles as form-table fieldset, connections with site date format, empty-state row, confirm on revoke; ConnectionUsage records last use via WP_Application_Passwords::record_application_password_usage (once a day). - Tools: plain-language legend, counter as inline notice, groups as core postboxes (postbox.js toggles, per-user closed state, summary when closed), fixed column widths with new "Art" column, submit above and below. - Protokoll: site-timezone times with UTC tooltip, result icons, filters with labels in the list table nav, retention link to Limits. - Limits: short labels with units and descriptions; snapshot count hidden but preserved. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
98 lines
2.8 KiB
PHP
98 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
if (! class_exists('WP_List_Table')) {
|
|
/**
|
|
* Minimal stand-in for wp-admin/includes/class-wp-list-table.php: just enough of the
|
|
* real class's shape (constructor args, $items, single_row_columns dispatching to
|
|
* column_<name>()/column_default()) for LogListTable's own logic to be unit-tested
|
|
* without a full WP admin bootstrap.
|
|
*/
|
|
class WP_List_Table
|
|
{
|
|
/** @var list<array<string, mixed>> */
|
|
public $items = [];
|
|
|
|
/** @var array{0: array<string, string>, 1: list<string>, 2: list<string>}|null */
|
|
public $_column_headers;
|
|
|
|
/** @var array<string, mixed> */
|
|
protected $_args;
|
|
|
|
/** @var array<string, mixed> */
|
|
protected $_pagination_args = [];
|
|
|
|
/** @param array<string, mixed> $args */
|
|
public function __construct(array $args = [])
|
|
{
|
|
$this->_args = $args;
|
|
}
|
|
|
|
public function get_pagenum(): int
|
|
{
|
|
return isset($_GET['paged']) ? max(1, (int) $_GET['paged']) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
}
|
|
|
|
/** @param array<string, mixed> $args */
|
|
public function set_pagination_args(array $args): void
|
|
{
|
|
$this->_pagination_args = $args;
|
|
}
|
|
|
|
/** @return array<string, mixed> */
|
|
public function pagination_args(): array
|
|
{
|
|
return $this->_pagination_args;
|
|
}
|
|
|
|
/** @return array<string, string> */
|
|
public function get_columns(): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
public function single_row($item): void
|
|
{
|
|
echo '<tr>';
|
|
$this->single_row_columns($item);
|
|
echo '</tr>';
|
|
}
|
|
|
|
/** @param array<string, mixed> $item */
|
|
protected function single_row_columns($item): void
|
|
{
|
|
foreach (array_keys($this->get_columns()) as $column_name) {
|
|
$method = 'column_' . $column_name;
|
|
$value = method_exists($this, $method) ? $this->{$method}($item) : $this->column_default($item, $column_name);
|
|
printf('<td class="%s">%s</td>', $column_name, $value);
|
|
}
|
|
}
|
|
|
|
/** @param array<string, mixed> $item */
|
|
protected function column_default($item, $column_name): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
public function no_items(): void
|
|
{
|
|
}
|
|
|
|
public function prepare_items(): void
|
|
{
|
|
}
|
|
|
|
/** Like the real class: the top table nav (with extra_tablenav()) comes before the rows. */
|
|
public function display(): void
|
|
{
|
|
$this->extra_tablenav('top');
|
|
}
|
|
|
|
/** @param string $which */
|
|
protected function extra_tablenav($which)
|
|
{
|
|
}
|
|
}
|
|
}
|