Manuales Joomla

Sistema de comentarios - Tutorial 4, Administración básica

(Lo puedes leer en: 24 - 47 minutos)

por .

Hacemos una parada en el desarrollo frontend de nuestro sistema de comentarios, para darle forma al backend del mismo. La administración por el momento va a ser bien sencilla, permitiendo una moderación básica de los comentarios. ¡Manos a la obra!

¿Qué elementos básicos necesitamos en la administración de nuestro sistema de comentarios? Sin duda, esta sería la primera pregunta a plantearnos antes de comenzar el trabajo en la administración. Las funcionalidades básicas que se requieren son, una opción para filtrar comentarios pendientes a publicar, una opción para publicar los comentarios y una opción para editar los comentarios. Creo que estas serían las funcionalidades básicas en cualquier sistema de comentarios, ¿no lo creen?

Nota: Recuerden, que en nuestro repositorio encontraran el código fuente del sistema de comentarios, hasta este cuarto tutorial del ciclo.

En esta cuarta entrega del ciclo, usaremos por primera vez el patrón MVC de Joomla dentro de un componente, por lo que sería recomendable que se leyera nuevamente el siguiente artículo de la documentación de Joomla.

Según nuestras funcionalidades básicas establecidas anteriormente, vamos necesitando de dos vistas en la administración. Una vista para listar todos los comentarios, tantos publicados como pendientes a publicar, donde añadiremos un filtrado de comentarios por el campo “state”. Y otra vista para la edición de un comentario determinado.

Elaboremos primero la vista que se va a encargar de listar todos los comentarios.

Creación de la interfaz en la administración de Joomla

Empezamos editando el primer archivo que se va a ejecutar al entrar a la administración del componente de comentarios, el archivo “mjcomments.php” de la carpeta “admin”.

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Component
  3.  * @subpackage mjcomments
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC''Mjcomments''task'
Source code

Punto de entrada del componente en el backend - Pasando el control al controlador maestro

Como podemos apreciar, el código es similar al punto de entrada del frontend (carpeta “site”), con la diferencia que hemos añadido en la línea 14, una redirección. Esta función de redirección pertenece a la clase “JControllerLegacy” como bien se habrán dado cuenta y se encarga de redireccionar el navegador en caso de ser necesario, luego de que se complete alguna tarea dentro de la administración del componente. Ya veremos como funciona más adelante.

Ahora pasemos al segundo archivo que interviene en el proceso de mostrar la vista que nos va a listar los comentarios introducidos en el sistema, el archivo “controller.php” de la carpeta admin.

El controlador es responsable de responder a las acciones del usuario. En el caso de una aplicación web, una acción del usuario es generalmente una solicitud de página. El controlador determinará qué solicitud ha sido realizada por el usuario y responderá de forma adecuada mediante la activación del modelo para manipular los datos de forma adecuada y pasar el modelo a la vista. El controlador no mostrará los datos en el modelo, sólo activa las funciones del modelo que modifican los datos y, a continuación, pasan del modelo a la vista que muestra los datos.

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Component
  3.  * @subpackage mjcomments
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC'/**
  8.  * Base controller class.
  9.  *
  10.  *//**
  11.   * The default view for the display function.
  12.   *
  13.   * @var string
  14.   * @since 12.2
  15.   */'commentslist';
  16. }
Source code

Controlador maestro - Definiendo la vista por defecto

¿Les parece muy pocas líneas? Pues es todo lo que necesitamos en nuestro controlador maestro. Por defecto, la clase “JControllerLegacy” ejecuta una función que es la encargada de renderizar la vista predeterminada que hemos establecido en la variable global “$default_view” definida en nuestra clase. La función en sí se llama “display” y la pueden encontrar a partir de la línea 638.

Ya nuestro controlador maestro esta dictando la orden de renderizar la vista que nos va a mostrar el listado de comentarios entrados en el sistema, por lo que nos toca crear esa vista.

La vista es la parte del componente que se utiliza para presentar los datos a partir del modelo de una manera que sea adecuada para la interacción. Para una aplicación basada en la web, la vista general sería una página HTML que se devuelve al usuario. La vista extrae los datos del modelo (que se pasan desde el controlador) y alimenta los datos en un layout que se rellena y se presentan al usuario.

Cuando el controlador manda a mostrar una vista, busca las vistas disponibles en la carpeta component/com_[nombre_componente]/views/[nombre_vista]/.

El nombre por defecto de la carpeta de la vista es el nombre del componente en sí. En nuestro la ruta sería component/com_mjcomments/views/mjcomments/. Pero como hemos definido previamente la vista predeterminada, la ruta es component/com_mjcomments/views/commentslist/.

El archivo que contendrá el código de la vista se llamará “view.[formato_vista].php”. El formato por defecto de la vista, y probablemente la única vista que un componente necesite es el formato html. Así que esto nos da el nombre del siguiente archivo a crear, “view.html.php”

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Component
  3.  * @subpackage mjcomments
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC'/**
  8.  * View class for a list of comments.
  9.  *//**
  10.   * Display the view
  11.   *
  12.   * @param string $tpl The name of the template file to parse; automatically searches through the template paths.
  13.   *
  14.   * @return void
  15.   */'Items');
  16.  
  17. // Check for errors.
  18. 'Errors'"\n"
Source code

Vista por defecto del componente - Mostrar una lista de comentarios insertados en el sistema

El nombre de la clase, sigue la misma nomenclatura que hasta ahora hemos usado, y que Joomla establece. Esta vez, ponemos nuestra clase a heredar de la clase “JViewLegacy” que la puedes encontrar en “libraries\legacy\view\legacy.php”. Esta clase nos aporta todo lo necesario para el renderizado de una vista.

Luego declaramos una función llamada “display”. Esta función ya está declarada en la clase padre “JViewLegacy” la cual es llamada desde la función “display” del controlador maestro, que es la tarea por defecto a ejecutar.

Dentro del cuerpo de la función “display” de la vista, lo primero que haremos es llamar a una función “Items” y almacenar todo lo que devuelva, dentro de la variable global “$items”. De seguro te suena conocido una función llamada “getItems()”, y es que precisamente ya la hemos usado. La vista extrae los datos desde un modelo (que se pasan desde el controlador), y como hemos visto anteriormente, en Joomla, hay una clase capaz de gestionar una lista de datos, la clase “JModelList”. Por lo que tendremos luego que crear este modelo para que la vista pueda obtener los datos necesarios para su correcta visualización. Luego comprobamos si ha sido lanzado algún error en todo este proceso con la función “getError” de la clase “JObject” (libraries\joomla\object\object.php), clase padre de la clase “JViewLegacy”.

Por último, llamamos a la función de la clase padre la cual nos va a imprimir el layout de la lista de comentarios. Joomla muestra los datos de las vistas, en estos layout. Por defecto, el archivo que usa, al no ser que nosotros especifiquemos lo contrario en el argumento “$tpl” de la función “display”, es el archivo “default.php”. Este archivo debemos colocarlo dentro de una carpeta llamada “tmpl” dentro de la carpeta de la vista. Recuerde que el mismo, contiene el layout de la lista de comentarios introducidos en el sistema. Por el momento lo dejamos vacío, tan solo mostrando un mensaje, para cuando probemos todo esto ver si ha funcionado bien o a fallado algo. Por tanto, el archivo “default.php” nos quedaría de la siguiente forma:

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Component
  3.  * @subpackage mjcomments
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC'
Source code

Layout de la vista del listado de comentarios - Desarrollo básico, para probar su funcionamiento

¿Ya podemos probar la vista para ver si funciona? No, aún no. Recuerden que la vista necesita los datos que el modelo le pasa, y aún ese modelo no lo hemos creado. Por lo tanto, creamos la carpeta “models” y dentro, un archivo llamado “commentslist.php” conteniendo lo siguiente:

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Component
  3.  * @subpackage mjcomments
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC'/**
  8.  * Methods supporting a list of comments records.
  9.  *
  10.  *//**
  11.   * Constructor.
  12.   *
  13.   * @param array $config An optional associative array of configuration settings.
  14.   *
  15.   */'filter_fields']))
  16. {
  17. $config['filter_fields''id', 'a.id',
  18. 'content_id', 'a.content_id',
  19. 'visitor_name', 'a.visitor_name',
  20. 'created', 'a.created',
  21. 'state', 'a.state'/**
  22.   * Method to auto-populate the model state.
  23.   *
  24.   * Note. Calling getState in this method will result in recursion.
  25.   *
  26.   * @param string $ordering An optional ordering field.
  27.   * @param string $direction An optional direction (asc|desc).
  28.   *
  29.   * @return void
  30.   *
  31.   */// List state information.
  32. 'a.id', 'desc');
  33. }
  34.  
  35. /**
  36.   * Method to get a store id based on model configuration state.
  37.   *
  38.   * This is necessary because the model is used by the component and
  39.   * different modules that might need different sets of data or different
  40.   * ordering requirements.
  41.   *
  42.   * @param string $id A prefix for the store id.
  43.   *
  44.   * @return string A store id.
  45.   *
  46.   */'')
  47. {
  48. // Compile the store id.
  49. /**
  50.   * Build an SQL query to load the list data.
  51.   *
  52.   * @return JDatabaseQuery
  53.   *
  54.   */// Select the required fields from the table.
  55. 'list.select',
  56. 'a.id, a.content_id, a.visitor_name, a.state, ' .
  57. 'a.visitor_email, a.visitor_comments, a.created'
  58. )
  59. );
  60.  
  61. $query->from('#__mjcomments AS a');
  62.  
  63. // Add the list ordering clause.
  64. 'list.ordering', 'a.id''list.direction', 'desc'' '/**
  65.   * Method to get a list of articles.
  66.   * Overridden to add a check for access levels.
  67.   *
  68.   * @return mixed An array of data items on success, false on failure.
  69.   *
  70.   */
Source code

Creación del modelo para el listado de cometarios
Creación del modelo para el listado de cometarios
Creación del modelo para el listado de cometariosCreación del modelo para el listado de cometarios

Les debe resultar familiar todo esto. Y es que precisamente ya hemos hecho uso de este tipo de modelo, cuando hemos estado trabajando en el frontend del sistema de comentarios. Por el momento, hemos dejado todo bien básico porque lo que queremos es ver si todo está funcionando como debe. Es decir, si cuando accedemos a la vista del componente desde la administración del sitio, no muestra ningún error.

Un último archivo debe ser modificado antes de la comprobación, el archivo manifiesto del componente, ya que tenemos que declarar las dos carpetas nuevas que hemos creado (models, views) así como el controlador maestro. Esto quedaría de la siguiente forma:

  1. <administration>
  2. <menu>com_mjcomments</menu>
  3.  
  4. <files folder="admin">
  5. <filename>controller.php</filename>
  6. <filename>mjcomments.php</filename>
  7. <folder>models</folder>
  8. <folder>sql</folder>
  9. <folder>tables</folder>
  10. <folder>views</folder>
  11. </files>
  12. </administration>
Source code

Archivo manifiesto del componente - Añadiendo archivos del backend

Noten, que en la línea 38 hemos añadido una etiqueta nueva dentro de los archivos de la administración. Esta etiqueta nos brinda la posibilidad de que nuestro componente aparezca en la lista de componentes en la administración del sitio. Tan simple como eso, veanlo con sus propios ojos. Actualicemos el paquete.

Vista de la administración del componente

¡Hombre! mejor no pudo funcionar. Tenemos en el listado de componente, el enlace al componente de nosotros, con el nombre sin traducir porque aún no hemos creado los archivos de idioma del componente en la administración. Cuando damos clic en el nombre, nos lleva a la vista por defecto de nuestro componente, la cual es el listado de comentarios insertados en el sistema, y como pueden ver, funciona al 100%.

Desarrollo de la lista de los comentarios añadidos

Ahora que estamos seguro que todo está respondiendo correctamente, mostremos la lista de los comentarios insertados en el sistema. Lo primero que trataremos de lograr es una tabla, donde cada fila va a pertenecer a un comentario insertado, del cual, mostraremos alguna información relacionada, como la fecha de creación, el autor del comentario, si esta publicado o despublicado etc. Como el layout de esta vista, va a usar los filtros introducidos en el modelo, pues tenemos que darle acceso desde la vista. Por lo que tendremos que editar el archivo “view.html.php” de la vista “commentslist”, añadiendo lo siguiente:

  1.  
Source code

  1. span style="color: #ff0000;">'State');
Source code

Vista del listado de comentarios - Añadiendo la gestión de filtros a la vista

Al igual que la función “getItems()”, nuestro modelo por herencia, cuenta con una función “getState” el cual nos brinda la posibilidad de obtener todos los filtros que se han definido en el modelo, por ejemplo, el filtro que establece el orden y la dirección en que se va a listar los comentarios en la vista.

Luego, editamos el layout de nuestra vista, en donde vamos a poner la tabla de los comentarios insertados en el sistema.

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Component
  3.  * @subpackage mjcomments
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC''bootstrap.tooltip''behavior.multiselect''list.ordering''list.direction'"<?php echo JRoute::_('index.php?option=com_mjcomments&amp;view=commentslist'); ?>" method="post" name="adminForm" id="adminForm">
  8. <div id="j-main-container""alert alert-no-items"'JGLOBAL_NO_MATCHING_RESULTS'"table table-striped" id="commentList">
  9. <thead>
  10. <tr>
  11. <th width="1%""center"'grid.checkall'"1%" style="min-width:55px""nowrap center"'searchtools.sort', 'JSTATUS', 'a.state''searchtools.sort', 'JGLOBAL_TITLE', 'a.content_id'"10%""nowrap hidden-phone"'searchtools.sort', 'JAUTHOR', 'a.visitor_name'"10%""nowrap hidden-phone"'searchtools.sort', 'JDATE', 'a.created'"1%""nowrap hidden-phone"'searchtools.sort', 'JGRID_HEADING_ID', 'a.id'"<?php echo $columns; ?>""row<?php echo $i % 2; ?>""center"'grid.id'"center"'jgrid.published''commentslist.'"has-context""small hidden-phone""nowrap small hidden-phone"'date''DATE_FORMAT_LC4'"hidden-phone""hidden" name="task" value="" />
  12. <input type="hidden" name="boxchecked" value="0"'form.token'
Source code

Layout de la vista del listado de comentarios - Definiendo la tabla qi muestra el listado de comentarios insertados en el sistema
Layout de la vista del listado de comentarios - Definiendo la tabla qi muestra el listado de comentarios insertados en el sistema
Layout de la vista del listado de comentarios - Definiendo la tabla qi muestra el listado de comentarios insertados en el sistema
Layout de la vista del listado de comentarios - Definiendo la tabla qi muestra el listado de comentarios insertados en el sistema

En las líneas 12 y 13, inicializamos el plugin “tooltip” de bootstrap y el framework que nos va a permitir marcar los checkbox de selección de cada fila. Recuerden que en esta página tenemos los distintos framework que podemos usar.

En las líneas 15, 16, 17 declaramos 3 variables que utilizaremos en la tabla del listado de comentarios. Noten que aquí hacemos uso de “$this->state” que de no haberla declarado anteriormente en el archivo “view.html.php”, pues esto iba a generar un error ya que el objeto no lo iba a encontrar por no estar definido.

Ahora viene lo interesante. En la línea 21 iniciamos la etiqueta “form”, dando lugar al formulario que va a interactuar en esta vista. Se preguntaran, porque poner un formulario, si lo que estamos haciendo es listar los registros de una tabla de la base de datos. Pues, como sabemos, en la interfaz de administración de Joomla, existen varias funcionalidades básicas que generalmente requieren todas las extensiones. Ejemplo, si nos ubicamos en el gestor de artículos, podemos observar que tenemos varios filtros que nos permite granular tanto como queramos la lista de artículos. Para poder utilizar estas funcionalidades, pues tenemos que hacer uso de un formulario, ya que las columnas que se pueden ordenar se basan un poco en javascript, el cual le añade al formulario los parámetros de ordenación de la lista. Por supuesto, esto también conlleva que la página vuelva a cargarse por cada filtro añadido.

El atributo “action” de este formulario, es opcional, ya que si no está presente, se enviaran los datos a la dirección actual del documento, ejemplo la misma página, que generalmente es el comportamiento adecuado. En nuestro caso, se ha especificado explícitamente, a través de la clase “JRoute” . Esta clase lleva un tratamiento más profundo, que haremos en su momento. Pueden empezar leyendo esta página para un mejor entendimiento de su comportamiento.

El atributo “name” del formulario tiene que tener el valor “adminForm” sí o sí.

El formulario necesita también algunos campos ocultos que pueden verlos en las líneas 86, 87 y 88. El primero contiene la tarea que se va a realizar, ya sea borrar, editar, publicar, despublicar etc. El segundo va a contener los checkbox que hemos seleccionado dentro de la lista de comentarios. Y el tercero, nos va a generar un “token” de seguridad.

En el cuerpo del formulario, tenemos la tabla con el listado de comentarios. Primero comprobamos en la línea 23 que exista algún comentario, y en caso negativo, mostramos un mensaje a través de la cadena “JGLOBAL_NO_MATCHING_RESULTS” que el propio Joomla define.

A partir de la línea 28, comienza la tabla con la lista de comentarios insertados en el sistema. Las clases CSS que hemos usado tanto en la tabla como en sus elementos, todas son definidas por Joomla o por el framework bootstrap que usa Joomla. También pueden notar, que hemos usado en varias ocasiones, tanto en la cabecera de la tabla (<thead>) como en el cuerpo de la misma (<tbody>) la clase “JHtml”. En el plugin la usamos para cargar los archivos “media” del mismo, ¿se acuerdan? Ahora la usaremos para cargar por ejemplo, los “checkbox” que van aparecer al principio de cada fila de la tabla, el cual usaremos para seleccionar una, varias o todas las filas de esta tabla. Pueden ver las líneas 32 y 63.

También usamos esta clase en la cabecera de la tabla, para que los nombres de las columnas funcionen como filtros, así cuando el usuario da clic en cualquier nombre de estos, la lista de comentarios será reordenada según ese campo. Esto Joomla lo hace mediante “JHtml::_('searchtools.sort')”, ejemplo, línea 35 en la cual cargamos un campo filtrable con nombre “Estado” (esto lo define la cadena JSTATUS), el cual va a referenciar al campo “state” de la tabla de comentarios en la base de datos. También le pasamos dos argumentos más “$listDirn” y “$listOrder”, los cuales le dicen a la función por qué campo se está ordenando la lista de comentarios.

Pueden ir a “libraries\cms\html\searchtools.php” para acercarse más a la clase “JHtmlSearchtools”. Notaran ahí, que luego de crear el objeto con todos los argumentos que le pasamos a la función “sort” llama al layout “layouts\joomla\searchtools\grid\sort.php” el cual nos va a generar el código HTML.

Lo que más me gusta de la clase “JHtmlSearchtools”, es que puno es dependiente de Mootools.

Otra línea interesante a analizar, es la línea 66 dentro del cuerpo de la tabla. Esta línea se encarga de mostrar si el elemento (en nuestro caso un comentario) está publicado o no. La clase que maneja esto la pueden ver en “libraries\cms\html\jgrid.php”. Ahí van a encontrar la función “published” a la que hemos pasado como argumento, el valor del estado del comentario (publicado 1, despublicado 0), el índice de la fila y el nombre del modelo como prefijo para la tarea que se va a ejecutar.

La explicación de todo este archivo ha sido muy buena, pero todos sabemos que si no vemos un resultado, nunca quedaremos conforme. Por lo que actualizamos el paquete y accedemos al componente desde la administración.

Vista del listado de comentarios en la administración

¡Funciona perfectamente!, no hemos tenido ni un fallo por suerte. Por supuesto, tenemos que insertar algunos comentarios desde el frontend para poder ver el listado, ya que en caso contrario, nos saldría un mensaje indicándonos que no existe ningún comentario.

Hemos logrado una vista funcional del listado de comentarios del sistema, pero aún queda camino por recorrer para lograr una vista 100% operable. Observemos algunos problemas en nuestra vista actual.

Primero, la columna “Título” no nos dice nada, ya qué “Título” puede entenderse como “título del comentario” lo cual es incorrecto. Por lo que tendremos que cambiar este nombre por algo como “Título del artículo comentado”. También, los valores de los títulos que se visualizan, no es precisamente un título, sino el ID del artículo, por lo que tendremos que lograr que se visualice el título del artículo.

Segundo, si damos clic encima de los nombres de cabecera de la tabla como son, Estado, Título, Autor, etc, no pasa nada, y ese comportamiento es incorrecto. Lo correcto sería que al dar clic en cualquier nombre de la cabecera de la tabla, la lista de comentarios se ordene según esa columna.

Tercero, el botón que aparece en la columna estado no pública o despublica el comentario. Si damos clic en ese botón, nos muestra un error notificandonos que no se encuentra el controlador “commentslist”. Y es que precisamente ya esto lo hemos hablado, cada acción o tarea debe ser llevada a cabo por un controlador, y esta no es la excepción.

Empecemos a resolver estos problemas de menor a mayor. Para cambiar el nombre de cabecera de la columna “Título” debemos editar el archivo “default.php” perteneciente al layout de la vista “commentslist”. Modificaremos la línea 38:

  1. span style="color: #ff0000;">'searchtools.sort', 'COM_MJCOMMENTS_VIEW_COMMENTLIST_ARTICLE_TITLE', 'a.content_id'
Source code

Resolviendo errores en la vista de comentarios de la administración - Enlaces de los encabezados

Aquí hemos modificado la cadena de texto “JGLOBAL_TITLE” por una personalizada “COM_MJCOMMENTS_VIEW_COMMENTLIST_ARTICLE_TITLE”. Ahora tenemos que asignarle un valor a esta cadena, para ello tenemos que crear el archivo de idioma del componente para la administración. El proceso es el mismo que llevamos a cabo en el frontend, pero esta vez dentro de la carpeta “admin”. Nos quedaría de esta forma:

  1. ; com_mjcomments
  2. ; Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  3. ; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  4. ; Note : All ini files need to be saved as UTF-8
  5.  
  6. COM_MJCOMMENTS="MJ - Sistema de comentarios"
  7. COM_MJCOMMENTS_XML_DESCRIPTION="Gestor de comentarios del Ciclo 1."
  8.  
  9. ; View commentlist
  10. COM_MJCOMMENTS_VIEW_COMMENTLIST_ARTICLE_TITLE="Título del artículo comentado"
Source code

Resolviendo errores en la vista de comentarios de la administración - Enlaces de los encabezados

Noten que hemos añadido las cadenas de idioma faltantes del manifiesto del componente. Y antes de que se nos pase, editamos el manifiesto añadiendo esta nueva carpeta en los archivos de la administración.

También crearemos otro archivo de idioma “es-ES.com_mjcomments.sys.ini”, que nos va a servir para aquellas cadenas de texto que pertenecen al componente, y que deben ser traducidas a pesar de que el componente no esté instanciado. Este archivo solo contendrá por el momento las cadenas “COM_MJCOMMENTS” y “COM_MJCOMMENTS_XML_DESCRIPTION” con sus respectivos valores asignados. Hagamos rápidamente una actualización del paquete para ver cómo vamos:

Resolviendo errores en la vista de comentarios de la administración - Enlaces de los encabezados

¡Espectacular! Aún no hemos terminado de resolver el primer problema planteado, nos falta que los títulos de los artículos se muestren en vez de su ID. Debemos obtener entonces, el título del artículo comentado, y como hemos usado la palabra “obtener” pues sin pensarlo nos dirigimos al modelo. Editamos el archivo “commentslist.php” y en la función “getListQuery” añadimos lo siguiente:

  1. // Join over the article.
  2. $query->select('c.title AS content_title, c.alias AS content_alias, c.catid AS content_category, c.language AS content_language''LEFT', '#__content AS c ON c.id = a.content_id');
Source code

Resolviendo errores en la vista de comentarios de la administración - Enlaces de los encabezados

Como pueden ver, hemos hecho un “join” con la tabla “content” que es la que tiene los datos que buscamos. Teniendo los datos en la mano, actualizamos el layout de la vista, y cambiamos en la línea 69 “content_id” por “content_title”:

  1.  
Source code

Resolviendo errores en la vista de comentarios de la administración - Enlaces de los encabezados

¿Actualizamos a ver que pasa? Claro que sí. Actualizamos el paquete nuevamente y...:

Resolviendo errores en la vista de comentarios de la administración - Enlaces de los encabezados

¡Nos ha quedado esa columna a pedir de boca! ¿no creen? Primer problema solucionado.

Nuestro próximo problema planteado, es hacer funcionar los filtros. Al parecer, nos han subido la parada con este problema, veamos por donde le entramos.

En el layout de la vista, usamos “JHtml::_('searchtools.sort')” en cada encabezado de la tabla, para hacerlos filtrable al dar clic en ellos, pero, aquí nos falta una cosa más para que incluya el comportamiento adecuado de estos campos:

  1. span style="color: #808080; font-style: italic;">// Search tools bar
  2. 'joomla.searchtools.default''view'
Source code

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento de los filtros

Aquí incluimos un layout más (layouts\joomla\searchtools\default.php) el cual nos brinda la barra de herramientas o de filtros que podemos ver dentro del gestor de artículos más el campo de búsqueda, pero además, nos brinda todo el material necesario para que nuestros encabezados puedan funcionar al dar clic sobre ellos. Este layout de “searchtools” solo nos pide una sola cosa para su funcionamiento, un archivo xml con los campos que son filtrables en la vista. Y nosotros como somos bondadosos, se lo creamos sin problema. Este archivo lo colocamos dentro de una carpeta “forms” que va dentro de la carpeta “models” de los archivos de la administración del componente (recuerden que Joomla establece esto así, no es arbitrariamente), conteniendo lo siguiente:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <form>
  3. <fields name="filter">
  4. <field
  5. name="search"
  6. type="text"
  7. label="COM_MJCOMMENTS_FILTER_SEARCH_DESC"
  8. description="COM_MJCOMMENTS_FILTER_SEARCH_DESC"
  9. hint="JSEARCH_FILTER"
  10. />
  11. <field
  12. name="published"
  13. type="commentstatus"
  14. label="COM_MJCOMMENTS_FILTER_PUBLISHED"
  15. description="COM_MJCOMMENTS_FILTER_PUBLISHED_DESC"
  16. onchange="this.form.submit();"
  17. >
  18. <option value="">JOPTION_SELECT_PUBLISHED</option>
  19. </field>
  20. </fields>
  21. <fields name="list">
  22. <field
  23. name="fullordering"
  24. type="list"
  25. label="COM_MJCOMMENTS_LIST_FULL_ORDERING"
  26. description="COM_MJCOMMENTS_LIST_FULL_ORDERING_DESC"
  27. onchange="this.form.submit();"
  28. default="a.id DESC"
  29. >
  30. <option value="">JGLOBAL_SORT_BY</option>
  31. <option value="a.state ASC">JSTATUS_ASC</option>
  32. <option value="a.state DESC">JSTATUS_DESC</option>
  33. <option value="a.content_id ASC">JGLOBAL_TITLE_ASC</option>
  34. <option value="a.content_id DESC">JGLOBAL_TITLE_DESC</option>
  35. <option value="a.visitor_name ASC">JAUTHOR_ASC</option>
  36. <option value="a.visitor_name DESC">JAUTHOR_DESC</option>
  37. <option value="a.created ASC">JDATE_ASC</option>
  38. <option value="a.created DESC">JDATE_DESC</option>
  39. <option value="a.id ASC">JGRID_HEADING_ID_ASC</option>
  40. <option value="a.id DESC">JGRID_HEADING_ID_DESC</option>
  41. </field>
  42. <field
  43. name="limit"
  44. type="limitbox"
  45. class="input-mini"
  46. default="25"
  47. label="COM_MJCOMMENTS_LIST_LIMIT"
  48. description="COM_MJCOMMENTS_LIST_LIMIT_DESC"
  49. onchange="this.form.submit();"
  50. />
  51. </fields>
  52. </form>
  53.  
Source code

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento de los filtros
Resolviendo errores en la vista de comentarios de la administración - Funcionamiento de los filtros

El nombre del archivo tiene que ser “filter_commentslist” donde “commentslist” es el nombre del modelo que estamos utilizando ahora.

Archivos como este ya lo hemos podido apreciar cuando estábamos desarrollando el plugin. Aquí sólo destacaremos algunas cosas.

Los campos los agrupamos en dos grupos. Un grupo que sería el campo de buscar más los filtros a utilizar (<fields name="filter">....</fields>) y otro grupo para la lista de campos filtrables y la cantidad de elementos a mostrar (<fields name="list">....</fields>). Esta es la forma en la que tenemos que concebir este archivo para el correcto funcionamiento del mismo.

Otra cosa a destacar, es que en casi todo los campos existe un atributo “onchange”, el cual nos brinda la funcionalidad de recargar la página aplicando los cambios en los filtros.

Ahora notemos algo interesante en la línea 13 de este archivo. El tipo de campo establecido aquí es “commentstatus” el cual no es un campo estándar de Joomla. Por tanto, tenemos que definir en algún lado este campo.

Creamos la carpeta “fields” y dentro un archivo llamado “commentstatus.php” conteniendo lo siguiente:

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Component
  3.  * @subpackage mjcomments
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC''predefinedlist');
  8.  
  9. /**
  10.  * Form Field to load a list of states
  11.  *
  12.  *//**
  13.   * The form field type.
  14.   * @var string
  15.   */'CommentStatus';
  16.  
  17. /**
  18.   * Available statuses
  19.   * @var array
  20.   */'0' => 'JUNPUBLISHED',
  21. '1' => 'JPUBLISHED',
  22. '*' => 'JALL'
  23. );
  24. }
Source code

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento de los filtros

En Joomla, hay un campo que pudiéramos haber utilizado en vez de crear uno personalizado para nosotros. Pueden verlo en “libraries\cms\form\field\status.php”. ¿Porque no utilizamos este campo? Porque nosotros no estamos manejando los estado de “Archivado” y “Papelera” por ello es que no podemos utilizarlo, pero si aprovecharlo, copiando casi completo el código del mismo, y utilizándolo en nuestro campo. Pueden ver la clase padre de nuestro campo “JFormFieldPredefinedList” en “libraries\joomla\form\fields\predefinedlist.php” para que vean como arman la salida HTML del campo.

Por último, recuerden añadir al archivo de idioma “es-ES.com_mjcomments.ini”, las cadenas de texto nuevas que hemos introducido en el archivo “filter_commentslist”.

Volvamos ahora al camino luego de este pequeño desvío. Ya tenemos el archivo xml que nos pide el layout “searchtools”, para su trabajo. Ahora solo nos queda asegurarnos de que la vista puede manejar este archivo, para que cuando “searchtools” lo pida, pueda dárselo. Así que editamos el archivo “view.html.php” añadiendo lo siguiente:

  1. span style="color: #ff0000;">'FilterForm');
Source code

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento de los filtros

Esta función la puedes encontrar en la clase padre de nuestro modelo “JModelList”. Con esto, ya la vista tiene todos los campos filtrables que hemos definido. ¡Por fin! hagamos una prueba para todo esto. Actualicemos el paquete.

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento de los filtros

¡Hombre, estamos de racha! no ha ocurrido ningún fallo nuevamente. Todos los filtros han funcionado perfectamente. Bueno, casi todos, porque tanto el filtro de “Seleccionar estado” bajo el botón desplegable de las herramientas de búsqueda, como el campo para buscar, aún no funcionan. Pero hemos solucionado el problema que habíamos planteado de los encabezados de la tabla. Ahora si da clic encima de cualquier encabezado, la página se volverá a cargar ordenando la tabla por el campo cliqueado.

Antes de continuar, vamos añadir una línea más al layout de la vista para el correcto funcionamiento y visibilidad de los filtros, para que nada falle:

  1. span style="color: #ff0000;">'formbehavior.chosen', 'select');
Source code

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento de los filtros

Si vuelven actualizar el paquete, verán que la visualidad de los filtros han cambiado un poco, mostrándose al estilo bootstrap.

Entonces, se nos han sumado dos problemas más a nuestra lista de problemas. Ahora tenemos:

Primero, el botón de publicar o despublicar no funciona, arrojando un error de controlador no encontrado.

Segundo, el filtro de “Seleccionar estado” bajo el botón desplegable de las herramientas de búsqueda no funciona

Tercero, el campo de búsqueda no funciona.

Sigamos resolviendo problemas en orden de menor a mayor. Las acciones o tareas llevadas a cabo por una vista, necesitan de un subcontrolador que las atienda. Por ello, al igual que hicimos en el frontend, crearemos una carpeta llamada “controllers” en los archivos de la administración del componente, conteniendo dentro el archivo “commentslist.php”.

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Component
  3.  * @subpackage mjcomments
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC'/**
  8.  * Comments list controller class.
  9.  *
  10.  *//**
  11.   * Constructor.
  12.   *
  13.   * @param array $config An optional associative array of configuration settings.
  14.   *
  15.   *//**
  16.   * Proxy for getModel.
  17.   *
  18.   * @param string $name The model name. Optional.
  19.   * @param string $prefix The class prefix. Optional.
  20.   * @param array $config Configuration array for model. Optional.
  21.   *
  22.   * @return object The model.
  23.   *
  24.   */'Commentform', $prefix = 'MjcommentsModel''ignore_request'
Source code

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento del botón de publicar o despublicar una galería
Resolviendo errores en la vista de comentarios de la administración - Funcionamiento del botón de publicar o despublicar una galería

Esta vez hemos usado como clase padre “JControllerAdmin” (libraries\legacy\controller\admin.php). Esta clase contiene funciones que pertenecen a las acciones o tareas más comunes a llevar a cabo por las vistas. Ejemplo, la función “delete”, encargada de eliminar un elemento. Otro ejemplo es la función “publish”, encargada de realizar la tarea que nos interesa a nosotros ahora, publicar un elemento.

Con esta clase padre haciendo todo lo que necesitamos, pocas cosas podemos hacer. Como sabemos, el controlador es el que maneja la tarea a llevar a cabo. La vista pidió publicar o despublicar un elemento, por lo que el controlador recoge la petición y manda al modelo a ejecutar la tarea de publicar o despublicar “este” elemento. Y es precisamente lo que hacemos a partir de la línea 39 en nuestra clase “MjcommentsControllerCommentslist”. Si se fijan en la función “publish”, dentro de la clase “JControllerAdmin”, en la línea 201 aproximadamente, se hace una llamada a la función “getModel”, para obtener el modelo que va a ejecutar la tarea de publicar o despublicar un elemento. Pero en nuestra clase, el modelo que le pasamos al controlador es “Commentform” el cual no hemos creado. ¿Porque crear un modelo nuevo? EL modelo que actualmente estamos usando es “commentslist”, que su objetivo es listar los comentarios insertados en el sistema. No tiene sentido insertar en este modelo funciones relacionadas a tareas que pertenecen a uno o algunos elementos en particular ¿no creen? Por ello la decisión de usar otro modelo para estas tareas.

La clase padre que estamos usando en el modelo “commentslist” es, “JModelList”, la cual, no nos favorece mucho a la hora de realizar tareas como publicar o eliminar un elemento. Por lo que otra razón por la que vamos a crear otro modelo, es que podemos hacer uso de la clase “JModelAdmin” (libraries\legacy\model\admin.php) que sí está bien preparada para estas tareas. Además, tenemos como extra, que la clase “JModelForm” es la clase padre de “JModelAdmin” por lo que tendremos todo lo necesario para cuando habilitemos la edición de un comentario. Así que necesariamente tenemos que tomar este pequeño desvío, por lo que crearemos el modelo “commentform.php”:

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Component
  3.  * @subpackage mjcomments
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC'/**
  8.  * Methods supporting a list of comments records.
  9.  *
  10.  *//**
  11.   * @var string The prefix to use with controller messages.
  12.   */'COM_MJCOMMENTS';
  13.  
  14. /**
  15.   * The type alias for this content type.
  16.   *
  17.   * @var string
  18.   */'com_mjcomments.commentform';
  19.  
  20. /**
  21.   * Method to get the record form.
  22.   *
  23.   * @param array $data Data for the form.
  24.   * @param boolean $loadData True if the form is to load its own data (default case), false if not.
  25.   *
  26.   * @return mixed A JForm object on success, false on failure
  27.   *
  28.   */// Get the form.
  29. 'commentform''control' => 'jform', 'load_data'/**
  30.   * Get database table
  31.   *
  32.   * @param string $type The table type to instantiate
  33.   * @param string $prefix A prefix for the table class name. Optional.
  34.   * @param array $config Configuration array for model. Optional.
  35.   *
  36.   * @return JTable
  37.   */'Mjcomments', $prefix = 'MjcommentsTable''published', 'state'
Source code

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento del botón de publicar o despublicar una galería
Resolviendo errores en la vista de comentarios de la administración - Funcionamiento del botón de publicar o despublicar una galería

Aquí hay muy pocas cosas nuevas, ya que un modelo similar a este lo hemos trabajado cuando estábamos desarrollando el frontend del sistema de comentarios.

Tenemos dos variables globales necesarias para las clases padres. La primera, “$text_prefix” se va a usar como prefijo para todos los mensajes generados desde el modelo padre. La segunda, es para establecer el nombre del formulario con el que va a trabajar nuestro modelo. Recuerden, que este modelo va a trabajar con uno o varios comentarios de nuestra tabla de comentarios, por lo que tiene que tener acceso a los campos del comentario, y sabemos que esto se hace a través de un formulario.

Pero ¿cúal formulario?. Dentro de la carpeta “site” en los archivos del componente, tenemos el formulario “site/models/forms/formcomment.xml” que se lo mostramos al visitante para que pueda comentar. Este formulario pudiéramos usarlo para la administración del componente ya que al final estamos usando los mismos campos, aunque entonces tuviéramos que añadir la ruta del mismo en la función “getForm” del modelo que acabamos de crear. Pero, buscando independencia en la administración y el frontend, hemos creado un formulario nuevo dentro de la carpeta admin de los archivos del componente, y lo llamamos “commentform.xml”. Por lo que tienen que crear un archivo XML con nombre “commentform” dentro de “admin/models/forms” y copiar todo el contenido del formulario “formcomment” (site/models/forms/formcomment.xml) en este archivo. Al hacer esto, hemos añadido cadenas de texto nuevas en la administración, por lo que debemos incluirlas en el archivo de idioma de esta parte (es-ES.com_mjcomments.ini). Noten, que tal vez algunas cadenas de texto no tienen que tener el mismo valor que le dimos en el frontend, ejemplo, COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_LABEL="Correo (no será publicado)", creo que este valor no tiene sentido en la administración, tal vez sería más coherente, dejarlo solo en “Correo electrónico” (Visualicen la edición de un comentario y se daran cuenta).

La función “getTable” es muy similar a la del frontend, pero, hemos añadido algo importante para el correcto funcionamiento de este modelo. En la línea 64, tenemos una función la cual le pertenece a la clase “JTable”. Esta función nos permite registrar un alias para una columna “especial” de la tabla. La razón es muy simple. Nuestro modelo utiliza la función “publish” de la clase padre “JModelAdmin”, para publicar o despublicar uno o varios comentarios seleccionados. Está a su vez utiliza la función “publish” de la clase “JTable” para llevar a cabo esta tarea. Esta última función utiliza una columna llamada “published”, como la columna que almacena el valor de los estados (publicado, despublicado, etc) de un elemento. En nuestro caso, la columna que se utiliza para este propósito, es la columna “state”. Por lo que a través de la línea 64 le decimos a la clase “JTable”, que trate “published” como la columna “state”. Así de simple.

Probemos entonces si ya podemos despublicar o publicar un elemento. Actualizamos el paquete:

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento del botón de publicar o despublicar una galería

¡Maravilloso! ha despublicado el comentario sin problema. Observen cómo ha salido una cadena de texto en el mensaje que nos notifica que se ha despublicado un elemento. Así que tendremos que añadir esta cadena, como la que sale cuando publicamos un comentario, a nuestro archivo de idioma. También noten que el empezar de la cadena corresponde al prefijo que añadimos en el modelo.

Otro problema solucionado, ya vamos saliendo. En nuestra lista de problemas nos queda:

Primero, el filtro de “Seleccionar estado” bajo el botón desplegable de las herramientas de búsqueda no funciona.

Segundo, el campo de búsqueda no funciona.

Ambos problemas, son problemas de filtros. Si buscamos en el modelo “commentslist” encargado de la lista de comentarios, nos damos cuenta que no realizamos un tratamiento a estos filtros, originando la causa de porque no funcionan. Así que a ambos los resolveremos en una sola edición.

Lo primero es modificar “populateState” estableciendo un valor para ambos filtros.

  1. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
  2. $this->setState('filter.search', $search);
  3.  
  4. $published = $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '');
  5. $this->setState('filter.published', $published);
Source code

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento del botón de estado y el campo de búsqueda

Recuerden que estos filtros están definidos en “filter_commentslist.xml”. Luego, modificamos la función “getStoreId” para que el modelo pueda recuperar los valores asignados para estos filtros.

  1. $id .= ':''filter.search');
  2. $id .= ':''filter.published');
Source code

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento del botón de estado y el campo de búsqueda

Y por último, añadimos el filtrado cuando construimos la consulta:

  1. // Filter by published state
  2. 'filter.published''a.state = ''*')
  3. {
  4. $query->where('(a.state = 0 OR a.state = 1)');
  5. }
  6.  
  7. // Filter by search in title.
  8. 'filter.search''id:') === 0)
  9. {
  10. $query->where('a.id = ''%'' ', '%''%'));
  11. $query->where('(c.title LIKE ' . $search . ' OR c.alias LIKE ' . $search . ')');
  12. }
  13. }
Source code

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento del botón de estado y el campo de búsqueda

Con esto, ya debe funcionar correctamente así que probemos. Actualizamos el paquete y:

Resolviendo errores en la vista de comentarios de la administración - Funcionamiento del botón de estado y el campo de búsqueda

¡Ni mandado a pedir hubiera quedado tan bien! Seguimos con la racha ganadora, y ya no nos queda más problemas por resolver, es una lástima ¿verdad?.

Seguimos, así que espero que no estés cansado. Vamos añadirle a este listado una paginación, porque sin duda que va a ser muy importante para cuando el listado crezca. Es bien fácil, recuerda que tenemos un modelo padre que hace todo por nosotros. Así que pasemos directamente a la vista “commentslist” y editemos el archivo “view.html.php”:

  1. protected $pagination;
Source code

  1. $this->pagination = $this->get('Pagination');
Source code

Vista del listado de comentarios en la administración - Paginación

La clase padre “JModelList” tiene una función “getPagination” que nos crea el objeto para la paginación de nuestra vista. Este objeto se lo asignamos a la variable global “$pagination” para poderla usar en el layout de la vista. Por lo que toca editar el archivo “default.php”:

  1.  
Source code

Vista del listado de comentarios en la administración - Paginación

Con tan solo llamar a la función “getListFooter” del objeto de la paginación, hemos terminado. ¿No me lo creen? porque no actualizan el paquete y lo ven por ustedes mismos.

Vista del listado de comentarios en la administración - Paginación

Ya ven que facil fue. Ha sido cuestión de llamar a unas funciones y listo.

A la verdad que la vista en la administración se va haciendo cada vez más agradable. Pero aún seguimos con una última carrera, así que aguanta que ya casi llegamos. Incluyamos por último la barra de herramientas de cualquier vista de un componente en la administración, la cual nos brinda botones como publicar, despublicar, el título de la vista etc. Para esto haremos uso de “JToolbarHelper”.

Abrimos una vez más el archivo “view.html.php” añadiendo lo siguiente:

  1. $this->addToolbar();
Source code

  1. /**
  2.  * Add the page title and toolbar.
  3.  *
  4.  * @return void
  5.  *
  6.  */// Get the toolbar object instance
  7. 'toolbar''COM_MJCOMMENTS_VIEWS_COMMENTSLIST_TITLE'), 'title comments');
  8.  
  9. JToolbarHelper::publish('commentslist.publish', 'JTOOLBAR_PUBLISH''commentslist.unpublish', 'JTOOLBAR_UNPUBLISH'
Source code

Vista del listado de comentarios en la administración - barra de herramientas

Algo que nos ha resultado nuevamente, bien fácil. Resaltar que “JToolbarHelper” no es parte de la librería de API´s de Joomla, sino más bien como una clase “helper” para simplificar la creación de la barra de herramientas en la administración. Bueno, y a que estamos esperando, actualicemos el paquete:

Vista básica completa del listado de artículos

¡Epale! a la verdad que mejor imposible.

Hemos logrado tener una administración básica para nuestro sistema de comentarios, pero de seguro todos coinciden conmigo que falta más. 

Por ejemplo, implementar el listado de control de acceso en el componente, permitiendo configurar que pueden ver o hacer los usuarios en el componente.

Crear la posibilidad que un moderador de comentarios pueda editar determinado comentario o eliminarlo, sería otro aspecto muy importante a llevar a cabo. 

Otro funcionalidad interesante sería implementar los parámetros globales del componente, a pesar que aún no nos haga falta.

En fin, siempre queda algo que mejorar, pero no podemos abarcarlo todo en un solo tutorial. Trataremos de cubrirlo todo según nos permita el ciclo, pero siempre asegurando que lo básico que tengamos, sea conciso.

Recuerden, que en nuestro repositorio encontraran el código fuente de todo lo que hemos hablado en estos cuatro tutoriales. Nos vemos.

Etiquetas: Desarrollo, Extensiones, Ciclo de desarrollo, Programación

Imprimir