diff --git a/assets/css/highContrast.css b/assets/css/highContrast.css index f62f560..d951cdd 100644 --- a/assets/css/highContrast.css +++ b/assets/css/highContrast.css @@ -370,7 +370,7 @@ margin-right: auto; box-shadow: 0 4px 8px 0 #00020f, 0 6px 20px 0 #00020f; } -.code.purchase { +.code.purchase, .code.resume { text-align: center; } .code.purchase h3 { diff --git a/assets/css/main.css b/assets/css/main.css index bedd0c6..5b8c3aa 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -368,7 +368,7 @@ main img { margin-right: auto; box-shadow: 0 4px 8px 0 #00020f, 0 6px 20px 0 #00020f; } -.code.purchase { +.code.purchase, .code.resume { text-align: center; } .code.purchase h3 { diff --git a/assets/js/cambiarCSS.js b/assets/js/cambiarCSS.js index d724994..51e9ba6 100644 --- a/assets/js/cambiarCSS.js +++ b/assets/js/cambiarCSS.js @@ -1,3 +1,8 @@ +/** + * Práctica - Sistemas Web | Grupo D + * CompluCine - FDI-cines + */ + function cambiarCSS(nuevo){ document.getElementById('estilo').setAttribute('href', nuevo); } \ No newline at end of file diff --git a/assets/js/checkPay.js b/assets/js/checkPay.js new file mode 100644 index 0000000..033d6ce --- /dev/null +++ b/assets/js/checkPay.js @@ -0,0 +1,89 @@ +/** + * Práctica - Sistemas Web | Grupo D + * CompluCine - FDI-cines + */ + + //Expresión regular para validar nombre y apellidos: +const regExpr = /^([A-Za-zÁÉÍÓÚñáéíóúÑ]{0}?[A-Za-zÁÉÍÓÚñáéíóúÑ\']+[\s])+([A-Za-zÁÉÍÓÚñáéíóúÑ]{0}?[A-Za-zÁÉÍÓÚñáéíóúÑ\'])+[\s]?([A-Za-zÁÉÍÓÚñáéíóúÑ]{0}?[A-Za-zÁÉÍÓÚñáéíóúÑ\'])?$/g; + +$(document).ready(function() { + + //Iconos para validar el titular de la tarjeta: + $("#cardNameValid").hide(); + $("#cardNameInvalid").hide(); + + //Iconos para validar el número de tarjeta: + $("#carNumberValid").hide(); + $("#cardNumerInvalid").hide(); + + //Iconos para validar el CVV: + $("#cvvValid").hide(); + $("#cvvInvalid").hide(); + + + //Comprueba que el titular de la tarjeta es válido. + $("#card-holder").change(function(){ + const cardHolder = $("#card-holder"); + cardHolder[0].setCustomValidity(""); + + if(cardHolder.val().length > 5 && holderCheck(cardHolder.val())){ + $("#cardNameValid").show(); + $("#cardNameInvalid").hide(); + cardHolder[0].setCustomValidity(""); + } else { + $("#cardNameValid").hide(); + $("#cardNameInvalid").show(); + cardHolder[0].setCustomValidity("El titular de la tarjeta no es válido."); + } + }); + + //Comprueba que el NÚMERO de la tarjeta es válido. + $("#card-number-0").change(function(){ + $("#card-number-1").change(function(){ + $("#card-number-2").change(function(){ + $("#card-number-3").change(function(){ + const cardNumber0 = $("#card-number-0"); + const cardNumber1 = $("#card-number-1"); + const cardNumber2 = $("#card-number-2"); + const cardNumber3 = $("#card-number-3"); + cardNumber0[0].setCustomValidity(""); + cardNumber1[0].setCustomValidity(""); + cardNumber2[0].setCustomValidity(""); + cardNumber3[0].setCustomValidity(""); + + if( (cardNumber0.val().length + cardNumber1.val().length + cardNumber2.val().length +cardNumber3.val().length) === 16 ){ + $("#carNumberValid").show(); + $("#cardNumerInvalid").hide(); + cardNumber0[0].setCustomValidity(""); + } else { + $("#carNumberValid").hide(); + $("#cardNumerInvalid").show(); + cardNumber0[0].setCustomValidity("El número de tarjeta debe tener 16 dígitos."); + } + }); + }); + }); + }); + + + //Comprueba que el CVV de la tarjeta es válido. + $("#card-cvv").change(function(){ + const cvv = $("#card-cvv"); + cvv[0].setCustomValidity(""); + + if(cvv.val().length === 3){ + $("#cvvValid").show(); + $("#cvvInvalid").hide(); + cvv[0].setCustomValidity(""); + } else { + $("#carcvvValiddNameValid").hide(); + $("#cvvInvalid").show(); + cvv[0].setCustomValidity("El CVV debe tener 3 dígitos."); + } + }); + + //Devuelve true si el nombre y apellidos del titular son válidos, false en caso contrario. + function holderCheck(name) { + return regExpr.test(name) ? true : false; + } +}) \ No newline at end of file diff --git a/assets/js/deleteConfirm.js b/assets/js/deleteConfirm.js index 3211bb0..70ebd9c 100644 --- a/assets/js/deleteConfirm.js +++ b/assets/js/deleteConfirm.js @@ -1,3 +1,28 @@ -function newWindow(page){ - window.open(page, 'Ventana de Confirmación', 'width=500, height=300'); -} \ No newline at end of file +/** + * Práctica - Sistemas Web | Grupo D + * CompluCine - FDI-cines + */ + +/* TO-DO: NO FUNCIONA LA PETICIÓN AJAX */ + +$(document).ready(function() { + document.getElementById("submit").onclick=function(){ + let _delete = confirm("¿Está seguro de que desea eliminar su cuenta de usuario?\nEsta acción no se puede deshacer."); + + if(_delete == true){ + //console.log(location.href += "&reply=" + _delete); + //location.href += "&reply=" + _delete; + $.ajax({ + url:"./?option=delete_user", + type: "POST", + data: {reply: "true"}, + success:function(data){ + console.log(data.reply); + }, + error:function(data){ + console.log(data.reply); + } + }); + } + } +}); \ No newline at end of file diff --git a/assets/js/promotions.js b/assets/js/promotions.js index ce59d65..8176c85 100644 --- a/assets/js/promotions.js +++ b/assets/js/promotions.js @@ -1,3 +1,9 @@ +/** + * Práctica - Sistemas Web | Grupo D + * CompluCine - FDI-cines + */ + +/* TO-DO: enviar el contenido del array de promociones */ window.onload = function () { var promos = document.getElementById("promotions").value; console.log(promos); diff --git a/assets/js/selectTicket.js b/assets/js/selectTicket.js index d649bca..8e2f1b8 100644 --- a/assets/js/selectTicket.js +++ b/assets/js/selectTicket.js @@ -1,3 +1,8 @@ +/** + * Práctica - Sistemas Web | Grupo D + * CompluCine - FDI-cines + */ + // Método 1: recargar la página y enviar un GET. window.onload = function(){ var select = document.getElementById("select_cinema"); @@ -6,7 +11,7 @@ window.onload = function(){ } } -// Método 2: enviar una petición AJAX con POST. (NO FUNCIONA) +// Método 2: enviar una petición AJAX con POST. ==> (NO FUNCIONA, PERO LA IDEA ERA HACERLO ASÍ PARA EVITAR REFRESCAR LA PÁGINA Y LLENAR LA URL) /* $(document).ready(function(){ $("#select_cinema_session").change(function(){ @@ -20,8 +25,6 @@ $(document).ready(function(){ cache : false, async : false, success: function(data){ - $("cinemas option").remove(); - $("cinemas").append(data); console.log(cinema); }, error: function(response) @@ -31,17 +34,4 @@ $(document).ready(function(){ }); }); }); -*/ - -//Método 3: enviar una petición AJAX con GET. (NO FUNCIONA) -/* -$(document).ready(function(){ - $("#select_cinema_session").change(function(){ - var cinema = $('select[id=cinemas]').val(); - //console.log($('select[id=cinemas]').val()); - $.get(window.location + "?cinema=" + cinema, function(data,status){ - console.log(cinema); - }); - }); -}); */ \ No newline at end of file diff --git a/assets/php/includes/hall_dao.php b/assets/php/includes/hall_dao.php index a6d123e..333f6b7 100644 --- a/assets/php/includes/hall_dao.php +++ b/assets/php/includes/hall_dao.php @@ -22,6 +22,25 @@ return $sql; } + + //Returns the hall's data by ID. + public function HallData($id){ + $id = $this->mysqli->real_escape_string($id); + + $sql = sprintf( "SELECT * FROM hall WHERE number = '%d'", $id ); + $resul = mysqli_query($this->mysqli, $sql) or die ('Error into query database'); + + $resul->data_seek(0); + $hall = null; + while ($fila = $resul->fetch_assoc()) { + $hall = $this->loadHall($fila["number"], $fila["idcinema"], $fila["numrows"], $fila["numcolumns"], $fila["total_seats"], null); + } + + //mysqli_free_result($selectUser); + $resul->free(); + + return $hall; + } //Returns a query to get the halls data. public function getAllHalls($cinema){ diff --git a/assets/php/includes/purchase.php b/assets/php/includes/purchase.php new file mode 100644 index 0000000..54a3e13 --- /dev/null +++ b/assets/php/includes/purchase.php @@ -0,0 +1,43 @@ +_idUser = $idUser; + $this->_idSession = $idSession; + $this->_idHall = $idHall; + $this->_idCinema = $idCinema; + $this->_numRow = $row; + $this->_numColumn = $column; + $this->_timePurchase = $time; + } + + //Methods: + + //Getters && Setters: + public function setUserId($idUser){ $this->_idUser = $id; } + public function getUserId(){ return $this->_idUser; } + public function setSessionId($idSession){ $this->_idSession = $idSession; } + public function getSessionId(){ return $this->_idSession; } + public function setHallId($idHall){ $this->_idHall = $idHall; } + public function getHallId(){ return $this->_idHall; } + public function setCinemaId($idCinema){ $this->_idCinema = $idCinema; } + public function getCinemaId(){ return $this->_idCinema; } + public function setRow($row){ $this->_numRow = $row; } + public function getRow(){ return $this->_numRow; } + public function setColumn($column){ $this->_numColumn = $column; } + public function getColumn(){ return $this->_numColumn; } + public function setTime($time){ $this->_timePurchase = $time; } + public function getTime(){ return $this->_timePurchase; } + + } +?> \ No newline at end of file diff --git a/assets/php/includes/purchase_dao.php b/assets/php/includes/purchase_dao.php new file mode 100644 index 0000000..5cfe328 --- /dev/null +++ b/assets/php/includes/purchase_dao.php @@ -0,0 +1,46 @@ +mysqli, $sql); + + return $resul; + } + + //All purchases of one user. + public function allPurchasesData($idUser){ + $sql = sprintf( "SELECT * FROM purchase WHERE iduser = '%d' ", $idUser); + $resul = mysqli_query($this->mysqli, $sql) or die ('Error into query database'); + + $purchases = null; + while($fila=$resul->fetch_assoc()){ + $purchases[] = $this->loadPurchase($fila["iduser"], $fila["idsession"], $fila["idhall"], $fila["idcinema"], $fila["numrow"], $fila["numcolum"], $fila["time_purchase"]); + } + $resul->free(); + return $purchases; + } + + //Create a new User Data Transfer Object. + public function loadPurchase($idUser, $idSession, $idHall, $idCinema, $row, $column, $time){ + return new Purchase($idUser, $idSession, $idHall, $idCinema, $row, $column, $time); + } + + } + +?> \ No newline at end of file diff --git a/assets/php/includes/session.php b/assets/php/includes/session.php index cb6e4d4..a8daa7f 100644 --- a/assets/php/includes/session.php +++ b/assets/php/includes/session.php @@ -120,5 +120,8 @@ public function setFormat($format){ $this->_format = $format; } public function getFormat(){ return $this->_format; } + public function setSeatsFull($bool){ $this->_seats_full = $bool; } + public function getSeatsFull(){ return $this->_seats_full; } + } ?> \ No newline at end of file diff --git a/assets/php/includes/user.php b/assets/php/includes/user.php index 1fc9927..213e3bf 100644 --- a/assets/php/includes/user.php +++ b/assets/php/includes/user.php @@ -1,5 +1,4 @@ - "; - if($page === "FDI-Cines") echo"\n"; - if($page === "Panel de Usuario") echo"\n"; - if($page === "Comprar Entrada") echo"\n"; + if($page === "FDI-Cines") echo"\n"; + if($page === "Panel de Usuario") echo"\n"; + if($page === "Comprar Entrada") echo" + \n"; } } diff --git a/panel_user/includes/formDeleteAccount.php b/panel_user/includes/formDeleteAccount.php index 8f3b5f3..d686421 100644 --- a/panel_user/includes/formDeleteAccount.php +++ b/panel_user/includes/formDeleteAccount.php @@ -77,11 +77,15 @@ class FormDeleteAccount extends Form { if( (unserialize($_SESSION['user'])->getId() === $user->getId()) && ($nombre === $user->getName()) && ($email === $user->getEmail()) && ($bd->verifyPass($password, $user->getPass())) ){ - $bd->deleteUserAccount($user->getId()); - unset($_SESSION); - session_destroy(); - - $result = ROUTE_APP; + if(!isset($_GET['reply'])){ + $bd->deleteUserAccount($user->getId()); + unset($_SESSION); + session_destroy(); + + $result = ROUTE_APP; + } else { + $result[] = "Operación cancelada."; + } } else { $result[] = "Los datos introducidos\nno son válidos."; diff --git a/panel_user/panelUser.php b/panel_user/panelUser.php index d6aceb8..cd6891e 100644 --- a/panel_user/panelUser.php +++ b/panel_user/panelUser.php @@ -89,8 +89,47 @@ //User purchase history. static function purchases(){ + require_once('../assets/php/includes/purchase_dao.php'); + + $purchaseDAO = new PurchaseDAO("complucine"); + $purchases = $purchaseDAO->allPurchasesData(unserialize($_SESSION['user'])->getId()); + + $sessions = array(); + $halls = array(); + $cinemas = array(); + $rows = array(); + $columns = array(); + $dates = array(); + foreach($purchases as $key=>$value){ + $sessions[$key] = $value->getSessionId(); + $halls[$key] = $value->getHallId(); + $cinemas[$key] = $value->getCinemaId(); + $rows[$key] = $value->getRow(); + $columns[$key] = $value->getColumn(); + $dates[$key] = $value->getTime(); + } + + $purchasesHTML = ''; + if(count($purchases) > 0){ + for($i = 0; $i < count($purchases); $i++){ + if($i%2 === 0){ + if($i != 0) $purchasesHTML .= ' + '; + $purchasesHTML .= '
+ '; + } else { + if($i != 0) $purchasesHTML .= '
+ '; + $purchasesHTML .= '
+ '; + } + $purchasesHTML .= '

'.$dates[$i].'


'; + } + } + return $reply = '
-

Aquí el historial de compras


+

Historial de compras


+ '.$purchasesHTML.'
'."\n"; } diff --git a/purchase/includes/formPurchase.php b/purchase/includes/formPurchase.php index b978648..81696a0 100644 --- a/purchase/includes/formPurchase.php +++ b/purchase/includes/formPurchase.php @@ -6,15 +6,22 @@ include_once($prefix.'assets/php/includes/film_dao.php'); include_once($prefix.'assets/php/includes/film.php'); include_once($prefix.'assets/php/includes/cinema_dao.php'); include_once($prefix.'assets/php/includes/cinema.php'); +include_once($prefix.'assets/php/includes/hall_dao.php'); +include_once($prefix.'assets/php/includes/hall.php'); +include_once($prefix.'assets/php/includes/purchase_dao.php'); +include_once($prefix.'assets/php/includes/purchase.php'); +include_once($prefix.'assets/php/includes/user.php'); class FormPurchase extends Form { //Atributes: private $session; // Session of the film to be purchased. private $cinema; // Cinema of the film to be purchased. + private $hall; // Hall of the film to be purchased. private $film; // Film to be purchased. private $years; // Actual year. private $months; // Months of the year. + private $_TODAY; // Actual date. public function __construct() { //$options = array("action" => $_SERVER['PHP_SELF']); @@ -29,9 +36,14 @@ class FormPurchase extends Form { $cinemaDAO = new Cinema_DAO("complucine"); $this->cinema = $cinemaDAO->cinemaData($this->session->getIdcinema()); + $hallDAO = new HallDAO("complucine"); + $this->hall = $hallDAO->HallData($this->session->getIdhall()); + $TODAY = getdate(); $year = "$TODAY[year]"; + $this->_TODAY = "$TODAY[year]-$TODAY[month]-$TODAY[mday] $TODAY[hours]:$TODAY[minutes]:$TODAY[seconds]"; + $this->years = array(); for($i = $year; $i < $year+10; $i++) array_push($this->years, $i); @@ -44,6 +56,10 @@ class FormPurchase extends Form { // Se generan los mensajes de error si existen. $htmlErroresGlobales = self::generaListaErroresGlobales($errores); $errorNombre = self::createMensajeError($errores, 'card-holder', 'span', array('class' => 'error')); + $errorCardNumber = self::createMensajeError($errores, 'card-number-0', 'span', array('class' => 'error')); + $errorCVV = self::createMensajeError($errores, 'card-cvv', 'span', array('class' => 'error')); + $errorCardExpirationMonth = self::createMensajeError($errores, 'card-expiration-month', 'span', array('class' => 'error')); + $errorCardExpirationYear = self::createMensajeError($errores, 'card-expiration-year', 'span', array('class' => 'error')); $monthsHTML = ""; foreach($this->months as $value){ @@ -55,7 +71,13 @@ class FormPurchase extends Form { $yearsHTML .= ""; } - $html = "
+ if($this->session->getSeatsFull()){ + $html = "
+

La sesión está llena, no quedan asientos disponibles.


+

Vuelva atrás para selecionar otra sesión.

+
"; + } else { + $html = "
Resumen de la Compra ".$this->film->getTittle()." @@ -70,16 +92,19 @@ class FormPurchase extends Form { Datos Bancarios
".$errorNombre."

+
-
+
".$errorCardNumber."

+ - +
".$errorCVV."
+
-
+
".$errorCardExpirationMonth.$errorCardExpirationYear."

@@ -93,7 +118,7 @@ class FormPurchase extends Form {
"; - + } return $html; } @@ -105,9 +130,44 @@ class FormPurchase extends Form { if ( empty($nombre) ) { $result['card-holder'] = "El nombre no puede estar vacío."; } + + for($i = 0; $i < 4; $i++){ + $card_numer = $this->test_input($datos['card-number-'.$i]) ?? null; + if ( empty($card_numer) || mb_strlen($card_numer) < 4 ) { + $result['card-number-0'] = "La tarjeta debe tener 16 dígitos."; + } + } + + $cvv = $this->test_input($datos['card-cvv']) ?? null; + if ( empty($cvv) || mb_strlen($cvv) < 3 ) { + $result['card-cvv'] = "El CVV debe tener 3 números."; + } + $month = $this->test_input($datos['card-expiration-month']) ?? null; + if ( empty($month) ) { + $result['card-expiration-month'] = "El mes de expiración no es correcto."; + } + + $year = $this->test_input($datos['card-expiration-year']) ?? null; + if ( empty($year) ) { + $result['card-expiration-year'] = "El año de expiración no es correcto."; + } + if (count($result) === 0) { - $result[] = "La compra aun está en desarrollo. Vuelva en unos días."; + if(isset($_SESSION["login"]) && $_SESSION["login"] == true){ + $purchaseDAO = new PurchaseDAO("complucine"); + $purchaseDAO->createPurchase(unserialize($_SESSION["user"])->getId(), $this->session->getId(), $this->session->getIdhall(), $this->cinema->getId(), rand(1, $this->hall->getNumRows()), rand(1, $this->hall->getNumCol()), date("Y-m-d H:i:s")); + $purchase = new Purchase(unserialize($_SESSION["user"])->getId(), $this->session->getId(), $this->session->getIdhall(), $this->cinema->getId(), rand(1, $this->hall->getNumRows()), rand(1, $this->hall->getNumCol()), strftime("%A %e de %B de %Y a las %H:%M")); + + $_SESSION["purchase"] = serialize($purchase); + $_SESSION["film_purchase"] = serialize($this->film); + $result = "resume.php"; + } else { + $purchase = new Purchase("null", $this->session->getId(), $this->session->getIdhall(), $this->cinema->getId(), rand(1, $this->hall->getNumRows()), rand(1, $this->hall->getNumCol()), strftime("%A %e de %B de %Y a las %H:%M")); + $_SESSION["purchase"] = serialize($purchase); + $_SESSION["film_purchase"] = serialize($this->film); + $result = "resume.php"; + } } return $result; diff --git a/purchase/index.php b/purchase/index.php index 78391b8..3691b21 100644 --- a/purchase/index.php +++ b/purchase/index.php @@ -2,7 +2,7 @@ //General Config File: require_once('../assets/php/config.php'); - //Get Film to purchase: + //Get Ticket to purchase: include_once($prefix.'assets/php/includes/film_dao.php'); include_once($prefix.'assets/php/includes/film.php'); include_once($prefix.'assets/php/includes/cinema_dao.php'); @@ -160,5 +160,5 @@ //General page content: require RAIZ_APP.'/HTMLtemplate.php'; - //TO-DO: añadir elegir promocione sy enviar con el POST. + //TO-DO: añadir elegir promociones y enviar con el POST. ?> diff --git a/purchase/resume.php b/purchase/resume.php new file mode 100644 index 0000000..fdbfaae --- /dev/null +++ b/purchase/resume.php @@ -0,0 +1,71 @@ +sessionData($purchase->getSessionId()); + $cinemaDAO = new Cinema_DAO("complucine"); + $cinema = $cinemaDAO->cinemaData($purchase->getCinemaId()); + + unset($_SESSION["purchase"]); + unset($_SESSION["film_purchase"]); + + $reply = "

Se ha realizado su compra con éxito, a continuación puede ver el resumen:


+
+ ".$film_purchase->getTittle()." +

Película: ".str_replace('_', ' ', strtoupper($film_purchase->getTittle()))."

+

Duración: ".$film_purchase->getDuration()." minutos

+

Idioma: ".$film_purchase->getLanguage()."

+

Precio: ".$session->getSeatPrice()." €

+
+
+

Sesión (Fecha): ".$session->getDate()."

+

Sesión (Hora): ".$session->getStartTime()."

+

Cine: ".$cinema->getName()."

+

Sala: ".$purchase->getHallId()."

+

Asiento (Columna): ".$purchase->getRow()."

+

Asiento (Fila): ".$purchase->getColumn()."

+

Hora de la Compra: ".$purchase->getTime()."

+
+ "; + + if(isset($_SESSION["login"]) && $_SESSION["login"] == true){ + $actions = '

Guarde esta información y enséñela para entrar al cine.


+

Se ha guardado la información de la compra en su panel de usuario.

+ + '; + } else { + $actions = '

Guarde esta información y enséñela para entrar al cine.


+