Joomla! Programmierung/Programmierung/Komponenten/Front/Model

Aus Joomla! Dokumentation
Wechseln zu: Navigation, Suche

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 Folder blue.png models. Erstellen Sie diese Datei und Sie erhalten folgende Ordnerstruktur:

Folder blue.png com_jnafu

|_ Folder blue.png assets
|_ Folder blue.png controllers
|_ Folder blue.png models
|_ File php.png jnafu.php
|_ Folder blue.png views
|_ Folder blue.png jnafu
|_ Folder blue.png tmpl
|_ File php.png view.html.php

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;
 
}

[Bearbeiten] Siehe auch

Meine Werkzeuge
Namensräume
Varianten
Aktionen
Navigation
Sonstiges
Team Navigation
Werkzeuge