Vorwort

Diese Anleitung wurde für Schulungszwecke erstellt, weshalb einiges nicht als fertiger Code zur Verfügung steht. Es soll keine Copy-Paste-Übung werden 😅

Sollte etwas unverständlich oder inkorrekt sein, bitte ich um Feedback um es beheben zu können. Nobody is perfect.

Die komplette Ordnerstruktur des Projektes
- | auth
- - | auth.php
- - | changeImage.php
- - | delete.php
- - | editLexikon.php
- - | fetch.php
- - | insert.php
- - | login.php
- - | logout.php
- - | registry.php
- - | secret.php
- | css
- - | custom.css
- | img
- - | Bilder die auf der Seite statisch verwendet werden
- | inc
- - | editEntry.inc.php
- - | liveSearch.inc.php
- - | login.inc.php
- - | loadModal.inc.php
- - | loggedNav.inc.php
- - | saveEntry.inc.php
- | js
- - | liveSearch.js
- | upload-img
- | index.php

Eintrag anlegen

Einen Eintrag anlegen Step 1: auth/editLexikon.php

Um einen neuen Eintrag anzulegen, wurde wieder ein Bootstrap Modal und die Formularelemente von Bootstrap verwendet. Die Formularelemente müssen wieder um die Attribute name erweitert werden. Die action verweist auf das File inc/saveEntry.inc.php . Da ein Bild bei Bedarf mit hochgeladen werden kann, muss zusätzlich zu method, action auch enctype="multipart/form-data"  deklariert werden.

Step 2: inc/saveEntry.inc.php

Als erstes werden die Einträge aus dem POST in Variablen abgespeichert. Außerdem wird in der Superglobalen Variablen $_FILE nachgeschaut, ob eine Datei mitgeschickt wurde oder nicht und je nachdem ist die Variable $file = NULL oder beinhaltet den Filenamen.

Da hochgeladene Files im Ordner lexikon_img abgespeichert werden soll, wird der Pfad ebenfalls in eine Variable gespeichert. $uploadOK dient als Error Variable. Solange sie 1 also true ist, kann das Programm weiterlaufen.

In der Variable $target_file speichere ich den Pfad und den Namen des Files ab.
strtolower setzt einen String in Kleinbuchstaben um, damit wird sichergestellt, dass die Fileendungen auch wirklich klein geschrieben sind und mit pathinfo(string, PATHINFO_EXTENSION) erhält man die Dateieindung.

Da mit Bildern auch schädliche Inhalte hochgeladen werden können, ist es wichtig zu checken ob das Bild auch wirklich ein Bild ist. Zusätzlich kann man mit einer einfachen if-Verzweigung nur bestimmte Bildformate erlauben. Da ich hier nicht auf Groß- und Kleinschreibung überprüfen möchte, wurde weiter oben das strtolower angewendet. Die Meldung „File is an image“ wird nicht wirklich ausgegeben, da es am Ende der Seite einen Reload der Seite gibt. Die Ausgaben der Fehlermeldungen und Erfolgsmeldungen sind noch nicht fertig. Update hierzu folgt noch.

Wenn es bis hier her keine Fehler gibt, wird das eigentliche Bild abgespeichert und eine entsprechende Meldung ausgegeben. Mit move_uploaded_file() definiere ich was wohin gespeichert wird.

Nun fehlt nur noch, dass die restlichen Eingabefelder und der Inhalt von $file (entweder NULL oder der Bildname) in der Datenbank abgespeichert wird.

Dies erfolgt wieder über ein Prepared Statement, dass wir aus der Registrierung schon kennen.

Wenn alles ohne Fehler durchgelaufen wird, wird der User zur letzten Seite zurück geschmissen (theoretisch…). Eigentlich erlebt der User nur dass sich die Seite neu ladet und der Eintrag da ist 🤣

 

Einträge anzeigen im auth/editLexikon.php mit den Buttons für das weitere verarbeiten

Die Einträge aus der Datenbank werden in diesem Beispiel als Liste dargestellt. Dazu dient als Grundgerüst eine Bootstrap Table. Damit auf die Einträge in der Datenbank zugegriffen werden kann wird das login.inc.php mit den Datenbankzugängen benötigt. Für die Listendarstellung und das eindeutige Zuordnen, werden lediglich die id und der title benötigt.
Mit mb_detect_encoding überprüfe ich, ob der Title, den ich erhalte UTF-8 oder ASCII codiert ist, wenn nicht, formatiere ich ihn hier um komische Sonderzeichen zu vermeiden.

Um eine eindeutige Referenz zusammen zu bekommen, wird in der id der Buttons die id aus der Datenbank übergeben. Den Rest macht dann Ajax und jQuery. Eine sauberere Variante wäre mit einer data-id zu arbeiten, anstatt mit einer id, da wir ja mal gelernt haben, dass id’s eigentlich UNIQUE sein sollten…. 😲

Innerhalb der Buttons werden die Icons von FontAwesome angezeigt.

Damit die Tabelle nach jedem neu hinzugefügten Eintrag gleich aussieht und ich sie nicht doppelt anlegen muss, habe ich dafür ein neues PHP File im Ordner auth mit dem Namen dataTable.inc.php.
Im editLexikon.php mach ich in der section ein include um die Daten Tabelle anzuzeigen.

Eintrag editieren

Das Modal um den Eintrag zu editieren

Nach der Tabelle in editLexikon.php ist das Modal zum Editieren der Einträge eingebunden. Hier wurde wieder ein Standard Modal mit den Formulareinträgen von Bootstrap verwendet. Ein Button explizit für das Modal wird nicht benötigt, da es dynamisch mit Inhalten befüllt wird und das einblenden und ausblenden durch jQuery gesteuert wird.
Die einzelnen Formularfelder müssen jeweils eine eindeutige ID besitzen.

Die 1. Ajax Logik für das Editieren von Einträgen (auth/editLexikon.php)

Die Buttons der einzelnen Einträge haben jeweils eigene Klassen, mit denen die function aufgerufen wird. Für das Editieren wird die Klasse edit_data verwendet. (Siehe zwei Screenshots weiter oben).
Um den richtigen Eintrag in der Datenbank zu finden, benötigen wir die id, die in die Variable entry_id gespeichert wird. Das console.log() ist nur zum Debugging notwenig.
Im Ajax-Teil an sich wird mit url angegeben, welches File aufgerufen wird, mit welcher method die Daten verschickt werden sollen und welche Daten data mitgeschickt werden sollen. Als dataType erwartet sich die Funktion im Erfolgsfall einen json-String.
Im Falle, dass die Daten richtig zurück kommen (success: function (data) {}) wird der Value der ankommenden Daten der ID im Modal zur Editierung zugeordnet. (Deshalb ist es wichtig, jedem input und textarea im Modal eine eindeutige ID zu geben.) Anschließend wird das Modal mit der ID add_data_Modal (also das Modal aus dem Screenshot davor) angezeigt mit .modal('show');
Sollte etwas nicht klappen, wird der Fehler in der Konsole ausgegeben.

Den zu bearbeitenden Datensatz aus der Datenbank holen und als JSON zurück geben (auth/fetch.php)

Vorab: der gesamte auskommentierte Bereich ist hilfreich, wenn die Daten nicht im Modal angezeigt werden. Damit kann ich den Fehler eingrenzen. Der Code wird NUR zum Debugging gebraucht.

Auch hier benötige ich wieder mein login.inc.php mit den Datenbankzugängen, da ein bestimmter Eintrag in der Datenbank gesucht wird.
Mit DISTINCT nach dem SELECT werden Redundanzen, die in einer Tabelle auftreten können, eliminiert und die Werte werden jeweils nur einmal angezeigt.
Weitere Informationen hierzu: https://www.datenbanken-verstehen.de/sql-tutorial/sql-distinct/

Da ein JSON-String erwartet wird, muss der Datensatz noch mit json_encode(); formatiert werden.

Die Ajaxlogik um die geänderten Daten abzuschicken (auth/editLexikon.php)

Jetzt ist das Modal mit den Inhalten die geändert werden soll aufgegangen. Um die Daten auch zu ändern ohne die Seite neu zu laden wird auch hier mit Ajax gearbeitet. Durch den Klick auf den Button mit id="insert" wird die nächste Funktion aufgerufen.
Informationen zu .preventDefault();:
https://www.mediaevent.de/javascript/event-handler-default-verhindern.html
https://wiki.selfhtml.org/wiki/JavaScript/DOM/Event/preventDefault

Bevor die Daten über Ajax abgeschickt werden, findet eine einfache Validierung statt, ob wirklich alle Felder ausgefüllt wurden. Wenn dem so ist, geht der POST zum url: "insert.php";

Mit .serialize() werden die Formularelemente als Zeichenfolge übermittelt. Als Spielerei wird vor dem Absenden noch der Text vom Button geändert.

Wenn alles erfolgreich war success: function(data) { ... } wird das Formular zurückgesetzt (d.h. die Formularfelder werden gelöscht), das Modal geschlossen und der geänderte Datensatz in der Tabelle eingefügt.

Die Abspeicherung in der Datenbank (auth/insert.php)

Auch hier wird gestartet, indem das File mit den Datenbankverbindungen integriert wird. Wenn der $_POST nicht leer ist, werden zwei Variablen mit einem leeren String angelegt. Hier wird später die Erfolgsmeldung hineingespeichert.

mysqli_real_escape_string() maskiert spezielle Zeichen innerhalb eines String unter Berücksichtigung des aktuellen Zeichensatzes.
Genauere Info: https://www.php.net/manual/de/mysqli.real-escape-string.php

Der var_dump() dient hier nur zum Debuggen.
Wenn eine id im $_POST vorhanden ist, wird der zugehörige Eintrag mit den neuen Parametern mittels dem alt bekannten Prepared Statement aktualisiert.

Wenn das UPDATE den Wert true liefert, wird einerseits eine Erfolgsmeldung in die Variable $output gespeichert und zum anderen alle Einträge aus der content Tabelle ausgelesen. Mit denen die Tabelle neu befüllt wird, die die vorhandene im editLexikon.php ersetzt. Damit muss die Seite nicht neu geladen werden, um den neuen bzw. aktualisierten Eintrag anzuzeigen. Der User hat so das Gefühl, der Eintrag erscheint ….

Eintrag löschen

auth/editLexikon.php – Delete Button

Der Button zum Löschen eines Eintrages unterscheidet sich nur wenig vom Button zum Editieren. Wichtig hier ist, dass der Button die Klasse delete_data besitzt mit der die dazugehörige Funktion aufgerufen wird.

auth/editLexikon.php – Delete Modal

Das dazugehörige Modal ist wieder ein Bootstrap Modal. Vor dem Löschvorgang wird dem User noch einmal der gesamte Inhalt präsentiert, nach dem Motto: „Das ist es was du löschen willst. Bist du dir sicher?“

Anmerkung: Die Einrückungen sind nicht ganz sauber von mir 😅 und es wäre von Vorteil dem Button, der für das Löschen zuständig ist eine andere Klasse als btn-default zugeben… Zum Beispiel: btn-danger

auth/editLexikon.php – Delete Ajax

Wie beim Editieren von Einträgen gibt es auch hier wieder zwei Funktionen. Die erste wird aufgerufen, wenn auf den Button mit dem Mistkübel geklickt wird, die Zweite wenn der Löschvorgang bestätigt ist.

In der ersten Funktion $(document).on('click', '.delete_data', function() { ... }); wird über das fetch.php der Eintrag aus der Datenbank geholt und in das Modal eingefügt.

Die zweite Funktion $(document).on('click', '#delete_form', function() { ... }); schickt den endgültigen Befehl an das auth/delete.php File. Der Rest ist fast identisch mit dem Edit Modal.

auth/delete.php

Wie gehabt: Die Datenbankverbindung wird inkludiert.
Wenn der $_POST nicht leer ist und die entry_id vorhanden ist, wird weitergemacht. Je nach dem ob ein Bild mit abgespeichert ist oder nicht, wird gegebenenfalls das Bild noch gelöscht (sonst müllen wir uns den Platz noch zu).

Wenn es bis hier keine Fehler gibt, wird der Eintrag aus der Datenbank über ein Prepared Statment gelöscht.

Der Rest ist wieder gleich wie beim Editieren von Einträgen.

Das ganze editLexikon.php File