Author: Progman, zuletzt bearbeitet von progman @ 2005-10-21 11:21:22
Bitte beachten Sie, dass die Tutorialkapitel zusammenhängen. Wenn sie direkt auf ein Kapitel verlinkt wurden müssen Sie gegebenenfalls die vorherigen Kapitel auch lesen. Achten Sie beim lesen darauf, dass Sie kein Kapitel überspringen.
Poll-Script
- Aufbau des Poll-Scripts
- MySQL-Tabellen zum Poll-Script
- Ändern des Layouts
- Adminbereich des Poll-Scripts
- Abstimmung hinzufügen
- Abstimmung bearbeiten
- Abstimmung löschen
- Formular zum Abstimmen
- Formularverarbeitung / Pollübersicht
1. Aufbau des Poll-Scripts
Jeder kennt es. Rechts ist meistens ein Bereich, in dem man voten kann. Dies ist bekannt als Poll. Wir schreiben nun auch so ein Poll-Script, wo man abstimmen kann und wo man in einer Übersicht alle schon abgeschlossenen Abstimmungen sieht. Damit das Abstimmungsergebnis nicht so sehr verfälscht werden kann wir eine IP- und Cookiesperre programmiert. Aber dies ist keine zuverlässige Methode, um eine Abstimmung eindeutig und nicht verfälscht zu halten. Denn ein Benutzer kann sich neu einwählen und/oder hat Cookies in seinem Browser deaktiviert. Eigentlich kann man Abstimmungen immer fälschen, es sei denn man muss sich irgentwo einloggen. Aber auch da kann man sich einen neuen Account machen und kann wieder voten.
2. MySQL-Tabellen zum Poll-Script
Nun müssen wir uns überlegen, wie wir die Daten in die MySQL-Datenbank speichern. Da man Frage, Antworten und Klicks speicher muss, würde man auf so ein Datenbank-Layout zuerst kommen.
poll(ID,Frage,Datum,Antwort1,Antwort2,Antwort3,....,Anzahl1,Anzahl2,Anzahl3,...)
poll_ip(IP,Datum,PollID)
Doch die Tabelle poll entspricht nicht den erste 3 Normalformen. Nehmen wir an, wir haben soviele Spalten hinzugefügt, dass man 10 Antworten angeben kann. Doch was mache ich wenn ich mehr als 10 Antworten haben möchte? Oder was mache ich wenn ich weniger als 10 Antworten haben möchte. Ich könnte die Anzahl der Spalten mit den Antworten auf 50 oder so setzen, aber dann verbrauche ich zu viel Speicherplatz wenn ich ein Ja-Nein-Poll habe. Deswegen müssen wir die Tabellenstruktur in der Datenbank etwas ändern. Die Antworten speichern wir in eine extra Tabelle.
poll(ID,Frage,Datum)
poll_antworten(ID,PollID,Antwort,Klicks)
poll_ip(IP,Datum,PollID)
Jetzt können wir dynamisch die Anzahl der Antworten bestimmen. Wir müssen nur die Poll-ID der Abstimmungsfrage in die Tabelle der Antworten speichern, damit man weiß, welche Antwort zu welcher Frage gehört. Dieses Layout erleichtert auch das Rechnen des prozentualen Anteils einer Antwort. Im ersten Fall müsste man im SELECT Befehl eine riesige Addition errechnen lassen. Bei 50 Spalten ist das eine ganz schöne schreibarbeit.
Die Tabelle für die IPs ist genauso aufgebaut und entpsricht der Funktionsweise die der IP-Sperre der Newskommentare.
Wie man diese Tabellen nun in MySQL erstellt solltet ihr nun wissen. Dies nehme ich nun nicht mehr weiter durch.
3. Ändern des Layouts
In vielen Seiten sieht man dass Links das Menu, in der Mitte der Inhalt und Rechts solche sachen wie Poll oder Last-CW vorhanden ist. Diese Seiten haben ein 3 Spalten Layout. Doch wir haben im moment nur ein 2 Spalten Layout. Wir müssen deshalb das Layout etwas anpassen.
Das alte Design müssen wir nur um eine neue Spalte erweitern.
<?php
// ...
echo " <div id=\"root\">\n"; // ganz oberer Div-Holder
echo " <div id=\"banner\">\n"; // banner
include "banner.php";
echo " </div>\n";
echo " <div id=\"links\">\n"; // linkes Menu
include "menu.php";
echo " </div>\n";
echo " <div id=\"mitte\">\n"; // In der Mitte der Inhalt
include "inhalt.php";
echo " </div>\n";
echo " <br style=\"clear:both;\" />\n"; // css-float beenden
echo " </div>\n";
// ...
?>
Dies ändern wir nur ein klein wenig.
<?php
// ...
echo " <div id=\"root\">\n"; // ganz oberer Div-Holder
echo " <div id=\"banner\">\n"; // banner
include "banner.php";
echo " </div>\n";
echo " <div id=\"links\">\n"; // linkes Menu
include "menu.php";
echo " </div>\n";
echo " <div id=\"mitte\">\n"; // In der Mitte der Inhalt
include "inhalt.php";
echo " </div>\n";
echo " <div id=\"rechts\">\n"; // rechtes Menu
include "rechts.php";
echo " </div>\n";
echo " <br style=\"clear:both;\" />\n"; // css-float beenden
echo " </div>\n";
// ...
?>
In der Datei rechts.php includen wir nun unser Poll-Script.
<?php
//include "lastcw.php";
include "showpoll.php";
?>
In der showpoll.php erstellen wir erstmal nur ein Dummy-Code.
<?php
echo "<p>\n";
echo " Pollscript\n";
echo "</p>\n";
?>
Diese Datei zeigt dann entweder ein Formular zum abstimmen oder das momentane Ergebnis der Abstimmung an, falls schon abgestimmt wurde. Doch an dieses Script wenden wir uns später zu.
4. Adminbereich des Poll-Scripts
Das Poll-Script sollen wir wieder über den Adminbereich verwalten können. Dazu müssen wir ein paar Veränderungen an bestehenden Dateien vornehmen. In der Datei admin_menu.php müssen wir eine neue Zeile hinzufügen, die so ähnlich augebaut ist wie die anderen Zeilen. Als Wert für den GET-Parameter site wähle ich poll. Entsprechend müssen wir das Array $admin_site aus der Variablen-Konfigurationsdatei bearbeiten. Damit wir auch in den Poll-Bereich reinkönnen müssen wir auch noch das Array $allRights um ein neues Element Poll erweitern.
Nachdem wir dies alles gemacht haben, erstellen wir wieder unser Grundgerüst mit der add-edit-del-switch Abfrage wie bei den anderen Bereichen.
<?php
$rights = getRights();
if(!in_array("Admin", $rights)) {
no_rights();
} else {
switch(isset($_GET['action'])?$_GET['action']:'') {
case "add":
break;
case "edit":
break;
case "del":
break;
default:
echo "<p>\n";
echo " Bitte benutzen sie nur einen Link aus dem Adminmenu.\n";
echo "</p>\n";
back2admin();
break;
}
}
?>
Nun schreiben wir die Code-Teile zum hinzufügen, bearbeiten und löschen von Abstimmungen.
5. Abstimmung hinzufügen
Zuerst gucken wir allgemein ob schon eine Abstimmung läuft. Dies machen wir, indem wir prüfen, ob ein Poll innerhalb der letzen Woche hinzugefügt wurde. In der Datenbank wird in der Spalte Datum der Startpunkt der Abstimmung gespeichert. Der Query sieht dann so aus:
SELECT
COUNT(*) AS Anzahl
FROM
poll
WHERE
DATE_ADD(Datum,INTERVAL 7 DAY) > NOW();
Diesen senden wir nun an die Datenbank. Dies machen wir nun mal mit unserer neu erstellten MySQL-Query Klasse, um ein wenig zu lernen wie man OOP benutzt.
<?php
case "add":
$sql = "SELECT
COUNT(*) AS Anzahl
FROM
poll
WHERE
DATE_ADD(Datum,INTERVAL 7 DAY) > NOW();";
$check = new Query($sql);
if($check->error()) {
die("<pre>".$check->geterror()."</pre>");
}
$row = $check->fetch();
if($row['Anzahl']) {
echo "<p class=\"error\">\n";
echo " Es läuft bereits eine Abstimmung, warten sie\n";
echo " bitte diese beendet ist.\n";
echo "</p>\n";
back2admin();
} else {
//es läuft keine Abstimmung
}
$check->free();
unset($check);
break;
?>
Wir erstellen nun erstmal wieder ein Grundlayout wie bei dem Newssystem. Die Antworten erstellen wir dann wieder mit einem extra Formular, genauso wie das Bearbeiten der Frage. Die Frage und die Antworten speichern wir in die Session.
<?php
case "add":
// ...
if($row['Anzahl']) {
// ...
} else {
if(!isset($_SESSION['Frage'])) {
$_SESSION['Frage'] = "";
}
if(!isset($_SESSION['Antworten'])) {
$_SESSION['Antworten'] = array();
}
switch(isset($_POST['submit'])?$_POST['submit']:'') {
default:
echo "<form action=\"index.php?section=admin&site=poll&action=add\"";
echo " method=\"post\"";
echo " class=\"formular\">\n";
echo " <p>\n";
echo " Neuen Poll hinzufügen\n";
echo " </p>\n";
echo " <ol>\n";
echo " <li>\n";
echo " Frage\n";
echo " <ul>\n";
echo " <li>\n";
echo $_SESSION['Frage']."\n";
echo " </li>\n";
echo " <li>\n";
echo "<input type=\"submit\" name=\"submit\" value=\"Frage bearbeiten\" />\n";
echo " </li>\n";
echo " </ul>\n";
echo " </li>\n";
echo " <li>\n";
echo " Antworten\n";
echo " <ul>\n";
if(count($_SESSION['Antworten'])) {
foreach($_SESSION['Antworten'] as $key => $value) {
echo "<li>\n";
echo "<input type=\"chechbox\" ";
echo " name=\"antworten[]\" ";
echo " value=\"".$key."\" />\n";
echo $value."\n";
echo "</li>\n";
}
}
echo " <li>\n";
echo "<input type=\"submit\" name=\"submit\"";
echo " value=\"Neue Antwort hinzufügen\" />\n";
if(count($_SESSION['Antworten'])) {
echo "<input type=\"submit\" name=\"submit\"";
echo " value=\"Löschen\" />\n";
}
echo " </li>\n";
echo " </ul>\n";
echo " </li>\n";
echo " <li>\n";
echo "<input type=\"submit\" name=\"submit\" value=\"Poll hinzufügen\" />\n";
echo "<input type=\"reset\" name=\"submit\" value=\"Zurücksetzen\" />\n";
echo "<input type=\"hidden\" name=\"".session_name()."\"";
echo " value=\"".session_id()."\" />";
echo " </li>\n";
echo " <ol>\n";
echo "</form>\n";
break;
}
}
$check->free();
unset($check);
break;
?>
Nun erstellen wir die Scripte zum Bearbeiten der Frage und zum Hinzufügen neuer Antworten.
<?php
case 'Frage bearbeiten':
echo "<form action=\"index.php?section=admin&site=poll&action=add\" ";
echo " method=\"post\"";
echo " class=\"formular\">\n";
echo " <p>\n";
echo " Frage bearbeiten.\n";
echo " </p>\n";
echo " <ol>\n";
echo " <li>\n";
echo " <label for=\"frage\">Frage</label>\n";
echo " <input type=\"text\" name=\"frage\"";
echo " id=\"name\" value=\"".$_SESSION['Frage']."\" />\n";
echo " </li>\n";
echo " <li>\n";
echo " <input type=\"submit\" name=\"submit\"";
echo " value=\"Frage speichern\" />\n";
echo " <input type=\"hidden\" name=\"".session_name()."\"";
echo " value=\"".session_id()."\" />";
echo " </li>\n";
echo " </ol>\n";
echo "</form>\n";
back2admin();
break;
?>
Und dann noch die Antworten.
<?php
case 'Neue Antwort hinzufügen':
echo "<form action=\"index.php?section=admin&site=poll&action=add\" ";
echo " method=\"post\"";
echo " class=\"formular\">\n";
echo " <p>\n";
echo " Antwort hinzufügen\n";
echo " </p>\n";
echo " <ol>\n";
echo " <li>\n";
echo " <label for=\"antwort\">Antwort</label>\n";
echo " <input type=\"text\" name=\"antwort\"";
echo " id=\"antwort\" />\n";
echo " </li>\n";
echo " <li>\n";
echo " <input type=\"submit\" name=\"submit\"";
echo " value=\"Antwort hinzufügen\" />\n";
echo " <input type=\"hidden\" name=\"".session_name()."\"";
echo " value=\"".session_id()."\" />";
echo " </li>\n";
echo " </ol>\n";
echo "</form>\n";
break;
?>
Die anderen Programmcodeteile fügen wir nun in den default-Teil ein, da sofort das Hauptformular angezeigt werden soll.
<?php
default:
if(isset($_POST['submit']) AND "Frage speichern" == $_POST['submit']) {
$_SESSION['Frage'] = htmlspecialchars(trim($_POST['frage']))
}
if(isset($_POST['submit']) AND "Antwort hinzufügen" == $_POST['submit']) {
$_SESSION['Antworten'][] = htmlspecialchars(trim($_POST['antwort']));
}
// ... Hauptformular
// ...
break;
?>
Nachdem man Antworten hinzugefügt hat, kann man diese Antworten auch wieder löschen. Dazu wählt man sie aus und klick auf den Button Löschen. Der dazu zuständige Programmcode schreiben wir auch im default-Bereich.
<?php
default:
if(isset($_POST['submit']) AND "Frage speichern" == $_POST['submit']) {
$_SESSION['Frage'] = htmlspecialchars(trim($_POST['frage']))
}
if(isset($_POST['submit']) AND "Antwort hinzufügen" == $_POST['submit']) {
$_SESSION['Antworten'][] = htmlspecialchars(trim($_POST['antwort']));
}
if(isset($_POST['submit']) AND "Löschen" == $_POST['submit']) {
if(isset($_POST['antworten'])) {
foreach($_POST['antworten'] as $value) {
unset($_SESSION['Antworten'][$value]);
}
$_SESSION['Antworten'] = array_values($_SESSION['Antworten']);
// lücken im Array schließen.
}
}
// ... Hauptformular
// ...
break;
?>
Nun brauchen wir nur noch den Programmteil, der den Poll auch wirklich in die Datenbank einträgt. Wir packen diesen Teil auch in den defaul-Bereich, da es sein kann, dass wir das Formular nochmal anzeigen müssen.
<?php
default:
if(isset($_POST['submit']) AND "Frage speichern" == $_POST['submit']) {
$_SESSION['Frage'] = htmlspecialchars(trim($_POST['frage']))
}
if(isset($_POST['submit']) AND "Antwort hinzufügen" == $_POST['submit']) {
$_SESSION['Antworten'][] = htmlspecialchars(trim($_POST['antwort']));
}
if(isset($_POST['submit']) AND "Löschen" == $_POST['submit']) {
if(isset($_POST['antworten'])) {
foreach($_POST['antworten'] as $value) {
unset($_SESSION['Antworten'][$value]);
}
$_SESSION['Antworten'] = array_values($_SESSION['Antworten']);
// lücken im Array schließen.
}
}
if(isset($_POST['submit']) AND "Poll hinzufügen" == $_POST['submit']) {
if(count($_SESSION['Antworten']) >= 2) {
$sql = "INSERT INTO
poll(Frage,Datum)
VALUES
('".addslashes($_SESSION['Frage'])."',
NOW());";
$poll = new Query($sql);
if($poll->error()) {
die("<pre>".$poll->getError()."</pre>\n");
}
unset($poll);
// nun muss ich die ID holen, damit ich die
// antworten hinzufügen kann
$sql = "SELECT
ID
FROM
poll
ORDER BY
Datum DESC
LIMIT
1;";
$getid = new Query($sql);
if($getid->error()) {
die("<pre>".$getid->getError()."</pre>\n");
}
$row = $getid->fetch();
$PollID = $row['ID'];
$getid->free();
unset($getid);
// und nun die Antworten hinzufügen, und die Klickcounter
// auf 0 setzen.
foreach($_SESSION['Antworten'] as $antwort) {
$sql = "INSERT INTO
poll_antworten(PollID,Antwort,Klicks)
VALUES
('".$PollID."',
'".$antwort."',
'0');";
$ansqry = new Query($sql);
if($ansqry->error()) {
die("<pre>".$ansqry->getError()."</pre>\n");
}
unset($ansqry);
}
echo "<p>\n";
echo " Poll wurde hinzugefügt.\n";
echo "</p>\n";
back2admin();
break;
// wir wollen nicht die If-Abfrage verlassen, was ja gar nicht
// geht, sondern die switch-Abfrage, da wir das Hauptformular
// nicht mehr brauchen.
} else {
echo "<p>\n";
echo " Bitte fügen sie mindestesn 2 Antworten hinzu.";
echo "</p>\n";
}
}
// ... Hauptformular
// ...
break;
?>
6. Abstimmung bearbeiten
Beim Bearbeiten einer Abstimmung müssen wir auf einige Sachen aufpassen. Wir können nicht einfach, wie bei den News die related Links, alle Antworten löschen und die bearbeiteten hinzufügen. Denn dann sind ja unsere Abstimmungen verloren. Das ist auch der Grund, warum die Tabelle poll_antworten auch eine ID-Spalte hat. Mit der können wir eine Antwort genau identifizieren bzw. erreichen.
Zuerst schreiben wir ein Formular um die Abstimmung zu wählen, die man bearbeiten möchte.
<?php
case "edit":
if(!isset($_SESSION['ID'])) {
$_SESSION['ID'] = 0;
} switch(@$_POST['submit']) {
case "Poll auswählen":
if(isset($_POST['PollID']) AND $_POST['PollID']) {
$sql = "SELECT
COUNT(*) as Anzahl
FROM
poll
WHERE
ID = '".addslashes($_POST['PollID'])."';";
$check = new Query($sql);
if($check->error()) {
die("<pre>".$check-getError()."</pre>\n");
}
$row = $check->fetch();
if($row['Anzahl']) {
$_SESSION['ID'] = $_POST['PollID'];
} else {
echo "<p>\n";
echo " Bitte wählen sie einen gültigen Poll aus.\n";
echo "</p>\n";
}
} else {
echo "<p>\n";
echo " Bitte wählen sie einen Poll aus\n";
echo "</pre>\n";
}
default:
if($_SESSION['ID']) {
// Zeige Formular
} else {
echo "<form action=\"index.php?section=admin&site=poll&action=edit\"";
echo " method=\"post\"";
echo " class=\"formular\">\n";
echo " <p>\n";
echo " </p>\n";
echo " Abstimmung auswählen.\n";
echo " <p>\n";
echo " <ol>n";
echo " <li>\n";
echo " <label for=\"pollid\">Poll</label>\n";
$sql = "SELECT
ID,
Frage,
Datum
FROM
poll
ORDER BY
Datum DESC;";
$polls = new Query($sql);
if($polls->error()) {
die("<pre>".$polls->getError()."</pre>\n");
}
echo "<select id=\"pollid\" name=\"PollID\">\n";
echo " <option value=\"0\">Bitte einen Poll wählen</option>\n";
while(