From d1c381d7ac9f8f77e467d1c34b6ac4a175dc8708 Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 11:02:48 +0200 Subject: [PATCH] Subir archivos a "clases" --- clases/ClasePregunta.php | 166 +++++++++++++++++++++++++-------------- clases/ClaseUsuario.php | 127 +++++++++++++++++++----------- 2 files changed, 190 insertions(+), 103 deletions(-) diff --git a/clases/ClasePregunta.php b/clases/ClasePregunta.php index b57c18e..937331f 100644 --- a/clases/ClasePregunta.php +++ b/clases/ClasePregunta.php @@ -3,21 +3,20 @@ require_once '../includes/conexionBD.php'; // Definición de la clase Pregunta que representará las preguntas de la trivia class Pregunta { - private ?int $id_pregunta; - private int $id_categoria; - private string $texto_pregunta; - private array $respuestas; - private PDO $db; + // ATRIBUTOS (Propiedades privadas para encapsular el estado de cada pregunta) + private ?int $id_pregunta; // El ID de la pregunta (autoincremental en la BD) + private int $id_categoria; // El ID de la categoría a la que pertenece la pregunta + private string $texto_pregunta; // El enunciado de la pregunta + private array $respuestas; // Array que guardará la lista de respuestas posibles asociadas a esta pregunta + // CONSTRUCTOR: Inicializa una nueva instancia de la clase Pregunta (sin pedir PDO de forma externa) public function __construct(int $id_categoria = 0, string $texto_pregunta = "", ?int $id_pregunta = null) { - global $db; // Vinculamos la variable global generada por conexion.php - $this->db = $db; - - $this->id_pregunta = $id_pregunta; - $this->id_categoria = $id_categoria; - $this->texto_pregunta = $texto_pregunta; - $this->respuestas = []; + $this->id_pregunta = $id_pregunta; // Asigna el ID (null si es una nueva pregunta que no se ha guardado) + $this->id_categoria = $id_categoria; // Asigna la categoría correspondiente + $this->texto_pregunta = $texto_pregunta; // Asigna el texto de la pregunta + $this->respuestas = []; // Inicializa el contenedor de respuestas como un array vacío } + // --- GETTERS Y SETTERS --- // Getter para obtener el ID de la pregunta (solo lectura) @@ -53,63 +52,116 @@ class Pregunta { // --- MÉTODOS DE BASE DE DATOS --- // Método para guardar una nueva pregunta en la base de datos - public function guardar(): bool { - // Preparamos la consulta SQL para insertar la categoría y el texto de la pregunta - $sql = "INSERT INTO pregunta (id_categoria, texto_pregunta) VALUES (:id_cat, :texto)"; - $stmt = $this->db->prepare($sql); - - // Ejecutamos la consulta asociando los atributos actuales del objeto a los marcadores SQL - $resultado = $stmt->execute([ - ':id_cat' => $this->id_categoria, - ':texto' => $this->texto_pregunta - ]); + public function guardar() { + // Obtenemos la conexión llamando a tu función unificada del proyecto + $conexion = conexionBD(); - // Si se guardó correctamente, actualizamos el atributo id_pregunta del objeto con el ID generado en la BD - if ($resultado) { - $this->id_pregunta = (int)$this->db->lastInsertId(); - return true; // Retorna verdadero si la operación tuvo éxito + // Si devuelve un array significa que ocurrió un error controlado al conectar + if (is_array($conexion)) { + return $conexion; + } + + try { + // Preparamos la consulta SQL para insertar la categoría y el texto de la pregunta + $sql = "INSERT INTO pregunta (id_categoria, texto_pregunta) VALUES (:id_cat, :texto)"; + $stmt = $conexion->prepare($sql); + + // Ejecutamos la consulta asociando los atributos actuales del objeto a los marcadores SQL + $stmt->execute([ + ':id_cat' => $this->id_categoria, + ':texto' => $this->texto_pregunta + ]); + + // Si se guardó correctamente, actualizamos el atributo id_pregunta del objeto con el ID generado en la BD + $this->id_pregunta = (int)$conexion->lastInsertId(); + + // Devolvemos la respuesta formateada con éxito e ID técnico para tu proyecto + return [ + 'exito' => 'Pregunta guardada correctamente', + 'exito_tecnico' => $this->id_pregunta + ]; + + } catch (PDOException $error) { + // Si falla la inserción en MySQL, capturamos el error + return [ + 'error' => 'Ocurrió un error al guardar la pregunta.', + 'error_tecnico' => $error->getMessage() + ]; } - return false; // Retorna falso si falló el guardado } // Método para buscar y cargar en memoria todas las respuestas asociadas a esta pregunta concreta - public function cargarRespuestas(): void { + public function cargarRespuestas() { // Si la pregunta aún no está guardada en la BD (su ID es null), no podemos buscar sus respuestas if ($this->id_pregunta === null) return; - // Consulta SQL para traer las respuestas vinculadas al ID de esta pregunta - $sql = "SELECT id_respuesta, texto_respuesta, es_correcta FROM respuesta WHERE id_pregunta = :id_preg"; - $stmt = $this->db->prepare($sql); - $stmt->execute([':id_preg' => $this->id_pregunta]); - - // Guardamos todas las filas encontradas directamente dentro del array de respuestas del objeto - $this->respuestas = $stmt->fetchAll(PDO::FETCH_ASSOC); + // Obtenemos la conexión llamando a tu función unificada del proyecto + $conexion = conexionBD(); + + // Si devuelve un array significa que ocurrió un error al conectar + if (is_array($conexion)) { + return $conexion; + } + + try { + // Consulta SQL adaptada exactamente a tus columnas reales: texto_respuesta y es_correcta + $sql = "SELECT id_respuesta, texto_respuesta, es_correcta FROM respuesta WHERE id_pregunta = :id_preg"; + $stmt = $conexion->prepare($sql); + $stmt->execute([':id_preg' => $this->id_pregunta]); + + // Guardamos todas las filas encontradas directamente dentro del array de respuestas del objeto + $this->respuestas = $stmt->fetchAll(PDO::FETCH_ASSOC); + + } catch (PDOException $error) { + // Capturamos cualquier excepción de base de datos + return [ + 'error' => 'Ocurrió un error al cargar las respuestas.', + 'error_tecnico' => $error->getMessage() + ]; + } } // Método estático para obtener un listado de preguntas aleatorias filtradas por una categoría - public static function obtenerPorCategoria(PDO $db, int $id_categoria, int $limite = 10): array { - // Consulta SQL que filtra por categoría, desordena los resultados al azar (RAND()) y limita la cantidad - $sql = "SELECT * FROM pregunta WHERE id_categoria = :id_cat ORDER BY RAND() LIMIT :limite"; - $stmt = $db->prepare($sql); - - // Vinculamos los parámetros asegurando que el límite sea interpretado estrictamente como un número entero (PARAM_INT) - $stmt->bindValue(':id_cat', $id_categoria, PDO::PARAM_INT); - $stmt->bindValue(':limite', $limite, PDO::PARAM_INT); - $stmt->execute(); // Ejecutamos la consulta + public static function obtenerPorCategoria(int $id_categoria, int $limite = 10) { + // Obtenemos la conexión llamando a tu función unificada del proyecto + $conexion = conexionBD(); - $preguntas = []; // Array donde amontonaremos los objetos Pregunta resultantes - - // Recorremos fila por fila los resultados devueltos por la base de datos - while ($datos = $stmt->fetch(PDO::FETCH_ASSOC)) { - // Creamos un nuevo objeto Pregunta con los datos de la fila actual - $preg = new Pregunta($db, $datos['id_categoria'], $datos['texto_pregunta'], $datos['id_pregunta']); - - // Llamamos al método interno del objeto para que busque y le pegue sus opciones de respuesta correspondientes - $preg->cargarRespuestas(); - - // Añadimos el objeto completamente armado al array final - $preguntas[] = $preg; + // Si devuelve un array significa que ocurrió un error al conectar + if (is_array($conexion)) { + return $conexion; + } + + try { + // Consulta SQL que filtra por categoría, desordena los resultados al azar (RAND()) y limita la cantidad + $sql = "SELECT * FROM pregunta WHERE id_categoria = :id_cat ORDER BY RAND() LIMIT :limite"; + $stmt = $conexion->prepare($sql); + + // Vinculamos los parámetros asegurando que el límite sea interpretado estrictamente como un número entero (PARAM_INT) + $stmt->bindValue(':id_cat', $id_categoria, PDO::PARAM_INT); + $stmt->bindValue(':limite', $limite, PDO::PARAM_INT); + $stmt->execute(); // Ejecutamos la consulta + + $preguntas = []; // Array donde amontonaremos los objetos Pregunta resultantes + + // Recorremos fila por fila los resultados devueltos por la base de datos + while ($datos = $stmt->fetch(PDO::FETCH_ASSOC)) { + // Creamos un nuevo objeto Pregunta con los datos de la fila actual + $preg = new Pregunta($datos['id_categoria'], $datos['texto_pregunta'], $datos['id_pregunta']); + + // Llamamos al método interno del objeto para que busque y le pegue sus opciones de respuesta correspondientes + $preg->cargarRespuestas(); + + // Añadimos el objeto completamente armado al array final + $preguntas[] = $preg; + } + return $preguntas; // Devolvemos la lista de objetos Pregunta listos para jugar + + } catch (PDOException $error) { + // Capturamos cualquier error en la consulta aleatoria + return [ + 'error' => 'Ocurrió un error al obtener las preguntas aleatorias.', + 'error_tecnico' => $error->getMessage() + ]; } - return $preguntas; // Devolvemos la lista de objetos Pregunta listos para jugar } } \ No newline at end of file diff --git a/clases/ClaseUsuario.php b/clases/ClaseUsuario.php index 336bc08..8c7b6eb 100644 --- a/clases/ClaseUsuario.php +++ b/clases/ClaseUsuario.php @@ -3,21 +3,18 @@ require_once '../includes/conexionBD.php'; // Definición de la clase Usuario que representará a los usuarios del sistema class Usuario { - private ?int $id_usuario; - private string $nombre_usuario; - private string $contrasena; - private string $email; - private PDO $db; // Se mantiene para realizar las consultas dentro de la clase + // ATRIBUTOS (Propiedades privadas para proteger los datos de accesos directos externos) + private ?int $id_usuario; // El ID del usuario (puede ser null si aún no se ha guardado en la base de datos) + private string $nombre_usuario; // El nombre de usuario en texto + private string $contrasena; // La contraseña (normalmente encriptada) + private string $email; // El correo electrónico del usuario + // CONSTRUCTOR: Se ejecuta automáticamente al crear un nuevo objeto (ya no pide base de datos por parámetro) public function __construct(string $nombre_usuario = "", string $contrasena = "", string $email = "", ?int $id_usuario = null) { - // Hacemos referencia a la variable global $db que se creó en conexion.php - global $db; - $this->db = $db; - - $this->id_usuario = $id_usuario; - $this->nombre_usuario = $nombre_usuario; - $this->contrasena = $contrasena; - $this->email = $email; + $this->id_usuario = $id_usuario; // Asigna el ID (por defecto es null si es un registro nuevo) + $this->nombre_usuario = $nombre_usuario; // Asigna el nombre de usuario recibido + $this->contrasena = $contrasena; // Asigna la contraseña recibida + $this->email = $email; // Asigna el email recibido } // --- GETTERS Y SETTERS (Métodos públicos para acceder y modificar los datos privados de forma segura) --- @@ -60,45 +57,83 @@ class Usuario { // --- MÉTODOS DE BASE DE DATOS (Lógica de negocio e interacción con SQL) --- // Método para registrar/insertar el usuario actual en la base de datos - public function registrar(): bool { - // Preparamos la consulta SQL usando marcadores (:nombre, :pass, :email) para evitar inyecciones SQL - $sql = "INSERT INTO usuario (nombre_usuario, contrasena, email) VALUES (:nombre, :pass, :email)"; - $stmt = $this->db->prepare($sql); // Prepara la consulta en el servidor de la base de datos - - // Encriptamos la contraseña con el algoritmo BCRYPT antes de guardarla por seguridad - $passHash = password_hash($this->contrasena, PASSWORD_BCRYPT); + public function registrar() { + // Obtenemos la conexión llamando a tu función unificada del proyecto + $conexion = conexionBD(); - // Ejecutamos la consulta pasando los valores reales que sustituirán a los marcadores - $resultado = $stmt->execute([ - ':nombre' => $this->nombre_usuario, - ':pass' => $passHash, // Guardamos la contraseña ya encriptada - ':email' => $this->email - ]); - - // Si la inserción fue exitosa, recuperamos el ID generado por la base de datos y lo asignamos al objeto - if ($resultado) { - $this->id_usuario = (int)$this->db->lastInsertId(); - return true; // Devuelve verdadero indicando que se registró correctamente + // Si devuelve un array significa que ocurrió un error controlado al conectar + if (is_array($conexion)) { + return $conexion; + } + + try { + // Preparamos la consulta SQL usando marcadores (:nombre, :pass, :email) para evitar inyecciones SQL + $sql = "INSERT INTO usuario (nombre_usuario, contrasena, email) VALUES (:nombre, :pass, :email)"; + $stmt = $conexion->prepare($sql); // Prepara la consulta en el servidor de la base de datos + + // Encriptamos la contraseña con el algoritmo BCRYPT antes de guardarla por seguridad + $passHash = password_hash($this->contrasena, PASSWORD_BCRYPT); + + // Ejecutamos la consulta pasando los valores reales que sustituirán a los marcadores + $stmt->execute([ + ':nombre' => $this->nombre_usuario, + ':pass' => $passHash, // Guardamos la contraseña ya encriptada + ':email' => $this->email + ]); + + // Si la inserción fue exitosa, recuperamos el ID generado por la base de datos y lo asignamos al objeto + $this->id_usuario = (int)$conexion->lastInsertId(); + + // Devolvemos una respuesta de éxito idéntica al formato del resto de tus clases + return [ + 'exito' => 'Usuario registrado correctamente', + 'exito_tecnico' => $this->id_usuario + ]; + + } catch (PDOException $error) { + // Si ocurre algún fallo en la consulta, capturamos el error y devolvemos la respuesta controlada + return [ + 'error' => 'Ocurrió un error al registrar el usuario.', + 'error_tecnico' => $error->getMessage() + ]; } - return false; // Devuelve falso si hubo algún error en la inserción } // Método estático para buscar un usuario por su ID sin necesidad de instanciar el objeto previamente - public static function buscarPorId(PDO $db, int $id): ?Usuario { - // Preparamos la consulta SQL filtrando por el ID recibido - $sql = "SELECT * FROM usuario WHERE id_usuario = :id"; - $stmt = $db->prepare($sql); - $stmt->execute([':id' => $id]); // Ejecutamos la consulta - - // Obtenemos el registro en forma de array asociativo - $datos = $stmt->fetch(PDO::FETCH_ASSOC); + public static function buscarPorId($id) { + // Obtenemos la conexión llamando a tu función unificada del proyecto + $conexion = conexionBD(); - // Si el usuario existe en la base de datos, creamos y devolvemos un nuevo objeto Usuario con sus datos - if ($datos) { - return new Usuario($db, $datos['nombre_usuario'], $datos['contrasena'], $datos['email'], $datos['id_usuario']); + // Si devuelve un array significa que ocurrió un error controlado al conectar + if (is_array($conexion)) { + return $conexion; + } + + try { + // Preparamos la consulta SQL filtrando por el ID recibido + $sql = "SELECT * FROM usuario WHERE id_usuario = :id"; + $stmt = $conexion->prepare($sql); + $stmt->execute([':id' => $id]); // Ejecutamos la consulta + + // Obtenemos el registro en forma de array asociativo + $datos = $stmt->fetch(PDO::FETCH_ASSOC); + + // Si el usuario existe en la base de datos, creamos y devolvemos un nuevo objeto Usuario con sus datos + if ($datos) { + return new Usuario($datos['nombre_usuario'], $datos['contrasena'], $datos['email'], $datos['id_usuario']); + } + + // Si la consulta termina pero no encuentra filas, devolvemos un aviso de error controlado + return [ + 'error' => 'No se encontró ningún usuario con ese ID.' + ]; + + } catch (PDOException $error) { + // Si ocurre algún fallo en la consulta SQL, capturamos el error + return [ + 'error' => 'Ocurrió un error al buscar el usuario.', + 'error_tecnico' => $error->getMessage() + ]; } - return null; // Si no se encuentra el usuario, devolvemos null } } - -