Joomla! Programmierung/Programmierung/Komponenten/Front/Model
Inhaltsverzeichnis |
[Bearbeiten] Ziel
In diesem Schritt wird das Model für den JNafu View erstellt. Dies liefert die benötigten Daten aus der Datenbank zur Weiterverarbeitung im View. (In unserem Fall aus der Datenbank-Datei "#__jnafu_entries" Gästebucheinträge.)
[Bearbeiten] jnafu.php - Das Model zum View
Das Model ist für die Beschaffung der Daten verantwortlich. In dem Model werden alle Datenbankzugriffe abgehandelt. In dieser Datei werden auch alle Abfragen implementiert, die anderweitig für die Datenbeschaffung benötigt werden, sei es das Auslesen von Dateiinhalten oder RSS Feeds. Da jedes Model direkt dem jeweiligen View zugeordnet wird, ist der Dateiname identisch mit dem Namen des Views. Bei diesem Standardview heißt das Model jnafu.php und befindet sich im Ordner
models. Erstellen Sie diese Datei und Sie erhalten folgende Ordnerstruktur:
Beim Gästebuch haben wir nur zwei Datenbankzugriffe: Einmal das Auslesen der Gästebucheinträge und als zweites das Berechnen der PaginationToDo Verlinken JPagination. Prinzipiell kann jeder Datenbankaufruf mit einer Methode abgehandelt werden, jedoch ist es empfehlenswert jeden Aufruf zu unterteilen; um zum einen doppelte Abfragen zu vermeiden und zum anderen Code wieder verwenden zu können. Somit werden für jede Abfrage fünf Methoden genutzt:
- Die Schnittstelle zum View
- Der Aufruf des Queries
- Die Generierung des Queries (aufgeteilt in 3 Methoden)
[Bearbeiten] Erste Hackversuche unterbinden
Wie in jeder anderen Joomla! Datei sollten Sie als erstes einen Schutz einbauen, der Direktzugriffe auf die Datei unterbindet:
// Verhindern, dass die Datei direkt aufgerufen wird defined('_JEXEC') or die('Restricted access');
[Bearbeiten] Die JNafuModelJNafu Klasse
Die Model-Klassen einer Komponente haben immer folgende Struktur: [Komponentenname]Model[Viewnamen] somit lautet die Klasse für dieses Model JNafuModelJNafu (Beachten Sie, dass die Groß- und Kleinschreibung bei Klassennamen nicht relevant sind). Diese Klasse soll nun alle Methoden von der Joomla! Klasse JModel erben (extends). Zusätzlich werden Klassenvariablen initialisiert, die später zur Zwischenspeichern verschiedenster Daten genutzt werden.
// Die JNafu Model Klasse class JNafuModelJNafu extends JModel { // enthält die abgefragten Einträge private $_entries = null; // Enthält die Pagination private $_pagination = null; }
[Bearbeiten] getJNafuEntries
Diese Methode ist die Schnittstelle zwischen View und Model. Sie wird vom View aufgerufen und ruft selbst weitere Methoden auf, die alle benötigten Einträge auslesen. Danach werden diese Einträge von dieser Methode an den View zurück geliefert.
// Einträge laden und zurück geben public function getJNafuEntries() { // lade alle Einträge $this->_loadEntries(); // liefert alle Einträge an das Model return $this->_entries; }
[Bearbeiten] _loadEntries
Diese Methode lädt mittels generiertem Query alle Einträge aus der Datenbank. Zusätzlich ruft sie die Pagination auf um für die Anzahl der Einträge ein Limit zu setzen.
// Query auswerten und Ergebnis in $_entries speichern private function _loadEntries() { // testen, ob Einträge noch nicht ausgelesen worden sind if(empty($this->_entries)) { // Pagination auslesen $pagination = $this->getPagination(); // Query generieren lassen $query = $this->_buildJNafuQuery(); // Einträge in Abhängigkeit der Pagination auslesen $this->_entries = $this->_getList($query, $pagination->get('limitstart'), $pagination->get('limit')); } // true zurück liefern return true; }
[Bearbeiten] _buildJNafuQuery
Diese Methode generiert das MySQL-Query und liefert es als String zurück. Die where und order by Abschnitte werden dabei in weitere Methoden ausgelagert um die Wartung zu vereinfachen und evtl. diese wieder verwenden zu können.
// Query generieren und zurückliefern private function _buildJNafuQuery() { // where clause laden $where = $this->_buildJNafuWhere(); // order by clause laden $orderby = $this->_buildJNafuOrderBy(); // Query erstellen $query = ' SELECT gb.'.$this->_db->nameQuote('id').', gb.'.$this->_db->nameQuote('text').', gb.'.$this->_db->nameQuote('date').', gb.'.$this->_db->nameQuote('author').', gb.'.$this->_db->nameQuote('email').', gb.'.$this->_db->nameQuote('show_email').', gb.'.$this->_db->nameQuote('homepage').' FROM '.$this->_db->nameQuote('#__jnafu_entries').' AS gb' .$where .$orderby; // Query zurück geben return $query; }
[Bearbeiten] _buildJNafuWhere
In dieser Methode wird der where Abschnitt generiert. Allgemein können hier alle möglichen Filter eingebaut werden. Zum Beispiel verschiedene Suchwörter, die über ein Formular angefragt worden sind oder es sollen nur bestimmte Beiträge mit einer entsprechenden ID ausgegeben werden uvm. Für den Anfang werden aber nur die nicht veröffentlichten Beiträge heraus gefiltert.
// generiere "where" Abschnitt private function _buildJNafuWhere() { // initialisiere Array $where = array(); // nur veröffentlichte Beiträge laden $where[] = 'gb.'.$this->_db->nameQuote('published').' = 1'; // where Array zusammenfügen $where = ( count( $where ) ? ' WHERE (' . implode( ') AND (', $where ) . ')' : '' ); // where Abschnitt zurück geben return $where; }
[Bearbeiten] _buildJNafuOrderBy
In dieser Methode wird der order by Abschnitt generiert. Im Frontend hat diese Methode meist wenig Funktionalität, da hier nur wenig sortiert werden muss. Deshalb wird diese Methode im Backend ausführlicher behandelt.
// generiere "order by" Abschnitt private function _buildJNafuOrderBy() { // initialisiere Array $orderby = array(); // order by Array zusammenfügen $orderby = ( count( $orderby ) ? ' ORDER BY ' . implode( ', ', $orderby ) : '' ); // order by Abschnitt zurück geben return $orderby; }
[Bearbeiten] getPagination
Diese Methode ist die Schnittstelle für das JPagination Object des Gästebuches und dem View. Hier wird bei Bedarf das JPagination Object geladen und zurückgegeben.
public function getPagination() { // Überprüfen, ob die Pagination schon geladen worden ist if (empty($this->_pagination)) { // Pagination laden $this->_loadPagination(); } // Pagination zurück geben return $this->_pagination; }
[Bearbeiten] _loadPagination
In dieser Methode findet die tatsächliche Generierung des JPagination Objektes statt. Zuerst werden alle Benutzereingaben wie die aktuelle Seite oder Beiträge pro Seite abgefragt. Danach wird die Anzahl der Gesamtbeiträge gezählt und am Ende wird mit all diesen Angaben das JPagination Objekt erstellt. Wichtig ist zu beachten, dass für die WHERE-Abfrage genau die selben Einschränkungen genutzt werden wie bei den Beiträgen selbst, damit die Seitenzahlen identisch sind.
// Methode zum Erstellen der Pagination private function _loadPagination() { // Laden des JApplication Objektes $app = JFactory::getApplication(); // Laden der Einträge pro Seite, entweder falls gegeben aus den Request Variablen, //ansonsten wird das Limit aus der globalen Konfiguration genutzt $limit = $app->getUserStateFromRequest( 'global.list.limit', 'limit', $app->getCfg('list_limit'), 'int' ); // Laden des Startpostest //(auf Seite drei wäre das z.B. 2*$limit, wird automatisch von der JPaginationklasse erstellt) $limitstart = JRequest::getVar('limitstart',0); // Laden der Filter für alle Einträge $where = $this->_buildJNafuEntriesWhere(); // Generieren des Query $query = ' SELECT COUNT('.$this->_db->nameQuote('id').') FROM '.$this->_db->nameQuote('#__jnafu_entries') .$where ; // Setzen des Query $this->_db->setQuery( $query ); // Ausgeben des Ergebnisses $total = $this->_db->loadResult(); // laden der JPagination Klasse jimport('joomla.html.pagination'); // Erstellen des JPagination Objekts mit allen Angaben und übergabe an die Klassenvariable $_pagination $this->_pagination = new JPagination( $total, $limitstart, $limit ); return true; }
[Bearbeiten] Der komplette Quellcode
Das Model ist bis hierher fertig und liefert alle benötigten Daten. Für das Speichern von Einträgen muss es später nochmals erweitert werden, aber aktuell sind alle gefragten Methoden implementiert.
<?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'); // Die JNafu Model Klasse class JNafuModelJNafu extends JModel { // enthält die abgefragten Einträge private $_entries = null; // Enthält die Pagination private $_pagination = null; } // Einträge laden und zurück geben public function getJNafuEntries() { // lade alle Einträge $this->_loadEntries(); // liefert alle Einträge an das Model return $this->_entries; } // Query auswerten und Ergebnis in $_entries speichern private function _loadEntries() { // testen, ob Einträge noch nicht ausgelesen worden sind if(empty($this->_entries)) { // Pagination auslesen $pagination = $this->getPagination(); // Query generieren lassen $query = $this->_buildJNafuQuery(); // Einträge in Abhängigkeit der Pagination auslesen $this->_entries = $this->_getList($query, $pagination->get('limitstart'), $pagination->get('limit')); } // true zurück liefern return true; } // Query generieren und zurückliefern private function _buildJNafuQuery() { // where clause laden $where = $this->_buildJNafuWhere(); // order by clause laden $orderby = $this->_buildJNafuOrderBy(); // Query erstellen $query = ' SELECT gb.'.$this->_db->nameQuote('id').', gb.'.$this->_db->nameQuote('text').', gb.'.$this->_db->nameQuote('date').', gb.'.$this->_db->nameQuote('author').', gb.'.$this->_db->nameQuote('email').', gb.'.$this->_db->nameQuote('show_email').', gb.'.$this->_db->nameQuote('homepage').' FROM '.$this->_db->nameQuote('#__jnafu_entries').' AS gb' .$where .$orderby; // Query zurück geben return $query; } // generiere "where" Abschnitt private function _buildJNafuWhere() { // initialisiere Array $where = array(); // nur veröffentlichte Beiträge laden $where[] = 'gb.'.$this->_db->nameQuote('published').' = 1'; // where Array zusammenfügen $where = ( count( $where ) ? ' WHERE (' . implode( ') AND (', $where ) . ')' : '' ); // where Abschnitt zurück geben return $where; } // generiere "order by" Abschnitt private function _buildJNafuOrderBy() { // initialisiere Array $orderby = array(); // order by Array zusammenfügen $orderby = ( count( $orderby ) ? ' ORDER BY ' . implode( ', ', $orderby ) : '' ); // order by Abschnitt zurück geben return $orderby; } public function getPagination() { // Überprüfen, ob die Pagination schon geladen worden ist if (empty($this->_pagination)) { // Pagination laden $this->_loadPagination(); } // Pagination zurück geben return $this->_pagination; } // Methode zum Erstellen der Pagination private function _loadPagination() { // Laden des JApplication Objektes $app = JFactory::getApplication(); // Laden der Einträge pro Seite, entweder falls gegeben aus den Request Variablen, //ansonsten wird das Limit aus der globalen Konfiguration genutzt $limit = $app->getUserStateFromRequest( 'global.list.limit', 'limit', $app->getCfg('list_limit'), 'int' ); // Laden des Startpostest //(auf Seite drei wäre das z.B. 2*$limit, wird automatisch von der JPaginationklasse erstellt) $limitstart = JRequest::getVar('limitstart',0); // Laden der Filter für alle Einträge $where = $this->_buildJNafuEntriesWhere(); // Generieren des Query $query = ' SELECT COUNT('.$this->_db->nameQuote('id').') FROM '.$this->_db->nameQuote('#__jnafu_entries') .$where ; // Setzen des Query $this->_db->setQuery( $query ); // Ausgeben des Ergebnisses $total = $this->_db->loadResult(); // laden der JPagination Klasse jimport('joomla.html.pagination'); // Erstellen des JPagination Objekts mit allen Angaben und übergabe an die Klassenvariable $_pagination $this->_pagination = new JPagination( $total, $limitstart, $limit ); return true; }