Desarrollo de un componente Modelo-Vista-Controlador (MVC) para Joomla! 2.5

Escrito por | 31 Octubre 2012 | Publicado en Nov. 2012
¿Sabías que la necesidad de modificar o ampliar la funcionalidad de Joomla! o a una de sus extensiones, hacen de ti un Desarrollador?. Pero por qué hacer modificaciones, cuando puedes crear una, a tu gusto y necesidad. Con este artículo vamos a desarrollar un Componente Modelo-Vista-Controlador básico para Joomla! 2.5, sin la necesidad de ser un experto en el arte de la programación.

Todo el contenido expuesto en este artículo, es extraído y traducido de la documentación que la comunidad de Joomla! ofrece íntegramente en inglés en su sección para desarrolladores. Para más información siga este enlace. Dicho esto, ¡pongámonos en la creación de nuestro componente com_helloworld!.

1- Empaquetar en un archivo .zip la carpeta de instalación

{Última Actualización: 30 Septiembre 2012 - 18:03}

Si has utilizado Joomla! antes de leer este tutorial, habrás notado que las extensiones se instalan mediante un archivo comprimido que contiene todas las cosas que son necesarias para la instalación y desinstalación de ellas.
Joomla! se divide en dos interfaces principales, la interfaz de usuario (site) y la de administración (admin). Por tanto, nuestro componente tiene que tener esa misma distribución.
Con el gestor de archivos favorito, crea un directorio (fuera de tu directorio de instalación de Joomla!) que contenga:

  • helloworld.xml
  • site / helloworld.php
  • site / index.html
  • admin / index.html
  • admin / helloworld.php
  • admin / sql / index.html
  • admin / sql / updates / index.html
  • admin / sql / updates / mysql / index.html
  • admin / sql / updates / mysql / 0.0.1.sql

0.0.1.sql es un archivo vacío que permite inicializar la versión del schema (esquema) del componente com_helloworld.
Los archivos helloworld.php de las dos carpetas (admin y site) por el momento estarán en blanco. Para identificarlos escribimos en uno “Hello World” y al otro “Hello World Administración” respectivamente.
Los archivos index.html van a ser comunes para todas las carpetas durante el proceso de desarrollo del componente y tan solo contendrán esta línea:

<html><body bgcolor="#FFFFFF"></body></html>

El archivo helloworld.xml contendrá toda la distribución de carpetas y archivos que iremos añadiendo a lo largo de este artículo, necesarios para el funcionamiento del componente. Es el archivo clave de nuestro componente, ya que es la única manera que Joomla! tiene para interpretar lo que queremos lograr. El archivo inicialmente contendrá lo siguiente:

<?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 & Andoitz B</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.1</version>

       <!-- La descripción es opcional. Por defecto se introduce el nombre del componente →
       <description>Descripción del Componente Hello World...</description>

<!-- Para las actualizaciones; Nuevo en 2.5 -->
       <update>
               <schemas>
                       <schemapath type="mysql">sql/updates/mysql</schemapath>
               </schemas>
       </update>

       <!-- Archivos pertenecientes  a la interfaz de usuario -->
       <!-- Note el atributo de la carpeta: Este atributo describe hacia donde y de donde van ha ser copiados los archivos del paquete de instalación.-->
<files folder="site">
<filename>index.html</filename>
  <filename>helloworld.php</filename>
       </files>

       <administration>
              <!-- Menú de la sección Administración  -->
              <menu>Hello World!</menu>
               <!-- Archivos pertenecientes  a la administración -->
              <!-- Note 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="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>
              </files>

      </administration>

</extension>

Crea un archivo comprimido (.zip) de este directorio con el nombre com_helloworld o descarga directamente el archivo que brinda la sección para los desarrolladores en la documentación de Joomla! e instálalo mediante el gestor de extensiones de Joomla!.  Puedes probar este componente básico poniendo  tusitio/index.php?option=com_helloworld (Figura 1) o tusitio/administrator/index.php?option=com_helloworld (Figura 2) en tu navegador. También se puede observar que el componente Hello World! es visible en la administración de la instalación de Joomla! en el menú Componentes (Figura 3).

Figura 1

Figura 2

Figura 3

2- Configuración Modelo-Vista-Controlador (MVC)

{Última Actualización: 30 Septiembre 2012 - 18:04 }

En el Framework de Joomla! 2.5, los autores de los componentes dividen el código en 3 partes principales:

  • models (Modelo): Gestionar los datos
  • views (Vista):  Mostrará el contenido de acuerdo al tipo (error, feed, html, json, raw, xml) y el diseño elegido por los controladores
  • controllers (Controlador): Llevan a cabo las tareas, establecen y obtienen el estado del  modelo y preguntan qué vista es la que hay que mostrar.

Configuración del Controlador

En el código del núcleo de Joomla, hay una clase capaz de gestionar los controladores: JController.  Esta clase tiene que ser extendida para ser usada en nuestro componente.  En el archivo site/helloworld.php (punto de entrada de nuestro componente Hello World!) ubicamos estas líneas:

<?php
// No permitir el acceso directo a este archivo
defined('_JEXEC') or die('Restricted access');

// Importar la biblioteca del controlador de Joomla
jimport('joomla.application.component.controller');

// Obtener una instancia del controlador prefijado por HelloWorld
$controller = JController::getInstance('HelloWorld');

// Lleva a cabo la tarea solicitada
$input = JFactory::getApplication()->input;
$controller->execute($input->getCmd('task'));

// Redirigir si se define por el controlador
$controller->redirect();

El método estático getInstance de la clase JController creará un controlador.  En el código anterior, se creará una instancia del objeto del controlador de una clase llamada HelloWorldController. Joomla! buscará la declaración de esa clase en un archivo llamado exactamente controller.php (es un comportamiento por defecto).
Ahora, controller.php es necesario crearlo y HelloWorldController debe ser declarado y definido. Así que con tu gestor de archivos y editor favorito , creamos el archivo site/controller.php que contenga lo siguiente:

<?php
// No permitir el acceso directo a este archivo
defined('_JEXEC') or die('Restricted access');

// Importar la biblioteca del controlador de Joomla
jimport('joomla.application.component.controller');

/**
* Controlador del Componente Hello World!
*/
class HelloWorldController extends JController
{
}

Cuando no hay ninguna tarea dada en las variables de petición, la tarea por defecto se ejecutará. Dicha tarea la contiene la clase JController, que ejecuta la tarea de visualización por defecto. En nuestro ejemplo, se mostrará una vista denominada HelloWorld.

Configuración de la Vista

Cuando la clase JController decide mostrar una vista, va en busca de los archivos que están en la carpeta component/com_[nombre_componente]/views/[nombre_vista]/ .
El nombre de la carpeta, de la vista por defecto, es el nombre del propio componente. En nuestro caso la ruta es component/com_helloworld/views/helloworld/.
El archivo que contiene el código de la vista se denomina view.[modo_vista].php. El modo de la vista por defecto, y probablemente el único que tenga un componente es el modo html. Así que esto nos da nuestro nombre del archivo, que es view.html.php.
Con el gestor de archivos y editor favorito, crea el archivo site/views/helloworld/view.html.php que será nuestra vista predeterminada, conteniendo lo siguiente:

<?php
// No permitir el acceso directo a este archivo
defined('_JEXEC') or die('Restricted access');

// Importar la biblioteca del controlador de Joomla
jimport('joomla.application.component.view');

/**
* HTML clase View para el componente HelloWorld */
class HelloWorldViewHelloWorld extends JView
{
       // Sobrescribir visualización del método JView
       function display($tpl = null)
       {
               // Asignar datos a la vista
               $this->msg = 'Hello World';

               // Visualiza la vista
               parent::display($tpl);
       }
}

El método de visualización de la clase JView se llama con la tarea de visualización de la clase JController. En nuestro caso, este método mostrará los datos utilizando el archivo tmpl/default.php.
Con el gestor de archivos y editor favorito , crea el archivo site/views/helloworld/tmpl/default.php que contenga lo siguiente:

<?php
// No permitir el acceso directo a este archivo
defined('_JEXEC') or die('Restricted access');
?>
<h1><?php echo $this->msg; ?></h1>

Este archivo de plantilla se incluirán en la clase JView. Por lo tanto, aquí, $this  se refiere a la clase HelloWorldViewHelloWorld.
Haciendo un recuento de lo que hemos creado hasta ahora, deberíamos de tener el siguiente 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.php
  • admin/index.html
  • admin/helloworld.php
  • admin/sql/index.html
  • admin/sql/updates/index.html
  • admin/sql/updates/mysql/index.html
  • admin/sql/updates/mysql/0.0.1.sql

Luego de rectificar esto, actualizamos el archivo helloworld.xml para añadir los cambios pertinentes:

<?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>October 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>

       <!--  La  versión de desarrollo del componente se registra en la tabla del mismo -->
       <version>0.0.2</version>

       <!-- The description is optional and defaults to the name →
       <description>Descripción del Componente Hello World...</description>

<!-- Para las actualizaciones; Nuevo en 2.5 -->
       <update>
               <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 donde 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>
       </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>
               </files>
       </administration>

</extension>

Si deseas probar los cambios, solo sigue los mismos pasos para empaquetar el directorio o descarga el archivo que brinda la sección para los desarrolladores en la documentación de Joomla! e instálalo mediante el gestor de extensiones de Joomla!. Luego ingresa tusitio/index.php?option=com_helloworld en tu navegador y verás por defecto el mensaje contenido en la variable $this->msg en el archivo view.html.php (Figura 4).

Figura 4

3- Añadir un tipo de elemento de Menú

{Última Actualización: 30 Septiembre 2012 - 18:05 }

En el Framework de Joomla!,  los componentes se ejecutan utilizando elementos del menú. Si vas al gestor de menú en la administración de tu sitio, verás que aún no existe ningún tipo de elemento de Menú correspondiente a nuestro componente Helloworld (Figura 5).

Figura 5

Para lograr esto, es muy sencillo en Joomla!, simplemente añadimos el archivo site/views/helloworld/tmpl/default.xml que contenga lo siguiente:

<?xml version="1.0" encoding="utf-8"?>
<metadata>
       <layout title="COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE">
               <message>
                       <![CDATA[COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC]]>
               </message>
       </layout>
</metadata>

Por el momento las cadenas no serán traducidas, ya que más adelante lo veremos con más detalles.
Ahora modificamos nuestro archivo helloworld.xml para añadir una nueva versión, ya que fue modificado el componente. Exactamente la línea que buscamos en el archivo es esta:

[….]
       <!--  La  versión de desarrollo del componente se registra en la tabla del mismo -->
       <version>0.0.3</version>
[….]

Si empaquetamos nuestro directorio y luego lo instalamos, veremos que ya tenemos un elemento de menú nuevo (Figura 6). También puedes descargarte el archivo brindado en la documentación de Joomla! para desarrolladores.

Figura 6

4- Añadir el Modelo

{Última Actualización: 30 Septiembre 2012 - 18:05}

En el Framework de Joomla!, los modelos son responsables de la gestión de los datos. La primera función que tiene que ser escrita para un modelo es la función get. Su objetivo es devolver los datos una vez haya sido llamada. En nuestro caso la que llama a esta función es la vista HelloWorldViewHelloWorld. Por defecto, el modelo llamado HelloWorldModelHelloWorld es el modelo principal asociado a esta vista. Para implementar esto, coge el gestor de archivos y editor favorito y crea el siguiente archivo site/models/helloworld.php, el cual contendrá lo siguiente:

<?php
// No permitir el acceso directo a este archivo
defined('_JEXEC') or die('Restricted access');

// Importar la biblioteca del controlador de Joomla
jimport('joomla.application.component.modelitem');

/**
* Modelo HelloWorld
*/
class HelloWorldModelHelloWorld extends JModelItem
{
       /**
        * @var string msg
        */
       protected $msg;

       /**
        * Obtener el mensaje
        * @return string El mensaje que se muestra al usuario
        */
       public function getMsg()
       {
               if (!isset($this->msg))
               {
                       $this->msg = 'Hello World!';
               }
               return $this->msg;
       }
}

Como sabemos la clase HelloWorldViewHelloWorld es la que le pregunta al modelo por los datos utilizando el método get de la clase JView. Modificando el archivo site/views/helloworld/view.html.php quedaría de la siguiente forma:

<?php
// No permitir el acceso directo a este archivo
defined('_JEXEC') or die('Restricted access');

// Importar la biblioteca del controlador de Joomla
jimport('joomla.application.component.view');

/**
* HTML clase View para el componente HelloWorld
*/
class HelloWorldViewHelloWorld extends JView
{
       // Sobrescribir visualización del método JView
       function display($tpl = null)
       {
               // Asignar datos a la vista
               $this->msg = $this->get('Msg');

               // Comprueba si hay errores.
               if (count($errors = $this->get('Errors')))
               {
                       JError::raiseError(500, implode('<br />', $errors));
                       return false;
               }
               // Visualiza la vista
               parent::display($tpl);
       }
}

Nota: $this->get()  es un miembro de JView::get que es un proxy para (get*) obtener los métodos por defecto del modelo, donde * se rellena con el valor del primer parámetro pasado a get().
Nota: La clase JError está obsoleta, utiliza la clase JLog o PHP Exception en su lugar.
Un cambio, una nueva versión para nuestro componente. Por tanto, modificamos la línea correspondiente en el archivo helloworld.xml, para añadir la nueva versión y la carpeta correspondiente a los modelos. Exactamente serían estas líneas:

[….]
<!--  La  versión de desarrollo del componente se registra en la tabla del mismo -->
       <version>0.0.4</version>
[….]
<!-- 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>
[….]

5- Adición de una petición de variable en el tipo de menú

{Última Actualización: 3 Octubre  2012 - 23:54}

Por el momento, el mensaje que siempre aparece es Hello World!. Joomla! 2.5 ofrece la posibilidad de agregar parámetros a los tipos de menú (Figura 7).

Figura 7

En nuestro caso, esto se hace en el archivo site/views/helloworld/tmpl/default.xml

<?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">
               <fieldset name="request">
                       <field
                               name="id"
                               type="list"
                               label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"
                               description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"
                               default="1"
                       >
                               <option value="1">Hello World!</option>
                               <option value="2">Good bye World!</option>
                       </field>
               </fieldset>
       </fields>
</metadata>

Dos cosas importantes a tener en cuenta:

  • El grupo de campos (fields) de solicitud (request) indica los campos obligatorios
  • El valor del atributo se pasa al componente en la dirección URL. En este caso, ?option=com_helloworld&id=1 indicaría que se ha elegido la opción “1”

El modelo tiene que ser modificado con el fin de cambiar entre los dos mensajes diferentes (que es elegido por el usuario con el campo definido anteriormente). Entonces el archivo site/models/helloworld.php quedaría:

<?php
// No permitir el acceso directo a este archivo
defined('_JEXEC') or die('Restricted access');

// Importar la biblioteca del controlador de Joomla
jimport('joomla.application.component.modelitem');


/**
* Modelo HelloWorld
*/
class HelloWorldModelHelloWorld extends JModelItem
{
       /**
        * @var string msg
        */
       protected $msg;

       /**
        * Obtener el mensaje
        * @return string El mensaje que se muestra al usuario
        */
       public function getMsg()
       {
               if (!isset($this->msg))
               {
                       $id = JRequest::getInt('id');
                       switch ($id)
                       {
                       case 2:
                               $this->msg = 'Good bye World!';
                       break;
                       default:
                       case 1:
                               $this->msg = 'Hello World!';
                       break;
                       }
               }
               return $this->msg;
       }
}

Otro cambio, otra versión para nuestro componente. Ya sería la 0.0.5 . Para ver en funcionamiento lo anteriormente explicado, solo tienes que escribir en tu navegador index.php?option=com_helloworld&id=1 para la primera opción (Figura 8) o index.php?option=com_helloworld&id=2 para la segunda (figura 9). Esto claro, después de haber empaquetado e instalado su nueva versión del componente. También puedes descargar el archivo que brinda la sección para desarrolladores en la documentación de Joomla.

Figura 8

Figura 9

6- Uso de la base de datos

{Última Actualización: 19 Octubre  2012 - 17:04 }

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');

/**
* Modelo HelloWorld
*/
class HelloWorldModelHelloWorld extends JModelItem
{
       /**
        * @var string msg
        */
       protected $msg;

       /**
        * Retorna una referencia al objeto Table, siempre creandolo.
        *
        * @param       type    El tipo de tabla a instanciar
        * @param       string  Un prefijo para el nombre de la clase de la tabla. Opcional.
        * @param       array   Configuración del array para el modelo. Opcional.
        * @return      JTable  Un objeto base de datos
        * @since       1.6
        */
       public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())
       {
               return JTable::getInstance($type, $prefix, $config);
       }
       /**
        * Obtener el mensaje
        * @return string El mensaje que va a ser mostrado al usuario
        */
       public function getMsg()
       {
               if (!isset($this->msg))
               {
                       $id = JRequest::getInt('id');
                       // Obtener una instancia a TableHelloWorld
                       $table = $this->getTable();

                       // Cargando el mensaje
                       $table->load($id);

                       // Asignar el mensaje
                       $this->msg = $table->greeting;
               }
               return $this->msg;
       }
}

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 de mensajes
        */
       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).

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

{Última Actualización: 27 Septiembre  2012 - 03:08 }

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>

Ahora puedes ver en tu componente hello-world un formulario con dos columnas, dos filas y casillas de verificación. Puedes hacer clic en las casillas para seleccionar las opciones que desees (Figura 11).

Figura 11

8- Añadir la gestión de idiomas

{Última Actualización: 30 Septiembre  2012 - 18:08 }

Joomla! 2.5 gestiona los idiomas de los componentes en cuatro situaciones diferentes:

  • Mostrando un componente en el sitio público
  • Gestionando un componente en la administración
  • Gestionando los menús en la administración
  • Instalando un componente (nuevo en 1.7)

Joomla! 2.5 utiliza dos ubicaciones de carpetas diferentes para los idiomas:

  • Una en administrator/language o language
  • Una en la carpeta del componente (administrator/components/*componente*/language o components/*componente*/language)

Esto depende de como se instale el componente.

Gestión del idioma en el sitio público

Con el gestor de archivo y editor favorito, coloque un archivo en site/language/es-ES/es-ES.com_helloworld.ini .  Este archivo contendrá la traducción para la parte pública. Por el momento, este archivo estará vacío.

Gestión del idioma en el manejo del componente

Con el gestor de archivo y editor favorito, coloque el archivo admin/language/es-ES/es-ES.com_helloworld.ini . Este archivo contendrá la traducción de la administración.

COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC="El mensaje de bienvenida que se visualizará"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL="Mensaje"
COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING="Bienvenida"
COM_HELLOWORLD_HELLOWORLD_HEADING_ID="Id"

Gestión del idioma en el manejo de los menús en la administración

Con el gestor de archivos y editor favorito, coloque el archivo admin/language/es-ES/es-ES.com_helloworld.sys.ini . Este archivo contendrá la traducción de la administración.

COM_HELLOWORLD="Hello World!"
COM_HELLOWORLD_DESCRIPTION="Esta es la descripción del componente  Hello World"
COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE="Hello World"
COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC="Esta vista muestra un mensaje seleccionado"
COM_HELLOWORLD_MENU="Hello World!"

Opciones de ubicación para los archivos de los diferentes idiomas

A partir de la versión 1.7 hay dos formas de instalar los archivos de idiomas para una extensión. Se puede utilizar uno u otro o una combinación de ambos.
En la versión 1.5 los archivos se instalan en la carpeta language del núcleo de Joomla! (RAÍZ/administrator/language/ y RAÍZ/language/). Desde la versión 1.6 existe una nueva vía que incluye los archivos de idiomas en la carpeta language de la raíz de la extensión.
Por lo tanto, una extensión puede incluir una carpeta language  con un .sys.ini diferente a la instalada en la carpeta language del núcleo de Joomla! (este último no está incluido en la carpeta language del núcleo de Joomla!, ya que en la característica multi-idioma de Joomla! podemos tener idiomas a la espera de que sean instalados). Entonces, con esto tenemos dos formas diferentes de mostrar las descripciones: una el .sys.ini en la carpeta language, que se utiliza para los mensajes que van ha ser mostrados cuando la instalación se haya completado, y otra (desde el .ini) se utiliza para el funcionamiento “normal” del componente, es decir, cuando la extensión es usada en la administración. Esto puede ser extremadamente útil en la instalación ya que puede existir la necesidad de que las descripciones requieran valores diferentes.
Nota:  El archivo .sys.ini también se utiliza para traducir el nombre de las extensiones en algunos gestores en la administración, y para proporcionar a los componentes una traducción al menú.
Por lo tanto, el archivo helloworld.xml incluiría desde la versión 1.6:

<files>
[...]
/*
   * Esta carpeta debe incluir las subcarpetas adecuadas, es decir, language/es-ES/ ... language/fr-FR
*/
<folder>language</folder>
<filename>cualquier cosa</filename>
[...]
</files>

Y desde la versión 1.5 (o puede ser que no se incluya):

[...]
<languages folder="carpetaidiomanucleojoomla"> // si se usa otra carpeta de idioma (puede colocar cualquier nombre que se ajuste)
   <language tag="es-ES">es-ES/es-ES.cualquiercosa.ini</language> // o
    <language tag="es-ES">es-ES.cualquiercosa.ini</language> // si no existe una subcarpeta
   <language tag="es-ES">es-ES/en-ES.cualquiercosa.sys.ini</language> // o
   <language tag="es-ES">es-ES.cualquiercosa.sys.ini</language> si no existe una subcarpeta
</languages>
[...]

O simplemente en la raíz:

<languages>
<language tag="es-ES">es-ES.cualquiercosa.ini</language>
<language tag="es-ES">es-ES.cualquiercosa.sys.ini</language>
</languages>

Al instalar o actualizar la extensión, el archivo .sys.ini presente en la carpeta language en la raíz de la extensión, mostrará el resultado de la instalación a partir del valor asociado a la descripción del mismo.  A partir de entonces, si está presente, el .sys.ini así como el .ini instalado en la carpeta language del núcleo de Joomla!, tendrá prioridad sobre los archivos presentes en la carpeta language en la raíz de la extensión.
Nota: Una de las ventajas de la instalación de los archivos en la carpeta language en la raíz de la extensión, es que estos no se tocan cuando se actualiza un paquete de idioma.  La otra ventaja es que esta carpeta puede incluir varios idiomas (en-GB, fr-FR, es-ES, etc) que no requieren que el usuario instale el paquete de idioma correspondiente.  Esto es útil ya que están disponibles si, más adelante, un usuario instala el paquete correspondiente.

Añadir traducción al instalar el componente

Vea: Opciones de ubicación para los archivos de los diferentes idiomas

Con tu gestor de archivos y editor favorito, crea un archivo en RaízExtensión/language/es-ES/es-ES.miextension.sys.ini . Este archivo contendrá la traducción para la instalación.

COM_HELLOWORLD="Hello World!"
COM_HELLOWORLD_DESCRIPTION="Esta es la descripción del componente Hello World"

El COM_HELLOWORLD_DESCRIPTION se puede utilizar en el archivo helloworld.xml.
Entonces, debido a las modificaciones antes expuestas, nuestro archivo helloworld.xml se actualiza de la siguiente forma:

<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">

       <name>COM_HELLOWORLD</name>
       <creationDate>Octubre 2012</creationDate>
       <author>Carlos R & Andoitz B</author>
       <authorEmail>email</authorEmail>
       <authorUrl>http://www.ejemplo.org</authorUrl>
       <copyright>Copyright Info</copyright>
       <license>Licensia Info</license>      
       <version>0.0.8</version>      
       <description>COM_HELLOWORLD_DESCRIPTION</description>

       <install>
               <sql>
                       <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
               </sql>
       </install>

       <uninstall>
               <sql>
                       <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
               </sql>
       </uninstall>
       <update>
               <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>
               <folder>language</folder> // Carpeta para los idiomas en la interfaz de usuario
     </files>

       <administration>
              
               <menu>COM_HELLOWORLD_MENU</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>                       
                       <folder>views</folder>
             </files>
 
/*
   * Carpetas y archivos para el idioma en la administración
*/
             <languages folder="admin">
               <language tag="es-ES">language/es-ES/es-ES.com_helloworld.ini</language>
               <language tag="es-ES">language/es-ES/es-ES.com_helloworld.sys.ini</language>
             </languages>
       </administration>

</extension>

En este archivo helloworld.xml, los idiomas están instalados en:

  • administrator/language para la parte de administración (ver la etiqueta de idiomas xml)
  • components/com_helloworld/language para la parte de la interfaz de usuario (No existe ninguna etiqueta de idiomas xml,  pero la carpeta del idioma está incluida)

Ahora para probar lo modificado ya sabes que hacer.

9- Añadir acciones a la administración

{Última Actualización: 30 Septiembre  2012 - 18:09 }

Añadir una barra de herramientas

En Joomla!, el administrador normalmente interactúa con los componentes a través de la barra de herramientas. Añade este contenido en el archivo admin/views/helloworlds/view.html.php. Esto creará una barra de herramientas básica y un título para el componente:

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar librería de vistas de Joomla
jimport('joomla.application.component.view');

/**
* Vistas HelloWorlds
*/
class HelloWorldViewHelloWorlds extends JView
{
       /**
        * método de presentación de la vista HelloWorlds
        * @return void
        */
       function display($tpl = null)
       {
               // Obtener datos del modelo
               $items = $this->get('Items');
               $pagination = $this->get('Pagination');

               // Comprobación de errores
               if (count($errors = $this->get('Errors')))
               {
                       JError::raiseError(500, implode('<br />', $errors));
                       return false;
               }
               // Asignar datos a la vista
               $this->items = $items;
               $this->pagination = $pagination;

               // Establecer la barra de herramientas
               $this->addToolBar();

               // Mostrar la plantilla
               parent::display($tpl);
       }

       /**
        * Configurar la barra de herramientas
        */
       protected function addToolBar()
       {
               JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'));
               JToolBarHelper::deleteList('', 'helloworlds.delete');
               JToolBarHelper::editList('helloworld.edit');
               JToolBarHelper::addNew('helloworld.add');
       }
}

Puedes encontrar otras acciones básicas de Administración en el archivo administrator/includes/toolbar.php de tu instalación de Joomla!.
Ya que la vista puede realizar algunas acciones, tenemos que añadir algunos datos de entrada. Con tu gestor y editor de archivos favorito, añade lo siguiente en el archivo admin/views/helloworlds/tmpl/default.php :

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted Access');
// cargar tooltip
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld'); ?>" method="post" name="adminForm" id="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>
       <div>
               <input type="hidden" name="task" value="" />
               <input type="hidden" name="boxchecked" value="0" />
               <?php echo JHtml::_('form.token'); ?>
       </div>
</form>

Añadir controladores específicos

Hay que incluir tres acciones:

  • helloworlds.delete
  • helloworld.edit
  • helloworld.add

Aquí puedes leer más sobre subcontroladores (en Inglés).
Estas son tareas compuestas (controller.task), así que hay que codificar dos nuevos controladores: HelloWorldControllerHelloWorlds y HelloWorldControllerHelloWorld .
admin/controllers/helloworlds.php 

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// importar librería de controladores de Joomla!
jimport('joomla.application.component.controlleradmin');

/**
*Controlador HelloWorlds
*/
class HelloWorldControllerHelloWorlds extends JControllerAdmin
{
       /**
        * Proxy para getModel.
        * @desde       2.5
        */
       public function getModel($name = 'HelloWorld', $prefix = 'HelloWorldModel')
       {
               $model = parent::getModel($name, $prefix, array('ignore_request' => true));
               return $model;
       }
}

admin/controllers/helloworld.php 

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar librería de controladores de formulario de Joomla
jimport('joomla.application.component.controllerform');

/**
*Controlador HelloWorld
*/
class HelloWorldControllerHelloWorld extends JControllerForm
{
}

Añadir y editar la vista

Esta vista mostrará datos utilizando un diseño.
Crea el archivo admin/views/helloworld/tmpl/edit.php que contenga:

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id='.(int) $this->item->id); ?>"
     method="post" name="adminForm" id="helloworld-form">
       <fieldset class="adminform">
               <legend><?php echo JText::_( 'COM_HELLOWORLD_HELLOWORLD_DETAILS' ); ?></legend>
               <ul class="adminformlist">
<?php foreach($this->form->getFieldset() as $field): ?>
                       <li><?php echo $field->label;echo $field->input;?></li>
<?php endforeach; ?>
               </ul>
       </fieldset>
       <div>
               <input type="hidden" name="task" value="helloworld.edit" />
               <?php echo JHtml::_('form.token'); ?>
       </div>
</form>

Añadir un modelo y modificar el existente

La vista HelloWorldViewHelloWorld pide el formulario y los datos a través de un modelo. Este modelo tiene que proporcionar un método getTable, un método getForm y un método loadData (llamados desde el controlador JModelAdmin)
admin/models/helloworld.php

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// importar librería modelform de Joomla
jimport('joomla.application.component.modeladmin');

/**
*Modelo HelloWorld
*/
class HelloWorldModelHelloWorld extends JModelAdmin
{
       /**
        * Devuelve una referencia al objeto Table, siempre creándolo.
        *
        * @param       type    Tipo de tabla a instanciar
        * @param       string  Prefijo para el nombre de clase de tabla. Opcional.
        * @param       array  Array de configuración para el modelo. Opcional.
        * @return      JTable  Objeto de base de datos
        * @since       2.5
        */
       public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())
       {
               return JTable::getInstance($type, $prefix, $config);
       }
       /**
        * Método para conseguir el formulario.
        *
        * @param      array   $data           Datos para el formulario.
        * @param      boolean $loadData   Verdadero si el formulario va a cargar sus propios datos (por defecto), falso si no.
        * @return      mixed    Un objeto JForm object si funciona, false si falla
        * @since       2.5
        */
       public function getForm($data = array(), $loadData = true)
       {
               // Get the form.
               $form = $this->loadForm('com_helloworld.helloworld', 'helloworld',
                                       array('control' => 'jform', 'load_data' => $loadData));
               if (empty($form))
               {
                       return false;
               }
               return $form;
       }
       /**
        * Método para obtener datos que deberían ser inyectados al formulario.
        *
        * @return      mixed   Datos para el formulario.
        * @since       2.5
        */
       protected function loadFormData()
       {
               // Comprueba la sesión para comprobar datos introducidos previamente.
               $data = JFactory::getApplication()->getUserState('com_helloworld.edit.helloworld.data', array());
               if (empty($data))
               {
                       $data = $this->getItem();
               }
               return $data;
       }
}

Este modelo hereda de la clase JModelAdmin y utiliza el método loadForm. Busca formularios en la carpeta forms. Con tu gestor y editor de archivos favorito, crea un archivo admin/models/forms/helloworld.xml que contenga:

<?xml version="1.0" encoding="utf-8"?>
<form>
       <fieldset>
               <field
                       name="id"
                       type="hidden"
               />
               <field
                       name="greeting"
                       type="text"
                       label="COM_HELLOWORLD_HELLOWORLD_GREETING_LABEL"
                       description="COM_HELLOWORLD_HELLOWORLD_GREETING_DESC"
                       size="40"
                       class="inputbox"
                       default=""
               />
       </fieldset>
</form>

Modificando el archivo helloworld.xml quedaría:

<?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 B</author>
       <authorEmail>email</authorEmail>
       <authorUrl>http://www.ejemplo.org</authorUrl>
       <copyright>Copyright Info</copyright>
       <license>Licencia info</license>
       <version>0.0.9</version>
       <description>COM_HELLOWORLD_DESCRIPTION</description>

       <install> <!-- Se ejecuta al instalar -->
               <sql>
                       <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
               </sql>
       </install>
       <uninstall> <!-- Se ejecuta al desinstalar -->
               <sql>
                       <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
               </sql>
       </uninstall>
       <update> <!-- Se ejecuta al actualizar; 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>
               <folder>language</folder>
       </files>

       <administration>
              
               <menu>COM_HELLOWORLD_MENU</menu>
                <files folder="admin">
                       <!-- Sección principal de Copia de Archivos de Administración -->
                       <filename>index.html</filename>
                       <filename>helloworld.php</filename>
                       <filename>controller.php</filename>

                       <!-- Sección de archivos SQL -->
                       <folder>sql</folder>

                       <!-- Sección de archivos de tablas -->
                       <folder>tables</folder>

                       <!-- Sección de archivos de modelos -->
                       <folder>models</folder>

                       <!-- Sección de archivos de vistas -->
                       <folder>views</folder>

                       <!-- Sección de archivos de controladores -->
                       <folder>controllers</folder>
               </files>

         <languages folder="admin">
              <language tag="es-ES">language/es-ES/es-ES.com_helloworld.ini</language>
              <language tag="es-ES">language/es-ES/es-ES.com_helloworld.sys.ini</language>
          </languages>
       </administration>

</extension>

Ahora crea un archivo comprimido de este directorio o descarga directamente el archivo (modificando el código en /admin/models/helloworld.php por el expuesto aquí) e instálalo utilizando el gestor de extensiones de Joomla.

10- Añadir decoración a la Administración

{Última Actualización: 30 Septiembre  2012 - 18:09 }

Añadir algunos iconos

Con tu gestor de archivos favorito crea una imagen de 16x16 y otra de 48x48 en el directorio media/images y añade una etiqueta media en tu archivo de instalación. Modifica la etiqueta menú para que utilice el nuevo icono.

Modificar las vistas

Añade las siguientes líneas al archivo admin/views/helloworlds/view.html.php:

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// importar librería de vistas de Joomla
jimport('joomla.application.component.view');

/**
* Vista HelloWorlds
*/
class HelloWorldViewHelloWorlds extends JView
{
       /**
        * Método de presentación de vistas HelloWorlds
        * @return void
        */
       function display($tpl = null)
       {
               // Obtener datos del modelo
               $items = $this->get('Items');
               $pagination = $this->get('Pagination');

               // Comprobar errores.
               if (count($errors = $this->get('Errors')))
               {
                       JError::raiseError(500, implode('<br />', $errors));
                       return false;
               }
               // Asignar datos a la vista
               $this->items = $items;
               $this->pagination = $pagination;

               // Configurar la barra de herramientas
               $this->addToolBar();

               // Mostrar la plantilla
               parent::display($tpl);

               // Configurar el documento
               $this->setDocument();
       }

       /**
        * Configurar la barra de herramientas
        */
       protected function addToolBar()
       {
               JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'), 'helloworld');
               JToolBarHelper::deleteListX('', 'helloworlds.delete');
               JToolBarHelper::editListX('helloworld.edit');
               JToolBarHelper::addNewX('helloworld.add');
       }
       /**
        * Método para configurar las propiedades del documento
        *
        * @return void
        */
       protected function setDocument()
       {
               $document = JFactory::getDocument();
               $document->setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION'));
       }
}

Esta vista utiliza un segundo parámetro para la función JToolBarHelper::title. Se utilizará para construir la clase css para el título. El método _setDocument define el título en el navegador. Añade las siguientes líneas en el archivo admin/views/helloworld/view.html.php :

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// importar librería de vistas de Joomla
jimport('joomla.application.component.view');

/**
* Vista HelloWorld
*/
class HelloWorldViewHelloWorld extends JView
{
       /**
        * Ver formulario
        *
        * @var         form
        */
       protected $form = null;

       /**
        * mostrar método de la vista HelloWorld
        * @return void
        */
       public function display($tpl = null)
       {
               // obtener datos
               $form = $this->get('Form');
               $item = $this->get('Item');

               // Comprobar errores.
               if (count($errors = $this->get('Errors')))
               {
                       JError::raiseError(500, implode('<br />', $errors));
                       return false;
               }
               // Asignar datos
               $this->form = $form;
               $this->item = $item;

               // Configurar la barra de herramientas
               $this->addToolBar();

               // Mostrar la plantilla
               parent::display($tpl);

               // Configurar el documento
               $this->setDocument();
       }

       /**
        * Configurar la barra de herramientas
        */
       protected function addToolBar()
       {               
               $input = JFactory::getApplication()->input;
               $input->set('hidemainmenu', true);
               $isNew = ($this->item->id == 0);
               JToolBarHelper::title($isNew ? JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW')
                                            : JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'), 'helloworld');
               JToolBarHelper::save('helloworld.save');
               JToolBarHelper::cancel('helloworld.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE');
       }
       /**
        * Método para configurar las propiedades del documento
        *
        * @return void
        */
       protected function setDocument()
       {
               $isNew = ($this->item->id < 1);
               $document = JFactory::getDocument();
               $document->setTitle($isNew ? JText::_('COM_HELLOWORLD_HELLOWORLD_CREATING')
                                          : JText::_('COM_HELLOWORLD_HELLOWORLD_EDITING'));
       }
}

Esta vista también utiliza el segundo parámetro de la función JToolBarHelper::title y define el título del navegador.

Modificar el archivo de entrada principal

En el archivo admin/helloworld.php, añade estas líneas para que utilice el icono de 48x48:

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Configurar algunas propiedades globales
$document = JFactory::getDocument();
$document->addStyleDeclaration('.icon-48-helloworld {background-image: url(../media/com_helloworld/images/tux-48x48.png);}');

// importar librería de controladores de Joomla
jimport('joomla.application.component.controller');

// Conseguir una instancia de controlador prefijado por HelloWorld
$controller = JController::getInstance('HelloWorld');

// Ejecutar la tarea de solicitud
$input = JFactory::getApplication()->input;
$controller->execute($input->getCmd('task'));

// Redirigir si está configurado por el controlador
$controller->redirect();

Añadir algunas líneas en el archivo de idioma

Modifica el admin/language/es-ES/es-ES.com_helloworld.ini y añade las siguientes líneas:

COM_HELLOWORLD_ADMINISTRATION="HelloWorld - Administración"
COM_HELLOWORLD_HELLOWORLD_CREATING="HelloWorld - Crear"
COM_HELLOWORLD_HELLOWORLD_DETAILS="Detalles"
COM_HELLOWORLD_HELLOWORLD_EDITING="HelloWorld - Editar"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC="Este es el mensaje que se visualiza"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL="Mensaje"
COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING="Bienvenida"
COM_HELLOWORLD_HELLOWORLD_HEADING_ID="Id"
COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT="HelloWorld manager: Editar mensaje"
COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW="HelloWorld manager: Nuevo Mensaje"
COM_HELLOWORLD_MANAGER_HELLOWORLDS="Gestor HelloWorld"
COM_HELLOWORLD_N_ITEMS_DELETED_1="Un mensaje eliminado"
COM_HELLOWORLD_N_ITEMS_DELETED_MORE="%d mensajes eliminados"

Antes de empaquetar nuestro componente hagamos un recuento del contenido que debemos 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
  • site/language/index.html
  • site/language/es-ES/index.html
  • site/language/es-ES/es-ES.com_helloworld.ini
  • 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/forms/index.html
  • admin/models/forms/helloworld.xml
  • admin/models/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/views/helloworld/index.html
  • admin/views/helloworld/view.html.php
  • admin/views/helloworld/tmpl/index.html
  • admin/views/helloworld/tmpl/edit.php
  • admin/tables/index.html
  • admin/tables/helloworld.php
  • admin/language/es-ES/es-ES.com_helloworld.ini
  • admin/language/es-ES/es-ES.com_helloworld.menu.ini
  • admin/controllers/index.html
  • admin/controllers/helloworld.php
  • admin/controllers/helloworlds.php
  • language/es-ES/es-ES.ini
  • media/index.html
  • media/images/index.html
  • media/images/tux-16x16.png
  • media/images/tux-48x48.png

Modificando el archivo helloworld.xml tendríamos:

<?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 B</author>
       <authorEmail>email<;/authorEmail>
       <authorUrl>http://www.ejemplo.org</authorUrl>
       <copyright>Copyright Info</copyright>
       <license>Licencia Info</license>
       <version>0.0.10</version>
       <description>COM_HELLOWORLD_DESCRIPTION</description>

       <install> <!-- Se ejecuta al instalar -->
               <sql>
                       <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
               </sql>
       </install>
       <uninstall> <!-- Se ejecuta al desinstalar -->
               <sql>
                       <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
               </sql>
       </uninstall>
       <update> <!-- Se ejecuta al actualizar; 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>
               <folder>language</folder>
       </files>

       <media destination="com_helloworld" folder="media">
               <filename>index.html</filename>
               <folder>images</folder>
       </media>

       <administration>
              
               <menu img="../media/com_helloworld/images/tux-16x16.png">COM_HELLOWORLD_MENU
               </menu>

              <files folder="admin">
                       <!-- Sección principal de Copia de Ficheros -->
                       <filename>index.html</filename>
                       <filename>helloworld.php</filename>
                       <filename>controller.php</filename>

                       <!-- Sección de archivos SQL -->
                       <folder>sql</folder>

                       <!-- Sección de archivos de tablas -->
                       <folder>tables</folder>

                       <!-- Sección de archivos de modelos -->
                       <folder>models</folder>

                       <!-- Sección de archivos de vistas -->
                       <folder>views</folder>

                       <!-- Sección de archivos de controladores -->
                       <folder>controllers</folder>
               </files>

              <languages folder="admin">
                 <language tag="es-ES">language/es-ES/es-ES.com_helloworld.ini</language>
                 <language tag="es-ES">language/es-ES/es-ES.com_helloworld.sys.ini</language>
              </languages>
       </administration>

</extension>

Crea un archivo comprimido de este directorio o descarga directamente el archivo e instálalo utilizando el gestor de extensiones de Joomla!.

11- Añadir verificaciones

{Última Actualización: 30 Septiembre  2012 - 18:10 }

Verificación de los formularios (lado del cliente)

Los formularios se pueden verificar en el lado del cliente mediante código javascript.
En el archivo admin/views/helloworld/tmpl/edit.php ingrese las siguientes líneas:

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
JHtml::_('behavior.formvalidation');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id='.(int) $this->item->id); ?>"
     method="post" name="adminForm" id="helloworld-form" class="form-validate">
       <fieldset class="adminform">
               <legend><?php echo JText::_( 'COM_HELLOWORLD_HELLOWORLD_DETAILS' ); ?></legend>
               <?php foreach($this->form->getFieldset() as $field): ?>
                       <?php if (!$field->hidden): ?>
                               <?php echo $field->label; ?>
                       <?php endif; ?>
                       <?php echo $field->input; ?>
               <?php endforeach; ?>
       </fieldset>
       <div>
               <input type="hidden" name="task" value="helloworld.edit" />
               <?php echo JHtml::_('form.token'); ?>
       </div>
</form>

Se puede notar en el formulario html, contenido en el archivo admin/views/helloworld/tmpl/edit.php, que ahora posee la clase form-validate. Tambien podras ver que hemos añadido la llamada JHTML::_('behavior.formvalidation'); para decirle a Joomla! que utilice su formulario de validación javascript.
Modificamos el archivo admin/models/forms/helloworld.xml para indicar que el campo greeting se tiene que verificar:

<?xml version="1.0" encoding="utf-8"?>
<form
       addrulepath="/administrator/components/com_helloworld/models/rules"
>
       <fieldset>
               <field
                       name="id"
                       type="hidden"
               />
               <field
                       name="greeting"
                       type="text"
                       label="COM_HELLOWORLD_HELLOWORLD_GREETING_LABEL"
                       description="COM_HELLOWORLD_HELLOWORLD_GREETING_DESC"
                       size="40"
                       class="inputbox validate-greeting"
                       validate="greeting"
                       required="true"
                       default=""
               />
       </fieldset>
</form>

Note que por el momento la clase css es “inputbox validate-greeting” y que el atributo required está puesto a true. Esto significa que este campo es obligatorio y debe ser verificado por un validador de formulario del Framework de Joomla!.
Con tu gestor de archivo y editor favorito cree el archivo admin/models/forms/helloworld.js que contenga:

window.addEvent('domready', function() {
       document.formvalidator.setHandler('greeting',
               function (value) {
                       regex=/^[^0-9]+$/;
                       return regex.test(value);
       });
});

Se añade un controlador al formulario de validación de Joomla! para los campos que tienen la clase “validate-greeting”.  Cada vez que se modifica el campo greeting  el controlador se ejecutará para comprobar su validez (sin cifras). El último paso es verificar el formulario cuando se hace clic en el botón guardar.
Con tu gestor de archivo y editor favorito cree el archivo admin/views/helloworld/submitbutton.js que contenga:

Joomla.submitbutton = function(task)
{
       if (task == '')
       {
               return false;
       }
       else
       {
               var isValid=true;
               var action = task.split('.');
               if (action[1] != 'cancel' && action[1] != 'close')
               {
                       var forms = $$('form.form-validate');
                       for (var i=0;i<forms.length;i++)
                       {
                               if (!document.formvalidator.isValid(forms[i]))
                               {
                                       isValid = false;
                                       break;
                               }
                       }
               }

               if (isValid)
               {
                       Joomla.submitform(task);
                       return true;
               }
               else
               {
                       alert(Joomla.JText._('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE',
                                            'Some values are unacceptable'));
                       return false;
               }
       }
}

Esta función verifica que todos los formularios que tienen la clase css “form-validate” sean validados. Tenga en cuenta que se mostrará un mensaje de alerta, traducido por el Framework de Joomla!.
En la vista la clase HelloWorldViewHelloWorld tiene que ser modificada para usar estos archivos javascript: admin/views/helloworld/view.html.php 

<?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 HelloWorld
*/
class HelloWorldViewHelloWorld extends JView
{
       /**
        * Mostrar el metodo de la vista Hello
        * @return void
        */
       public function display($tpl = null)
       {
               // Obtener los datos
               $form = $this->get('Form');
               $item = $this->get('Item');
               $script = $this->get('Script');

               // Verificar existencia de errores.
               if (count($errors = $this->get('Errors')))
               {
                       JError::raiseError(500, implode('<br />', $errors));
                       return false;
               }
               // Asiganar datos
               $this->form = $form;
               $this->item = $item;
               $this->script = $script;

               // Establezca el Toolbar
               $this->addToolBar();

               // Mostrar la plantilla
               parent::display($tpl);

               // Establesca el Document
               $this->setDocument();
       }

       /**
        * Configuración del Toolbar
        */
       protected function addToolBar()
       {
               $input = JFactory::getApplication()->input;
               $input->set('hidemainmenu', true);
               $isNew = ($this->item->id == 0);
               JToolBarHelper::title($isNew ? JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW') : JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'), 'helloworld');
               JToolBarHelper::save('helloworld.save');
               JToolBarHelper::cancel('helloworld.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE');
       }
       /**
        * Método para configurar las propiedades del documento
        *
        * @return void
        */
       protected function setDocument()
       {
               $isNew = ($this->item->id < 1);
               $document = JFactory::getDocument();
               $document->setTitle($isNew ? JText::_('COM_HELLOWORLD_HELLOWORLD_CREATING') : JText::_('COM_HELLOWORLD_HELLOWORLD_EDITING'));
               $document->addScript(JURI::root() . $this->script);
               $document->addScript(JURI::root() . "/administrator/components/com_helloworld" . "/views/helloworld/submitbutton.js");
               JText::script('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE');
       }
}

Esta vista ahora:

  • Verifica si el modelo no tiene error
  • Agrega dos archivos Javascript
  • Inyecta traducciones usando la función javascript JText::script

El paso final es implementar una función getScript en el modelo HelloWorldModelHelloWorld. Modificando el archivo admin/models/helloworld.php tenemos:

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar la biblioteca modelform
jimport('joomla.application.component.modeladmin');

/**
* Modelo HelloWorld
*/
class HelloWorldModelHelloWorld extends JModelAdmin
{
       /**
        * Retornar una referencia a la tabla object, siempre que se cree.
        *
        * @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 para el modelo. Opcional.
        * @return      JTable   Un objeto de Base de Datos.
        * @since       2.5
        */
       public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())
       {
               return JTable::getInstance($type, $prefix, $config);
       }
       /**
        * Método para obtener el formulario de registro.
        *
        * @param       array   $data            Datos para el formulario.
        * @param       boolean  $loadData    True si el formulario carga sus propios datos (caso por     defecto), false si no.
        * @return       mixed     Un objeto JForm en caso de éxito, FALSE en caso de fallo
        * @since       2.5
        */
       public function getForm($data = array(), $loadData = true)
       {
               // Obtener el formulario
               $form = $this->loadForm('com_helloworld.helloworld', 'helloworld',
                                       array('control' => 'jform', 'load_data' => $loadData));
               if (empty($form))
               {
                       return false;
               }
               return $form;
       }
       /**
        * Método para obtener los script que se deben incluir en el formulario
        *
        * @return string       Archivos Script
        */
       public function getScript()
       {
               return 'administrator/components/com_helloworld/models/forms/helloworld.js';
       }
       /**
        * Método para obtener los datos que deben ser inyectados en el formulario.
        *
        * @return      mixed   Los datos para el formulario.
        * @since       2.5
        */
       protected function loadFormData()
       {
               // Compruebe la sesión de datos del formulario previamente introducidos.
               $data = JFactory::getApplication()->getUserState('com_helloworld.edit.helloworld.data', array());
               if (empty($data))
               {
                       $data = $this->getItem();
               }
               return $data;
       }
}

Verificación de los formularios (lado del servidor)

Las verificaciones de los formularios en el lado del servidor se realiza mediante la herencia de la clase JControllerForm. Hemos especificado en el archivo admin/models/forms/helloworld.xml que la función de validación del servidor usará el archivo greeting.php.
Con tu gestor de archivos y editor favorito crea el archivo admin/models/rules/greeting.php que contenga:

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar la biblioteca formrule de Joomla
jimport('joomla.form.formrule');

/**
* Reglas de la clase formulario para el Framework de Joomla.
*/
class JFormRuleGreeting extends JFormRule
{
       /**
        * Una expresión regular.
        *
        * @access      protected
        * @var         string
        * @since       2.5
        */
       protected $regex = '^[^0-9]+$';
}

Empaqueta tu componente e instalalo mediante el gestor de extensiones de Joomla! o descarga el archivo directamente.

12- Añadir categorías

{Última Actualización: 27 Septiembre  2012 - 03:11 }

El Framework de Joomla! ha implementado el uso de categorías para todos los componentes. Añadir esta habilidad es bastante simple.

Modificar el SQL

Para gestionar las categorías, tenemos que cambiar las tablas SQL.
Con tu editor favorito, modifica el archivo admin/sql/install.mysql.utf8.sql y añade estas líneas:

DROP TABLE IF EXISTS `#__helloworld`;

CREATE TABLE `#__helloworld` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `greeting` VARCHAR(25) NOT NULL,
 `catid` INT(11) NOT NULL DEFAULT '0',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

INSERT INTO `#__helloworld` (`greeting`) VALUES
       ('Hello World!'),
       ('Good bye World!');

Recuerden que esto trae consigo que modifiquemos el siguiente fichero admin/sql/updates/mysql/0.0.12.sql:

ALTER TABLE `#__helloworld` ADD `catid` INT(11) NOT NULL DEFAULT '0'

Modificar el formulario

El mensaje HelloWorld puede pertenecer ahora a una categoría. Tenemos que modificar el formulario de edición. Añade estas líneas al archivo admin/models/forms/helloworld.xml:

<?xml version="1.0" encoding="utf-8"?>
<form
       addrulepath="/administrator/components/com_helloworld/models/rules"
>
       <fieldset>
               <field
                       name="id"
                       type="hidden"
               />
               <field
                       name="greeting"
                       type="text"
                       label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"
                       description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"
                       size="40"
                       class="inputbox validate-greeting"
                       validate="greeting"
                       required="true"
                       default=""
               />
               <field
                       name="catid"
                       type="category"
                       extension="com_helloworld"
                       class="inputbox"
                       default=""
                       label="COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL"
                       description="COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC"
                       required="true"
               >
                       <option value="0">JOPTION_SELECT_CATEGORY</option>
               </field>
       </fieldset>
</form>

Nota: La categoría puede ser 0 (lo que indica que no hay categoría)

Modificar el tipo de menú

El tipo de menú HelloWorld muestra una lista desplegable con todos los mensajes. Si el mensaje está categorizado, tenemos que añadir la categoría en la presentación.
En el archivo admin/models/fields/helloworld.php, añade las siguientes líneas:

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die;

// importar el tipo de campo list
jimport('joomla.form.helper');
JFormHelper::loadFieldClass('list');

/**
* Clase de campo de formulario para el componente HelloWorld
*/
class JFormFieldHelloWorld extends JFormFieldList
{
       /**
        * El tipo de campo.
        *
        * @var         string
        */
       protected $type = 'HelloWorld';

       /**
        * Método para obtener una lista de opciones para entrada de lista.
        *
        * @return      array           Array de opciones JHmtl.
        */
       protected function getOptions()
       {
               $db = JFactory::getDBO();

               /// $query = new JDatabaseQuery; ATENCIÓN - Hay un error en esta línea, JDatabaseQuery es una clase abstracta
               $query = $db->getQuery(true); // ESTE ES EL ARREGLO, OJO DEBE SER MODIFICADO EN ARCHIVO COMPRIMIDO (SI ES QUE LO DESCARGA Y LO USA)
               $query->select('#__helloworld.id as id,greeting,#__categories.title as category,catid');
               $query->from('#__helloworld');
               $query->leftJoin('#__categories on catid=#__categories.id');
               $db->setQuery((string)$query);
               $messages = $db->loadObjectList();
               $options = array();
               if ($messages)
               {
                       foreach($messages as $message)
                       {
                               $options[] = JHtml::_('select.option', $message->id, $message->greeting .
                                                     ($message->catid ? ' (' . $message->category . ')' : ''));
                       }
               }
               $options = array_merge(parent::getOptions(), $options);
               return $options;
       }
}

Ahora mostrará la categoría entre paréntesis.

Gestionar el submenú

El componente com_categories permite configurar el submenú utilizando el archivo helper. Con tu gestor y editor de archivos preferido, crea un archivo admin/helpers/helloworld.php que contenga estas líneas:

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die;

/**
* Ayuda del componente HelloWorld.
*/
abstract class HelloWorldHelper
{
       /**
        * Configurar la barra de enlaces.
        */
       public static function addSubmenu($submenu)
       {
               JSubMenuHelper::addEntry(JText::_('COM_HELLOWORLD_SUBMENU_MESSAGES'),
                                        'index.php?option=com_helloworld', $submenu == 'messages');
               JSubMenuHelper::addEntry(JText::_('COM_HELLOWORLD_SUBMENU_CATEGORIES'), 'index.php?option=com_categories&view=categories&extension=com_helloworld', $submenu == 'categories');
               // configurar algunas propiedades globales
               $document = JFactory::getDocument();
               $document->addStyleDeclaration('.icon-48-helloworld ' . '{background-image: url(../media/com_helloworld/images/tux-48x48.png);}');
               if ($submenu == 'categories')
               {
                       $document->setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION_CATEGORIES'));
               }
       }
}

Esta función será llamada automáticamente por el componente com_categories. Sepa que:

  • Cambiará el submenú
  • Cambiará algunas propiedades css (para mostrar iconos)
  • Cambiará el título del navegador si el submenú es categories
  • Cambiará el título y añadirá un botón preferences

Tenemos que modificar el controlador general para llamar a esta función y modificar el punto de entrada del componente (la clase css .icon-48-helloworld se configura ahora en la función addSubmenu)

admin/controller.php 

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar librería controller de Joomla
jimport('joomla.application.component.controller');

/**
* Controlador General del componente HelloWorld
*/
class HelloWorldController extends JController
{
       /**
        * mostrar tarea
        *
        * @return void
        */
       function display($cachable = false)
       {
               // configurar vista por defecto si no está configurada
               $input = JFactory::getApplication()->input;
               $input->set('view', $input->getCmd('view', 'HelloWorlds'));

               // llamar comportamiento padre
               parent::display($cachable);

               // Configurar el submenú
               HelloWorldHelper::addSubmenu('messages');
       }
}

admin/helloworld.php

<?php
// No permitir acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// requerir archivo de ayuda
JLoader::register('HelloWorldHelper', dirname(__FILE__) . DS . 'helpers' . DS . 'helloworld.php');

// importar librería de controladores de Joomla
jimport('joomla.application.component.controller');

// Obtener una instancia del controlador prefijado por HelloWorld
$controller = JController::getInstance('HelloWorld');

// Realizar la tarea de solicitud
$input = JFactory::getApplication()->input;
$controller->execute($input->getCmd('task'));

// Redirigir si está configurado por el controlador
$controller->redirect();

Añadir algunas cadenas de traducción

Algunas cadenas tienen que ser traducidas. En el archivo admin/language/es-ES/es-ES.com_helloworld.ini, añade las siguientes líneas:

COM_HELLOWORLD="Hello World!"
COM_HELLOWORLD_ADMINISTRATION="HelloWorld - Administración"
COM_HELLOWORLD_ADMINISTRATION_CATEGORIES="HelloWorld - Categorías"
COM_HELLOWORLD_HELLOWORLD_CREATING="HelloWorld - Crear"
COM_HELLOWORLD_HELLOWORLD_DETAILS="Detalles"
COM_HELLOWORLD_HELLOWORLD_EDITING="HelloWorld - Editar"
COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE="Algunos valores no se pueden aceptar"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC="Categoría a la que pertenecen los mensajes"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL="Categoría"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC="Se mostrará este mensaje"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL="Mensaje"
COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING="Bienvenida"
COM_HELLOWORLD_HELLOWORLD_HEADING_ID="Id"
COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT="Gestor de HelloWorld: Editar Mensaje"
COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW="Gestor de HelloWorld: Nuevo Mensaje"
COM_HELLOWORLD_MANAGER_HELLOWORLDS="Gestor de HelloWorld"
COM_HELLOWORLD_N_ITEMS_DELETED_1="Un mensaje eliminado"
COM_HELLOWORLD_N_ITEMS_DELETED_MORE="%d mensajes eliminados"
COM_HELLOWORLD_SUBMENU_MESSAGES="Mensajes"
COM_HELLOWORLD_SUBMENU_CATEGORIES="Categorías"

Nuestro archivo helloworld.xml queda de la siguiente forma:

<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">

       <name>COM_HELLOWORLD</name>       
       <creationDate>Octubre 2012</creationDate>
       <author>Carlos R & Andoitz B</author>
       <authorEmail>email</authorEmail>
       <authorUrl>http://www.ejemplo.org</authorUrl>
       <copyright>Copyright Info</copyright>
       <license>Licencia Info</license>       
       <version>0.0.12</version>       
       <description>COM_HELLOWORLD_DESCRIPTION</description>

       <install>
               <sql>
                       <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
               </sql>
       </install>
       <uninstall>
               <sql>
                       <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
               </sql>
       </uninstall>
       <update>
               <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>
               <folder>language</folder>
       </files>

       <media destination="com_helloworld" folder="media">
               <filename>index.html</filename>
               <folder>images</folder>
       </media>

       <administration>
              
               <menu img="../media/com_helloworld/images/tux-16x16.png">COM_HELLOWORLD_MENU</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>                       
                       <folder>views</folder>                       
                       <folder>controllers</folder>

                       <!-- Sección de archivos helpers -->
                       <folder>helpers</folder>
               </files>

               <languages folder="admin">
                  <language tag="es-ES">language/es-ES/es-ES.com_helloworld.ini</language>
                  <language tag="es-ES">language/es-ES/es-ES.com_helloworld.sys.ini</language>
               </languages>
       </administration>

</extension>

Ya sabes que hacer para comprobar esto. Recuerda también que puedes descargar el archivo directamente, pero ten presente antes de instalarlo, modificar la línea en el archivo admin/models/fields/helloworld.php.

13- Añadir parámetros de configuración

{Última Actualización: 30 Septiembre  2012 - 18:11 }

El Framework de Joomla! permite el uso de parámetros almacenados en cada componente. Con el gestor de archivo y editor favorito cree el archivo admin/config.xml que contenga las siguientes líneas:

<?xml version="1.0" encoding="utf-8"?>
<config>
       <fieldset
               name="greetings"
               label="COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_LABEL"
               description="COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_DESC"
       >
               <field
                       name="show_category"
                       type="radio"
                       label="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL"
                       description="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC"
                       default="0"
               >
                       <option value="0">JHIDE</option>
                       <option value="1">JSHOW</option>
               </field>
       </fieldset>
</config>

Este archivo será leído por el componente com_config del núcleo Joomla!. Por el momento, sólo hemos definido un parámetro: ¿El título de la categoría deberá ser mostrado en la interfaz pública?
La mejor manera de establecer los parámetros es poner un botón Preferences  en la barra de herramientas.
Modificando el archivo admin/views/helloworlds/view.html.php nos queda:

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar biblioteca view de Joomla
jimport('joomla.application.component.view');

/**
* Vista HelloWorlds
*/
class HelloWorldViewHelloWorlds extends JView
{
       /**
        * Metodo para mostrar la vista HelloWorlds
        * @return void
        */
       function display($tpl = null)
       {
               // Obtener los datos del 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 datos a la vista
               $this->items = $items;
               $this->pagination = $pagination;

               // Establecer el Toolbar
               $this->addToolBar();

               // Mostrar la plantilla
               parent::display($tpl);

               // Establecer el Document
               $this->setDocument();
       }

       /**
        * Configuración del toolbar
        */
       protected function addToolBar()
       {
               JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'), 'helloworld');
               JToolBarHelper::deleteListX('', 'helloworlds.delete');
               JToolBarHelper::editListX('helloworld.edit');
               JToolBarHelper::addNewX('helloworld.add');
               JToolBarHelper::preferences('com_helloworld');
       }
       /**
        * Método para configurar las propiedades del document
        *
        * @return void
        */
       protected function setDocument()
       {
               $document = JFactory::getDocument();
               $document->setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION'));
       }
}

El uso de parámetros de configuración como valor predeterminado

Queremos definir este parámetro individualmente en todos los datos HelloWorld. Modificando el archivo admin/models/forms/helloworld.xml nos queda:

<?xml version="1.0" encoding="utf-8"?>
<form
       addrulepath="/administrator/components/com_helloworld/models/rules"
>
       <fieldset name="details">
               <field
                       name="id"
                       type="hidden"
               />
               <field
                       name="greeting"
                       type="text"
                       label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"
                       description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"
                       size="40"
                       class="inputbox validate-greeting"
                       validate="greeting"
                       required="true"
                       default=""
               />
               <field
                       name="catid"
                       type="category"
                       extension="com_helloworld"
                       class="inputbox"
                       default=""
                       label="COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL"
                       description="COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC"
                       required="true"
               >
                       <option value="0">JOPTION_SELECT_CATEGORY</option>
               </field>
       </fieldset>
       <fields name="params">
               <fieldset
                       name="params"
                       label="JGLOBAL_FIELDSET_DISPLAY_OPTIONS"
               >
                       <field
                               name="show_category"
                               type="list"
                               label="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL"
                               description="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC"
                               default=""
                       >
                               <option value="">JGLOBAL_USE_GLOBAL</option>
                               <option value="0">JHIDE</option>
                               <option value="1">JSHOW</option>
                       </field>
               </fieldset>
       </fields>
</form>

Definimos el mismo parámetro para cada mensaje con un valor adicional: Use global.

Modificar el SQL

Los datos ahora contiene un nuevo parámetro: params. La estructura SQL tiene que ser modificada. Con tu editor favorito coloque estas líneas en el archivo admin/sql/install.mysql.utf8.sql :

DROP TABLE IF EXISTS `#__helloworld`;

CREATE TABLE `#__helloworld` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `greeting` VARCHAR(25) NOT NULL,
 `catid` INT(11) NOT NULL DEFAULT '0',
 `params` TEXT NOT NULL DEFAULT '',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

INSERT INTO `#__helloworld` (`greeting`) VALUES
       ('Hello World!'),
       ('Good bye World!');

Hecho esto tenemos que modificar el archivo admin/sql/updates/mysql/0.0.13.sql :
ALTER TABLE `#__helloworld` ADD `params` VARCHAR(1024) NOT NULL DEFAULT '';

La TableHelloWorld tiene que ser modificada con el fin de de tratar con estos parámetros: ellos se almacenan en un formato JSON y obtienen la clase JParameter. Modificando el archivo admin/tables/helloworld.php nos queda:

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar la biblioteca table de Joomla
jimport('joomla.database.table');

/**
* Clase Hello Table
*/
class HelloWorldTableHelloWorld extends JTable
{
       /**
        * Constructor
        *
        * @param object Objeto de conexión a la Base de datos
        */
       function __construct(&$db)
       {
               parent::__construct('#__helloworld', 'id', $db);
       }
       /**
        * Overloaded bind function
        *
        * @param       array           nombre del array
        * @return      null|string     null es que la operación fue satisfactoria, de lo contrario devuelve un error
        * @see JTable:bind
        * @since 1.5
        */
       public function bind($array, $ignore = '')
       {
               if (isset($array['params']) && is_array($array['params']))
               {
                       // Convert the params field to a string.
                       $parameter = new JRegistry;
                       $parameter->loadArray($array['params']);
                       $array['params'] = (string)$parameter;
               }
               return parent::bind($array, $ignore);
       }

       /**
        * Overloaded load function
        *
        * @param       int $pk llave primaria
        * @param       boolean $reset resetear los datos
        * @return      boolean
        * @see JTable:load
        */
       public function load($pk = null, $reset = true)
       {
               if (parent::load($pk, $reset))
               {
                       // Convertir el campo params a un registro.
                       $params = new JRegistry;                 
                      // loadJSON esta @obsoleto    12.1  Use loadString pasandole JSON como formato en su lugar.
                      // $params->loadString($this->item->params, 'JSON');
                      // "item" no deben estar presentes.
                      $params->loadJSON($this->params);

                       $this->params = $params;
                       return true;
               }
               else
               {
                       return false;
               }
       }
}

Modificando la Administración

La administración, tiene la vista de edición de las opciones para el administrador. Añadiendo las siguientes líneas al archivo admin/views/helloworld/tmpl/edit.php quedaría:

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
JHtml::_('behavior.formvalidation');
$params = $this->form->getFieldsets('params');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id='.(int) $this->item->id); ?>"
     method="post" name="adminForm" id="helloworld-form" class="form-validate">

       <div class="width-60 fltlft">
               <fieldset class="adminform">
                       <legend><?php echo JText::_( 'COM_HELLOWORLD_HELLOWORLD_DETAILS' ); ?></legend>
                       <ul class="adminformlist">
<?php                      foreach($this->form->getFieldset('details') as $field): ?>
                                <li><?php echo $field->label;echo $field->input;?></li>
<?php                      endforeach; ?>
                       </ul>
               </fieldset>
       </div>

       <div class="width-40 fltrt">
<?php        echo JHtml::_('sliders.start', 'helloworld-slider');
            foreach ($params as $name => $fieldset):
               echo JHtml::_('sliders.panel', JText::_($fieldset->label), $name.'-params');
               if (isset($fieldset->description) && trim($fieldset->description)): ?>
                       <p class="tip"><?php echo $this->escape(JText::_($fieldset->description));?></p>
<?php           endif;?>
               <fieldset class="panelform" >
                       <ul class="adminformlist">
<?php                        foreach ($this->form->getFieldset($name) as $field) : ?>
                                <li><?php echo $field->label; ?><?php echo $field->input; ?></li>
<?php                        endforeach; ?>
                       </ul>
               </fieldset>
<?php        endforeach; ?>

               <?php echo JHtml::_('sliders.end'); ?>
       </div>

       <div>
               <input type="hidden" name="task" value="helloworld.edit" />
               <?php echo JHtml::_('form.token'); ?>
       </div>
</form>

Modificando la Interfaz Pública

La interfaz pública tiene que ser modificada, de acuerdo al nuevo parámetro show_category.
Tenemos que modificar el modelo:

  • Tiene que combinar los parámetros globales y los parámetros individuales
  • Tiene que proporcionar la categoría

Entonces modificando el archivo site/models/helloworld.php quedaría:

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar biblioteca  modelitem de Joomla
jimport('joomla.application.component.modelitem');

/**
* Modelo HelloWorld
*/
class HelloWorldModelHelloWorld extends JModelItem
{
       /**
        * @var object item
        */
       protected $item;

       /**
        * Método para rellenar automáticamente el estado del modelo.
        *
        * Este método sólo debe ser llamado una vez por instancia         
        * y está diseñado para ser llamado en la primera llamada
        * del metodo getState() a menos que el indicador de
        * configuración del modelo ignore la solicitud establecida
        *
        * Nota. Llamando a getState en este método dará lugar a la recursividad.
        *
        * @return      void
        * @since       2.5
        */
       protected function populateState()
       {
               $app = JFactory::getApplication();
               // Obtener el id del mensaje
               $input = JFactory::getApplication()->input;
               $id = $input->getInt('id');
               $this->setState('message.id', $id);

               // Cargar los parámetros.
               $params = $app->getParams();
               $this->setState('params', $params);
               parent::populateState();
       }

       /**
        * Retornar una referencia a Table object, siempre creandola.
        *
        * @param       type    El tipo de tabla a instanciar
        * @param       string  Un prefijo para el nombre de la clase de la tabla. Opcional.
        * @param       array   Configuración del array para el modelo. Opcional.
        * @return      JTable  Un objeto Base de Datos
        * @since       2.5
        */
       public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())
       {
               return JTable::getInstance($type, $prefix, $config);
       }

       /**
        * Obtener el mensaje
        * @return object El mensaje que se muestra al usuario
        */
       public function getItem()
       {
               if (!isset($this->item))
               {
                       $id = $this->getState('message.id');
                       $this->_db->setQuery($this->_db->getQuery(true)
                               ->from('#__helloworld as h')
                               ->leftJoin('#__categories as c ON h.catid=c.id')
                               ->select('h.greeting, h.params, c.title as category')
                               ->where('h.id=' . (int)$id));
                       if (!$this->item = $this->_db->loadObject())
                       {
                               $this->setError($this->_db->getError());
                       }
                       else
                       {
                               // Cargar la cadena JSON
                               $params = new JRegistry;
                               // loadJSON esta @obsoleto    12.1  Use loadString pasandole JSON como formato a usar
                               //$params->loadString($this->item->params, 'JSON');
                               $params->loadJSON($this->item->params);
                               $this->item->params = $params;

                               // Combinar los parametros globales con los parámetros del artículo
                               $params = clone $this->getState('params');
                               $params->merge($this->item->params);
                               $this->item->params = $params;
                       }
               }
               return $this->item;
       }
}

La vista tiene que preguntarle al modelo por la categoría. Con tu editor favorito agregue estas líneas al archivo site/views/helloworld/view.html.php :

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar biblioteca view de Joomla
jimport('joomla.application.component.view');

/**
* Clase View HTML para el componente HelloWorld
*/
class HelloWorldViewHelloWorld extends JView
{
       // Sobrescribir método JView
       function display($tpl = null)
       {
               // Asignar los datos a la vista
               $this->item = $this->get('Item');

               // Verificar existencia de errores
               if (count($errors = $this->get('Errors')))
               {
                       JError::raiseError(500, implode('<br />', $errors));
                       return false;
               }
               // Mostrar la vista
               parent::display($tpl);
       }
}

El diseño ahora puede o no puede visualizar correctamente la categoría. Con su editor favorito ponga las siguientes líneas en el archivo site/views/helloworld/tmpl/default.php :

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
?>
<h1><?php echo $this->item->greeting.(($this->item->category and $this->item->params->get('show_category'))
                                     ? (' ('.$this->item->category.')') : ''); ?>
</h1>

Agregando algunas cadenas de traducción

Algunas cadenas tienen que ser añadidas al archivo admin/language/es-ES/es-ES.com_helloworld.ini :

COM_HELLOWORLD="Hello World!"
COM_HELLOWORLD_ADMINISTRATION="HelloWorld - Administración"
COM_HELLOWORLD_ADMINISTRATION_CATEGORIES="HelloWorld - Categorías"
COM_HELLOWORLD_HELLOWORLD_CREATING="HelloWorld - Crear"
COM_HELLOWORLD_HELLOWORLD_DETAILS="Detalles"
COM_HELLOWORLD_HELLOWORLD_EDITING="HelloWorld - Editar"
COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE="Algunos valores son inaceptables"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC="El mensaje pertenece a la categoría"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL="Categoría"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC="Este mensaje se mostrará"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL="Mensaje"
COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL="Mostrar categoría"
COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC="Si esta puesto en mostrar, el título de la categoría del mensaje será mostrada."
COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING="Bienvenida"
COM_HELLOWORLD_HELLOWORLD_HEADING_ID="Id"
COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT="HelloWorld manager: Editar Mensaje"
COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW="HelloWorld manager: Nuevo Mensaje"
COM_HELLOWORLD_MANAGER_HELLOWORLDS="Gestor HelloWorld"
COM_HELLOWORLD_N_ITEMS_DELETED_1="Un mensaje eliminado"
COM_HELLOWORLD_N_ITEMS_DELETED_MORE="%d mensajes eliminados"
COM_HELLOWORLD_SUBMENU_MESSAGES="Mensajes"
COM_HELLOWORLD_SUBMENU_CATEGORIES="Categorias"
COM_HELLOWORLD_CONFIGURATION="Configurar HelloWorld"
COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_LABEL="Configurar Mensaje"
COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_DESC="Los ajustes que se aplicarán a todos los mensajes por defecto"

Modificando nuestro archivo helloworld.xml quedaría:

<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">

       <name>COM_HELLOWORLD</name>       
       <creationDate>Octubre 2012</creationDate>
       <author>Carlos R & Andoitz B</author>
       <authorEmail>email</authorEmail>
       <authorUrl>http://www.ejemplo.org</authorUrl>
       <copyright>Copyright Info</copyright>
       <license>Licencia Info</license>       
       <version>0.0.13</version>       
       <description>COM_HELLOWORLD_DESCRIPTION</description>

       <install>
               <sql>
                       <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
               </sql>
       </install>
       <uninstall>
               <sql>
                       <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
               </sql>
       </uninstall>
       <update>
               <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>
               <folder>language</folder>
       </files>

       <media destination="com_helloworld" folder="media">
               <filename>index.html</filename>
               <folder>images</folder>
       </media>

       <administration>
              
               <menu img="../media/com_helloworld/images/tux-16x16.png">COM_HELLOWORLD_MENU</menu>
              
               <files folder="admin">                       
                       <filename>index.html</filename>
                       <filename>config.xml</filename>
                       <filename>helloworld.php</filename>
                       <filename>controller.php</filename>                       
                       <folder>sql</folder>                       
                       <folder>tables</folder>                       
                       <folder>models</folder>                       
                       <folder>views</folder>                       
                       <folder>controllers</folder>                       
                       <folder>helpers</folder>
               </files>

               <languages folder="admin">
                  <language tag="es-ES">language/es-ES/es-ES.com_helloworld.ini</language>
                  <language tag="es-ES">language/es-ES/es-ES.com_helloworld.sys.ini</language>
               </languages>
       </administration>

</extension>

Empaqueta tu directorio e instalalo o descarga el archivo directamente, pero antes de instalarlo recuerda los cambios antes explicados (debido a que están obsoletos).

14- Añadiendo el control de acceso (ACL)

{Última Actualización: 11  Octubre  2012 - 07:11 }

Con el control de acceso de joomla!, podemos definir la posibilidad de permitir o negar acciones en nuestro componente. En este ejemplo usamos las acciones que se definen en el núcleo de Joomla!.  Para el componente en su conjunto: core.admin (acceso a la configuración) y core.manage (acceso desde la administración). Y en las acciones de los distintos niveles, como crear, eliminar y editar. Además de las acciones del núcleo, puedes definir tus propias acciones, pero que a menudo no es necesario y no se muestra en este ejemplo. Acceso de Lectura / Escritura  no se gestiona a través de esas acciones, pero si con niveles de acceso de las Vista; consulte la documentación general sobre Joomla! ACL para eso.
En la tabla # __assets la lista actual almacena: que grupos de usuarios se les concede o se les deniega hacer que acciones y en que recurso (assets).  Esta es la implementación de la lista de control de acceso (ACL).
En este artículo vamos a mostrar cómo agregar y utilizar los permisos de acceso a diferentes niveles de granularidad: para el componente como un todo, para las categorías y para los elementos individualmente.

Requisitos mínimos de ACL a nivel de componente

Hay dos acciones que deben ser definidas a nivel de componente para los componentes en Joomla! 2.5, para ofrecer un soporte básico de ACL.

  • Configuración (core.admin): ¿Qué grupos tiene permitido configurar el componente a través del botón “Opciones” de la barra de herramientas?
  • Acceso (core.manage): ¿Qué grupos tienen acceso al componente desde la administración?

Este soporte básico de ACL se realiza en 4 pasos sencillos:

 

Añadir los dos requisitos mínimos a nivel de componente en el archivo access.xml

Agregar un archivo access.xml a la raíz de la carpeta admin. Coloque las 2 acciones básicas para el componente com_helloworld en este archivo.

<?xml version="1.0" encoding="utf-8" ?>
<access component="com_helloworld">
       <section name="component">
               <action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
               <action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
       </section>
</access>

Añadir los permisos fieldset en el archivo config.xml

Agregue los siguientes permisos fieldset en el archivo admin/config.xml con el fin de ser capaz de establecer permisos de nivel en nuestros componente:

<fieldset
               name="permissions"
               label="JCONFIG_PERMISSIONS_LABEL"
               description="JCONFIG_PERMISSIONS_DESC"
       >
               <field
                       name="rules"
                       type="rules"
                       label="JCONFIG_PERMISSIONS_LABEL"
                       class="inputbox"
                       validate="rules"
                       filter="rules"
                       component="com_helloworld"
                       section="component"
               />
       </fieldset>

Vea más abajo un ejemplo más elaborado del archivo config.xml , como ejemplo adicional para el lugar exacto dónde insertar este código.

Agregar el botón 'Opciones' a la barra de herramientas, siempre y cuando, el usuario está autorizado a ello

Añadir las siguientes líneas en el archivo admin/views/helloworlds/view.html.php :

// Botón Opciones.
   if (JFactory::getUser()->authorise('core.admin', 'com_helloworld'))   

{        

JToolBarHelper::preferences('com_helloworld');
}

Vea más abajo un ejemplo mejor elaborado de admin/views/helloworlds/view.html.php donde JToolBarHelper::preferences('com_helloworld') se realiza en el método addToolBar() junto con los otros botones de la barra de herramientas y la comprobación JUser->authorise() que se realiza en el archivo helper admin/helpers/helloworld.php , dando lugar a las propiedades $canDo .

Restringir el acceso al componente desde la administración, a grupos de usuarios autorizados

Para controlar esto, debes ingresar las siguientes líneas en el archivo admin/helloworld.php :

// Verificación de Acceso: Este usuario puede acceder al componente desde la administración?
if (!JFactory::getUser()->authorise('core.manage', 'com_helloworld'))
{
       return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR'));
}

Vea más abajo un ejemplo mejor elaborado de todo el código del archivo admin/helloworld.php.

Añadir más acciones a nivel de categoría y a nivel de elemento

Al agregar más acciones y más niveles, los cuatro pasos anteriormente descritos se realizan también. Pero esto provoca que también tengamos que hacer los siguientes pasos:

Describir las acciones para controlar el acceso a

Cada componente (o parte de él) tiene su propio conjunto de permisos que pueden ser controlados. Se describe en el archivo access.xml que se encuentra en la raíz de la carpeta de admin. En este ejemplo las acciones cuyo acceso está controlado se dividen en tres secciones: a nivel de componente, a nivel de categoría y a nivel del elemento. Un "elemento" es un "message" en nuestro componente de ejemplo, de ahí el nombre de la tercera sección.

<?xml version="1.0" encoding="utf-8" ?>
<access component="com_helloworld">
       <section name="component">
               <action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
               <action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
               <action name="core.create" title="JACTION_CREATE" description="JACTION_CREATE_COMPONENT_DESC" />
               <action name="core.delete" title="JACTION_DELETE" description="JACTION_DELETE_COMPONENT_DESC" />
               <action name="core.edit" title="JACTION_EDIT" description="JACTION_EDIT_COMPONENT_DESC" />
       </section>
       <section name="category">
               <action name="core.create" title="JACTION_CREATE" description="COM_CATEGORIES_ACCESS_CREATE_DESC" />
               <action name="core.delete" title="JACTION_DELETE" description="COM_CATEGORIES_ACCESS_DELETE_DESC" />
               <action name="core.edit" title="JACTION_EDIT" description="COM_CATEGORIES_ACCESS_EDIT_DESC" />
               <action name="core.edit.state" title="JACTION_EDITSTATE" description="COM_CATEGORIES_ACCESS_EDITSTATE_DESC" />
               <action name="core.edit.own" title="JACTION_EDITOWN" description="COM_CATEGORIES_ACCESS_EDITOWN_DESC" />
       </section>
       <section name="message">
               <action name="core.delete" title="JACTION_DELETE" description="COM_HELLOWORLD_ACCESS_DELETE_DESC" />
               <action name="core.edit" title="JACTION_EDIT" description="COM_HELLOWORLD_ACCESS_EDIT_DESC" />
       </section>
</access>

Agregar la configuración de permisos en las preferencias del componente

Puesto que ahora se pueden utilizar los permisos de control de acceso en nuestro componente, tenemos que ser capaces de establecerlos desde nuestro componente. Esto se hace en las preferencias de este componente: la pantalla que aparece después de hacer clic en el botón "Opciones". El archivo config.xml es una forma de definición para las Preferencias. Podríamos definir también aquí las acciones a nivel del componente, pero ahora es preferible poner estas acciones en el archivo access.xml: de esa manera todas las reglas de acceso de este componente se encuentran en un solo lugar.

admin/config.xml 

<?xml version="1.0" encoding="utf-8"?>
<config>
       <fieldset
               name="greetings"
               label="COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_LABEL"
               description="COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_DESC"
       >
               <field
                       name="show_category"
                       type="radio"
                       label="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL"
                       description="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC"
                       default="0"
               >
                       <option value="0">JHIDE</option>
                       <option value="1">JSHOW</option>
               </field>
       </fieldset>
       <fieldset
               name="permissions"
               label="JCONFIG_PERMISSIONS_LABEL"
               description="JCONFIG_PERMISSIONS_DESC"
       >
               <field
                       name="rules"
                       type="rules"
                       label="JCONFIG_PERMISSIONS_LABEL"
                       class="inputbox"
                       validate="rules"
                       filter="rules"
                       component="com_helloworld"
                       section="component"
               />
       </fieldset></config>

Viendo sólo los botones adecuados de la barra de herramientas

Los botones de la barra de herramientas a mostrar depende de los permisos de control de acceso para el usuario. Ponemos todos los permisos para este usuario en la propiedad $canDo de la vista, de modo que al final pueda referirse a ella en los diseños (en la edición de los formularios, por ejemplo).
En el archivo admin/views/helloworlds/view.html.php ubicamos las siguientes líneas:

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar biblioteca view de Joomla
jimport('joomla.application.component.view');

/**
* Vista HelloWorlds
*/
class HelloWorldViewHelloWorlds extends JViewLegacy
{
       protected $items;
       protected $pagination;
       protected $canDo;
       /**
        * metodo para mostrar la vista HelloWorlds
        * @return void
        */
       function display($tpl = null)
       {
               // Obtener los datos del modelo
               $this->items = $this->get('Items');
               $this->pagination = $this->get('Pagination');

               // ¿Qué tipos de permiso tiene este usuario? ¿Qué puede el o ella hacer?
              $this->canDo = HelloWorldHelper::getActions();
               // Verificar existencia de errores
               if (count($errors = $this->get('Errors')))
               {
                       JError::raiseError(500, implode('<br />', $errors));
                       return false;
               }

               // Establecer la barra de herramientas
               $this->addToolBar();

               // Mostrar la plantilla
               parent::display($tpl);

               // Establecer el documento
               $this->setDocument();
       }

       /**
        * Setting the toolbar
        */
       protected function addToolBar()
       {
               JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'), 'helloworld');
               if ($this->canDo->get('core.create'))
               {
                       JToolBarHelper::addNew('helloworld.add', 'JTOOLBAR_NEW');
               }
               if ($this->canDo->get('core.edit'))
               {
                       JToolBarHelper::editList('helloworld.edit', 'JTOOLBAR_EDIT');
               }
               if ($this->canDo->get('core.delete'))
               {
                       JToolBarHelper::deleteList('', 'helloworlds.delete', 'JTOOLBAR_DELETE');
               }
               if ($this->canDo->get('core.admin'))
               {
                       JToolBarHelper::divider();
                       JToolBarHelper::preferences('com_helloworld');
               }
       }
       /**
        * Método para configurar las propiedades del documento
        *
        * @return void
        */
       protected function setDocument()
       {
               $document = JFactory::getDocument();
               $document->setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION'));
       }
}

En el archivo admin/views/helloworld/view.html.php ubica las siguientes líneas:

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar biblioteca  view de Joomla
jimport('joomla.application.component.view');

/**
* Vista HelloWorld
*/
class HelloWorldViewHelloWorld extends JViewLegacy
{
       protected $form;
       protected $item;
       protected $script;
       protected $canDo;
       /**
        * Mostrar el metodo de la vista  Hello
        * @return void
        */
       public function display($tpl = null)
       {
               // Obtener los datos
               $this->form = $this->get('Form');
               $this->item = $this->get('Item');
               $this->script = $this->get('Script');

               // ¿Qué tipos de permiso tiene este usuario? ¿Qué puede el o ella hacer?
               $this->canDo = HelloWorldHelper::getActions($this->item->id);
               // Verificar existencia de errores
               if (count($errors = $this->get('Errors')))
               {
                       JError::raiseError(500, implode('<br />', $errors));
                       return false;
               }

               // Establecer la barra de herremienta
               $this->addToolBar();

               // Mostrar la plantilla
               parent::display($tpl);

               // Establecer el documento
               $this->setDocument();
       }

       /**
        * Configuración de la barra de herramienta
        */
       protected function addToolBar()
       {
               $input = JFactory::getApplication()->input;
               $input->set('hidemainmenu', true);
               $user = JFactory::getUser();
               $userId = $user->id;
               $isNew = $this->item->id == 0;
               JToolBarHelper::title($isNew ? JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW')
                                            : JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'), 'helloworld');
               // Construir las acciones para los registros nuevos y existentes.
               if ($isNew)
               {
                       // Para los nuevos registros, comprobar el permiso create
                       if ($this->canDo->get('core.create'))
                       {
                               JToolBarHelper::apply('helloworld.apply', 'JTOOLBAR_APPLY');
                               JToolBarHelper::save('helloworld.save', 'JTOOLBAR_SAVE');
                               JToolBarHelper::custom('helloworld.save2new', 'save-new.png', 'save-new_f2.png',
                                                      'JTOOLBAR_SAVE_AND_NEW', false);
                       }
                       JToolBarHelper::cancel('helloworld.cancel', 'JTOOLBAR_CANCEL');
               }
               else
               {
                       if ($this->canDo->get('core.edit'))
                       {
                               // Podemos guardar el nuevo registro
                               JToolBarHelper::apply('helloworld.apply', 'JTOOLBAR_APPLY');
                               JToolBarHelper::save('helloworld.save', 'JTOOLBAR_SAVE');

                               // Podemos guardar este registro, pero revise el permiso create a ver
                               // si podemos volver a hacer uno nuevo.
                               if ($this->canDo->get('core.create'))
                               {
                                       JToolBarHelper::custom('helloworld.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false);
                               }
                       }
                       if ($this->canDo->get('core.create'))
                       {
                               JToolBarHelper::custom('helloworld.save2copy', 'save-copy.png', 'save-copy_f2.png',
                                                      'JTOOLBAR_SAVE_AS_COPY', false);
                       }
                       JToolBarHelper::cancel('helloworld.cancel', 'JTOOLBAR_CLOSE');
               }
       }
       /**
        * Método para configurar las propiedades del documento
        *
        * @return void
        */
       protected function setDocument()
       {
               $isNew = $this->item->id == 0;
               $document = JFactory::getDocument();
               $document->setTitle($isNew ? JText::_('COM_HELLOWORLD_HELLOWORLD_CREATING')
                                          : JText::_('COM_HELLOWORLD_HELLOWORLD_EDITING'));
               $document->addScript(JURI::root() . $this->script);
               $document->addScript(JURI::root() . "/administrator/components/com_helloworld"
                                                 . "/views/helloworld/submitbutton.js");
               JText::script('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE');
       }
}

Estos dos archivos utilizan el método definido getActions en el archivo admin/helpers/helloworld.php :

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die;

/**
* Componente HelloWorld helper.
*/
abstract class HelloWorldHelper
{
       /**
        * Configurar la barra de enlaces.
        */
       public static function addSubmenu($submenu)
       {
               JSubMenuHelper::addEntry(JText::_('COM_HELLOWORLD_SUBMENU_MESSAGES'),
                                        'index.php?option=com_helloworld', $submenu == 'messages');
               JSubMenuHelper::addEntry(JText::_('COM_HELLOWORLD_SUBMENU_CATEGORIES'),
                                        'index.php?option=com_categories&view=categories&extension=com_helloworld',
                                        $submenu == 'categories');
               // establecer algunas propiedades globales
               $document = JFactory::getDocument();
               $document->addStyleDeclaration('.icon-48-helloworld ' .
                                              '{background-image: url(../media/com_helloworld/images/tux-48x48.png);}');
               if ($submenu == 'categories')
               {
                       $document->setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION_CATEGORIES'));
               }
       }

       /**
        * Obtener las acciones
        */
       public static function getActions($messageId = 0)
       {
                jimport('joomla.access.access');
               $user   = JFactory::getUser();
               $result = new JObject;

               if (empty($messageId))
               {
                       $assetName = 'com_helloworld';
               }
               else {
                       $assetName = 'com_helloworld.message.'.(int) $messageId;
               }
               $actions = JAccess::getActions('com_helloworld', 'component');

               foreach ($actions as $action)
             {
                       $result->set($action->name, $user->authorise($action->name, $assetName));
               }
               return $result;
       }
}

Restringir el acceso al componente

La idea principal en el ACL es restringir las acciones a grupos de usuarios. La primera medida que ha restringido es el acceso del propio componente por la administración. Con tu editor favorito agrega esta líneas al archivo admin/helloworld.php :

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Verificación de acceso: ¿Este usuario puede acceder al componente desde la administración?
if (!JFactory::getUser()->authorise('core.manage', 'com_helloworld'))
{
       return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR'));
}
// Requiere del archivo helper
JLoader::register('HelloWorldHelper', dirname(__FILE__) . '/helpers/helloworld.php');

// Importar biblioteca controller de Joomla
jimport('joomla.application.component.controller');

// Obtener una instancia del controlador prefijado por HelloWorld
$controller = JController::getInstance('HelloWorld');

// Realice la tarea Solicitada
$input = JFactory::getApplication()->input;
$controller->execute($input->getCmd('task'));

// Redirigir si se define por el controlador
$controller->redirect();

Agregue la columna asset_id a la tabla de la base de datos

Con el fin de ser capaz de trabajar con JTable la columna asset_id tiene que ser creada en la tabla #__helloworld . Así que, admin/sql/install.mysql.utf8.sql se convierte en: 

DROP TABLE IF EXISTS `#__helloworld`;

CREATE TABLE `#__helloworld` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `asset_id` INT(10) NOT NULL DEFAULT '0',  `greeting` varchar(25) NOT NULL,
 `catid` int(11) NOT NULL DEFAULT '0',
 `params` TEXT NOT NULL DEFAULT '',
  PRIMARY KEY  (`id`)
);

INSERT INTO `#__helloworld` (`greeting`) VALUES
       ('Hello World!'),
       ('Good bye World!');

Para las actualizaciones se añade en el archivo admin/sql/updates/mysql/0.0.14.sql :

ALTER TABLE`#__helloworld` ADD COLUMN `asset_id` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `id`;

Restringir el acceso a los mensajes

Hasta ahora hemos restringido el acceso al componente en sí, pero también tenemos que hacerlo a nivel de mensaje.
Para verificar el permiso “core.delete” necesitamos modificar la clase del modelo admin/models/helloworld.php añadiendo las siguientes líneas:

 **
  * Método para comprobar si está preparado para borrar un mensaje. Sobrescribe JModelAdmin::canDelete
*/
protected function canDelete($record)
       {
           if( !empty( $record->id ) ){
               $user = JFactory::getUser();
               return $user->authorise( "core.delete", "com_helloworld.message." . $record->id );
         }
}

Para comprobar el "core.edit" (y el “core.add” si lo desea) necesitas actualizar el sub-controlador (no el modelo). No estoy seguro de porqué esto es así, pero así es como otros componentes estándar de Joomla! lo hacen. Es necesario añadir las siguientes líneas en el archivo: /admin/controllers/helloworld.php 

/**
    * Aplicar allowAdd o no
    *
    * No se utiliza en este momento (pero se puede ver cómo otros componentes lo usan ....)
    * Sobreescribiendo: JControllerForm::allowAdd
    *
    * @param array $data
    * @return bool
    */
   protected function allowAdd($data = array())
   {
       return parent::allowAdd($data);
   }

   /**
    * Implementar para permitir o no editar
    * Sobreescribiendo: JControllerForm::allowEdit
    *
    * @param array $data
    * @param string $key
    * @return bool
    */
   protected function allowEdit($data = array(), $key = 'id')
   {
       $id = isset( $data[ $key ] ) ? $data[ $key ] : 0;
       if( !empty( $id ) ){
           $user = JFactory::getUser();
           return $user->authorise( "core.edit", "com_helloworld.message." . $id );
       }
   }

Tenga en cuenta que allowAdd simplemente llama al padre. Lo he puesto aquí en caso de que quiera hacer uso de ella en su componente. Si nos fijamos en el archivo admin/access.xml  te darás cuenta de que no hay acción core.add definido para "messages", por lo que tendrá que añadirlo también allí si quieres ser capaz de configurar la interfaz.

Configuración de los valores de los permisos en la tabla assets

Con el fin de almacenar los permisos para cada mensaje en la tabla assets , tenemos que  instruir a la clase table asociada con el modelo para salvar esos permisos en la tabla assets.
JTable no sólo proporciona una interfaz para el almacenamiento de los datos de los registros propios en la tabla del elemento, sino que también almacena los permisos para ese registro en la tabla assets.  Por ello hay que añadir información al método bind() acerca de los valores de los permisos. También tenemos que proporcionar el nombre del assets, el título y el id del assets padre, vía helloworld JTable.  Por lo tanto, tenemos que sustituir 3 métodos:

  • _getAssetName():  un nombre único para este assets, el cual puede ser recuperado
  • _getAssetTitle(): una forma más humana de identificar el assets (no es necesario que sea único)
  • _getAssetParentId(): el asset_id padre en la tabla asset (del cual los permisos son heredados)

admin/tables/helloworld.php 

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

// Importar biblioteca table de Joomla
jimport('joomla.database.table');

/**
* Clase Hello Table
*/
class HelloWorldTableHelloWorld extends JTable
{
       /**
        * Constructor
        *
        * @param object Ibjeto conector de Base de Datos
        */
       function __construct(&$db)
       {
               parent::__construct('#__helloworld', 'id', $db);
       }

       /**
        * Sobreescribiendo la función bind
        *
        * @param       array           nombre del array
        * @return      null|string     null si la operación fue satisfactoria, de otra forma retorna un error
        * @see JTable:bind
        * @since 1.5
        */
       public function bind($array, $ignore = '')
       {
               if (isset($array['params']) && is_array($array['params']))
               {
                       // Convertir los parametros field en string.
                       $parameter = new JRegistry;
                       $parameter->loadArray($array['params']);
                       $array['params'] = (string)$parameter;
               }

               // Bind the rules.
               if (isset($array['rules']) && is_array($array['rules']))
               {
                       $rules = new JAccessRules($array['rules']);
                       $this->setRules($rules);
               }
               return parent::bind($array, $ignore);
       }

       /**
        * Reemplazando función de carga
        *
        * @param       int $pk llave primaria
        * @param       boolean $reset restablecer los datos
        * @return      boolean
        * @see JTable:load
        */
       public function load($pk = null, $reset = true)
       {
               if (parent::load($pk, $reset))
               {
                       // Convirtiendo los parametros field en registry.
                       $params = new JRegistry;
                       $params->loadJSON($this->params);
                       $this->params = $params;
                       return true;
               }
               else
               {
                       return false;
               }
       }

       /**
        * Método para calcular el nombre por defecto del asset
        * El nombre por defecto es en la forma `table_name.id`
        * donde el id es el valor de la clave principal de la tabla
        *
        * @return      string
        * @since       2.5
        */        protected function _getAssetName()
       {
               $k = $this->_tbl_key;
               return 'com_helloworld.message.'.(int) $this->$k;
       }
       /**
        * Método para devolver el título a utilizar para la tabla asset.
        *
        * @return      string
        * @since       2.5
        */
       protected function _getAssetTitle()
       {
               return $this->greeting;
       }
       /**
        * Método para obtener el id del asset padre del elemento
        *
        * @return      int
        */
       protected function _getAssetParentId()
       {
               // Vamos a obtener el asset padre de la tabla Asset
               $assetParent = JTable::getInstance('Asset');
               // Por defecto: si no se encuentran aseet padre tomamos el asset global
               $assetParentId = $assetParent->getRootId();
               // Encuentre el asset padre
               if (($this->catid)&& !empty($this->catid))
               {
                       // El elemento tiene una categoría como asset padre
                       $assetParent->loadByName('com_helloworld.category.' . (int) $this->catid);
               }

               else
               {
                       // El elemento tiene un componente como asset padre
                       $assetParent->loadByName('com_helloworld');
               }
               // Retornar el id del asset padre encontrado
               if ($assetParent->id)
               {
                       $assetParentId=$assetParent->id;
               }
               return $assetParentId;
       }
}

Este código de _getAssetParentId() anterior usa JTableAsset para recuperar el asset_id del asset padre.  Esto es diferente del código en la versión actual de com_content, donde se recupera el asset_id de la categoría de la tabla de la base de datos # __categories. Esa es otra posibilidad; ya saben que existen muchos caminos que conducen a Roma. En com_content sin embargo, si un artículo no pertenece a una categoría, entonces el asset_id del asset global es retornado. Eso no sería, por supuesto, estar en lo correcto, pero se solucionado poniendo una categoría por defecto “uncategorised”, por lo que un artículo siempre va a pertenecer a una categoría. Es por eso que no se puede simplemente copiar el código de _getAssetParentId() de com_content para nuestro componente. El código anterior es más general.

Mostrando la configuración de permisos a nivel del elemento

Añadiendo los “rules field” en el archivo admin/models/forms/helloworld.xml :

<fieldset name="accesscontrol">
       <field name="asset_id" type="hidden" filter="unset" />
       <field name="rules"
               type="rules"
               label="JFIELD_RULES_LABEL"
               translate_label="false"
               filter="rules"
               validate="rules"
               class="inputbox"
               component="com_helloworld"
               section="message"
       />
   </fieldset>

Y mostrando la interfaz de ACL en la parte inferior de su Helloworld en el archivo admin/views/helloworld/tmpl/edit.php :

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
JHtml::_('behavior.formvalidation');
$params = $this->form->getFieldsets('params');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id='.(int) $this->item->id); ?>"
     method="post" name="adminForm" id="helloworld-form" class="form-validate">

  <div class="width-60 fltlft">
     <fieldset class="adminform">
        <legend><?php echo JText::_( 'COM_HELLOWORLD_HELLOWORLD_DETAILS' ); ?></legend>
        <ul class="adminformlist">
           <?php foreach($this->form->getFieldset('details') as $field): ?>
              <li><?php echo $field->label;echo $field->input;?></li>
           <?php endforeach; ?>
        </ul>
     </fieldset>
  </div>

  <div class="width-40 fltrt">
     <?php echo JHtml::_('sliders.start', 'helloworld-slider');
        foreach ($params as $name => $fieldset):
           echo JHtml::_('sliders.panel', JText::_($fieldset->label), $name.'-params');
           if (isset($fieldset->description) && trim($fieldset->description)): ?>
              <p class="tip"><?php echo $this->escape(JText::_($fieldset->description));?></p>
           <?php endif;?>
           <fieldset class="panelform" >
              <ul class="adminformlist">
                 <?php foreach ($this->form->getFieldset($name) as $field) : ?>
                    <li><?php echo $field->label; ?><?php echo $field->input; ?></li>
                 <?php endforeach; ?>
              </ul>
           </fieldset>
        <?php endforeach; ?>

     <?php echo JHtml::_('sliders.end'); ?>
  </div>

  <!-- Comienzo de la definición de las ACL -->
  <div class="clr"></div>
  <?php if ($this->canDo->get('core.admin')): ?>
     <div class="width-100 fltlft">
        <?php echo JHtml::_('sliders.start', 'permissions-sliders-'.$this->item->id, array('useCookie'=>1)); ?>
           <?php echo JHtml::_('sliders.panel', JText::_('COM_HELLOWORLD_FIELDSET_RULES'), 'access-rules'); ?>
           <fieldset class="panelform">
              <?php echo $this->form->getLabel('rules'); ?>
              <?php echo $this->form->getInput('rules'); ?>
           </fieldset>
        <?php echo JHtml::_('sliders.end'); ?>
     </div>
  <?php endif; ?>
  <!-- Final de la definición de las ACL -->
  <div>
     <input type="hidden" name="task" value="helloworld.edit" />
     <?php echo JHtml::_('form.token'); ?>
  </div>
</form>

Añadiendo cadenas de idioma

Se utilizó 3 cadenas que tienen que ser añadidas al archivo de idioma de la administración. admin/language/es-ES/es-ES.com_helloworld.ini :

COM_HELLOWORLD_FIELDSET_RULES="Permisos de Mensaje"
COM_HELLOWORLD_ACCESS_DELETE_DESC="¿Está este grupo autorizado a editar este mensaje?"
COM_HELLOWORLD_ACCESS_DELETE_DESC="¿Está este grupo autorizado a eliminar este mensaje?"

Lecturas complementarias

Más información sobre las acciones, assets y ACL se pueden encontrar en las siguientes páginas:

Clases obsoletas

Por el momento dejamos las referencias obsoletas JError como están.  Probablemente aún esté disponible en Joomla! 3.x. No podemos cambiarlas a declaraciones JLog::add() porqué en Joomla! 2.5 los mensajes no se ponen en colas. Otras soluciones, como el uso de $app->enqueueMessage()  o directamente tirando PHP-exceptions, son posibles, pero todavía habría numerosas referencias a JError en toda la aplicación. Por ejemplo, en las vistas, comprobamos si hay errores planteados en el modelo con: count($errors = $this->get('Errors')) que utiliza JError del JOBject que fue la base para JModel. Para obtener la misma funcionalidad sin necesidad de utilizar JError en absoluto, tendríamos que cambiar la forma en que el modelo plantea ahora los errores y las advertencias. Si queremos hacer una aplicación que funcione en Joomla! 2.5 y 3.x podemos seguir utilizando JError. En el momento en que queramos utilizar nuestras extensiones 3.x o también 4.x vamos a tener que cambiar esto (y probablemente mucho más también). Este tutorial está ahora centrado principalmente en Joomla! 2.5. Por lo tanto: notamos el cambio próximo, pero dejarlo ahí por el momento.
Desde Joomla! 2.5.5 las clases bases del modelo MVC, JController, JModel  y JView tienen en su poder JControllerLegacy, JModelLegacy and JViewLegacy. Se recomienda el uso de ellas en lugar de las clases originales,  para lograr una compatibilidad hacia adelante con las clases heredadas de Joomla! 3.x .

15- Añadiendo un archivo script de Instalación - Desinstalación - Actualización

{Última Actualización: 30 Septiembre  2012 - 18:12 }

Crear el script de la extensión

Instalación, actualización y desinstalación de un componente puede requerir operaciones adicionales que no pueden ser alcanzados por las operaciones básicas descritas en el archivo XML principal. Joomla! ofrece un nuevo enfoque para resolver este problema. Consiste en el uso de un archivo script php en la raíz de nuestro directorio que contiene una clase que usa cinco métodos:

  • Preflight: que se ejecuta antes de instalar y actualizar
  • Instalar
  • Actualizar
  • Desinstalar
  • Postflight: que se ejecuta después de la instalación y actualización

Escribir este script consiste en declarar una clase cuyo nombre es com_NombreComponenteInstallerScript con estos 5 métodos: script.php

<?php
// No permitir el acceso directo al archivo
defined('_JEXEC') or die('Restricted access');

/**
* Archivo Script del componente HelloWorld
*/
class com_helloWorldInstallerScript
{
       /**
        * Método de instalación del componente
        *
        * @return void
        */
       function install($parent)
       {
               // $parent es la clase que llama al método
               $parent->getParent()->setRedirectURL('index.php?option=com_helloworld');
       }

       /**
        * Método para desinstalar el componente
        *
        * @return void
        */
       function uninstall($parent)
       {
               // $parent es la clase que llama al método
               echo '<p>' . JText::_('COM_HELLOWORLD_UNINSTALL_TEXT') . '</p>';
       }

       /**
        * Método para actualizar el componente
        *
        * @return void
        */
       function update($parent)
       {
               // $parent es la clase que llama al método
               echo '<p>' . JText::sprintf('COM_HELLOWORLD_UPDATE_TEXT', $parent->get('manifest')->version) . '</p>';
       }

       /**
        * Método que se ejecuta antes del método de instalar/actualizar/desinstalar
        *
        * @return void
        */
       function preflight($type, $parent)
       {
               // $parent es la clase que llama al método
               // $type es el tipo de cambio (instalar, actualizar o discover_install)
               echo '<p>' . JText::_('COM_HELLOWORLD_PREFLIGHT_' . $type . '_TEXT') . '</p>';
       }

       /**
        * Método que se ejecuta después del método de instalar/actualizar/desinstalar
        *
        * @return void
        */
       function postflight($type, $parent)
       {
               // $parent es la clase que llama al método
               // $type es el tipo de cambio (instalar, desinstalar o discover_install)
               echo '<p>' . JText::_('COM_HELLOWORLD_POSTFLIGHT_' . $type . '_TEXT') . '</p>';
       }
}

Este archivo de script , se redirige al usuario al componente com_helloworld cuando se instala, y se mostrarán mensajes cuando se actualiza o se desinstala. En el método de actualización, se mostrará la versión nueva con $parent->get('manifest')->version.

Añadiendo algunas cadenas de idiomas

admin/language/es-ES/es-ES.com_helloworld.sys.ini 

COM_HELLOWORLD="Hello World!"
COM_HELLOWORLD_DESCRIPTION="Esta es la descripción de HelloWorld"
COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC="Esta vista muestra un mensaje seleccionado"
COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE="Hello World"
COM_HELLOWORLD_INSTALL_TEXT="Script de Instalación de HelloWorld"
COM_HELLOWORLD_MENU="Hello World!"
COM_HELLOWORLD_POSTFLIGHT_DISCOVER_INSTALL_TEXT="HelloWorld postlight descubre script de instalación"
COM_HELLOWORLD_POSTFLIGHT_INSTALL_TEXT="HelloWorld postflight script de instalación"
COM_HELLOWORLD_POSTFLIGHT_UNINSTALL_TEXT="HelloWorld postflight script de dsinstalación"
COM_HELLOWORLD_POSTFLIGHT_UPDATE_TEXT="HelloWorld postflight script de actualización"
COM_HELLOWORLD_PREFLIGHT_DISCOVER_INSTALL_TEXT="HelloWorld preflight descubre script de instalación"
COM_HELLOWORLD_PREFLIGHT_INSTALL_TEXT="HelloWorld preflight script de instalación"
COM_HELLOWORLD_PREFLIGHT_UNINSTALL_TEXT="HelloWorld preflight script de desinstalación"
COM_HELLOWORLD_PREFLIGHT_UPDATE_TEXT="HelloWorld preflight script de actualización"
COM_HELLOWORLD_UNINSTALL_TEXT="HelloWorld desinstalado"
COM_HELLOWORLD_UPDATE_TEXT="HelloWorld actualizadot. HelloWorld ahora se actualizo a la versión %s."

Verifiquemos ahora el contenido que debemos tener en nuestro directorio:

  • helloworld.xml
  • script.php
  • 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
  • site/language/index.html
  • site/language/es-ES/index.html
  • site/language/es-ES/es-ES.com_helloworld.ini
  • admin/index.html
  • admin/access.xml
  • admin/config.xml
  • 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/sql/updates/mysql/0.0.12.sql
  • admin/sql/updates/mysql/0.0.13.sql
  • admin/models/index.html
  • admin/models/fields/index.html
  • admin/models/fields/helloworld.php
  • admin/models/forms/index.html
  • admin/models/forms/helloworld.xml
  • admin/models/forms/helloworld.js
  • admin/models/rules/index.html
  • admin/models/rules/greeting.php
  • admin/models/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/views/helloworld/index.html
  • admin/views/helloworld/view.html.php
  • admin/views/helloworld/submitbutton.js
  • admin/views/helloworld/tmpl/index.html
  • admin/views/helloworld/tmpl/edit.php
  • admin/helpers/index.html
  • admin/helpers/helloworld.php
  • admin/tables/index.html
  • admin/tables/helloworld.php
  • admin/language/es-ES/es-ES.com_helloworld.ini
  • admin/language/es-ES/es-ES.com_helloworld.sys.ini
  • admin/controllers/index.html
  • admin/controllers/helloworld.php
  • admin/controllers/helloworlds.php
  • language/es-ES/es-ES.ini
  • media/index.html
  • media/images/index.html
  • media/images/tux-16x16.png
  • media/images/tux-48x48.png

Nuestro helloworld.xml es modificado:

<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">

       <name>COM_HELLOWORLD</name>
       <creationDate>Octubre 2012</creationDate>
       <author>Carlos R & Andoitz B</author>
       <authorEmail>email</authorEmail>
       <authorUrl>http://www.ejemplo.org</authorUrl>
       <copyright>Copyright Info</copyright>
       <license>Licencia Info</license>
       <version>0.0.15</version>
       <description>COM_HELLOWORLD_DESCRIPTION</description>

       <!-- Ejecutar instalación/desinstalación/actualización; Nuevo en 2.5 -->
       <scriptfile>script.php</scriptfile>

       <install>
               <sql>
                       <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
               </sql>
       </install>
       <uninstall>
               <sql>
                       <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
               </sql>
       </uninstall>
       <update>
               <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>
               <folder>language</folder>
       </files>

       <media destination="com_helloworld" folder="media">
               <filename>index.html</filename>
               <folder>images</folder>
       </media>

       <administration>
              
              <menu img="../media/com_helloworld/images/tux-16x16.png">COM_HELLOWORLD_MENU</menu>
              <files folder="admin">                       
                       <filename>index.html</filename>
                       <filename>config.xml</filename>
                       <filename>access.xml</filename>
                       <filename>helloworld.php</filename>
                       <filename>controller.php</filename>  
                       <folder>sql</folder>                       
                       <folder>tables</folder>                       
                       <folder>models</folder>                       
                       <folder>views</folder>                       
                       <folder>controllers</folder>                       
                       <folder>helpers</folder>
               </files>

               <languages folder="admin">
                  <language tag="es-ES">language/es-ES/es-ES.com_helloworld.ini</language>
                  <language tag="es-ES">language/es-ES/es-ES.com_helloworld.sys.ini</language>
               </languages>
       </administration>

</extension>

Ahora crea un archivo comprimido del contenido del componente e instalalo a través del gestor de extensiones de Joomla!. Recuerda que también puedes descargar el archivo directamente.

16- Añade la definición UpdateServer (Servidor de Actualizaciones)

{Última Actualización: 30 Septiembre 2012 - 18:13 }

Para agregar la funcionalidad UpdateServer hay que ajustar el helloworld.xml a este aspecto:

<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">

       <name>COM_HELLOWORLD</name>       
       <creationDate>November 2009</creationDate>
       <author>Carlos R & Andoitz B</author>
       <authorEmail>email</authorEmail>
       <authorUrl>http://www.example.org</authorUrl>
       <copyright>Copyright Info</copyright>
       <license>Licencia Info</license>       >
       <version>0.0.15</version>       
       <description>COM_HELLOWORLD_DESCRIPTION</description>
      
       <scriptfile>script.php</scriptfile>

       <install>
               <sql>
                       <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
               </sql>
       </install>
       <uninstall>
               <sql>
                       <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
               </sql>
       </uninstall>
       <update>
               <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>
               <folder>language</folder>
       </files>

       <media destination="com_helloworld" folder="media">
               <filename>index.html</filename>
               <folder>images</folder>
       </media>

       <administration>               
               <menu img="../media/com_helloworld/images/tux-16x16.png">COM_HELLOWORLD_MENU</menu>
              
               <files folder="admin">                       
                       <filename>index.html</filename>
                       <filename>config.xml</filename>
                       <filename>access.xml</filename>
                       <filename>helloworld.php</filename>
                       <filename>controller.php</filename>                       
                       <folder>sql</folder>                       >
                       <folder>tables</folder>                       
                       <folder>models</folder>                       
                       <folder>views</folder>                       
                       <folder>controllers</folder>                       
                       <folder>helpers</folder>
               </files>

               <languages folder="admin">
                  <language tag="es-ES">language/es-ES/es-ES.com_helloworld.ini</language>
                  <language tag="es-ES">language/es-ES/es-ES.com_helloworld.sys.ini</language>
               </languages>
       </administration>

       <!-- DEFINICIÓN UPDATESERVER -->
       <updateservers>
               <!-- Nota: No se permiten espacios ni saltos de líneas entre las entiquetas del servidor -->
               <server type="extension" priority="1" name="HelloWorld Update Site">http://yourdomain.com/update/helloworld-update.xml</server>
       </updateservers>

</extension>

También es necesario poner un archivo XML en el servidor que contenga toda la información sobre las actualizaciones.
helloworld-update.xml 

<?xml version="1.0" encoding="utf-8"?>
<updates>
  <update>
     <name>HelloWorld</name>
     <description>Componente HelloWorld Component</description>
     <element>com_helloworld</element>
     <type>component</type>
     <version>1.5.0</version>

     <infourl title="HalloWorld URL">http://yourdomain.com</infourl>
     <downloads>
        <downloadurl type="full" format="zip">http://yourdomain.com/files/com_helloworld-1.5.0-final.zip</downloadurl>
     </downloads>
     <tags>
        <tag>some-tag</tag>
     </tags>

     <maintainer>HelloWorld Inc.</maintainer>
     <maintainerurl>http://yourdomain.com</maintainerurl>
     <section>some-section</section>
     <targetplatform name="joomla" version="2.5" />
  </update>
  <update>
     <name>HelloWorld</name>
     <description>HelloWorld Component</description>
     <element>com_helloworld</element>
     <type>component</type>
     <version>1.5.0</version>

     <infourl title="HalloWorld URL">http://yourdomain.com</infourl>
     <downloads>
        <downloadurl type="full" format="zip">http://yourdomain.com/files/com_helloworld-1.5.0-final.zip</downloadurl>
     </downloads>
     <tags>
        <tag>some-tag</tag>
     </tags>

     <maintainer>HelloWorld Inc.</maintainer>
     <maintainerurl>http://yourdomain.com</maintainerurl>
     <section>some-section</section>
     <targetplatform name="joomla" version="2.5" />
  </update>
  <update>
     <name>HelloWorld</name>
     <description>HelloWorld Component</description>
     <element>com_helloworld</element>
     <type>component</type>
     <version>1.5.0</version>

     <infourl title="HalloWorld URL">http://yourdomain.com</infourl>
     <downloads>
        <downloadurl type="full" format="zip">http://yourdomain.com/files/com_helloworld-1.5.0-final.zip</downloadurl>
     </downloads>
     <tags>
        <tag>some-tag</tag>
     </tags>

     <maintainer>HelloWorld Inc.</maintainer>
     <maintainerurl>http://yourdomain.com</maintainerurl>
     <section>some-section</section>
     <targetplatform name="joomla" version="2.5" />
  </update>

   <update>
     <name>HelloWorld</name>
     <description>HelloWorld Component</description>
     <element>com_helloworld</element>
     <type>component</type>
     <version>1.5.1</version>

     <infourl title="HelloWorld URL">http://yourdomain.com</infourl>
     <downloads>
        <downloadurl type="full" format="zip">http://yourdomain.com/files/com_helloworld-1.5.1-final.zip</downloadurl>
     </downloads>
     <tags>
        <tag>some-tag</tag>
     </tags>

     <maintainer>HelloWorld Inc.</maintainer>
     <maintainerurl>http://yourdomain.com</maintainerurl>
     <section>some-section</section>
     <targetplatform name="joomla" version="2.5" />
  </update>
   <update>
     <name>HelloWorld</name>
     <description>HelloWorld Component</description>
     <element>com_helloworld</element>
     <type>component</type>
     <version>1.5.1</version>

     <infourl title="HelloWorld URL">http://yourdomain.com</infourl>
     <downloads>
        <downloadurl type="full" format="zip">http://yourdomain.com/files/com_helloworld-1.5.1-final.zip</downloadurl>
     </downloads>
     <tags>
        <tag>some-tag</tag>
     </tags>

     <maintainer>HelloWorld Inc.</maintainer>
     <maintainerurl>http://yourdomain.com</maintainerurl>
     <section>some-section</section>
     <targetplatform name="joomla" version="2.5" />
  </update>
   <update>
     <name>HelloWorld</name>
     <description>HelloWorld Component</description>
     <element>com_helloworld</element>
     <type>component</type>
     <version>1.5.1</version>

     <infourl title="HelloWorld URL">http://yourdomain.com</infourl>
     <downloads>
        <downloadurl type="full" format="zip">http://yourdomain.com/files/com_helloworld-1.5.1-final.zip</downloadurl>
     </downloads>
     <tags>
        <tag>some-tag</tag>
     </tags>

     <maintainer>HelloWorld Inc.</maintainer>
     <maintainerurl>http://yourdomain.com</maintainerurl>
     <section>some-section</section>
     <targetplatform name="joomla" version="2.5" />
  </update>

</updates>

Es necesario agregar una nueva actualización cada vez que se publique una nueva versión, así como para cada versión de Joomla!.(se necesita un nodo distinto para cada actualización TargetPlatform)

Vea también

Aquí concluye este extenso tutorial. Espero que haya sido de tu agrado y que hayas podido crear tu componente siguiendo el mismo. Como pudistes darte cuenta, en cada punto hemos puesto la fecha de actualización que tenían los mismos a la hora de haber creado este tutorial. Por lo que queremos destacar que la información ofrecida en este artículo se actualizará a través de “artículos de actualización” en caso de que se hagan modificaciones en la documentación de Joomla! Sabemos que la información vale de poco cuando no está actualizada.
Este es solo el primero de una larga serie de tutoriales dirigidos a esas personas que, después de tener o adquirir cierta base y conocimiento del funcionamiento de Joomla!, quieran dar un paso más allá y aprender a modificar o ampliar su funcionalidad o, por qué no, programar sus propias extensiones.
A lo largo de estos tutoriales cubriremos todo tipo de temas, como la creación de módulos desde cero, creación de plugins, parámetros, migración de componentes... También hablaremos de cómo crear componentes con funcionalidades como el envío de emails, la carga de archivos... Pasaremos por AJAX, plantillas, flujo de trabajo, usar el editor en los componentes y todo lo que surja, siempre con el objetivo de explotar todas las posibilidades que nos ofrece Joomla! para conseguir lo que deseemos.

Por supuesto, lo más valioso de Joomla! es su Comunidad, y como tal, te invitamos a que nos hagas llegar tus sugerencias si deseas tener un tutorial en español sobre un tema concreto. Estaremos encantados de trabajar en ello y ayudarte en todo lo que podamos.

Traducido por: Carlos Rodríguez y Andoitz Brit

Miembros de: Equipo de Marketing y Difusión de Joomla! en Español

Visto 36613 veces Etiquetado como Spanish, Desarrollador