conn = $db; } // --- 1. INSCRIPTION --- public function register($username, $email, $password) { // On vérifie si l'email ou le pseudo existe déjà if ($this->emailExists($email) || $this->usernameExists($username)) { return ["success" => false, "message" => "Pseudo ou email déjà utilisé."]; } // Génération d'un code de liaison unique (ex: WG-X89F2) $pairing_code = $this->generateUniquePairingCode(); // Hachage sécurisé du mot de passe $hashed_password = password_hash($password, PASSWORD_BCRYPT); $query = "INSERT INTO " . $this->table_name . " SET username = :username, email = :email, password = :password, pairing_code = :pairing_code"; $stmt = $this->conn->prepare($query); $stmt->bindParam(":username", $username); $stmt->bindParam(":email", $email); $stmt->bindParam(":password", $hashed_password); $stmt->bindParam(":pairing_code", $pairing_code); if ($stmt->execute()) { return [ "success" => true, "message" => "Utilisateur créé avec succès.", "pairing_code" => $pairing_code ]; } return ["success" => false, "message" => "Erreur lors de l'inscription."]; } // --- 2. CONNEXION --- public function login($email, $password) { $query = "SELECT id, username, email, password, pairing_code, partner_id FROM " . $this->table_name . " WHERE email = :email LIMIT 0,1"; $stmt = $this->conn->prepare($query); $stmt->bindParam(":email", $email); $stmt->execute(); if ($stmt->rowCount() > 0) { $row = $stmt->fetch(); // Vérification du mot de passe if (password_verify($password, $row['password'])) { return [ "success" => true, "user" => [ "id" => $row['id'], "username" => $row['username'], "email" => $row['email'], "pairing_code" => $row['pairing_code'], "partner_id" => $row['partner_id'] ] ]; } } return ["success" => false, "message" => "Identifiants incorrects."]; } // --- 3. LIAISON DE DEUX COMPTES --- public function linkPartner($current_user_id, $partner_code) { // 1. Trouver le partenaire qui possède ce code $query = "SELECT id, partner_id FROM " . $this->table_name . " WHERE pairing_code = :partner_code LIMIT 0,1"; $stmt = $this->conn->prepare($query); $stmt->bindParam(":partner_code", $partner_code); $stmt->execute(); if ($stmt->rowCount() == 0) { return ["success" => false, "message" => "Code de liaison invalide."]; } $partner = $stmt->fetch(); $partner_id = $partner['id']; // Sécurité : On ne peut pas se lier à soi-même if ($partner_id == $current_user_id) { return ["success" => false, "message" => "Tu ne peux pas te lier à ton propre compte."]; } // Sécurité : Vérifier si le partenaire est déjà pris if (!is_null($partner['partner_id'])) { return ["success" => false, "message" => "Ce partenaire est déjà lié à quelqu'un d'autre."]; } try { // On commence une transaction SQL pour être sûr que les deux updates passent (ou aucun) $this->conn->beginTransaction(); // Update de l'utilisateur actuel $query1 = "UPDATE " . $this->table_name . " SET partner_id = :partner_id WHERE id = :current_id"; $stmt1 = $this->conn->prepare($query1); $stmt1->bindParam(":partner_id", $partner_id); $stmt1->bindParam(":current_id", $current_user_id); $stmt1->execute(); // Update du partenaire (réciprocité) $query2 = "UPDATE " . $this->table_name . " SET partner_id = :current_id WHERE id = :partner_id"; $stmt2 = $this->conn->prepare($query2); $stmt2->bindParam(":current_id", $current_user_id); $stmt2->bindParam(":partner_id", $partner_id); $stmt2->execute(); $this->conn->commit(); return ["success" => true, "message" => "Comptes liés avec succès !"]; } catch (Exception $e) { $this->conn->rollBack(); return ["success" => false, "message" => "Erreur lors de la liaison."]; } } // --- 4. RÉCUPÉRER LE STATUT DE PAIRAGE --- public function getPairingStatus($user_id) { // On récupère les infos de l'utilisateur et de son partenaire s'il existe $query = "SELECT u1.pairing_code, u1.partner_id, u2.username AS partner_username FROM " . $this->table_name . " u1 LEFT JOIN " . $this->table_name . " u2 ON u1.partner_id = u2.id WHERE u1.id = :user_id LIMIT 1"; $stmt = $this->conn->prepare($query); $stmt->bindParam(":user_id", $user_id); $stmt->execute(); if ($stmt->rowCount() > 0) { return ["success" => true, "data" => $stmt->fetch()]; } return ["success" => false, "message" => "Utilisateur introuvable."]; } // --- 5. CASSER LE LIEN (DÉLIAISON) --- public function unlinkPartner($user_id) { // 1. On cherche d'abord l'ID du partenaire actuel $query = "SELECT partner_id FROM " . $this->table_name . " WHERE id = :user_id LIMIT 1"; $stmt = $this->conn->prepare($query); $stmt->bindParam(":user_id", $user_id); $stmt->execute(); $user = $stmt->fetch(); if (!$user || is_null($user['partner_id'])) { return ["success" => false, "message" => "Tu n'es lié à personne."]; } $partner_id = $user['partner_id']; try { $this->conn->beginTransaction(); // On passe le partner_id à NULL pour les deux utilisateurs $query1 = "UPDATE " . $this->table_name . " SET partner_id = NULL WHERE id = :user_id"; $stmt1 = $this->conn->prepare($query1); $stmt1->bindParam(":user_id", $user_id); $stmt1->execute(); $query2 = "UPDATE " . $this->table_name . " SET partner_id = NULL WHERE id = :partner_id"; $stmt2 = $this->conn->prepare($query2); $stmt2->bindParam(":partner_id", $partner_id); $stmt2->execute(); $this->conn->commit(); return ["success" => true, "message" => "Comptes déliés avec succès."]; } catch (Exception $e) { $this->conn->rollBack(); return ["success" => false, "message" => "Erreur lors de la déliaison."]; } } // --- UTILS / VALIDATIONS --- private function emailExists($email) { $query = "SELECT id FROM " . $this->table_name . " WHERE email = :email LIMIT 1"; $stmt = $this->conn->prepare($query); $stmt->bindParam(":email", $email); $stmt->execute(); return $stmt->rowCount() > 0; } private function usernameExists($username) { $query = "SELECT id FROM " . $this->table_name . " WHERE username = :username LIMIT 1"; $stmt = $this->conn->prepare($query); $stmt->bindParam(":username", $username); $stmt->execute(); return $stmt->rowCount() > 0; } private function generateUniquePairingCode() { $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; do { $code = 'WG-'; for ($i = 0; $i < 6; $i++) { $code .= $characters[rand(0, strlen($characters) - 1)]; } // On vérifie en BDD que le code n'existe pas déjà par pur hasard $query = "SELECT id FROM " . $this->table_name . " WHERE pairing_code = :code LIMIT 1"; $stmt = $this->conn->prepare($query); $stmt->bindParam(":code", $code); $stmt->execute(); $exists = $stmt->rowCount() > 0; } while ($exists); return $code; } }