Joomla! Programmierung/Programmierung/Komponenten/Front/Der Einstiegspunkt
Inhaltsverzeichnis |
[Bearbeiten] Ziel
In diesem Schritt soll der Einstiegspunkt erstellt und die Komponente in soweit vorbereitet werden, dass im nächsten Schritt direkt die Ausgabe programmiert werden kann. Zusätzlich wird die Komponente in die Joomla! Datenbank eingetragen damit sie im Backend verfügbar ist.
[Bearbeiten] Grundlegendes
Jede Komponente in Joomla! wird über die
index.php aus dem Joomla! root aufgerufen und geparst. Der Befehl lautet:
index.php?option=com_komponentenname
Dabei wird dann jeweils aus dem Ordner
components der Ordner
komponentenname mit der Datei
komponentenname.php aufgerufen. In dieser Datei muss dann (von Ihnen) der Ablauf der Komponente bestimmt sein, damit die Funktionalität der Komponente ausgeführt wird.
Bezogen auf unsere Komponente "Gästebuch" wird der Aufruf folgendermaßen lauten:
index.php?option=com_jnafu
und die Datei
components/com_jnafu/jnafu.php wird aufgerufen werden.
[Bearbeiten] jnafu.php - Der Einstiegspunkt
Starten Sie mit der jnafu.php. Erstellen Sie diese Datei im ersten Ordner Ihrer vorhin erstellten Ordnerstruktur und öffnen Sie diese in Ihrem PHP EditorToDo Verlinken.
[Bearbeiten] Erste Hackversuche unterbinden
Als erstes sollten Sie in jeder PHP Datei, die sie in Ihrer Joomlaumgebung nutzen, einen Schutz einbauen, der Direktzugriffe auf die Datei unterbindet. Somit ist es einem potentiellen Skriptkiddie nicht möglich der Datei durch einen Direktaufruf mit Parametern in einem kriminellen Sinn zu manipulieren. Diese Codezeile lautet wie folgt:
// Verhindern, dass die Datei direkt aufgerufen wird defined('_JEXEC') or die('Restricted access');
[Bearbeiten] Einbinden der JTable Klassen
Als nächstes können Sie verschiedene Klassen und Pfade einbinden, die Sie global für Ihre Komponente brauchen, sei es eine CSS Datei oder eine eigene Klasse. Wichtig ist es aber, dass Sie Joomla! sagen, wo Sie Ihre JTable Klassen hingespeichert haben. Diese werden genutzt um Daten in die Datenbank zu speichern und befinden sich in unserem Fall im Administrator Ordner der Komponente:
Mittels JTable::addIncludePath wird nun Joomla! mitgeteilt wo sich der Ordner befindet. Dabei wird die vordefinierte Konstante für den Backendordner der Komponente genutzt. Warum genau dieser Ordner eingebunden werden muss und was für Funktionen dadurch bereitgestellt werden wird später behandelt.
// Standard JTable Pfad an Joomla! übergeben JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.DS.'tables');
[Bearbeiten] weitere Klassen
Prinzipiell sind nun keine weiteren Klassen von nöten, aber wir werden noch die JFile Klasse von Joomla! einbinden, da wir damit ein Pseudo Override für Controller erstellen können.
// Einbinden der JFile Klasse jimport('joomla.filesystem.file');
[Bearbeiten] globales Stylesheet einbinden
In diesem Tutorial werden die verschiedensten CSS Klassen genutzt. Diese werden nicht weiter spezifiziert, können aber vom Programmierer selbst in der Stylesheetdatei definiert werden. Diese Datei befindet sich im Unterordner
css des Ordners
assets.
Das Stylesheet kann mit der Methode JHTML::stylesheet eingebunden werden. Dabei muss nur der Dateiname
jnafu.css und der Pfad zur Datei angegeben werden.
// Stylesheet laden JHTML::_('stylesheet', 'jnafu.css', 'administrator/components/com_jnafu/assets/css/');
[Bearbeiten] Aufruf des Controllers
Der Controller ist das Herzstück der Komponente. Über ihn werden alle Befehle abgearbeitet. Der Standardvorgang ist, dass geschaut wird, ob ein spezieller Controller angefragt wird, der dann eingebunden wird oder einfach nur der Standardcontroller genutzt werden soll. In diesem Tutorial werden wir aber einen kleinen Trick anwenden, damit die jeweiligen speziellen Controller durch das Template überschrieben werden könnenToDo siehe Override verlinken.
// Einbinden des Standardcontrollers JLoader::import('controller', JPATH_COMPONENT); // Falls ein spezieller Controller angefragt wird, den Namen in der Variable $controller speichern $controller = JRequest::getWord( 'controller' ); // Falls ein spezieller Controller abgefragt wird, dann sollte dieser u.U. eingebunden werden if( $controller ) { $app = JFactory::getApplication(); // Pfad zum Ordner des Templates für das Override $path1 = JPATH_THEMES.DS.$app->getTemplate().DS.'controllers'.DS.'com_jnafu'.DS.$controller.'.php'; // Standard Controllerpfad der Komponente $path2 = JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php'; // Falls das Controlleroverride existiert... if (JFile::exists($path1)) : // ...binde dieses ein require $path1; // falls der spezielle Controller in der Komponente existiert elseif (JFile::exists($path2)) : // binde diesen ein require $path2; // ansonsten binde keinen speziellen Controller ein else : $controller = ''; endif; }
Wichtig ist hierbei, dass auch wirklich die Methode JRequest::getWord verwendet wird, damit alle Zeichen, die keine Buchstaben oder kein Unterstrich sind, herausgefiltert werden. Es ist schon häufiger vorgekommen, dass sich gerade an dieser Stelle durch unsauberes Filtern des Codes Sicherheitslücken aufgetan haben.
[Bearbeiten] Initialisierung des Controllers
Zum aktuellen Zeitpunkt haben wir alle benötigten Klassen geladen, inklusive des benötigten Controllers. Nun wird einfach der Controller initialisiert und alle weitere Aufgaben (Tasks) an diesen weitergereicht. Am Ende wird noch die Weiterleitung ausgeführt, falls eine solche gesetzt wurde.
// Zusammensetzen des Controllernames unter Beachtung des speziellen Controllers $classname = 'JNafuController'.$controller; // Initialisierung des Controllers $controller = new $classname(); // Ausführen des Tasks (ab diesem Punkt werden alle Aufgaben vom Controller übernommen) $controller->execute( JRequest::getWord( 'task' ) ); // Weiterleiten, falls eine Weiterleitung vom Controller gesetzt worden ist $controller->redirect();
[Bearbeiten] Der komplette Quellcode
<?php /** * @author Joomla!-Nafu * @authorurl http://www.joomla-nafu.de * @version 0.1 * @license GNU General Public License, http://www.gnu.org/licenses/gpl-2.0.html * * JNafu! - Joomla! 1.5.x Gästebuch Demo Komponente * Copyright (C) 2009 - Joomla!-Nafu * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see <http://www.gnu.org/licenses/>. **/ // Verhindern, dass die Datei direkt aufgerufen wird defined('_JEXEC') or die('Restricted access'); // Standard JTable Pfad an Joomla! übergeben JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.DS.'tables'); // Einbinden der JFile Klasse jimport('joomla.filesystem.file'); // Stylesheet laden JHTML::_('stylesheet', 'jnafu.css', 'administrator/components/com_jnafu/assets/css/'); // Einbinden des Standardcontrollers JLoader::import('controller', JPATH_COMPONENT_SITE); // Falls ein spezieller Controller angefragt wird, den Namen in der Variable $controller speichern $controller = JRequest::getWord( 'controller' ); // Falls ein spezieller Controller abgefragt wird, dann sollte dieser u.U. eingebunden werden if( $controller ) { $app = JFactory::getApplication(); // Pfad zum Ordner des Templates für das Override $path1 = JPATH_THEMES.DS.$app->getTemplate().DS.'controllers'.DS.'com_jnafu'.DS.$controller.'.php'; // Standard Controllerpfad der Komponente $path2 = JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php'; // Falls das Controlleroverride existiert... if (JFile::exists($path1)) : // ...binde dieses ein require $path1; // falls der spezielle Controller in der Komponente existiert elseif (JFile::exists($path2)) : // binde diesen ein require $path2; // ansonsten binde keinen speziellen Controller ein else : $controller = ''; endif; } // Zusammensetzen des Controllernames unter Beachtung des speziellen Controllers $classname = 'JNafuController'.$controller; // Initialisierung des Controllers $controller = new $classname( ); // Ausführen des Tasks (ab diesem Punkt werden alle Aufgaben vom Controller übernommen) $controller->execute( JRequest::getWord( 'task' ) ); // Weiterleiten, falls eine Weiterleitung vom Controller gesetzt worden ist $controller->redirect(); ?>
[Bearbeiten] controller.php - Die Schaltzentrale
Wie schon erwähnt ist der Controller das Herzstück der Komponente. Hier werden alle Aufgaben delegiert und abgearbeitet. Der Hauptcontroller befindet sich wie auch die
jnafu.php direkt im Hauptordner der Komponente.
[Bearbeiten] Hackversuche unterbinden
Auch in dieser Datei sollte als erstes der Direktzugriffsschutz eingebunden werden:
// Verhindern, dass die Datei direkt aufgerufen wird defined('_JEXEC') or die('Restricted access');
[Bearbeiten] Basiscontroller einbinden
Joomla! selbst liefert eine Basisklasse für den Controller, den Sie einbinden sollten, damit Sie Ihre eigene Controllerklasse von dem Basiscontroller ableiten können. Dieser Controller befindet sich in der "library" von Joomla! und wird durch jimport eingebunden.
// Joomla! Basiscontroller einbinden jimport('joomla.application.component.controller');
[Bearbeiten] Die Klasse und der Konstruktor
Nun müssen Sie die Controllerklasse erstellen. Diese wiederum sollte vom Joomla! Basiscontroller abgeleitet werden. Der Hauptcontroller einer Komponente setzt sich immer aus dem Komponentennamen und dem Wort "Controller" zusammen. Somit heißt er in diesem Fall JNafuController. Da PHP case insensitiv ist, hat die Groß- und Kleinschreibung keinerlei Einfluss auf den Klassennamen.
// JNafu Hauptcontrollerklasse class JNafuController extends JController { [...] }
Als nächstes wird der Konstruktor der Klasse erstellt. In diesem können Variablen etc. initialisiert werden. In unserem Fall nutzen wir diesen nur um den Konstruktor der Elternklasse JController aufzurufen. Beachten Sie, dass diese Handhabung nur mit PHP 5 funktionieren wird. Für PHP 4 müssen Sie anstatt __construct() die veraltete Schreibweise JNafuController() nutzen.
// Konstruktor für die Initialisierung public function __construct() { parent::__construct(); }
[Bearbeiten] Die Aufgaben (Tasks)
Wie oben schon erwähnt, verarbeitet der Controller alle Tasks. Ganz am Anfang haben wir nur einen Task und zwar den Standardtask "display". Dieser wird von Joomla! immer automatisch aufgerufen, wenn kein spezieller Task angefragt wird. "display" ist dafür verantwortlich, dass es zu einer normalen Ausgabe der Komponenteninhalte kommt. In unserem Fall die Auflistung aller Gästebucheinträge. In dieser Methode könnten Sie unterschiedliche Datenbankklassen oder Views laden lassen oder sonstige Basiseinstellungen ändern. Dies wird aber (wie auch beim Konstruktor) später behandelt. Aktuell wird ganz normal der Standardview der Komponente geladen, somit müssen Sie selbst nichts definieren sondern können einfach die komplette Arbeit von Joomla! Basiscontroller erledigen lassen.
// Ausgabe des Views laden public function display () { parent::display(); }
[Bearbeiten] Der komplette Quellcode
Somit ist der Hauptcontroller fürs erste fertig gestellt. Später wird dieser noch erweitert und angepasst, aber aktuell genügt er den Ansprüchen.
<?php /** * @author Joomla!-Nafu * @authorurl http://www.joomla-nafu.de * @version 0.1 * @license GNU General Public License, http://www.gnu.org/licenses/gpl-2.0.html * * JNafu! - Joomla! 1.5.x Gästebuch Demo Komponente * Copyright (C) 2009 - Joomla!-Nafu * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see <http://www.gnu.org/licenses/>. **/ // Verhindern, dass die Datei direkt aufgerufen wird defined('_JEXEC') or die('Restricted access'); // Joomla! Basiscontroller einbinden jimport('joomla.application.component.controller'); // JNafu Hauptcontrollerklasse class JNafuController extends JController { // Konstruktor für die Initialisierung public function __construct() { parent::__construct(); } // Ausgabe des Views laden public function display () { parent::display(); } } ?>
[Bearbeiten] Komponente in Joomla! verfügbar machen
Die Grunddateien der Komponente existieren nun und alles wurde vorbereitet, sodass der erste View erstellt werden kann, aber für Joomla! selbst ist die Komponente noch völlig unbekannt. Dies soll nun geändert werden. Dieser Schritt wird eigentlich mit der ersten Installation der Komponente automatisch von dem Joomla! Installer ausgeführt, aber da die Komponente noch nicht fertig ist, vereinfacht es das Entwickeln ungemein, wenn Sie diesen Schritt relativ am Anfang per Hand ausführen. Dazu führen Sie folgenden Code (z.B. mittels PHPMyAdmin) in Ihrer Datenbank aus:
INSERT INTO `#__components` (`id`, `name`, `link`, `menuid`, `parent`, `admin_menu_link`, `admin_menu_alt`, `option`, `ordering`, `admin_menu_img`, `iscore`, `params`, `enabled`) VALUES (NULL, 'JNafu', 'option=com_jnafu', 0, 0, 'option=com_jnafu', 'JNafu', 'com_jnafu', 0, '', 0, '', 1);
Achten Sie darauf den Datenbankpräfix "#__" entsprechend Ihrer Einstellung anzupassen (z.B. jos_).
Nun sollte die Komponente JNafu im Backend unter dem Menupunkt Komponenten sowie beim Erstellen eines neuen Menueintrages für das Frontend auftauchen. Natürlich liefert beides aktuell noch eine Fehlermeldung, da die entsprechenden Dateien noch nicht existieren. Später werden die Funktionen automatisch von Joomla! erkannt und (abhängig vom Menüeintrag) automatisch aktiviert.