accountDisplayColumn();
// ---------------------------------------------------------------------------
// Counters. acp_count() returns 0 for a table this engine does not have,
// so an unusual schema degrades to a zero instead of a fatal error.
// ---------------------------------------------------------------------------
$statAccounts = acp_count("SELECT COUNT(*) AS `c` FROM `accounts`;");
$statPlayers = acp_count("SELECT COUNT(*) AS `c` FROM `players`;");
$statGuilds = acp_count("SELECT COUNT(*) AS `c` FROM `guilds`;");
$statHouses = acp_count("SELECT COUNT(*) AS `c` FROM `houses`;");
$statOnline = znote_server_adapter()->onlineCount();
$statPoints = acp_count("SELECT COALESCE(SUM(`points`), 0) AS `c` FROM `znote_accounts`;");
$statOrders = acp_count("SELECT COUNT(*) AS `c` FROM `znote_shop_orders`;");
// Moderation queues - reuse the same counters the sidebar badges use.
$queueReports = acp_badge_reports();
$queueTickets = acp_badge_helpdesk();
$queueImages = acp_badge_gallery();
$queueFeedback = acp_badge_feedback();
// ---------------------------------------------------------------------------
// Recent activity
// ---------------------------------------------------------------------------
$latestAccounts = db()->fetchAll("
SELECT `a`.`id` AS `account_id`, {$accNameCol} AS `account_name`, `za`.`created`, `za`.`points`
FROM `znote_accounts` `za`
INNER JOIN `accounts` `a` ON `a`.`id` = `za`.`account_id`
ORDER BY `za`.`created` DESC
LIMIT 10;
");
$latestPlayers = db()->fetchAll("
SELECT `name`, `level`, `vocation`
FROM `players`
ORDER BY `id` DESC
LIMIT 10;
");
$topPoints = db()->fetchAll("
SELECT `a`.`id` AS `account_id`, {$accNameCol} AS `account_name`, `za`.`points`
FROM `znote_accounts` `za`
INNER JOIN `accounts` `a` ON `a`.`id` = `za`.`account_id`
WHERE `za`.`points` > 0
ORDER BY `za`.`points` DESC
LIMIT 10;
");
$recentShopPurchases = znote_table_exists('znote_shop_logs')
? db()->fetchAll("
SELECT `l`.`account_id`, {$accNameCol} AS `account_name`, `l`.`itemid`, `l`.`type`, `l`.`count`, `l`.`points`, `l`.`time`
FROM `znote_shop_logs` `l`
LEFT JOIN `accounts` `a` ON `a`.`id` = `l`.`account_id`
ORDER BY `l`.`id` DESC
LIMIT 8;
")
: false;
$recentShopPurchases = is_array($recentShopPurchases) ? $recentShopPurchases : array();
$shopItemNames = function_exists('getItemList') ? getItemList() : array();
$shopOrderTypes = array(
1 => t('acp.sord.type_item'),
2 => t('acp.sord.type_premium'),
3 => t('acp.sord.type_gender'),
4 => t('acp.sord.type_name'),
5 => t('acp.sord.type_outfit'),
6 => t('acp.sord.type_mount'),
7 => t('acp.sord.type_custom'),
8 => t('acp.sord.type_custom'),
);
$recentPointsPurchases = znote_table_exists('znote_payment_transactions')
? db()->fetchAll("
SELECT `t`.`account_id`, {$accNameCol} AS `account_name`, `t`.`provider`, `t`.`price`, `t`.`currency`, `t`.`points`, `t`.`credited`, `t`.`created_at`
FROM `znote_payment_transactions` `t`
LEFT JOIN `accounts` `a` ON `a`.`id` = `t`.`account_id`
ORDER BY `t`.`id` DESC
LIMIT 8;
")
: false;
$recentPointsPurchases = is_array($recentPointsPurchases) ? $recentPointsPurchases : array();
// znote row: keep the stored version in step with the running one, the way
// the old admin.php did on every visit.
$znote = user_znote_data('version', 'installed', 'cached');
if (is_array($znote) && ($znote['version'] ?? null) !== $version) {
$oldVersion = (string)($znote['version'] ?? '');
db()->execute("UPDATE `znote` SET `version` = ?;", [$version]);
acp_log('system.version_sync', $version, ['from' => $oldVersion]);
$znote['version'] = $version;
}
$obSteps = array(
array(
'done' => !empty($config['twoFactorAuthenticator']),
'label' => t_default('acp.dash.ob_2fa', 'Enable two-factor authentication'),
'url' => acp_url('settings') . '#set_twoFactorAuthenticator',
),
array(
'done' => function_exists('znote_backups_list') && count(znote_backups_list()) > 0,
'label' => t_default('acp.dash.ob_backup', 'Create your first backup'),
'url' => acp_url('backups'),
),
array(
'done' => function_exists('scheduler_enabled') && scheduler_enabled('backups'),
'label' => t_default('acp.dash.ob_scheduler', 'Turn on automatic backups'),
'url' => acp_url('scheduler'),
),
array(
'done' => function_exists('znote_migrations_pending') && !znote_migrations_pending(),
'label' => t_default('acp.dash.ob_migrations', 'Apply pending database migrations'),
'url' => acp_url('migrations'),
),
);
$obRemaining = count(array_filter($obSteps, static fn(array $s): bool => !$s['done']));
?>
0): ?>
= t_default('acp.dash.ob_title', 'Getting started') ?>
= h(t_default('acp.dash.ob_sub', '{n} step(s) left - this card goes away once they are all done.', ['n' => $obRemaining])) ?>
|
= h($step['label']) ?>
|
= $step['done'] ? t('acp.dash.enabled') : t_default('acp.dash.ob_todo', 'To do') ?>
|
= t('acp.dash.review') ?>
|
- ZnoteX
- = h($version) ?>= is_array($znote) && isset($znote['version']) ? '' : ' '. t('acp.dash.znote_table_missing') .'' ?>
- PHP
- = h(PHP_VERSION) ?>
- = t('acp.dash.server_engine') ?>
- = h(serverEngineReal()) ?>
- = t('acp.dash.database') ?>
- = h($config['sqlDatabase'] ?? '') ?> @ = h($config['sqlHost'] ?? '') ?>
- = t('acp.dash.site_url') ?>
- = h($config['site_url'] ?? '') ?>
- = t('acp.dash.installed') ?>
- = is_array($znote) && !empty($znote['installed']) ? h(getClock((int)$znote['installed'], true)) : '—' ?>
- = t('acp.dash.last_cache') ?>
- = is_array($znote) && !empty($znote['cached']) ? h(getClock((int)$znote['cached'], true)) : '—' ?>
- = t('acp.dash.two_factor') ?>
- = !empty($config['twoFactorAuthenticator'])
? ''. t('acp.dash.enabled') .''
: ''. t('acp.dash.disabled') .'' ?>
= t('acp.dash.newest_accounts') ?>
| = t('acp.dash.col_account') ?> | = t('acp.dash.col_created') ?> | = t('acp.dash.col_points') ?> |
| = h($row['account_name']) ?> |
= h(getClock((int)$row['created'], true)) ?> |
= (int)$row['points'] ?> |
= t('acp.dash.newest_characters') ?>
| = t('acp.dash.col_name') ?> | = t('acp.dash.col_vocation') ?> | = t('acp.dash.col_level') ?> |
|
= h($row['name']) ?>
|
= h(vocation_id_to_name((int)$row['vocation'])) ?> |
= (int)$row['level'] ?> |
= t('acp.dash.top_balances') ?>
| # | = t('acp.dash.col_account') ?> | = t('acp.dash.col_points') ?> |
| = $rank ?> |
= h($row['account_name']) ?> |
= number_format((int)$row['points']) ?> |
= t_default('acp.dash.recent_shop', 'Recent Shop Purchases') ?>
| = t('acp.dash.col_account') ?> |
= t('acp.sord.col_item') ?> |
= t('acp.sord.col_points') ?> |
= t('acp.sord.col_date') ?> |
| = $row['account_name'] !== null ? h($row['account_name']) : ''. t('acp.sord.deleted_account', ['id' => (int)($row['account_id'] ?? 0)]) .'' ?> |
0): ?>
= h($shopItemNames[$itemId] ?? t('acp.sord.item_unknown')) ?>
= h($shopOrderTypes[(int)($row['type'] ?? 0)] ?? t('acp.sord.type_unknown')) ?>
|
= (int)($row['points'] ?? 0) ?> |
= h(getClock((int)($row['time'] ?? 0), true)) ?> |
= t_default('acp.dash.recent_points', 'Recent Points Purchases') ?>
| = t('acp.dash.col_account') ?> |
= t_default('acp.dash.col_provider', 'Provider') ?> |
= t_default('acp.dash.col_amount', 'Amount') ?> |
= t('acp.dash.col_points') ?> |
= t('acp.sord.col_date') ?> |
| = $row['account_name'] !== null ? h($row['account_name']) : ''. t('acp.sord.deleted_account', ['id' => (int)($row['account_id'] ?? 0)]) .'' ?> |
= h(ucfirst((string)($row['provider'] ?? ''))) ?> |
= h(number_format((float)($row['price'] ?? 0), 2, '.', '')) ?> = h((string)($row['currency'] ?? '')) ?> |
= (int)($row['points'] ?? 0) ?>
= !empty($row['credited']) ? ' '. t_default('acp.dash.credited', 'Credited') .'' : ' '. t_default('acp.dash.pending', 'Pending') .'' ?>
|
= !empty($row['created_at']) ? h(getClock((int)$row['created_at'], true)) : '—' ?> |