22.3 Die Komponentenverwaltung
 
Die größte Aufgabe, die jetzt vor uns liegt, ist die Programmierung der Datenverwaltung im Backend. Hier sind zwei Bereiche wichtig. Der eine ist die Listenanzeige der Datensätze, die verwaltet werden sollen. Sie wird über die beiden admin-Dateien gestaltet. Der andere betrifft die Symbolleiste rechts oben und wird über die toolbar-Dateien beschrieben.
Achtung: Die Dateien für den Administratorbereich liegen im Verzeichnis joomla/administrator/components/com_pair_rank. Wenn Sie unser Komponenten-Fragment bereits installiert haben, müssen Sie die neuen Dateien in diesem Verzeichnis erstellen!
|
Um den Datenbankzugriff zu erleichtern, schreiben wir eine Klasse, die von der Joomla!-Datenbankklasse mosDBTable abgeleitet ist.
1 <?php
2 defined( '_VALID_MOS' ) or die( 'Direct Access to this
3 script is not allowed');
4 class mosPair_rank extends mosDBTable
5 {
6 var $id = null;
7 var $pair = null;
8 var $points = null;
9 var $published = null;
10 function mosPair_rank( &$db ) {
11 $this->mosDBTable('jos_pair_rank', 'id', $db);
12 }
13 }
14 ?>
Listing 22.4 pair_rank.class.php
Die Klasse wird in den Zeilen 4 bis 13 definiert. Zunächst wird für jede Tabellenspalte eine passende Variable erstellt und mit einem Standardwert (null bedeutet so viel wie »leer«) belegt. Die Funktion mosPair_rank (Zeilen 10 – 12) hat den gleichen Namen wie die Klasse. Das führt dazu, dass sie automatisch ausgeführt wird, wenn ein Objekt der Klasse mit new erstellt wird. Hier wird eine weitere Funktion der Oberklasse aufgerufen, die unser Objekt initialisiert. Jetzt haben wir sehr einfache Funktionen zum Speichern und Löschen der Datensätze zur Verfügung.
22.3.1 Die Listenansicht
 
Beginnen wir die Arbeit im Backendbereich damit, die vorhandenen Daten auszugegeben. Dazu sind die beiden admin-Dateien nötig, die wir jetzt nur mit den Funktionen für die Ausgabe bestücken und später dann erweitern werden. Die Datei admin.pair_rank.php nimmt die Anfragen entgegen, verteilt die Aufgaben und stellt die Daten zur Verfügung.
1 <?php
2 defined( '_VALID_MOS' ) or die( 'Direct Access to this
3 script is not allowed');
4 require_once($mainframe->getPath('class'));
5 require_once($mainframe->getPath('admin_html'));
6 if ((!$act || $act == 'all') && !$task)
7 $task="listItems";
8 switch ($task) {
9 case "listItems": listItems($option); break;
10 }
11 function listItems($option) {
12 global $database;
13 $database->setQuery("SELECT * FROM #__pair_rank"
14 ." ORDER BY id");
15 $rows = $database->loadObjectList();
16 HTML_pair_rank::listItems($option, $rows);
17 }
18 ?>
Listing 22.5 admin.pair_rank_nurListe.php
In den Zeilen 4 und 5 werden über das mainframe-Objekt die Dateien pair_rank. class.php und admin.pair_rank.html.php eingebunden. Dieser Mechanismus erspart es uns, den kompletten Pfad auszuschreiben. In den Zeilen 6 und 7 wird der Parameter act ausgewertet. Das ist in unserem Fall sehr einfach, weil wir nur eine Aktion angegeben haben, nämlich all. Die wird beispielsweise angefordert, wenn die Komponente über das Menü aufgerufen wird. Wenn das passiert, soll die Liste mit den Datensätzen angezeigt werden; also setzen wir die Variable $task auf den entsprechenden Wert. Die nächste Auswahl (Zeilen 8 – 10) nimmt den Parameter $task entgegen. Hier gibt es bisher auch nur eine Aufgabe, es werden aber später mehrere dazukommen. Zunächst wird die Funktion listItems (Zeilen 11 – 17) aufgerufen, die die Ausgabe vorbereitet. Dort werden als Erstes alle Daten aus der Datenbanktabelle abgefragt, und dann wird die Ausgabefunktion aus der Datei aufgerufen, die für das HTML zuständig ist.
Diese Datei gilt es als Nächstes zu erstellen.
1 <?php
2 defined( '_VALID_MOS' ) or die( 'Direct Access to this
3 script is not allowed');
4 class HTML_pair_rank {
5 function listItems ( $option, &$rows ) {
6 $number = count($rows);
7 echo <<< HTML
8 <script language="javascript" type="text/javascript">
9 function submitbutton(pressbutton) {
10 var form = document.adminForm;
11 if (pressbutton == "cancel") {
12 submitform( pressbutton );
13 return;
14 }
15 submitform( pressbutton );
16 }
17 </script>
18 <form action="index2.php" method="post"
19 name="adminForm">
20 <table cellpadding="4" cellspacing="0"
21 border="0" width="100%" class="adminlist">
22 <tr>
23 <th width="20">
24 <input type="checkbox" name="toggle"
25 value="" onclick="checkAll($number);"/>
26 </th>
27 <th align="left">Tanzpaar</th>
28 <th align="left">Punkte</th>
29 <th>Published</th>
30 </tr>
31 HTML;
32 $i = 0;
33 foreach ($rows as $row) {
34 $evenodd = $i % 2;
35 echo <<< HTML
36 <tr class="row$evenodd">
37 <td>
38 <input type="checkbox" id="cb$i" name="cid[]"
39 value="$row->id"
40 onclick="isChecked(this.checked);" />
41 </td>
42 <td>
43 <a href="#edit"
44 onclick="return listItemTask('cb$i','edit')">
45 $row->pair</a>
46 </td>
47 <td>$row->points</td>
48 <td align="center">
50 HTML;
51 if ($row->published == "1") {
52 echo "<img src='images/tick.png' "
53 ."border='0' />";
54 } else {
55 echo "<img src='images/publish_x.png' "
56 ."border='0' />";
57 }
58 echo "</td></tr>";
59 $i++;
60 }
61 echo <<< HTML
62 </table>
63 <input type="hidden" name="option"
64 value="$option" />
65 <input type="hidden" name="task" value="" />
66 <input type="hidden" name="boxchecked" value="0" />
67 </form>
68 HTML;
69 }
70 }
71 ?>
Listing 22.6 admin.pair_rank.html_nurListe.php
In diesem Skript finden sich drei verschiedene Programmier- bzw. Beschreibungssprachen. Die gesamte Datei ist eine PHP-Datei und enthält zur Steuerung der Ausgabe auch einige PHP-Befehle. Diese sind zur besseren Übersichtlichkeit fett gedruckt. Der größte Teil der Ausgabe ist HTML-Code, der eine Tabelle beschreibt. Am Anfang unserer Ausgabe findet sich noch ein JavaScript, das das Verhalten beim Absenden von Informationen regelt. Dieses bezieht sich auf Funktionen, die im Seitenheader über ein externes JavaScript aufgerufen werden, und muss uns hier im Detail nicht interessieren.
Betrachten wir zunächst den PHP-Teil. In Zeile 4 wird die Klasse HTML_Pair_rank mit einer Funktion listItems (Zeile 5) deklariert. Die Anzahl der Elemente, die über $row an die Funktion übergeben werden, wird in Zeile 6 für die Ausgabe in eine Variable gespeichert. Ab Zeile 7 wird die Ausgabe des ersten HTML-Teils (Beginn des Formulars und erste Tabellenzeile) mit echo eingeleitet. Dabei verwenden wir den so genannten Heredoc-Mechanismus. Alles, was zwischen den beiden Bezeichnern HTML in Zeile 7 und in Zeile 31 steht, wird genau so ausgegeben, wie es im Code steht. Allerdings wird die Variable in Zeile 25 durch ihren Wert ersetzt.
Achtung: In den Zeilen, die den HTML-Marker enthalten, dürfen keine Zeichen (z. B. Leerzeichen) vor oder hinter dem eigentlichen Befehl stehen.
|
Ab Zeile 32 beginnt die Ausgabe der einzelnen Datensätze. Dazu wird zunächst ein Durchlaufzähler auf 0 gesetzt, den wir brauchen, um die einzelnen Zeilen zu identifizieren (Zeile 32). Die Schleife wird über foreach realisiert, die alle Elemente von $rows durchläuft. Die Variable $oddeven wird benötigt, um in der Tabelle jede zweite Zeile hellgrau zu hinterlegen. In den Zeilen 51 – 60 wird zunächst je nach Publikationsstatus ein anderes Icon ausgegeben (Zeilen 51 – 57). Dann wird die Zeile beendet (Zeile 58) und der Durchlaufzähler um eins erhöht. Ab Zeile 61 werden noch einige abschließende HTML-Elemente ausgegeben.
Die HTML-Ausgabe beschreibt eine Tabelle (Zeile 20/21) in einem Formular (Zeile 18/19). Die vergebenen Attribute sollten in der Form beibehalten werden, da sich einige JavaScript-Befehle, die zum Joomla!-Framework gehören, auf sie beziehen. Das ist insbesondere der Fall, wenn wir später noch die Toolbar einführen. Die Titelzeile der Tabelle wird in den Zeilen 22 – 30 ausgegeben. Bemerkenswert ist hier lediglich die erste Zelle (Zeilen 23 – 26), die eine Checkbox ausgibt, mit der alle Elemente der Tabelle auf einmal über ein JavaScript von Joomla! markiert werden können.
Ab Zeile 36 folgt die Ausgabe der Tabellenzeilen. Da kommt zunächst die Checkbox, mit der das Element ausgewählt werden kann (Zeilen 37 – 41). Ein JavaScript sorgt dafür, dass diese Auswahl auch registriert wird. Die nächste Zelle enthält den Namen des Tanzpaares. Dieser wird über das JavaScript listItemTask mit der Edit-Funktion verbunden (Zeilen 42 – 46). In der dritten Spalte wird ganz unspektakulär der Punktestand ausgegeben. Die letzte Zelle in der Reihe zeigt den Publikationsstatus mit einem Bild an, das über eine PHP-Auswahl eingebunden wird (Zeilen 48 – 58). Den Abschluss bilden drei versteckte Variablen, die vom Joomla!-Framework benötigt werden, um die Eingaben zu bearbeiten (Zeilen 63 – 66).
Sie können die Ausgabe bereits testen. Vergessen Sie nicht, die beiden Dateien im Verzeichnis joomla/administrator/components/com_pair_rank abzulegen und nicht in joomla/components/com_pair_rank. Wenn alles geklappt hat, sehen Sie eine Liste wie in Abbildung 22.3.
22.3.2 Bearbeitungsmodus und Funktionen
 
Neben der Listenübersicht benötigen wir noch eine Einzelansicht zum Bearbeiten der Dateien. Dazu müssen wir die beiden admin-Dateien erweitern. In der Programmdatei muss die Auswahl um ein paar Funktionen wie Speichern und Löschen ergänzt werden.
6 $id = mosGetParam( $_REQUEST, 'cid', array(0) );
7 if (!is_array( $id )) {
8 $id = array(0);
9 }
10 if ((!$act || $act == 'all') && !$task)
11 $task="listItems";
12 switch ($task) {
13 case "listItems": listItems($option); break;
14 case "edit": edit($option, $id[0]); break;
15 case "new": edit($option, ''); break;
16 case "save": save($option); break;
17 case "delete": delete($option, $id); break;
18 case "publish": publish($option, '1', $id); break;
19 case "unpublish": publish($option, '0', $id); break;
20 }
… # ListItems
28 function edit($option, $uid) {
29 global $database;
30 $row = new mosPair_rank($database);
31 $row->load($uid);
32 HTML_pair_rank::edit( $option, $row);
33 }
34 function save($option) {
35 global $database;
36 $row = new mosPair_rank($database);
37 $row->bind($_POST);
38 $row->store();
39 mosRedirect("index2.php?option=$option", "Saved");
40 }
41 function delete( $option, $cid ) {
42 global $database;
43 $cids = implode( ',', $cid );
44 $database->setQuery( "DELETE FROM #__pair_rank "
45 ."WHERE id IN ($cids)" );
46 $database->query();
47 mosRedirect( "index2.php?option=$option" );
48 }
49 function publish( $option, $publish ,$cid ) {
50 global $database;
51 $cids = implode( ',', $cid );
52 $database->setQuery( "UPDATE #__pair_rank "
53 ."SET published='$publish' "
54 ."WHERE id IN ($cids)" );
55 $database->query();
56 mosRedirect( "index2.php?option=$option" );
57 }
Listing 22.7 Auszug aus admin.pair_rank.php
Zunächst müssen wir noch einen zusätzlichen Parameter $id abholen, der über das Formular übergeben wird und eine Liste der Datensätze enthält, die bearbeitet werden sollen (Zeilen 6 – 7). Die eigentliche Aufgabenverteilung wird im switch-Statement (Zeilen 12 – 20) vorgenommen. Es kommen die Funktionen für Bearbeiten, Neu, Speichern, Löschen und Publizieren bzw. Verstecken hinzu.
Die Funktion edit (Zeilen 28 – 33) erstellt ein neues Objekt unserer pair_rank-Klasse (Zeile 30) und füllt es mit den Daten, die zur übergebenen ID passen (Zeile 31). Danach wird die Ausgabeseite mit den Daten aufgerufen. Beachten Sie, dass auch die Funktion zum Erstellen eines neuen Datensatzes über edit aufgerufen wird. In diesem Fall wird allerdings keine ID übergeben (Zeile 32).
Die save-Funktion (Zeilen 34 – 40) erstellt ebenfalls ein pair_rank-Objekt. Dieses wird in Zeile 37 mit den Parametern gefüllt, die aus dem Formular übergeben wurden. Dann wird der gesamte Datensatz mit store gespeichert, und die Komponentenseite wird wieder aufgerufen.
Die beiden Funktionen delete (Zeilen 41 – 48) und publish (Zeilen 49 – 57) können mehrere Datensätze gleichzeitig behandeln und arbeiten daher direkt in der Datenbank. Zunächst wird das übergebene Array $cid serialisiert, d. h. in eine Zeichenkette umgewandelt (Zeile 43 und 51). Dann wird das jeweilige SQL-Statement generiert (Zeilen 44/45 und 52 – 54). Hier sehen Sie, dass das serialisierte Array $cids direkt übergeben werden kann. Zuletzt wird die Abfrage ausgeführt und wieder auf die Komponentenseite weitergeleitet.
Jetzt müssen wir uns noch um die Ausgabe der Bearbeitungsseite kümmern. Fügen Sie die Funktion in der Klasse HTML_pair_rank nach der listItems-Funktion ein.
69 function edit( $option, &$row ) {
70 echo <<< HTML
71 <script language="javascript" type="text/javascript">
72 function submitbutton(pressbutton) {
73 var form = document.adminForm;
74 if (pressbutton == "cancel") {
75 submitform( pressbutton );
76 return;
77 }
78 submitform( pressbutton );
79 }
80 </script>
81 <form action="index2.php" method="post"
82 name="adminForm" id="adminForm" class="adminForm">
83 <table border="0" cellpadding="3" cellspacing="0">
84 <tr>
85 <td>Tanzpaar: </td>
86 <td>
87 <input type="text" size="50" maxsize="100"
88 name="pair" value="$row->pair" />
89 </td>
90 </tr>
91 <tr>
92 <td>Punkte: </td>
93 <td>
94 <input type="text" size="50" maxsize="100"
95 name="points" value="$row->points" />
96 </td>
97 </tr>
98 </table>
99 <input type="hidden" name="id" value="$row->id" />
100 <input type="hidden" name="option" value="$option" />
101 <input type="hidden" name="task" value="" />
102 </form>
103 HTML;
104 }
Listing 22.8 Auszug aus admin.pair_rank.html.php
Hier wird wieder ein Formular mit der Heredoc-Funktion ausgegeben und an den entsprechenden Stellen mit Werten aus dem Datensatz gefüllt. Es ist lediglich zu beachten, dass die Namen der übergebenen Werte (Zeilen 88 und 95) den Spalten in der Datenbank entsprechen, da nur in diesem Fall das Binden der Daten beim Speichern (vgl. save-Funktion der Programmdatei, Zeile 37) richtig funktioniert.
Sie können sich das Formular bereits ansehen, wenn Sie in der Listenansicht der Komponente auf den Namen eines Tanzpaares klicken. Die Ausgabe sehen Sie in Abbildung 22.4.
22.3.3 Die Toolbar
 
Leider haben wir bisher noch keine Möglichkeit, den Datensatz zu speichern, weil die nötigen Buttons fehlen. Daher müssen wir im letzten Schritt noch die Toolbar programmieren. Auch hier trennen wir Programmlogik und Ausgabe. Beachten Sie, dass zwei verschiedene Toolbars zu verwalten sind, je nachdem, ob wir in der Listen- oder Bearbeitungsansicht sind.
1 <?php
2 defined( '_VALID_MOS' ) or die( 'Direct Access to this
3 script is not allowed');
4 require_once($mainframe->getPath('toolbar_html'));
5 if (!$task) $task="listItems";
6 switch($task) {
7 case 'new':
8 case 'edit': menuPair_rank::edit_menu(); break;
9 default: menuPair_rank::list_menu(); break;
10 }
11 ?>
Listing 22.9 toolbar.pair_rank.php
In Zeile 4 wird die Datei toolbar.pair_rank.html.php eingebunden. Danach folgt eine Sicherheitsabfrage für den Fall, dass das Skript ohne $task-Parameter aufgerufen wird. In diesem Fall wird davon ausgegangen, dass die Listenansicht ausgegeben wird. In den Zeilen 6 – 10 wählt switch zwischen den beiden Menüs aus. Wird ein Datensatz neu erstellt (new) oder bearbeitet (edit), so wird die Funktion edit_menu aufgerufen, ansonsten list_menu. Diese beiden Funktionen sind in der Ausgabedatei zu finden.
1 <?php
2 defined( '_VALID_MOS' ) or die( 'Direct Access to this
3 script is not allowed');
4 class menuPair_rank {
5 function list_menu() {
6 mosMenuBar::startTable();
7 mosMenuBar::publish('publish');
8 mosMenuBar::unpublish('unpublish');
9 mosMenuBar::addNew('new');
10 mosMenuBar::editList('edit');
11 mosMenuBar::deleteList('', 'delete');
12 mosMenuBar::endTable();
13 }
14 function edit_menu() {
15 mosMenuBar::startTable();
16 mosMenuBar::back();
17 mosMenuBar::save('save');
18 mosMenuBar::endTable();
19 }
20 }
21 ?>
Listing 22.10 toolbar.pair_rank.html.php
Die Toolbar wird mit Funktionen der Klasse mosMenuBar aufgebaut, so dass wir uns in diesem Fall um das eigentliche HTML nicht mehr kümmern müssen. Am Anfang der Toolbar wird die Funktion startTable (Zeile 6 bzw. 15) aufgerufen, am Ende endTable (Zeile 12 bzw. 18). Die beiden geben den Rahmencode für die Symbolleiste aus. Dann folgen der Reihe nach die Symbole, die angezeigt werden sollen. Eine Liste von Symbolen finden Sie im Anhang A. Der Parameter in Klammern gibt an, welcher Wert als $task an die Komponente übergeben werden soll, wenn auf das Symbol geklickt wird.
Jetzt ist die Pair-Rank-Komponente voll einsatzfähig, und Sie können nach Belieben Paare und Wertungen eingeben und anzeigen lassen.
Achtung: Beachten Sie, dass wir im Code mit Sicherheitsabfragen sehr sparsam umgegangen sind, um die Programme übersichtlich zu halten. Wenn Sie eigene Komponenten einsetzen, sollten Sie Benutzereingaben und Übergabeparameter sowie die Datenbankabfragen jeweils mit Fehlerbehandlungen schützen.
|
|