1. Eigenen Adminbereich schreiben
Früher oder später benötigen wir einen Bereich um unsere Bereiche zu steuern wie z.B. neue Newseinträge schreiben. Und dann ist es nicht nur eine Person die an dem System arbeiten sondern mehrere Personen, die dann auch noch unterschiedliche Zugriffsrechte haben sollen. Daher brauchen wir ein Rechtesystem mit dem wir steuern können welcher Benutzer was machen darf.
Früher hat man dies mit Bitmasken erstellt. So wurde in einer Zahl kodiert
welche Rechte ein Benutzer hat. So bedeutete die Zahl 5 das der Benutzer
das Recht 4 (2^2
) und 1 (2^0
) besas was dann
z.B. den Benutzer für den News-Bereich und
Download-Bereich authorisierte. Dies sind jedoch Steinzeitmethoden. Wir
besitzen eine relationale Datenbank also nutzen wir sie auch.
Für unser Adminbereich definieren wir zuerst eine Tabelle die alle möglichen Rechtenamen enthält.
-
ID
- Jedes Recht bekommt eine ID auf die später referenziert werden kann. Daher ist der Typ wie üblich INT mit den entsprechenden Attributen UNSIGNED, AUTO_INCREMENT und PRIMARY KEY. -
Name
- Die Bezeichnung vom Recht, Typ ist VARCHAR(30).
Die SQL-Anfrage sieht wie folgt aus.
CREATE TABLE Rechteliste ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Name VARCHAR(30) NOT NULL );
Das Recht mit der ID 1
setzen wir auf Admin
. Dies können
wir z.B. mit phpMyAdmin hinzufügen. Zum testen fügen wir noch weitere Rechte mit
den Bezeichnungen Recht 1
, Recht 2
und Recht 3
hinzu.
Aufgrund der AUTO_INREMENT-Eigenschaft werden diese
Rechte die IDs 2
, 3
und 4
bekommen.
Da wir nun die Rechteliste haben müssen wir für jeden User speichern welche Rechte er besitzt.
Hierfür verwenden wir eine neue Tabelle Adminrechte
. Sie besitzt 2 Spalten
die ein UserID mit einem Recht verbindet.
-
UserID
- Die ID des Benutzers, entsprechend vom Typ INT mit den Attributen UNSIGNED und NOT NULL. -
RechtID
- Die ID des Recht aus der Rechteliste, auch vom Typ INT mit den Attributen UNSIGNED udn NOT NULL.
Wie man sieht haben beide Spalten weder ein AUTO_INCREMENT- noch ein PRIMARY KEY-Attribut. Diese sind in dieser Tabelle nicht nötig da wir einen Datensatz durch beide Werte bereits eindeutig identifizieren können. Diese Tabelle kann dann mittels phpMyAdmin oder durch folgende SQL-Anfrage hinzugefügt werden.
CREATE TABLE Adminrechte ( UserID INT UNSIGNED NOT NULL, RechtID INT UNSIGNED NOT NULL );
Für jedes Recht das ein Benutzer hat wird ein neuer Datensatz hinzugefügt. Wenn z.B.
der Benutzer mit der ID 5 das Recht mit der ID 7 besitzt so wird der Datensatz
(5,7)
hinzugefügt. Wenn er dieses Recht nicht mehr besitzt so wird
der Datensatz wieder gelöscht. So kann ganz dynamisch die Tabelle gefüllt werden die
die Rechte der einzelnen Benutzer angibt.
Zum Testen müssen wir unserem Benutzeraccount das Admin-Recht geben. Da
die eigene UserID wahrscheinlich 1
ist und das Admin-Recht die
ID 1
besitzt müssen wir über phpMyAdmin manuell den Datensatz
(1,1)
hinzufügen.
2. Hilfsfunktionen schreiben
Für unseren Adminbereich und für die einzelnen Unterbereiche brauchen wir zwei Hilfsfunktionen um zu überprüfen ob der Benutzer das Recht hat die Bereiche zu verwenden.
-
bool hasRight(MySQLi $db, String $right)
- Mit dieser Funktion soll überprüft werden ob der angemeldete Benutzer das angegebene Recht besitzt. Der erste Parameter wird dabei unser MySQLi-Objekt sein, der zweite Parameter das zu prüfende Recht.<?php
/**
* Prüft ob der angemeldete Benutzer das angegeben Recht hat.
*
* Mit dieser Funktion kann überprüft werden ob der angemeldete Benutzer
* das angegebene Recht besitzt. Wenn die Parameter ungültig sind oder
* ein MySQL-Fehler auftrat wird das PHP-Skript mit einer Fehlermeldung
* beendet.
*
* @param db Das MySQLi-Objekt zur Datenbank
* @param right Der Name vom zu prüfenden Recht
* @return True wenn der angemeldete Benutzer das Recht hat, sonst false
*/
function hasRight($db, $right) {
if (!($db instanceof MySQLi)) {
die('Erster Parameter muss ein MySQLi-Objekt sein.');
}
if (!is_string($right)) {
die('Zweiter Parameter muss ein String sein.');
}
if (!$UserID = getUserID($db)) {
return false;
}
$sql = 'SELECT
Adminrechte.UserID
FROM
Adminrechte
JOIN
Rechteliste
ON
Adminrechte.RechtID = Rechteliste.ID
WHERE
Adminrechte.UserID = ? AND
Rechteliste.Name = ?';
if (!$stmt = $db->prepare($sql)) {
// wir lassen das skript beenden, nicht so wie in der getUserID-Funktion
die ('MySQL-Fehler: '.$db->error);
}
$stmt->bind_param('is', $UserID, $right);
if (!$stmt->execute()) {
die ('MySQL-Statement-Fehler: '.$stmt->error); // s.o.
}
$stmt->bind_result($UserID); // interessiert eh keinen
$ret = $stmt->fetch(); // ist true wenn ein Datensatz vorhanden ist oder
// NULL wenn nicht (und false wenn ein fehler auftrat)
$stmt->close();
return (bool)$ret;
}Untypisch für unser System beenden wir das PHP-Skript bei einem MySQL-Fehler. Wie gern würden wir hier Exceptions benutzen, jedoch haben wir weder gelernt was Exceptions sind noch benutzt die MySQLi-Extension Exceptions wie wir sie brauchen. Der Rückgabewert wird zu Boolean gecasted damit er entweder
true
oderfalse
ist. -
bool gotSomeRights(MySQLi $db)
- Diese Funktion überprüft ob der angemeldete Benutzer mindestens ein Recht besitzt. Anhand der Funktion können wir steuern ob der Adminbereich dargestellt wird oder nicht. Der erste Parameter ist dabei das MySQLi-Objekt.<?php
/**
* Prüft ob der angemeldete Benutzer mindestens ein Recht besitzt.
*
* Mit dieser Funktion kann überprüft werden ob der angemeldete
* Benutzer mindestens ein Recht besitzt. Wenn der Parameter
* ungültig ist oder ein MySQL-Fehler auftrat wird das
* PHP-Skript mit einer Fehlermeldung beendet.
*
* @param db Das MySQLi-Objekt
* @return True wenn der angemeldete Benutzer mindestens ein Recht besitzt, sonst false.
*/
function gotSomeRights($db) {
if (!($db instanceof MySQLi)) {
die('Erster Parameter muss ein MySQLi-Objekt sein');
}
if (!$UserID = getUserID($db)) {
return false;
}
$sql = 'SELECT
UserID
FROM
Adminrechte
WHERE
UserID = ?';
if (!$stmt = $db->prepare($sql)) {
die('MySQL-Fehler: '.$db->error);
}
$stmt->bind_param('i', $UserID);
if (!$stmt->execute()) {
die('MySQL-Statement-Fehler: '.$db->error);
}
$stmt->bind_result($UserID);
$ret = $stmt->fetch();
$stmt->close();
return (bool)$ret;
}
?>
Beide Funktionen fügen wir dann in die functions.php
-Datei ein.
3. Übersicht des Adminbereichs
In den Adminbereich soll man nur gelangen wenn man mindestens ein Recht besitzt,
daher auch die Funktion gotSomeRights(MySQLi)
. Außerdem darf der
Adminbereich nur die Bereiche anzeigen zu den der Benutzer auch das Recht hat.
Die Unterbereiche ihrerseids müssen überprüfen ob der angemeldete Benutzer
auch das Recht hat den entsprechenden Bereich zu nutzen.
Zuerst definieren wir wieder unsere Template-Datei, in diesem Fall die
admin.tpl
.
<?php /* Daten: * Rechteliste - Ein Array mit allen möglichen Rechten. Bei einem Element ist der * Schlüssel die RechtID und der Wert der Name vom Recht. * Userrechte - Ein Array mit allen Rechten die der angemeldete Benutzer besitzt. * Die Werte entsprechend die IDs von den Rechten. */ ?><table id="admin"> <caption>Adminbereich</caption> <thead> <tr> <th>Bereich</th> <th colspan="3">Aktionen</th> </tr> </thead> <tbody> <?php foreach($data['Rechteliste'] as $key => $value) { if (in_array($key, $data['Userrechte'])) { ?> <tr> <th><?php echo $value; ?></th> <td><a href="index.php?section=admin&cat=<?php echo rawurlencode($value); ?>&action=add">Hinzufügen</a></td> <td><a href="index.php?section=admin&cat=<?php echo rawurlencode($value); ?>&action=edit">Bearbeiten</a></td> <td><a href="index.php?section=admin&cat=<?php echo rawurlencode($value); ?>&action=del">Löschen</a></td> </tr> <?php } else { ?> <tr> <th><?php echo $value; ?></th> <td>Hinzufügen</td> <td>Bearbeiten</td> <td>Löschen</td> </tr> <?php } } ?> </tbody> </table>
Wie man sieht werden wir später die Bereiche immer auf die gleiche Weise aufrufen.
Wir sehen auch das der Name des Rechts als cat
-Parameter an das
Admin-Skript übergeben wird. Und wir geben den Wert $value
(der
den Namen des Rechts enthält) direkt aus, daher sollten unsere Rechte in
der Rechteliste-Tabelle keine HTML-Zeichen enthalten (und sonst auch Zeichen die
für URLs ungemütlich werden können).
Die Include-Datei admin.php
enthält zuerst einige Abfragen ob der Adminbereich
geladen werden kann und holt dann aus der Datenbank die Informationen zu den Rechten.
<?php
$ret = array();
$ret['filename'] = 'admin.tpl';
$ret['data'] = array();
if (!$UserID = getUserID($db)) {
return NOT_LOGGED_IN;
}
if (!gotSomeRights($db)) {
return NO_RIGHTS;
}
$sql = 'SELECT
ID,
Name
FROM
Rechteliste
ORDER BY
Name ASC';
if (!$res = $db->query($sql)) {
return $db->error;
}
$Rechteliste = array();
// beachtet, $res ist "nur" ein MySQLi_Result-Objekt, kein MySQLi_STMT-Objekt
while ($row = $res->fetch_assoc()) {
$Rechteliste[$row['ID']] = $row['Name'];
}
$res->free_result();
$sql = 'SELECT
RechtID
FROM
Adminrechte
WHERE
UserID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
$stmt->bind_param('i', $UserID);
if (!$stmt->execute()) {
return $stmt->error;
}
$Userrights = array();
$stmt->bind_result($RechtID);
while ($stmt->fetch()) {
$Userrights[] = $RechtID;
}
$stmt->close();
$ret['data']['Rechteliste'] = $Rechteliste;
$ret['data']['Userrechte'] = $Userrights;
return $ret;
?>
Je nach dem für welche Bereiche man Rechte besitzt werden die Links angezeigt.
Zum testen sind dies nur die Links für den Bereich für die Admin-Verwaltung.
Die Konstante NO_RIGHTS
muss natürlich in der
constants.php
-Datei definiert werden.
Damit wir die entsprechend Bereiche laden müssen wir auf die GET-Variablen
cat
und action
reagieren. Dazu reichen einfache If-Abfragen
und include-Zeilen die die Dateien admin_{cat}_{action}.php
aufrufen.
<?php
// [...]
while ($stmt->fetch()) {
$Userrights[] = $RechtID;
}
$stmt->close();
if (isset($_GET['cat'], $_GET['action'])) {
if (!hasRight($db, $_GET['cat'])) {
// man hätte auch in_array() auf $Userrights anwenden können,
// wo wir das array schon haben ...
return NO_RIGHTS;
}
return include 'admin_'.str_replace(' ', '_', $_GET['cat']).'_'.$_GET['action'].'.php';
}
$ret['data']['Rechteliste'] = $Rechteliste;
$ret['data']['Userrechte'] = $Userrights;
return $ret;
?>
Da, wie gesagt, Dateien der Form admin_{cat}_{action}.php
geladen werden
sind wir in der Bezeichnung der Rechte eingeschränkt und sollten nicht
exotische Zeichen wie §
verwenden. Des Weiteren sieht es so aus
als ob das System unsicher ist da wir den Dateinamen dynamisch aus Usereingaben
generieren. Jedoch wird das Ganze durch die Funktionen hasRight(MySQLi, String)
abgesichert.
4. Admin hinzufügen
Wir werden zwei Schritte verwenden um einen Admin hinzuzufügen. Zuerst
wählen wir Anhand der User-ID den Benutzer aus. Wenn der
Benutzer gefunden wird zeigen wir ein Formular an in dem wir die
Rechte auswählen können die der neue Admin haben soll. Wir brauchen also
zwei verschiede Templates. Daher definieren wir zuerst die Template-Datei
admin_Admin_add_userselect.tpl
.
<form action="index.php?section=admin&cat=Admin&action=add" method="post"> <fieldset> <legend>Benutzer auswählen</legend> <label>Benutzer ID: <input type="text" name="BenutzerID" /></label> <input type="submit" name="formaction" value="Benutzer wählen" /> </fieldset> </form>
Die zweite Template-Datei, die admin_Admin_add_selectrights.tpl
,
sieht wie folgt aus.
<?php /* Daten: * BenutzerID - Die ID des Benutzers der zum Admin befördert werden soll * Username - Der Name vom Benutzer * Rechte - Ein Array mit allen möglichen Rechten. Bei einem Arrayelement ist * der Schlüssel die ID und der Wert der Name vom Recht. */ ?><form action="index.php?section=admin&cat=Admin&action=add" method="post"> <fieldset> <legend>Rechte einstellen</legend> <p class="info"> Name: <?php echo htmlspecialchars($data['Username']); ?> </p> <fieldset> <legend>Rechte auswählen</legend> <?php foreach ($data['Rechte'] as $key => $value) { ?> <label><input type="checkbox" name="Recht[]" value="<?php echo $key; ?>" /><?php echo htmlspecialchars($value); ?></label> <?php } ?> </fieldset> <input type="submit" name="formaction" value="Admin hinzufügen" /> <input type="hidden" name="BenutzerID" value="<?php echo $data['BenutzerID']; ?>" /> </fieldset> </form>
Das Skript wird mit zuerst mit der GET-Methode aufgerufen und dann später
mit der POST-Methode. Bei der POST-Methode können wir das formaction
-Feld
abfragen und die entsprechenden Aktionen durchführen. Unsere Include-Datei
admin_Admin_add.php
sieht zuerst wie folgt aus.
<?php
$ret = array();
$ret['data'] = array();
$ret['filename'] = 'admin_Admin_add_userselect.tpl';
if ('POST' != $_SERVER['REQUEST_METHOD']) {
return $ret;
}
?>
Wenn das Skript mit der POST-Methode aufgerufen wird müssen wir die
Eingaben verarbeiten. Zuerst überprüfen wir ob die BenutzerID existiert und
ob der Benutzer bereits ein Admin ist oder nicht. Diese Überprüfungen gelten
für beide Bereiche Benutzer wählen
und Admin hinzufügen
.
<?php
// [...]
if ('POST' != $_SERVER['REQUEST_METHOD']) {
return $ret;
}
if (!isset($_POST['BenutzerID'], $_POST['formaction'])) {
return INVALID_FORM;
}
if ('' == $BenutzerID = trim($_POST['BenutzerID'])) {
return EMPTY_FORM;
}
$sql = 'SELECT
ID,
Username
FROM
User
WHERE
ID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
$stmt->bind_param('i', $BenutzerID);
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->bind_result($BenutzerID, $Username);
if (!$stmt->fetch()) {
return 'Es existiert kein Benutzer mit dieser ID.';
}
$stmt->close();
$sql = 'SELECT
UserID
FROM
Adminrechte
WHERE
UserID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
$stmt->bind_param('i', $BenutzerID);
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->store_result();
if ($stmt->num_rows) {
return 'Der Benutzer ist bereits als Admin vorhanden.';
// dies schließt auch die eigene Benutzer ID mit ein, da man sonst
// nicht den Adminbereich betreten hätte können
}
$stmt->close();
?>
Da nun die Benutzer-ID gültig ist können wir auf die Formulardaten reagieren.
<?php
// [...]
if ($stmt->num_rows) {
return 'Der Benutzer ist bereits als Admin vorhanden.';
// dies schließt auch die eigene Benutzer ID mit ein, da man sonst
// nicht den Adminbereich betreten hätte können
}
$stmt->close();
if ('Admin hinzufügen' == $_POST['formaction']) {
// todo
} else {
$sql = 'SELECT
ID,
Name
FROM
Rechteliste
ORDER BY
Name ASC';
if (!$res = $db->query($sql)) {
return $db->error;
}
$Rechteliste = array();
while ($row = $res->fetch_assoc()) {
$Rechteliste[$row['ID']] = $row['Name'];
}
$res->free_result();
$ret['data']['BenutzerID'] = $BenutzerID;
$ret['data']['Username'] = $Username;
$ret['data']['Rechte'] = $Rechteliste;
$ret['filename'] = 'admin_Admin_add_selectrights.tpl';
return $ret;
}
?>
In den If-Teil müssen wir nun die Checkboxen auslesen und dann
ggf. in die Adminrechte
-Tabelle schreiben.
<?php
// [...]
if ('Admin hinzufügen' == $_POST['formaction']) {
if (!isset($_POST['Recht'])) {
return 'Bitte wähl mindestens ein Recht aus.';
// oder return EMPTY_FORM;, was man halt lieber mag
}
if (!is_array($_POST['Recht'])) {
return INVALID_FORM;
}
// prüfen ob alle IDs gültig sind
$IDs = array();
$sql = 'SELECT
ID
FROM
Rechteliste
WHERE
ID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
foreach ($_POST['Recht'] as $Recht) {
$stmt->bind_param('i', $Recht);
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->bind_result($Recht);
if (!$stmt->fetch()) {
return 'Es wurde kein Recht mit der angegebenen ID gefunden.';
}
$IDs[] = $Recht;
}
$stmt->close();
// alle IDs sind gültig, speichern
$sql = 'INSERT INTO
Adminrechte (UserID, RechtID)
VALUES
(?,?)';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
foreach ($IDs as $Recht) {
$stmt->bind_param('ii', $BenutzerID, $Recht);
if (!$stmt->execute()) {
return $stmt->error;
}
}
$stmt->close();
return showInfo('Der Admin wurde mit den ausgewählten Rechten hinzugefügt.');
} else {
// [...]
}
?>
Für jede ID im Recht-Array prüfen wir ob es auch wirklich ein Recht mit dieser ID gibt. Wenn alles IDs gültig sind werden sie mit einer foreach-Schleife in die Datenbank gespeichert.
5. Admin bearbeiten
Die Bearbeitung eines Admins benutzt fast die selben Formulare wie das Hinzufügen eines Admins. Jedoch müssen ne Idee mehr Abfragen eingebaut werden da z.B. ein Admin sich nicht selbst ausschließen darf.
Da wir mehrere Formulare benötigen brauchen wir wieder getrennte
Template-Dateien. Zuerst die admin_Admin_edit_selectadmin.tpl
-Datei.
<form action="index.php?section=admin&cat=Admin&action=edit" method="post"> <fieldset> <legend>Admin wählen</legend> <label>Benutzer ID: <input type="text" name="AdminID" value="" /></label> <input type="submit" name="formaction" value="Admin wählen" /> </fieldset> </form>
Und nun die Template-Datei admin_Admin_edit_rights.tpl
.
<?php /* Daten: * AdminID - Die ID vom Admin * Username - Der Name vom Admin * Rechteliste - Eine Liste aller möglichen Rechte. Bei einem Arrayelement ist * der Schlüssel die ID und der Wert der Name vom Recht. * Adminrechte - Ein Array mit Rechte-IDs die der Admin bereits besitzt. */ ?><form action="index.php?section=admin&cat=Admin&action=edit" method="post"> <fieldset> <legend>Rechte bearbeiten</legend> <p class="info"> Admin: <?php echo htmlspecialchars($data['Username']); ?> </p> <fieldset> <legend>Rechte</legend> <?php foreach ($data['Rechteliste'] as $key => $value) { if (in_array($key, $data['Adminrechte'])) { ?> <label><input type="checkbox" name="Recht[]" value="<?php echo $key; ?>" checked="checked" /> <?php } else { ?> <label><input type="checkbox" name="Recht[]" value="<?php echo $key; ?>" /> <?php } ?> <?php echo htmlspecialchars($value); ?></label> <?php } ?> </fieldset> <input type="submit" name="formaction" value="Rechte speichern" /> <input type="hidden" name="AdminID" value="<?php echo $data['AdminID']; ?>" /> </fieldset> </form>
Zuerst zeigen wir mit unserere Include-Datei admin_Admin_edit.php
die erste Template-Datei wenn das Skript mit der GET-Methode aufgerufen wird.
<?php
$ret = array();
$ret['filename'] = 'admin_Admin_edit_selectadmin.tpl';
$ret['data'] = array();
if ('POST' != $_SERVER['REQUEST_METHOD']) {
return $ret;
}
?>
Wie für den PHP-Code zum hinzufügen von Admins prüfen wir ob es ein Admin mit der gegebenen Admin-ID gibt.
<?php
// [...]
if ('POST' != $_SERVER['REQUEST_METHOD']) {
return $ret;
}
if (!isset($_POST['AdminID'], $_POST['formaction'])) {
return INVALID_FORM;
}
if ('' == $AdminID = trim($_POST['AdminID'])) {
return EMPTY_FORM;
}
$sql = 'SELECT
UserID
FROM
Adminrechte
WHERE
UserID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
$stmt->bind_param('i', $AdminID);
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->bind_result($AdminID);
if (!$stmt->fetch()) {
return 'Es wurde kein Admin mit dieser ID gefunden.';
}
$stmt->close();
?>
Da die Admin-ID gültig ist prüfen wir den Wert von
$_POST['formaction']
und rufen
aus der Datenbank die Datensätze ab.
<?php
// [...]
if (!$stmt->fetch()) {
return 'Es wurde kein Admin mit dieser ID gefunden.';
}
$stmt->close();
if ('Rechte speichern' == $_POST['formaction']) {
// todo
} else {
$sql = 'SELECT
ID,
Name
FROM
Rechteliste
ORDER BY
Name ASC';
if (!$res = $db->query($sql)) {
return $db->error;
}
$Rechteliste = array();
while ($row = $res->fetch_assoc()) {
$Rechteliste[$row['ID']] = $row['Name'];
}
$res->free_result();
$sql = 'SELECT
RechtID
FROM
Adminrechte
WHERE
UserID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
$stmt->bind_param('i', $AdminID);
$Adminrechte = array();
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->bind_result($RechtID);
while($stmt->fetch()) {
$Adminrechte[] = $RechtID;
}
$stmt->close();
$sql = 'SELECT
Username
FROM
User
WHERE
ID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
$stmt->bind_param('i', $AdminID);
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->bind_result($Username);
if (!$stmt->fetch()) {
// Wenn dieser Code ausgeführt wird ist wirklich was
// schiefgegangen.
return 'Konnte nicht den Benutzernamen laden.';
}
$stmt->close();
$ret['data']['AdminID'] = $AdminID;
$ret['data']['Username'] = $Username;
$ret['data']['Rechteliste'] = $Rechteliste;
$ret['data']['Adminrechte'] = $Adminrechte;
$ret['filename'] = 'admin_Admin_edit_rights.tpl';
return $ret;
}
?>
In dem Teil für Rechte speichern
müssen wir neben dem Speichern
auch überprüfen ob sich der letzte Admin ausschließen will indem er sich
das Admin-Recht wegnimmt. Um die neuen Rechte zu speichern löschen
wir alle alten Rechte und fügen dann die Rechte neu ein. Das erspart uns
einiges an Programmlogik die entsprechen würde wenn wir z.B. nur die
Rechte löschen die überflüssig sind oder nur die Datensätze
hinzufügen die neu sind.
<?php
// [...]
if ('Rechte speichern' == $_POST['formaction']) {
if (!isset($_POST['Recht'])) {
return 'Der Admin muss mindestens ein Recht besitzen.';
}
if (!is_array($_POST['Recht'])) {
return INVALID_FORM;
}
// prüfen ob alle IDs gültig sind.
$IDs = array();
$sql = 'SELECT
ID
FROM
Rechteliste
WHERE
ID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
foreach ($_POST['Recht'] as $RechtID) {
$stmt->bind_param('i', $RechtID);
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->bind_result($RechtID);
if (!$stmt->fetch()) {
return 'Es wurde kein Recht mit der angegebenen ID gefunden.';
}
$IDs[] = $RechtID;
}
$stmt->close();
// IDs sind gültig, gucken ob der letzte admin sich ausschließen würde.
// Hier gehen wir davon aus das 1 das Admin-Recht ist.
if (!in_array(1, $IDs)) {
// Wenn die 1 drin ist ist es eh egal, dann kriegt er ja
// das Admin-Recht, aber so müssen wir es überprüfen.
$sql = 'SELECT
UserID
FROM
Adminrechte
WHERE
UserID != ? AND
RechtID = 1';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
$stmt->bind_param('i', $AdminID);
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->store_result();
if (!$stmt->num_rows) {
return 'Sie können sich nicht selbst das Adminrecht nehmen da sonst '.
'keine Admins mehr vorhanden sind.';
}
$stmt->close();
}
// alte Rechte löschen
$sql = 'DELETE FROM
Adminrechte
WHERE
USerID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
$stmt->bind_param('i', $AdminID);
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->close();
// neue Rechte hinzufügen
$sql = 'INSERT INTO
Adminrechte(UserID, RechtID)
VALUES
(?,?)';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
foreach ($IDs as $ID) {
$stmt->bind_param('ii', $AdminID, $ID);
if (!$stmt->execute()) {
return $stmt->error;
}
}
$stmt->close();
return showInfo('Die Rechte vom Admin wurden gespeichert.');
} else {
// [...]
}
?>
Nun können die einzelnen Admins bearbeitet werden.
6. Admin löschen
Einen Admin zu löschen ist hingegen wieder ganz einfach. Da braucht man
nur die Datensätze aus der Adminrechte
-Tabelle zu löschen.
Da wir nur eine Template-Datei brauchen (zum Wählen des Admins) heißt
die Datei nur admin_Admin_del.tpl
.
<form action="index.php?section=admin&cat=Admin&action=del" method="post">
<fieldset>
<legend>Admin löschen</legend>
<label>Admin ID: <input type="text" name="AdminID" /></label>
<input type="submit" name="formaction" value="Admin löschen" />
</fieldset>
</form>
In der Include-Datei admin_Admin_del.php
zeigen wir beim
Aufruf über die GET-Methode das Template an.
<?php
$ret = array();
$ret['filename'] = 'admin_Admin_del.tpl';
$ret['data'] = array();
if ('POST' != $_SERVER['REQUEST_METHOD']) {
return $ret;
}
?>
Wenn die Datei über die POST-Methode aufgerufen wird prüfen wir
zuerst die Formulardaten und löschen dann ggf. die Datensätze aus
der Adminrechte
-Tabelle.
<?php
$ret = array();
$ret['filename'] = 'admin_Admin_del.tpl';
$ret['data'] = array();
if ('POST' != $_SERVER['REQUEST_METHOD']) {
return $ret;
}
if (!isset($_POST['formaction'], $_POST['AdminID'])) {
return INVALID_FORM;
}
if ('' == $AdminID = trim($_POST['AdminID'])) {
return EMPTY_FORM;
}
$sql = 'SELECT
UserID
FROM
Adminrechte
WHERE
UserID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
$stmt->bind_param('i', $AdminID);
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->bind_result($AdminID);
if (!$stmt->fetch()) {
return 'Es wurde kein Admin mit dieser ID gefunden.';
}
$stmt->close();
if ($AdminID == $UserID) {
return 'Sie können sich nicht selbst löschen.';
}
$sql = 'DELETE FROM
Adminrechte
WHERE
UserID = ?';
if (!$stmt = $db->prepare($sql)) {
return $db->error;
}
$stmt->bind_param('i', $AdminID);
if (!$stmt->execute()) {
return $stmt->error;
}
$stmt->close();
return showInfo('Der Admin wurde gelöscht.');
?>
Und schon kann man ein Admin löschen.