Quakenet/#php Tutorial

Hinweis: Wenn sie diese Seite von einer externen URL aufgerufen haben achten sie darauf das alle Kapitel aufeinander aufbauen. Stellen sie daher sicher dass sie alle vorherigen Kapitel gelesen haben, da sie sonst relevante Informationen übersehen.

Adminbereich

  1. Eigenen Adminbereich schreiben
  2. Hilfsfunktionen schreiben
  3. Übersicht des Adminbereichs
  4. Admin hinzufügen
  5. Admin bearbeiten
  6. Admin löschen

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.

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.

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.

  1. 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 oder false ist.

  2. 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&amp;cat=<?php echo rawurlencode($value); ?>&amp;action=add">Hinzufügen</a></td>
            <td><a href="index.php?section=admin&amp;cat=<?php echo rawurlencode($value); ?>&amp;action=edit">Bearbeiten</a></td>
            <td><a href="index.php?section=admin&amp;cat=<?php echo rawurlencode($value); ?>&amp;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&amp;cat=Admin&amp;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&amp;cat=Admin&amp;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&amp;cat=Admin&amp;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&amp;cat=Admin&amp;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&amp;cat=Admin&amp;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.

Fragen zum Kapitel

Keine Fragen zum Kapitel vorhanden

Zurück zu Weiter zu
Copyright © bei den OPs von #php.de/QuakeNet Valid XHTML 1.0 Strict Valid CSS!