29.4 Backend-Komponente erweitern
In diesem Abschnitt erweitern Sie die Backend-Komponente um ein paar sinnvolle Features, die Sie schon aus der einen oder anderen Standardfunktionalität von Joomla! kennen. Mit dabei: eine Seitenleiste in der Urlaubszielliste, Komponentenkonfiguration über System • Konfiguration und eine Anlaufstelle für programminterne Aktionen, wenn Joomla! die Komponente installiert. Diese Dateiaktualisierungen finden Sie auf der Begleitwebsite im Version-0.4.0-Paket.
29.4.1 Seitenleiste einblenden
Analog zu den Bootstrap-Reitern der Einzelansicht bietet die Listendarstellung ein ähnliches Navigationselement. Die Seitenleiste erscheint links der Elementliste und aktiviert beliebige Joomla!-Funktionen oder dient einfach als Linkliste (siehe Abbildung 29.21).
Die Aktivierung der Seitenleiste erfolgt ausschließlich über den Komponenten-View der Locations-Ansicht, keine Controller oder Models sind dabei involviert. Werfen Sie zunächst einen Blick auf die Businesslogik-Updates unter /administrator/components/com_location/views/locations/view.html.php:
[…]
if ($isAllowed->get('core.admin'))
{
JToolbarHelper::preferences('com_location');
}
JHtmlSidebar::addEntry('List Locations', 'index.php?option=com_location&
view=locations');
$this->sidebar = JHtmlSidebar::render();
parent::display($tpl);
}
}
Zwischen Buttonleiste (JToolbarHelper) und Übergabe an die Darstellungsfunktion der Elternklasse fügen Sie per JHtml::Sidebar::addEntry() beliebige Links der Seitenleiste hinzu. Abschließend erzeugen Sie den HTML-Code mit JHtmlSidebar::render() und schreiben ihn in die Variable $this->sidebar, auf die Sie dann im HTML-Template (/tmpl/default.php) zugreifen:
<?php
defined('_JEXEC') or die;
?>
<form action="<?php echo JRoute::_('index.php?option=com_location&view=
locations'); ?>" method="post" name="adminForm" id="adminForm">
<?php if (!( $this->sidebar)) : ?>
<div id="j-sidebar-container" class="span2">
<?php echo $this->sidebar; ?>
</div>
<div id="j-main-container" class="span10">
<?php else : ?>
<div id="j-main-container">
<?php endif;?>
<div class="clearfix"> </div>
<table class="table table-striped" id="locationList">
[…]
Auf HTML-Seite ergänzen Sie das Template um eine kleine Fallunterscheidung. Falls die Sidebar-Variable nicht leer ist (also den HTML-Code für die Seitenleiste enthält), packen Sie die Seitenleiste in einen <div>-Block der Bootstrap-Breite span2 (zwei Spalten) und öffnen die Locations-Liste mit dem Spaltenmaß span10. (Sie erinnern sich, dass die volle Fensterbreite nach Bootstrap-Regeln 12 Spalten umfasst.) Ist die Sidebar dagegen leer, bleibt alles beim Alten. <div id="j-main-container"> benötigt keine Bootstrap-Spalten, da sich das Layout über die volle Breite zieht.
29.4.2 Konfigurationsseite und Berechtigungskonfiguration ergänzen
Sämtliche Komponentenkonfigurationen listet Joomla! über System • Konfiguration in der Seitenleiste. Um dort einen Eintrag zu erhalten (siehe Abbildung 29.22), ergänzen Sie die Komponente um eine weitere Konfigurationsdatei config.xml, da aus historischen Gründen keine <config>-Blöcke in Komponenten-XML-Manifesten erlaubt sind.
Konfigurationsdateien erzeugen und einbinden
Die config.xml-Datei legen Sie ins Hauptverzeichnis der Backend-Komponente, also neben controller.php und location.php.
<?xml version="1.0" encoding="utf-8"?>
<config>
<fieldset name="component"
label="COM_LOCATION_COMPONENT_LABEL"
description="COM_LOCATION_COMPONENT_DESC">
</fieldset>
<fieldset name="permissions"
label="COM_LOCATION_PERMISSIONS_LABEL"
description="COM_LOCATION_PERMISSIONS_DESC">
<field name="rules" type="rules"
label="COM_LOCATION_PERMISSIONS_LABEL"
component="com_location"
filter="rules"
validate="rules"
section="component" />
</fieldset>
</config>
Das Format der Konfigurationsdatei richtet sich nach den JForm-Regeln und ist damit identisch mit der <config>-Block-Konfiguration von Plugins oder Modulen oder dem Formular für die Einzelansicht von Komponentenelementen. Im Beispiel erzeugen die beiden <fieldset>-Blöcke zwei Reiter: einen für Ihre eigenen Konfigurationsanforderungen und einen weiteren für das Standardberechtigungsformular, das fast alle Joomla!-Komponentenkonfigurationen einblenden. Die Integration gestaltet sich einfach, da JForm für das gesamte Formular einen eigenen Feldtyp vorsieht: type="rules". Damit die neue config.xml-Datei später bei Installationen der Komponente Berücksichtigung findet, ergänzen Sie sie im XML-Manifest:
[…]
<administration>
<menu>COM_LOCATION_MENU</menu>
<files folder="admin">
<filename>index.html</filename>
<filename>access.xml</filename>
<filename>config.xml</filename>
<filename>controller.php</filename>
[…]
Zu guter Letzt fügen Sie noch die zusätzlichen Sprachschlüssel und Bezeichnungen ans Ende der Sprachdatei en-GB.com_location.ini:
[…]
COM_LOCATION_CONFIGURATION="Location Manager Configuration"
COM_LOCATION_COMPONENT_LABEL="Location Manager Configuration"
COM_LOCATION_COMPONENT_DESC="This is a brief introduction text for the Reiseforum
Location Manager configuration."
COM_LOCATION_PERMISSIONS_LABEL="Location Manager Permissions"
COM_LOCATION_PERMISSIONS_DESC="This is a brief introduction text for the
Reiseforum Location Manager permissions."
Damit stehen die Konfigurationsformulare zur Bearbeitung bereit, wie sieht es aber mit ihrem Einsatz aus? Die Berechtigungen spiegeln sich grundsätzlich in den Buttons der Listenansicht. Erstellen entspricht dem Button Neu, Bearbeiten dem Button Bearbeiten, Löschen dem Button Löschen und ACL & Optionen konfigurieren dem Button Optionen rechts außen. Für das Ein- und Ausblenden setzen Sie also lediglich eine Fallunterscheidung ein, die die Berechtigungen abfragt.
Helferklasse etablieren
Dafür benötigen Sie zunächst eine Helferfunktion, die nicht so recht in die Dateistruktur der MVC-Architektur passt und deshalb ausgelagert wird. Dazu dient ein neues Verzeichnis /helpers/ unter /administrator/components/com_location/ und darin die neue Helferdatei location.php.
<?php
defined('_JEXEC') or die;
class LocationHelper
{
public static function getActions()
{
$user = JFactory::getUser();
$result = new JObject;
$actions = JAccess::getActions('com_location', 'component');
foreach ($actions as $action)
{
$result->set($action->name, $user->authorise($action->name,
'com_location'));
}
return $result;
}
}
getActions() ist eine öffentlich (public) bereitgestellte Funktion zur Abfrage der Locations-Komponenten-Berechtigungen des aktuellen Benutzers. Die erlaubten Aktionen fließen aus JAccess::getActions('com_location', 'component') in die Variable $result.
Berechtigungen abfragen
Um die Helferklasse in der Komponente bereitzustellen, laden Sie sie im Haupt-Controller:
[…]
public function display($cachable = false, $urlparams = false)
{
require_once JPATH_COMPONENT . '/helpers/location.php';
$view = $this->input->get('view', 'locations');
[…]
Jetzt steht getActions() allen Komponentenklassen zur Verfügung und wird im View der Listenansicht eingesetzt:
<?php
defined('_JEXEC') or die;
class LocationViewLocations extends JViewLegacy
{
protected $locations;
public function display($tpl = null)
{
$this->locations = $this->get('Items');
$isAllowed = LocationHelper::getActions();
$bar = JToolBar::getInstance('toolbar');
JToolbarHelper::title(JText::_('COM_LOCATION_MANAGER_LOCATIONS'), '');
if ($isAllowed->get('core.create'))
{
JToolbarHelper::addNew('location.add');
}
if ($isAllowed->get('core.edit'))
{
JToolbarHelper::editList('location.edit');
}
if ($isAllowed->get('core.delete'))
{
JToolbarHelper::deleteList(JText::_('COM_LOCATION_DELETE_CONFIRMATION'),
'locations.delete', 'JTOOLBAR_DELETE');
}
if ($isAllowed->get('core.admin'))
{
JToolbarHelper::preferences('com_location');
}
JHtmlSidebar::addEntry('List Locations', 'index.php?option=com_
location&view=locations');
$this->sidebar = JHtmlSidebar::render();
parent::display($tpl);
}
}
Testen Sie nun die verschiedenen Berechtigungen mit zwei Browsern. Im einen sind Sie als Super Benutzer eingeloggt und justieren die Rechte, im anderen melden Sie sich als Testbenutzer einer besonderen Benutzergruppe an, um durch jeweiliges Neuladen der Locations-Liste mit (F5) (OS X: (cmd) + (R)) die Darstellung der Buttons zu prüfen. Beachten Sie, dass die Testbenutzergruppe Backend-Zugriffsrechte hat (siehe Abschnitt 11.3.1, »Globale Berechtigungen«).
29.4.3 Installationsscript hinzufügen
Zum Abschluss dieses Kapitels lernen Sie einen Mechanismus kennen, mit dem Sie aktiv in den Installationsvorgang Ihrer Komponente eingreifen. Das nutzen Sie z. B. zur weiteren Vorbereitung der Datenbankinhalte oder Komponentenkonfiguration, zur Erzeugung von Verzeichnissen, einer eigenen Add-on-Verwaltung oder einfach nur für die Anzeige erklärender Texte (siehe Abbildung 29.23). Dabei stehen Ihnen fünf Ereignisse zur Verfügung:
-
preflight: vor der Installation oder Aktualisierung der Komponente, z. B. zur Überprüfung von Versionskompatibilitäten zwischen Joomla! und der Erweiterung
-
install: Nach der Ausführung der Datenbankscripts; in der Regel ist das Ereignis preflight vorzuziehen.
-
postflight: nach der Installation oder Aktualisierung der Komponente und ihrer Registrierung in Joomla; eignet sich, um Standardwerte zu setzen oder Konfigurationen abzuschließen
-
update: Nach der Ausführung von Datenbank-Updates; auch hier sollten Sie preflight bevorzugen.
-
uninstall: kurz vor der Deinstallation der Komponente, ihrer Dateien und Datenbanktabellen
Um den Mechanismus einzurichten, erzeugen Sie eine neue Datei script.php im Hauptverzeichnis Ihres Komponentenpakets, also dort, wo auch das XML-Manifest liegt. Das Script selbst ist simpel aufgebaut und enthält Funktionen zum Abfangen eines oder mehrerer Ereignisse.
<?php
defined('_JEXEC') or die;
class com_locationInstallerScript
{
function preflight($type, $parent)
{
echo '<p>This function is called before the component is being installed,
can be used to check some prerequisites</p>';
}
function install($parent)
{
echo '<p>This function is called before execution of the database scripts,
better use preflight</p>';
}
function postflight($type, $parent)
{
echo '<p>This function is called after the componend was installed, can be
used to set the proper environment, configuration etc.</p>';
}
function update($parent)
{
echo '<p>After running update database scripts, better use preflight</p>';
}
function uninstall($parent)
{
echo '<p>Just before uninstalling the component, files and database tables
</p>';
}
}
Beachten Sie, dass Sie mit Ausnahme von uninstall() alle Ereignisse abbrechen, indem Sie die jeweilige Funktion über return false; verlassen. Dabei rollt Joomla! sämtliche zuvor durchgeführten Operationen zurück, was insbesondere beim Preflight praktisch ist, falls sich z. B. herausstellt, dass die Komponente inkompatibel mit der eingesetzten Joomla!-Version ist.
Damit das Script während der Komponenteninstallation ausgeführt wird, genügt die Erwähnung im XML-Manifest über das spezielle Tag <scriptfile>.
[…]
<description>COM_LOCATION_XML_DESCRIPTION</description>
<scriptfile>script.php</scriptfile>
<install>
[…]