Posts Categorized / Tutoriales

Arquitectura Modelo – Vista – Controlador

Posted Posted by admin in Tutoriales     Comments No Comments
Dic
16

El MVC (Modelo – Vista – Controlador) es un patrón utilizado continuamente  en la programación Web, a menudo utilizando un Framework que facilite el trabajo. A continuación vamos a ver un ejemplo claro de modificación de una tabla de nuestra base de datos utilizando este patrón:

Empezaremos explicando brevemente en qué consiste:

El modelo gestiona el acceso con la base de datos. Es el encargado tanto de hacer consultas como actualizaciones de esta, implementando los privilegios de acceso.

Envía a la vista, la información que se le ha solicitado para que sea la vista la encargada de mostrarla al usuario. Tanto la petición de obtener los resultados de una consulta, como de actualización de la base de datos, se recibe del controlador, por lo que para mostrar una vista con los datos devueltos, también se utilizará el controlador.

 

El controlador es una sección de código que hace de intermediario entre el “modelo” y la “vista”, encargándose además de proveer de cierta seguridad a la aplicación.

Funciona respondiendo a los eventos accionados por el usuario y envía peticiones al modelo, que será el encargado de interactuar con la base de datos o archivos.

Una vez el modelo devuelve al controlador los correspondientes datos, en función de la petición solicitada, será el controlador el que haga la llamada a la vista, enviándole los datos devueltos por el modelo.

La vista, en definitiva, es la interfaz de usuario, que muestra los datos obtenidos del modelo. A través de la vista, el usuario puede generar diferentes eventos que los recibirá el controlador, y este llamará al modelo para devolver los datos solicitados a la vista de nuevo.

Gestión de artículos

Para que este artículo no se haga demasiado extenso, partiremos suponiendo que se tiene un mínimo conocimiento sobre HTML y CSS para la creación de vistas, y PHP que será el lenguaje de programación Web utilizado.

A continuación se muestra el proceso de creación y modificación de la tabla artículos. Cada artículo se encuentra asociado a un usuario. A continuación se muestra el diagrama entidad – relación:

entidad - relación

Para hacer más fácil el seguimiento del proceso, vamos a empezar creando nuestro controlador.

A continuación expongo un ejemplo de controlador:

Incluimos el archivo de vistas y modelo, y en la clase del controlador, declaramos las variables privadas modelo y vistas, que las utilizaremos para llamar a la instancia que debemos de haber creado con dichas variables.

A continuación, recibimos el valor de la variable do, y en función del valor que se reciba, entraremos en el caso definido para tal acción del condicional “switch”.

<?php
    include_once("models/users_model.php");
    include_once("views/users_views.php");
    class ControllerAdmin{
       private $users_model, $users_view;
       public function ControllerAdmin() {
          $this->users_model = new Users_model();
          $this->users_views = new Users_views();
       }
    function main(){
       if(!isset($_REQUEST['do'])){
          $do="showLogin";
       }else{
          $do=$_REQUEST['do'];
    }
    switch($do){
       case "viewArticles": // Vista general de artículos
          if($acceso==1){
             $this->viewArticles();
          }else{
             $this->users_views->loginForm();
          }
          break;
       case "editArticle":
          if($acceso==true){
             $this->viewEditArticle();
          }else{
             $this->users_views->loginForm();
          }
          break;
       case "showAltaArticle":
          $this->viewEditArticle("newArticle");
          break;
       case "searchArticles":
          $this->searchArticles();
          break;
       case "newArticle":
          $this->newArticle();
          break;
    }

Los siguientes métodos, realizan determinadas tareas, llamando al modelo y a la vista en función de la tarea que se esté realizando.
 
/**
* Parámetros: puede recibir una variable error para mostrarlo en la vista. si no se recibe está vacía
* Función: muestra la vista de los artículos
*/
          function viewArticles($error=""){
       $data = $this->users_model->showArticles();
       $this->users_views->viewAdminArticles($data,$error);
    }
    function viewEditArticle($error=""){
       if ($error == "newArticle"){
          $error="";
          $titHead = "Nuevo artículo";
          $a = unserialize($_COOKIE['SADSD']);
          $autores = $this->users_model->showUsers();
          $this->users_views->viewEditArticles(0, $autores, $titHead, $a['id'], $error);
       }else{
          $titHead = "Administración de artículos";
          if(isset($_REQUEST['editar'])){
             $data = $this->users_model->select("articulos", "id_art", $_REQUEST['id_art']);
             $autores = $this->users_model->showUsersAdmin();
             $this->users_views->viewEditArticles($data, $autores ,$titHead, $error);
          }else if(isset($_REQUEST['eliminar'])){
                //Si en la vista se ha pulsado el boton eliminar ejecuta el modelo eliminaUsuarios
                $id_art=$_REQUEST["id_art"];
                $sw=$this->users_model->delete("articulos", "id_art", $_REQUEST['id_art']);
                switch($sw){
                   case 1:
                      $this->viewArticles();
                      break;
                   case 2: 
                      $this->viewArticles($error);
                      break;
                }
             }else if(isset($_REQUEST['actualizar'])){
                $sw = $this->users_model->actualizaArticulos();
 // Comprueba si no se ha ejecutado correctamente, en este caso hace una consulta para obtener los datos 
 // del usuario y cambia la variable sw para mostra la vista de perfil (viewPerfilUsers) con el error.

                if ($sw != 1 ){
                   $data = $this->users_model->select("articulos", "id_art", $_REQUEST['id_art']);
                   $sw=2;
                }
                switch($sw){
                   case 1: $this->viewArticles();
                   break;
                   case 2: 
                      $autores = $this->users_model->showUsers();
                      $this->users_views->viewEditArticles($data,$autores,$titHead,"No se han podido actualizar los datos");
                   break;
                } 
             }
          }
       }
    }
/**
* Parámetros: $error: permite la posibilidad de recibir un error de búsqueda, que se mostrará en la vista
* Función: genera la consulta para mostrar los artículos según el filtro indicado de texto
*/
    function searchArticles($error=""){
       $data = $this->users_model->searchArticles();
       if ($data == null)
          $error = "No se encuentran coincidencias";
       $this->users_views->viewAdminArticles($data,$error);
    }
/**
* Parámetros: $error: permite la posibilidad de recibir un error de búsqueda, que se mostrará en la vista
* Función: genera la consulta para insertar un nuevo artículo en la BD
*/
    function newArticle($error=""){
       $sw = $this->users_model->insertArticle();
       if ($sw == 1)
          $this->viewArticles();
       else
          $this->viewArticles("No se ha podido crear el artículo");
       }
}
?>

El código anterior, será el encargado de controlar el modelo y las vistas, formando vistas según el evento seleccionado, obteniendo los datos de la base de datos a través del modelo. A continuación, vamos a ver el archivo del modelo.

En nuestro ejemplo, el modelo no es el encargado de hacer las consultas sobre la base de datos, si no que prepara las consultas y las envía a una capa intermedia entre el modelo y la base de datos, a la que se denomina capa de abstracción, la cuál tendrá los métodos encargados de recibir la consulta y ejecutarla.

Lo primero que debe de contener, es la inclusión de los archivos de configuración, en el que se guardará en variables, los datos de acceso a la base de datos: usuario, contraseña, nombre de base de datos y nombre del servidor. Además, se incluirá el archivo de la clase “consulta”, que será la capa de abstracción de nuestro sistema.

El código del modelo será el siguiente:

<?php
   include_once ('class/consult.php');
   include_once ($_SERVER['DOCUMENT_ROOT']."/Servidores/TheBares/configuration.php");

   class Users_model{

   private $consulObj;
   private $configObj;
   function Users_model() {
      $configObj = new JConfig(); //Instancio la clase JConfig del archivo de configuracion
      $dbtype = $configObj->dbtype; //Obtengo el valor del gestor de bases de datos
      switch ($dbtype) {
         case "mysqli": //Base de datos MySql
            $this->consulObj = new classConsultMysqli;
            break;
      }
   }
   function showArticles(){
      $data=$this->consulObj->selectU("SELECT id_art, nombre, descripcion, usuarios.nombre_us, usuarios.mail, fecha_creacion FROM articulos INNER JOIN usuarios ON usuarios.usuario = articulos.autor ORDER BY nombre asc;");
      return $data;
   }
   function showDataArticle($id){
      $data=$this->consulObj->select("SELECT id_art, articulos.nombre, articulos.descripcion, usuarios.nombre_us, fecha_creacion, code, usuarios.mail FROM articulos INNER JOIN usuarios ON usuarios.usuario = articulos.autor WHERE id_art LIKE ".$id.";");
      return $data;
   }
   function showUsersAdmin(){
      $data=$this->consulObj->selectU("select * from usuarios where rol=2");
      return $data; 
   }
   function searchArticles(){
      $text = $_REQUEST['texto'];
      $query = "select id_art, nombre, descripcion, usuarios.nombre_us, usuarios.mail, fecha_creacion from articulos INNER JOIN usuarios ON usuarios.usuario = articulos.autor where nombre LIKE '%".$text."%' OR descripcion LIKE '%".$text."%' OR autor LIKE '%".$text."%' OR fecha_creacion LIKE '%".$text."%';";
      $data = $this->consulObj->selectU($query);
      return $data;
   }
 /**
 * Parameters: todos los atributos de la tabla articulos
 * Function: actualiza los datos del articulo
 */
  function actualizaArticulos(){
     $id=$_REQUEST["id_art"];
     $nombre=$_REQUEST["nombre"];
     $descrip=$_REQUEST["descrip"];
     $autor=$_REQUEST["autores"];
     $code=$_REQUEST["code"];

     $ok=$this->consulObj->update("update articulos set nombre='$nombre', descripcion='$descrip', autor='$autor', code='$code' where id_art LIKE '$id'"); 
     return $ok;
  }
  function insertArticle(){
     $id = $_REQUEST["id"];
     $nombre = $_REQUEST["nombre"];
     $descrip = $_REQUEST["descrip"];
     $code = $_REQUEST["code"];
     $ok = $this->consulObj->insert("insert articulos set nombre='$nombre', descripcion='$descrip', autor='$id', code='$code'");
     return $ok;
  }} ?>

Como podemos observar, la clase modelo es básica, por lo que un problema al que deberemos de enfrentarnos, es el de intentar reutilizar el máximo número de líneas de código para hacer nuestro programa lo más sencillo y escalable posible.

Por último, indicaremos el código escrito en nuestra capa de abstracción, la cuál será la que interactúe con nuestra base de datos.

<?php
    include ($_SERVER['DOCUMENT_ROOT']."/Servidores/TheBares/configuration.php");
    class classConsultMysqli{
       private $conexdb;
       private $config;

       // Método que crea una conexión a la base de datos
       private function conecta() {
          $config = new JConfig();
          $host = $config->host;
          $user = $config->user;
          $password = $config->password;
          $db = $config->db;
          $this->conexdb = new mysqli($host,$user,$password,$db);
       }

       // Método que cierra la conexión con la base de datos
       private function desconecta(){
          $this->conexdb->close(); 
       }
       function selectU($query){
          $this->conecta();
          $resul= $this->conexdb->query($query);
          if ($this->conexdb->affected_rows <= 0){
             $resul = null; //NO SE HA PODIDO EJECUTAR LA SENTENCIA
          }
          $this->desconecta();
          return $resul;
       }
       function insert($query){
          $this->conecta();
          $this->conexdb->query($query);
          if (count($this->conexdb) > 0){
             $resul = 1; //INGRESO CORRECTO
          }else{
             $resul = 2; //NO SE HA PODIDO EJECUTAR LA SENTENCIA
          }
          $this->desconecta();
          return $resul;
       }
       function update($query){
          $this->conecta();
              //Ejecución de la consulta
          $this->conexdb->query($query);
          if ($this->conexdb->affected_rows > 0){
             $resul = 1; //ACTUALIZACIÓN CORRECTA
          }else{
             $resul = 2; //NO SE HA PODIDO EJECUTAR LA SENTENCIA
          }
          $this->desconecta();
          return $resul;
       }
       function delete ($query){
          $this->conecta();
          $this->conexdb->query($query); 
          if (count($this->conexdb) > 0){
             $resul = 1; //ELIMINADO CORRECTO
          }else{
             $resul = 2; //NO ELIMINADO
          }
          $this->desconecta();
          return $resul;
       }
   }
?>

En esta clase, como hemos podido observar, recibimos un parámetro ($query), el cuál contendrá una cadena de texto con la consulta ya formada que se vaya a ejecutar, devolviendo un parámetro al modelo y a su vez al controlador, que será el encargado de mostrar una u otra vista dependiendo de si el resultado de la ejecución ha tenido éxito.

Las vistas no se exponen porque estas dependerán exclusivamente del proyecto para el que vayamos a desarrollar.
La estructura seguida, es una clase “vistas” en la que encontraremos diferentes métodos, a los cuáles son los que se llaman desde el controlador para mostrar la vista correspondiente, en la que incluiremos el archivo de la vista deseado.

Sistemas de control de versiones

Posted Posted by admin in Tutoriales     Comments No Comments
Nov
21

En este artículo podemos encontrar una breve explicación sobre los sistemas de control de versiones probablemente más utilizados en la actualidad.

  • ¿Qué son y para qué se utilizan?

Es un sistema que registra los cambios realizados sobre una colección de archivos.

Este tipo de sistemas se utiliza para llevar un control sobre los archivos, permitiéndonos crear diferentes versiones de un mismo archivo, que guardará  un breve comentario introducido por el desarrollador/a para poder localizar dicha versión con más rapidez en un futuro, aconsejándose indicar la fecha exacta. Además, nos permite utilizar estas revisiones para ver la evolución del código generado, dando la posibilidad de volver a una versión anterior si fuera necesario.

  • ¿En qué consisten y cuál es su funcionamiento?

A menudo, para crear nuestro propio control de versiones, simplemente se hacen copias del directorio raíz de nuestro proyecto en otro directorio diferente, siendo aconsejable si utilizamos este método, el de añadir la fecha en la que se hace la copia. Este método presenta diversos problemas, ya que es frecuente perder datos o incluso sobre escribirlos sin darnos cuenta.

Para solucionar este problema existen controles de versiones locales, que contienen una base de datos en la que guarda un registro de los cambios realizados. Este se utilizará principalmente, si los archivos van a ser modificados desde una sola máquina, debido a que en caso de modificarse un archivo en distintos sitios, el sistema no podrá guardar los cambios correctamente.

Si nuestro proyecto va a ser modificado por varias o muchas personas, la solución es utilizar un sistema de control de versiones centralizado, que consiste en que tendremos instalado el sistema en un servidor al que iremos enviando los cambios modificados para que cree distintas versiones del fichero, por lo que se deberá de trabajar sobre la última versión estable para no perder ningún cambio accidentalmente.

  • ¿Algunos ejemplos de este tipo de sistemas?

Existen muchos sistemas diferentes, sirviendo como ejemplo CVS, Subversion, Bazaar, Mercurial o Git.

Git lo fundó Linux Torvalds en 2005 bajo licencia GNU y GPL v2, y actualmente alberga algunos de los proyectos más importantes de código abierto, como son Gnome, Android, VLC e incluso el desarrollo del Kernel de Linux.

La mayoría de estos sistemas son de código abierto, aunque si queremos privatizarlo permiten hacerlo adquiriendo una cuenta de pago.

Mercurial, fundado en 2005 bajo licencia GPL v2, da soporte a proyectos como son Python, OpenOffice, Mozilla, Netbeans o la red social española “Tuenti”.

Instalación de Magento en un servidor local

Posted Posted by admin in Tutoriales     Comments No Comments
Nov
14

Magento es un CMS específico para el comercio electrónico con el que se pueden desarrollar prácticamente todo tipo de proyectos e-commerce.

En este artículo vamos a ver el proceso de instalación de Magento, explicando los problemas y errores encontrados en dicho proceso.

Primero deberemos descargarnos el paquete de archivos de Magento para poder hacer la instalación, en este caso en un servidor local creado utilizando WampServer 2.2 x64 para Windows.

Una vez descargado el paquete de archivos de Magento, deberemos de descargar los archivos para cambiar el idioma de la interfaz al que nosotros deseemos, en nuestro caso español, dicha carpeta deberemos de copiarla en el directorio “C:\wamp\www\magento\app\locale”.

El último paso antes de iniciar la instalación deberemos de crear una nueva base de datos desde nuestro gestor de base de datos (MySql).

Pasos para la instalación

Iniciamos nuestro servidor local y abrimos nuestro navegador para acceder al servidor (“localhost/magento”), con lo que entraremos en la instalación automáticamente.

En el primer paso aparece la configuración del idioma, que dejaremos por defecto. El siguiente paso nos pedirá datos relacionados con la base de datos, en el que deberemos indicar el servidor (“localhost”), el nombre que le hayamos dado a nuestra base de datos y credenciales de acceso al gestor de base de datos (SGBD) como se muestra a continuación.

imagen2

En la siguiente imagen se muestra el siguiente paso, en el que indicaremos la dirección en la que va a ha estar ubicado nuestro sistema y el nombre con el que podremos acceder a la parte de administración.

Configuración

Seguidamente nos aparece un error de configuración relacionado con la extensión de PHP “curl”.

Configuración

Para solucionar este error se siguieron distintos pasos:

  1. Hacemos clic sobre el icono de nuestro servidor local y entramos en “PHP/PHP extensions/” y activamos la extensión “php_curl”.
  2. Si el problema persiste, el cual fue nuestro caso, la solución fue sustituir la versión de WampServer con arquitectura de 64 bits a una versión de 32 bits, debido a que en ocasiones se provoca incompatibilidad entre Windows 7 y WampServer, ambos para arquitecturas de 64 bits. Una vez hecho este paso no deberá de dar error.

En el siguiente paso deberemos de introducir información sobre el administrador para acceder al panel de administración.

Configuración

Por último, el sistema nos proporcionará la clave de encriptación, que deberemos de guardar en un lugar seguro de forma que nadie no autorizado pueda tener acceso a ella. Esta clave es una “semilla” que utilizará junto con un sistema de cifrado para los datos.

Configuración

Si vamos al panel de administración, aparece una ventana de acceso para que introduzcamos las credenciales oportunas.

Configuración

 

En este paso no debe de dar error, aunque la instalación en servidores puede dar problemas de seguridad por lo que en este caso deberemos desactivar esta seguridad.

Nota importante: en caso de subir nuestro sistema a un servidor Web, deberemos de dejar estas líneas de código sin comentar ya que comprometen la seguridad gravemente.

Esta modificación debemos de hacerla sobre el archivo:

“C:\wamp\www\tienda\app\code\core\Mage\Core\Model\Session\Abstract\Varien.php”

El cambio a realizar es el mostrado en las siguientes imágenes:

Archivo inicial

Configuración

Archivo modificado

Configuración

El último paso de la instalación, será actualizar la página e identificarnos para acceder a la administración, en el que como se muestra en la imagen, nos permitirá cambiar el idioma utilizado.

Configuración