J3.x

Difference between revisions of "Developing an MVC Component/Adding ACL/es"

From Joomla! Documentation

< J3.x:Developing an MVC Component
(Created page with "=== Configuración de los valores de permisos en la tabla assets ===")
(Updating to match new version of source page)
 
(77 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
<noinclude><languages /></noinclude>
 
<noinclude><languages /></noinclude>
{{review}}
 
 
{{:J3.1:Developing an MVC Component/es}}
 
{{:J3.1:Developing an MVC Component/es}}
 
== Introducción ==
 
== Introducción ==
Line 12: Line 11:
 
En este artículo vamos a mostrar cómo agregar y utilizar los permisos de acceso con diferentes niveles de granularidad: para el componente como un todo, para las categorías y para los elementos individuales.
 
En este artículo vamos a mostrar cómo agregar y utilizar los permisos de acceso con diferentes niveles de granularidad: para el componente como un todo, para las categorías y para los elementos individuales.
  
Nota: en este ejemplo HelloWorld estamos trabajando en el lado servidor, por lo que los únicos niveles de acceso disponibles son ''administrador'' y ''superusuario''.
+
Para probar esta funcionalidad crea usuarios y asócialos con los grupos de usuarios que tienen acceso a la funcionalidad de administrador del lado servidor (es decir, aquellos grupos de usuarios que tienen permisos de Inicio de sesión como Administrador en los permisos de la Configuración Global). De forma predeterminada, son Gestor y Administrador, pero también puedes definir tus propios grupos de usuarios y, opcionalmente, establecerlos como dependientes de Gestor o Administrador.
Para probar este tutorial primero crear un nuevo usuario administrador y a continuación, establecer sus permisos (trabajando como superusuario).
+
 
Después al estar registrado en el sistema como administrador podrá ver los cambios.
+
Si aún no está muy familiarizado con la Lista de control de Acceso de Joomla!, te recomiendo ver este video [https://youtu.be/CFqXAc3orkY ACL Explicado (En inglés)] (entre 2 minutos y 32 minutos es la sección a mirar) y lee esto [[S:MyLanguage/J3.x:Access_Control_List_Tutorial|Tutorial de la lista de control de acceso]].
 +
 
 +
Tres vídeos (en inglés) asociados con este paso del tutorial cubren la [https://youtu.be/kOqWcSF-p5Q Infraestructura de Control de Acceso de] de Joomla, una explicación del [https://youtu.be/sljTur6zMOs código del tutorial] de este paso y un vídeo complementario en [https://youtu.be/CS_Ok1t550E Niveles de acceso de visualización]
 +
 
 +
{{#widget:YouTube|id=kOqWcSF-p5Q}}
 +
 
 +
{{#widget:YouTube|id=sljTur6zMOs}}
 +
 
 +
{{#widget:YouTube|id=CS_Ok1t550E}}
  
 
== Requerimientos mínimos de ACL a nivel del componente ==
 
== Requerimientos mínimos de ACL a nivel del componente ==
Line 22: Line 29:
  
 
Esta soporte ACL básico se realiza en 4 sencillos pasos:
 
Esta soporte ACL básico se realiza en 4 sencillos pasos:
* [[#Agregar_las_2_acciones_mínimas_a_nivel_de_componente_a_access.xml|Agregar las 2 acciones mínimas a nivel de componente a access.xml]]
+
* [[#Agregar_las_2_acciones_mínimas_a_nivel_de_componente_a_access.xml |Agregar las 2 acciones mínimas a nivel de componente a access.xml]]
 
* [[#Agregar_los_conjuntos_de_campo_de_permisos_a_config.xml|Agregar los conjuntos de campo de permisos a config.xml]]
 
* [[#Agregar_los_conjuntos_de_campo_de_permisos_a_config.xml|Agregar los conjuntos de campo de permisos a config.xml]]
 
* [[#Agregar_el_botón_.27Opciones.27_en_la_barra_de_herramientas_cuando_el_usuario_esta_autorizado|Agregar el botón 'Opciones' en la barra de herramientas cuando el usuario esta autorizado]]
 
* [[#Agregar_el_botón_.27Opciones.27_en_la_barra_de_herramientas_cuando_el_usuario_esta_autorizado|Agregar el botón 'Opciones' en la barra de herramientas cuando el usuario esta autorizado]]
 
* [[#Restringir_el_acceso_al_lado_servidor_del_componente_a_grupos_de_usuarios_autorizados|Restringir el acceso al lado servidor del componente a grupos de usuarios autorizados]]
 
* [[#Restringir_el_acceso_al_lado_servidor_del_componente_a_grupos_de_usuarios_autorizados|Restringir el acceso al lado servidor del componente a grupos de usuarios autorizados]]
 
  
 
=== Agregar las 2 acciones mínimas a nivel de componente a access.xml ===
 
=== Agregar las 2 acciones mínimas a nivel de componente a access.xml ===
Line 79: Line 85:
 
</source>
 
</source>
  
Véase más abajo para un [[#admin/views/helloworlds/vista.html.php|ejemplo más elaborado ''admin/views/helloworlds/view.html.php'']] donde esta ''JToolBarHelper::preferencias('com_helloworld')'', se hace en un método addToolBar() junto con el resto de botones de la barra de herramientas y la comprobación ''JUser->authorise()'' se realiza con JHelperContent, lo que resulta de la propiedad $canDo.
+
Véase más abajo para un [[#admin/views/helloworlds/view.html.php|ejemplo más elaborado de ''admin/views/helloworlds/view.html.php'']] donde esta ''JToolBarHelper::preferencias('com_helloworld')'', se hace en un método addToolBar() junto con el resto de botones de la barra de herramientas y la comprobación ''JUser->authorise()'' se realiza con JHelperContent, lo que resulta de la propiedad $canDo.
  
 
=== Restringir el acceso al lado servidor del componente a grupos de usuarios autorizados ===
 
=== Restringir el acceso al lado servidor del componente a grupos de usuarios autorizados ===
Line 103: Line 109:
 
Además también tenemos que hacer los siguientes pasos:
 
Además también tenemos que hacer los siguientes pasos:
 
* [[#Agregar_un_asset_id_a_la_tabla_de_la_base_de_datos|Agregar un asset_id a la tabla de la base de datos del elemento para el control de acceso a nivel del ítem]]
 
* [[#Agregar_un_asset_id_a_la_tabla_de_la_base_de_datos|Agregar un asset_id a la tabla de la base de datos del elemento para el control de acceso a nivel del ítem]]
* [[#Setting_the_permission_values_in_the_assets_table|Guardar los permisos en la tabla de recursos. Especialmente cuidar de establecer el asset_id del asset padre]]
+
* [[#Configuración_de_los_valores_de_permisos_en_la_tabla_assets|Guardar los permisos en la tabla de recursos. Especialmente cuidar de establecer el asset_id del asset padre]]
* [[#Showing_the_setting_of_permissions_on_the_item_level|Realizar los ajustes de los permisos a nivel de elemento editable]]
+
* [[#Mostrar_la_configuración_de_permisos_a_nivel_de_elemento|Realizar los ajustes de los permisos a nivel de elemento editable]]
* [[#Adding_language_strings|Agregar algunas cadenas de idioma]]
+
* [[#Agregar_cadenas_de_idioma|Agregar algunas cadenas de idioma]]
  
 
=== Describiendo las acciones sobre las que deseas controlar el acceso ===
 
=== Describiendo las acciones sobre las que deseas controlar el acceso ===
Each component (or part of it) has its own set of permissions that can be controlled. They are described in an <tt>access.xml</tt> file located at the root of the ''admin'' folder. In this helloworld-example the actions to which access is controlled are divided in three sections: at the component level, the category level and the item level. An 'item' is called a 'message' in our example component, hence the name of the third section.
+
Cada componente (o parte de el) tiene su propio conjunto de permisos que pueden ser controlados. Ellos son descriptos en el archivo <tt>access.xml</tt> que se encuentra en la raíz de la carpeta ''admin''. En este ejemplo helloworld las acciones en las que el acceso es controlado se dividen en tres secciones: a nivel de componente, a nivel de categoría y a nivel de elemento. Un 'elemento' se llama un 'mensaje' en nuestro ejemplo de componente, de ahí el nombre de la tercera sección.
  
 
<span id="admin/access.xml">
 
<span id="admin/access.xml">
 
<tt>admin/access.xml</tt>
 
<tt>admin/access.xml</tt>
<source lang="xml" highlight="10-16">
+
<source lang="xml" highlight="9-10,12-18">
 
<?xml version="1.0" encoding="utf-8" ?>
 
<?xml version="1.0" encoding="utf-8" ?>
 
<access component="com_helloworld">
 
<access component="com_helloworld">
Line 121: Line 127:
 
<action name="core.delete" title="JACTION_DELETE" description="JACTION_DELETE_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" />
 
<action name="core.edit" title="JACTION_EDIT" description="JACTION_EDIT_COMPONENT_DESC" />
 +
<action name="core.edit.state" title="JACTION_EDITSTATE" description="JACTION_EDITSTATE_COMPONENT_DESC" />
 +
<action name="core.edit.own" title="JACTION_EDITOWN" description="JACTION_EDITOWN_COMPONENT_DESC" />
 
</section>
 
</section>
 
<section name="category">
 
<section name="category">
Line 138: Line 146:
  
 
=== Agregando la configuración de permisos en las Preferencias del componente ===
 
=== Agregando la configuración de permisos en las Preferencias del componente ===
Since we now use Access Control permissions in our component, we need to be able to set them at the component level. That is done in the Preferences of this component: the screen you see after clicking the 'Options' button. The config.xml-file is a form-definition for those Preferences. We could define the component level actions here too, as a child of the "rules" field-tag, but it is now preferred to also put those actions in <tt>access.xml</tt> in that way all access rules for this component are on one spot.
+
Puesto que ahora usamos permisos de Control de Acceso en nuestro componente, tenemos que ser capaces de ponerlos en el nivel del componente. Se hace en las Preferencias de este componente: la pantalla se puede ver después de hacer clic en el botón 'Opciones'. El archivo de configuración config.xml es un archivo de formulario con la definición de esas Preferencias. Podríamos definir el nivel de las acciones del componente aquí también, como un hijo de las "reglas" de la etiqueta del campo, pero ahora se prefiere también poner esas acciones en <tt>access.xml</tt> de esa manera todas las reglas de acceso para este componente están en un solo lugar.
  
 
<span id="admin/config.xml">
 
<span id="admin/config.xml">
Line 184: Line 192:
 
=== Mostrar sólo los botones correctos de la barra de herramientas ===
 
=== Mostrar sólo los botones correctos de la barra de herramientas ===
  
Which toolbar buttons to display depends on the Access Control permissions for the user. We put all permissions for this user in the $canDo property of the view; so we can eventually refer to it in layouts (in the edit-form for example).
+
Que botones de la barra de herramientas se van a mostrar depende de los permisos de Control de Acceso del usuario.  
 +
 
 +
Comúnmente con los componentes base de Joomla, usamos JHelperContent::getActions() para encontrar los permisos. Pasamos a esta función la identidad del registro activo, y devuelve un objeto que contiene todas las Acciones que están asociadas con nuestro componente helloworld, junto con (para cada Acción) si el usuario actualmente conectado tiene ese permiso o no. Si luego llamamos a <tt>get('alguna.acción')</tt> en este objeto, devolverá verdadero o falso, dependiendo de si el usuario tiene este permiso o no.  
  
In the <tt>admin/views/helloworlds/view.html.php</tt>, put this code:
+
En el archivo <tt>admin/views/helloworlds/view.html.php</tt> coloca estas líneas:
  
 
<span id="admin/views/helloworlds/view.html.php">
 
<span id="admin/views/helloworlds/view.html.php">
 
<tt>admin/views/helloworlds/view.html.php</tt>
 
<tt>admin/views/helloworlds/view.html.php</tt>
<source lang="php" highlight="42-44,83-85,87-89,91-93,95-98,100" >
+
<source lang="php" highlight="42-44,48,81-83,85-87,89-91,93-96,98" >
 
<?php
 
<?php
 
/**
 
/**
Line 196: Line 206:
 
  * @subpackage  com_helloworld
 
  * @subpackage  com_helloworld
 
  *
 
  *
  * @copyright  Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
+
  * @copyright  Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  */
 
  */
Line 233: Line 243:
  
 
// What Access Permissions does this user have? What can (s)he do?
 
// What Access Permissions does this user have? What can (s)he do?
$this->canDo = JHelperContent::getActions();
+
$this->canDo = JHelperContent::getActions('com_helloworld');
  
 
// Check for errors.
 
// Check for errors.
Line 304: Line 314:
 
<span>
 
<span>
  
In the <tt>admin/views/helloworld/view.html.php</tt>, put this code:
+
En el archivo <tt>admin/views/helloworld/view.html.php</tt> coloca estas líneas:
  
 
<span id="admin/views/helloworld/view.html.php">
 
<span id="admin/views/helloworld/view.html.php">
 
<tt>admin/views/helloworld/view.html.php</tt>
 
<tt>admin/views/helloworld/view.html.php</tt>
<source lang="php" highlight="23,39-41,76-78,81-89,93-112">
+
<source lang="php" highlight="23,39-41,45,79-111">
 
<?php
 
<?php
 
/**
 
/**
Line 314: Line 324:
 
  * @subpackage  com_helloworld
 
  * @subpackage  com_helloworld
 
  *
 
  *
  * @copyright  Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
+
  * @copyright  Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  */
 
  */
Line 348: Line 358:
  
 
// What Access Permissions does this user have? What can (s)he do?
 
// What Access Permissions does this user have? What can (s)he do?
$this->canDo = JHelperContent::getActions($this->item->id);
+
$this->canDo = JHelperContent::getActions('com_helloworld', 'helloworld', $this->item->id);
  
 
// Check for errors.
 
// Check for errors.
Line 436: Line 446:
 
                                  . "/views/helloworld/submitbutton.js");
 
                                  . "/views/helloworld/submitbutton.js");
 
JText::script('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE');
 
JText::script('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE');
}
 
}
 
 
</source>
 
</span>
 
 
These two files use the ''getActions'' method defined in the <tt>admin/helpers/helloworld.php</tt> file.
 
 
In the helper-file, put this code:
 
 
<span id="admin/helpers/helloworld.php">
 
<tt>admin/helpers/helloworld.php</tt>
 
<source lang="php" highlight="50-72">
 
<?php
 
/**
 
* @package    Joomla.Administrator
 
* @subpackage  com_helloworld
 
*
 
* @copyright  Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
 
* @license    GNU General Public License version 2 or later; see LICENSE.txt
 
*/
 
 
// No direct access to this file
 
defined('_JEXEC') or die('Restricted access');
 
 
/**
 
* HelloWorld component helper.
 
*
 
* @param  string  $submenu  The name of the active view.
 
*
 
* @return  void
 
*
 
* @since  1.6
 
*/
 
abstract class HelloWorldHelper
 
{
 
/**
 
* Configure the Linkbar.
 
*/
 
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'
 
);
 
 
// set some global property
 
$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'));
 
}
 
}
 
 
/**
 
* Get the actions
 
*/
 
public static function getActions($messageId = 0)
 
{
 
$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, JFactory::getUser()->authorise($action->name, $assetName));
 
}
 
 
return $result;
 
 
}
 
}
 
}
 
}
Line 528: Line 454:
 
=== Restringir el acceso al componente ===
 
=== Restringir el acceso al componente ===
  
The main idea in ACL is to restrict actions to groups of users. The first action to be restricted is access to the administrative backend of the component itself. With your favourite file editor, edit the <tt>admin/helloworld.php</tt> file and add the lines with the access check.
+
La idea principal en ACL es restringir las acciones de los grupos de usuarios. La primera acción a ser restringida, es el acceso a la administración del lado servidor del propio componente. Con tu editor de archivos favorito, modifica el archivo <tt>admin/helloworld.php</tt> y agrega las líneas con la comprobación de acceso.
  
 
<span id="admin/helloworld.php">
 
<span id="admin/helloworld.php">
Line 538: Line 464:
 
  * @subpackage  com_helloworld
 
  * @subpackage  com_helloworld
 
  *
 
  *
  * @copyright  Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
+
  * @copyright  Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  */
 
  */
Line 572: Line 498:
 
=== Agregar un asset_id a la tabla de la base de datos ===
 
=== Agregar un asset_id a la tabla de la base de datos ===
  
In order to be able to work with JTable an asset_id column has to be added to the database #__helloworld table.
+
Con el fin de ser capaz de trabajar con JTable una columna asset_id tiene que ser agregada a la tabla #__helloworld de la base de datos.
  
So, <tt>admin/sql/install.mysql.utf8.sql</tt> becomes:
+
Así, <tt>admin/sql/instalar.mysql.utf8.sql</tt> se convierte en:
  
 
<span id="admin/sql/install.mysql.utf8.sql">
 
<span id="admin/sql/install.mysql.utf8.sql">
Line 601: Line 527:
 
</span>
 
</span>
  
For updates we add a sql-update-file:
+
Para actualizaciones añadimos un archivo sql de actualización:
  
 
<span id="admin/sql/updates/mysql/0.0.14.sql">
 
<span id="admin/sql/updates/mysql/0.0.14.sql">
 
<tt>admin/sql/updates/mysql/0.0.14.sql</tt>
 
<tt>admin/sql/updates/mysql/0.0.14.sql</tt>
 
<source lang="mysql">
 
<source lang="mysql">
ALTER TABLE`#__helloworld` ADD COLUMN `asset_id` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `id`;
+
ALTER TABLE `#__helloworld` ADD COLUMN `asset_id` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `id`;
 
</source>
 
</source>
 
</span>
 
</span>
  
=== Restricting access to the messages ===
+
=== Restringir el acceso a los mensajes ===
  
So far we have restricted access to the component itself, but we also need to do that at ''message'' level.
+
Hasta ahora hemos restringido el acceso al componente en sí, pero también tenemos que hacerlo a nivel ''mensaje''.
  
To check the '''"core.delete"''' permission you need to modify the model class: <tt>admin/models/helloworld.php</tt> by adding these lines:
+
Para comprobar los permisos del '''"core.delete"''' es necesario modificar la clase del modelo: <tt>admin/models/helloworld.php</tt> al agregar estas líneas:
  
 
<span id="admin/models/helloworld.php">
 
<span id="admin/models/helloworld.php">
Line 624: Line 550:
 
  * @subpackage  com_helloworld
 
  * @subpackage  com_helloworld
 
  *
 
  *
  * @copyright  Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
+
  * @copyright  Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  */
 
  */
Line 715: Line 641:
 
}
 
}
 
/**
 
/**
* Method to check if it's OK to delete a message. Overwrites JModelAdmin::canDelete
+
* Method to check if it's OK to delete a message. Overrides JModelAdmin::canDelete
 
*/
 
*/
 
protected function canDelete($record)
 
protected function canDelete($record)
Line 721: Line 647:
 
if( !empty( $record->id ) )
 
if( !empty( $record->id ) )
 
{
 
{
return JFactory::getUser()->authorise( "core.delete", "com_helloworld.message." . $record->id );
+
return JFactory::getUser()->authorise( "core.delete", "com_helloworld.helloworld." . $record->id );
 
}
 
}
 
}
 
}
Line 729: Line 655:
 
</span>
 
</span>
  
To check '''"core.edit"''' (and '''core.add''' if you wish) you need to update the sub-controller (''not'' the model). I am not sure why this is so, but that's how other standard Joomla components do it. You need to add the following lines in the file: <tt>admin/controllers/helloworld.php</tt>
+
Para comprobar '''"core.edit"''' (y '''core.add''' si lo deseas) necesitas actualizar el sub-controlador (''no'' el modelo). No estoy seguro por qué esto es así, pero es la forma estándar de hacerlo en los componentes de Joomla. Necesitas agregar las siguientes líneas en el archivo: <tt>admin/controllers/helloworld.php</tt>
  
 
<span id="admin/controllers/helloworld.php">
 
<span id="admin/controllers/helloworld.php">
Line 739: Line 665:
 
  * @subpackage  com_helloworld
 
  * @subpackage  com_helloworld
 
  *
 
  *
  * @copyright  Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
+
  * @copyright  Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  */
 
  */
Line 780: Line 706:
 
if( !empty( $id ) )
 
if( !empty( $id ) )
 
{
 
{
return JFactory::getUser()->authorise( "core.edit", "com_helloworld.message." . $id );
+
return JFactory::getUser()->authorise( "core.edit", "com_helloworld.helloworld." . $id );
 
}
 
}
 
}
 
}
Line 788: Line 714:
 
</span>
 
</span>
  
Please note that ''allowAdd'' simply calls its parent. I've put it here in case you want to actually use it in your component. If you look at your <tt>admin/access.xml</tt> file, you will notice there is no ''core.add'' action defined for "messages", so you will need to add it there as well if you want to be able to configure it in the interface.
+
Por favor, ten en cuenta que ''allowAdd'' simplemente llama a su padre. Lo he puesto aquí en caso de que desees utilizarlo en tu componente. Si miras tu archivo <tt>admin/access.xml</tt>, te darás cuenta que no hay una acción ''core.add'' definida para "mensajes", por lo que será necesario agregarla, así que si eres capaz puedes configurar la interfaz.
  
 
=== Configuración de los valores de permisos en la tabla assets ===
 
=== Configuración de los valores de permisos en la tabla assets ===
  
In order to store permissions for each message in the assets database table, we have to instruct the table class associated with the model to save those permissions in the assets table.
+
Con el fin de almacenar los permisos para cada uno de los mensajes en la tabla assets de base de datos, tenemos que instruir a la clase de la tabla asociada con el modelo para salvar esos permisos en la tabla assets.
  
JTable not only provides an interface for storing the data of the record itself in the item's database table, but also for storing the permissions for that record in the assets database table. Therefore we must add information to the bind()-method about the permission-values. We also  have to provide the asset name, asset title and the id of the asset parent via the helloworld JTable. Therefore we override 3 methods:
+
JTable no sólo proporciona una interfaz para el almacenamiento de los datos del registro mismo en el elemento de la tabla de base de datos, también almacena los permisos para este registro en la tabla assets de base de datos. Por lo tanto debemos agregar información al método bind() sobre los valores de los permisos. También tenemos que proporcionar el nombre, título y el id del asset padre a través de JTable de helloworld. Por lo tanto, reescribimos 3 métodos:
* _getAssetName(): a unique name for this asset, by which it can be retrieved
+
* _getAssetName(): un nombre único para este asset, por el que se pueda recuperar
* _getAssetTitle(): a more human-friendly way to identify the asset (not necessary unique)
+
* _getAssetTitle(): una forma más humana y amigable de identificar los asset (no es necesario que sea único)
* _getAssetParentId(): the asset_id of the parent in the asset database table (from whom permissions are inherited)
+
* _getAssetParentId(): el asset_id del padre en la tabla asset de la base de datos (a partir de los cuales los permisos se heredan)
  
 
<span id="admin/tables/helloworld.php">
 
<span id="admin/tables/helloworld.php">
 
<tt>admin/tables/helloworld.php</tt>
 
<tt>admin/tables/helloworld.php</tt>
<source lang="php" highlight="45-52,80-133">
+
<source lang="php" highlight="45-52,56-109">
 
<?php
 
<?php
 
/**
 
/**
Line 807: Line 733:
 
  * @subpackage  com_helloworld
 
  * @subpackage  com_helloworld
 
  *
 
  *
  * @copyright  Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
+
  * @copyright  Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  * @license    GNU General Public License version 2 or later; see LICENSE.txt
 
  */
 
  */
Line 857: Line 783:
 
}
 
}
  
/**
 
* Overloaded load function
 
*
 
* @param      int $pk primary key
 
* @param      boolean $reset reset data
 
* @return      boolean
 
* @see JTable:load
 
*/
 
public function load($pk = null, $reset = true)
 
{
 
if (parent::load($pk, $reset))
 
{
 
// Convert the params field to a registry.
 
$params = new JRegistry;
 
$params->loadString($this->params, 'JSON');
 
 
$this->params = $params;
 
return true;
 
}
 
else
 
{
 
return false;
 
}
 
}
 
 
/**
 
/**
 
* Method to compute the default name of the asset.
 
* Method to compute the default name of the asset.
Line 892: Line 794:
 
{
 
{
 
$k = $this->_tbl_key;
 
$k = $this->_tbl_key;
return 'com_helloworld.message.'.(int) $this->$k;
+
return 'com_helloworld.helloworld.'.(int) $this->$k;
 
}
 
}
 
/**
 
/**
Line 940: Line 842:
 
</span>
 
</span>
  
This code for _getAssetParentId() above uses JTableAsset to retrieve the asset_id of the asset-parent. This is different from the code in the current version of com_content, where the asset_id of the category is retrieved from the #__categories database table. That is another possibility; many ways leading to Rome. In com_content however, if an item would not be under a category, then the asset_id of the global asset is returned. That would of course not be right, but is fixed there by providing a default category "uncategorised", so that an article is ''always'' under a category.
+
Este código de _getAssetParentId () anterior utiliza JTableAsset para recuperar el asset_id del asset del padre. Esto es diferente del código en la versión actual de com_content, donde el asset_id de la categoría que se recupera de la tabla #__categories de la base de datos. Que es otra posibilidad; son muchos caminos que llevan a Roma. En com_content sin embargo, si un artículo no está sometido a una categoría, entonces se devuelve el asset_id del asset a nivel global. Que sería, por supuesto, incorrecto, pero se fija allí para proporcionar un valor predeterminado de la categoría "sin categoría", para que un artículo este "siempre" en una categoría.
  
=== Showing the setting of permissions on the item level ===
+
=== Mostrar la configuración de permisos a nivel de elemento ===
  
Adding the rules field to the form-definition of the edit-form.  
+
Agregar las reglas de campo a la definición del formulario del formulario de edición.  
  
 
<span id="admin/models/forms/helloworld.xml">
 
<span id="admin/models/forms/helloworld.xml">
Line 1,028: Line 930:
 
</span>
 
</span>
  
Now the ACL interface is displayed at the bottom of the Helloworld editform too (the ''edit.php'' file automatically get the fieldsets from the above xml).
+
El archivo de diseño edit.php anterior mostraría el campo de permisos automáticamente, pero hemos cambiado el diseño para que se muestre en un formato con pestañas, similar a otros componentes de Joomla. Cuando un usuario cambia un permiso, hay una llamada Ajax para volver a calcular la Configuración Calculada, y necesitamos un poco de javascript para que funcione.
 +
 
 +
<span id="admin/views/helloworld/tmpl/edit.php">
 +
<tt>admin/views/helloworld/tmpl/edit.php</tt>
 +
<source lang='php'  highlight="14-23,29,33-67">
 +
<?php
 +
/**
 +
* @package    Joomla.Administrator
 +
* @subpackage  com_helloworld
 +
*
 +
* @copyright  Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 +
* @license    GNU General Public License version 2 or later; see LICENSE.txt
 +
*/
 +
 
 +
// No direct access
 +
defined('_JEXEC') or die('Restricted access');
 +
JHtml::_('behavior.formvalidator');
 +
 
 +
// The following is to enable setting the permission's Calculated Setting
 +
// when you change the permission's Setting.
 +
// The core javascript code for initiating the Ajax request looks for a field
 +
// with id="jform_title" and sets its value as the 'title' parameter to send in the Ajax request
 +
JFactory::getDocument()->addScriptDeclaration('
 +
jQuery(document).ready(function() {
 +
        greeting = jQuery("#jform_greeting").val();
 +
jQuery("#jform_title").val(greeting);
 +
});
 +
');
 +
 
 +
?>
 +
<form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id=' . (int) $this->item->id); ?>"
 +
    method="post" name="adminForm" id="adminForm" class="form-validate">
 +
   
 +
    <input id="jform_title" type="hidden" name="helloworld-message-title"/>
 +
   
 +
    <div class="form-horizontal">
 +
 
 +
    <?php echo JHtml::_('bootstrap.startTabSet', 'myTab', array('active' => 'details')); ?>
 +
    <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'details',
 +
        empty($this->item->id) ? JText::_('COM_HELLOWORLD_TAB_NEW_MESSAGE') : JText::_('COM_HELLOWORLD_TAB_EDIT_MESSAGE')); ?>
 +
        <fieldset class="adminform">
 +
            <legend><?php echo JText::_('COM_HELLOWORLD_LEGEND_DETAILS') ?></legend>
 +
            <div class="row-fluid">
 +
                <div class="span6">
 +
                    <?php echo $this->form->renderFieldset('details');  ?>
 +
                </div>
 +
            </div>
 +
        </fieldset>
 +
    <?php echo JHtml::_('bootstrap.endTab'); ?>
 +
 
 +
    <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'params', JText::_('COM_HELLOWORLD_TAB_PARAMS')); ?>
 +
        <fieldset class="adminform">
 +
            <legend><?php echo JText::_('COM_HELLOWORLD_LEGEND_PARAMS') ?></legend>
 +
            <div class="row-fluid">
 +
                <div class="span6">
 +
                    <?php echo $this->form->renderFieldset('params');  ?>
 +
                </div>
 +
            </div>
 +
        </fieldset>
 +
    <?php echo JHtml::_('bootstrap.endTab'); ?>
 +
 
 +
    <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'permissions', JText::_('COM_HELLOWORLD_TAB_PERMISSIONS')); ?>
 +
        <fieldset class="adminform">
 +
            <legend><?php echo JText::_('COM_HELLOWORLD_LEGEND_PERMISSIONS') ?></legend>
 +
            <div class="row-fluid">
 +
                <div class="span12">
 +
                    <?php echo $this->form->renderFieldset('accesscontrol');  ?>
 +
                </div>
 +
            </div>
 +
        </fieldset>
 +
    <?php echo JHtml::_('bootstrap.endTab'); ?>
 +
    <?php echo JHtml::_('bootstrap.endTabSet'); ?>
  
=== Adding language strings ===
+
    </div>
We used 4 language strings that have to be added to the backend language-file.
+
    <input type="hidden" name="task" value="helloworld.edit" />
 +
    <?php echo JHtml::_('form.token'); ?>
 +
</form>
 +
 
 +
</source>
 +
</span>
 +
 
 +
=== Agregar cadenas de idioma ===
 +
Hemos utilizado varias cadenas de idioma que tiene que ser añadida al archivo de idioma del lado servidor.
  
 
<span id="admin/language/en-GB/en-GB.com_helloworld.ini">
 
<span id="admin/language/en-GB/en-GB.com_helloworld.ini">
 
<tt>admin/language/en-GB/en-GB.com_helloworld.ini</tt>
 
<tt>admin/language/en-GB/en-GB.com_helloworld.ini</tt>
<source lang="text" highlight="41-44">
+
<source lang="text" highlight="41-51">
 
; Joomla! Project
 
; Joomla! Project
; Copyright (C) 2005 - 2015 Open Source Matters. All rights reserved.
+
; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved.
 
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
 
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
 
; Note : All ini files need to be saved as UTF-8
 
; Note : All ini files need to be saved as UTF-8
Line 1,078: Line 1,059:
 
COM_HELLOWORLD_FIELDSET_RULES="Message Permissions"
 
COM_HELLOWORLD_FIELDSET_RULES="Message Permissions"
 
COM_HELLOWORLD_FIELD_RULES_LABEL="Permissions"
 
COM_HELLOWORLD_FIELD_RULES_LABEL="Permissions"
COM_HELLOWORLD_ACCESS_DELETE_DESC="Is this group allowed to edit this message?"
+
COM_HELLOWORLD_ACCESS_EDIT_DESC="Is this group allowed to edit this message?"
 
COM_HELLOWORLD_ACCESS_DELETE_DESC="Is this group allowed to delete this message?"
 
COM_HELLOWORLD_ACCESS_DELETE_DESC="Is this group allowed to delete this message?"
 +
COM_HELLOWORLD_TAB_NEW_MESSAGE="New Message"
 +
COM_HELLOWORLD_TAB_EDIT_MESSAGE="Edit Message"
 +
COM_HELLOWORLD_TAB_PARAMS="Parameters"
 +
COM_HELLOWORLD_TAB_PERMISSIONS="Permissions"
 +
COM_HELLOWORLD_LEGEND_DETAILS="Message Details"
 +
COM_HELLOWORLD_LEGEND_PARAMS="Message Parameters"
 +
COM_HELLOWORLD_LEGEND_PERMISSIONS="Message Permissions"
  
 
</source>
 
</source>
 
</span>
 
</span>
  
== Further reading ==
+
Otras lecturas
More information on actions, assets and ACL can be found on the following pages:
+
Más información sobre  acciones, assets y ACL se pueden encontrar en las siguientes páginas:
* General information and use: [[S:MyLanguage/J3.x:Access_Control_List_Tutorial|Access Control List/Tutorial]]
+
* Información general y uso: [[S:MyLanguage/J3.x:Access_Control_List_Tutorial|Lista de Control de Acceso/Tutorial]]
* Technical information, under construction: [[S:MyLanguage/ACL Technique in Joomla!|ACL Technique in Joomla!]]
+
* [[S:MyLanguage/How to implement actions in your code|Cómo implementar acciones en tu código]]
* [[S:MyLanguage/How to implement actions in your code|How to implement actions in your code]]
+
* [[S:MyLanguage/Adding ACL rules to your component|Agregar reglas ACL a tu componente]]
* [[S:MyLanguage/Adding ACL rules to your component|Adding ACL rules to your component]]
 
  
== Deprecated classes ==
+
== Empaquetado del componente ==
For the moment we leave the '''deprecated JError'''-references as they are. They will probably still be available in Joomla! 3.x. We cannot just change them to JLog::add() statements because in Joomla! 2.5 the messages will then not be enqueued (as there is no messagequeue-logger added as is in /libraries/cms.php in Joomla! 3.0). Other solutions, like using $app->enqueueMessage() or directly throwing PHP-exceptions as showstopper are also possible, but then there would still be numerous references to JError throughout the application. For instance in the view, we now check for errors raised in the model with: <span style="color:#900">count($errors = $this->get('Errors'))</span>, which uses JError from the JOBject that was the base for JModel. To get the same functionality without using JError at all, we would have to change the way the Model raises those errors and warnings now. If we want to make an application that would work in Joomla! 2.5 and 3.x we can continue using JError. The moment we want to use our 3.x extensions also in 4.x we will have to change this (and probably a lot more too). This tutorial is now primarily focused on Joomla! 3.x. So: we notice the upcoming change, but leave it there for the moment.
 
  
Since Joomla! 2.5.5 the MVC-base-classes JController, JModel and JView got proxies JControllerLegacy, JModelLegacy and JViewLegacy. You are recommended to use those proxies instead of the original classes to be forward compatibility with Joomla! CMS 3.x legacy classes.
+
El contenido de su directorio de código. Cada enlace de archivo a continuación te lleva al paso en el tutorial que tiene la última versión de ese archivo de código fuente.  
 
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#helloworld.xml|helloworld.xml]]''
== Packaging the component ==
 
 
 
Content of your code directory
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#helloworld.xml|helloworld.xml]]''
 
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_a_view_to_the_site_part#site/helloworld.php|site/helloworld.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_a_view_to_the_site_part#site/helloworld.php|site/helloworld.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/index.html]]''
Line 1,105: Line 1,087:
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/views/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/views/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/views/helloworld/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/views/helloworld/index.html]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_a_view_to_the_site_part#site/views/helloworld/view.html.php|site/views/helloworld/view.html.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_configuration#site/views/helloworld/view.html.php|site/views/helloworld/view.html.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/views/helloworld/tmpl/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/views/helloworld/tmpl/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Using_the_database#site/views/helloworld/tmpl/default.xml|site/views/helloworld/tmpl/default.xml]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Using_the_database#site/views/helloworld/tmpl/default.xml|site/views/helloworld/tmpl/default.xml]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_a_view_to_the_site_part#site/views/helloworld/tmpl/default.php|site/views/helloworld/tmpl/default.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_configuration#site/views/helloworld/tmpl/default.php|site/views/helloworld/tmpl/default.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/models/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/models/index.html]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Using_the_database#site/models/helloworld.php|site/models/helloworld.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_configuration#site/models/helloworld.php|site/models/helloworld.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/language/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/language/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/language/en-GB/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|site/language/en-GB/index.html]]''
 
* ''[[S:MyLanguage/J3.x:Developing an MVC Component/Adding language management#site.2Flanguage.2Fen-GB.2Fen-GB.com_helloworld.ini|site/language/en-GB/en-GB.com_helloworld.ini]]''
 
* ''[[S:MyLanguage/J3.x:Developing an MVC Component/Adding language management#site.2Flanguage.2Fen-GB.2Fen-GB.com_helloworld.ini|site/language/en-GB/en-GB.com_helloworld.ini]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/index.html]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Basic_backend#admin/helloworld.php|admin/helloworld.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/helloworld.php|admin/helloworld.php]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_configuration#admin/config.xml|admin/config.xml]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/config.xml|admin/config.xml]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Basic_backend#admin/controller.php|admin/controller.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Basic_backend#admin/controller.php|admin/controller.php]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_categories#admin/access.xml|admin/access.xml]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/access.xml|admin/access.xml]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_categories#admin/helpers/helloworld.php|admin/helpers/helloworld.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_categories#admin/helpers/helloworld.php|admin/helpers/helloworld.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/helpers/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/helpers/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/sql/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/sql/index.html]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Using_the_database#admin/sql/install.mysql.utf8.sql|admin/sql/install.mysql.utf8.sql]]''
+
* ''[[J3.2:Developing_an_MVC_Component/Adding_ACL#admin/sql/install.mysql.utf8.sql|admin/sql/install.mysql.utf8.sql]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Using_the_database#admin/sql/uninstall.mysql.utf8.sql|admin/sql/uninstall.mysql.utf8.sql]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Using_the_database#admin/sql/uninstall.mysql.utf8.sql|admin/sql/uninstall.mysql.utf8.sql]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/sql/updates/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/sql/updates/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/sql/updates/mysql/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/sql/updates/mysql/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#admin/sql/updates/mysql/0.0.1.sql|admin/sql/updates/mysql/0.0.1.sql]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#admin/sql/updates/mysql/0.0.1.sql|admin/sql/updates/mysql/0.0.1.sql]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Using_the_database#admin/sql/install.mysql.utf8.sql|admin/sql/updates/mysql/0.0.6.sql]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/sql/install.mysql.utf8.sql|admin/sql/updates/mysql/0.0.6.sql]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_categories#admin/sql/updates/mysql/0.0.12.sql|admin/sql/updates/mysql/0.0.12.sql]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_categories#admin/sql/updates/mysql/0.0.12.sql|admin/sql/updates/mysql/0.0.12.sql]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_configuration#admin/sql/updates/mysql/0.0.13.sql|admin/sql/updates/mysql/0.0.13.sql]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_configuration#admin/sql/updates/mysql/0.0.13.sql|admin/sql/updates/mysql/0.0.13.sql]]''
Line 1,133: Line 1,115:
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/models/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/models/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/models/fields/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/models/fields/index.html]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Using_the_database#admin/models/fields/helloworld.php|admin/models/fields/helloworld.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_categories#admin/models/fields/helloworld.php|admin/models/fields/helloworld.php]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Basic_backend#admin/models/helloworlds.php|admin/models/helloworlds.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_categories#admin/models/helloworlds.php|admin/models/helloworlds.php]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_backend_actions#admin/models/helloworlds.php|admin/models/helloworld.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/models/helloworld.php|admin/models/helloworld.php]]''
 +
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding decorations to the backend#admin/models/forms/filter_helloworlds.xml|admin/models/forms/filter_helloworlds.xml]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/models/forms/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/models/forms/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_verifications#admin/models/forms/helloworld.js|admin/models/forms/helloworld.js]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_verifications#admin/models/forms/helloworld.js|admin/models/forms/helloworld.js]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_backend_actions#admin/models/forms/helloworld.xml|admin/models/forms/helloworld.xml]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/models/forms/helloworld.xml|admin/models/forms/helloworld.xml]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_verifications#admin/models/rules/greeting.php|admin/models/rules/greeting.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_verifications#admin/models/rules/greeting.php|admin/models/rules/greeting.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/models/rules/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/models/rules/index.html]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_backend_actions#admin/controllers/helloworld.php|admin/controllers/helloworld.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/controllers/helloworld.php|admin/controllers/helloworld.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_backend_actions#admin/controllers/helloworlds.php|admin/controllers/helloworlds.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_backend_actions#admin/controllers/helloworlds.php|admin/controllers/helloworlds.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/controllers/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/controllers/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/views/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/views/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/views/helloworld/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/views/helloworld/index.html]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_backend_actions#admin/views/helloworld/view.html.php|admin/views/helloworld/view.html.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/views/helloworld/view.html.php|admin/views/helloworld/view.html.php]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_backend_actions#admin/views/helloworld/tmpl/edit.php|admin/views/helloworld/tmpl/edit.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/views/helloworld/tmpl/index.html]]''
 +
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/views/helloworld/tmpl/edit.php|admin/views/helloworld/tmpl/edit.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_verifications#admin/views/helloworld/submitbutton.js|admin/views/helloworld/submitbutton.js]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_verifications#admin/views/helloworld/submitbutton.js|admin/views/helloworld/submitbutton.js]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/views/helloworlds/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/views/helloworlds/index.html]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Basic_backend#admin/views/helloworlds/view.html.php|admin/views/helloworlds/view.html.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/views/helloworlds/view.html.php|admin/views/helloworlds/view.html.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/views/helloworlds/tmpl/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/views/helloworlds/tmpl/index.html]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Basic_backend#admin/views/helloworlds/tmpl/default.php|admin/views/helloworlds/tmpl/default.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_categories#admin/views/helloworlds/tmpl/default.php|admin/views/helloworlds/tmpl/default.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/tables/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/tables/index.html]]''
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Using_the_database#admin/tables/helloworld.php|admin/tables/helloworld.php]]''
+
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Adding_ACL#admin/tables/helloworld.php|admin/tables/helloworld.php]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/language/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/language/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/language/en-GB/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|admin/language/en-GB/index.html]]''
* ''[[S:MyLanguage/J3.x:Developing an MVC Component/Adding language management#admin.2Flanguage.2Fen-GB.2Fen-GB.com_helloworld.ini|admin/language/en-GB/en-GB.com_helloworld.ini]]''
+
* ''[[S:MyLanguage/J3.x:Developing an MVC Component/Adding_ACL#admin.2Flanguage.2Fen-GB.2Fen-GB.com_helloworld.ini|admin/language/en-GB/en-GB.com_helloworld.ini]]''
* ''[[S:MyLanguage/J3.x:Developing an MVC Component/Adding language management#admin.2Flanguage.2Fen-GB.2Fen-GB.com_helloworld.sys.ini|admin/language/en-GB/en-GB.com_helloworld.sys.ini]]''
+
* ''[[S:MyLanguage/J3.x:Developing an MVC Component/Adding_decorations_to_the_backend#admin.2Flanguage.2Fen-GB.2Fen-GB.com_helloworld.sys.ini|admin/language/en-GB/en-GB.com_helloworld.sys.ini]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|media/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|media/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|media/images/index.html]]''
 
* ''[[S:MyLanguage/J3.2:Developing_an_MVC_Component/Developing_a_Basic_Component#index.html|media/images/index.html]]''
Line 1,164: Line 1,148:
 
* ''[[S:MyLanguage/J3.x:Developing_an_MVC_Component/Adding_decorations_to_the_backend#Adding_some_icons|media/images/tux-48x48.png]]''
 
* ''[[S:MyLanguage/J3.x:Developing_an_MVC_Component/Adding_decorations_to_the_backend#Adding_some_icons|media/images/tux-48x48.png]]''
  
Create a compressed file of this directory or directly download the [https://github.com/scionescire/Joomla-3.2-Hello-World-Component/archive/step-14-adding-ACL.zip archive] and install it using the extension manager of Joomla. You can add a menu item of this component using the menu manager in the backend.
+
Crea un archivo comprimido de este directorio o descargar directamente el [https://github.com/scionescire/Joomla-3.2-Hello-World-Component/archive/step-14-adding-ACL.zip archivo] e instálalo con el gestor de extensiones de Joomla. Puedes agregar un elemento de menú de este componente usando el gestor de menús en el lado del servidor.
  
 
<span id="helloworld.xml">
 
<span id="helloworld.xml">
 
<tt>helloworld.xml</tt>
 
<tt>helloworld.xml</tt>
<source lang="xml">
+
<source lang="xml" highlight="13">
 
<?xml version="1.0" encoding="utf-8"?>
 
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="3.2.0" method="upgrade">
+
<extension type="component" version="3.0" method="upgrade">
  
 
<name>COM_HELLOWORLD</name>
 
<name>COM_HELLOWORLD</name>
 
<!-- The following elements are optional and free of formatting constraints -->
 
<!-- The following elements are optional and free of formatting constraints -->
<creationDate>February 2015</creationDate>
+
<creationDate>January 2018</creationDate>
 
<author>John Doe</author>
 
<author>John Doe</author>
 
<authorEmail>john.doe@example.org</authorEmail>
 
<authorEmail>john.doe@example.org</authorEmail>
Line 1,259: Line 1,243:
 
</span>
 
</span>
  
== Contributors ==
+
== Colaboradores ==
 
*[[User:Dwarkesh0204|Dwarkesh Soni]]
 
*[[User:Dwarkesh0204|Dwarkesh Soni]]
 
*[[User:cdemko|Christophe Demko]]
 
*[[User:cdemko|Christophe Demko]]
Line 1,267: Line 1,251:
 
* TDZweb (Ståle Rolf Sæbøe), Elin Waring, Neil via https://groups.google.com/forum/#!topic/joomla-dev-general/aCH3GNA91m4
 
* TDZweb (Ståle Rolf Sæbøe), Elin Waring, Neil via https://groups.google.com/forum/#!topic/joomla-dev-general/aCH3GNA91m4
 
*[[User:Scionescire|Scionescire]]
 
*[[User:Scionescire|Scionescire]]
 +
*[[User:Robbiej|Robbie Jackson]]
  
 
<div class="row">  
 
<div class="row">  
<div class="large-6 columns">{{Basic button|S:MyLanguage/J3.x:Developing_an_MVC_Component/Adding configuration|Prev: Adding configuration|class=expand success}}</div>
+
<div class="large-6 columns">{{Basic button|S:MyLanguage/J3.x:Developing_an_MVC_Component/Adding configuration|Prev: Agregar configuración|class=expand success}}</div>
<div class="large-6 columns">{{Basic button|S:MyLanguage/J3.x:Developing_an_MVC_Component/Adding an install-uninstall-update script file|Next: Adding an install-uninstall-update script file|class=expand}}</div>
+
<div class="large-6 columns">{{Basic button|S:MyLanguage/J3.x:Developing_an_MVC_Component/Adding an install-uninstall-update script file|Sig: Agregar un archivo de secuencia de comandos instalar-desinstalar-actualizar|class=expand}}</div>
 
</div>
 
</div>
 
__NOTOC__
 
__NOTOC__
 
<noinclude>
 
<noinclude>
[[Category:Joomla! 3.x]]
+
[[Category:Joomla! 3.x{{#translation:}}]]
[[Category:Joomla! 3.0]]
+
[[Category:Joomla! 3.0{{#translation:}}]]
[[Category:Joomla! 3.1]]
+
[[Category:Joomla! 3.1{{#translation:}}]]
[[Category:Joomla! 3.2]]
+
[[Category:Joomla! 3.2{{#translation:}}]]
[[Category:Joomla! 3.3]]
+
[[Category:Joomla! 3.3{{#translation:}}]]
[[Category:Joomla! 3.4]]
+
[[Category:Joomla! 3.4{{#translation:}}]]
[[Category:Beginner Development]]
+
[[Category:Beginner Development{{#translation:}}]]
[[Category:Component Development]]
+
[[Category:Component Development{{#translation:}}]]
[[Category:Tutorials]]
+
[[Category:Tutorials{{#translation:}}]]
[[Category:Tutorials in a Series]]
+
[[Category:Tutorials in a Series{{#translation:}}]]
 
</noinclude>
 
</noinclude>

Latest revision as of 23:51, 1 April 2019

Other languages:
English • ‎español • ‎français • ‎italiano • ‎العربية • ‎中文(台灣)‎
Joomla! 
3.x
Tutorial
Desarrollo de un Componente MVC

Agregar una variable de petición en el tipo de menú

Utilizando la base de datos

Lado servidor básico

Agregar gestión de idioma

Agregar acciones del lado servidor

Agregar decoraciones del lado servidor

Agregar verificaciones

Agregar categorías

Agregar configuración

  1. Agregar ACL

Agregar un archivo de secuencia de comandos instalar-desinstalar-actualizar

Agregar un formulario del lado cliente

  1. Agregar una imagen
  2. Agregar un mapa
  3. Agregar AJAX
  4. Agregar un alias

Usar la facilidad filtro de idioma

  1. Agregar una Modal
  2. Agregar Asociaciones
  3. Agregar Comprobación
  4. Agregar Ordenamiento
  5. Agregar Niveles
  6. Agregar Control de Versiones
  7. Agregar Etiquetas
  8. Agregar Accesos
  9. Agregar procesos por lote
  10. Agregar Caché
  11. Agregar un Canal de Noticias

Agregar un servidor de actualización

  1. Agregar campos personalizados
  2. Upgrading to Joomla4



Esta es una serie multi-artículos de tutoriales sobre cómo desarrollar un Componente Modelo-Vista-Controlador para Joomla! VersiónJoomla 3.x.

Comenzar con la Introducción, y navegar por los artículos de esta serie usando el botón de navegación en la parte inferior o en el cuadro de la derecha (los "Artículos de esta serie").



Introducción

Este artículo es parte del tutorial Desarrollo de un Componente MVC para Joomla! 3.2. Te invitamos a leer las partes anteriores del tutorial antes de leer esto.

Agregar Control de Acceso

Con el Control de Acceso de Joomla! se puede definir a que grupos de usuarios se les permite o niega realizar acciones sobre el componente. En este ejemplo vamos a utilizar acciones que se definen en el núcleo. Para el componente en su conjunto: core.admin (acceso a la configuración) y core.manage (acceso al lado servidor). Y con varios niveles de acciones como crear, borrar y editar. Además de esas acciones puedes definir tus propias acciones, pero que a menudo no es necesario y no se muestran en este ejemplo. El Acceso a Ver/Leer no es gestionado a través de esas acciones, pero con la Vista de los Niveles de Acceso; para esto véase la documentación general sobre ACL de Joomla!.

En la tabla #__assets la lista actual almacena: a cuales grupos de usuarios se les permite o niega hacer qué acciones sobre cuales los recursos (assets). Se trata de 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 con diferentes niveles de granularidad: para el componente como un todo, para las categorías y para los elementos individuales.

Para probar esta funcionalidad crea usuarios y asócialos con los grupos de usuarios que tienen acceso a la funcionalidad de administrador del lado servidor (es decir, aquellos grupos de usuarios que tienen permisos de Inicio de sesión como Administrador en los permisos de la Configuración Global). De forma predeterminada, son Gestor y Administrador, pero también puedes definir tus propios grupos de usuarios y, opcionalmente, establecerlos como dependientes de Gestor o Administrador.

Si aún no está muy familiarizado con la Lista de control de Acceso de Joomla!, te recomiendo ver este video ACL Explicado (En inglés) (entre 2 minutos y 32 minutos es la sección a mirar) y lee esto Tutorial de la lista de control de acceso.

Tres vídeos (en inglés) asociados con este paso del tutorial cubren la Infraestructura de Control de Acceso de de Joomla, una explicación del código del tutorial de este paso y un vídeo complementario en Niveles de acceso de visualización

Requerimientos mínimos de ACL a nivel del componente

Hay 2 acciones que deben ser definidas a nivel del componente para un componente Joomla! 2.5+ para ofrecer servicios básicos de soporte de ACL:

  • Configurar (core.admin): a cuales grupos se le permite configurar el nivel de permisos del componente a través del botón Opciones de la barra de herramientas?
  • Acceso al Componente (core.manage): a cuales grupos se les permite el acceso al lado servidor del componente?

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

Agregar las 2 acciones mínimas a nivel de componente a access.xml

Un mínimo ACL access.xml consistiría sólo de estas 2 acciones básicas:

Basic admin/access.xml

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

Ver admin/access.xml para el actual y una versión más elaborada.

Agregar los conjuntos de campo de permisos a config.xml

Agregue los siguientes conjuntos de campos de permisos a admin/config.xml con el fin de ser capaz de establecer nuestro nivel de permisos del 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>

Consulte el ejemplo más elaborado de config.xml más abajo para el lugar exacto donde se inserta este código.

Agregar el botón 'Opciones' en la barra de herramientas cuando el usuario esta autorizado

En el archivo admin/views/helloworlds/view.html.php puedes agregar el siguiente código para comprobar si el usuario puede editar las preferencias:

    // Options button.
    if (JFactory::getUser()->authorise('core.admin', 'com_helloworld')) 
    {
	JToolBarHelper::preferences('com_helloworld');
    }

Véase más abajo para un ejemplo más elaborado de admin/views/helloworlds/view.html.php donde esta JToolBarHelper::preferencias('com_helloworld'), se hace en un método addToolBar() junto con el resto de botones de la barra de herramientas y la comprobación JUser->authorise() se realiza con JHelperContent, lo que resulta de la propiedad $canDo.

Restringir el acceso al lado servidor del componente a grupos de usuarios autorizados

Para controlar el acceso al lado servidor del componente agrega las siguientes líneas al archivo de entrada admin/helloworld.php:

// Access check: is this user allowed to access the backend of this component?
if (!JFactory::getUser()->authorise('core.manage', 'com_helloworld')) 
{
	throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'));
}

Véase más abajo para todo el código del archivo admin/helloworld.php.

Agregar más acciones, también a nivel de la categoría y nivel del elemento

Al agregar más acciones y más niveles, los 4 pasos anteriormente descriptos también se llevan a cabo:

Además también tenemos que hacer los siguientes pasos:

Describiendo las acciones sobre las que deseas controlar el acceso

Cada componente (o parte de el) tiene su propio conjunto de permisos que pueden ser controlados. Ellos son descriptos en el archivo access.xml que se encuentra en la raíz de la carpeta admin. En este ejemplo helloworld las acciones en las que el acceso es controlado se dividen en tres secciones: a nivel de componente, a nivel de categoría y a nivel de elemento. Un 'elemento' se llama un 'mensaje' en nuestro ejemplo de componente, de ahí el nombre de la tercera sección.

admin/access.xml

<?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" />
		<action name="core.edit.state" title="JACTION_EDITSTATE" description="JACTION_EDITSTATE_COMPONENT_DESC" />
		<action name="core.edit.own" title="JACTION_EDITOWN" description="JACTION_EDITOWN_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>

Agregando la configuración de permisos en las Preferencias del componente

Puesto que ahora usamos permisos de Control de Acceso en nuestro componente, tenemos que ser capaces de ponerlos en el nivel del componente. Se hace en las Preferencias de este componente: la pantalla se puede ver después de hacer clic en el botón 'Opciones'. El archivo de configuración config.xml es un archivo de formulario con la definición de esas Preferencias. Podríamos definir el nivel de las acciones del componente aquí también, como un hijo de las "reglas" de la etiqueta del campo, pero ahora se prefiere también poner esas acciones en access.xml de esa manera todas las reglas de acceso para este componente están 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>

Mostrar sólo los botones correctos de la barra de herramientas

Que botones de la barra de herramientas se van a mostrar depende de los permisos de Control de Acceso del usuario.

Comúnmente con los componentes base de Joomla, usamos JHelperContent::getActions() para encontrar los permisos. Pasamos a esta función la identidad del registro activo, y devuelve un objeto que contiene todas las Acciones que están asociadas con nuestro componente helloworld, junto con (para cada Acción) si el usuario actualmente conectado tiene ese permiso o no. Si luego llamamos a get('alguna.acción') en este objeto, devolverá verdadero o falso, dependiendo de si el usuario tiene este permiso o no.

En el archivo admin/views/helloworlds/view.html.php coloca estas líneas:

admin/views/helloworlds/view.html.php

<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 *
 * @copyright   Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

// No direct access to this file
defined('_JEXEC') or die('Restricted access');

/**
 * HelloWorlds View
 *
 * @since  0.0.1
 */
class HelloWorldViewHelloWorlds extends JViewLegacy
{
	/**
	 * Display the Hello World view
	 *
	 * @param   string  $tpl  The name of the template file to parse; automatically searches through the template paths.
	 *
	 * @return  void
	 */
	function display($tpl = null)
	{
		
		// Get application
		$app = JFactory::getApplication();
		$context = "helloworld.list.admin.helloworld";
		// Get data from the model
		$this->items		= $this->get('Items');
		$this->pagination	= $this->get('Pagination');
		$this->state		= $this->get('State');
		$this->filter_order	= $app->getUserStateFromRequest($context.'filter_order', 'filter_order', 'greeting', 'cmd');
		$this->filter_order_Dir = $app->getUserStateFromRequest($context.'filter_order_Dir', 'filter_order_Dir', 'asc', 'cmd');
		$this->filterForm    	= $this->get('FilterForm');
		$this->activeFilters 	= $this->get('ActiveFilters');

		// What Access Permissions does this user have? What can (s)he do?
		$this->canDo = JHelperContent::getActions('com_helloworld');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		// Set the submenu
		HelloWorldHelper::addSubmenu('helloworlds');

		// Set the toolbar and number of found items
		$this->addToolBar();

		// Display the template
		parent::display($tpl);

		// Set the document
		$this->setDocument();
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function addToolBar()
	{
		$title = JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS');

		if ($this->pagination->total)
		{
			$title .= "<span style='font-size: 0.5em; vertical-align: middle;'>(" . $this->pagination->total . ")</span>";
		}

		JToolBarHelper::title($title, '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');
		}
	}
	/**
	 * Method to set up the document properties
	 *
	 * @return void
	 */
	protected function setDocument() 
	{
		$document = JFactory::getDocument();
		$document->setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION'));
	}
}

En el archivo admin/views/helloworld/view.html.php coloca estas líneas:

admin/views/helloworld/view.html.php

<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 *
 * @copyright   Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

// No direct access to this file
defined('_JEXEC') or die('Restricted access');

/**
 * HelloWorld View
 *
 * @since  0.0.1
 */
class HelloWorldViewHelloWorld extends JViewLegacy
{
	protected $form;
	protected $item;
	protected $script;
	protected $canDo;

	/**
	 * Display the Hello World view
	 *
	 * @param   string  $tpl  The name of the template file to parse; automatically searches through the template paths.
	 *
	 * @return  void
	 */
	public function display($tpl = null)
	{
		// Get the Data
		$this->form = $this->get('Form');
		$this->item = $this->get('Item');
		$this->script = $this->get('Script');

		// What Access Permissions does this user have? What can (s)he do?
		$this->canDo = JHelperContent::getActions('com_helloworld', 'helloworld', $this->item->id);

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors), 500);
		}

		// Set the toolbar
		$this->addToolBar();

		// Display the template
		parent::display($tpl);

		// Set the document
		$this->setDocument();
	}

	/**
	 * Add the page title and toolbar.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	protected function addToolBar()
	{
		$input = JFactory::getApplication()->input;

		// Hide Joomla Administrator Main menu
		$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');
		// Build the actions for new and existing records.
		if ($isNew)
		{
			// For new records, check the create permission.
			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'))
			{
				// We can save the new record
				JToolBarHelper::apply('helloworld.apply', 'JTOOLBAR_APPLY');
				JToolBarHelper::save('helloworld.save', 'JTOOLBAR_SAVE');
 
				// We can save this record, but check the create permission to see
				// if we can return to make a new one.
				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');
		}
	}
	/**
	 * Method to set up the document properties
	 *
	 * @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');
	}
}

Restringir el acceso al componente

La idea principal en ACL es restringir las acciones de los grupos de usuarios. La primera acción a ser restringida, es el acceso a la administración del lado servidor del propio componente. Con tu editor de archivos favorito, modifica el archivo admin/helloworld.php y agrega las líneas con la comprobación de acceso.

admin/helloworld.php

<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 *
 * @copyright   Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

// No direct access to this file
defined('_JEXEC') or die('Restricted access');

// Set some global property
$document = JFactory::getDocument();
$document->addStyleDeclaration('.icon-helloworld {background-image: url(../media/com_helloworld/images/tux-16x16.png);}');

// Access check: is this user allowed to access the backend of this component?
if (!JFactory::getUser()->authorise('core.manage', 'com_helloworld'))
{
	throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'));
}

// Require helper file
JLoader::register('HelloWorldHelper', JPATH_COMPONENT . '/helpers/helloworld.php');

// Get an instance of the controller prefixed by HelloWorld
$controller = JControllerLegacy::getInstance('HelloWorld');

// Perform the Request task
$controller->execute(JFactory::getApplication()->input->get('task'));;

// Redirect if set by the controller
$controller->redirect();

Agregar un asset_id a la tabla de la base de datos

Con el fin de ser capaz de trabajar con JTable una columna asset_id tiene que ser agregada a la tabla #__helloworld de la base de datos.

Así, admin/sql/instalar.mysql.utf8.sql se convierte en:

admin/sql/install.mysql.utf8.sql

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,
	`published` tinyint(4) NOT NULL,
	`catid`	    int(11)    NOT NULL DEFAULT '0',
	`params`   VARCHAR(1024) NOT NULL DEFAULT '',
	PRIMARY KEY (`id`)
)
	ENGINE =MyISAM
	AUTO_INCREMENT =0
	DEFAULT CHARSET =utf8;

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

Para actualizaciones añadimos un archivo sql de actualización:

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 mensaje.

Para comprobar los permisos del "core.delete" es necesario modificar la clase del modelo: admin/models/helloworld.php al agregar estas líneas:

admin/models/helloworld.php

<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 *
 * @copyright   Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

// No direct access to this file
defined('_JEXEC') or die('Restricted access');

/**
 * HelloWorld Model
 *
 * @since  0.0.1
 */
class HelloWorldModelHelloWorld extends JModelAdmin
{
	/**
	 * Method to get a table object, load it if necessary.
	 *
	 * @param   string  $type    The table name. Optional.
	 * @param   string  $prefix  The class prefix. Optional.
	 * @param   array   $config  Configuration array for model. Optional.
	 *
	 * @return  JTable  A JTable object
	 *
	 * @since   1.6
	 */
	public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())
	{
		return JTable::getInstance($type, $prefix, $config);
	}

	/**
	 * Method to get the record form.
	 *
	 * @param   array    $data      Data for the form.
	 * @param   boolean  $loadData  True if the form is to load its own data (default case), false if not.
	 *
	 * @return  mixed    A JForm object on success, false on failure
	 *
	 * @since   1.6
	 */
	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;
	}
	/**
	 * Method to get the script that have to be included on the form
	 *
	 * @return string	Script files
	 */
	public function getScript() 
	{
		return 'administrator/components/com_helloworld/models/forms/helloworld.js';
	}
	/**
	 * Method to get the data that should be injected in the form.
	 *
	 * @return  mixed  The data for the form.
	 *
	 * @since   1.6
	 */
	protected function loadFormData()
	{
		// Check the session for previously entered form data.
		$data = JFactory::getApplication()->getUserState(
			'com_helloworld.edit.helloworld.data',
			array()
		);

		if (empty($data))
		{
			$data = $this->getItem();
		}

		return $data;
	}
	/**
	 * Method to check if it's OK to delete a message. Overrides JModelAdmin::canDelete
	 */
	protected function canDelete($record)
	{
		if( !empty( $record->id ) )
		{
			return JFactory::getUser()->authorise( "core.delete", "com_helloworld.helloworld." . $record->id );
		}
	}
}

Para comprobar "core.edit" (y core.add si lo deseas) necesitas actualizar el sub-controlador (no el modelo). No estoy seguro por qué esto es así, pero es la forma estándar de hacerlo en los componentes de Joomla. Necesitas agregar las siguientes líneas en el archivo: admin/controllers/helloworld.php

admin/controllers/helloworld.php

<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 *
 * @copyright   Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
// No direct access to this file
defined('_JEXEC') or die('Restricted access');

/**
 * HelloWorld Controller
 *
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 * @since       0.0.9
 */
class HelloWorldControllerHelloWorld extends JControllerForm
{
	/**
	* Implement to allowAdd or not
	*
	* Not used at this time (but you can look at how other components use it....)
	* Overwrites: JControllerForm::allowAdd
	*
	* @param array $data
	* @return bool
	*/
	protected function allowAdd($data = array())
	{
		return parent::allowAdd($data);
	}
	/**
	* Implement to allow edit or not
	* Overwrites: 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 ) )
		{
			return JFactory::getUser()->authorise( "core.edit", "com_helloworld.helloworld." . $id );
		}
	}
}

Por favor, ten en cuenta que allowAdd simplemente llama a su padre. Lo he puesto aquí en caso de que desees utilizarlo en tu componente. Si miras tu archivo admin/access.xml, te darás cuenta que no hay una acción core.add definida para "mensajes", por lo que será necesario agregarla, así que si eres capaz puedes configurar la interfaz.

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

Con el fin de almacenar los permisos para cada uno de los mensajes en la tabla assets de base de datos, tenemos que instruir a la clase de la tabla 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 del registro mismo en el elemento de la tabla de base de datos, también almacena los permisos para este registro en la tabla assets de base de datos. Por lo tanto debemos agregar información al método bind() sobre los valores de los permisos. También tenemos que proporcionar el nombre, título y el id del asset padre a través de JTable de helloworld. Por lo tanto, reescribimos 3 métodos:

  • _getAssetName(): un nombre único para este asset, por el que se pueda recuperar
  • _getAssetTitle(): una forma más humana y amigable de identificar los asset (no es necesario que sea único)
  • _getAssetParentId(): el asset_id del padre en la tabla asset de la base de datos (a partir de los cuales los permisos se heredan)

admin/tables/helloworld.php

<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 *
 * @copyright   Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
// No direct access
defined('_JEXEC') or die('Restricted access');

/**
 * Hello Table class
 *
 * @since  0.0.1
 */
class HelloWorldTableHelloWorld extends JTable
{
	/**
	 * Constructor
	 *
	 * @param   JDatabaseDriver  &$db  A database connector object
	 */
	function __construct(&$db)
	{
		parent::__construct('#__helloworld', 'id', $db);
	}
	/**
	 * Overloaded bind function
	 *
	 * @param       array           named array
	 * @return      null|string     null is operation was satisfactory, otherwise returns an 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;
		}

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

		return parent::bind($array, $ignore);
	}

	/**
	 * Method to compute the default name of the asset.
	 * The default name is in the form `table_name.id`
	 * where id is the value of the primary key of the table.
	 *
	 * @return	string
	 * @since	2.5
	 */
	protected function _getAssetName()
	{
		$k = $this->_tbl_key;
		return 'com_helloworld.helloworld.'.(int) $this->$k;
	}
	/**
	 * Method to return the title to use for the asset table.
	 *
	 * @return	string
	 * @since	2.5
	 */
	protected function _getAssetTitle()
	{
		return $this->greeting;
	}
	/**
	 * Method to get the asset-parent-id of the item
	 *
	 * @return	int
	 */
	protected function _getAssetParentId(JTable $table = NULL, $id = NULL)
	{
		// We will retrieve the parent-asset from the Asset-table
		$assetParent = JTable::getInstance('Asset');
		// Default: if no asset-parent can be found we take the global asset
		$assetParentId = $assetParent->getRootId();

		// Find the parent-asset
		if (($this->catid)&& !empty($this->catid))
		{
			// The item has a category as asset-parent
			$assetParent->loadByName('com_helloworld.category.' . (int) $this->catid);
		}
		else
		{
			// The item has the component as asset-parent
			$assetParent->loadByName('com_helloworld');
		}

		// Return the found asset-parent-id
		if ($assetParent->id)
		{
			$assetParentId=$assetParent->id;
		}
		return $assetParentId;
	}
}

Este código de _getAssetParentId () anterior utiliza JTableAsset para recuperar el asset_id del asset del padre. Esto es diferente del código en la versión actual de com_content, donde el asset_id de la categoría que se recupera de la tabla #__categories de la base de datos. Que es otra posibilidad; son muchos caminos que llevan a Roma. En com_content sin embargo, si un artículo no está sometido a una categoría, entonces se devuelve el asset_id del asset a nivel global. Que sería, por supuesto, incorrecto, pero se fija allí para proporcionar un valor predeterminado de la categoría "sin categoría", para que un artículo este "siempre" en una categoría.

Mostrar la configuración de permisos a nivel de elemento

Agregar las reglas de campo a la definición del formulario del formulario de edición.

admin/models/forms/helloworld.xml

<?xml version="1.0" encoding="utf-8"?>
<form
				addrulepath="/administrator/components/com_helloworld/models/rules"
>
	<fieldset
				name="details"
				label="COM_HELLOWORLD_HELLOWORLD_DETAILS"
	>
		<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=""
				/>
		<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>
	<fieldset
			name="accesscontrol"
			label="COM_HELLOWORLD_FIELDSET_RULES"
	>
    	<field
				name="asset_id"
				type="hidden"
				filter="unset"
				/>
    	<field
				name="rules"
				type="rules"
				label="COM_HELLOWORLD_FIELD_RULES_LABEL"
				filter="rules"
				validate="rules"
				class="inputbox"
				component="com_helloworld"
				section="message"
				/>
    </fieldset>
</form>

El archivo de diseño edit.php anterior mostraría el campo de permisos automáticamente, pero hemos cambiado el diseño para que se muestre en un formato con pestañas, similar a otros componentes de Joomla. Cuando un usuario cambia un permiso, hay una llamada Ajax para volver a calcular la Configuración Calculada, y necesitamos un poco de javascript para que funcione.

admin/views/helloworld/tmpl/edit.php

<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 *
 * @copyright   Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

// No direct access
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.formvalidator');

// The following is to enable setting the permission's Calculated Setting 
// when you change the permission's Setting. 
// The core javascript code for initiating the Ajax request looks for a field
// with id="jform_title" and sets its value as the 'title' parameter to send in the Ajax request
JFactory::getDocument()->addScriptDeclaration('
	jQuery(document).ready(function() {
        greeting = jQuery("#jform_greeting").val();
		jQuery("#jform_title").val(greeting);
	});
');

?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id=' . (int) $this->item->id); ?>"
    method="post" name="adminForm" id="adminForm" class="form-validate">
    
    <input id="jform_title" type="hidden" name="helloworld-message-title"/>
    
    <div class="form-horizontal">

    <?php echo JHtml::_('bootstrap.startTabSet', 'myTab', array('active' => 'details')); ?>
    <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'details', 
        empty($this->item->id) ? JText::_('COM_HELLOWORLD_TAB_NEW_MESSAGE') : JText::_('COM_HELLOWORLD_TAB_EDIT_MESSAGE')); ?>
        <fieldset class="adminform">
            <legend><?php echo JText::_('COM_HELLOWORLD_LEGEND_DETAILS') ?></legend>
            <div class="row-fluid">
                <div class="span6">
                    <?php echo $this->form->renderFieldset('details');  ?>
                </div>
            </div>
        </fieldset>
    <?php echo JHtml::_('bootstrap.endTab'); ?>

    <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'params', JText::_('COM_HELLOWORLD_TAB_PARAMS')); ?>
        <fieldset class="adminform">
            <legend><?php echo JText::_('COM_HELLOWORLD_LEGEND_PARAMS') ?></legend>
            <div class="row-fluid">
                <div class="span6">
                    <?php echo $this->form->renderFieldset('params');  ?>
                </div>
            </div>
        </fieldset>
    <?php echo JHtml::_('bootstrap.endTab'); ?>

    <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'permissions', JText::_('COM_HELLOWORLD_TAB_PERMISSIONS')); ?>
        <fieldset class="adminform">
            <legend><?php echo JText::_('COM_HELLOWORLD_LEGEND_PERMISSIONS') ?></legend>
            <div class="row-fluid">
                <div class="span12">
                    <?php echo $this->form->renderFieldset('accesscontrol');  ?>
                </div>
            </div>
        </fieldset>
    <?php echo JHtml::_('bootstrap.endTab'); ?>
    <?php echo JHtml::_('bootstrap.endTabSet'); ?>

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

Agregar cadenas de idioma

Hemos utilizado varias cadenas de idioma que tiene que ser añadida al archivo de idioma del lado servidor.

admin/language/en-GB/en-GB.com_helloworld.ini

; Joomla! Project
; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved.
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
; Note : All ini files need to be saved as UTF-8

COM_HELLOWORLD_ADMINISTRATION="HelloWorld - Administration"
COM_HELLOWORLD_ADMINISTRATION_CATEGORIES="HelloWorld - Categories"
COM_HELLOWORLD_NUM="#"
COM_HELLOWORLD_HELLOWORLDS_FILTER="Filters"
COM_HELLOWORLD_PUBLISHED="Published"
COM_HELLOWORLD_HELLOWORLDS_NAME="Name"
COM_HELLOWORLD_ID="Id"

COM_HELLOWORLD_HELLOWORLD_CREATING="HelloWorld - Creating"
COM_HELLOWORLD_HELLOWORLD_DETAILS="Details"
COM_HELLOWORLD_HELLOWORLD_EDITING="HelloWorld - Editing"
COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE="Some values are unacceptable"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC="The category the messages belongs to"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL="Category"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC="This message will be displayed"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL="Message"
COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL="Show category"
COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC="If set to Show, the title of the message&rsquo;s category will show."
COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING="Greeting"
COM_HELLOWORLD_HELLOWORLD_HEADING_ID="Id"
COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT="HelloWorld manager: Edit Message"
COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW="HelloWorld manager: New Message"
COM_HELLOWORLD_MANAGER_HELLOWORLDS="HelloWorld manager"
COM_HELLOWORLD_EDIT_HELLOWORLD="Edit message"
COM_HELLOWORLD_N_ITEMS_DELETED_1="One message deleted"
COM_HELLOWORLD_N_ITEMS_DELETED_MORE="%d messages deleted"
COM_HELLOWORLD_N_ITEMS_PUBLISHED="%d message(s) published"
COM_HELLOWORLD_N_ITEMS_UNPUBLISHED="%d message(s) unpublished"
COM_HELLOWORLD_HELLOWORLD_GREETING_LABEL="Greeting"
COM_HELLOWORLD_HELLOWORLD_GREETING_DESC="Add Hello World Greeting"
COM_HELLOWORLD_SUBMENU_MESSAGES="Messages"
COM_HELLOWORLD_SUBMENU_CATEGORIES="Categories"
COM_HELLOWORLD_CONFIGURATION="HelloWorld Configuration"
COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_LABEL="Messages settings"
COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_DESC="Settings that will be applied to all messages by default"
COM_HELLOWORLD_FIELDSET_RULES="Message Permissions"
COM_HELLOWORLD_FIELD_RULES_LABEL="Permissions"
COM_HELLOWORLD_ACCESS_EDIT_DESC="Is this group allowed to edit this message?"
COM_HELLOWORLD_ACCESS_DELETE_DESC="Is this group allowed to delete this message?"
COM_HELLOWORLD_TAB_NEW_MESSAGE="New Message"
COM_HELLOWORLD_TAB_EDIT_MESSAGE="Edit Message"
COM_HELLOWORLD_TAB_PARAMS="Parameters"
COM_HELLOWORLD_TAB_PERMISSIONS="Permissions"
COM_HELLOWORLD_LEGEND_DETAILS="Message Details"
COM_HELLOWORLD_LEGEND_PARAMS="Message Parameters"
COM_HELLOWORLD_LEGEND_PERMISSIONS="Message Permissions"

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

Empaquetado del componente

El contenido de su directorio de código. Cada enlace de archivo a continuación te lleva al paso en el tutorial que tiene la última versión de ese archivo de código fuente.

Crea un archivo comprimido de este directorio o descargar directamente el archivo e instálalo con el gestor de extensiones de Joomla. Puedes agregar un elemento de menú de este componente usando el gestor de menús en el lado del servidor.

helloworld.xml

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

	<name>COM_HELLOWORLD</name>
	<!-- The following elements are optional and free of formatting constraints -->
	<creationDate>January 2018</creationDate>
	<author>John Doe</author>
	<authorEmail>john.doe@example.org</authorEmail>
	<authorUrl>http://www.example.org</authorUrl>
	<copyright>Copyright Info</copyright>
	<license>License Info</license>
	<!--  The version string is recorded in the components table -->
	<version>0.0.14</version>
	<!-- The description is optional and defaults to the name -->
	<description>COM_HELLOWORLD_DESCRIPTION</description>

	<install> <!-- Runs on install -->
		<sql>
			<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
		</sql>
	</install>
	<uninstall> <!-- Runs on uninstall -->
		<sql>
			<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
		</sql>
	</uninstall>
	<update> <!-- Runs on update; New since J2.5 -->
		<schemas>
			<schemapath type="mysql">sql/updates/mysql</schemapath>
		</schemas>
	</update>

	<!-- Site Main File Copy Section -->
	<!-- Note the folder attribute: This attribute describes the folder
		to copy FROM in the package to install therefore files copied
		in this section are copied from /site/ in the package -->
	<files folder="site">
		<filename>index.html</filename>
		<filename>helloworld.php</filename>
		<filename>controller.php</filename>
		<folder>views</folder>
		<folder>models</folder>
	</files>

        <languages folder="site/language">
		<language tag="en-GB">en-GB/en-GB.com_helloworld.ini</language>
        </languages>

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

	<administration>
		<!-- Administration Menu Section -->
		<menu link='index.php?option=com_helloworld' img="../media/com_helloworld/images/tux-16x16.png">COM_HELLOWORLD_MENU</menu>
		<!-- Administration Main File Copy Section -->
		<!-- Note the folder attribute: This attribute describes the folder
			to copy FROM in the package to install therefore files copied
			in this section are copied from /admin/ in the package -->
		<files folder="admin">
			<!-- Admin Main File Copy Section -->
			<filename>index.html</filename>
			<filename>config.xml</filename>
			<filename>helloworld.php</filename>
			<filename>controller.php</filename>
			<filename>access.xml</filename>
			<!-- SQL files section -->
			<folder>sql</folder>
			<!-- tables files section -->
			<folder>tables</folder>
			<!-- models files section -->
			<folder>models</folder>
			<!-- views files section -->
			<folder>views</folder>
			<!-- controllers files section -->
			<folder>controllers</folder>
			<!-- helpers files section -->
			<folder>helpers</folder>
		</files>
		<languages folder="admin/language">
        		<language tag="en-GB">en-GB/en-GB.com_helloworld.ini</language>
                        <language tag="en-GB">en-GB/en-GB.com_helloworld.sys.ini</language>
		</languages>
	</administration>

</extension>

Colaboradores