102 lines
5.3 KiB
PHP
102 lines
5.3 KiB
PHP
<?php
|
|
// Edição de um utilizador pelo administrador de sistema: nome, email, telefone,
|
|
// perfil (incluindo promover a admin) e estado. A palavra-passe continua em
|
|
// set_password.php. Só o sysadmin chega aqui — um admin não se pode promover.
|
|
|
|
require __DIR__ . '/../../config/db.php';
|
|
require __DIR__ . '/../../config/functions.php';
|
|
$user = require_sysadmin();
|
|
|
|
$target = db_get_user($pdo, (int) ($_GET['id'] ?? $_POST['id'] ?? 0));
|
|
if (!$target) {
|
|
header('Location: ' . base_url('views/user/index.php'));
|
|
exit;
|
|
}
|
|
|
|
// Não se altera o próprio perfil/estado aqui: evita o sysadmin ficar sem acesso
|
|
// por engano (o último sysadmin deixaria de existir).
|
|
$is_self = ((int) $target['id'] === (int) $user['id']);
|
|
$roles = ['sysadmin', 'admin', 'staff', 'client'];
|
|
$error = '';
|
|
$saved = false;
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
csrf_check();
|
|
$name = trim($_POST['name'] ?? '');
|
|
$email = strtolower(trim($_POST['email'] ?? ''));
|
|
$phone = trim($_POST['phone'] ?? '');
|
|
$role = $is_self ? $target['role'] : (string) ($_POST['role'] ?? '');
|
|
$active = $is_self ? (int) $target['is_active'] : (isset($_POST['is_active']) ? 1 : 0);
|
|
|
|
if ($name === '' || mb_strlen($name) > 100) {
|
|
$error = 'Indique um nome (máx. 100 caracteres).';
|
|
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL) || strlen($email) > 190) {
|
|
$error = 'Email inválido.';
|
|
} elseif (!in_array($role, $roles, true)) {
|
|
$error = 'Perfil inválido.';
|
|
} elseif (mb_strlen($phone) > 20) {
|
|
$error = 'Telefone demasiado longo (máx. 20 caracteres).';
|
|
} else {
|
|
$other = db_get_user_by_email($pdo, $email);
|
|
if ($other && (int) $other['id'] !== (int) $target['id']) {
|
|
$error = 'Já existe outro utilizador com esse email.';
|
|
}
|
|
}
|
|
|
|
if ($error === '') {
|
|
$fields = ['name', 'email', 'phone', 'role', 'is_active'];
|
|
$before = array_intersect_key($target, array_flip($fields));
|
|
$new = ['name' => $name, 'email' => $email, 'phone' => $phone !== '' ? $phone : null,
|
|
'role' => $role, 'is_active' => $active];
|
|
$pdo->prepare('UPDATE users SET name=?, email=?, phone=?, role=?, is_active=? WHERE id=?')
|
|
->execute([$name, $email, $new['phone'], $role, $active, (int) $target['id']]);
|
|
$changes = platform_audit_diff($before, $new);
|
|
if ($changes) {
|
|
audit('user.update', [
|
|
'target_type' => 'user', 'target_id' => (int) $target['id'],
|
|
'target_label' => $name, 'changes' => $changes,
|
|
]);
|
|
}
|
|
$saved = true;
|
|
$target = db_get_user($pdo, (int) $target['id']) ?? $target;
|
|
} else {
|
|
// Mantém o que foi escrito para o formulário não perder as alterações.
|
|
$target = array_merge($target, ['name' => $name, 'email' => $email, 'phone' => $phone, 'role' => $role, 'is_active' => $active]);
|
|
}
|
|
}
|
|
|
|
$page_title = 'Editar utilizador';
|
|
include __DIR__ . '/../../includes/header.php';
|
|
?>
|
|
<div class="container" style="max-width:640px;">
|
|
<h1 class="h3 mb-4">Editar utilizador</h1>
|
|
<?php if ($saved): ?><div class="alert alert-success">Utilizador atualizado.</div><?php endif; ?>
|
|
<?php if ($error): ?><div class="alert alert-danger"><?= htmlspecialchars($error) ?></div><?php endif; ?>
|
|
<?php if ($is_self): ?>
|
|
<div class="alert alert-info small">É a sua própria conta: o perfil e o estado não podem ser alterados aqui, para não perder o acesso.</div>
|
|
<?php endif; ?>
|
|
|
|
<form method="POST" class="card shadow-sm"><div class="card-body">
|
|
<?= csrf_field() ?>
|
|
<input type="hidden" name="id" value="<?= (int) $target['id'] ?>">
|
|
<div class="mb-3"><label class="form-label" for="eu-name">Nome</label>
|
|
<input class="form-control" id="eu-name" name="name" required maxlength="100" value="<?= htmlspecialchars($target['name']) ?>"></div>
|
|
<div class="mb-3"><label class="form-label" for="eu-email">Email</label>
|
|
<input type="email" class="form-control" id="eu-email" name="email" required maxlength="190" value="<?= htmlspecialchars($target['email']) ?>"></div>
|
|
<div class="mb-3"><label class="form-label" for="eu-phone">Telefone</label>
|
|
<input class="form-control" id="eu-phone" name="phone" maxlength="20" value="<?= htmlspecialchars((string) ($target['phone'] ?? '')) ?>"></div>
|
|
<div class="mb-3"><label class="form-label" for="eu-role">Perfil</label>
|
|
<select class="form-select" id="eu-role" name="role"<?= $is_self ? ' disabled' : '' ?>>
|
|
<?php foreach ($roles as $r): ?>
|
|
<option value="<?= $r ?>"<?= $target['role'] === $r ? ' selected' : '' ?>><?= htmlspecialchars(role_label($r)) ?></option>
|
|
<?php endforeach; ?>
|
|
</select></div>
|
|
<div class="form-check mb-3"><input class="form-check-input" type="checkbox" name="is_active" id="eu-active" value="1"
|
|
<?= !empty($target['is_active']) ? 'checked' : '' ?><?= $is_self ? ' disabled' : '' ?>>
|
|
<label class="form-check-label" for="eu-active">Conta ativa</label></div>
|
|
<button class="btn btn-primary">Guardar</button>
|
|
<a class="btn btn-link" href="<?= base_url('views/user/index.php') ?>">Voltar</a>
|
|
</div></form>
|
|
</div>
|
|
<?php include __DIR__ . '/../../includes/footer.php'; ?>
|