20.4 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 database-Objekt realisiert.
| Hinweis: 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 das 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 20.4 Tabellen in der Datenbank
| Tabelle
|
Beschreibung
|
| categories
|
Daten und Einstellungen der Kategorien
|
| components
|
Die installierten Komponenten
|
| content
|
Inhalte und Daten der Inhaltselemente
|
| core_acl_aro_groups
|
Die Usergruppen. Diese Tabelle haben Sie bereits in Abschnitt 12.6, Für Profis: Eigene Usergruppen und Berechtigungen, gesehen.
|
| mambots
|
Die installierten Mambots
|
| menu
|
Alle Menüpunkte aus allen Menüs
|
| messages
|
Mitteilungen an die User
|
| modules
|
Die installierten Module
|
| sections
|
Daten und Einstellungen der Sektionen
|
| users
|
Daten der registrierten User
|
Wie Sie sehen, hat man durch einen Datenbankzugriff sehr weit reichende 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. Die 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 Letztes 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, also beispielsweise
SELECT * FROM #__content
Joomla! setzt dann automatisch das richtige Präfix ein. Damit ergibt sich die Abfrage in PHP, die wir einfach an das Ende der Datei joomla/modules/mod_ usercontent_1.php anfügen:
21 $id = $my->id;
22 $query = "SELECT * FROM #__content
23 WHERE created_by = $id
24 ORDER BY modified DESC";
25 $database->setQuery($query);
26 if ( !$database->query() ) {
27 echo "<script type='text/javascript'>
28 alert('".$database->getErrorMsg()."');
29 </script>";
30 } else {
31 $rows = $database->loadObjectList();
32 }
Listing 20.7 Auschnitt aus mod_usercontent.php
Dieses Statement wird zunächst mit der Methode setQuery in das Datenbank-Objekt geladen (Zeile 25) und dann in Zeile 26 über query ausgeführt. Der Block von Zeile 27 bis 29 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 Hinweis-Fenster 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
|
Nachdem wir nicht genau wissen, wie viele Einträge die Abfrage bringt, verwenden wir im Folgenden die foreach-Schleife, die jede Zeile aus $rows nimmt und innerhalb der geschweiften Klammern als $row verfügbar macht. Die eigentliche Ausgabe des Titels erfolgt in Zeile 35:
33 foreach ($rows as $row)
34 {
35 echo $row->title.'<br />';
36 }
Listing 20.8 Ausschnitt aus mod_usercontent_1.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:
33 foreach ($rows as $row)
34 {
35 # --- Link in den Bearbeitungsmodus
36 $link = 'index.php?option=com_content&'
37 .'task=edit&id='. $row->id;
38 echo " <a href='".$link."'>";
39 echo "<img src='images/M_images/edit.png'
40 height='12' border='0'>";
41 echo "</a>";
42 # --- Link zur normalen Ansicht
43 $link = sefRelToAbs(
44 'index.php?option=com_content&'
45 .'task=edit&id='. $row->id );
46 echo " <a href='".$link."'>";
47 # --- Anzeige, ob publiziert
48 echo "<img src='";
49 if ($row->state)
50 echo "administrator/images/publish_g.png";
51 else
52 echo "administrator/images/publish_x.png";
53 echo "' border='0'> ";
54 # --- Ausgabe des Titels
55 echo $row->title.'</a><br />';
56 }
Listing 20.9 Ausschnitt aus mod_usercontent_2.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 36–37 wird der Link zur Bearbeitungsseite des Inthaltselements generiert. Die Content-Komponente (option=com_content) wird im Bearbeitungsmodus (task=edit) und der aktuellen Seiten-ID verlinkt. Die ID wird dabei aus der Datenbank entnommen ($row–>id). In den Zeilen 38–41 wird der Link mit dem üblichen Icon für die Bearbeitung ausgegeben. Danach folgt der Link zur normalen Ansicht (task=view), der den Rest der Ausgabe umspannt. In Zeile 43 wird der Befehl sefRelToAbs verwendet. Dieser bewirkt, dass die URL, die als Parameter angegeben wird, gegebenenfalls in eine suchmaschinenfreundliche URL umgewandelt wird. In den Zeilen 48–53 legen wir anhand des Publikationsstatus ($row->state) fest, welches Icon diesbezüglich ausgegeben werden soll. Zeile 55 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 20.4.
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 Skripts vorgenommen, damit mögliche Änderungen auch gleich im Modul ausgegeben werden.
1 <?php
2 defined( '_VALID_MOS' ) or die( 'Direct Access to this
3 location is not allowed.' );
4 # --- Parameter entgegen nehmen
5 if ($act = mosGetParam($_GET, 'h_act'))
6 {
7 $pubid = mosGetParam($_GET, 'h_pid');
8 # --- SQL-Statement erstellen
9 $sql = "UPDATE #__content SET state=";
10 if ($act == "pub")
11 $sql .= '1';
12 else
13 $sql .= '0';
14 $sql .= " WHERE Id = ".$pubid;
16 # --- Datenbankabfrage ausführen
17 $database->setQuery($sql);
18 if ( !$database->query() ) {
19 echo "<script type='text/javascript'>
20 alert('".$database->getErrorMsg()."');
21 </script>";
22 }
23 }
Listing 20.10 Auschnitt aus mod_usercontent_3.php
Ist eine Anfrage angekommen (Zeile 5), so werden die beiden URL-Parameter in lokale Variablen übernommen (Zeilen 5, 7). In Abhängigkeit von der gewünschten Aktion wird in den Zeilen 9–14 das SQL-Statement generiert, das in Zeile 17 in das Database-Objekt geladen und in Zeile 18 ausgeführt wird. Falls etwas schief geht, wird in den Zeilen 19–21 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.
52 # --- URL von alten Parametern säubern
53 $uri = preg_replace('/(&h_act=.[^&]*)|(&h_pid=.[^&]*)/',
54 '', $_SERVER['REQUEST_URI']);
55 foreach ($rows as $row)
56 {
... # --- Link in den Bearbeitungsmodus
64 # --- Publizier-Link zusammenbauen
65 echo '<a href="'.$uri.'&h_act=';
66 if ($row->state)
67 echo "unpub";
68 else
69 echo "pub";
70 echo '&h_pid='.$row->id.'">';
71 # --- Anzeige, ob publiziert
72 echo "<img src='";
73 if ($row->state)
74 echo "administrator/images/publish_g.png";
75 else
76 echo "administrator/images/publish_x.png";
77 echo "' border='0'></a> ";
78 # --- Ausgabe des Titels
79 $link = sefRelToAbs(
80 .'index.php?option=com_content&'
81 .'task=edit&id='.$row->id );
82 echo " <a href='".$link."'>";
83 echo $row->title.'</a><br />';
84 }
85 ?>
Listing 20.11 Ausschnitt aus mod_usercontent_3.php
In den Zeilen 53 und 54 wird mit Hilfe eines regulären Ausdrucks die alte URI, die in der Variable $_SERVER['REQUEST_URI'] zu finden ist, von den Parametern bereinigt, die bisher durch unser Modul erzeugt wurden. 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 65–70) und das Icon ausgegeben (Zeilen 72–77). Den Rest ab Zeile 79 kennen Sie schon. Damit haben wir die Funktionalität unseres Moduls fertig gestellt.
|