Haremos una serie de modificaciones a nuestra aplicación del login a un sitio web, luego de haber visto la estructura fundamental en los conceptos anteriores, ésto nos servirá para identificar que partes de la aplicación se deben modificar.
Modificar el acceso a datos utilizando la librería PDO.
Hay que hacer cambios en todos los archivos que accedemos a datos de MySQL.
conexion.php<?php function retornarConexion() { $server="localhost"; $usuario="root"; $clave=""; $base="base1"; return new PDO("mysql:dbname=$base;host=$server", "$usuario","$clave", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); } ?>login.php
<?php require("conexion.php"); $pdo = retornarConexion(); $sql = $pdo->prepare("select nombre,clave from usuarios where nombre=:nombre and clave=:clave"); $sql->execute(array("nombre" => $_POST['usuario'], "clave" => $_POST['clave'])); if ($sql->rowCount() == 1) { session_start(); $_SESSION['usuario'] = $_POST['usuario']; echo "correcta"; } else { echo "incorrecta"; } ?>datosusuarios.php
<?php header('Content-Type: application/json'); require("conexion.php"); $pdo = retornarConexion(); switch ($_GET['accion']) { case 'agregar': $sql = $pdo->prepare("insert into usuarios(nombre,clave) values (:nombre,:clave)"); $resultado = $sql->execute(array( "nombre" => $_POST['nombrenuevo'], "clave" => $_POST['clave1'] )); echo json_encode($resultado); break; case 'existe': $sql = $pdo->prepare("select nombre from usuarios where nombre=:nombre"); $sql->execute(array("nombre" => $_POST['nombrenuevo'])); if ($sql->rowCount() == 1) echo '{"resultado":"repetido"}'; else echo '{"resultado":"norepetido"}'; break; } ?>index.php
<?php session_start(); if (!isset($_SESSION['usuario'])) { header("Location:login.html"); exit(0); } ?> <!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Calendario de Eventos</title> <link href="bootstrap-4.3.1/css/bootstrap.min.css" rel="stylesheet"> <link href="datatables/datatables.min.css" rel="stylesheet"> <link href="clockpicker/bootstrap-clockpicker.css" rel="stylesheet"> <link href="fullcalendar-4.3.1/packages/core/main.css" rel="stylesheet"> <link href="fullcalendar-4.3.1/packages/daygrid/main.css" rel="stylesheet"> <link href="fullcalendar-4.3.1/packages/timegrid/main.css" rel="stylesheet"> <link href="fullcalendar-4.3.1/packages/list/main.css" rel="stylesheet"> <link href="fullcalendar-4.3.1/packages/bootstrap/main.css" rel="stylesheet"> <script src="js/jquery-3.4.1.js"></script> <script src="js/popper.min.js"></script> <script src="bootstrap-4.3.1/js/bootstrap.min.js"></script> <script src="datatables/datatables.min.js"></script> <script src="clockpicker/bootstrap-clockpicker.js"></script> <script src='js/moment-with-locales.js'></script> <script src='fullcalendar-4.3.1/packages/core/main.js'></script> <script src='fullcalendar-4.3.1/packages/daygrid/main.js'></script> <script src='fullcalendar-4.3.1/packages/timegrid/main.js'></script> <script src='fullcalendar-4.3.1/packages/interaction/main.js'></script> <script src='fullcalendar-4.3.1/packages/list/main.js'></script> <script src='fullcalendar-4.3.1/packages/core/locales/es.js'></script> <script src='fullcalendar-4.3.1/packages/bootstrap/main.js'></script> </head> <body> <div class="container-fluid"> <section class="content-header"> <h1> <small>Panel de control de <strong><?php echo $_SESSION['usuario']; ?></strong></small> <small style="float:right"><a href="logout.php">Cerrar la sesión</a></small> </h1> </section> <div class="row"> <div class="col-10"> <div id="Calendario1" style="border: 1px solid #000;padding:2px"></div> </div> <div class="col-2"> <div id='external-events' style="margin-bottom:1em; height: 350px; border: 1px solid #000; overflow: auto;padding:1em"> <h4 class="text-center">Eventos predefinidos</h4> <div id='listaeventospredefinidos'> <?php require("conexion.php"); $pdo = retornarConexion(); $sql = $pdo->prepare("SELECT codigo,titulo,horainicio,horafin,colortexto,colorfondo FROM eventospredefinidosusuarios where usuario=:usuario"); $sql->execute(array( "usuario" => $_SESSION['usuario'] )); $ep = $sql->fetchAll(PDO::FETCH_ASSOC); foreach ($ep as $fila) echo "<div class='fc-event' data-titulo='$fila[titulo]' data-horafin='$fila[horafin]' data-horainicio='$fila[horainicio]' data-colorfondo='$fila[colorfondo]' data-colortexto='$fila[colortexto]' data-codigo='$fila[codigo]' style='border-color:$fila[colorfondo];color:$fila[colortexto];background-color:$fila[colorfondo];margin:10px'> $fila[titulo] [" . substr($fila['horainicio'], 0, 5) . " a " . substr($fila['horafin'], 0, 5) . "]</div>"; ?> </div> </div> <hr> <div style="text-align:center"><button type="button" id="BotonEventosPredefinidos" class="btn btn-success">Administrar eventos predefinidos</button> </div> </div> </div> </div> <!-- FormularioEventos --> <div class="modal fade" id="FormularioEventos" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <input type="hidden" id="Codigo"> <div class="form-row"> <div class="form-group col-md-12"> <label>Título del evento:</label> <input type="text" id="Titulo" class="form-control" placeholder=""> </div> </div> <div class="form-row"> <div class="form-group col-md-6"> <label>Fecha de inicio:</label> <div class="input-group" data-autoclose="true"> <input type="date" id="FechaInicio" value="" class="form-control" /> </div> </div> <div class="form-group col-md-6" id="TituloHoraInicio"> <label>Hora de inicio:</label> <div class="input-group clockpicker" data-autoclose="true"> <input type="text" id="HoraInicio" value="" class="form-control" autocomplete="off" /> </div> </div> </div> <div class="form-row"> <div class="form-group col-md-6"> <label>Fecha de fin:</label> <div class="input-group" data-autoclose="true"> <input type="date" id="FechaFin" value="" class="form-control" /> </div> </div> <div class="form-group col-md-6" id="TituloHoraFin"> <label>Hora de fin:</label> <div class="input-group clockpicker" data-autoclose="true"> <input type="text" id="HoraFin" value="" class="form-control" autocomplete="off" /> </div> </div> </div> <div class="form-group"> <label>Descripción:</label> <textarea id="Descripcion" rows="3" class="form-control"></textarea> </div> <div class="form-group"> <label>Color de fondo:</label> <input type="color" value="#3788D8" id="ColorFondo" class="form-control" style="height:36px;"> </div> <div class="form-group"> <label>Color de texto:</label> <input type="color" value="#ffffff" id="ColorTexto" class="form-control" style="height:36px;"> </div> </div> <div class="modal-footer"> <button type="button" id="BotonAgregar" class="btn btn-success">Agregar</button> <button type="button" id="BotonModificar" class="btn btn-success">Modificar</button> <button type="button" id="BotonBorrar" class="btn btn-success">Borrar</button> <button type="button" class="btn btn-success" data-dismiss="modal">Cancelar</button> </div> </div> </div> </div> <script> document.addEventListener("DOMContentLoaded", function() { $('.clockpicker').clockpicker(); let calendario1 = new FullCalendar.Calendar(document.getElementById('Calendario1'), { plugins: ['dayGrid', 'timeGrid', 'interaction'], height: 800, droppable: true, locale: 'es', showNonCurrentDates: false, header: { left: 'today,prev,next', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay' }, editable: true, events: 'datoseventos.php?accion=listar', dateClick: function(info) { limpiarFormulario(); $('#BotonAgregar').show(); $('#BotonModificar').hide(); $('#BotonBorrar').hide(); if (info.allDay) { $('#FechaInicio').val(info.dateStr); $('#FechaFin').val(info.dateStr); } else { let fechaHora = info.dateStr.split("T"); $('#FechaInicio').val(fechaHora[0]); $('#FechaFin').val(fechaHora[0]); $('#HoraInicio').val(fechaHora[1].substring(0, 5)); } $("#FormularioEventos").modal(); }, eventClick: function(info) { $('#BotonModificar').show(); $('#BotonBorrar').show(); $('#BotonAgregar').hide(); $('#Codigo').val(info.event.id); $('#Titulo').val(info.event.title); $('#Descripcion').val(info.event.extendedProps.descripcion); $('#FechaInicio').val(moment(info.event.start).format("YYYY-MM-DD")); $('#FechaFin').val(moment(info.event.end).format("YYYY-MM-DD")); $('#HoraInicio').val(moment(info.event.start).format("HH:mm")); $('#HoraFin').val(moment(info.event.end).format("HH:mm")); $('#ColorFondo').val(info.event.backgroundColor); $('#ColorTexto').val(info.event.textColor); $("#FormularioEventos").modal(); }, eventResize: function(info) { $('#Codigo').val(info.event.id); $('#Titulo').val(info.event.title); $('#FechaInicio').val(moment(info.event.start).format("YYYY-MM-DD")); $('#FechaFin').val(moment(info.event.end).format("YYYY-MM-DD")); $('#HoraInicio').val(moment(info.event.start).format("HH:mm")); $('#HoraFin').val(moment(info.event.end).format("HH:mm")); $('#ColorFondo').val(info.event.backgroundColor); $('#ColorTexto').val(info.event.textColor); $('#Descripcion').val(info.event.extendedProps.descripcion); let registro = recuperarDatosFormulario(); modificarRegistro(registro); }, eventDrop: function(info) { $('#Codigo').val(info.event.id); $('#Titulo').val(info.event.title); $('#FechaInicio').val(moment(info.event.start).format("YYYY-MM-DD")); $('#FechaFin').val(moment(info.event.end).format("YYYY-MM-DD")); $('#HoraInicio').val(moment(info.event.start).format("HH:mm")); $('#HoraFin').val(moment(info.event.end).format("HH:mm")); $('#ColorFondo').val(info.event.backgroundColor); $('#ColorTexto').val(info.event.textColor); $('#Descripcion').val(info.event.extendedProps.descripcion); let registro = recuperarDatosFormulario(); modificarRegistro(registro); }, drop: function(info) { limpiarFormulario(); $('#ColorFondo').val(info.draggedEl.dataset.colorfondo); $('#ColorTexto').val(info.draggedEl.dataset.colortexto); $('#Titulo').val(info.draggedEl.dataset.titulo); let fechaHora = info.dateStr.split("T"); $('#FechaInicio').val(fechaHora[0]); $('#FechaFin').val(fechaHora[0]); if (info.allDay) { //verdadero si el calendario esta en vista de mes $('#HoraInicio').val(info.draggedEl.dataset.horainicio); $('#HoraFin').val(info.draggedEl.dataset.horafin); } else { $('#HoraInicio').val(fechaHora[1].substring(0, 5)); $('#HoraFin').val(moment(fechaHora[1].substring(0, 5)).add(1, 'hours')); } let registro = recuperarDatosFormulario(); agregarEventoPredefinido(registro); } }); calendario1.render(); new FullCalendarInteraction.Draggable(document.getElementById('listaeventospredefinidos'), { itemSelector: '.fc-event', eventData: function(eventEl) { return { title: eventEl.innerText.trim() } } }); //Eventos de botones de la aplicación $('#BotonAgregar').click(function() { let registro = recuperarDatosFormulario(); agregarRegistro(registro); $("#FormularioEventos").modal('hide'); }); $('#BotonModificar').click(function() { let registro = recuperarDatosFormulario(); modificarRegistro(registro); $("#FormularioEventos").modal('hide'); }); $('#BotonBorrar').click(function() { let registro = recuperarDatosFormulario(); borrarRegistro(registro); $("#FormularioEventos").modal('hide'); }); $('#BotonEventosPredefinidos').click(function() { window.location = "eventospredefinidos.php"; }); // funciones para comunicarse con el servidor via ajax function agregarRegistro(registro) { $.ajax({ type: 'POST', url: 'datoseventos.php?accion=agregar', data: registro, success: function(msg) { calendario1.refetchEvents(); }, error: function(error) { alert("Hay un problema:" + error); } }); } function modificarRegistro(registro) { $.ajax({ type: 'POST', url: 'datoseventos.php?accion=modificar', data: registro, success: function(msg) { calendario1.refetchEvents(); }, error: function(error) { alert("Hay un problema:" + error); } }); } function borrarRegistro(registro) { $.ajax({ type: 'POST', url: 'datoseventos.php?accion=borrar', data: registro, success: function(msg) { calendario1.refetchEvents(); }, error: function(error) { alert("Hay un problema:" + error); } }); } function agregarEventoPredefinido(registro) { $.ajax({ type: 'POST', url: 'datoseventos.php?accion=agregar', data: registro, success: function(msg) { calendario1.removeAllEvents(); calendario1.refetchEvents(); }, error: function(error) { alert("Hay un problema:" + error); } }); } // funciones que interactuan con el formulario de entrada de datos function limpiarFormulario() { $('#Codigo').val(''); $('#Titulo').val(''); $('#Descripcion').val(''); $('#FechaInicio').val(''); $('#FechaFin').val(''); $('#HoraInicio').val(''); $('#HoraFin').val(''); $('#ColorFondo').val('#3788D8'); $('#ColorTexto').val('#ffffff'); } function recuperarDatosFormulario() { let registro = { codigo: $('#Codigo').val(), titulo: $('#Titulo').val(), descripcion: $('#Descripcion').val(), inicio: $('#FechaInicio').val() + ' ' + $('#HoraInicio').val(), fin: $('#FechaFin').val() + ' ' + $('#HoraFin').val(), colorfondo: $('#ColorFondo').val(), colortexto: $('#ColorTexto').val() }; return registro; } }); </script> </body> </html>datoseventos.php
<?php header('Content-Type: application/json'); session_start(); require("conexion.php"); $pdo = retornarConexion(); switch ($_GET['accion']) { case 'listar': $sql = $pdo->prepare("select codigo as id, titulo as title, descripcion, inicio as start, fin as end, colortexto as textColor, colorfondo as backgroundColor from eventosusuarios where usuario=:usuario"); $sql->execute(array( "usuario" => $_SESSION['usuario'] )); $resultado = $sql->fetchAll(PDO::FETCH_ASSOC); echo json_encode($resultado); break; case 'agregar': $sql = $pdo->prepare("insert into eventosusuarios(titulo,descripcion,inicio,fin,colortexto,colorfondo,usuario) values (:titulo,:descripcion,:inicio,:fin,:colortexto,:colorfondo,:usuario)"); $resultado = $sql->execute(array( "titulo" => $_POST['titulo'], "descripcion" => $_POST['descripcion'], "inicio" => $_POST['inicio'], "fin" => $_POST['fin'], "colortexto" => $_POST['colortexto'], "colorfondo" => $_POST['colorfondo'], "usuario" => $_SESSION['usuario'] )); echo json_encode($resultado); break; case 'modificar': $sql = $pdo->prepare("update eventosusuarios set titulo=:titulo, descripcion=:descripcion, inicio=:inicio, fin=:fin, colortexto=:colortexto, colorfondo=:colorfondo where codigo=:codigo"); $resultado = $sql->execute(array( "titulo" => $_POST['titulo'], "descripcion" => $_POST['descripcion'], "inicio" => $_POST['inicio'], "fin" => $_POST['fin'], "colortexto" => $_POST['colortexto'], "colorfondo" => $_POST['colorfondo'], "codigo" => $_POST['codigo'] )); echo json_encode($resultado); break; case 'borrar': $sql = $pdo->prepare("delete from eventosusuarios where codigo=:codigo"); $resultado = $sql->execute(array( "codigo" => $_POST['codigo'] )); echo json_encode($resultado); break; }datoseventospredefinidos.php
<?php header('Content-Type: application/json'); session_start(); require("conexion.php"); $pdo = retornarConexion(); switch ($_GET['accion']) { case 'listar': $sql = $pdo->prepare("select codigo,titulo,horainicio,horafin,colortexto,colorfondo from eventospredefinidosusuarios where usuario=:usuario"); $sql->execute(array("usuario" => $_SESSION['usuario'])); $resultado = $sql->fetchAll(PDO::FETCH_ASSOC); echo json_encode($resultado); break; case 'agregar': $sql = $pdo->prepare("insert into eventospredefinidosusuarios(titulo,horainicio,horafin,colortexto,colorfondo,usuario) values (:titulo,:horainicio,:horafin,:colortexto,:colorfondo,:usuario)"); $resultado = $sql->execute(array( "titulo" => $_POST['titulo'], "horainicio" => $_POST['horainicio'], "horafin" => $_POST['horafin'], "colortexto" => $_POST['colortexto'], "colorfondo" => $_POST['colorfondo'], "usuario" => $_SESSION['usuario'] )); echo json_encode($resultado); break; case 'borrar': $sql = $pdo->prepare("delete from eventospredefinidosusuarios where codigo=:codigo"); $resultado = $sql->execute(array( "codigo" => $_POST['codigo'] )); echo json_encode($resultado); break; } ?>
No sufren cambios los archivos: login.html, logout.php y eventospredefinidos.php.