El concepto CRUD está estrechamente
vinculado a la gestión de datos digitales. CRUD hace referencia a un
acrónimo en el que se reúnen las primeras letras de las cuatro
operaciones fundamentales de aplicaciones persistentes en sistemas de bases de
datos:
- Create (Crear
registros)
- Read (Leer registros)
- Update (Actualizar registros)
- Delete (Borrar
registros)
En pocas palabras, CRUD resume las
funciones requeridas por un usuario para crear y gestionar datos. Varios
procesos de gestión de datos están basados en CRUD, en los que dichas
operaciones están específicamente adaptadas a los requisitos del sistema y de
usuario, ya sea para la gestión de bases de datos o para el uso de
aplicaciones.
El proyecto STAR CRUD, es un
ejercicio de programación completo para crear un sistema CRUD que gestione una
base de datos donde vamos a poder guardar, editar o eliminar un registro de
todos los planetas existentes en el universo de ficción de la saga STAR WARS.
El sistema está programado con PHP
siguiendo el paradigma de programación orientada a objetos POO y, siguiendo el
patrón de diseño de software MVC (Modelo Vista Controlador).
El sistema dispondrá también de
un sistema de registro de usuarios y login para poder entrar al sistema, y la
base de datos y su tratamiento está construida con Mysql y XAMPP.
Para la parte de estilos en
cascada usaremos Bootstrap 5.
ESTRUCTURA DEL PROYECTO
REGISTRO Y LOGIN CON PHP POO
(AÑADIENDO CLASES A MI MODELO)
Creamos la siguinete estructura de carpetas en la carpata
raiz del proyecto:
Creamos los archivos styles.css y scripts.js en las carpetas CSS y JS respectivamente
Creamos el archivo de inicio del
proyecto index.php
DEPENDENCIAS
Vamos a enlazar nuestros estilos
css y el JavaScript desde el index.php
Usaremos la fuente oficial de STAR WARS, añadiéndola al proyecto mediante su cdn:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>STARS
CRUD</title>
<link href="https://allfont.net/allfont.css?fonts=star-jedi" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<script src="js/scripts.js"></script>
</body>
</html>
En nuestro archivo CSS haremos un
sencillo reset y estableceremos la
fuente por defecto:
html {
box-sizing:
border-box;
font-family:
'Star Jedi', arial;
font-size:
16px;
}
*, *:before,
*:after
{
box-sizing:
inherit;
}
body, h1,
h2, h3,
h4, h5,
h6, p,
ol, ul
{
margin:
0;
padding:
0;
font-weight:
normal;
}
ol, ul
{
list-style:
none;
}
img {
max-width:
100%;
height:
auto;
}
Para ver como nos queda haremos
un pequeño hola mundo con un h1 en el index:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>STARS
CRUD</title>
<link href="https://allfont.net/allfont.css?fonts=star-jedi" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<h1><b>Hola
STARS CRUD<b></h1>
<script src="js/scripts.js"></script>
</body>
</html>
Añadiremos el cdn de bootstrap y
Font awesome parausar iconos,para usar fontawesome hay que registrarse y
recibir el script:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>STARS
CRUD</title>
<!--Bootstrap cdn-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<!--Fontawesome
cdn-->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.1.2/css/fontawesome.min.css" integrity="sha384-X8QTME3FCg1DLb58++lPvsjbQoCT9bp3MsUU3grbIny/3ZwUJkRNO8NPW6zqzuW9" crossorigin="anonymous">
<!--Starwars
Font cdn-->
<link href="https://allfont.net/allfont.css?fonts=star-jedi" rel="stylesheet" type="text/css" />
<!--Mis
estilos-->
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<h1><b>Hola
STARS CRUD<b><i class="fa-solid
fa-file-code"></i></h1>
<!--Font
awesome personal js-->
<script src="https://kit.fontawesome.com/1e88d8726f.js" crossorigin="anonymous"></script>
<!--Bootstrap
js-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<!--Mis
scripts JS-->
<script src="js/scripts.js"></script>
</body>
</html>
Por ultimo añadiremos nuestro
favicon al sitio, tenemos el archivo en assets
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<link rel="icon" type="image/jpg" href="assets/favicon.ico"/>
MAQUETACIÓN DEL INDEX.PHP
Vamos a crear un primera
maquetación usando Bootstrap para nuestro index:
NOTA. Para cambiar estilos bootstrap debes eliminar la
clase bootstrap y poner una propia
CREANDO EL NAVBAR
<body>
<!--Navbar-->
<nav class="navbar
navbar-expand-sm bg-dark navbar-dark fixed-top">
<div class="container-fluid">
<a class="brand" href="#">STARS
CRUD</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse
navbar-collapse myNav" id="collapsibleNavbar">
<ul class="navbar-nav">
<li class="nav-item">
<a href="#">Link</a>
</li>
<li class="nav-item">
<a
href="#">Link</a>
</li>
<li class="nav-item">
<a
href="#">Link</a>
</li>
</ul>
</div>
</div>
</nav>
<!--end navbar-->
CLASES CSS PARA EL HEADER Y NAV
/*HEADER AND NAV CLASSES*/
.brand
{
color:
red;
text-decoration:
none;
font-weight:
bolder;
font-size:
1.5rem;
opacity:
1;
}
.brand:hover
{
transition:
0.8s ease all;
color:
var(--secondary)
}
.navbar-nav
{
padding-left:
50px;
}
.nav-item
{
padding-left:
20px;
}
.nav-item
a{
color:red;
text-decoration:
none;
font-weight:
bolder;
font-size:
1rem;
}
.nav-item
a:hover{
transition:
0.8s ease all;
color:
var(--secondary)
}
.custom-toggler .navbar-toggler-icon
{
background-image:
url("data:image/svg+xml;charset=utf8,%3Csvg
viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath
stroke='rgba(255,0,0, 1)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10'
d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E");
}
CREANDO LA SECCIÓN HEROE
<!-- Hero -->
<div class="p-5
text-center bg-image rounded-3 heroe">
<div class="mask">
<div class="d-flex
justify-content-center align-items-center">
<div class="text-white
heroe-title">
<h1 class="mb-3">STAR
CRUD</h1>
<h4 class="mb-3">May
the 4th be with you</h4>
<a class="btn
btn-outline-light btn-lg" href="#!" role="button">Do
or do not, there is no try</a>
</div>
</div>
</div>
</div>
<!-- Hero -->
CLASES PARA LA SECCIÓN HEROE
/*------HEROE CLASSES-----*/
.heroe
{
background-image:
url("../assets/mustafar.jpg");
background-position:
center;
background-size:
contain; /*Hace
que la imagen de fonde sea responsiva, cover no*/
background-repeat:
no-repeat;
background-color:
rgba(0,
0, 0,
0.6);
height:
100vh;
}
.heroe-title
{
padding-top:20%;
}
@media(min-width:
1400px) {
.heroe
{
background-size:
cover;
}
}
@media(min-width:
400px) {
.heroe
{
background-size:
cover;
}
}
<!--footer-->
<footer clas="footer
mt-auto py-3 bg-darck">
<div class="container">
<div class="row">
<div class="col-sm
line icon-f"><i class="fa-brands
fa-facebook-f fa-3x"></i></div>
<div class="col-sm
line icon-y"><i class="fa-brands
fa-youtube fa-3x"></i></div>
<div class="col-sm
line icon-i"><i class="fa-brands
fa-instagram fa-3x"></i></div>
</div>
</div>
</footer>
CLASES PARA EL FOOTER
/*------FOOTER CLASSES-----*/
footer
{
/*------FOOTER CLASSES-----*/
footer
{
width: 100%;
position:
absolute;
bottom:
0;
left: 0;
}
.footext {
color: red;
}
.icon-f,.icon-i,
.icon-y {
text-align:
center;
padding:
2%;
}
.icon-f i
{
color: #3b5998;
}
.icon-y i
{
color: #c4302b
}
.icon-i i
{
color: #3f729b;
}
BBDD
CREANDO LA BASE DE DATOS
Vamos a crear la base de datos
del proyecto como nuestra aplicación va a disponer de un sistema de login y
registro, lo primero que necesitaremos será crear una tabla para almacenar a
nuestros usuarios, posteriormente crearemos la tabla que contendrá los planetas
del universo star wars (no todos), y deberemos crear una tabla catálogo con las
regiones conocidas hasta el momento, ya que esta información es contante. De
forma que cuando queramos crear un planeta podamos seleccionar a qué región pertenece
desde un select.
Las regiones que forman el
universo star wars del canon son:
- Regiones desconocidas
- Borde medio
- Borde exterior
- Space Sauvage
- Space Hutt
- Zona de expansión
- Marco interior
- Colonias
- Mundos del núcleo
- Más allá del laberinto Rishi
TABLA USUARIOS
CREATE DATABASE
starDB;
USE starDB;
CREATE TABLE IF NOT EXISTS
users (
id int(11)
NOT NULL
AUTO_INCREMENT,
username varchar(30)
NOT NULL,
email varchar(30)
NOT NULL,
password varchar(30)
NOT NULL,
PRIMARY KEY
(id),
) ENGINE=MyISAM DEFAULT
CHARSET=utf8 AUTO_INCREMENT=3;
CREATE TABLE
planetas(
)ENGINE= MyISAM CHARSET=utf8;
TABLA PLANETAS
CREATE TABLE IF NOT EXISTS
planets (
name varchar(50)
NOT NULL,
description varchar(450)
NOT NULL,
region varchar(30)
NOT NULL,
system VARCHAR(30)
NOT NULL,
habitants VARCHAR(30),
capital city VARCHAR(30),
PRIMARY KEY
(name),
FULLTEXT INDEX
buscador (
name,
nombre ASC,
region ASC,
system ASC,
)
)ENGINE= MyISAM CHARSET=utf8;
TABLA CATÁLOGO regions
-- catalog table regions
CREATE TABLE
regions (
regionName VARCHAR(30)
NOT NULL,
PRIMARY KEY
(regionName)
)ENGINE= MyISAM CHARSET=utf8;
INSERT INTO
regions (regionName) VALUES
('Regiones desconocidas'),
('Borde medio'),
('Borde exterior'),
('Space Sauvage'),
('Space Hutt'),
('Zona de expansión'),
('Marco interior'),
('Colonias'),
('Mundos del núcleo'),
('Más allá del laberinto Rishi');
PRECARGA DE LA TABLA planets
INSERT INTO
planets(name,
description,
imgURL,
region,
system,
habitants,
capitalCity
) VALUES
("Coruscant",
"El sueño de los cosmopolitas: una inmensa gran
ciudad cubre este planeta del corazón de la galaxia (sus coordenadas de
navegación son 0-0-0).
Coruscant es la capital gubernamental y sede de
la República, del Senado Galáctico y del Consejo Jedi. Algunos de sus edificios
tienen kilómetros
de altura y entre ellos, circulan naves de todo
tipo a diferentes niveles.
Al sur de la ciudad están las Montañas Manarai
siempre cubiertas de nieve. Otros puntos de interés turístico de Coruscant son
las Grandes Torres,
los Jardines Botánicos del Domo, el Gran
Vestíbulo de Recepciones de un kilómetro de largo, la ciudad subterránea de
Dometown, el teatro Grandis Mon,
el Zoológico Holográfico de Animales
Extinguidos, el Museo Galáctico, la Universidad de Coruscant o el Edificio de
Operaciones de Seguridad Imperial.
El espacio que rodea el planeta está defendido
por estaciones de batalla orbitales Golan III y una instalación de puertos
estelares en órbita.
Durante los tiempos del Imperio, además,
protegían Coruscant dos capas de sofisticados campos de energía.
",
"planetacoruscant.jpg",
"Mundos del núcleo",
"coruscant",
"Muchos tipos",
"Ciudad Galáctica"
)
Abrimos nuestro phpmyadmin,
creamos la base de datos con el nombre starDB e importamos nuestro archivo
starDB.sql en ella:
CREANDO EL ARCHIVO dbacces.php (models)
El Archivo dbacces.php forma
parte del modelo de nuestra app. En él crearemos la clase modelo DBacces que és
una clase especializada en el acceso a la base de datos que centraliza todas
las peticiones y sentencias SQL de otras clases modelo.
<?php
/*
Clase DBacces especializada en el acceso a la BAse de
DAtos.
Centraliza todas las peticiones de sentencias SQL de
otras
clases modelo
*/
class DBaccess
{
//Propiedades privadas
que guardan los datos de conexión a la base de datos
private $db;
private $host;
private $user;
private $password;
/*La propia clase de
gestión de la base de datos guarda los objetos necesarios
para realizar esta conexión,
desde el programa externo que la use.
*/
private $connection;
//Conexión real con la base de datos
private $data;
//Datos reales retornados por una consulta exitosa
private $row;
//Una fila de los datos de la consulta realizada
//Constructor de la
clase, sireve para crear objetos de la clase
//debemos pasarle los
de conexión.
function __construct($host,
$user, $password,
$db) {
$this->db
= $db;
$this->host
= $host;
$this->user
= $user;
$this->password
= $password;
}
//Método que realiza
la conexión a la base de datos con los datos indicados en el constructor
public function connect_DB()
{
$res
= true;
$this->connection
= mysqli_connect($this->host,
$this->user,
$this->password,
$this->db);
//$this->connection
= mysqli_connect("stardb", "localhost", "root",
"");
//mysqli_set_charset($this->connection,
"utf-8");
if
(!$this->connection)
{
$res
= false;
die("No
se ha podido establecer la conexión con la base de datos. ERROR: ");
}
return $res;
}
//Desconectar de la
base de datos
public function disconnect_DB()
{
if(isset($this->connection))
{
mysqli_close($this->connection);
}
}
//Función anti ataques
SQL-Injection. Esta función retorna los datos que se le pasen
//filtrando carcteres
"peligrosos".
public function escape_data($data)
{
return mysqli_real_escape_string($this->connection,
$data);
}
/*
Ejecuta un SQL, ya sea SELECT (el
retorno del cuál será un dataset o insert), UPDATE o DELETE
que retorna true o false dependiendo de
si ha habido éxito o no.
Se da por hecho que la conexión se ha
realizado previamente, si el SQL es un SELECT, retornará
el conjunto global de resultados del
SELELECT.
Posteriormente se tendrá que usar la
función "consult_row" para obtener la primera fila (o posteriores)
de resultados
*/
public function consult_SQL($consult)
{
$this->data
= mysqli_query($this->connection,
$consult);
if(mysqli_errno($this->connection)
!= 0)
{
$res
= false;
} else{
$res
= true;
}
return $res;
}
//Función que obtiene
la fila de datos de una consulta previamente realizada. Retorna todos los datos
//de la fila para ser
consultados posteriormente con "consult_data"
public function consult_row()
{
$this->row
= null;
if($this->data
!= null)
{
$this->row
= mysqli_fetch_assoc($this->data);
}
return $this->row;
}
/*
Función que despues de consultar una
fila y dado el nombre de un campo de la consulta, retorna la data
del campo del registro actual. Tanto si
el nombre del campo no existe como si ya se han consultado todas
las filas del resultado, la función
devolverá NULL.
*/
public function consult_data($field)
{
$res
= null;
if
($this->row
!= null)
{
$res
= $this->row[$field];
}
return $res;
}
//Retorna el número de
filas involucradas en una consulta_SQL
public function affected_rows()
{
$res
= 0;
if($this->connection
!= null)
{
$res
= mysqli_affected_rows($this->connection);
}
return
($res);
}
//Elimina la memoria
asiciada a la última consulta realizada
public function consult_close()
{
mysqli_free_result($this->data);
}
//Retorna un eventual
mensaje de error producido en una consulta SQL
public function error_message()
{
$res
= "";
if(mysqli_errno($this->connection)
!= 0)
{
$res
= mysqli_error($this->connection);
}
return $res;
}
}
?>
MODELOS A CONSTRUIR (UNO POR CADA TABLA DE LA BASE DE DATOS)
STAR CRUD tiene 3 tablas users,
planets y regios. Pero regions es una tabla catálog que solo vamos a listar y
no a modificar por lo que solo tenemos que construir dos modelos Tusers y
Tplanets, vamos a nuestra carpeta models y creamos los archivos:
Modelo tusers
Observa que en azul, están los datos que recibiremos de la vista
formulario de registro, mientras que en verde están las credenciales necesarias
para la conexión a la base de datos que mandaremos desde tcontrol
Propiedades y constructor de
la clase Tusers:
<?php
include_once ("dbaccess.php");
class Tusers
{
//Propiedades privadas
private $username;
private $email;
private $password;
private $img;
private $dba;
//Constructor
function __construct($u_name, $u_email, $u_password,
$host, $user, $password, $db)
{
//Adquisición
de datos
$this->username
= $u_name;
$this->email
= $u_email;
$this->password
= $u_password;
}
//Destructor
function __destruct()
{
if(isset($this->dba))
{
unset($this->dba);
}
}
}
?>
LA VARIABLE $DBA
Necesitamos crear ahora una
variable que guarde una instancia de la clase dbaccess(payload) la podemos
llamar como queramos por ejemplo dba (database access) y llamada al método de
conexión de la clase dbacces, que guardaremos en la propiedad privada dba:
<?php
include_once ("dbaccess.php");
Class Tusers
{
//Propiedades privadas
private $username;
private $email;
private $password;
private $img;
private $dba;
//Constructor
function __consturctor($u_name,
$u_email, $u_password,
$u_img)
{
//Adquisición
de datos
$this->username
= $u_name;
$this->email
= $u_email;
$this->password
= $u_password;
$this->img
= $u_img;
//Instancia de la clase DBaccess y
llamada a su método connect_DB que guardamos en la propiedad dba.
$v_dba = new DBaccess ($db_name, $server, $user, $pass);
$this->dba = $v_dba;
$this->dba = connect_DB();
}
}
?>
Destructor del a clase Tuser
//Destructor
function __destruct()
{
if(isset($this->dba))
{
unset($this->dba);
}
}
Aquí debemos preguntarnos qué
métodos podemos necesitar para gestionar la tabla users dela base de datos, si
lo pensamos podemos necesitar las siguientes funciones:
·
Comprobar si un usuario existe
·
Registrar un nuevo usuario
·
Eliminar usuario
·
Método para login
·
Método para hacer logout
Comprobar si un usuario existe. Método user_exists
Este método realiza una consulta
a la base de datos usando el método de la clase dbaccess consult_SQL para
comprobar si el mail que hemos recibido vía formulario
register->gestionavista->tcontrol->hasta llegar aquí.
Consultamos a l abase d edatos si
ya existe ese mail, consult_SQL hace la consulta, consult_row consulta las
filas devueltas, si el numero de filas es mayor que 0 ese mail existe y la
función devuelve true, si no existe la función devuelve false. En el método
register que crearemos a continuación usaremos esta función para asegurarnos de
que no registramos un usuario con el mismo mail.
//Comprobar si existe
un usuario
public function user_exists()
{
$res
= false;
//consulta
usando el método consult_SQL de la clase dbaccess
if($this->dba->consult_SQL("
SELECT *
FROM users WHERE
email = '".
$this->email."'
"))
{
if($this->dba->consult_row()
> 0)
{
$res= true;
}
}
return $res;
}
//Registrar usuario
usuario
public function register()
{
$res
= false;
if(!($this->user_exists()))
//Uso user_exists para ver si existe un user co n ese
mail si no cargo el user
{
if($this->dba->consult_SQL("INSERT INTO
users ( username, email, password)VALUES(
'".$this->dba->escape_data($this->username)."',
'".$this->dba->escape_data($this->email)."',
'".$this->dba->escape_data($this->password)."')"))
{
//Alert js para lanzar mensaje y redirigir con js:
echo "<script
language='javascript'>
alert('Registered');
location='../index.php';
</script>";
//Lo mismo pero con php:
//$res = "<h2 class='successs'>El usuario
".$this->username." se ha registrado</h2>";
//redireccionar al index dando tiempo para que se vea
el mensaje
//header("Refresh:4;url=../index.php");
}
else
{
//Algo ha fallado en la conexión a la base de datos
echo "<script language='javascript'>
alert('Something were wrong :(');
location='../views/register.php';
</script>";
}
$res
= "<h2 class='successs'>El usuario ".$this->username."
se ha registrado</h2>";
}
echo "<script
language='javascript'>
alert('mail alredy exists,
please use another');
location='../views/register.php';
</script>";
return $res;
}
Como podemos ver el método
primero comprueba que el mail del usuario a registrar no exista usando el
método user_exisis que creamos anteriormente. Si el mail ya existe lanzamos un
alert javascript con el mensaje el mail ya existe y redirigimos al usuario de
vuelta al register, si no existe creamos una consulta a la base de datos usando
el método consult_SQL de la clase dbaccess, y hacemos un INSERT con los datos
recibidos vía
formulario register->gestionavista->tcontrol->hasta llegar aquí.
En este punto antes de continuar
creando los métodos que restan por crear, vamos a poner en práctica nuestro
método register. Para ello necesitamos crear los siguientes archivos:
·
Vista register.php: esta vista contendrá
el formulario de registro y enviará los datos del usuario a un controlador que
llamaremos gestionvista.
·
Controlador gestionvista.php: este
controlador recogerá los datos enviados en la vista register.php y creará una
instancia de la clase controlador
Tcontrol para usar su método userRegister(), que a su vez creará una
instancia de la clase tusers para por fin usar su método register() que es el
que insertará el nuevo usuario en la base de datos, usando métodos del modelo
dbaccess.
Vamos a ello primero creemos la
vista de registro register.php:
VISTA REGISTER.PHP
Vamos a nuestra carpeta views y
creamos un nuevo archivo que llamamos register.php
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<link rel="icon" type="image/jpg" href="assets/favicon.ico"/>
<title>STAR
CRUD</title>
<!--Bootstrap
cdn-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<!--Fontawesome
cdn-->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.1.2/css/fontawesome.min.css" integrity="sha384-X8QTME3FCg1DLb58++lPvsjbQoCT9bp3MsUU3grbIny/3ZwUJkRNO8NPW6zqzuW9" crossorigin="anonymous">
<!--Starwars Font
cdn-->
<link href="https://allfont.net/allfont.css?fonts=star-jedi" rel="stylesheet" type="text/css" />
<!--Mis
estilos-->
<link rel="stylesheet" href="../css/styles.css">
</head>
<body>
<!--Navbar-->
<nav class="navbar
navbar-expand-sm bg-dark navbar-dark fixed-top">
<div class="container-fluid">
<a class="brand" href="../index.php">STARS
CRUD</a>
<button class="navbar-toggler
custom-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse
navbar-collapse myNav" id="collapsibleNavbar">
<ul class="navbar-nav">
<li class="nav-item">
<a href="#"><i class="fa-solid
fa-user fa-2x"></i></i></a>
</li>
<li class="nav-item">
<a href="#">Link</a>
</li>
<li class="nav-item">
<a
href="#">Link</a>
</li>
</ul>
</div>
</div>
</nav>
<!--end navbar-->
<!-- Hero form -->
<!-- Hero -->
<div class="p-5
text-center rounded-3">
<div class="mask">
<div class="d-flex
justify-content-center align-items-center">
<!--Form-->
<form class="myform" name="user_frm" action="../controllers/gestionvista.php" method="post" enctype="multipart/form-data">
<div class="mb-3">
<label for="exampleInputname" class="form-label">User
name</label>
<input type="text" name="name_txt" class="form-control" id="exampleInputname" aria-describedby="nameHelp">
</div>
<div class="mb-3">
<label for="exampleInputEmail1" class="form-label">Email
address</label>
<input type="email" name="email_txt" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
<div id="emailHelp" class="form-text
cuote">We'll never share your email with anyone else.</div>
</div>
<div class="mb-3">
<label for="exampleInputPassword1" class="form-label">Password</label>
<input type="password" name="password_txt" class="form-control" id="exampleInputPassword1">
</div>
<button type="submit" name="nuevo_usuario_btn" class="btn btn-dark">Submit</button>
</form>
<!--End
form-->
</div>
</div>
</div>
<!-- Hero -->
<!--footer-->
<footer clas="footer
mt-auto py-3 bg-darck">
<div class="container">
<div class="row">
<div class="col-sm
line icon-f"><i class="fa-brands
fa-facebook-f fa-2x"></i></div>
<div class="col-sm
line icon-y"><i class="fa-brands
fa-youtube fa-2x"></i></div>
<div class="col-sm
line icon-i"><i class="fa-brands
fa-instagram fa-2x"></i></div>
</div>
</div>
</footer>
<!--Font awesome personal js-->
<script src="https://kit.fontawesome.com/1e88d8726f.js" crossorigin="anonymous"></script>
<!--Bootstrap js-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<!--Mis scripts JS-->
<script src="js/scripts.js"></script>
</body>
</html>
<button type="submit" name="nuevo_usuario_btn" class="btn btn-dark">Submit</button>
Para poder saber cuando se ha
hecho click en el botón de submit, es decir se ha enviado el formulario. Por
ultimo al mismo form, le hemos dado nombre , action que es donde indicamos qué
debe hacer el form con la información a donde debe enviarla y en nuestro caso
es al controlado gestión vista que vamos a crear a continuación:
<form class="myform" name="user_frm" action="../controllers/gestionvista.php" method="post" enctype="multipart/form-data">
Controlador gestionvista.php
Cuando el formularo de la vista
register.php envia los datos del usuario lo hace a este archivo
gestionvista.php, por tanto este es el controlador de la vista register, lo que
vamos a hacer aquí es recoger esos datos para enviarlos al controlador general
tcontrol, este tiene la capacidad de comunicarse directamente con cualquier
modelo. Ya sea tusers o tplanets, en este caso querremos comunicarnos con
tusers y usar algunos de sus métodos, veamos como:
<!DOCTYPE html>
<html lang="eS">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>STAR
CRUD</title>
</head>
<body>
<section>
<?php
header("Content-Type:
text/html;charset=utf-8");
include_once("tcontrol.php");
/*
Este es el controlador da la página rgister aquí
deberemos incluir el modelo tusers, es decir la clase que gestiona la
tabla users. Aquí recibiremos los datos de alta un
nuevo usuario y los trataremos tanto para la subida a
la BBDD, como para otras cosas.
*/
//Recogemos los datos del formulario por el nombre del
botón de submit name="nuevo_usuario_btn"
//es el submit del form, y los datos vienen por post,
es decir si existe la variable global es que
//se ha apretado el botón de submit
if(isset($_POST["nuevo_usuario_btn"]))
{
//Recogemos los datos
en variables, los cazamos por el nombre de input
$u_name = $_POST["name_txt"];
$u_email = $_POST["email_txt"];
$u_password = $_POST["password_txt"];
//creamos una instancia
del método userRegister() de tcontrol.php
//este metodo espera
el siguiente payload:
//public function
userRegister($u_name, $u_email, $u_password, $u_img)
$u_r = new Tcontrol();
$new_user = $u_r->userRegister($u_name, $u_email, $u_password);
}
?>
</section>
</body>
</html>
Como puedes ver usamos la función isset() de
php para saber si el botón submit de nombre nuevo_usuario_btn ha sido activado,
si es así accedemos a las variables globales $_POST[“nombre_del_input”] que se
ha creado de forma automática al enviar le form.
Recogemos esa información y la
guardamos en variables. Por ultimo creamos una instancia del controlador Tcontrol,
para poder usar su métodos userRegister() que está esperando como payload estos
datos que hemos recibido.
CREANDO EL CONTROLADOR Tcontrol.php
En la carpeta controles, vamos a
crear un nuevo archivo que llamaremos Tcontrol:
Este es el controlador que se
encargará de la relación entre la vistas y los modelos y donde vamos a crear el
método userRegister
que acabamos de crerar en gestiónvista.php, para ello lo primero es incluir en
este archivo los modelos de nuestras tablas. No es necesario incluir el modelo
dbaccess ya que será los modelos de cada tabla los que hablarán con ese modelo.
Como vamos aquí ya a tratar con
los datos que vienen de la vista es
importante añadir una cabecera con la codificación utf-8
<?php
header("Content-Type:
text/html;charset=utf-8");
//Clase de CONTROLADOR
include_once ("../models/tusers.php");
include_once ("../models/tplanets.php");
?>
IMPORTANTE: Es en este
controlador general donde vamos a establecer las credenciales para la conexión
con la base de datos. Ya que los métodos que vamos a crear aquí son instancias
de los métodos de los modelos tusers y tplanets, y además de enviar a esto
métodos como payload los datos recogidos en las vistas, también deberemos
enviar las credenciales de conexión a la base de datos que esos métodos de los
modelos requieren, veamoslo:
En el constructor definimos las credenciales de conexión
a la base de datos NOTA: ES IMPORTANTE
MANTENER EL ORDER: servidor, usuario, password, base de datos.
<?php
header("Content-Type:
text/html;charset=utf-8");
//Clase de CONTROLADOR
include_once ("../models/tusers.php");
include_once ("../models/tplanets.php");
class Tcontrol()
{
private $servidor;
private $usuario;
private $password;
private $base_datos;
function __construct()
{
$this->servidor
= "localhost";
$this->usuario
= "root";
$this->password
= "";
$this->base_datos
= "stardb";
}
}
?>
//______________________________Métodos__________________________
public function userRegister($u_name,
$u_email, $u_password)
{
/*
Creamos una instancia dela clase Tuser que
espera el siguiente payload:
function __consturctor($u_name,
$u_email, $u_password, $u_img, $db, $host, $user, $password)
donde los que empiezan por u_ son los datos que
vienen desdela vista (form) y el resto son las credenciales
para la conexión de la base de datos.
Es importante poner el payload en el orden que
la clase Tuser los espera recibir,
*/
$u
= new Tusers($u_name,
$u_email, $u_password,
$this->host,
$this->user,
$this->password,
$this->db);
//Invoco el método de
la clase Tuser register guardando la respuesta una variable
$res
= $u->register();
return $res;
}
Como puedes ver este método crea
una instancia de la clase Tusers (el modelo de la tabala users) y en el
payload, envía los datos recogidos del form pero además las credenciales de
conexión al método register de la clase Tusers.
Acuerdate que cuando creamos la
clase Tusersrecibíamos en el constructor, todo este payload:
Constructor de la clase Tusers:
class Tusers
{
//Propiedades privadas
private $username;
private $email;
private $password;
private $img;
private $dba;
//Constructor
function __construct($u_name, $u_email, $u_password, $host, $user, $password, $db)
{
//Adquisición
de datos
$this->username
= $u_name;
$this->email
= $u_email;
$this->password
= $u_password;
//Instancia
de la clase DBaccess y llamada a su método connect_DB que guardamos en la
propiedad dba.
$v_dba
= new DBaccess
($host, $user,
$password, $db);
//-----------------------------------------No está
llegando la info de credenciales FALLO 1
//$v_dba
= new DBaccess ('stardb','localhost','root','');
$this->dba
= $v_dba;
$this->dba->connect_DB();
//Guardo la conexiòn a la bbdd
Pongámoslo a prueba:
Vamos a la página register:
Si vamos a nuestra
base de datos y refrescamos veremos que en la tabla users se ha cargado nuestro
primer usuario
PONIENDO A PRUEBA NUESTRO
MÉTODO user_exists()
Ahora que ya tenemos un usuario
en nuestra base de datos, ¿Qué pasa si tratamos de registrarnos con el mismo
mail? Lo que debe ocurrir es que nuestro método user_exists, nos alertará de
que ya existe un usuario con ese mail y no cargará el nuevo usuario en la base
de datos, veamos si es cierto.
Intento registrarme con el mismo
mail:
El sistema nos alerta
de que el mail ya está en uso
Y si vamos a nuestra
base de datos podremos ver que no se ha cargado / duplicado el usuario. Por lo
tanto todo está funcionando correctamente.
No hay comentarios:
Publicar un comentario