accountIdentityColumn() === 'id'); $accNameCol = znote_server_adapter()->accountDisplayColumn(); $search = trim((string)($_GET['q'] ?? '')); $accountId = intv($_GET['id'] ?? 0); // --------------------------------------------------------------------------- // Actions // --------------------------------------------------------------------------- if ($_SERVER['REQUEST_METHOD'] === 'POST') { $id = intv($_POST['id'] ?? 0); $do = (string)($_POST['do'] ?? ''); if ($id <= 0) { acp_flash_error(t('acp.acc.no_selected')); acp_redirect('accounts'); } if ($do === 'points') { $delta = intv($_POST['points'] ?? 0); $row = db()->fetchOne("SELECT `points` FROM `znote_accounts` WHERE `account_id` = ? LIMIT 1;", [$id]); if (!is_array($row)) { acp_flash_error(t('acp.acc.no_row')); } else { $new = max(0, (int)$row['points'] + $delta); db()->execute("UPDATE `znote_accounts` SET `points` = ? WHERE `account_id` = ?;", [$new, $id]); acp_log('account.points', '#' . $id, ['delta' => $delta, 'new_balance' => $new]); acp_flash_success(t('acp.acc.points_applied', ['delta' => ($delta >= 0 ? '+' : '') . $delta, 'new' => $new])); } } acp_redirect('accounts', array('id' => $id)); } // ------------------------------------------------------ Bulk (selected rows) if ($_SERVER['REQUEST_METHOD'] === 'POST' && (string)($_POST['do'] ?? '') === 'bulk_points') { $ids = array_values(array_unique(array_filter(array_map('intv', (array)($_POST['ids'] ?? []))))); $delta = intv($_POST['bulk_points'] ?? 0); if (!$ids) { acp_flash_error(t_default('acp.acc.bulk_none_selected', 'Select at least one account first.')); acp_redirect('accounts', array('q' => $search)); } if ($delta === 0) { acp_flash_error(t('acp.mpts.zero_value')); acp_redirect('accounts', array('q' => $search)); } $placeholders = implode(',', array_fill(0, count($ids), '?')); $updated = db()->execute(" UPDATE `znote_accounts` SET `points` = GREATEST(0, `points` + ?) WHERE `account_id` IN ({$placeholders}); ", array_merge([$delta], $ids)); if ($updated !== false) { acp_log('accounts.bulk_points', implode(',', $ids), ['delta' => $delta, 'count' => count($ids)]); acp_flash_success(t_default('acp.acc.bulk_points_done', '{delta} points applied to {n} account(s).', ['delta' => ($delta >= 0 ? '+' : '') . $delta, 'n' => count($ids)])); } else { acp_flash_error(t('acp.mpts.failed')); } acp_redirect('accounts', array('q' => $search)); } // --------------------------------------------------------------------------- // One account // --------------------------------------------------------------------------- $account = null; if ($accountId > 0) { $account = db()->fetchOne(" SELECT `a`.`id`, {$accNameCol} AS `account_name`, `a`.`email`, `za`.`points`, `za`.`created`, `za`.`ip`, `za`.`flag`, `za`.`active_email` FROM `accounts` `a` LEFT JOIN `znote_accounts` `za` ON `za`.`account_id` = `a`.`id` WHERE `a`.`id` = ? LIMIT 1; ", [$accountId]); if (!is_array($account)) { acp_flash_error(t('acp.acc.no_account', ['id' => $accountId])); acp_redirect('accounts'); } $characters = db()->fetchAll(" SELECT `id`, `name`, `level`, `vocation`, `group_id` FROM `players` WHERE `account_id` = ? ORDER BY `level` DESC; ", [$accountId]); $characters = is_array($characters) ? $characters : array(); $purchases = db()->fetchAll(" SELECT `type`, `itemid`, `count`, `points`, `time` FROM `znote_shop_logs` WHERE `account_id` = ? ORDER BY `id` DESC LIMIT 10; ", [$accountId]); $purchases = is_array($purchases) ? $purchases : array(); } // --------------------------------------------------------------------------- // Search / listing // --------------------------------------------------------------------------- const ACP_ACCOUNTS_PER_PAGE = 50; $results = array(); if ($account === null) { $where = ''; $params = []; if ($search !== '') { $like = '%' . $search . '%'; // Match the account name, its e-mail, or a character on it. if ($isOthire) { $where = "WHERE `a`.`id` = ? OR `a`.`email` LIKE ? OR `a`.`id` IN (SELECT `account_id` FROM `players` WHERE `name` LIKE ?)"; $params = [(int)$search, $like, $like]; } else { $where = "WHERE `a`.`name` LIKE ? OR `a`.`email` LIKE ? OR `a`.`id` IN (SELECT `account_id` FROM `players` WHERE `name` LIKE ?)"; $params = [$like, $like, $like]; } } $totalRow = db()->fetchOne("SELECT COUNT(*) AS `n` FROM `accounts` `a` {$where};", $params); $total = is_array($totalRow) ? (int)$totalRow['n'] : 0; $pageCount = max(1, (int)ceil($total / ACP_ACCOUNTS_PER_PAGE)); $page = max(1, min($pageCount, intv($_GET['ap'] ?? 1))); $offset = ($page - 1) * ACP_ACCOUNTS_PER_PAGE; $results = db()->fetchAll(" SELECT `a`.`id`, {$accNameCol} AS `account_name`, `a`.`email`, `za`.`points`, `za`.`created`, (SELECT COUNT(*) FROM `players` `p` WHERE `p`.`account_id` = `a`.`id`) AS `characters` FROM `accounts` `a` LEFT JOIN `znote_accounts` `za` ON `za`.`account_id` = `a`.`id` {$where} ORDER BY `a`.`id` DESC LIMIT {$offset}, " . ACP_ACCOUNTS_PER_PAGE . "; ", $params); $results = is_array($results) ? $results : array(); } /** Keep the current search when building a paging link. */ function acp_accounts_page_url(int $page, string $search): string { $params = ['ap' => $page]; if ($search !== '') { $params['q'] = $search; } return acp_url('accounts', $params); } ?>
#

' . h(long2ip((int)$account['ip'])) . '' : '—' ?>

count($characters)]) ?>

 
1): ?>

t('acp.acc.type_item'), 2 => t('acp.acc.type_premium'), 3 => t('acp.acc.type_gender'), 4 => t('acp.acc.type_name'), 5 => t('acp.acc.type_outfit'), 6 => t('acp.acc.type_mount'), 7 => t('acp.acc.type_custom'), ); foreach ($purchases as $buy): ?>
$total]) : t_default('acp.acc.total_count', '{n} accounts', ['n' => $total]) ?> 1): ?> · (int)$page, 'pageCount' => (int)$pageCount]) ?>

# 
$search]) : t('acp.acc.no_accounts_yet'), 'fa-address-card-o'); ?>
1): ?>