administración de proyectos - uv.mx · facultad de estadística e informática patrón de mvc mvc...

Post on 20-Sep-2018

229 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Facultad de Estadística e Informática

Administración de Proyectos

Facultad de Estadística e Informática

Proyecto Final

NOVIEMBRE 2017

Facultad de Estadística e Informática

Administración de Proyectos

Facultad de Estadística e Informática

Facultad de Estadística e Informática

Administración de Proyectos

Facultad de Estadística e Informática

Proyecto Final◦Patrón de arquitectura Modelo Vista Controlador

◦Paradigma Orientado a Objetos

Facultad de Estadística e Informática

¿Qué es MVC?

◦ Patrón de arquitectura de software que separa el modelo, la interfaz de usuario y el control de la lógica de una aplicación, en tres distintos componentes.

◦ Presentado por Trygve Reenskaug en 1979 para el Framework Smalltalk (utilizada para crear las interfaces de Apple Lisa y Macintosh).

Modelo

VistaControlador

Facultad de Estadística e Informática

Patrón de MVC

◦MVC propone la construcción de tres distintos componentes:

1. Modelo

2. Vista

3. Controlador

Modelo

VistaControlador

ACTUALIZA MANIPULA

MUESTRA UTILIZA

Facultad de Estadística e Informática

Patrón de MVC

El modelo

Representación de los datosLógica del negocioObtiene y almacena datos en un almacenamiento persistente(Base de Datos)

La vista

Interfaz de usuario a partir del modeloElementos de interacción(HTML, XML)

El controlador

Maneja la interacción con el usuario e invoca cambios al Modelo y Vistas.Intermediario entre el Modelo y la Vista.

Facultad de Estadística e Informática

Jerarquía de dependencia en MVC

El modelo

El Modelo solo conoce sobre el mismo.Esto quiere decir, que el código fuente del Modelo no hace referencias ni a la Vista o al Controlador.

La vista

La Vista si conoce al Modelo. Preguntará al Modelo sobre su estado para saber que mostrar.De esta manera, la Vista puede desplegar algo que esta basado en lo que el Modelo ha hecho.La Vista no sabe nada del Controlador.

El controlador

Conoce al Modelo y a la Vista.Si el usuario realiza una acción, el Controlador sabe que función en el Modelo llamar y también sabe que Vista mostrar al usuario.

Facultad de Estadística e Informática

Flujo de MVC

1. El usuario realiza una acción en la interfaz (ej. presiona un botón)

2. El Controlador toma el evento o acción de entrada

3. El Controlador notifica la acción al Modelo, la cuál pudiera involucrar un cambio en el Modelo (ej. edición de datos).

4. Esto genera una nueva Vista que se envía al usuario. La Vista toma los datos del Modelo (ej. lista de usuarios).

5. La interfaz de usuario espera por otra interacción de usuario, lo que inicia un nuevo ciclo.

Facultad de Estadística e Informática

Modelado de la Base de Datos

Facultad de Estadística e Informática

Crear el modelo de BD

Facultad de Estadística e Informática

Requerimientos de software▪ MySQL. https://www.mysql.com/.

▪ MySQL Community Edition▪ MySQL Community Server 5.7.20

▪ PHP versión 7▪ Apache o Internet Information Services (IIS)

Facultad de Estadística e Informática

Requerimientos de softwareBiblioteca multiplataforma de JavaScript. JQuery.

◦ http://jquery.com/download/

Framework de diseño. Bootstrap.◦ https://getbootstrap.com/docs/3.3/

Plugin de validación de formularios. jQuery Validation Plugin.◦ https://github.com/jquery-validation/jquery-validation/releases/tag/1.17.0

Framework de autenticación para PHP. PHP-Auth.◦ https://github.com/delight-im/PHP-Auth

Composer. Administrador de dependencias para PHP.◦ https://getcomposer.org/download/

Google Maps◦ https://developers.google.com/maps/documentation/javascript/tutorial

JQuery Location Picker◦ https://github.com/Logicify/jquery-locationpicker-plugin

Dropzone◦ https://gitlab.com/meno/dropzone

Iconos Font Awesome◦ http://fontawesome.io/get-started/

FancyBox◦ http://fancyapps.com/fancybox/3/

Facultad de Estadística e Informática

Facultad de Estadística e Informática

Importar JQuery<!-- JQuery --><script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

http://jquery.com/download/

Servicio de Red de Entrega de Contenido Global (CDN)

Facultad de Estadística e Informática

Importar Bootstrap

<!-- Bootstrap --><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

https://getbootstrap.com/docs/3.3/

Facultad de Estadística e Informática

Importar jQuery Validation Plugin

Descargar

Descomprimir e importar la carpeta “dist” con el nombre “jqueryvalidation”.

<!-- JQuery Validation --><script src="../jqueryvalidation/jquery.validate.js"></script>

<script>$("form").validate();</script>

https://github.com/jquery-validation/jquery-validation/releases/tag/1.17.0

Facultad de Estadística e Informática

Instalar Composerhttps://getcomposer.org/download/

Instalar en la carpeta de PHP

En Windows, reiniciar la computadora

Facultad de Estadística e Informática

PHP-AuthTener instalado Composer y haber reiniciado la computadora

Abrir una ventana de comandos y ubicarse en el directorio

del Proyecto Final

Instalar PHP-Auth vía Composer

Crear las tablas de PHP-Auth

> composer require delight-im/auth

https://github.com/delight-im/PHP-Auth/blob/master/Database/MySQL.sql

https://github.com/delight-im/PHP-Auth

Facultad de Estadística e Informática

PHP-AuthCrear las tablas de PHP-Auth

https://github.com/delight-im/PHP-Auth/blob/master/Database/MySQL.sql

Facultad de Estadística e Informática

Google MapsObtener una clave válida:https://developers.google.com/maps/documentation/javascript/get-api-key#key

Facultad de Estadística e Informática

JQuery Location PickerDescargar: https://github.com/Logicify/jquery-locationpicker-plugin

Descomprimir e importar la carpeta “dist” con el nombre “jquerylocationpicker”.

Facultad de Estadística e Informática

JQuery Location Picker¿Cómo se usa?

<script>$('#us2').locationpicker({location: { latitude: $("#latitud").val(), longitude: $("#longitud").val() },radius: 300,inputBinding: {latitudeInput: $('#latitud’),longitudeInput: $('#longitud’),radiusInput: null,locationNameInput: $('#direccion')

},enableAutocomplete: true,enableReverseGeocode: true

});</script>

<!-- JQuery Location Picker --><scriptsrc="../js/jquerylocationpicker/locationpicker.jquery.js"></script>

Facultad de Estadística e Informática

DropzoneDescargar: https://gitlab.com/meno/dropzone

Descomprimir e importar la carpeta “dist” con el nombre “dropzone”.

<!-- Dropzone --><link href="js/dropzone/dropzone.css" rel="stylesheet" type="text/css" /><script src="js/dropzone/dropzone.js"></script><!-- Mi Dropzone --><link href="js/midropzone/midropzone.css" rel="stylesheet" type="text/css" /><script src="js/midropzone/midropzone.js"></script>

<script>DropzoneFotografia = IniciaDropzone('.fotografia-dropzone', EXTENSIONESIMAGEN, MAXNUMFILES, MAXIMAGESIZE, FOTOGRAFIA);</script>

Facultad de Estadística e Informática

Font Awesome CDN

<!-- Font Awesome --><link rel="stylesheet" href="js/font-awesome/css/font-awesome.min.css">

Facultad de Estadística e Informática

FancyBox

<!-- Fancybox --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.2.1/jquery.fancybox.min.css" /><script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.2.1/jquery.fancybox.min.js"></script>

Programación

Facultad de Estadística e Informática

MVC

index.php

controladores

modelos

vistas

Facultad de Estadística e Informática

Estructura de directoriosconfig: aquí irán los archivos de configuración de la base de datos, globales, etc.

controladores: como sabemos en la arquitectura MVC los controladores se encargarán de recibir y filtrar datos que le llegan de las vistas, llamar a los modelos y pasar los datos de estos a las vistas. Pues en este directorio colocaremos los controladores

nucleo: aquí colocaremos las clases base de las que heredarán por ejemplo controladores y modelos, y también podríamos colocar más librerías hechas por nosotros o por terceros, esto sería el núcleo del framework.

modelos: aquí irán los modelos, para ser fieles al paradigma orientado objetos tenemos que tener una clase por cada tabla o entidad de la base de datos(excepto para las tablas pivote) y estas clases servirán para crear objetos de ese tipo de entidad(por ejemplo crear un objeto usuario para crear un usuario en la BD). También tendremos modelos de consulta a la BD que contendrán consultas más complejas que estén relacionadas con una o varias entidades.

vistas: aquí irán las vistas, es decir, donde se imprimirán los datos y lo que verá el usuario.

index.php será el controlador frontal por el que pasará absolutamente todo en la aplicación.

Facultad de Estadística e Informática

Crear archivos de configuración

En el directorio config, crearemos un archivo database.php en el que irá la configuración de la base de datos. Este devuelve un array que posteriormente utilizaremos.

<?phpreturn array("driver" => "mysql","host" => “localhost","user" => "proyectofinal","pass" => "P4ssw0rd","database" => "proyectofinal","charset" => "utf8mb4");

Facultad de Estadística e Informática

Crear archivos de configuraciónTambién podemos crear un archivo global.php en el que irán constantes que luego nos servirán, por ejemplo para establecer controladores y acciones por defecto (y todo lo que queramos agregarle).

Y también un archivo auth.php donde se preguntará si el usuario esta logueado.

<?phpdefine("TITULO", "Proyecto Final 2017");define("SUBTITULO", "Sistemas Web");define("CONTROLADOR_DEFECTO", "Home");define("ACCION_DEFECTO", "index");define("UPLOADS_DIR", "uploads");?>

<?phpif ($auth->isLoggedIn()) {// Usuario válido}else {// Usuario no válido// Redirecciona al loginheader("Location: login.php");exit;}

Facultad de Estadística e Informática

Crear las clases del núcleo

Primero crearemos la clase Conectar que nos servirá para conectarnos a la base de datos utilizando el driver PDO.

<?phpclass Conectar {private $driver;private $host, $user, $pass, $database, $charset;public function __construct() {// Regresa un arreglo$db_cfg = require_once 'config/Database.php';$this->driver = $db_cfg["driver"];$this->host = $db_cfg["host"];$this->user = $db_cfg["user"];$this->pass = $db_cfg["pass"];$this->database = $db_cfg["database"];$this->charset = $db_cfg["charset"];}public function conexion() { $con = new \PDO("{$this->driver}:dbname={$this->database};host={$this->host};charset={$this->charset}", $this->user, $this->pass);return $con;}}?>

Facultad de Estadística e Informática

Crear las clases del núcleo

Seguimos creando el archivo EntidadBase.php de esta clase heredarán los modelos que representen entidades, en el constructor le pasaremos el nombre de la tabla y tendremos tantos métodos como queramos para ayudarnos con las peticiones a la BD a través de los objetos que iremos creando. La ventaja es que estos métodos pueden ser reutilizados en otras clases ya que le indicamos la tabla en el constructor.

<?phpclass EntidadBase {protected $db;protected $conectar; public function __construct( $adapter ) {$this->conectar = null;$this->db = $adapter;}public function getConectar(){return $this->conectar;}public function db() {return $this->db;}}?>

Facultad de Estadística e Informática

Crear las clases del núcleo

La siguiente clase que crearemos es ControladoresBasede la cual heredarán los controladores, esta clase carga EntidadesBase, ModelosBase, y todos los modelos creados dentro del directorio model.

<?phpclass ControladorBase {public $auth;public $conectar;public $adapter;

public function __construct() {require_once 'Conectar.php';require_once 'EntidadBase.php';require_once join( DIRECTORY_SEPARATOR, array( 'vendor', 'autoload.php' ) );//Incluir todos los modelosforeach( glob( "modelos/*.php" ) as $file ){require_once $file;}}

/** Este método lo que hace es recibir los datos del controlador en forma de array* los recorre y crea una variable dinámica con el indice asociativo y le da el * valor que contiene dicha posición del array, luego carga los helpers para las* vistas y carga la vista que le llega como parámetro. En resumen un método para* renderizar vistas.*/public function view( $vista, $datos = null ) {foreach ($datos as $id_assoc => $valor) {${$id_assoc} = $valor; }require_once 'AyudaVistas.php';$helper = new AyudaVistas();require_once join( DIRECTORY_SEPARATOR, array( 'vistas', "{$vista}View.php" ) );}

public function getJsonRequest() {$content = file_get_contents( "php://input" );if ( $content === false ) {http_response_code( 400 );exit( 'Invalid request.' );}$obj = json_decode( $content );return $obj;}

public function json( $response ) {header("Content-Type: application/json");echo json_encode( $response );}public function redirect( $controlador = CONTROLADOR_DEFECTO, $accion = ACCION_DEFECTO, $params = '' ) {header( "Location:index.php?controller={$controlador}&action={$accion}" . $params );exit();}

public function ObtenPerfil() { if ( $this->auth->isLoggedIn() ) {// Usuario válido}else {// Usuario no válido// Redirecciona al login$this->redirect( "login" );}}}?>

Facultad de Estadística e Informática

Crear las clases del núcleo

Ahora crearemos la clase AyudaVistas que puede contener diversos helpers (pequeños métodos que nos ayuden en pequeñas tareas dentro de las vistas).

<?phpclass AyudaVistas{public function url( $controlador = CONTROLADOR_DEFECTO, $accion = ACCION_DEFECTO ){$urlString = "index.php?controller={$controlador}&action={$accion}";return $urlString;}

public function imagen_url( $nombre ){$urlString = UPLOADS_DIR . '/' . $nombre;return $urlString;}

public function print_row( &$item ) {echo('<tr>');echo('<td>');echo(implode('</td><td>', $item));echo('</td>');echo('</tr>');}}?>

Facultad de Estadística e Informática

Crear las clases del núcleo

Ahora crearemos el archivo ControladorFrontal.func.php que tiene las funciones que se encargan de cargar un controlador u otro y una acción u otra en función de lo que se le diga por la url.

<?php//FUNCIONES PARA EL CONTROLADOR FRONTALfunction cargarControlador( $controller ){$controlador = ucwords( $controller ) . 'Controller';$strFileController = join( DIRECTORY_SEPARATOR, array( 'controladores', "{$controlador}.php" ) );if( ! is_file( $strFileController ) ){$strFileController = join( DIRECTORY_SEPARATOR, array( 'controladores', ucwords( CONTROLADOR_DEFECTO ), 'Controller.php' ) );}require_once join( DIRECTORY_SEPARATOR, array( __DIR__, '..', $strFileController ) );$controllerObj = new $controlador();return $controllerObj;}function cargarAccion( $controllerObj, $action ) {$accion = $action;$controllerObj->$accion();}function lanzarAccion( $controllerObj ) {if( isset( $_GET["action"] ) && method_exists( $controllerObj, $_GET["action"] ) ) {cargarAccion( $controllerObj, $_GET["action"] );} else {cargarAccion( $controllerObj, ACCION_DEFECTO );}}?>

Facultad de Estadística e Informática

El controlador frontal index.phpEl controlador frontal es donde se cargan todos los archivos de la aplicación y por tanto la única pagina que visita el usuario realmente es esta, en este caso index.php.

<?php//Configuración globalrequire_once 'config/Global.php';//Base para los controladoresrequire_once 'nucleo/ControladorBase.php';//Funciones para el controlador frontalrequire_once 'nucleo/ControladorFrontal.func.php';//Cargamos controladores y accionesif( isset( $_GET["controller"] ) ) {$controllerObj = cargarControlador( $_GET["controller"] );lanzarAccion( $controllerObj );} else {$controllerObj = cargarControlador( CONTROLADOR_DEFECTO );lanzarAccion( $controllerObj );}?>

Facultad de Estadística e Informática

Modelos y objetos

Si queremos seguir el paradigma de la programación orientada a objetos teóricamente deberíamos tener una clase por cada tabla de la base de datos(excepto tablas pivote) que haga referencia a un objeto de la vida real, en este caso el objeto que crearíamos seria “Usuario” y el usuario tendría un nombre, un apellido, un email, etc, pues bien eso serian los atributos del objeto y tendríamos un método get y set por cada atributo que servirán para establecer el valor de las propiedades y para conseguir el valor de cada atributo.

<?phpclass Usuario extends EntidadBase {public function __construct( $adapter ) {parent::__construct( $adapter );}

public function getAll() {// Preparar$stmt = $this->db->prepare("select * from users");

// ejecutar la consulta$stmt->execute();// ligar variables de resultadoif( $filas = $stmt->fetchAll(PDO::FETCH_ASSOC) ) {$resultSet = $filas;}return $resultSet;}

public function getUsuario( $userid ) {// Preparar$stmt = $this->db->prepare("select * from users where id = :userid");$stmt->bindParam( ':userid', $userid );// Asigna valores$userid = $userid;

// ejecutar la consulta$stmt->execute();// ligar variables de resultado$resultSet = null;if( $resultSet = $stmt->fetch(PDO::FETCH_ASSOC) ) {if( $stmt->rowCount() > 0 )return $resultSet;}return null;}}?>

Facultad de Estadística e Informática

Modelos y objetos

Crear los modelos:◦ Comentario

◦ MeGusta

◦ Seguir

◦ Usuario

<?phpclass Comentario extends EntidadBase {private $id;private $userid;private $imagenid;private $titulo;private $cuerpo;private $fecha;public function __construct( $adapter ) {parent::__construct( $adapter );}public function setId($id) {$this->id = $id;}

public function setUserId($userid) {$this->userid = $userid;}public function setImagenId($imagenid) {$this->imagenid = $imagenid;}

public function setTitulo($titulo) {$this->titulo = $titulo;}

public function setCuerpo($cuerpo) {$this->cuerpo = $cuerpo;}

public function setFecha($fecha) {$this->fecha = $fecha;}

public function getAll( $imagenid ) {// Preparar$stmt = $this->db->prepare("select comentarios.*, users.email, users.usernamefrom comentarios inner join users on comentarios.userid = users.id where comentarios.imagenid = :imagenid order bycomentarios.id desc");$stmt->bindParam( ':imagenid', $imagenid );// Asigna valores$imagenid = $imagenid;}}?>

Facultad de Estadística e Informática

Los controladoresLos crearemos en el directorio controller con el sufijo Controller.

◦ BotonesController

◦ ComentariosController

◦ HomeController

◦ LoginController

◦ MiGaleriaController

◦ RegistroController

◦ RegistroController

◦ SiguiendoController

◦ UploadController

◦ UsuarioController

<?phpclass BotonesController extends ControladorBase {public function __construct() {parent::__construct();

// Conectar a BD$this->conectar = new Conectar();$this->adapter = $this->conectar->conexion();

// Carga Auth$this->auth = new \Delight\Auth\Auth( $this->adapter );$this->ObtenPerfil();}

public function nuevo() { //Cargamos la vista index y le pasamos valores$this->view( "NuevaImagen" , array("menu" => 'Mi galería'));}

public function botoncomentarios() {$obj = $this->getJsonRequest();

$boton = '<i class="fa fa-comment-o"></i> Comentarios';

// Contadorif ( !empty( $obj->id ) ) {//Creamos el objeto$comentario = new Comentario( $this->adapter );$boton .= ' <span class="badge">' . $comentario->Cuenta( $obj->id ) . '</span>';}

$response = array('boton' => $boton);

$this->json ( $response );}public function botonmegusta() {$obj = $this->getJsonRequest();

Código incompleto…Ver código fuente…

Facultad de Estadística e Informática

Las vistasLos crearemos en el directorio vistas con el sufijo View.

◦ _Comentario

◦ _Encabezado

◦ _FichaView

◦ _Menu

◦ _NuevoComentario

◦ _Pie

◦ Busqueda

◦ Detalles

◦ Home

◦ Login

◦ MiGaleria

◦ NuevaImagen

◦ Populares

◦ Registro

◦ Seguidores

◦ Seguiendo

◦ Usuarios

<?php// Incluye Encabezadorequire_once '_Encabezado.php';?>

<div class="container"><h3 class="text-center">Más recientes</h3><p>Listado de hasta 10 imágenes más recientes.</p>

<?php if( isset( $allimagenes ) && count( $allimagenes ) > 0 ) :$totalcont = count( $allimagenes ); ?><p class="text-primary">Mostrando <?php echo $totalcont; ?> elementos</p><div class="cuadros flex-row row"><?php foreach( $allimagenes as $imagen ) {echo '<div class="col-lg-4 col-md-4 col-sm-12 col-xs-12">';require '_FichaView.php';echo '</div>';} ?></div><?php else: ?><div class="alert alert-info" role="alert"><p>No se han encontrado imágenes.</p></div><?php endif; ?></div>

<?php// Incluye el pierequire_once '_Pie.php';?>

Facultad de Estadística e Informática

Para acceder a otros controladores y acciones por la url

Se usa el parámetro:◦ Controller. Nombre del controlador (clase).

◦ Action. Nombre de la acción (función dentro de la clase).

Facultad de Estadística e Informática

Archivos de soporte

Tenemos las carpetas◦ Css. Estilos del sistema.

◦ Uploads. Donde se guardaran las imágenes.

◦ Js. Scripts de cliente de apoyo.

// Variables globalesvar MAXNUMFILES = 1;var MAXIMAGESIZE = 1;var EXTENSIONESIMAGEN = ".jpg,.png,.pdf";var FOTOGRAFIA = 1;

// Funciones Globales$(document).ready(function () {MenuSistema();});

function MenuSistema() {// Activa el menu actual$(".navbar-nav li:contains('" + $('.menu-activo').text() + "')").addClass('active');}

function DibujaComentarios( boton, id ) {var url = "index.php?controller=botones&action=botoncomentarios";var method = "POST";var data = { id: id };ajaxHelper(url, method, data).done(function (data, status, jqXHR) {$(boton).html( data.boton );});}

function DibujaMeGusta( boton, id ) {var url = "index.php?controller=botones&action=botonmegusta";var method = "POST";var data = { id: id };ajaxHelper(url, method, data).done(function (data, status, jqXHR) {$(boton).html( data.boton );$(boton).click(function(){ ClicMeGusta( boton, id );});});}

Facultad de Estadística e Informática

Uso de llamadas asíncronas con AJAX

Para las acciones de “Me gusta” y “Seguir”, se utilizan llamadas asíncronas a acciones de controladores por medio de AJAX.

Se hace uso de la función Ajax() de la biblioteca Jquery.

// Funcion para llamadas Ajax

function ajaxHelper(uri, method, data) {return $.ajax({type: method,url: uri,dataType: 'json',contentType: 'application/json',data: data ? JSON.stringify(data) : null,statusCode: {401: function (jqXHR, textStatus, errorThrown) {alert( errorThrown );}}});}

Gracias por su atención

top related