This commit is contained in:
@@ -298,44 +298,68 @@ final class CommunityAccess
|
||||
}
|
||||
|
||||
$limit = max(1, min(50, $limit));
|
||||
$rowsById = [];
|
||||
|
||||
$tokens = array_values(array_filter(preg_split('/\s+/u', mb_strtolower($query)) ?: [], static fn(string $token): bool => $token !== ''));
|
||||
if ($tokens === []) {
|
||||
return [];
|
||||
if ($tokens !== []) {
|
||||
$conditions = [];
|
||||
$params = [];
|
||||
foreach ($tokens as $index => $token) {
|
||||
$displayKey = ':display_' . $index;
|
||||
$conditions[] = 'LOWER(COALESCE(up.display_name, "")) LIKE ' . $displayKey;
|
||||
$params[$displayKey] = '%' . $token . '%';
|
||||
}
|
||||
|
||||
$sql = '
|
||||
SELECT u.id, u.email, u.status, up.display_name, up.first_name, up.last_name
|
||||
FROM users u
|
||||
LEFT JOIN user_profiles up ON up.user_id = u.id
|
||||
WHERE ' . implode(' AND ', $conditions) . '
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN LOWER(COALESCE(up.display_name, "")) = :exactDisplayQuery THEN 0
|
||||
ELSE 1
|
||||
END,
|
||||
COALESCE(up.display_name, ""),
|
||||
u.id DESC
|
||||
LIMIT ' . $limit;
|
||||
$params[':exactDisplayQuery'] = mb_strtolower($query);
|
||||
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) ?: [] as $row) {
|
||||
$rowsById[(int)($row['id'] ?? 0)] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$conditions = [];
|
||||
$params = [];
|
||||
foreach ($tokens as $index => $token) {
|
||||
$displayKey = ':display_' . $index;
|
||||
$nameKey = ':name_' . $index;
|
||||
$emailKey = ':email_' . $index;
|
||||
$conditions[] = '(LOWER(COALESCE(up.display_name, "")) LIKE ' . $displayKey . ' OR LOWER(CONCAT_WS(" ", COALESCE(up.first_name, ""), COALESCE(up.last_name, ""))) LIKE ' . $nameKey . ' OR LOWER(COALESCE(u.email, "")) LIKE ' . $emailKey . ')';
|
||||
$needle = '%' . $token . '%';
|
||||
$params[$displayKey] = $needle;
|
||||
$params[$nameKey] = $needle;
|
||||
$params[$emailKey] = $needle;
|
||||
if (str_contains($query, '@')) {
|
||||
$emailRow = $this->emailStore()->findUserByEmail($query, 'id, email, status');
|
||||
if (is_array($emailRow)) {
|
||||
$profileStmt = $this->pdo->prepare('SELECT display_name, first_name, last_name FROM user_profiles WHERE user_id = :uid LIMIT 1');
|
||||
$profileStmt->execute(['uid' => (int)$emailRow['id']]);
|
||||
$profileRow = $profileStmt->fetch(\PDO::FETCH_ASSOC) ?: [];
|
||||
$emailRow['display_name'] = (string)($profileRow['display_name'] ?? '');
|
||||
$emailRow['first_name'] = (string)($profileRow['first_name'] ?? '');
|
||||
$emailRow['last_name'] = (string)($profileRow['last_name'] ?? '');
|
||||
$rowsById[(int)$emailRow['id']] = $emailRow;
|
||||
}
|
||||
}
|
||||
|
||||
$sql = '
|
||||
SELECT u.id, u.email, u.status, up.display_name, up.first_name, up.last_name
|
||||
FROM users u
|
||||
LEFT JOIN user_profiles up ON up.user_id = u.id
|
||||
WHERE ' . implode(' AND ', $conditions) . '
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN LOWER(COALESCE(up.display_name, "")) = :exactDisplayQuery THEN 0
|
||||
WHEN LOWER(COALESCE(u.email, "")) = :exactEmailQuery THEN 1
|
||||
ELSE 2
|
||||
END,
|
||||
COALESCE(up.display_name, ""),
|
||||
u.id DESC
|
||||
LIMIT ' . $limit;
|
||||
$params[':exactDisplayQuery'] = mb_strtolower($query);
|
||||
$params[':exactEmailQuery'] = mb_strtolower($query);
|
||||
$rows = array_values($rowsById);
|
||||
usort($rows, static function (array $left, array $right) use ($query): int {
|
||||
$leftDisplay = mb_strtolower((string)($left['display_name'] ?? ''));
|
||||
$rightDisplay = mb_strtolower((string)($right['display_name'] ?? ''));
|
||||
$needle = mb_strtolower($query);
|
||||
$leftRank = $leftDisplay === $needle ? 0 : 1;
|
||||
$rightRank = $rightDisplay === $needle ? 0 : 1;
|
||||
if ($leftRank !== $rightRank) {
|
||||
return $leftRank <=> $rightRank;
|
||||
}
|
||||
return ((int)($right['id'] ?? 0)) <=> ((int)($left['id'] ?? 0));
|
||||
});
|
||||
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
return $this->emailStore()->decryptRowEmails($stmt->fetchAll(\PDO::FETCH_ASSOC) ?: [], 'id');
|
||||
$rows = array_slice($rows, 0, $limit);
|
||||
return $this->emailStore()->decryptRowEmails($rows, 'id');
|
||||
}
|
||||
|
||||
public function setRestriction(int $actingUserId, int $targetUserId, string $type, string $reason): void
|
||||
|
||||
Reference in New Issue
Block a user