martes, 18 de febrero de 2014

Las bases de datos

Ya empieza a tener forma nuestra aplicación, pero falta lo más importante, dotarla de la funcionalidad desead: la lógica de negocio. Como comenté anteriormente la filosofía de Zend Framework se basa en la arquitectura Modelo-Vista-Controlador, siendo el modelo las clases que representan las relaciones de nuestros datos.
Para empezar definiremos los parámetros de conexión en nuestro fichero application/configs/application.ini, en la sección [production] de la siguiente forma:
resources.db.adapter = PDO_MYSQL
resources.db.params.host = localhost
resources.db.params.username = nombre_usuario
resources.db.params.password = password
resources.db.params.dbname = nombre_base_de_datos

Evidentemente con los datos de seguridad adecuados. Con nuestro gestor de datos habitual crearemos la base de datos y el usuario, yo personalmente uso phpMyAdmin. Puede descargarse el paquete para Zend Server o directamente el código he instalarlo en nuestro servidor. Como ayuda la configuración del alias de Apache podría tener esta forma:

   Alias /phpmyadmin "C:\Zend\Apache2\htdocs\phpMyAdmin"
   <Directory "C:\Zend\Apache2\htdocs\phpMyAdmin">
       Options Indexes MultiViews FollowSymLinks
       AllowOverride All
       Order allow,deny
       Allow from all
   </Directory>

Para invocarlo tan solo es necesario navegar a la dirección http://localhost/phpmyadmin.
Al abordar el modelo de datos apreciamos la potencia de Zend Framework, dado que trabajaremos con formularios para introducir/editar la información, y por supuesto las vistas que serán las diferentes representaciones de nuestro modelo de datos.

El modelo de relaciones entre la tabla menú y menu_items es:



Las tablas de menús (menus y menu_items). Con phpMyAdmin crearemos las dos tablas:

--
-- Estructura de tabla para la tabla `menus`
--

CREATE TABLE IF NOT EXISTS `menus` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `access_level` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

--
-- Estructura de tabla para la tabla `menu_items`
--

CREATE TABLE IF NOT EXISTS `menu_items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `menu_id` int(11) DEFAULT NULL,
  `label` varchar(250) DEFAULT NULL,
  `link` varchar(250) DEFAULT NULL,
  `position` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Para poder interactuar con estas tablas crearemos un modelo para cada una de ellas en nuestra aplicación. Una opción es crear un modelo por cada entidad, para más información se puede consultar la documentacion de Zend Framework Create a Model and Database Table.

Para indicarle a nuestra aplicación que busque los modelos de datos modificaremos nuestra clase Bootstrap para que los incluya.
Añadiremos la siguiente función miembro a la clase Bootstrap del fichero application/Bootstrap.php:
    protected function _initAutoload()
    {
     // Incluiremos un namespace vacio
     $autoLoader = Zend_Loader_Autoloader::getInstance();
     $autoLoader->registerNamespace('CMS_');
     $resourceLoader = new Zend_Loader_Autoloader_Resource(array(
       'basePath' => APPLICATION_PATH,
       'namespace' => '',
       'resourceTypes' => array(
               'model' => array(
                 'path' => 'models/',
                 'namespace' => 'Model_'
               ),
       ),
     ));
     // Devolvemos el autoloader que sera almacenado por el Bootstrap
     return $autoLoader;
    }

Como podemos observar nuestro modelo ha de tener la forma "Model_[nombre tabla]", y debe estar contenido en el directorio models. Las clases modelo derivan de la clase Zend_Db_Table_Abstract, que es la que nos proporcionará todas las funciones primitivas de acceso a los datos como selects, updates, deletes, etc. Es importante definir la variable protegida $_name que nos indica el nombre del modelo, asimismo en el modelo vendrán definidas las relaciones y las dependencias con el resto de modelos, es importante dado que podemos declarar acciones para garantizar la integridad de los datos. La variable que define la dependencia de tablas es un array $_dependentTables, y la de referencias otro de nombre $_referenceMap. Así nuestra clase Menú (en el fichero application/models/Menu.php) tendrá la siguiente forma:

<?php
require_once ('Zend/Db/Table/Abstract.php');

class Model_Menu extends Zend_Db_Table_Abstract
{

    protected $_name = 'menus';

    protected $_dependentTables = array(
            'Model_MenuItem'
    );
}

?>   
Y nuestra clase menu_items (en el fichero application/models/MenuItem.php) será:
<?php
require_once ('Zend/Db/Table/Abstract.php');

class Model_MenuItem extends Zend_Db_Table_Abstract
{

    protected $_name = 'menu_items';

    protected $_referenceMap = array(
            'Menu' => array(
                    'columns' => array(
                            'menu_id'
                    ),
                    'refTableClass' => 'Model_Menu',
                    'refColumns' => array(
                            'id'
                    ),
                    'onDelete' => self::CASCADE,
                    'onUpdate' => self::RESTRICT
            )
    );
}

?>

Como podemos ver en menu_items está definida la relación entre la clase menu_item (menu_id) y la clase menu (id), el detalle de la definición de las acciones 'onDelete' y 'onUpdate' para salvaguardar la integridad de los datos.

No hay comentarios:

Publicar un comentario