mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-16 18:04:34 -05:00
484 lines
19 KiB
PHP
484 lines
19 KiB
PHP
<?php
|
|
// phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
|
|
// phpcs:disable PSR1.Files.SideEffects.FoundWithSymbols
|
|
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
|
|
/** @phpstan-var \Gazelle\User $Viewer */
|
|
/** @phpstan-var \Twig\Environment $Twig */
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Gazelle;
|
|
|
|
$userMan = new Manager\User();
|
|
|
|
if (isset($_GET['search'])) {
|
|
$_GET['search'] = trim($_GET['search']);
|
|
}
|
|
|
|
if (isset($_GET['search'])) {
|
|
if (preg_match(IP_REGEXP, $_GET['search'])) {
|
|
$_GET['ip'] = $_GET['search'];
|
|
} elseif (preg_match(EMAIL_REGEXP, $_GET['search'])) {
|
|
$_GET['email'] = $_GET['search'];
|
|
} elseif (str_starts_with($_GET['search'], '#')) {
|
|
$found = $userMan->findById((int)substr($_GET['search'], 1));
|
|
if ($found) {
|
|
header('Location: ' . $found->location());
|
|
exit;
|
|
}
|
|
} elseif (preg_match(USERNAME_REGEXP, $_GET['search'], $match)) {
|
|
$username = $match['username'];
|
|
$found = $userMan->findByUsername($username);
|
|
if ($found) {
|
|
header('Location: ' . $found->location());
|
|
exit;
|
|
}
|
|
$_GET['username'] = $username;
|
|
} else {
|
|
$_GET['comment'] = $_GET['search'];
|
|
}
|
|
}
|
|
|
|
foreach (['ip', 'email', 'username', 'comment'] as $field) {
|
|
if (isset($_GET[$field])) {
|
|
$_GET[$field] = trim($_GET[$field]);
|
|
}
|
|
}
|
|
|
|
function option(string $field, string $value, string $label): string {
|
|
return sprintf('<option value="%s"%s>%s</option>',
|
|
$value,
|
|
($_GET[$field] ?? '') === $value ? ' selected="selected"' : '',
|
|
$label);
|
|
}
|
|
|
|
$orderBy = [
|
|
'Bounty' => 'Bounty',
|
|
'Downloaded' => 'uls1.Downloaded',
|
|
'Downloads' => 'Downloads',
|
|
'Email' => 'um1.Email',
|
|
'Invites' => 'um1.Invites',
|
|
'Joined' => 'um1.created',
|
|
'Last Seen' => 'ula.last_access',
|
|
'Ratio' => '(uls1.Uploaded / uls1.Downloaded)',
|
|
'Seeding' => 'Seeding',
|
|
'Snatches' => 'Snatches',
|
|
'Uploaded' => 'uls1.Uploaded',
|
|
'Username' => 'um1.Username',
|
|
];
|
|
$dir = ['Ascending' => 'ASC', 'Descending' => 'DESC'];
|
|
|
|
// Arrays, regexps, and all that fun stuff we can use for validation, form generation, etc
|
|
$orderByValue = ['inarray' => array_keys($orderBy)];
|
|
$dirValue = ['inarray' => array_keys($dir)];
|
|
$dateChoice = ['inarray' => ['on', 'before', 'after', 'between']];
|
|
$singledateChoice = ['inarray' => ['on', 'before', 'after']];
|
|
$numberChoice = ['inarray' => ['equal', 'above', 'below', 'between', 'buffer']];
|
|
$offNumberChoice = ['inarray' => ['equal', 'above', 'below', 'between', 'buffer', 'off']];
|
|
$yesNo = ['inarray' => ['any', 'yes', 'no']];
|
|
$nullable = ['inarray' => ['any', 'isnull', 'isnotnull']];
|
|
|
|
$emailHistoryChecked = false;
|
|
$ipHistoryChecked = false;
|
|
$disabledIpChecked = false;
|
|
$trackerLiveSource = true;
|
|
|
|
$paginator = new Util\Paginator(USERS_PER_PAGE, (int)($_GET['page'] ?? 1));
|
|
$stylesheet = new Manager\Stylesheet()->list();
|
|
|
|
$matchMode = $_GET['matchtype'] ?? 'fuzzy';
|
|
$searchDisabledInvites = isset($_GET['disabled_invites']) && $_GET['disabled_invites'] != '';
|
|
$searchDisabledUploads = isset($_GET['disabled_uploads']) && $_GET['disabled_uploads'] != '';
|
|
$searchLockedAccount = ($_GET['lockedaccount'] ?? '') === 'locked';
|
|
$showInvited = ($_GET['invited'] ?? 'off') !== 'off';
|
|
|
|
if ($_GET === []) {
|
|
$result = [];
|
|
} else {
|
|
$emailHistoryChecked = isset($_GET['email_history']);
|
|
$disabledIpChecked = isset($_GET['disabled_ip']);
|
|
$ipHistoryChecked = isset($_GET['ip_history']);
|
|
$trackerLiveSource = ($_GET['tracker-src'] ?? 'live') == 'live';
|
|
$dateRegexp = ['regexp' => '/\d{4}-\d{2}-\d{2}/'];
|
|
$userclassList = [];
|
|
$secClassList = [];
|
|
foreach ($userMan->classList() as $id => $value) {
|
|
if ($value['Secondary']) {
|
|
$secClassList[] = $id;
|
|
} else {
|
|
$userclassList[] = $id;
|
|
}
|
|
}
|
|
|
|
$validator = new Util\Validator();
|
|
$validator->setFields([
|
|
['avatar', false, 'string', 'Avatar URL too long', ['maxlength' => 512]],
|
|
['bounty', false, 'inarray', "Invalid bounty field", $offNumberChoice],
|
|
['cc', false, 'inarray', 'Invalid Country Code', ['maxlength' => 2]],
|
|
['comment', false, 'string', 'Comment is too long.', ['maxlength' => 512]],
|
|
['disabled_invites', false, 'inarray', 'Invalid disabled_invites field', $yesNo],
|
|
['disabled_uploads', false, 'inarray', 'Invalid disabled_uploads field', $yesNo],
|
|
['downloaded', false, 'inarray', 'Invalid downloaded field', $numberChoice],
|
|
['enabled', false, 'inarray', 'Invalid enabled field', ['inarray' => ['', 0, 1, 2]]],
|
|
['join1', false, 'regexp', 'Invalid join1 field', $dateRegexp],
|
|
['join2', false, 'regexp', 'Invalid join2 field', $dateRegexp],
|
|
['joined', false, 'inarray', 'Invalid joined field', $dateChoice],
|
|
['lastactive', false, 'inarray', 'Invalid lastactive field', $dateChoice],
|
|
['lastactive1', false, 'regexp', 'Invalid lastactive1 field', $dateRegexp],
|
|
['lastactive2', false, 'regexp', 'Invalid lastactive2 field', $dateRegexp],
|
|
['lockedaccount', false, 'inarray', 'Invalid locked account field', ['inarray' => ['any', 'locked', 'unlocked']]],
|
|
['matchtype', false, 'inarray', 'Invalid matchtype field', ['inarray' => ['strict', 'fuzzy', 'regexp']]],
|
|
['order', false, 'inarray', 'Invalid ordering', $orderByValue],
|
|
['passkey', false, 'string', 'Invalid passkey', ['maxlength' => 32]],
|
|
['ratio', false, 'inarray', 'Invalid ratio field', $numberChoice],
|
|
['secclass', false, 'inarray', 'Invalid class', ['inarray' => $secClassList]],
|
|
['seeding', false, 'inarray', "Invalid seeding field", $offNumberChoice],
|
|
['snatched', false, 'inarray', "Invalid snatched field", $offNumberChoice],
|
|
['stylesheet', false, 'inarray', 'Invalid stylesheet', ['inarray' => array_keys($stylesheet)]],
|
|
['uploaded', false, 'inarray', 'Invalid uploaded field', $numberChoice],
|
|
['warned', false, 'inarray', 'Invalid warned field', $nullable],
|
|
['way', false, 'inarray', 'Invalid way', $dirValue],
|
|
]);
|
|
if (!$validator->validate($_GET)) {
|
|
Error400::error($validator->errorMessage());
|
|
}
|
|
|
|
$m = new Search\User($matchMode);
|
|
$where = [];
|
|
$args = [];
|
|
$join = [];
|
|
$distinct = false;
|
|
$order = '';
|
|
|
|
$invitedValue = $showInvited
|
|
? '(SELECT count(*) FROM relay.users_main AS umi WHERE umi.inviter_user_id = um1."ID")'
|
|
: "'X'";
|
|
$seedingValue = ($_GET['seeding'] ?? 'off') == 'off'
|
|
? "'X'"
|
|
: '(SELECT count(DISTINCT fid)
|
|
FROM relay.xbt_files_users xfu
|
|
WHERE xfu.active = 1 AND xfu.remaining = 0 AND xfu.mtime > unix_timestamp(now() - INTERVAL 1 HOUR)
|
|
AND xfu.uid = um1."ID")';
|
|
$snatchesValue = ($_GET['snatched'] ?? 'off') == 'off'
|
|
? "'X'"
|
|
: '(SELECT count(DISTINCT fid) FROM relay.xbt_snatched AS xs WHERE xs.uid = um1."ID")';
|
|
|
|
$columns = "
|
|
um1.\"ID\" AS user_id,
|
|
$seedingValue AS seeding,
|
|
$snatchesValue AS snatches,
|
|
$invitedValue AS invited
|
|
";
|
|
|
|
$from = 'FROM relay.users_main AS um1
|
|
INNER JOIN relay.permissions p ON (p."ID" = um1."PermissionID")
|
|
INNER JOIN relay.users_leech_stats AS uls1 ON (uls1."UserID" = um1."ID")
|
|
INNER JOIN relay.users_info AS ui1 ON (ui1."UserID" = um1."ID")
|
|
LEFT JOIN relay.user_last_access AS ula ON (ula.user_id = um1."ID")
|
|
';
|
|
|
|
if (strlen($_GET['username'] ?? '')) {
|
|
$where[] = $m->matchField('um1."Username"');
|
|
$args[] = $_GET['username'];
|
|
}
|
|
|
|
if (strlen($_GET['email'] ?? '')) {
|
|
if (isset($_GET['email_history'])) {
|
|
$distinct = true;
|
|
$join['he'] = 'INNER JOIN relay.users_history_emails AS he ON (he."UserID" = um1."ID")';
|
|
$where[] = $m->matchField('he."Email"');
|
|
} else {
|
|
$where[] = $m->matchField('um1."Email"');
|
|
}
|
|
$args[] = $_GET['email'];
|
|
}
|
|
|
|
if (strlen($_GET['email_opt'] ?? '') && strlen($_GET['email_cnt'] ?? '')) {
|
|
$where[] = sprintf('um1."ID" IN (%s)',
|
|
$m->op('
|
|
SELECT "UserID" FROM relay.users_history_emails GROUP BY "UserID" HAVING count(DISTINCT "Email")
|
|
', $_GET['emails_opt']
|
|
)
|
|
);
|
|
$args[] = (int)$_GET['email_cnt'];
|
|
}
|
|
|
|
if (strlen($_GET['ip'] ?? '')) {
|
|
if ($ipHistoryChecked) {
|
|
$distinct = true;
|
|
$join['hi'] = 'INNER JOIN relay.users_history_ips AS hi ON (hi."UserID" = um1."ID")';
|
|
$where[] = $m->leftMatch('hi."IP"');
|
|
} else {
|
|
$where[] = $m->leftMatch('um1."IP"');
|
|
}
|
|
$args[] = trim($_GET['ip']);
|
|
}
|
|
|
|
if ($searchLockedAccount) {
|
|
$join['la'] = 'INNER JOIN relay.locked_accounts AS la ON (la."UserID" = um1."ID")';
|
|
} elseif (isset($_GET['lockedaccount']) && $_GET['lockedaccount'] == 'unlocked') {
|
|
$join['la'] = 'LEFT JOIN relay.locked_accounts AS la ON (la."UserID" = um1."ID")';
|
|
$where[] = 'la."UserID" IS NULL';
|
|
}
|
|
|
|
if (strlen($_GET['cc'] ?? '')) {
|
|
$where[] = $m->op('um1.ipcc', $_GET['cc_op']);
|
|
$args[] = trim($_GET['cc']);
|
|
}
|
|
|
|
if (strlen($_GET['tracker_ip'] ?? '')) {
|
|
$distinct = true;
|
|
$join['xfu'] = $trackerLiveSource
|
|
? 'INNER JOIN relay.xbt_files_users AS xfu ON (um1."ID" = xfu.uid)'
|
|
: 'INNER JOIN relay.xbt_snatched AS xfu ON (um1."ID" = xfu.uid)';
|
|
$where[] = $m->leftMatch('xfu.ip');
|
|
$args[] = trim($_GET['tracker_ip']);
|
|
}
|
|
|
|
if (strlen($_GET['comment'] ?? '')) {
|
|
$distinct = true;
|
|
$join['audit'] = 'inner join user_audit_trail uat on (uat.id_user = um1."ID")';
|
|
$where[] = "note_ts @@ plainto_tsquery('simple', ?)";
|
|
$args[] = $_GET['comment'];
|
|
}
|
|
|
|
if (strlen($_GET['lastfm'] ?? '')) {
|
|
$distinct = true;
|
|
$join['lfm'] = 'INNER JOIN relay.lastfm_users AS lfm ON (lfm."ID" = um1."ID")';
|
|
$where[] = $m->matchField('lfm."Username"');
|
|
$args[] = $_GET['lastfm'];
|
|
}
|
|
|
|
if (strlen($_GET['invites'] ?? '') && strlen($_GET['invites1'] ?? '')) {
|
|
$op = $_GET['invites'];
|
|
$where[] = $m->op('um1."Invites"', $op);
|
|
$args = array_merge($args, [$_GET['invites1']], ($op === 'between' ? [$_GET['invites2']] : []));
|
|
}
|
|
|
|
if ($showInvited && strlen($_GET['invited1'] ?? '')) {
|
|
$op = $_GET['invited'];
|
|
$where[] = 'um1.ID IN ('
|
|
. $m->op('SELECT umi."ID"
|
|
FROM relay.users_main umii
|
|
INNER JOIN relay.users_main umi ON (umi."ID" = umii.inviter_user_id)
|
|
GROUP BY umi."ID"
|
|
HAVING count(*)', $op
|
|
) . ')';
|
|
$args = array_merge($args, [$_GET['invited1']], ($op === 'between' ? [$_GET['invited2']] : []));
|
|
}
|
|
|
|
if ($searchDisabledInvites) {
|
|
$allow = $_GET['disabled_invites'] == 'yes' ? '' : 'NOT ';
|
|
$where[] = $allow . ' EXISTS(
|
|
SELECT 1
|
|
FROM relay.user_has_attr uha_invite
|
|
WHERE uha_invite."UserID" = um1."ID"
|
|
AND uha_invite."UserAttrID" = (SELECT "ID" FROM user_attr WHERE "Name" = ?)
|
|
)';
|
|
$args[] = 'disable-invites';
|
|
}
|
|
|
|
if ($searchDisabledUploads) {
|
|
$allow = $_GET['disabled_uploads'] == 'yes' ? '' : 'NOT ';
|
|
$where[] = $allow . ' EXISTS(
|
|
SELECT 1
|
|
FROM relay.user_has_attr uha_upload
|
|
WHERE uha_upload."UserID" = um1."ID"
|
|
AND uha_upload."UserAttrID" = (SELECT "ID" FROM user_attr WHERE "Name" = ?)
|
|
)';
|
|
$args[] = 'disable-upload';
|
|
}
|
|
|
|
if (strlen($_GET['joined'] ?? '') && strlen($_GET['join1'] ?? '')) {
|
|
$op = $_GET['joined'];
|
|
$where[] = $m->date('um1.created', $op);
|
|
$args[] = $_GET['join1'];
|
|
if ($op === 'on') {
|
|
$args[] = $_GET['join1'];
|
|
} elseif ($op === 'between') {
|
|
$args[] = $_GET['join2'];
|
|
}
|
|
}
|
|
|
|
if (strlen($_GET['lastactive'] ?? '') && strlen($_GET['lastactive1'] ?? '')) {
|
|
$op = $_GET['lastactive'];
|
|
$where[] = $m->date('ula.last_access', $op);
|
|
$args[] = $_GET['lastactive1'];
|
|
if ($op === 'on') {
|
|
$args[] = $_GET['lastactive1'];
|
|
} elseif ($op === 'between') {
|
|
$args[] = $_GET['lastactive2'];
|
|
}
|
|
}
|
|
|
|
if (strlen($_GET['ratio'] ?? '') && strlen($_GET['ratio1'] ?? '')) {
|
|
$frac = explode('.', $_GET['ratio1']);
|
|
$decimals = strlen(end($frac));
|
|
if (!$decimals) {
|
|
$decimals = 0;
|
|
}
|
|
$op = $_GET['ratio'];
|
|
$where[] = $m->op('CASE WHEN uls1."Downloaded" = 0 then 0 ELSE round(uls1."Uploaded"/uls1."Downloaded", ?) END', $op);
|
|
$args = array_merge($args, [$decimals, $_GET['ratio1']], ($op === 'between' ? [$_GET['ratio2']] : []));
|
|
}
|
|
|
|
if (strlen($_GET['bounty'] ?? '') && $_GET['bounty'] !== 'off' && strlen($_GET['bounty1'] ?? '')) {
|
|
$op = $_GET['bounty'];
|
|
$where[] = $m->op('(SELECT sum("Bounty") FROM relay.requests_votes rv WHERE rv."UserID" = um1."ID")', $op);
|
|
$args = array_merge($args, [$_GET['bounty1'] * 1024 ** 3], ($op === 'between' ? [$_GET['bounty2'] * 1024 ** 3] : []));
|
|
}
|
|
|
|
if (strlen($_GET['downloads'] ?? '') && $_GET['downloads'] !== 'off' && strlen($_GET['downloads1'] ?? '')) {
|
|
$op = $_GET['downloads'];
|
|
$where[] = $m->op('(SELECT count(DISTINCT "TorrentID") FROM relay.users_downloads ud WHERE ud."UserID" = um1."ID")', $op);
|
|
$args = array_merge($args, [$_GET['downloads1']], ($op === 'between' ? [$_GET['downloads2']] : []));
|
|
}
|
|
|
|
if (strlen($_GET['seeding'] ?? '') && $_GET['seeding'] !== 'off' && strlen($_GET['seeding1'] ?? '')) {
|
|
$op = $_GET['seeding'];
|
|
$where[] = $m->op('(SELECT count(DISTINCT fid)
|
|
FROM relay.xbt_files_users xfu
|
|
WHERE xfu.active = 1 AND xfu.remaining = 0 AND xfu.mtime > unix_timestamp(now() - INTERVAL 1 HOUR)
|
|
AND xfu.uid = um1."ID")', $op);
|
|
$args = array_merge($args, [$_GET['seeding1']], ($op === 'between' ? [$_GET['seeding2']] : []));
|
|
}
|
|
|
|
if (strlen($_GET['snatched'] ?? '') && $_GET['snatched'] !== 'off' && strlen($_GET['snatched1'] ?? '')) {
|
|
$op = $_GET['snatched'];
|
|
$where[] = $m->op('(SELECT count(DISTINCT fid) FROM relay.xbt_snatched AS xs WHERE xs.uid = um1."ID")', $op);
|
|
$args = array_merge($args, [$_GET['snatched1']], ($op === 'between' ? [$_GET['snatched2']] : []));
|
|
}
|
|
|
|
if (strlen($_GET['uploaded'] ?? '') && strlen($_GET['uploaded1'] ?? '')) {
|
|
$op = $_GET['uploaded'];
|
|
if ($op === 'buffer') {
|
|
$where[] = 'uls1."Uploaded" - uls1."Downloaded" BETWEEN ? AND ?';
|
|
$args = array_merge($args, [0.9 * $_GET['uploaded1'] * 1024 ** 3, 1.1 * $_GET['uploaded1'] * 1024 ** 3]);
|
|
} else {
|
|
$where[] = $m->op('uls1."Uploaded"', $op);
|
|
$args[] = $_GET['uploaded1'] * 1024 ** 3;
|
|
if ($op === 'on') {
|
|
$args[] = $_GET['uploaded1'] * 1024 ** 3;
|
|
} elseif ($op === 'between') {
|
|
$args[] = $_GET['uploaded2'] * 1024 ** 3;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (strlen($_GET['downloaded'] ?? '') && strlen($_GET['downloaded1'] ?? '')) {
|
|
$op = $_GET['downloaded'];
|
|
$where[] = $m->op('uls1."Downloaded"', $op);
|
|
$args[] = $_GET['downloaded1'] * 1024 ** 3;
|
|
if ($op === 'on') {
|
|
$args[] = $_GET['downloaded1'] * 1024 ** 3;
|
|
} elseif ($op === 'between') {
|
|
$args[] = $_GET['downloaded2'] * 1024 ** 3;
|
|
}
|
|
}
|
|
|
|
if (strlen($_GET['enabled'] ?? '')) {
|
|
$where[] = 'um1."Enabled" = ?';
|
|
$args[] = $_GET['enabled'];
|
|
}
|
|
|
|
if (isset($_GET['class']) && is_array($_GET['class'])) {
|
|
$where[] = 'um1."PermissionID" IN (' . placeholders($_GET['class']) . ')';
|
|
$args = array_merge($args, $_GET['class']);
|
|
}
|
|
|
|
if (strlen($_GET['secclass'] ?? '')) {
|
|
$join['ul'] = 'INNER JOIN relay.users_levels AS ul ON (um1."ID" = ul."UserID")';
|
|
$where[] = 'ul."PermissionID" = ?';
|
|
$args[] = $_GET['secclass'];
|
|
}
|
|
|
|
if (isset($_GET['warned'])) {
|
|
$where[] = $m->op('ui1."Warned"', $_GET['warned']);
|
|
}
|
|
|
|
if ($disabledIpChecked) {
|
|
$distinct = true;
|
|
if ($ipHistoryChecked) {
|
|
if (!isset($join['hi'])) {
|
|
$join['hi'] = 'LEFT JOIN relay.users_history_ips AS hi ON (hi."UserID" = um1."ID")';
|
|
}
|
|
$join['um2'] = 'LEFT JOIN relay.users_main AS um2 ON (um2."ID" != um1."ID" AND um2."Enabled" = \'2\' AND um2."ID" = hi."UserID")';
|
|
} else {
|
|
$join['um2'] = 'LEFT JOIN relay.users_main AS um2 ON (um2."ID" != um1."ID" AND um2."Enabled" = \'2\' AND um2."IP" = um1."IP")';
|
|
}
|
|
}
|
|
|
|
if (strlen($_GET['passkey'] ?? '')) {
|
|
$where[] = $m->matchField('um1.torrent_pass');
|
|
$args[] = $_GET['passkey'];
|
|
}
|
|
|
|
if (strlen($_GET['avatar'] ?? '')) {
|
|
$where[] = $m->matchField('um1.avatar');
|
|
$args[] = $_GET['avatar'];
|
|
}
|
|
|
|
if (strlen($_GET['stylesheet'] ?? '')) {
|
|
$where[] = $m->matchField('um1.stylesheet_id');
|
|
$args[] = $_GET['stylesheet'];
|
|
}
|
|
|
|
$order = 'ORDER BY ' . $orderBy[$_GET['order'] ?? 'Joined'] . ' ' . $dir[$_GET['way'] ?? 'Descending'];
|
|
|
|
//---------- Build the query
|
|
$query = "SELECT count(*) $from " . implode("\n", $join);
|
|
if (count($where)) {
|
|
$query .= " WHERE " . implode("\nAND ", $where);
|
|
}
|
|
if ($distinct) {
|
|
$query .= ' GROUP BY um1."ID"';
|
|
}
|
|
|
|
$pg = new DB\Pg(PG_RW_DSN);
|
|
$paginator->setTotal((int)$pg->scalar($query, ...$args));
|
|
|
|
$query = "SELECT $columns $from " . implode("\n", $join);
|
|
if (count($where)) {
|
|
$query .= ' WHERE ' . implode("\nAND ", $where);
|
|
}
|
|
if ($distinct) {
|
|
$query .= 'GROUP BY um1."ID", um1.created';
|
|
}
|
|
$query .= " $order LIMIT ? OFFSET ?";
|
|
|
|
$result = $pg->all($query, ...array_merge($args, [$paginator->limit(), $paginator->offset()]));
|
|
foreach ($result as &$r) {
|
|
$r['user'] = $userMan->findById($r['user_id']);
|
|
}
|
|
unset($r);
|
|
}
|
|
|
|
// Neither level nor ID is particularly useful when searching secondary classes, so sort them alphabetically.
|
|
$userclassLevel = $userMan->classLevelList();
|
|
$secondary = array_filter($userclassLevel, fn ($c) => $c['Secondary'] == '1');
|
|
usort($secondary, fn($c1, $c2) => $c1['Name'] <=> $c2['Name']);
|
|
|
|
echo $Twig->render('admin/advanced-user-search.twig', [
|
|
'page' => $result,
|
|
'paginator' => $paginator,
|
|
'show_invited' => $showInvited,
|
|
'url_stem' => new User\Stylesheet($Viewer)->imagePath(),
|
|
'viewer' => $Viewer,
|
|
'input' => $_GET,
|
|
|
|
'tracker_live_source' => $trackerLiveSource,
|
|
'check_disabled_ip' => $disabledIpChecked,
|
|
'check_ip_history' => $ipHistoryChecked,
|
|
'check_email_history' => $emailHistoryChecked,
|
|
|
|
// third column
|
|
'primary_class' => array_filter($userclassLevel, fn ($c) => $c['Secondary'] == '0'),
|
|
'secondary_class' => $secondary,
|
|
'stylesheet' => $stylesheet,
|
|
'match_mode' => $matchMode,
|
|
|
|
// sorting widgets
|
|
'field_by' => array_shift($orderByValue),
|
|
'order_by' => array_shift($dirValue),
|
|
]);
|