pdo->prepare('SELECT id FROM users WHERE email = :email LIMIT 1'); $st->execute([':email' => $email]); $id = $st->fetchColumn(); if ($id !== false && $id !== null) { return (string)$id; } // 2) Création // Génère un hash robuste sur une valeur aléatoire (aucune chance de connexion par mot de passe). $randomSecret = bin2hex(random_bytes(32)); $randomHash = password_hash($randomSecret, PASSWORD_DEFAULT); $sql = <<pdo->prepare($sql); $st->execute([ ':email' => $email, ':hash' => $randomHash, ]); return (string)$st->fetchColumn(); } catch (\PDOException $e) { // Unique violation sur email (23505) → on relit l’id (race condition) if ($e->getCode() === '23505') { $st = $this->pdo->prepare('SELECT id FROM users WHERE email = :email LIMIT 1'); $st->execute([':email' => $email]); $id = $st->fetchColumn(); if ($id !== false && $id !== null) { return (string)$id; } } throw $e; } } public function findByEmail(string $email): ?User { $sql = 'SELECT id, email, password_hash, is_active FROM users WHERE email = :email LIMIT 1'; $st = $this->pdo->prepare($sql); $st->execute([':email' => $email]); $row = $st->fetch(PDO::FETCH_ASSOC); if (!$row) { return null; } $isActive = $this->toBool($row['is_active']); return new User( (string)$row['id'], (string)$row['email'], (string)$row['password_hash'], $isActive ); } public function create(string $email, string $passwordHash): string { // PostgreSQL $sql = 'INSERT INTO users (email, password_hash) VALUES (:email, :hash) RETURNING id'; $st = $this->pdo->prepare($sql); $st->execute([':email' => $email, ':hash' => $passwordHash]); return (string)$st->fetchColumn(); } public function updatePassword(string $userId, string $newHash): void { $sql = <<pdo->prepare($sql); $st->execute([':h' => $newHash, ':id' => $userId]); } /** * Normalise un bool venant de PDO/pgsql ('t','f',1,0,true,false,'1','0','true','false') */ private function toBool(mixed $v): bool { if (is_bool($v)) { return $v; } if (is_int($v)) { return $v === 1; } if (is_string($v)) { $v = strtolower($v); return in_array($v, ['t', '1', 'true', 'on', 'yes'], true); } return (bool)$v; } }