Auditoria 6.3 apontava dashboard.php (2×), user/index.php e
user/profile.php como as únicas vistas com SQL direto, quebrando a
convenção da frota (config/functions_*.php como camada de models). As
quatro passam a chamar db_users_count_clients(), db_users_count_team(),
db_users_list() e db_user_update_profile() — mesmo SQL, mesmos
parâmetros, só movido para onde o resto do código já vai buscar dados.
Nota: views/admin/gyms/{create,edit}.php e views/admin/reviews/index.php
também têm SQL direto, mas não estavam no âmbito dos "3 vistas" da
auditoria (entraram depois, no trabalho de multi-ginásio) — por tratar
numa próxima passagem.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
80 lines
3.3 KiB
PHP
80 lines
3.3 KiB
PHP
<?php
|
|
// ─── Generic DB helpers ──────────────────────────────────────────────────────
|
|
// Per the fleet convention, page files never write raw SQL — they call helpers
|
|
// here (and in feature-specific config/functions_*.php files added later). This
|
|
// pass ships only the user/auth-adjacent helpers needed by the SSO shell and
|
|
// the admin/user dashboards; domain CRUD (plataforma_fitness, team, modalidades,
|
|
// horário, galerias) lands with the follow-up port.
|
|
|
|
// Fetch a single user row by id (NULL if missing).
|
|
function db_get_user(PDO $pdo, int $id): ?array {
|
|
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ? LIMIT 1");
|
|
$stmt->execute([$id]);
|
|
return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
|
|
}
|
|
|
|
// Fetch a single user row by email (canonical SSO key).
|
|
function db_get_user_by_email(PDO $pdo, string $email): ?array {
|
|
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ? LIMIT 1");
|
|
$stmt->execute([strtolower(trim($email))]);
|
|
return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
|
|
}
|
|
|
|
// All backoffice users (sysadmin + admin + staff) for management lists.
|
|
function db_get_all_staff(PDO $pdo): array {
|
|
return $pdo->query(
|
|
"SELECT * FROM users
|
|
WHERE role IN ('sysadmin','admin','staff')
|
|
ORDER BY FIELD(role,'sysadmin','admin','staff'), name"
|
|
)->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
// Active admins (sysadmin + admin) — e.g. assignment dropdowns.
|
|
function db_get_active_admins(PDO $pdo): array {
|
|
return $pdo->query(
|
|
"SELECT * FROM users
|
|
WHERE role IN ('sysadmin','admin') AND is_active = 1
|
|
ORDER BY name"
|
|
)->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
// Every user, in role order — the listing at views/user/index.php.
|
|
function db_users_list(PDO $pdo): array {
|
|
return $pdo->query(
|
|
"SELECT id, name, email, phone, role, is_active, password_hash, last_login_at, last_login_ua
|
|
FROM users ORDER BY FIELD(role,'sysadmin','admin','staff','client'), name"
|
|
)->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
// Dashboard widget counts (views/admin/dashboard.php).
|
|
function db_users_count_clients(PDO $pdo): int {
|
|
return (int) $pdo->query("SELECT COUNT(*) FROM users WHERE role = 'client'")->fetchColumn();
|
|
}
|
|
|
|
function db_users_count_team(PDO $pdo): int {
|
|
return (int) $pdo->query("SELECT COUNT(*) FROM users WHERE role IN ('admin','staff')")->fetchColumn();
|
|
}
|
|
|
|
// Profile self-edit (views/user/profile.php) — the contact-details half of
|
|
// the form; the password half already goes through auth_set_password().
|
|
function db_user_update_profile(PDO $pdo, int $userId, array $data): void {
|
|
$pdo->prepare(
|
|
"UPDATE users SET phone=?, address=?, city=?, postal_code=?,
|
|
email_opt_out=?, sms_opt_out=?, marketing_consent=?
|
|
WHERE id=?"
|
|
)->execute([
|
|
$data['phone'], $data['address'], $data['city'], $data['postal_code'],
|
|
$data['email_opt_out'], $data['sms_opt_out'], $data['marketing_consent'], $userId,
|
|
]);
|
|
}
|
|
|
|
// PT-PT label for the role ladder.
|
|
function role_label(string $role): string {
|
|
return [
|
|
'sysadmin' => 'Administrador de sistema',
|
|
'admin' => 'Administrador',
|
|
'staff' => 'Equipa',
|
|
'client' => 'Cliente',
|
|
][$role] ?? ucfirst($role);
|
|
}
|