Suchformular Auswertung (mit komplettem PHP-Code)

Formular wird ausgefüllt, Abschicken wird gedrückt

Ich setze mal voraus, daß ein wenig Grundwissen in PHP-Formularen vorhanden ist, der Code für das Formular kommt später, jetzt geht es erstmal ums Prinzip. Ich zeige nur mal exemplarisch den Code für das Dropdown-Feld für die Fitness:

echo ‚Fitness auswählen:‘;
        echo „<select name = ‚auswahl_fitness‘>“;
            echo „<option value=’%‘>egal</option>“;    
            echo „<option value=’Anfänger‘>Anfänger</option>“;
            echo „<option value=’Freizeitsportler‘>Freizeitsportler</option>“;
            echo „<option value=’Profi‘>Profi</option>“;

        echo “    </select><br>“;

Das Schlüsselwort „select“ definiert ein Dropdown-Feld, die „options“ sind die einzelnen Einträge. Die „values“ entsprechen genau unseren möglichen Einträgen in der Mitgliederstamm-Tabelle.

Jetzt kommt die Action

Der Benutzer wählt also im Dropdown-Feld seine Fitneß aus und macht seine Häkchen bei den anderen Optionen. Dann klickt er auf „Abschicken“, und erst jetzt tritt unser PHP-Skript wirklich in Aktion. Die Benutzereingaben werden aus den Formularfeldern abgegriffen und auf Variable gelegt. Ich belege alle NICHT angekreuzten Optionen auch gleich mit einem % (Prozentzeichen), das ist der Platzhalter für eine beliebige Zeichenfolge in MySQL. Das ist mal der erste Schritt.

Ob der Button „Abschicken“ gedrückt wurde, fragte man mit dem ISSET-Befehl ab, ich setz den mal hier nur mit der ersten Variablenbelegung für die Fitness rein:

if ( isset($_POST[„senden“]) ) {

(…hier kommt die Variablenbelegung mit den Formularinhalten…)

$akt_auswahl_fitness = $_POST[‚auswahl_fitness‘];

}

Zugriff auf die Datenbank – der Select

Damit aus den Benutzereingaben jetzt auch eine Ausgabe wird, müssen wir natürlich auf unsere Datenbank zugreifen, denn in der stecken ja alle relevanten Informationen. Wir machen das wieder mit einem wpdb-Objekt, wie gewohnt, und basteln uns aus den Variablen mit den Benutzereingaben den passenden Select zusammen. Der wird am Ende in etwa so aussehen:

$alleposts = $wpdb->get_results( „SELECT * from „.MAINTABLE.“
                                        JOIN wp_posts

ON „.MAINTABLE.“.id = SUBSTRING_INDEX( wp_posts.post_title,‘ ‚,1)
                                        WHERE wp_posts.post_status LIKE ‚publish‘                        
                                        AND „.MAINTABLE.“.fitness LIKE ‚“.$akt_auswahl_fitness.“‚
                                        AND „.MAINTABLE.“.tagesfreizeit LIKE ‚“.$akt_auswahl_tagesfreizeit.“‚
                                        AND „.MAINTABLE.“.turnen LIKE ‚“.$akt_auswahl_turnen.“‚
                                        AND „.MAINTABLE.“.aerobic LIKE ‚“.$akt_auswahl_aerobic.“‚
                                        AND „.MAINTABLE.“.fussball LIKE ‚“.$akt_auswahl_fussball.“‚
                                        AND „.MAINTABLE.“.basketball LIKE ‚“.$akt_auswahl_basketball.“‚
                                        AND „.MAINTABLE.“.feierabend LIKE ‚“.$akt_auswahl_feierabend.“‚
                                        AND „.MAINTABLE.“.wochenende LIKE ‚“.$akt_auswahl_wochenende.“‚
                                        „);

Das sieht jetzt erstmal schlimm aus, ist aber gar nicht so kompliziert. Erklärung folgt etwas später.

Zwischenbemerkung: ich hab mal kurz eine Neuerung im Join eingeführt

Wir hatten für die Mitglieder-ID ein benutzerdefiniertes Feld in jedem Beitrag eingeführt, erinnern sie sich? Und dann habe ich noch die Regel eingeführt, daß jeder Beitrag mit der ID und dem Vornamen des Mitglieds betitelt wird, also etwa „1 Ferdinand“ oder „9 Ivonne“. Das war doppelt gemoppelt, wenn man die Benennung der Beiträge konsequent durchführt und immer die richtige ID-Nummer angibt, kann man sich das benutzerdefinierte Feld glatt sparen und die ID aus dem Beitragstitel extrahieren. Dazu schneidet man den Beitragstitel einfach beim ersten Vorkommen eines Leerzeichens ab, das passiert hier mit der Anweisung:

SUBSTRING_INDEX( wp_posts.post_title,‘ ‚,1)

Übrig bleibt die numerische ID, und auf die kann man einwandfrei joinen. Voraussetzung ist wie gesagt, daß man beim Anlegen der Mitglieds-Beiträge konsequent arbeitet und immer die richtige ID angibt.

Die WHERE-Klausel

Die wird ziemlich lang, weil wir natürlich für jedes Feld aus dem Suchformular eine Bedingung haben. Ich nehm mal die erste raus:

WHERE wp_posts.post_status LIKE ‚publish‘                        
                                        AND „.MAINTABLE.“.fitness LIKE ‚“.$akt_auswahl_fitness.“‚

Den post_status LIKE ‚publish‘ brauchen wir, damit uns wirklich nur die veröffentlichten Mitgliedsbeiträge ins Netz gehen.

Die nächste Bedingung (mit AND drangehängt) vergleicht einfach nur, ob der Wert des Feldes „fitness“ gleich dem ist, den wir in der Variable $akt_auswahl_fitness gespeichert haben. Dieser Wert kommt natürlich aus dem Dropdown-Feld des Formulars, und kann „%“ für „egal“ enthalten, oder er ist mit einer der drei anderen Möglichkeiten (Anfänger, Freizeitsportler, Profi) belegt. Damit fischen wir uns alle Mitglieder-Datensätze heraus, die der aktuellen Auswahl Fitness entsprechen.

Die zweite Bedingung lautet:

 AND „.MAINTABLE.“.tagesfreizeit LIKE ‚“.$akt_auswahl_tagesfreizeit.“‚

Im Tabellenfeld tagesfreizeit kann nur „ja“ oder „nein“ drinstehen, und unsere Variable $akt_auswahl_tagesfreizeit aus dem Formular enthält entweder ein „ja“ oder ein „%“ für egal, damit kriegen wir alle mit Tagesfreizeit oder alle bei denen der Benutzer nichts angewählt hat.

Und so gehts lustig weiter, immer mit „AND“ drangehängt die nächste Bedingung mit dem nächsten Datenbankfeld und der nächsten Variablen, bis wir die Liste durch haben. War doch jetzt nicht so schwer, oder?

Die Ausgabe

Jetzt fehlt noch die Ausgabe, aber da gibts nicht viel Neues zu erzählen, das machen wir ganz einfach wieder mit einer Foreach-Schleife über das Ergebnis unseres Selects, die könnte zum Beispiel so ausehen, als Tabelle formatiert:

echo „<table>“;    
    
    // Titelzeile ausgeben
    echo „<tr><td>Turnen</td><td>Aerobic</td><td>Fußball</td><td>Basketball</td><td>Tagesfreizeit</td><td>Feierabend</td><td>Wochenende</td><td>Vorname</td><td>Nachname</td><td>Fitness</td><td>Paßfoto</td><td>Link</td></tr>“;
    
    //Eine Zeile pro Datensatz ausgeben
    foreach ( $alleposts as $einpost ) {
        echo „<td>“.$einpost->turnen.“</td>“;
        echo „<td>“.$einpost->aerobic.“</td>“;
        echo „<td>“.$einpost->fussball.“</td>“;
        echo „<td>“.$einpost->basketball.“</td>“;
        echo „<td>“.$einpost->tagesfreizeit.“</td>“;
        echo „<td>“.$einpost->feierabend.“</td>“;
        echo „<td>“.$einpost->wochenende.“</td>“;
        
        echo „<td>“.$einpost->vorname.“</td>“;        
        echo „<td>“.$einpost->nachname.“</td>“;
        echo „<td>“.$einpost->fitness.“</td>“;
         // Link zum Mitgliedsbeitrag ausgeben
        echo „<td><a href =“.$einpost->guid.“>Zum Mitgliedsbeitrag</<a></td>“;
       
        echo „</tr>“;

    } //end foreach

echo „</table>“;

Haben wir alles schon gehabt, dazu muß ich glaube ich nicht viel erzählen. Hat doch Spaß gemacht, nicht wahr? Auch wenn es jetzt weniger mit WordPress und mehr mit PHP und MySQL zu tun hatte.

Kompletter Code des Suchformulars

Den gibt es hier als gezipptes PHP-Skript. Es sind noch etliche Debug-Ausgaben mit drin, aber die kann sich jeder selber rauskommentieren.

Suchformular als ZIP-Datei

Sportpartner Suche – die Anforderungen

Sportpartnersuche Online

Ich hatte ja früher schon erwähnt, daß der Turnverein Weiß-Blau seinen Mitgliedern einen besonderen Service anbieten möchte, und zwar die gezielte Suche nach möglichen Freizeitsportpartnern online auf der Homepage des Vereins. Man soll herausfinden können, wer sich z.B. auch für Fußball interessiert, am Wochenende Zeit hat und von der Fitneß her auch Anfänger ist. Damit das klappt, müssen wir natürlich eine Möglichkeit schaffen, daß man die gewünschten Suchkriterien online eingeben kann, und das geschieht mit Hilfe eines PHP-Formulars für die Benutzereingaben.

Das Suchformular

Das Suchformular kann natürlich nur das wiederspiegeln, was in unserer Mitgliederstamm-Tabelle auch drin ist, aber das ist ja gar nicht so wenig. Wir haben drei Stufen für die Fitneß (Anfänger, Freizeitsportler, Profi), wir haben vier Sportarten zur Auswahl, und wir haben drei mögliche Kriterien für die verfügbare Freizeit. Im ersten Ansatz kann das Suchformular also so aussehen:

suchformular

suchformular

Für die Fitneß habe ich ein Dropdown-Feld gewählt und zusätzlich die Auswahl „egal“ (für alle Fitneß-Angaben) eingefügt, bei den Sportarten und den Angaben zur Freizeit ist eine Mehrfachauswahl möglich. Wenn man seine Auswahl getroffen hat, klickt man auf den Button „Abschicken“ – ja und dann? Dann wirds programmiertechnisch erst richtig interessant, dann sollen nämlich alle Mitglieder ausgegeben werden, auf die die getroffene Auswahl zutrifft. Wie das programmiertechnisch gelöst wird, dazu gibts einen neuen Beitrag.

Privatsphäre für personenbezogene Daten: das Plugin Secret Content

Adressdaten und Datenschutz

Jetzt haben wir also unser schönes Mitgliederverzeichnis mit allen Adressdaten und freuen uns darüber – aber mal langsam, so geht das „in echt“ natürlich nicht. Man kann nicht einfach Fotos und persönliche Daten von echten Personen ins Internet stellen und blind darauf vertrauen, daß schon nieman Schindluder damit treiben wird. Also muß ein Schutzmechanismus her, und genaugenommen müssen wir auch die Datenschutzerklärung (die auf dem Anmeldeformular) erweitern. Wie gehen wir das an?

Wir nutzen das WordPress-Login

Eine einfache Lösung ist es, unser Mitgliederverzeichnis nur für eingeloggte WordPress-Benutzer sichtbar zu machen. In unserem Fall ist das erstmal nur ich, der Admin, weitere Benutzer gibt es noch nicht (Werden wir aber noch brauchen, später, für die versprochene Suche nach Sportpartnern). Wie stellen wir es also an, daß unser Mitgliederverzeichnis nur für eingeloggte User sichtbar ist?

Das PluginSecret Content

Plugin-Seite: https://de.wordpress.org/plugins/secret-content/

Ich liebe Werkzeuge, die genau einen speziellen Zweck erfüllen und keinen Schnickschnack mitschleppen. Das Plugin Secret Content macht genau ein Ding: es ermöglicht einem, auf jeder Seite und auf jedem Beitrag anzugeben, daß sie nur für eingeloggte Benutzer sichtbar sein sollen. Nach Installation und Aktivierung des Plugins gibt es ein zusätzliches Fensterchen rechts oben im Editor, wo man anwählen kann, ob die Seite oder der Beitrag nur für eingeloggte Benutzer sichtbar sein soll.

secretcontent

secretcontent

Häkchen reinsetzen, speichern, fertig. Seite ist unsichtbar, wenn man nicht eingeloggt ist. Das wars! Das Plugin ist zwar seit über zwei Jahren nicht aktualisiert worden, aber es funktioniert einwandfrei, wieso sollte man daran was verbessern wollen?

Datenschutzerklärung anpassen nicht vergessen

Man muß das schon genau nehmen mit dem Schutz der personenbezogenen Daten, und deshalb müßten wir auch unsere Datenschutzerklärung auf dem Anmeldeformular anpassen, sobald wir echte Personendaten verwalten. Da gehört noch ein Passus hinein, daß Fotos und Adressdaten für andere Vereinsmitglieder sichtbar sind, wenn sie auf der Vereinsseite eingeloggt sind. Wie man das am Besten formuliert – ich würde im Echtfall einen Anwalt fragen, ganz ehrlich.

So, aber jetzt gehts weiter mit ein bißchen Spiel und Spaß mit PHP, wir machen uns an das Sportpartner-Suchformular, und dafür gibt es einen neuen Beitrag.

Mitgliederverzeichnis mit Adressdaten

Wir basteln uns ein Mitgliederverzeichnis

Damit wir von unserer tabellarischen Ausgabe zu einem vernünftigen Mitgliederverzeichnis komplett mit Fotos kommen, ist ein wenig Handarbeit angesagt, wie immer, wenn man es in WordPress mit einzelnen Beiträgen zu tun hat. Aber keine Bange, wir machen nur das absolute Minimum. Jetzt knüpfen wir uns die neuen Mitglieder der Reihe nach vor und legen uns zu jedem Mitglieds-Datensatz einen eigenen Beitrag an.

Dazu folgende Vorüberlegungen:

  1. Wenn wir den Beitrag einfach mit Vorname und Name des Mitglieds betiteln, kann es zu Konflikten kommen, schließlich können wir mehr als einen „Peter Müller“ oder „Stefan Huber“ in unserer Mitgliederliste haben. Also stellen wir dem Namen einfach die automatisch vergebene id aus der Tabelle mitglieder_stamm voran, dann haben wir Eindeutigkeit. Und weil unsere Mitglieder untereinander per Du sind, verzichten wir auf den Nachnamen und sparen uns Tipparbeit. Unser erster Beitrag erhält also den Titel „1 Ferdinand“, der zweite wird „2 Marius“ heißen, der dritte „3 Ivonne“ usw., einfach der Reihe nach durch.
  2. Das Paßfoto laden wir als Beitragsbild hoch (rechts unten im Beitragseditor bei „Beitragsbild festlegen“), dann haben wir für spätere Ausgaben Zugriff über darauf. Auch das haben wir schon mal gemacht, mit wp_get_attachment_url(get_post_thumbnail_id(post_ID))
  3. Wir legen 1 benutzerdefiniertes Feld an, das heißt „mitglied_id“ und erhält als Inhalt (na was wohl?) unsere eindeutige id.
mitglied_id

mitglied_id

4. Wenn wir den Beitrag für ein neues Mitglied vollständig angelegt haben, könnten wir das Feld „status“ in der Tabelle mitglieder_stamm von „neuzugang“ auf „aktiv“ stellen – jaja ich hörs schon, das sollte man programmgesteuert mit einem Update machen, aber wir operieren hier gerade mal auf einer Handvoll Testdaten, da reicht der manuelle Eintrag. Soll ja auch nur beispielhaft zeigen, daß der Bearbeitungsstand eines Mitgliederdatensatzes durch den Status mitprotokolliert werden kann.

Das wars schon! Den Rest holen wir uns aus der Datenbank, aber ich hol mir mal einen frischen Kaffee während sie die Beiträge anlegen 🙂

Vorüberlegung: was wollen wir im Mitgliederverzeichnis alles ausgeben?

Na, alles! Die kompletten Adressdaten, die sportlichen Präferenzen, das Paßfoto, den ganzen Summs möchten wir im Mitgliederverzeichnis sehen, ohne auch nur ein einziges weiteres Datenfeld manuell eingeben zu müssen. Uns reicht das benutzerdefinierte Feld mitglied_id, darüber verknüpfen wir uns die ganze Tabelle mitglieder_stamm und basteln uns die gewünschte Ausgabe.

Wie sieht es jetzt aus?

Das ist leider sehr abhängig vom Theme und läßt sich nicht so global sagen. Aber wenn sie jetzt auf ihre Beitragsseite gehen, müßten eigentlich die Beitragsbilder(Paßfotos) und die eingegebenen Beitragstitel (1 Ferdinand, 2 Marius…) aufgelistet werden. Manche Themes geben allerdings die Thumbnails (Beitragsbilder) in der Übersicht gar nicht mit aus. Wenn wir jetzt auf einen Beitragstitel klicken, sehen wir – nichts. Völlig korrekt, wir haben ja auch keinerlei Beitragstext eingegeben. Und unser benutzerdefiniertes Feld mitglied_id sehen wir auch nicht, weil es noch nicht in das Template mit eingebunden ist. Also, an die Arbeit. Wenn sie genau nachvollziehen wollen, an welcher Stelle welche Anpassungen wie greifen, wäre es sinnvoll, wenn sie das selbe Theme wie ich verwenden, es ist ein Child-Theme von Twentyfourteen.

Unsere Anpassungen an der single.php

Für die Darstellung der einzelnen Beiträge wird die single.php verwendet, und die nehmen wir uns jetzt vor. Machen sie eine Kopie der Originaldatei, legen sie sie in ihrem Child-Theme-Ordner ab und öffnen sie sie in einem Editor. Unsere Anpassungen erfolgen innerhalb des Loops, unmittelbar vor der Previous/next post navigation, hier im Screenshot wirds deutlich:

innerhalb_des_loops

innerhalb_des_loops

Geben sie hier mal zum Testen nur die einzige Echo-Zeile ein und schauen sie sich einen Beitrag an, da darf nichts stehen ausser dem Text des echo.

Wie kriegen wir jetzt unsere Stammdaten hier rein?

Über eine Verknüpfung mit der Tabelle mitglieder_stamm über das benutzerdefinierte  Feld mitglied_id. Wir geben als allererstes mal nur die mitglied_id aus, das machen wir so:

echo "<h2>Mitgliederdaten</h2>";
                    $akt_mitglied_id = get_post_meta($post->ID, 'mitglied_id', true);
                    echo "Aktuelle Mitglied ID:&nbsp".$akt_mitglied_id."<br>";

Der Witz steckt natürlich in der Funktion get_post_meta, die holt uns zur aktuellen WordPress-ID des Beitrags den Wert des benutzerdefinierten Feldes mit dem Namen „mitglied_id“. Das „true“ bewirkt, daß ein einzelner String ausgegeben wird, mehr brauchen wir nicht.

Jetzt müssen wir noch angeben, aus welcher Tabelle wir die Daten holen wollen, dazu lege ich den Tabellennamen wieder auf eine Konstante, damit man ihn später leicht auswechseln kann, und gönne mir noch eine Debug-Ausgabe.

/*****Haupttabelle Name als Konstante definieren*******/
                    define("MAINTABLE","mitglieder_stamm");                    
                    echo "Aktuelle Tabelle =&nbsp".MAINTABLE."<br>";

Und jetzt haben wir schon alles, was wir für unseren Select brauchen! Der sieht so aus:

$alleposts = $wpdb->get_results( "SELECT * from ".MAINTABLE."
 WHERE id = '".$akt_mitglied_id."'");

Und schon haben wir den richtigen Datensatz anhand der Mitglieds-id herausgefischt! Die Ausgabe der einzelnen Felder erfolgt dann wie gehabt wieder mit einer Foreach-Schleife, ich gebe hier mal beispielhaft nur ein paar Felder aus:

foreach ( $alleposts as $einpost ) {             
                            
                            echo $einpost->vorname."<br>";
                            echo $einpost->nachname."<br>";
                            echo $einpost->ort."<br>";
                            echo $einpost->strassehausnummer."<br>";
                    }

Das Ergebnis

…ist noch nicht besonders hübsch formatiert, aber es zeigt das Prinzip:

maja_daten

maja_daten

Am schönsten sähe es natürlich aus, wenn man die Stammdaten tabellarisch ausgibt, aber das kann sich jeder selber einrichten wie er es möchte. Jedenfalls haben wir übere unsere Verknüpfung mit der mitglied_id Zugriff auf alle Datenfelder der Tabelle mitglieder_stamm, und das war ja genau das, um was es ging. So simpel ist die Lösung mit einer eigenen Tabelle für die Mitgliederdaten!

Klarer Vorteil gegenüber den benutzerdefinierten Feldern

Ausser der mitglied_id muß im Beitrag nichts per Hand eingegeben werden, das erspart einem einen Haufen (fehlerträchtiger) Handarbeit. Stellen sie sich nur mal vor, sie müßten jetzt zu allen Mitgliedern die vollständigen Adressdaten händisch in Custom Fields erfassen – also nee, echt nicht. Das haben wir eleganter gelöst. Und wenn es mal Änderungen an den Benutzerdaten geben sollte, auch die können wir in unser eigenen Tabelle mitglieder_stamm einpflegen, wir müssen dazu nicht den entsprechenden Beitrag bearbeiten. Auch das ist ein weiterer Vorteil, der nicht zu unterschätzen ist. Man kann sich auch mit PHP einen kleinen Mitgliederdaten-Editor basteln, vielleicht mach ich das später mal, das führt jetzt wirklich zu weit. Und jetzt viel Vergnügen beim individuellen Einbinden und Formatieren ihrer Felder!

Turnverein die erste Liste: Mitglieder-Adressen

Ausgabe Adressenliste

Alle alten Programmierer lieben Listen, und wir können uns aus unseren schönen Stammdaten schon eine erste Ausgabe bauen: Namen, Adressen und Telefonnummern nämlich, da brauchen wir gar nichts weiter dazu als unser gutes altes Arbeitspferd PHP Code for Posts. Unsere eigene Tabelle mitglieder_stamm kann nämlich vom $wpdb-Objekt genau so angesprochen werden wie die WordPress-eigenen Tabellen, liegt ja in der selben Datenbank.

Tabelle als Konstante definieren

Da wir ja ganz am Ende wieder auf unsere Originaltabelle savecontactform7_1 switchen wollen, lege ich den Namen der aktuellen Tabelle auf eine Konstante und gebe den Tabellennamen im Kopf mit aus, damit wir wissen wo wir arbeiten.

/*****Haupttabelle Name als Konstante definieren*******/
 define("MAINTABLE","mitglieder_stamm");

echo "<h2>Mitglieder Adressenliste</h2>";

echo "Aktuelle Tabelle =&nbsp".MAINTABLE."<br>";

Der Select ist dann ganz simpel:

global $wpdb;
        $alleposts = $wpdb->get_results( "SELECT * from ".MAINTABLE."");

Ausgabe als Tabelle

Wie gewohnt mit einer Foreach-Schleife, das haben wir schon oft genug gemacht, da spare ich mir jetzt nähere Kommentare:

foreach_adressen

foreach_adressen

Das reicht schon, wir bekommen jetzt alle eingegebenen Testdaten tabellarisch angezeigt.

adressenliste

adressenliste

Das war jetzt zu einfach, nicht wahr? Bitte sehr, wir erweitern unsere Möglichkeiten jetzt gleich kräftig, aber dazu gibts einen neuen Beitrag.

Turnverein: die Mitglieder-Stammdaten

Woher kommen die Daten?

Wie im vorigen Artikel bereits angesprochen, gibt es ein in Contact Form 7 erstelltes Anmeldeformular, das wird für die Erfassung aller Mitgliederdaten genutzt. Hacken sie einfach ein paar Testmitglieder mit unterschiedlichen Sportarten und Freizeitoptionen ein, so fünf bis zehn Stück reichen für den Anfang. Contact Form 7 schickt ihnen zu jedem erfaßten Formular ein E-Mail mit den zugehörigen Daten. Wir brauchen hier aber nur das Paßfoto, das als Attachment mitgeschickt wird, die anderen Daten werden in einer MySQL-Tabelle automatisch gespeichert.

Speichern der Formulardaten in einer Tabelle

Das zusätzliche Plugin Save Contact Form 7 sorgt dafür, daß die Formulardaten in einer Tabelle landen, mit der wir später weiterarbeiten können. Diese Tabelle heißt default-mässig savecontactform7_X, wobei X eine laufende Nummer ist. Da wir nur ein Kontaktformular haben, ist das die Nummer 1, folglich heißt unsere Tabelle savecontactform7_1. Von der machen wir uns zunächst einmal eine Kopie: das geht im phpmyadmin unter „Operationen“, wir kopieren Struktur und Daten und geben der Tabelle einen aussagekräftigen Namen, die heißt jetzt mitglieder_stamm. Das wird unsere Arbeitstabelle. Warum eine Kopie? Weil wir noch am Testen sind. Im Real-Betrieb arbeitet man mit der „echten“ Tabelle, damit man neu angemeldete Mitglieder auch in Echtzeit mitkriegt. Wir nutzen jetzt erstmal die Kopie unserer Mitglieder-Stammdaten und haben ein bißchen Spaß auf der Datenbank!

Struktur der Tabelle mitglieder_stamm

In der Tabellenstruktur spiegelt sich 1:1 unser Formular wieder:

mitglieder_stamm_struktur

mitglieder_stamm_struktur

Ich geh mal von oben nach unten:

  1. id wird von contact form 7 automatisch fortlaufend vergeben, das wird unser Schlüssel, die Mitglieds-Nummer
  2. created_on Timestamp, wird von CF7 automatisch vergeben, brauchen wir eigentlich nicht
  3. status das hab ich glatt unterschlagen: ich nutze das Plugin CF7 Dynamic Text Extension um ein „hidden“-Feld mitzugeben, das erhält defaultmäßig den Wert „neuzugang“. Wir werden später noch sehen, wozu wir das brauchen.
  4. die restlichen Felder: sind 1:1 die selben wie in unserem Formular, das ist keine Hexerei.
  5. Das Feld zustimmung brauchen wir nur für die Datenschutzerklärung, das sieht in CF7 so aus:
datenschutzerklaerung

datenschutzerklaerung

Die muß mit rein, schließlich erheben wir personenbezogene Daten!

So, das wars schon. Ready to go, Testdaten drin? Dann gehts zur ersten Ausgabe im nächsten Beitrag.

Der Turnverein Weiß-Blau: jede Menge Spaß mit eigenen Tabellen

Über den TV Weiß-Blau

Der kleine fiktive  Vorort-Turnverein im Münchner Norden möchte WordPress für seinen Webauftritt verwenden. Die informativen Seiten (Über den TV-Weiß-Blau, Vereinsangebot) sind schnell angelegt. Dann kommt noch ein Registrierungsformular für neue Mitglieder dazu, das machen wir mit Contact Form 7 und nutzen gleich noch Save Contact Form 7 um die Daten den prospektiven Mitglieder direkt in der MySQL-Datenbank zu speichern. Save Contact Form 7 erzeugt zu jedem neuen abgeschickten Formular eine fortlaufende ID, die wird unsere Mitgliedsnummer.

Unser besonderer Service: finden sie ihren individuellen Freizeitsport-Partner!

Und weil wir mit dem Registrierungsformular so schöne Daten abfragen (Beispiel kommt noch) möchten wir als besonders „Zuckerl“ für unsere Mitglieder einen super Service anbieten: man kann nach geeigneten Sportpartnern suchen! Wer hat am Abend oder am Wochenende Zeit, wer ist in meiner Leistungsgruppe oder Größenklasse, wer hat Interesse an Basketball oder Tennis – das wird der ganz besondere Service für den Verein und hebt unser Angebot von der Konkurrenz ab.

Das Datenmodell in WordPress und Contact Form 7

… ist denkbar einfach. Wir legen für jedes Vereinsmitglied einen Beitrag an, da kommt noch ein Paßfoto mit dazu, und das wars auch schon. Alle anderen relevanten Daten bekommen wir aus unserem Registrierungsformular. Das haben wir mit Contact Form 7 schnell erstellt. Im ersten Teil werden die persönlichen Daten und die Adresse abgefragt:

anmeldeformular_adressdaten

Nichts weiter ungewöhnliches, interessanter wirds da schon im zweiten Teil, da werden Infos zu den sportlichen Aktivitäten abgefragt:

fitness_sportarten

fitness_sportarten

Der Größenbereich erlaubt die Auswahl „unter 170“, „170-180“ und „über 180“. Bei „Fitneß“ kann man Anfänger, Freizeitsportler oder Profi auswählen, die anderen Formularfelder sind eigentlich selbsterklärend. Warum habe ich bei „Verfügbarkeit“ und „Sportarten“ Radiobuttons mit ja/nein gewählt, und keine Optionsgruppen? Weil die Daten so schöner auszuwerten sind, das wird man später noch sehen.

Woher kommen nun die Daten?

Alle diese wertvollen Daten erhalten wir einfach dadurch, daß Anmeldeformulare ausgefüllt und abgeschickt werden. Wenn sich jemand persönlich vor Ort oder auf traditionell schriftlichem Weg im Verein anmeldet, werden die persönlichen Daten halt auch einfach über das Kontaktformular erfaßt, ist ja egal wer die eingibt. Jedenfalls haben wir so schnell einen kleinen Stammdaten-Pool beieinander, mit dem wir arbeiten können.

Kleine Anmerkung zur tabellarischen Darstellung in CF7

Wie bringt man CF7 dazu, eine Gruppe mit Radiobuttons vernünftig formatiert darzustellen? Bin ich gefragt worden, gebe ich gern Auskunft. Man packt sie in eine Tabelle, das sieht dann im Entwurf so aus:

cf7_tabellen

cf7_tabellen

Das aber nur als kleiner Layout-Tipp am Rande. Im nächsten Artikel geht es weiter mit unseren Mitgliederdaten.

 

Eigene Tabellen – schließlich heißt es „MeinSQL“

MySQL läßt sich so schön übersetzen

Mir gefällt auch die Semantik: das ist „Mein SQL“, hier kann ich schalten und walten wie ich will, kann Tabellen und Abfragen anlegen und verknüpfen, kann sortieren und inserten und updaten nach Lust und Laune, und Open Source und kostenlos ist es obendrein. MySQL bietet wirklich unbegrenzte Möglichkeiten und ist flexibel ohne Ende. Über den genialen phpMyAdmin steht auch eine professionelle Verwaltungsoberfläche zur Verfügung, die keine Wünsche offenläßt. Also, warum nutzen wir dann dieses Potential nicht zur Erweiterung von WordPress?

Gut gemeint, bedingt brauchbar: Benutzerdefinierte Felder

Einleitung

Als vor ein paar Jahren die benutzerdefinierten Felder (Custom Fields) in WordPress eingeführt wurden, wurde das als großer Schritt in Richtung CMS hochgelobt und gleich mit -zig Anwendungsbeispielen unterfüttert. Benutzerdefinierte Felder sind dafür gedacht, die Beiträge mit weiteren Daten anzureichern, das kann ganz unterschiedliche Anwendungen haben. Man könnte z.B. in einem Bücherblog die ISBN-Nummer des jeweils besprochenen Buches in ein benutzerdefiniertes Feld eintragen, man könnte in einem kleinen Online-Shop zu einzelnen Artikeln die Preise hinterlegen, man könnte in einem Mitgliederverzeichnis für einen Verein verschiedene Daten zu den einzelnen Mitgliedern abspeichern (Geburtsdatum, Telefonnummer, Adresse).

OK, Feld ist gespeichert. Und jetzt?

Wenn man seine benutzerdefinierten Felder in den Beiträgen auch sehen möchte, muß man sie in den Code der entsprechenden PHP-Datei (z.B. single.php) eintragen, das sieht dann etwa so aus:

<?php get_post_meta($post_id, '$key', $single); ?>

Dabei ist die $post_id natürlich die ID des aktuellen Beitrags, das $key ist der Platzhalter für den Namen des benutzerdefinierten Feldes, und $single weist WordPress an, einen einzelnen String auszugeben (alternativ ginge auch ein Array, wenn ein Custom Field mehrere Werte enthält, aber das lassen wir jetzt mal weg).

Ein Beispiel wäre jetzt hier mal der Preis zu einem Beitrag, der $key wäre hier schlicht „Preis“:

benutzerdefiniert_preis

benutzerdefiniert_preis

Was passiert hinter den Kulissen auf der Datenbank?

In der Tabelle wp_postmeta landet ein neuer Eintrag mit einer laufenden meta_id:

post_meta_custom_field

post_meta_custom_field

Hier wird über die post_id der Name und der Wert des benutzerdefinierten Feldes festgehalten. Der meta_value ist übrigens ein Longtext, also hier können sie jede Menge Text (max. 4.294.967.295 Byte) eingeben!

Sie können allerdings auch jede Menge Unsinn eingeben, statt dem Preis in € das Tagesdatum zum Beispiel, oder auch unsinnige Werte wie „Zwofuffzig“, WordPress ist das egal. Die Nachteile hiervon liegen auf der Hand, und deswegen gibt es auch Plugins, die die Verwaltung von Custom Fields erheblich verbessen.

Das Plugin Custom Field Template

Diese Plugin ermöglicht es, die Eingabebereiche von benutzerdefinierten Feldern einzugrenzen. Mit Hilfe von definierbaren Eingabefeldern, Radio-Buttons, Checkboxes usw. wird es dem Benutzer sehr vereinfacht, sinnvolle Eingaben zu machen. Das ist alles gut und schön und auch sehr professionell gemacht, aber mir gefällt das alles nicht so recht, und ich sage auch gleich, warum.

Wer tippt den ganzen Datenhaufen ein?

Um mal bei dem Anwendungsbeispiel mit dem kleinen Onlineshop zu bleiben: angenommen, man legt für jeden Artikel einen Beitrag an, hübsch mit Bild und kleinem Text. Dann könnte man ein benutzerdefiniertes Feld für den Preis anlegen, vielleicht noch eins für die Artikelnummer, und interessant wäre vielleicht auch der noch Lagerbestand, wieviele Stück noch verfügbar sind. In einem normalen kleinen Laden hat man hierfür zumindest eine Excel-Liste, in der man die ganzen Artikel verwaltet. So, und jetzt kommen die Custom Fields: das soll man alles per Hand einhacken? Nicht in echt, oder?

Oder sehen wir uns mal das Mitgliederverzeichnis eines Vereins an: Miitgliedsnummer, Name, vollständige Adresse, Geburtsdatum, Funktion… da gibt es jede Menge Daten, die hineingehören. Und die soll man alle per Hand erfassen? Ja mir wannsd net gangst, wie man auf bairisch sagt, zu Hochdeutsch: „Das geht ja wohl gar nicht!“

Letztes Beispiel: Bei meiner Modeldatenbank hätte ich zu jedem Model (1 Model=1 Beitrag) sage und schreibe 34 benutzerdefinierte Felder auszufüllen: Körpergröße, Kleidergröße, Schuhgröße, Haarfarbe, Augenfarbe, Oberweite… usw. usf, was halt so alles zu einer Modelsedcard gehört, und das ist eine Menge Holz! Also nee echt nicht, das hacke ich da nicht per Hand rein. Schon gar nicht, weil ich die ganzen Modeldaten eh über ein Contact Form 7-Formular erfasse und sowieso in der Datenbank gespeichert habe.

Und bevor wir jetzt darüber nachdenken, wie man die passenden Einträge zu den benutzerdefinierten Feldern in der wp_postmeta aus unseren Excel-Listen oder MySQL-Tabellen automatisiert erzeiugen könnten – nicht wahr, liebe alte Programmierer, daran habt ihr sofort gedacht! Also, das machen wir NICHT. Wir machen uns das Leben deutlich einfacher.

Wir verwenden eigene Tabellen

Aber dazu gibt es definitiv einen neuen Beitrag, dieser hier ist lang genug geworden.

 

 

 

 

WordPress und die Kategorien: kleine Gruseltour auf der Datenbank

Die Kategorien von WordPress sind ein sehr praktisches und flexibles Werkzeug. Im Prinzip handelt es sich hier um eine 1:n-Beziehung (ein Beitrag kann zu mehreren Kategorien gehören), dazu kommt allerdings noch eine nahezu unbegrenzte Schachtelungstiefe in Unterkategorien, Unter-Unterkategorien und so weiter. Das ist wie gesagt sehr flexibel gelöst, auch wenn ich bezweifle, daß im Normalfall eine Schachtelungstiefe von mehr als drei Kategorie-Ebenen notwendig ist. Die Möglichkeit ist jedenfalls da.

Und wie sieht das auf der Datenbank aus?

WordPress gönnt sich für die Verwaltung der Kategorien drei Tabellen, die alle an einem „term“ im Namen erkennbar sind (warum terms und nicht categories?). Es gibt die wp_terms, in der findet sich recht übersichtlich eine Auslistung aller Kategorien mit term_id und name.

wp_terms

wp_terms

Dann gibt es noch die wp_term_taxonomy, die ist schon weniger durchsichtig. Hier werden über das Feld „parent“ die Zuordnungen zu Unterkategorien verwaltet, und ein Zähler(count) mitgeführt.

wp_term_taxonomy

wp_term_taxonomy

Und schließlich ist da noch die wp_term_relationships, in der erfolgt letztendlich die Zuordnung der Kategorien (anhand der term_taxonomy_id) zu den Beiträgen (object_id). Um also herauszufinden, welche Kategorien zu einem Beitrag gehören, müßte man einen Join über alle drei Tabellen machen, aber das ersparen wir uns.

wp_term_relationships

wp_term_relationships

Warum so kompliziert? Wegen der unbegrenzten (ich habs nicht ausprobiert) Schachtelungstiefe, und weil WordPress hier noch die Möglichkeit der sogenannten „Custom Taxonomies“ offenläßt. Das sind eigene Gruppierungen, die man erstellen und dann ganz genau so wie Kategorien zur Sortierung und Anzeige der Beiträge verwenden kann. Ich hab das mal für eine Taxonomie „Jahreszeiten“ gemacht, die bestand halt dann nur aus „Frühjahr, Sommer,Herbst,Winter“, war aber für ihren Zweck ganz praktisch.

Stattdessen: get_the_category()

Weil uns aber vor lauter unterschiedlichen ids und terms und taxonomies und was weiß ich noch alles schon der Kopf schwirrt, nehmen wir eine einfachere Lösung. Praktischerweise hat WordPress eine eingebaute Funktion, die uns ein Array aller zu einem Beitrag gehörenden Kategorien liefert. Man holt sich das Array über die ID des aktuellen Beitrags. In unserer foreach-Schleife sieht das dann so aus:

$category = get_the_category($einpost->ID);

Jetzt brauchen wir noch eine kleine foreach-Schleife für die Ausgabe des Ergebnis-Arrays, und wir nehmen mal als Trennzeichen noch ein Komma und ein Leerzeichen:

foreach ($category as $eincat){
                    echo $eincat->cat_name.", ";
                }

Damit können wir eine Ausflistung der Kategorien in unsere Beitragsausgabe mit einbauen, bei mir sieht das dann so aus:

alleposts_mit_kategorien

alleposts_mit_kategorien

Kniefiesler werden bemerken, daß das letzte Komma in der Kategorienauflistung überflüssig ist, aber da seh ich mal großzügig darüber hinweg. Ich finde die Beitragsausgabe jetzt eine runde Sache und recht übersichtlich. So man hat, kann man natürlich auch noch das Beitragsbild mit ausgeben, die Anzahl der ausgegeben Beiträge beschränken, ein Order by rand() mit einbauen etc. pp, da kann sich jeder selber spielen wie er mag. Viel Spaß dabei!