From 8d767e61e815e3ec24c0783780a7c8c6457847d7 Mon Sep 17 00:00:00 2001 From: "v.rodriguezcamacho" Date: Thu, 24 Sep 2026 09:30:38 +0200 Subject: [PATCH 01/23] carpeta includes con conexionBD.php --- includes/conexionBD.php | 29 +++++++++++++++++++++++++++++ index.php | 1 + 2 files changed, 30 insertions(+) create mode 100644 includes/conexionBD.php diff --git a/includes/conexionBD.php b/includes/conexionBD.php new file mode 100644 index 0000000..0d4636c --- /dev/null +++ b/includes/conexionBD.php @@ -0,0 +1,29 @@ + PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, + ]; + + return new PDO($dsn, $usuario, $pass, $opciones); + + } catch (PDOException $error) { + return [ + 'error' => 'No se pudo conectar a la base de datos.', + 'error_tecnico' => $error->getMessage() + ]; + } +} +?> \ No newline at end of file diff --git a/index.php b/index.php index a47b9e7..ee8d7dc 100644 --- a/index.php +++ b/index.php @@ -1,3 +1,4 @@ + From dd810ed2cb71d2012480e7ba4e64bf71715c3cab Mon Sep 17 00:00:00 2001 From: Juanjo Date: Thu, 24 Sep 2026 09:40:09 +0200 Subject: [PATCH 02/23] clases Juanjo --- clases/claseCategoria.php | 148 ++++++++++++++++++++++++++++++++++++++ clases/claseEquipo.php | 148 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+) create mode 100644 clases/claseCategoria.php create mode 100644 clases/claseEquipo.php diff --git a/clases/claseCategoria.php b/clases/claseCategoria.php new file mode 100644 index 0000000..015ef5e --- /dev/null +++ b/clases/claseCategoria.php @@ -0,0 +1,148 @@ +idCategoria = $idCategoria; + $this->nombreCategoria = $nombreCategoria; + } + + + function crear(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("INSERT INTO categoria (nombreCategoria) VALUES (:nombreCategoria)"); + + $consulta->bindParam(':nombreCategoria', $this->nombreCategoria); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Categoría creada correctamente', + 'exito_tecnico' => $this->nombreCategoria + ]; + + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al guardar la categoría.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } + } + + + function listar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $sql = 'SELECT * FROM categoria'; + + $consulta = $conexion->prepare($sql); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + + return $resultado; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de categorías.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } + } + + + function buscar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM categoria WHERE idCategoria = :idCategoria"); + + $consulta->bindParam(':idCategoria', $this->idCategoria); + + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + return $resultado; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al buscar la categoría.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } + } + + + function borrar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("DELETE FROM categoria WHERE idCategoria = :idCategoria"); + + $consulta->bindParam(':idCategoria', $this->idCategoria); + + $consulta->execute(); + + if($consulta->rowCount() > 0){ + $respuesta = [ + 'exito' => 'Se eliminó correctamente la categoría', + 'exito_tecnico' => $this->idCategoria + ]; + }else{ + $respuesta = [ + 'error' => 'No existe ninguna categoría con ese ID.', + 'error_tecnico' => $this->idCategoria + ]; + } + + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al eliminar la categoría.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } + } + +} + +?> \ No newline at end of file diff --git a/clases/claseEquipo.php b/clases/claseEquipo.php new file mode 100644 index 0000000..bb31594 --- /dev/null +++ b/clases/claseEquipo.php @@ -0,0 +1,148 @@ +idEquipo = $idEquipo; + $this->nombreEquipo = $nombreEquipo; + } + + + function crear(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("INSERT INTO equipo (nombreEquipo) VALUES (:nombreEquipo)"); + + $consulta->bindParam(':nombreEquipo', $this->nombreEquipo); + + $consulta->execute(); + + $respuesta = [ + 'exito' => 'Equipo creado correctamente', + 'exito_tecnico' => $this->nombreEquipo + ]; + + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al guardar el equipo.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } + } + + + function listar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $sql = 'SELECT * FROM equipo'; + + $consulta = $conexion->prepare($sql); + $consulta->execute(); + + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + + return $resultado; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado de equipos.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } + } + + + function buscar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM equipo WHERE idEquipo = :idEquipo"); + + $consulta->bindParam(':idEquipo', $this->idEquipo); + + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + + return $resultado; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al buscar el equipo.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } + } + + + function borrar(){ + $conexion = conexionBD(); + + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("DELETE FROM equipo WHERE idEquipo = :idEquipo"); + + $consulta->bindParam(':idEquipo', $this->idEquipo); + + $consulta->execute(); + + if($consulta->rowCount() > 0){ + $respuesta = [ + 'exito' => 'Se eliminó correctamente el equipo', + 'exito_tecnico' => $this->idEquipo + ]; + }else{ + $respuesta = [ + 'error' => 'No existe ningún equipo con ese ID.', + 'error_tecnico' => $this->idEquipo + ]; + } + + return $respuesta; + + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al eliminar el equipo.', + 'error_tecnico' => $error + ]; + + $conexion = null; + return $respuesta; + } + } + } + +} + +?> \ No newline at end of file From 42c4785d98aea3429fbaa56e476c8eed698742f5 Mon Sep 17 00:00:00 2001 From: marga Date: Thu, 24 Sep 2026 09:45:16 +0200 Subject: [PATCH 03/23] clase Marga --- clases/ClasePregunta.php | 169 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 clases/ClasePregunta.php diff --git a/clases/ClasePregunta.php b/clases/ClasePregunta.php new file mode 100644 index 0000000..7971d1c --- /dev/null +++ b/clases/ClasePregunta.php @@ -0,0 +1,169 @@ +idRespuesta=$idRespuesta; + $this->idPregunta=$idPregunta; + $this->nombreRespuesta=$nombreRespuesta; + $this->correcta=$correcta; + }//fin constructor + + public function insertar(){ + $conexion = conexionBD(); + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("INSERT INTO respuesta (idPregunta, nombreRespuesta, correcta) VALUES (:idPregunta, :nombreRespuesta, :correcta)"); + $consulta->bindParam(':idPregunta', $this->idPregunta); + $consulta->bindParam(':nombreRespuesta', $this->nombreRespuesta); + $consulta->bindParam(':correcta', $this->correcta); + $consulta->execute(); + $respuesta = [ + 'exito' => 'La respuesta se guardó correctamente.', + 'exito_tecnico' => $conexion->lastInsertId() + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al guardar la respuesta.', + 'error_tecnico' => $error->getMessage() + ]; + $conexion = null; + return $respuesta; + } + } + }//fin método insertar + + public function listar(){ + $conexion = conexionBD(); + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM respuesta"); + $consulta->execute(); + return $consulta->fetchAll(PDO::FETCH_ASSOC); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener el listado.', + 'error_tecnico' => $error->getMessage() + ]; + $conexion = null; + return $respuesta; + } + } + }//fin método listar + + public function eliminar(){ + $conexion = conexionBD(); + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("DELETE FROM respuesta WHERE idRespuesta=:idRespuesta"); + $consulta->bindParam(':idRespuesta', $this->idRespuesta); + $consulta->execute(); + $respuesta = [ + 'exito' => 'La respuesta se eliminó correctamente.', + 'exito_tecnico' => $this->idRespuesta + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'No se pudo eliminar la respuesta.', + 'error_tecnico' => $error->getMessage() + ]; + $conexion = null; + return $respuesta; + } + } + }//fin método eliminar + + public function editar(){ + $conexion = conexionBD(); + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("UPDATE respuesta SET idPregunta=:idPregunta, nombreRespuesta=:nombreRespuesta, correcta=:correcta WHERE idRespuesta=:idRespuesta"); + $consulta->bindParam(':idRespuesta', $this->idRespuesta); + $consulta->bindParam(':idPregunta', $this->idPregunta); + $consulta->bindParam(':nombreRespuesta', $this->nombreRespuesta); + $consulta->bindParam(':correcta', $this->correcta); + $consulta->execute(); + $respuesta = [ + 'exito' => 'La respuesta se editó correctamente.', + 'exito_tecnico' => $this->idRespuesta + ]; + return $respuesta; + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al editar la respuesta.', + 'error_tecnico' => $error->getMessage() + ]; + $conexion = null; + return $respuesta; + } + } + }//fin método editar + + public function buscar(){ + $conexion = conexionBD(); + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM respuesta WHERE idRespuesta=:idRespuesta"); + $consulta->bindParam(':idRespuesta', $this->idRespuesta); + $consulta->execute(); + return $consulta->fetchAll(PDO::FETCH_ASSOC); + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al buscar la respuesta.', + 'error_tecnico' => $error->getMessage() + ]; + $conexion = null; + return $respuesta; + } + } + }//fin método buscar + + public function listarPorPregunta(){//trae todas las respuestas posibles de una pregunta + $conexion = conexionBD(); + if(is_array($conexion)){ + return $conexion; + }else{ + try{ + $consulta = $conexion->prepare("SELECT * FROM respuesta WHERE idPregunta=:idPregunta"); + $consulta->bindParam(':idPregunta', $this->idPregunta); + $consulta->execute(); + $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); + if(!isset($resultado[0])){ + $respuesta = [ + 'error' => 'La pregunta no tiene respuestas.' + ]; + return $respuesta; + }else{ + return $resultado; + } + }catch(PDOException $error){ + $respuesta = [ + 'error' => 'Ocurrió un error al obtener las respuestas de la pregunta.', + 'error_tecnico' => $error->getMessage() + ]; + $conexion = null; + return $respuesta; + } + } + }//fin método listarPorPregunta + +}//fin clase + +?> \ No newline at end of file From e257527321829e1105afa7ca7266d3906bbbbf56 Mon Sep 17 00:00:00 2001 From: marga Date: Thu, 24 Sep 2026 09:53:43 +0200 Subject: [PATCH 04/23] renombrar clase --- clases/{ClasePregunta.php => ClaseRespuesta.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clases/{ClasePregunta.php => ClaseRespuesta.php} (100%) diff --git a/clases/ClasePregunta.php b/clases/ClaseRespuesta.php similarity index 100% rename from clases/ClasePregunta.php rename to clases/ClaseRespuesta.php From 39d0ef51be55cc1a91b72dc14aa3100b2916e08c Mon Sep 17 00:00:00 2001 From: Juanjo Date: Thu, 24 Sep 2026 09:56:18 +0200 Subject: [PATCH 05/23] cambios en conexion base de datos --- clases/claseCategoria.php | 2 +- clases/claseEquipo.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clases/claseCategoria.php b/clases/claseCategoria.php index 015ef5e..1b17c6d 100644 --- a/clases/claseCategoria.php +++ b/clases/claseCategoria.php @@ -1,5 +1,5 @@ Date: Thu, 24 Sep 2026 10:05:39 +0200 Subject: [PATCH 06/23] claseVictorDiaz --- clasePartida.php | 332 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 clasePartida.php diff --git a/clasePartida.php b/clasePartida.php new file mode 100644 index 0000000..f1fa8e5 --- /dev/null +++ b/clasePartida.php @@ -0,0 +1,332 @@ +idPartida=$idPartida; + $this->nombrePartida=$nombrePartida; + $this->idUsuario=$idUsuario; + } + + public function insertar(){ + $conexion=conexionBD(); + if(is_array($conexion)){ + return $conexion; + } + try{ + $consulta=$conexion->prepare(" + INSERT INTO partida + (nombrePartida,idUsuario) + VALUES + (:nombrePartida,:idUsuario) + "); + $consulta->bindParam(":nombrePartida",$this->nombrePartida); + $consulta->bindParam(":idUsuario",$this->idUsuario); + $consulta->execute(); + return[ + "exito"=>"La partida se creó correctamente.", + "exito_tecnico"=>$conexion->lastInsertId() + ]; + }catch(PDOException $error){ + return[ + "error"=>"Ocurrió un error al guardar la partida.", + "error_tecnico"=>$error + ]; + } + } + + public function listar(){ + $conexion=conexionBD(); + if(is_array($conexion)){ + return $conexion; + } + try{ + $consulta=$conexion->prepare("SELECT * FROM partida"); + $consulta->execute(); + return $consulta->fetchAll(PDO::FETCH_ASSOC); + }catch(PDOException $error){ + return[ + "error"=>"Ocurrió un error al obtener el listado.", + "error_tecnico"=>$error + ]; + } + } + + public function buscar(){ + $conexion=conexionBD(); + if(is_array($conexion)){ + return $conexion; + } + try{ + $consulta=$conexion->prepare(" + SELECT * + FROM partida + WHERE idPartida=:idPartida + "); + $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->execute(); + return $consulta->fetch(PDO::FETCH_ASSOC); + }catch(PDOException $error){ + return[ + "error"=>"Ocurrió un error al buscar la partida.", + "error_tecnico"=>$error + ]; + } + } + + public function editar(){ + $conexion=conexionBD(); + if(is_array($conexion)){ + return $conexion; + } + try{ + $consulta=$conexion->prepare(" + UPDATE partida + SET + nombrePartida=:nombrePartida, + idUsuario=:idUsuario + WHERE idPartida=:idPartida + "); + $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->bindParam(":nombrePartida",$this->nombrePartida); + $consulta->bindParam(":idUsuario",$this->idUsuario); + $consulta->execute(); + return[ + "exito"=>"La partida se editó correctamente.", + "exito_tecnico"=>$this->idPartida + ]; + }catch(PDOException $error){ + return[ + "error"=>"Ocurrió un error al editar la partida.", + "error_tecnico"=>$error + ]; + } + } + + public function eliminar(){ + $conexion=conexionBD(); + if(is_array($conexion)){ + return $conexion; + } + try{ + $consulta=$conexion->prepare(" + DELETE FROM partida + WHERE idPartida=:idPartida + "); + $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->execute(); + return[ + "exito"=>"La partida se eliminó correctamente.", + "exito_tecnico"=>$this->idPartida + ]; + }catch(PDOException $error){ + return[ + "error"=>"No se pudo eliminar la partida.", + "error_tecnico"=>$error + ]; + } + } + + /** + * Devuelve las preguntas asignadas a la partida, junto con el + * idPartidaxPregunta (necesario para guardar respuestas después). + */ + public function getPreguntas(){ + $conexion=conexionBD(); + if(is_array($conexion)){ + return $conexion; + } + try{ + $consulta=$conexion->prepare(" + SELECT + pxp.idPartidaxPregunta, + p.* + FROM partidaxpregunta pxp + INNER JOIN pregunta p + ON pxp.idPregunta=p.idPregunta + WHERE pxp.idPartida=:idPartida + ORDER BY pxp.idPartidaxPregunta + "); + $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->execute(); + return $consulta->fetchAll(PDO::FETCH_ASSOC); + }catch(PDOException $error){ + return[ + "error"=>"Ocurrió un error al recuperar las preguntas de la partida.", + "error_tecnico"=>$error + ]; + } + } + + /** + * Asocia una pregunta ya existente a esta partida. + */ + public function asignarPregunta($idPregunta){ + $conexion=conexionBD(); + if(is_array($conexion)){ + return $conexion; + } + try{ + $consulta=$conexion->prepare(" + INSERT INTO partidaxpregunta + (idPartida,idPregunta) + VALUES + (:idPartida,:idPregunta) + "); + $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->bindParam(":idPregunta",$idPregunta); + $consulta->execute(); + return[ + "exito"=>"La pregunta se asignó correctamente.", + "exito_tecnico"=>$conexion->lastInsertId() + ]; + }catch(PDOException $error){ + return[ + "error"=>"Ocurrió un error al asignar la pregunta.", + "error_tecnico"=>$error + ]; + } + } + + + + //Cuenta cuántas preguntas tiene la partida en total. Es la primera mitad de la comprobación "¿ha terminado el usuario de jugar?". + public function contarPreguntasAsignadas(){ + $conexion=conexionBD(); + if(is_array($conexion)){ + return $conexion; + } + try{ + $consulta=$conexion->prepare(" + SELECT COUNT(*) AS total + FROM partidaxpregunta + WHERE idPartida=:idPartida + "); + $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->execute(); + $fila=$consulta->fetch(PDO::FETCH_ASSOC); + return (int)$fila["total"]; + }catch(PDOException $error){ + return[ + "error"=>"Ocurrió un error al contar las preguntas.", + "error_tecnico"=>$error + ]; + } + } + + public function contarRespuestasUsuario($idUsuario){ + $conexion=conexionBD(); + if(is_array($conexion)){ + return $conexion; + } + try{ + $consulta=$conexion->prepare(" + SELECT COUNT(*) AS total + FROM respuestaalmacenada ra + INNER JOIN partidaxpregunta pxp + ON ra.idPartidaxPregunta=pxp.idPartidaxPregunta + WHERE pxp.idPartida=:idPartida + AND ra.idUsuario=:idUsuario + "); + $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->bindParam(":idUsuario",$idUsuario); + $consulta->execute(); + $fila=$consulta->fetch(PDO::FETCH_ASSOC); + return (int)$fila["total"]; + }catch(PDOException $error){ + return[ + "error"=>"Ocurrió un error al contar las respuestas del usuario.", + "error_tecnico"=>$error + ]; + } + } + + /** + * Sustituye al antiguo campo `terminada`: compara cuántas preguntas + * tiene la partida contra cuántas ha respondido este usuario. + */ + public function estaFinalizadaParaUsuario($idUsuario){ + $totalPreguntas=$this->contarPreguntasAsignadas(); + if(is_array($totalPreguntas)){ + return $totalPreguntas; + } + $totalRespondidas=$this->contarRespuestasUsuario($idUsuario); + if(is_array($totalRespondidas)){ + return $totalRespondidas; + } + return $totalPreguntas>0 && $totalPreguntas===$totalRespondidas; + } + + /** + * Partidas creadas por un usuario, de más reciente a más antigua. + */ + public function listarDelUsuario(){ + $conexion=conexionBD(); + if(is_array($conexion)){ + return $conexion; + } + try{ + $consulta=$conexion->prepare(" + SELECT * + FROM partida + WHERE idUsuario=:idUsuario + ORDER BY idPartida DESC + "); + $consulta->bindParam(":idUsuario",$this->idUsuario); + $consulta->execute(); + return $consulta->fetchAll(PDO::FETCH_ASSOC); + }catch(PDOException $error){ + return[ + "error"=>"Ocurrió un error al recuperar las partidas del usuario.", + "error_tecnico"=>$error + ]; + } + } + + + + + + public function preguntaAsignada($idPregunta){ + $conexion=conexionBD(); + + if(is_array($conexion)){ + return $conexion; + } + + try{ + $consulta=$conexion->prepare(" + SELECT COUNT(*) AS total + FROM partidaxpregunta + WHERE idPartida=:idPartida + AND idPregunta=:idPregunta + "); + + $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->bindParam(":idPregunta",$idPregunta); + $consulta->execute(); + + $fila=$consulta->fetch(PDO::FETCH_ASSOC); + + return (int)$fila["total"] > 0; + + }catch(PDOException $error){ + + return[ + "error"=>"Ocurrió un error al comprobar la pregunta.", + "error_tecnico"=>$error + ]; + } + } + +} +?> \ No newline at end of file From 93ac0e9ec2dac1d06c96e17a4c8cb9aaa1cb6d24 Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 10:07:25 +0200 Subject: [PATCH 07/23] Subir archivos a "clases" --- clases/ClasePregunta.php | 115 +++++++++++++++++++++++++++++++++++++++ clases/ClaseUsuario.php | 102 ++++++++++++++++++++++++++++++++++ 2 files changed, 217 insertions(+) create mode 100644 clases/ClasePregunta.php create mode 100644 clases/ClaseUsuario.php diff --git a/clases/ClasePregunta.php b/clases/ClasePregunta.php new file mode 100644 index 0000000..b4d6c1b --- /dev/null +++ b/clases/ClasePregunta.php @@ -0,0 +1,115 @@ +db = $db; // Asigna la conexión a la base de datos + $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) + public function getIdPregunta(): ?int { + return $this->id_pregunta; + } + + // Getter para obtener el ID de la categoría + public function getIdCategoria(): int { + return $this->id_categoria; + } + + // Setter para cambiar la categoría de la pregunta + public function setIdCategoria(int $id_categoria): void { + $this->id_categoria = $id_categoria; + } + + // Getter para obtener el texto de la pregunta + public function getTextoPregunta(): string { + return $this->texto_pregunta; + } + + // Setter para cambiar el texto de la pregunta + public function setTextoPregunta(string $texto_pregunta): void { + $this->texto_pregunta = $texto_pregunta; + } + + // Getter para obtener el array con todas las respuestas cargadas de esta pregunta + public function getRespuestas(): array { + return $this->respuestas; + } + + // --- 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 + ]); + + // 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 + } + 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 { + // 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); + } + + // 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 + + $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; + } + 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 new file mode 100644 index 0000000..87a128a --- /dev/null +++ b/clases/ClaseUsuario.php @@ -0,0 +1,102 @@ +db = $db; // Asigna la conexión a la base de datos al atributo interno + $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) --- + + // Getter para obtener el ID del usuario (es de solo lectura, no tiene setter) + public function getIdUsuario(): ?int { + return $this->id_usuario; + } + + // Getter para obtener el nombre de usuario + public function getNombreUsuario(): string { + return $this->nombre_usuario; + } + + // Setter para cambiar el nombre de usuario desde fuera de la clase + public function setNombreUsuario(string $nombre_usuario): void { + $this->nombre_usuario = $nombre_usuario; + } + + // Getter para obtener la contraseña + public function getContrasena(): string { + return $this->contrasena; + } + + // Setter para cambiar la contraseña desde fuera de la clase + public function setContrasena(string $contrasena): void { + $this->contrasena = $contrasena; + } + + // Getter para obtener el correo electrónico + public function getEmail(): string { + return $this->email; + } + + // Setter para cambiar el correo electrónico desde fuera de la clase + public function setEmail(string $email): void { + $this->email = $email; + } + + // --- 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); + + // 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 + } + 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); + + // 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']); + } + return null; // Si no se encuentra el usuario, devolvemos null + } +} + + Date: Thu, 24 Sep 2026 10:12:19 +0200 Subject: [PATCH 08/23] meter claseUsuario en la carpeta clases --- clasePartida.php => clases/clasePartida.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clasePartida.php => clases/clasePartida.php (100%) diff --git a/clasePartida.php b/clases/clasePartida.php similarity index 100% rename from clasePartida.php rename to clases/clasePartida.php From 29a11a85145a8f055f98908b84701d410ca62e59 Mon Sep 17 00:00:00 2001 From: "v.rodriguezcamacho" Date: Thu, 24 Sep 2026 10:39:45 +0200 Subject: [PATCH 09/23] =?UTF-8?q?a=C3=B1adido=20el=20BD=20en=20conexion.ph?= =?UTF-8?q?p=20en=20algunas=20clases?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clases/ClasePregunta.php | 2 +- clases/ClaseUsuario.php | 2 +- clases/clasePartida.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clases/ClasePregunta.php b/clases/ClasePregunta.php index b4d6c1b..1e74104 100644 --- a/clases/ClasePregunta.php +++ b/clases/ClasePregunta.php @@ -1,5 +1,5 @@ Date: Thu, 24 Sep 2026 10:43:11 +0200 Subject: [PATCH 10/23] puesto de la misma manera los require en todas las clases --- clases/ClaseRespuesta.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clases/ClaseRespuesta.php b/clases/ClaseRespuesta.php index 7971d1c..733ba9a 100644 --- a/clases/ClaseRespuesta.php +++ b/clases/ClaseRespuesta.php @@ -1,6 +1,5 @@ Date: Thu, 24 Sep 2026 10:49:38 +0200 Subject: [PATCH 11/23] Subir archivos a "clases" --- clases/ClasePregunta.php | 28 ++++++++++++++-------------- clases/ClaseUsuario.php | 28 +++++++++++++++------------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/clases/ClasePregunta.php b/clases/ClasePregunta.php index 1e74104..b57c18e 100644 --- a/clases/ClasePregunta.php +++ b/clases/ClasePregunta.php @@ -1,23 +1,23 @@ db = $db; // Asigna la conexión a la base de datos - $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 + 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 = []; } - // --- GETTERS Y SETTERS --- // Getter para obtener el ID de la pregunta (solo lectura) diff --git a/clases/ClaseUsuario.php b/clases/ClaseUsuario.php index 594674e..336bc08 100644 --- a/clases/ClaseUsuario.php +++ b/clases/ClaseUsuario.php @@ -1,21 +1,23 @@ db = $db; // Asigna la conexión a la base de datos al atributo interno - $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 + 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; } // --- GETTERS Y SETTERS (Métodos públicos para acceder y modificar los datos privados de forma segura) --- From d1c381d7ac9f8f77e467d1c34b6ac4a175dc8708 Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 11:02:48 +0200 Subject: [PATCH 12/23] 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 } } - - Date: Thu, 24 Sep 2026 11:13:44 +0200 Subject: [PATCH 13/23] Subir archivos a "clases" --- clases/ClasePregunta.php | 117 ++++++++---------------------- clases/ClaseUsuario.php | 151 ++++++++++++++++++++------------------- 2 files changed, 108 insertions(+), 160 deletions(-) diff --git a/clases/ClasePregunta.php b/clases/ClasePregunta.php index 937331f..cfd2049 100644 --- a/clases/ClasePregunta.php +++ b/clases/ClasePregunta.php @@ -1,88 +1,53 @@ 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 + public function __construct(int $idCategoria = 0, string $nombrePregunta = "", ?int $idPregunta = null) { + $this->idPregunta = $idPregunta; + $this->idCategoria = $idCategoria; + $this->nombrePregunta = $nombrePregunta; + $this->respuestas = []; } - // --- GETTERS Y SETTERS --- - - // Getter para obtener el ID de la pregunta (solo lectura) - public function getIdPregunta(): ?int { - return $this->id_pregunta; - } + public function getIdPregunta(): ?int { return $this->idPregunta; } - // Getter para obtener el ID de la categoría - public function getIdCategoria(): int { - return $this->id_categoria; - } - - // Setter para cambiar la categoría de la pregunta - public function setIdCategoria(int $id_categoria): void { - $this->id_categoria = $id_categoria; - } + public function getIdCategoria(): int { return $this->idCategoria; } + public function setIdCategoria(int $idCategoria): void { $this->idCategoria = $idCategoria; } - // Getter para obtener el texto de la pregunta - public function getTextoPregunta(): string { - return $this->texto_pregunta; - } - - // Setter para cambiar el texto de la pregunta - public function setTextoPregunta(string $texto_pregunta): void { - $this->texto_pregunta = $texto_pregunta; - } + public function getNombrePregunta(): string { return $this->nombrePregunta; } + public function setNombrePregunta(string $nombrePregunta): void { $this->nombrePregunta = $nombrePregunta; } - // Getter para obtener el array con todas las respuestas cargadas de esta pregunta - public function getRespuestas(): array { - return $this->respuestas; - } + public function getRespuestas(): array { return $this->respuestas; } - // --- MÉTODOS DE BASE DE DATOS --- - - // Método para guardar una nueva pregunta en la base de datos public function guardar() { - // Obtenemos la conexión llamando a tu función unificada del proyecto $conexion = conexionBD(); - // 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)"; + $sql = "INSERT INTO pregunta (idCategoria, nombrePregunta) VALUES (:idCat, :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 + ':idCat' => $this->idCategoria, + ':texto' => $this->nombrePregunta ]); - // Si se guardó correctamente, actualizamos el atributo id_pregunta del objeto con el ID generado en la BD - $this->id_pregunta = (int)$conexion->lastInsertId(); + $this->idPregunta = (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 + 'exito_tecnico' => $this->idPregunta ]; } 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() @@ -90,30 +55,23 @@ class Pregunta { } } - // Método para buscar y cargar en memoria todas las respuestas asociadas a esta pregunta concreta 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; + if ($this->idPregunta === null) return; - // 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"; + $sql = "SELECT idRespuesta, nombreRespuesta, correcta FROM respuesta WHERE idPregunta = :idPreg"; $stmt = $conexion->prepare($sql); - $stmt->execute([':id_preg' => $this->id_pregunta]); + $stmt->execute([':idPreg' => $this->idPregunta]); - // 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() @@ -121,43 +79,30 @@ class Pregunta { } } - // Método estático para obtener un listado de preguntas aleatorias filtradas por una categoría - public static function obtenerPorCategoria(int $id_categoria, int $limite = 10) { - // Obtenemos la conexión llamando a tu función unificada del proyecto + public static function obtenerPorCategoria(int $idCategoria, int $limite = 10) { $conexion = conexionBD(); - // 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"; + $sql = "SELECT * FROM pregunta WHERE idCategoria = :idCat 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(':idCat', $idCategoria, PDO::PARAM_INT); $stmt->bindValue(':limite', $limite, PDO::PARAM_INT); - $stmt->execute(); // Ejecutamos la consulta + $stmt->execute(); - $preguntas = []; // Array donde amontonaremos los objetos Pregunta resultantes - - // Recorremos fila por fila los resultados devueltos por la base de datos + $preguntas = []; 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 + $preg = new Pregunta((int)$datos['idCategoria'], $datos['nombrePregunta'], (int)$datos['idPregunta']); + $preg->cargarRespuestas(); $preguntas[] = $preg; } - return $preguntas; // Devolvemos la lista de objetos Pregunta listos para jugar + return $preguntas; } catch (PDOException $error) { - // Capturamos cualquier error en la consulta aleatoria return [ 'error' => 'Ocurrió un error al obtener las preguntas aleatorias.', 'error_tecnico' => $error->getMessage() diff --git a/clases/ClaseUsuario.php b/clases/ClaseUsuario.php index 8c7b6eb..3b31c6d 100644 --- a/clases/ClaseUsuario.php +++ b/clases/ClaseUsuario.php @@ -1,97 +1,98 @@ 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 + public function __construct( + string $nombreUsuario = "", + string $contrasena = "", + string $email = "", + ?string $avatar = null, + ?string $cookie = null, + int $aciertos = 0, + int $victorias = 0, + int $derrotas = 0, + ?int $idUsuario = null + ) { + $this->idUsuario = $idUsuario; + $this->nombreUsuario = $nombreUsuario; + $this->contrasena = $contrasena; + $this->email = $email; + $this->avatar = $avatar; + $this->cookie = $cookie; + $this->aciertos = $aciertos; + $this->victorias = $victorias; + $this->derrotas = $derrotas; } - // --- GETTERS Y SETTERS (Métodos públicos para acceder y modificar los datos privados de forma segura) --- - - // Getter para obtener el ID del usuario (es de solo lectura, no tiene setter) - public function getIdUsuario(): ?int { - return $this->id_usuario; - } + public function getIdUsuario(): ?int { return $this->idUsuario; } - // Getter para obtener el nombre de usuario - public function getNombreUsuario(): string { - return $this->nombre_usuario; - } - - // Setter para cambiar el nombre de usuario desde fuera de la clase - public function setNombreUsuario(string $nombre_usuario): void { - $this->nombre_usuario = $nombre_usuario; - } + public function getNombreUsuario(): string { return $this->nombreUsuario; } + public function setNombreUsuario(string $nombreUsuario): void { $this->nombreUsuario = $nombreUsuario; } - // Getter para obtener la contraseña - public function getContrasena(): string { - return $this->contrasena; - } - - // Setter para cambiar la contraseña desde fuera de la clase - public function setContrasena(string $contrasena): void { - $this->contrasena = $contrasena; - } + public function getContrasena(): string { return $this->contrasena; } + public function setContrasena(string $contrasena): void { $this->contrasena = $contrasena; } - // Getter para obtener el correo electrónico - public function getEmail(): string { - return $this->email; - } - - // Setter para cambiar el correo electrónico desde fuera de la clase - public function setEmail(string $email): void { - $this->email = $email; - } + public function getEmail(): string { return $this->email; } + public function setEmail(string $email): void { $this->email = $email; } - // --- MÉTODOS DE BASE DE DATOS (Lógica de negocio e interacción con SQL) --- + public function getAvatar(): ?string { return $this->avatar; } + public function setAvatar(?string $avatar): void { $this->avatar = $avatar; } + + public function getCookie(): ?string { return $this->cookie; } + public function setCookie(?string $cookie): void { $this->cookie = $cookie; } + + public function getAciertos(): int { return $this->aciertos; } + public function setAciertos(int $aciertos): void { $this->aciertos = $aciertos; } + + public function getVictorias(): int { return $this->victorias; } + public function setVictorias(int $victorias): void { $this->victorias = $victorias; } + + public function getDerrotas(): int { return $this->derrotas; } + public function setDerrotas(int $derrotas): void { $this->derrotas = $derrotas; } - // Método para registrar/insertar el usuario actual en la base de datos public function registrar() { - // Obtenemos la conexión llamando a tu función unificada del proyecto $conexion = conexionBD(); - // 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 + $sql = "INSERT INTO usuario (nombreUsuario, contrasena, email, avatar, cookie, aciertos, victorias, derrotas) + VALUES (:nombre, :pass, :email, :avatar, :cookie, :aciertos, :victorias, :derrotas)"; + $stmt = $conexion->prepare($sql); - // 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 + ':nombre' => $this->nombreUsuario, + ':pass' => $passHash, + ':email' => $this->email, + ':avatar' => $this->avatar, + ':cookie' => $this->cookie, + ':aciertos' => $this->aciertos, + ':victorias' => $this->victorias, + ':derrotas' => $this->derrotas ]); - // 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(); + $this->idUsuario = (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 + 'exito_tecnico' => $this->idUsuario ]; } 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() @@ -99,41 +100,43 @@ class Usuario { } } - // Método estático para buscar un usuario por su ID sin necesidad de instanciar el objeto previamente public static function buscarPorId($id) { - // Obtenemos la conexión llamando a tu función unificada del proyecto $conexion = conexionBD(); - // 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"; + $sql = "SELECT * FROM usuario WHERE idUsuario = :id"; $stmt = $conexion->prepare($sql); - $stmt->execute([':id' => $id]); // Ejecutamos la consulta + $stmt->execute([':id' => $id]); - // 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']); + return new Usuario( + $datos['nombreUsuario'], + $datos['contrasena'], + $datos['email'], + $datos['avatar'], + $datos['cookie'], + (int)$datos['aciertos'], + (int)$datos['victorias'], + (int)$datos['derrotas'], + (int)$datos['idUsuario'] + ); } - // 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() ]; } } -} +} \ No newline at end of file From 3348188d445ac3b4962928737858cb74635ba909 Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 11:21:34 +0200 Subject: [PATCH 14/23] Subir archivos a "clases" --- clases/ClaseEquipoxUsuario.php | 58 ++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 clases/ClaseEquipoxUsuario.php diff --git a/clases/ClaseEquipoxUsuario.php b/clases/ClaseEquipoxUsuario.php new file mode 100644 index 0000000..524c6ca --- /dev/null +++ b/clases/ClaseEquipoxUsuario.php @@ -0,0 +1,58 @@ +idEquipoxUsuario = $idEquipoxUsuario; + $this->idUsuario = $idUsuario; + $this->idEquipo = $idEquipo; + } + + public function registrarUsuarioEnEquipo() { + $conexion = conexionBD(); + if (is_array($conexion)) return $conexion; + + try { + $sql = "INSERT INTO equipoxusuario (idUsuario, idEquipo) VALUES (:idUsuario, :idEquipo)"; + $consulta = $conexion->prepare($sql); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':idEquipo', $this->idEquipo); + $consulta->execute(); + + return [ + 'exito' => 'Usuario vinculado al equipo correctamente.', + 'exito_tecnico' => $conexion->lastInsertId() + ]; + } catch (PDOException $error) { + return [ + 'error' => 'Ocurrió un error al unir al usuario con el equipo.', + 'error_tecnico' => $error->getMessage() + ]; + } + } + + public static function listarUsuariosPorEquipo($idEquipo) { + $conexion = conexionBD(); + if (is_array($conexion)) return $conexion; + + try { + $sql = "SELECT u.* FROM equipoxusuario exu + INNER JOIN usuario u ON exu.idUsuario = u.idUsuario + WHERE exu.idEquipo = :idEquipo"; + $consulta = $conexion->prepare($sql); + $consulta->bindParam(':idEquipo', $idEquipo); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $error) { + return [ + 'error' => 'Ocurrió un error al obtener los miembros del equipo.', + 'error_tecnico' => $error->getMessage() + ]; + } + } +} From a3cd770956d470d18054398d007be89d406bea91 Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 12:35:15 +0200 Subject: [PATCH 15/23] Actualizar clases/ClaseCategoria.php --- clases/{claseCategoria.php => ClaseCategoria.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clases/{claseCategoria.php => ClaseCategoria.php} (100%) diff --git a/clases/claseCategoria.php b/clases/ClaseCategoria.php similarity index 100% rename from clases/claseCategoria.php rename to clases/ClaseCategoria.php From cab040aaa1b8a677d9bdc30573e56be7adc9add9 Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 12:35:28 +0200 Subject: [PATCH 16/23] Actualizar clases/ClaseEquipo.php --- clases/{claseEquipo.php => ClaseEquipo.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clases/{claseEquipo.php => ClaseEquipo.php} (100%) diff --git a/clases/claseEquipo.php b/clases/ClaseEquipo.php similarity index 100% rename from clases/claseEquipo.php rename to clases/ClaseEquipo.php From b9dea2a3cae17bcea0a33b6fc02648bff3e7038f Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 12:35:42 +0200 Subject: [PATCH 17/23] Actualizar clases/ClasePartida.php --- clases/{clasePartida.php => ClasePartida.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clases/{clasePartida.php => ClasePartida.php} (100%) diff --git a/clases/clasePartida.php b/clases/ClasePartida.php similarity index 100% rename from clases/clasePartida.php rename to clases/ClasePartida.php From 9bcb06a651590d0b7635aa562f3cdf19b1a3c493 Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 12:37:28 +0200 Subject: [PATCH 18/23] Subir archivos a "clases" --- clases/ClasePartida.php | 424 ++++++++++++++++++++++++++-------------- 1 file changed, 272 insertions(+), 152 deletions(-) diff --git a/clases/ClasePartida.php b/clases/ClasePartida.php index 84091fb..16f4dae 100644 --- a/clases/ClasePartida.php +++ b/clases/ClasePartida.php @@ -1,137 +1,143 @@ idPartida=$idPartida; - $this->nombrePartida=$nombrePartida; - $this->idUsuario=$idUsuario; + $idPartida = null, + $nombrePartida = null, + $idUsuario = null + ) { + $this->idPartida = $idPartida; + $this->nombrePartida = $nombrePartida; + $this->idUsuario = $idUsuario; } - public function insertar(){ - $conexion=conexionBD(); - if(is_array($conexion)){ + public function insertar() + { + $conexion = conexionBD(); + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare(" + try { + $consulta = $conexion->prepare(" INSERT INTO partida (nombrePartida,idUsuario) VALUES (:nombrePartida,:idUsuario) "); - $consulta->bindParam(":nombrePartida",$this->nombrePartida); - $consulta->bindParam(":idUsuario",$this->idUsuario); + $consulta->bindParam(":nombrePartida", $this->nombrePartida); + $consulta->bindParam(":idUsuario", $this->idUsuario); $consulta->execute(); - return[ - "exito"=>"La partida se creó correctamente.", - "exito_tecnico"=>$conexion->lastInsertId() + return [ + "exito" => "La partida se creó correctamente.", + "exito_tecnico" => $conexion->lastInsertId() ]; - }catch(PDOException $error){ - return[ - "error"=>"Ocurrió un error al guardar la partida.", - "error_tecnico"=>$error + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al guardar la partida.", + "error_tecnico" => $error ]; } } - public function listar(){ - $conexion=conexionBD(); - if(is_array($conexion)){ + public function listar() + { + $conexion = conexionBD(); + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare("SELECT * FROM partida"); + try { + $consulta = $conexion->prepare("SELECT * FROM partida"); $consulta->execute(); return $consulta->fetchAll(PDO::FETCH_ASSOC); - }catch(PDOException $error){ - return[ - "error"=>"Ocurrió un error al obtener el listado.", - "error_tecnico"=>$error + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al obtener el listado.", + "error_tecnico" => $error ]; } } - public function buscar(){ - $conexion=conexionBD(); - if(is_array($conexion)){ + public function buscar() + { + $conexion = conexionBD(); + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare(" + try { + $consulta = $conexion->prepare(" SELECT * FROM partida WHERE idPartida=:idPartida "); - $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->bindParam(":idPartida", $this->idPartida); $consulta->execute(); return $consulta->fetch(PDO::FETCH_ASSOC); - }catch(PDOException $error){ - return[ - "error"=>"Ocurrió un error al buscar la partida.", - "error_tecnico"=>$error + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al buscar la partida.", + "error_tecnico" => $error ]; } } - public function editar(){ - $conexion=conexionBD(); - if(is_array($conexion)){ + public function editar() + { + $conexion = conexionBD(); + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare(" + try { + $consulta = $conexion->prepare(" UPDATE partida SET nombrePartida=:nombrePartida, idUsuario=:idUsuario WHERE idPartida=:idPartida "); - $consulta->bindParam(":idPartida",$this->idPartida); - $consulta->bindParam(":nombrePartida",$this->nombrePartida); - $consulta->bindParam(":idUsuario",$this->idUsuario); + $consulta->bindParam(":idPartida", $this->idPartida); + $consulta->bindParam(":nombrePartida", $this->nombrePartida); + $consulta->bindParam(":idUsuario", $this->idUsuario); $consulta->execute(); - return[ - "exito"=>"La partida se editó correctamente.", - "exito_tecnico"=>$this->idPartida + return [ + "exito" => "La partida se editó correctamente.", + "exito_tecnico" => $this->idPartida ]; - }catch(PDOException $error){ - return[ - "error"=>"Ocurrió un error al editar la partida.", - "error_tecnico"=>$error + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al editar la partida.", + "error_tecnico" => $error ]; } } - public function eliminar(){ - $conexion=conexionBD(); - if(is_array($conexion)){ + public function eliminar() + { + $conexion = conexionBD(); + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare(" + try { + $consulta = $conexion->prepare(" DELETE FROM partida WHERE idPartida=:idPartida "); - $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->bindParam(":idPartida", $this->idPartida); $consulta->execute(); - return[ - "exito"=>"La partida se eliminó correctamente.", - "exito_tecnico"=>$this->idPartida + return [ + "exito" => "La partida se eliminó correctamente.", + "exito_tecnico" => $this->idPartida ]; - }catch(PDOException $error){ - return[ - "error"=>"No se pudo eliminar la partida.", - "error_tecnico"=>$error + } catch (PDOException $error) { + return [ + "error" => "No se pudo eliminar la partida.", + "error_tecnico" => $error ]; } } @@ -140,13 +146,14 @@ class Partida{ * Devuelve las preguntas asignadas a la partida, junto con el * idPartidaxPregunta (necesario para guardar respuestas después). */ - public function getPreguntas(){ - $conexion=conexionBD(); - if(is_array($conexion)){ + public function getPreguntas() + { + $conexion = conexionBD(); + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare(" + try { + $consulta = $conexion->prepare(" SELECT pxp.idPartidaxPregunta, p.* @@ -156,13 +163,13 @@ class Partida{ WHERE pxp.idPartida=:idPartida ORDER BY pxp.idPartidaxPregunta "); - $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->bindParam(":idPartida", $this->idPartida); $consulta->execute(); return $consulta->fetchAll(PDO::FETCH_ASSOC); - }catch(PDOException $error){ - return[ - "error"=>"Ocurrió un error al recuperar las preguntas de la partida.", - "error_tecnico"=>$error + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al recuperar las preguntas de la partida.", + "error_tecnico" => $error ]; } } @@ -170,66 +177,66 @@ class Partida{ /** * Asocia una pregunta ya existente a esta partida. */ - public function asignarPregunta($idPregunta){ - $conexion=conexionBD(); - if(is_array($conexion)){ + public function asignarPregunta($idPregunta) + { + $conexion = conexionBD(); + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare(" + try { + $consulta = $conexion->prepare(" INSERT INTO partidaxpregunta (idPartida,idPregunta) VALUES (:idPartida,:idPregunta) "); - $consulta->bindParam(":idPartida",$this->idPartida); - $consulta->bindParam(":idPregunta",$idPregunta); + $consulta->bindParam(":idPartida", $this->idPartida); + $consulta->bindParam(":idPregunta", $idPregunta); $consulta->execute(); - return[ - "exito"=>"La pregunta se asignó correctamente.", - "exito_tecnico"=>$conexion->lastInsertId() + return [ + "exito" => "La pregunta se asignó correctamente.", + "exito_tecnico" => $conexion->lastInsertId() ]; - }catch(PDOException $error){ - return[ - "error"=>"Ocurrió un error al asignar la pregunta.", - "error_tecnico"=>$error + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al asignar la pregunta.", + "error_tecnico" => $error ]; } } - - - //Cuenta cuántas preguntas tiene la partida en total. Es la primera mitad de la comprobación "¿ha terminado el usuario de jugar?". - public function contarPreguntasAsignadas(){ - $conexion=conexionBD(); - if(is_array($conexion)){ + public function contarPreguntasAsignadas() + { + $conexion = conexionBD(); + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare(" + try { + $consulta = $conexion->prepare(" SELECT COUNT(*) AS total FROM partidaxpregunta WHERE idPartida=:idPartida "); - $consulta->bindParam(":idPartida",$this->idPartida); + $consulta->bindParam(":idPartida", $this->idPartida); $consulta->execute(); - $fila=$consulta->fetch(PDO::FETCH_ASSOC); + $fila = $consulta->fetch(PDO::FETCH_ASSOC); return (int)$fila["total"]; - }catch(PDOException $error){ - return[ - "error"=>"Ocurrió un error al contar las preguntas.", - "error_tecnico"=>$error + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al contar las preguntas.", + "error_tecnico" => $error ]; } } - public function contarRespuestasUsuario($idUsuario){ - $conexion=conexionBD(); - if(is_array($conexion)){ + public function contarRespuestasUsuario($idUsuario) + { + $conexion = conexionBD(); + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare(" + try { + $consulta = $conexion->prepare(" SELECT COUNT(*) AS total FROM respuestaalmacenada ra INNER JOIN partidaxpregunta pxp @@ -237,15 +244,15 @@ class Partida{ WHERE pxp.idPartida=:idPartida AND ra.idUsuario=:idUsuario "); - $consulta->bindParam(":idPartida",$this->idPartida); - $consulta->bindParam(":idUsuario",$idUsuario); + $consulta->bindParam(":idPartida", $this->idPartida); + $consulta->bindParam(":idUsuario", $idUsuario); $consulta->execute(); - $fila=$consulta->fetch(PDO::FETCH_ASSOC); + $fila = $consulta->fetch(PDO::FETCH_ASSOC); return (int)$fila["total"]; - }catch(PDOException $error){ - return[ - "error"=>"Ocurrió un error al contar las respuestas del usuario.", - "error_tecnico"=>$error + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al contar las respuestas del usuario.", + "error_tecnico" => $error ]; } } @@ -254,79 +261,192 @@ class Partida{ * Sustituye al antiguo campo `terminada`: compara cuántas preguntas * tiene la partida contra cuántas ha respondido este usuario. */ - public function estaFinalizadaParaUsuario($idUsuario){ - $totalPreguntas=$this->contarPreguntasAsignadas(); - if(is_array($totalPreguntas)){ + public function estaFinalizadaParaUsuario($idUsuario) + { + $totalPreguntas = $this->contarPreguntasAsignadas(); + if (is_array($totalPreguntas)) { return $totalPreguntas; } - $totalRespondidas=$this->contarRespuestasUsuario($idUsuario); - if(is_array($totalRespondidas)){ + $totalRespondidas = $this->contarRespuestasUsuario($idUsuario); + if (is_array($totalRespondidas)) { return $totalRespondidas; } - return $totalPreguntas>0 && $totalPreguntas===$totalRespondidas; + return $totalPreguntas > 0 && $totalPreguntas === $totalRespondidas; } /** * Partidas creadas por un usuario, de más reciente a más antigua. */ - public function listarDelUsuario(){ - $conexion=conexionBD(); - if(is_array($conexion)){ + public function listarDelUsuario() + { + $conexion = conexionBD(); + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare(" + try { + $consulta = $conexion->prepare(" SELECT * FROM partida WHERE idUsuario=:idUsuario ORDER BY idPartida DESC "); - $consulta->bindParam(":idUsuario",$this->idUsuario); + $consulta->bindParam(":idUsuario", $this->idUsuario); $consulta->execute(); return $consulta->fetchAll(PDO::FETCH_ASSOC); - }catch(PDOException $error){ - return[ - "error"=>"Ocurrió un error al recuperar las partidas del usuario.", - "error_tecnico"=>$error + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al recuperar las partidas del usuario.", + "error_tecnico" => $error ]; } } + public function preguntaAsignada($idPregunta) + { + $conexion = conexionBD(); - - - - public function preguntaAsignada($idPregunta){ - $conexion=conexionBD(); - - if(is_array($conexion)){ + if (is_array($conexion)) { return $conexion; } - try{ - $consulta=$conexion->prepare(" + try { + $consulta = $conexion->prepare(" SELECT COUNT(*) AS total FROM partidaxpregunta WHERE idPartida=:idPartida AND idPregunta=:idPregunta "); - $consulta->bindParam(":idPartida",$this->idPartida); - $consulta->bindParam(":idPregunta",$idPregunta); + $consulta->bindParam(":idPartida", $this->idPartida); + $consulta->bindParam(":idPregunta", $idPregunta); $consulta->execute(); - $fila=$consulta->fetch(PDO::FETCH_ASSOC); + $fila = $consulta->fetch(PDO::FETCH_ASSOC); return (int)$fila["total"] > 0; + } catch (PDOException $error) { - }catch(PDOException $error){ + return [ + "error" => "Ocurrió un error al comprobar la pregunta.", + "error_tecnico" => $error + ]; + } + } + /** + * Vincula un equipo a esta partida en la tabla intermedia 'equipoxpartida'. + * Permite registrar qué grupos están participando en este torneo. + */ + public function registrarEquipoEnPartida($idEquipo) { + $conexion = conexionBD(); // Obtenemos la conexión modular del proyecto + + if (is_array($conexion)) { + return $conexion; // Si hay error en la conexión, lo devuelve + } + + try { + // Preparamos la consulta para insertar la relación en la tabla intermedia real + $consulta = $conexion->prepare(" + INSERT INTO equipoxpartida + (idPartida, idEquipo) + VALUES + (:idPartida, :idEquipo) + "); + + // Vinculamos los parámetros con el objeto de la partida actual y el equipo recibido + $consulta->bindParam(":idPartida", $this->idPartida); + $consulta->bindParam(":idEquipo", $idEquipo); + $consulta->execute(); + + return [ + "exito" => "El equipo se vinculó a la partida correctamente.", + "exito_tecnico" => $conexion->lastInsertId() + ]; + } catch (PDOException $error) { + // Capturamos el error extrayendo solo el mensaje de texto limpio + return [ + "error" => "Ocurrió un error al asignar el equipo a la partida.", + "error_tecnico" => $error->getMessage() + ]; + } + } - return[ - "error"=>"Ocurrió un error al comprobar la pregunta.", - "error_tecnico"=>$error + /** + * Obtiene todos los equipos que están compitiendo en esta partida. + * Es útil para mostrar la lista de rivales antes de empezar a responder. + */ + public function getEquiposParticipantes() { + $conexion = conexionBD(); + + if (is_array($conexion)) { + return $conexion; + } + + try { + // Hacemos un INNER JOIN para traer los nombres de los equipos desde la tabla intermedia + $consulta = $conexion->prepare(" + SELECT + exp.idEquipoxPartida, + e.idEquipo, + e.nombreEquipo + FROM equipoxpartida exp + INNER JOIN equipo e + ON exp.idEquipo = e.idEquipo + WHERE exp.idPartida = :idPartida + ORDER BY e.nombreEquipo ASC + "); + + $consulta->bindParam(":idPartida", $this->idPartida); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); // Devuelve el array con los equipos rivales + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al recuperar los equipos de la partida.", + "error_tecnico" => $error->getMessage() + ]; + } + } + + /** + * Obtiene todos los jugadores reales (Usuarios) que están jugando en esta partida. + * Utiliza la tabla 'equipoxusuario' en SQL para cruzar los datos. + */ + public function getJugadoresDeLaPartida() { + $conexion = conexionBD(); + + if (is_array($conexion)) { + return $conexion; + } + + try { + // Cruza la partida con los equipos, y luego los equipos con los usuarios + // para saber los nombres de todas las personas que están jugando el torneo. + $consulta = $conexion->prepare(" + SELECT DISTINCT + u.idUsuario, + u.nombreUsuario, + u.email, + e.nombreEquipo + FROM equipoxpartida exp + INNER JOIN equipoxusuario exu + ON exp.idEquipo = exu.idEquipo + INNER JOIN usuario u + ON exu.idUsuario = u.idUsuario + INNER JOIN equipo e + ON exu.idEquipo = e.idEquipo + WHERE exp.idPartida = :idPartida + "); + + $consulta->bindParam(":idPartida", $this->idPartida); + $consulta->execute(); + + return $consulta->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $error) { + return [ + "error" => "Ocurrió un error al obtener la lista de jugadores.", + "error_tecnico" => $error->getMessage() ]; } } } -?> \ No newline at end of file From 87fdf7285f3013a91eec62a2aa040048ec839ef2 Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 12:37:39 +0200 Subject: [PATCH 19/23] Subir archivos a "clases" From 63e9c3ceab4abf6709159b5a729327df06dd57bd Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 12:52:32 +0200 Subject: [PATCH 20/23] Subir archivos a "clases" --- clases/ClaseCategoria.php | 8 ++++---- clases/ClaseEquipo.php | 6 +++--- clases/ClasePartida.php | 22 +++++++++++----------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/clases/ClaseCategoria.php b/clases/ClaseCategoria.php index 1b17c6d..8890ec6 100644 --- a/clases/ClaseCategoria.php +++ b/clases/ClaseCategoria.php @@ -35,7 +35,7 @@ class Categoria{ }catch(PDOException $error){ $respuesta = [ 'error' => 'Ocurrió un error al guardar la categoría.', - 'error_tecnico' => $error + 'error_tecnico' => $error->getMessage() ]; $conexion = null; @@ -64,7 +64,7 @@ class Categoria{ }catch(PDOException $error){ $respuesta = [ 'error' => 'Ocurrió un error al obtener el listado de categorías.', - 'error_tecnico' => $error + 'error_tecnico' => $error->getMessage() ]; $conexion = null; @@ -94,7 +94,7 @@ class Categoria{ }catch(PDOException $error){ $respuesta = [ 'error' => 'Ocurrió un error al buscar la categoría.', - 'error_tecnico' => $error + 'error_tecnico' => $error->getMessage() ]; $conexion = null; @@ -134,7 +134,7 @@ class Categoria{ }catch(PDOException $error){ $respuesta = [ 'error' => 'Ocurrió un error al eliminar la categoría.', - 'error_tecnico' => $error + 'error_tecnico' => $error->getMessage() ]; $conexion = null; diff --git a/clases/ClaseEquipo.php b/clases/ClaseEquipo.php index 62a84b1..2b373ed 100644 --- a/clases/ClaseEquipo.php +++ b/clases/ClaseEquipo.php @@ -35,7 +35,7 @@ class Equipo{ }catch(PDOException $error){ $respuesta = [ 'error' => 'Ocurrió un error al guardar el equipo.', - 'error_tecnico' => $error + 'error_tecnico' => $error->getMessage() ]; $conexion = null; @@ -64,7 +64,7 @@ class Equipo{ }catch(PDOException $error){ $respuesta = [ 'error' => 'Ocurrió un error al obtener el listado de equipos.', - 'error_tecnico' => $error + 'error_tecnico' => $error->getMessage() ]; $conexion = null; @@ -94,7 +94,7 @@ class Equipo{ }catch(PDOException $error){ $respuesta = [ 'error' => 'Ocurrió un error al buscar el equipo.', - 'error_tecnico' => $error + 'error_tecnico' => $error->getMessage() ]; $conexion = null; diff --git a/clases/ClasePartida.php b/clases/ClasePartida.php index 16f4dae..b681685 100644 --- a/clases/ClasePartida.php +++ b/clases/ClasePartida.php @@ -41,7 +41,7 @@ class Partida } catch (PDOException $error) { return [ "error" => "Ocurrió un error al guardar la partida.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } @@ -59,7 +59,7 @@ class Partida } catch (PDOException $error) { return [ "error" => "Ocurrió un error al obtener el listado.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } @@ -82,7 +82,7 @@ class Partida } catch (PDOException $error) { return [ "error" => "Ocurrió un error al buscar la partida.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } @@ -112,7 +112,7 @@ class Partida } catch (PDOException $error) { return [ "error" => "Ocurrió un error al editar la partida.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } @@ -137,7 +137,7 @@ class Partida } catch (PDOException $error) { return [ "error" => "No se pudo eliminar la partida.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } @@ -169,7 +169,7 @@ class Partida } catch (PDOException $error) { return [ "error" => "Ocurrió un error al recuperar las preguntas de la partida.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } @@ -200,7 +200,7 @@ class Partida } catch (PDOException $error) { return [ "error" => "Ocurrió un error al asignar la pregunta.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } @@ -224,7 +224,7 @@ class Partida } catch (PDOException $error) { return [ "error" => "Ocurrió un error al contar las preguntas.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } @@ -252,7 +252,7 @@ class Partida } catch (PDOException $error) { return [ "error" => "Ocurrió un error al contar las respuestas del usuario.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } @@ -296,7 +296,7 @@ class Partida } catch (PDOException $error) { return [ "error" => "Ocurrió un error al recuperar las partidas del usuario.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } @@ -328,7 +328,7 @@ class Partida return [ "error" => "Ocurrió un error al comprobar la pregunta.", - "error_tecnico" => $error + 'error_tecnico' => $error->getMessage() ]; } } From 52a97dfd01a35761cea40f04b627b47566200bcb Mon Sep 17 00:00:00 2001 From: dbvictor2002 Date: Thu, 24 Sep 2026 12:52:42 +0200 Subject: [PATCH 21/23] Subir archivos a "clases" --- clases/ClaseRespuestaAlmacenada.php | 79 +++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 clases/ClaseRespuestaAlmacenada.php diff --git a/clases/ClaseRespuestaAlmacenada.php b/clases/ClaseRespuestaAlmacenada.php new file mode 100644 index 0000000..50e82cb --- /dev/null +++ b/clases/ClaseRespuestaAlmacenada.php @@ -0,0 +1,79 @@ +idRespuestaAlmacenada = $idRespuestaAlmacenada; + $this->idPartidaxPregunta = $idPartidaxPregunta; + $this->idUsuario = $idUsuario; + $this->idRespuesta = $idRespuesta; + $this->primero = $primero; + } + + /** + * Guarda la respuesta que ha seleccionado un usuario en una pregunta de la partida. + */ + public function guardarRespuesta() { + $conexion = conexionBD(); + if (is_array($conexion)) return $conexion; + + try { + $sql = "INSERT INTO respuestaalmacenada (idPartidaxPregunta, idUsuario, idRespuesta, primero) + VALUES (:idPartidaxPregunta, :idUsuario, :idRespuesta, :primero)"; + $consulta = $conexion->prepare($sql); + + $consulta->bindParam(':idPartidaxPregunta', $this->idPartidaxPregunta); + $consulta->bindParam(':idUsuario', $this->idUsuario); + $consulta->bindParam(':idRespuesta', $this->idRespuesta); + $consulta->bindParam(':primero', $this->primero, PDO::PARAM_INT); + $consulta->execute(); + + return [ + 'exito' => 'Respuesta del usuario almacenada correctamente.', + 'exito_tecnico' => $conexion->lastInsertId() + ]; + } catch (PDOException $error) { + return [ + 'error' => 'Ocurrió un error al guardar la respuesta del jugador.', + 'error_tecnico' => $error->getMessage() + ]; + } + } + + /** + * Obtiene los aciertos totales de un usuario en una partida específica. + * Útil para calcular las estadísticas individuales al terminar el juego. + */ + public static function obtenerAciertosUsuarioEnPartida($idPartida, $idUsuario) { + $conexion = conexionBD(); + if (is_array($conexion)) return $conexion; + + try { + $sql = "SELECT COUNT(*) AS aciertos + FROM respuestaalmacenada ra + INNER JOIN partidaxpregunta pxp ON ra.idPartidaxPregunta = pxp.idPartidaxPregunta + INNER JOIN respuesta r ON ra.idRespuesta = r.idRespuesta + WHERE pxp.idPartida = :idPartida AND ra.idUsuario = :idUsuario AND r.correcta = 1"; + + $consulta = $conexion->prepare($sql); + $consulta->bindParam(':idPartida', $idPartida); + $consulta->bindParam(':idUsuario', $idUsuario); + $consulta->execute(); + + $resultado = $consulta->fetch(PDO::FETCH_ASSOC); + return (int)$resultado['aciertos']; + } catch (PDOException $error) { + return [ + 'error' => 'Ocurrió un error al calcular los aciertos.', + 'error_tecnico' => $error->getMessage() + ]; + } + } +} \ No newline at end of file From 9df7bd9d45fb7a2c6a9729cead91742834f189db Mon Sep 17 00:00:00 2001 From: "v.rodriguezcamacho" Date: Thu, 24 Sep 2026 13:27:11 +0200 Subject: [PATCH 22/23] add controladorEquipoxUsuario.php --- controladorEquipoxUsuario.php | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 controladorEquipoxUsuario.php diff --git a/controladorEquipoxUsuario.php b/controladorEquipoxUsuario.php new file mode 100644 index 0000000..59ab0c1 --- /dev/null +++ b/controladorEquipoxUsuario.php @@ -0,0 +1,47 @@ + 'No hay una sesión activa de usuario. Por favor, inicie sesión.' + ]); + break; + } + $idUsuario = $_SESSION['idUsuario']; + $idEquipo = intval($_POST['idEquipo'] ?? 0); + break; + if ($idEquipo <= 0) { + echo json_encode([ + 'error' => 'El ID del equipo proporcionado no es válido.' + ]); + break; + } + $equipoxusuario = new EquipoxUsuario(); + $resultado = $equipoxusuario->registrarUsuarioEnEquipo($idEquipo, $idUsuario); + echo json_encode($resultado); + break; + + case 'listarUsuariosPorEquipo': + $idEquipo = intval($_POST['idEquipo'] ?? 0); + + if ($idEquipo <= 0) { + echo json_encode(['error' => 'ID de equipo no válido']); + break; + } + $equipoxusuario = new EquipoxUsuario(); + $listado = $equipoxusuario->listarUsuariosPorEquipo($idEquipo); + break; + echo json_encode($listado); + break; + + +} + + +?> From 22f86c2d6d3b6f625d97bd143971a55f44c2d7e0 Mon Sep 17 00:00:00 2001 From: marga Date: Thu, 24 Sep 2026 14:00:24 +0200 Subject: [PATCH 23/23] =?UTF-8?q?a=C3=B1adir=20carpeta=20controlador=20y?= =?UTF-8?q?=20controladorUsuario?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cabecera.php | 149 ++++++++++++++++++ .../controladorEquipoxUsuario.php | 0 controladores/controladorUsuario.php | 86 ++++++++++ index.php | 54 ++++++- 4 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 cabecera.php rename controladorEquipoxUsuario.php => controladores/controladorEquipoxUsuario.php (100%) create mode 100644 controladores/controladorUsuario.php diff --git a/cabecera.php b/cabecera.php new file mode 100644 index 0000000..605722e --- /dev/null +++ b/cabecera.php @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/controladorEquipoxUsuario.php b/controladores/controladorEquipoxUsuario.php similarity index 100% rename from controladorEquipoxUsuario.php rename to controladores/controladorEquipoxUsuario.php diff --git a/controladores/controladorUsuario.php b/controladores/controladorUsuario.php new file mode 100644 index 0000000..4a17875 --- /dev/null +++ b/controladores/controladorUsuario.php @@ -0,0 +1,86 @@ + 'Todos los campos son obligatorios' + ]); + + break; + } + + $usuarioExistente = Usuario::buscarPorEmail($email); + + if ($usuarioExistente instanceof Usuario) { + + echo json_encode([ + 'error' => 'Ya existe una cuenta con ese correo electrónico' + ]); + + break; + } + + $usuario = new Usuario( + $nombreUsuario, + $contrasena, + $email + ); + + $resultado = $usuario->registrar(); + + echo json_encode($resultado); + + break; + + + case 'comprobarUsuario': + + $email = trim($_POST['email'] ?? ''); + $contrasena = $_POST['contrasena'] ?? ''; + + $resultado = Usuario::login($email, $contrasena); + + if ($resultado instanceof Usuario) { + + $_SESSION['idUsuario'] = $resultado->getIdUsuario(); + $_SESSION['email'] = $resultado->getEmail(); + $_SESSION['nombreUsuario'] = $resultado->getNombreUsuario(); + + echo json_encode([ + 'exito' => 'Login correcto', + 'idUsuario' => $resultado->getIdUsuario(), + 'nombreUsuario' => $resultado->getNombreUsuario() + ]); + + } else { + + echo json_encode([ + 'error' => 'Usuario o contraseña incorrectos' + ]); + } + + break; + + + case 'cerrarSesion': + + session_destroy(); + + echo json_encode([ + 'exito' => 'Sesión cerrada' + ]); + + break; +} \ No newline at end of file diff --git a/index.php b/index.php index ee8d7dc..803d90f 100644 --- a/index.php +++ b/index.php @@ -1,12 +1,60 @@ + + - + - Proyecto Trivial + Triviagmático - + +
+
+ + + + + + + +
+
+
+

RANKING GLOBAL DE JUGADORES

+
+
+ +
+ +

Cargando clasificación...

+

Los mejores equipos y jugadores aparecerán aquí pronto.

+
+
+
+
+ +
+
+ + + + \ No newline at end of file