LinuxParty
6- Uso de la base de datos
Los componentes suelen gestionar sus contenidos utilizando la base de datos. Durante la fase de instalación o desinstalación o actualización de un componente, se pueden ejecutar consultas SQL a través del uso de archivos de texto SQL.
Coge tu editor favorito, crea dos archivos llamados admin/sql/install.mysql.utf8.sql y admin/sql/updates/mysql/0.0.6.sql . Ambos deberán tener el contenido siguiente:
DROP TABLE IF EXISTS `#__helloworld`;
CREATE TABLE `#__helloworld` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`greeting` VARCHAR(25) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
INSERT INTO `#__helloworld` (`greeting`) VALUES
('Hello World!'),
('Good bye World!');
El archivo admin/sql/install.mysql.utf8.sql se ejecuta al instalar el componente. El archivo 0.0.6.sql se ejecuta al actualizar el componente.
Nota: Cuando el componente está instalado, los archivos de la carpeta SQL correspondientes a las actualizaciones del componente (por ejemplo admin/sql/updates/mysql) se leen y el nombre del último archivo (alfabéticamente) se utiliza para rellenar el número de la versión del componente en la tabla #__schemas. Este valor debe estar con un orden (en este caso alfabético) en la tabla, para que la actualización automática ejecute los archivos de actualización de SQL para futuras versiones. Por esta razón, es una buena práctica crear un archivo de actualización SQL para cada versión (incluso si está vacío o sólo tiene un comentario). De esta manera la versión #__schemas siempre coincidirá con la versión de los componentes.
Para que esto se ejecute nuestro archivo helloworld.xml tiene que ser modificado para agregar las líneas correspondientes. De paso, agrego todas las otras modificaciones que verán más abajo:
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>Hello World!</name>
<!-- Los siguientes elementos son opcionales y sin restricciones de formato -->
<creationDate>Octubre 2012</creationDate>
<author>Carlos R</author>
<authorEmail>email</authorEmail>
<authorUrl>http://www.ejemplo.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>Licencia Info</license>
<!-- La versión de desarrollo del componente se registra en la tabla del mismo -->
<version>0.0.6</version>
<!-- La descripción es opcional. Por defecto se introduce el nombre del componente -->
<description>Descripción del Componente Hello World!...</description>
<install> <!-- Se ejecuta en la instalación -->
<sql>
<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Se ejecuta en la desinstalación -->
<sql>
<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Se ejecuta en la actualización; Nuevo en 2.5 -->
<schemas>
<schemapath type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<!-- Archivos pertenecientes a la interfaz de usuario -->
<!-- Nota el atributo de la carpeta: Este atributo describe hacia dónde
y de donde van a ser copiados los archivos del paquete de instalación.-->
<files folder="site">
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<folder>views</folder>
<folder>models</folder>
</files>
<administration>
<!-- Menú de la sección de Administración -->
<menu>Hello World!</menu>
<!-- Archivos pertenecientes a la administración -->
<!-- Nota el atributo de la carpeta: Este atributo describe hacia donde
y de donde van a ser copiados los archivos del paquete de instalación. -->
<files folder="admin">
<!-- Archivos principales de la carpeta admin -->
<filename>index.html</filename>
<filename>helloworld.php</filename>
<!-- Archivos de la sección de SQL -->
<folder>sql</folder>
<!-- Archivos de la Sección de las Tablas -->
<folder>tables</folder>
<!-- Archivos de la Sección de los Modelos -->
<folder>models</folder>
</files>
</administration>
</extension>
Hacemos lo mismo con el archivo de desinstalación. Con su editor favorito, cree el archivo admin/sql/uninstall.mysql.utf8.sql que contenga:
DROP TABLE IF EXISTS `#__helloworld`;
Añadir un nuevo tipo de campo
Por el momento, se ha utilizado un tipo de campo codificado para los mensajes. El objetivo es utilizar nuestra base de datos para elegir el mensaje. Para esto modificamos el archivo site/views/helloworld/tmpl/default.xml y le agregamos estas líneas:
<?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE">
<message>COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC</message>
</layout>
<fields
name="request"
addfieldpath="/administrator/components/com_helloworld/models/fields"
>
<fieldset name="request">
<field
name="id"
type="helloworld"
label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"
/>
</fieldset>
</fields>
</metadata
Esta parte introduce un nuevo tipo de campo y le dice a Joomla! que debe buscar la definición del campo en la carpeta /administrator/components/com_helloworld/models/fields.
Con tu editor favorito crea el archivo admin/models/fields/helloworld.php que contenga lo siguiente:
<?php // No permitir el acceso directo al archivo defined('_JEXEC') or die('Restricted access'); // Importar biblioteca modelitem de Joomla // jimport('joomla.application.component.modelitem'); jimport('joomla.form.helper'); JFormHelper::loadFieldClass('list'); class JFormFieldHelloWorld extends JFormFieldList { /** * The field type. * * @varstring */ protected $type = 'HelloWorld'; /** * Method to get a list of options for a list input. * * @return array An array of JHtml options. */ protected function getOptions() { $db = JFactory::getDBO(); $query = $db->getQuery(true); $query->select('id,greeting'); $query->from('#__helloworld'); $db->setQuery((string)$query); $messages = $db->loadObjectList(); $options = array(); if ($messages) { foreach($messages as $message) { $options[] = JHtml::_('select.option', $message->id, $message->greeting); } } $options = array_merge(parent::getOptions(), $options); return $options; } }
El nuevo tipo de campo muestra una lista desplegable de mensajes para elegir. Usted puede ver el resultado de este cambio, en el gestor de menú en la administración de su sitio para el elemento
HelloWorld (Figura 7).
Muestra el mensaje seleccionado
Cuando un elemento de menú del componente, se cree o se actualice, Joomla! almacena el identificador del mensaje. El modelo HelloWorldModelHelloWorld tiene ahora para calcular el mensaje de acuerdo a este identificador y los datos son almacenados en la base de datos. De acuerdo a esto, necesitamos entonces modificar el archivo site/models/helloworld.php :
<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
// importar la biblioteca de Joomla modelitem
jimport('joomla.application.component.modelitem');
/**
* Modelo HelloWorld
*/
class HelloWorldModelHelloWorld extends JModelItem
{
/**
* @var array demensajes
*/
protected $messages;
/**
* Devuelve una referencia al objeto Tabla, siempre creando
*
* @param type El tipo de tabla para crear una instancia
* @param string Un prefijo para el nombre de la clase de la tabla. Opcional
* @param array Configuración del array del Modelo. Opcional
* @return JTable Un objeto de tipo Base de Datos
* @since 2.5
*/
public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())
{
return JTable::getInstance($type, $prefix, $config);
}
/**
* Obtener el mensaje
* @param int Recuperar el ID del mensaje corrrespondiente
* @return string El mensaje que se le muestra al usuario
*/
public function getMsg($id = 1)
{
if (!is_array($this->messages))
{
$this->messages = array();
}
if (!isset($this->messages[$id]))
{
//solicitar el ID seleccionado
$id = JRequest::getInt('id');
// Obtener una instancia de TableHelloWorld
$table = $this->getTable();
// Cargar el mensaje
$table->load($id);
// Asignar el mensaje
$this->messages[$id] = $table->greeting;
}
return $this->messages[$id];
}
}
El modelo ahora le pide a TableHelloWorld hacer llegar el mensaje. Esta clase tiene que ser definida en el archivo admin/tables/helloworld.php :
<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
// Importar la librería table de Joomla
jimport('joomla.database.table');
/**
* Clase Hello Table
*/
class HelloWorldTableHelloWorld extends JTable
{
/**
* Constructor
*
* @param object Database connector object
*/
function __construct(&$db)
{
parent::__construct('#__helloworld', 'id', $db);
}
}
No debes ver ninguna diferencia, pero si se accede a la base de datos debería ver una tabla denominada jos_helloworld con dos columnas: id y greeting. Y dos entradas: Hello World! y Good bye World! (Figura 10).
Para probar los cambios ya sabes que hacer, tan sólo tienes que empaquetar e instalar. Pero primero hagamos un recuento del contenido que tenemos que tener en nuestro directorio:
- helloworld.xml
- site/index.html
- site/helloworld.php
- site/controller.php
- site/views/index.html
- site/views/helloworld/index.html
- site/views/helloworld/view.html.php
- site/views/helloworld/tmpl/index.html
- site/views/helloworld/tmpl/default.xml
- site/views/helloworld/tmpl/default.php
- site/models/index.html
- site/models/helloworld.php
- admin/index.html
- admin/helloworld.php
- admin/sql/index.html
- admin/sql/install.mysql.utf8.sql
- admin/sql/uninstall.mysql.utf8.sql
- admin/sql/updates/index.html
- admin/sql/updates/mysql/index.html
- admin/sql/updates/mysql/0.0.1.sql
- admin/sql/updates/mysql/0.0.6.sql
- admin/models/index.html
- admin/models/fields/index.html
- admin/models/fields/helloworld.php
- admin/tables/index.html
- admin/tables/helloworld.php
También puedes descargar el archivo directamente, pero necesitas antes de instalarlo copiar el código de los archivo site/models/helloworld.php y admin/models/fields/helloworld.php antes expuesto, ya que no viene incluido en el paquete.
7- Administración Básica
Diseñar la parte de Administración nos lleva a crear al menos el tríptico Modelo-Vista-Controlador. Tenemos que modificar el punto de entrada de la administración de nuestro componente, el archivo ha ser modificado sería admin/helloworld.php :
<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
// Importar la biblioteca controller de jomla
jimport('joomla.application.component.controller');
// Obtener una instancia del controlador prefijado por HelloWorld
$controller = JController::getInstance('HelloWorld');
// Realice la tarea solicitada
$controller->execute(JRequest::getCmd('task'));
// Redirigir si se define por el controlador
$controller->redirect();
Crear el controlador general
Ahora, el punto de entrada recibe una instancia del controlador prefijado por HelloWorld. Creemos un controlador básico para la parte de la administración: admin/controller.php
<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
// Importar la biblioteca controller de jomla
jimport('joomla.application.component.controller');
/**
* General Controller of HelloWorld component
*/
class HelloWorldController extends JController
{
/**
* Mostrar la tarea
*
* @return void
*/
function display($cachable = false)
{
// programar una vista por defecto si no se establece
JRequest::setVar('view', JRequest::getCmd('view', 'HelloWorlds'));
// call parent behavior
parent::display($cachable);
}
}
Este controlador mostrará la vista HelloWorlds por defecto.
Crear la vista
Con tu gestor y editor de archivos favorito, crea un archivo admin/views/helloworlds/view.html.php que contenga:
<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
// Importar la biblioteca view de Joomla
jimport('joomla.application.component.view');
/**
* Vista HelloWorlds */
class HelloWorldViewHelloWorlds extends JView
{
/**
*Métodoo para mostrar la vista HelloWorlds
* @return void
*/
function display($tpl = null)
{
// Obtener los datos desde el modelo
$items = $this->get('Items');
$pagination = $this->get('Pagination');
// Verificar existencia de errores.
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('<br />', $errors));
return false;
}
// Asignar los datos a la vista
$this->items = $items;
$this->pagination = $pagination;
// Mostrar la plantilla
parent::display($tpl);
}
}
En Joomla!, las vistas muestran los datos usando un diseño. Con tu gestor y editor de archivos favorito, pon el archivo admin/views/helloworlds/tmpl/default.php que contenga:
<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted Access');
// Cargar el comportamiento tooltip
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld'); ?>" method="post" name="adminForm">
<table class="adminlist">
<thead><?php echo $this->loadTemplate('head');?></thead>
<tfoot><?php echo $this->loadTemplate('foot');?></tfoot>
<tbody><?php echo $this->loadTemplate('body');?></tbody>
</table>
</form>
Este diseño llama a varios sub-diseños (head, foot y body). Cada uno de ellos corresponde a un archivo prefijado por el nombre del diseño principal (default), y un guión bajo.
Pon un archivo llamado admin/views/helloworlds/tmpl/default_head.php que contenga:
<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted Access');
?>
<tr>
<th width="5">
<?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_HEADING_ID'); ?>
</th>
<th width="20">
<input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count($this->items); ?>);" />
</th>
<th>
<?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING'); ?>
</th>
</tr>
CheckAll es una función JavaScript definida en el core de Joomla!, capaz de comprobar todos los elementos.
Pon un archivo llamado admin/views/helloworlds/tmpl/default_body.php que contenga:
<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted Access');
?>
<?php foreach($this->items as $i => $item): ?>
<tr class="row<?php echo $i % 2; ?>">
<td>
<?php echo $item->id; ?>
</td>
<td>
<?php echo JHtml::_('grid.id', $i, $item->id); ?>
</td>
<td>
<?php echo $item->greeting; ?>
</td>
</tr>
<?php endforeach; ?>
JHtml::_ es una función de ayuda que muestra varias salidas HTML. En este caso mostrará una casilla de verificación para el elemento.
Pon un archivo llamado admin/views/helloworlds/tmpl/default_foot.php que contenga:
<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted Access');
?>
<tr>
<td colspan="3"><?php echo $this->pagination->getListFooter(); ?></td>
</tr>
JPagination es una clase de Joomla! que maneja y controla objetos de paginación.
Crear el modelo
La vista HelloWorlds le pide los datos al modelo. En Joomla!, hay una clase que maneja una lista de datos: JModelList. La clase JModelList y las clases heredadas sólo necesitan un método:
- getListQuery que construye una sentencia SQL
Y dos estados:
- list.start para determinar la compensación de la lista
- list.limit para determinar la longitud de la lista
Los métodos getItems y getPagination se definen en la clase JModelList. No necesitan ser definidos en la clase HelloWorldModelHelloWorlds. Modificando el archivo admin/models/helloworlds.php quedaría:
<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
// Importar biblioteca modellist de Joomla
jimport('joomla.application.component.modellist');
/**
* HelloWorldList Model
*/
class HelloWorldModelHelloWorlds extends JModelList
{
/**
* Método para crear una consulta SQL para cargar los datos de la lista.
*
* @return string Una consulta SQL
*/
protected function getListQuery()
{
// Cree un objeto de consulta nueva.
$db = JFactory::getDBO();
$query = $db->getQuery(true);
// Seleccione algunos campos
$query->select('id,greeting');
// De la tabla hello
$query->from('#__helloworld');
return $query;
}
}
El método _populateState es (por defecto) llamado automáticamente cuando un estado es leído por el método getState.
Luego de este paso el contenido del directorio se ha incrementado:
- helloworld.xml
- site/index.html
- site/helloworld.php
- site/controller.php
- site/views/index.html
- site/views/helloworld/index.html
- site/views/helloworld/view.html.php
- site/views/helloworld/tmpl/index.html
- site/views/helloworld/tmpl/default.xml
- site/views/helloworld/tmpl/default.php
- site/models/index.html
- site/models/helloworld.php
- admin/index.html
- admin/helloworld.php
- admin/controller.php
- admin/sql/index.html
- admin/sql/install.mysql.utf8.sql
- admin/sql/uninstall.mysql.utf8.sql
- admin/sql/updates/index.html
- admin/sql/updates/mysql/index.html
- admin/sql/updates/mysql/0.0.1.sql
- admin/sql/updates/mysql/0.0.6.sql
- admin/models/index.html
- admin/models/fields/index.html
- admin/models/fields/helloworld.php
- admin/models/helloworlds.php
- admin/views/index.html
- admin/views/helloworlds/index.html
- admin/views/helloworlds/view.html.php
- admin/views/helloworlds/tmpl/index.html
- admin/views/helloworlds/tmpl/default.php
- admin/views/helloworlds/tmpl/default_head.php
- admin/views/helloworlds/tmpl/default_body.php
- admin/views/helloworlds/tmpl/default_foot.php
- admin/tables/index.html
- admin/tables/helloworld.php
Crea un archivo comprimido de este directorio o descárga directamente el archivo e instálalo utilizando el gestor de extensiones de Joomla!. Recuerda también que hay que modificar el archivo helloworld.xml :
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>Hello World!</name>
<creationDate>Octubre 2012</creationDate>
<author>Carlos R & Andoitz Brit</author>
<authorEmail>email</authorEmail>
<authorUrl>http://www.ejemplo.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>Licencia Info</license>
<version>0.0.7</version>
<description>Descripción del Componente Hello World!...</description>
<install> <!-- Se ejecuta en la instalación-->
<sql>
<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Se ejecuta en la desintalación -->
<sql>
<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Se ejecuta en la actualización; Nuevo en 2.5 -->
<schemas>
<schemapath type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<files folder="site">
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<folder>views</folder>
<folder>models</folder>
</files>
<administration>
<menu>Hello World!</menu>
<files folder="admin">
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<folder>sql</folder>
<folder>tables</folder>
<folder>models</folder>
<!-- Sección para los archivos de las vistas -->
<folder>views</folder>
</files>
</administration>
</extension>
Desarrollo de componentes en Joomla 2.5 (2 de 8) | Desarrollo de componentes en Joomla 2.5 (4 de 8)
-
Programación
- Thomas E. Kurtz, coinventor de BASIC, muere a los 96 años
- Profesor de informática del MIT prueba el impacto de la IA en la formación de programadores
- Lanzamiento del IDE de código abierto Qt Creator 14 con soporte para complementos basados en Lua
- Plantillas para Joomla - Episodio 1: Plantillas, marcos y clubes o no...
- Este es el mejor libro que he visto para aprender a programar en Python en castellano desde cero, gratis y online
- ¿Deberían los niños seguir aprendiendo a programar en la era de la IA?
- La 'obsolescencia' de VBScript confirmada por Microsoft y su eventual eliminación de Windows
- El Gran Debate: ¿Deberían los Modelos de Inteligencia Artificial Ser de Código Abierto?
- El lenguaje de programación BASIC cumple 60 años
- El CEO de Nvidia dice que los niños no deberían aprender a programar
- 40 años de Turbo Pascal: recuerdos del dinosaurio codificador que revolucionó los IDE
- Los lenguajes de programación más populares y dónde aprenderlos.
- Top 5 de los principales lenguajes de programación para desarrollar aplicaciones de escritorio Linux
- Qt Creator 12 lanzado con complementos de grabación de pantalla y Explorador de compiladores
- 10 sitios web para practicar problemas de programación