40.6 Auf die Datenbank zugreifen 

Fast alle maßgeblichen Daten von Joomla! sind in der Datenbank kodiert. Aus diesem Grund ist es auch für die Erweiterungen essenziell, Zugriff auf die Datenbank zu haben. Das wird über das JDatabase-Objekt realisiert.
Tabellenpräfix nicht vergessen! |
Beachten Sie, dass alle Tabellen im Folgenden ohne Präfix angegeben werden. Wenn Sie bei der Installation so ein Präfix eingestellt haben, müssen Sie es konsequenterweise auch hier vor die Tabellennamen stellen. |
Bevor wir mit der Abfrage beginnen, sollten wir uns über die wichtigsten Tabellen der Datenbank klar werden.
Tabelle | Beschreibung |
categories |
Daten und Einstellungen der Kategorien |
components |
Die installierten Komponenten |
content |
Inhalte und Daten der Inhaltselemente |
core_acl_aro_groups |
Die Usergruppen |
menu |
Alle Menüpunkte aus allen Menüs |
messages |
Mitteilungen an die User |
modules |
Die installierten Module |
plugins |
Die installierten Plug-ins |
sections |
Daten und Einstellungen der Bereiche |
users |
Daten der registrierten User |
Wie Sie sehen, hat man durch einen Datenbankzugriff sehr weitreichende Möglichkeiten, auf das System Einfluss zu nehmen. Um dieses Potenzial ausschöpfen zu können, sollten Sie also ruhig mal – beispielsweise mit phpMyAdmin – einen Blick auf die Tabellen werfen.
Die Abfrage der Datenbank wird über die Sprache SQL durchgeführt. Um Daten aus der Datenbank zu holen, müssen wir zunächst die Abfrage vorbereiten und dann das Ergebnis in einer Variablen abholen. Nehmen wir an, wir wollen die Titel aller Content-Items ausgeben, die der aktuelle Benutzer geschrieben hat. Dazu müssen wir die ID des Users kennen. Diese ist, wie oben bereits erwähnt, in $my->userid enthalten. Das SQL-Statement dazu lautet so:
SELECT title FROM content WHERE created_by = ID
Aus der Tabelle content werden alle Einträge der Spalte title ausgegeben, bei denen der zugehörige Wert der Spalte created_by mit der ID übereinstimmt. Wir wollen denjenigen Eintrag zuerst sehen, der als Letzter bearbeitet wurde. Diese Information findet sich in der Spalte modified. Daher ist an das SQL-Statement noch ein
ORDER BY modified DESC
anzuhängen. Viele Betreiber einer Joomla!-Seite verwenden ein Präfix für alle Tabellen der Datenbank, um nicht mit anderen Systemen und Installationen in Konflikt zu geraten. Da Sie nicht wissen können, welches Präfix verwendet wird, wenn ein User Ihr Modul installiert, gibt es hierfür in Joomla! eine Abkürzung. Verwenden Sie #__ vor der Tabelle (ein Hash-Zeichen und zwei Unterstriche), also beispielsweise
SELECT * FROM #__content
Joomla! setzt dann automatisch das richtige Präfix ein. Damit ergibt sich die Abfrage in PHP, die wir als neue Funktion am Ende der Helper-Klasse einfügen:
22 public function getUserContributions() 23 { 24 $db =& JFactory::getDBO(); 25 $user =& JFactory::getUser(); 26 $id = $user->id; 27 $query = "SELECT * FROM #__content 28 WHERE created_by = $id 29 ORDER BY modified DESC"; 30 $db->setQuery($query); 31 if ( !$db->query() ) { 32 echo "<script type='text/javascript'> 33 alert('".$db->getErrorMsg()."'); 34 </script>"; 35 return false; 36 } else { 37 $rows = $db->loadObjectList(); 38 return $rows; 39 } 40 }
Listing 40.13 Ausschnitt aus »helper.php«
In den Zeilen 24 –25 wird als Erstes das Datenbank- und Benutzerobjekt aus der Factory abgeholt. Dann wird in den Zeilen 2 –9 das SQL-Statement vorbereitet. Dieses Statement wird mit der Methode setQuery in das Datenbank-Objekt geladen (Zeile 30) und dann in Zeile 31 über query ausgeführt. Der Block von Zeile 3 –34 behandelt den Fehlerfall, z. B. wenn das SQL-Statement nicht korrekt ist. In diesem Fall wird die Fehlermeldung, die MySQL generiert, über die Methode getErrorMsg mittels eines JavaScripts als Hinweisfenster ausgegeben. In Zeile 31 wird das Ergebnis der erfolgreichen Abfrage in eine Variable $rows gelesen, die wir dann weiterverarbeiten können.
Die Ergebnisliste ist ein Array, das für jeden Datenbankeintrag ein Objekt mit den Spalten als Eigenschaften enthält. Der Zugriff erfolgt also nach dem Schema, das Sie in der folgenden Skizze sehen können:
SpalteA | SpalteB | SpalteC | |
0 |
$rows[0]->SpalteA |
$rows[0]->SpalteB |
$rows[0]->SpalteC |
1 |
$rows[1]->SpalteA |
$rows[1]->SpalteB |
$rows[1]->SpalteC |
2 |
$rows[2]->SpalteA |
$rows[2]->SpalteB |
$rows[2]->SpalteC |
Die Liste der Ergebnisse können wir gleich an die View weitergeben. Diese Aufgabe übernimmt die Modulbasis:
9 $userContrib = ModAPIHelper::getUserContributions();
Listing 40.14 Auszug aus »mod_api.php«
Jetzt können wir uns in default.php an die Ausgabe machen. Da wir nicht genau wissen, wie viele Einträge die Abfrage erzeugt, verwenden wir im Folgenden die foreach-Schleife, die jede Zeile aus $userContrib nimmt und innerhalb der geschweiften Klammern als $row verfügbar macht. Die eigentliche Ausgabe des Titels erfolgt in Zeile 14:
10 <br/> 11 <?php 12 foreach ($userContrib as $row) 13 { 14 echo $row->title.'<br />'; 15 } 16 ?>
Listing 40.15 Ausschnitt aus »default.php«
Das Ziel unseres kleinen Moduls ist, dass ein Benutzer einen schnellen Zugriff auf seine – auch unveröffentlichten – Beiträge hat und diese per Link bearbeiten kann. Dazu ist in der Schleife etwas mehr Arbeit nötig. Pro Eintrag muss ein Link in den Bearbeitungsmodus generiert werden. Außerdem sollte der User sehen, ob es sich um einen bereits publizierten Artikel handelt. Schematisch sieht jede Zeile also so aus:
<Bearbeiten-Link><Bearbeiten-Bild /><Bearbeiten-Link> <Ansicht-Link><Published-Bild/>Titel</Ansicht-Link>
Sehen wir uns den Code einmal an:
11 foreach ($rows as $row) 12 { 13 # --- Link in den Bearbeitungsmodus 14 $link = 'index.php?option=com_content&' 15 .'task=edit&id='. $row->id; 16 echo " <a href='".$link."'>"; 17 echo "<img src='images/M_images/edit.png' 18 height='12' border='0'>"; 19 echo "</a>"; 20 # --- Link zur normalen Ansicht 21 $link = 'index.php?option=com_content&' 22 .'view=article&id='. $row->id; 23 echo " <a href='".$link."'>"; 24 # --- Anzeige, ob publiziert 25 echo "<img src='"; 26 if ($row->state) 27 echo "administrator/images/publish_g.png"; 28 else 29 echo "administrator/images/publish_x.png"; 30 echo "' border='0'> "; 31 # --- Ausgabe des Titels 32 echo $row->title.'</a><br />'; 33 }
Listing 40.16 Ausschnitt aus »default.php«
Wie im Skript zuvor wird der Code in einer foreach-Schleife ausgeführt, um auch alle Einträge ausgeben zu können. In den Zeilen 14 –15 wird der Link zur Bearbeitungsseite des Inthaltselements generiert. Die Content-Komponente (option=com_content) wird im Bearbeitungsmodus (task=edit) und mit der aktuellen Seiten-ID verlinkt. Die ID wird dabei aus der Datenbank entnommen ($row–>id). In den Zeilen 16–19 wird der Link mit dem üblichen Icon für die Bearbeitung ausgegeben. Danach folgt der Link zur normalen Ansicht (view= article), der den Rest der Ausgabe umspannt. In den Zeilen 26 –30 legen wir anhand des Publikationsstatus ($row->state) fest, welches Icon für den entsprechenden Zustand ausgegeben werden soll. Zeile 32 gibt den Titel aus und beendet den Ansichtslink. Achten Sie darauf, dass hier im Vergleich zum vorherigen Skript ein </a> dazugekommen ist.
Hat alles geklappt, dann sollte unser Modul jetzt in etwa so aussehen wie in Abbildung 40.3.
Abbildung 40.3 Das Benutzer-Modul
Nun wollen wir das Modul noch dahingehend ausbauen, dass der Benutzer seine eigenen Beiträge auch selbst freischalten kann. Dies soll über einen Klick auf das entsprechende Icon geschehen. Das bestehende Skript muss also in zweierlei Hinsicht ergänzt werden: Zum einen müssen wir die gewünschte Aktion ausführen, und zum anderen brauchen wir einen Link mit eigenen Parametern, der über das Icon aufgerufen wird, das den Publikationsstatus anzeigt. Die Kommunikation zwischen User und Modul erfolgt über die URL. Daher benötigen wir zwei neue Parameter: einen (h_act), der festlegt, ob ein Artikel gezeigt oder versteckt werden soll, und einen zweiten (h_pid), der die ID des Artikels enthält. Der SQL-Befehl, der den Publikationsstatus ändert, sieht folgendermaßen aus:
UPDATE content SET state = 1 WHERE id = ID
Sehen wir uns den ersten Teil der Veränderungen einmal an. Diese werden am Anfang des Basisskripts vorgenommen, damit mögliche Änderungen auch gleich im Modul ausgegeben werden.
4 if (JRequest::getVar('h_act', '')) 5 ModAPIHelper::publishArticle( 6 JRequest::getVar('h_act', ''), 7 JRequest::getVar('h_pid', false));
Listing 40.17 Auszug aus »mod_api.php«
Ist eine Anfrage angekommen (Zeile 4), so werden die beiden URL-Parameter an die Helper-Funktion übergeben (Zeilen 6, 7). In der Helper-Datei erstellen wir eine neue Funktion publishArticle, die die eigentliche Arbeit übernimmt:
45 public function publishArticle($act, $pid) 46 { 47 if (!pid) return false; 48 # --- SQL-Statement erstellen 49 $sql = "UPDATE #__content SET state="; 50 if ($act == "pub") 51 $sql .= '1'; 52 else 53 $sql .= '0'; 54 $sql .= " WHERE Id = ".$pubid; 56 # --- Datenbankabfrage ausführen 57 $db =& JFactory::getDBO(); 58 $db->setQuery($sql); 59 if ( !$db->query() ) { 60 echo "<script type='text/javascript'> 61 alert('".$db->getErrorMsg()."'); 62 </script>"; 63 } 64 }
Listing 40.18 Ausschnitt aus »helper.php«
Gleich am Anfang der Funktion hinterlegen wir eine Sicherheitsabfrage. Ist der Parameter für die ID nicht gesetzt, wird die Funktion verlassen. In Abhängigkeit von der gewünschten Aktion wird in den Zeilen 49–54 das SQL-Statement generiert, das in Zeile 58 in das Database-Objekt geladen und in Zeile 59 ausgeführt wird. Falls etwas schiefgeht, wird in den Zeilen 60–62 eine Fehlermeldung ausgegeben.
Jetzt müssen wir die Ausgabe noch so modifizieren, dass die Icons, die den Publikationsstatus anzeigen, mit den richtigen Links unterlegt werden. Wir befinden uns hier wieder in der Schleife, die die einzelnen Datensätze ausgibt.
11 # --- URL von alten Parametern säubern 12 $uri = preg_replace('/(&h_act=.[^&]*)|(&h_pid=.[^&]*)/', 13 '', $_SERVER['REQUEST_URI']); 14 foreach ($userContrib as $row) 15 { ... # --- Link in den Bearbeitungsmodus 23 # --- Publizier-Link zusammenbauen 24 echo '<a href="'.$uri.'&h_act='; 25 if ($row->state) 26 echo "unpub"; 27 else 28 echo "pub"; 29 echo '&h_pid='.$row->id.'">'; 30 # --- Anzeige, ob publiziert 31 echo "<img src='"; 32 if ($row->state) 33 echo "administrator/images/publish_g.png"; 34 else 35 echo "administrator/images/publish_x.png"; 36 echo "' border='0'></a> "; 37 # --- Ausgabe des Titels 38 $link = 'index.php?option=com_content&' 39 .'task=edit&id='.$row->id ; 40 echo " <a href='".$link."'>"; 41 echo $row->title.'</a><br />'; 42 } 43 ?>
Listing 40.19 Ausschnitt aus »default.php«
In den Zeilen 12 und 13 werden die Parametern, die bisher durch unser Modul erzeugt wurden, mithilfe eines regulären Ausdrucks aus dem alten URI gelöscht, der in der Variable $_SERVER['REQUEST_URI'] zu finden ist. Das ist nötig, da sich ansonsten bei wiederholtem Gebrauch der Funktion ganze Kaskaden von h_act und h_pid in der URL finden würden. Daraufhin wird der Link in Abhängigkeit vom Publikationsstatus zusammengesetzt (Zeilen 24 –29) und das Icon ausgegeben (Zeilen 31–36). Den Rest ab Zeile 37 kennen Sie schon. Damit haben wir die Funktionalität unseres Moduls fertiggestellt.