Nix für schwache Nerven: wooCommerce-Bestellungen auf der Datenbank

1 Bestellung = 1 Beitrag

Wenn jetzt endlich ein Kunde etwas in unserem Online-Shop gekauft hat, landet die Bestellung – wie könnte es anders sein – in der wp_posts mit dem Post Type „shop_order“. Das schauen wir uns mal ganz kurz an. Ich nehme nur ein paar ausgewählte Felder, sonst wirds unübersichtlich:

SELECT wp_posts.ID, wp_posts.post_author, wp_posts.post_content, wp_posts.post_title, wp_posts.post_status, wp_posts.post_name, wp_posts.post_type, wp_posts.comment_count
FROM wp_posts
WHERE (((wp_posts.post_type) Like „shop_order“));

Ergebnis:

shop_orders

shop_orders

Der post_status scheint noch interessant zu sein, da steht nur einer auf wc-completed, alle anderen auf wc-on-hold. Was ein comment_count von 3 bedeuten soll ist mir allerdings ein Rätsel – und es ist mir schnuppe.

Eine Bestellung, wie viele Einträge in der wp_postmeta?

Wir klemmen uns mal die erste Order-ID, das ist die 42, und gehen in der wp_postmeta suchen, was dazu alles abgespeichert ist. Zur Erinnerung: in der wp_postmeta ist jedem Datensatz die zugehörige post_id aus der wp_posts zugeordnet.

SELECT wp_postmeta.meta_id, wp_postmeta.post_id, wp_postmeta.meta_key, wp_postmeta.meta_value, wp_posts.ID, wp_posts.post_title, wp_posts.post_status, wp_posts.post_type
FROM wp_postmeta INNER JOIN wp_posts ON wp_postmeta.post_id = wp_posts.ID
WHERE (((wp_postmeta.post_id)=“42″) AND ((wp_posts.post_type) Like „shop_order“));

Das – halleluja! Spuckt 48 Datensätze aus. Achtundvierzig. Will heissen, zu Order Nr. 42 hat wooCommerce 48 Einträge in der wp_postmeta angelegt und dort irgendwelche Daten gespeichert. Ich stelle hier mal spaßeshalber eine Liste der Meta-Keys rein:

 

order_42
meta_key
_order_key
_customer_user
_payment_method
_payment_method_title
_transaction_id
_customer_ip_address
_customer_user_agent
_created_via
_date_completed
_completed_date
_date_paid
_paid_date
_cart_hash
_billing_first_name
_billing_last_name
_billing_company
_billing_address_1
_billing_address_2
_billing_city
_billing_state
_billing_postcode
_billing_country
_billing_email
_billing_phone
_shipping_first_name
_shipping_last_name
_shipping_company
_shipping_address_1
_shipping_address_2
_shipping_city
_shipping_state
_shipping_postcode
_shipping_country
_order_currency
_cart_discount
_cart_discount_tax
_order_shipping
_order_shipping_tax
_order_tax
_order_total
_order_version
_prices_include_tax
_billing_address_index
_shipping_address_index
_shipping_method
_recorded_sales
_recorded_coupon_usage_counts
_order_stock_reduced

Hübsch, nicht wahr? Wenigstens haben die wooCommerce_Entwickler recht sprechende Namen für die Meta-Keys verwendet, da kann man sich in den meisten Fällen wenigstens denken, was das sein soll.

Und das sind nur die Einträge zu einer einzigen ausgewählten Bestellung!

Was, wenn ich Auswertungen über die Bestellungen fahren will?

Aber ja verehrtes Publikum, sowas kommt vor. Daß man wissen will, wie viele Bestellungen an einem bestimmten Tag eingegangen sind. Oder wie viele davon per Scheck bezahlt wurden. Oder Bestellungen nach Postleitzahlen geordnet oder oder… sie wissen schon, was da so alles beim Kunden anliegt.

Das hatten wir schon ein paar mal, wenn man aus der wp_postmeta die meta_values zu einer bestimmten ID aus der wp_posts herauskriegen will, muß man pro Meta Key einen Join auf die wp_postmeta anlegen. Würde im Ernstfall hier einen 48fachen Join verlangen, das muß man sich mal so richtig reinziehen…

Eine andere Möglichkeit wäre eine Kreuztabelle (Microsoft Access kann sowas, bei MySQL bin ich mir nicht sicher), aber die hätte dann mehr als 48 Felder, das ist auch eher von der unhandlichen Sorte.

Ja Kruzitürken, haben die noch nie etwas von Fremdschlüsseln und Detailtabellen gehört?

Ein Beispiel wie man’s NICHT macht

Wir nehmen nur mal ein Beispiel:

Beim meta_key _payment_method steht in meinem Datensatz Nr. 42 der meta_value „cheque“. Dann nehmen wir den meta_key _payment_method_title noch mit, der hat den Wert „Scheckzahlung“

Und wenn ich jetzt ein paar Hundert oder Tausend Bestellungen habe, stehen der cheque und die Scheckzahlung eben auch Hundert oder Tausend mal in der wp_postmeta. Das, verehrtes Publikum, ist Redundanz, und zwar so richtig kriminelle Redundanz. So macht man sowas nicht. Da nimmt man eine Detailtabelle mit den Zahlungsarten (Scheck, Nachname, Bar bei Abholung…), von denen kriegt jede eine ID, die wird zu den Bestellungen dann als Fremdschlüssel gespeichert. Das ist Datennormalisierung für Anfänger, erstes Semester.

Und damit, liebe Leser, lasse ich euch mal mit den 48 Meta Keys allein meditieren, das langt für einen Beitrag.

 

In eigener Sache: Let’s talk about SEO, baby!

An diesem Wochenende hat mein Besucherzähler auf dieser Seite die 5.000er-Marke geknackt, und das ist eine respektable Zahl für einen sehr spezialisierten kleinen Blog wie den schwarzen Pinguin. Gezählt wird hier seit Februar diesen Jahres (2017), also hab ich hier rund gerechnet 5.000 Besucher in einem halben Jahr gehabt. Das freut mich persönlich sehr und ermutigt mich, mit meiner lockeren Plauderei über IT am Feierabend und WordPress im Speziellen weiterzumachen. Mir geht auch so schnell der Stoff nicht aus, keine Bange, nächste Woche gibts dann wieder Spaß auf der Datenbank!

Barrierefreiheit als SEO-Booster

Da wir gerade beim Thema sind: der Renner auf evileu.de ist nach wie vor das Inselfisch-Kochbuch mit aktuell 33.648 Besuchern, und da sind die Besucherzahlen nach einem eh schon guten Start nochmal kräftig in die Höhe gegangen, seit ich das Kochbuch in Sachen Barrierefreiheit  komplett umgebaut habe. Auch nicht schlecht läuft meine Oddballs-Handarbeitsseite, hier sind es immerhin auch schon 11.297 Besucher in einem halben Jahr. Das ist wirklich nicht übel für eine rein private Webseite, und ich werde oft gefragt, wie ich das denn gemacht habe.

Meine SEO-Tricks

Da muß ich euch leider enttäuschen. Ich nutze kein SEO-all-in-one Pack, ich jongliere nicht mit Keywords, mir ist mein Google Ranking egal, ich schalte keine Werbung, ich mach das hier alles zu Fuß.

Was ich allerdings schon mache: ich blogge wie der Weltmeister. Im Inselfisch-Kochbuch gibts mindestens einmal die Woche ein neues Rezept, hier quassel ich auch ungefähr ebenso oft aus dem Nähkästchen der alten Programmiererin, und auf den Handarbeitsseiten gibts regelmäßig Fotos meiner aktuellen Socken, Schals und Pullover und gelegentlich auch mal eine neue Anleitung zum Download als PDF. Das heißt, auf meinen Blogseiten ist regelmäßig Neues geboten, und das lieben nicht nur die Suchmaschinen, das lieben anscheinend auch menschliche Besucher.

Beiträge mit Hand und Fuß

Und ich erzähle halt nicht nur irgendeinen Keyword-gespickten Quark, meine Beiträge haben (meistens) Hand und Fuß. Nach meinen Kochrezepten kann auch ein Anfänger kochen, wenn man einen Schal nach meiner Handarbeitsanleitung strickt, dann wird das auch was, und wenn man meinen Code hier nachprogrammiert, dann funzt das auch. Das ist mein ganzes Geheimnis.

Wiederholungstäter und Mundpropaganda

Das sind meine wichtigsten Werbemittel. Meine streng wissenschaftlichen Analysen (ich hab einfach viele Leute gefragt) haben ergeben, dass gerade das Inselfisch-Kochbuch durch Mundpropaganda immer mehr Besucher bekommt, besonders das mit der Barrierefreiheit spricht sich hübsch herum. Und dann kommen meine Besucher auch wieder, sie benutzen das Kochbuch als Nachschlagewerk. Ich hab jetzt schon von vielen weiblichen Fans gehört, dass sie im Supermarkt mit dem Smartphone schnell mal ein Rezept im Inselfisch-Kochbuch nachschlagen und schauen, was sie dafür einkaufen müssen. Da hilft es natürlich, dass ein sauber umgesetztes WordPress-Theme im Regelfall fully responsive ist und auch auf dem Smartphone vernünftig dargestellt wird.

Spezialisierung: ein Blog, ein Thema

Das mit der Spezialisierung war bei mir dringend notwendig, weil ich so breitgefächerte Interessen habe. Ich male, ich programmiere, ich koche für mein Leben gern, ich schreibe Bücher für Kinder und für Erwachsene und produziere Handarbeiten am laufenden Band, und das ist noch lang nicht alles.

Ich habe in früheren Jahren schon mehrere vergebliche Anläufe gemacht, alle meine Interessensgebiete auf einer einzigen Webseite unterzubringen, und bin jedesmal  an dieser Sysiphosarbeit gescheitert. Letztendlich war  Wordpress der Schlüssel für die erfolgreiche Realisierung des Gemischtwarenladens evileu.de.

Ich habe jedem meiner vielen Hobbies einen eigenen Blog gegönnt, in dem ich jeweils nur über ein einziges Thema blogge. Es sind jetzt insgesamt etwas mehr als 10 Blogs, nicht alle sehr aktiv, aber doch eine stolze Anzahl für eine private Homepage. Wenn man nur mal auf die Seiten über meine Malerei schaut, das Thema ist jetzt aufgesplittet in meine Biographie als Malerin, meine Aquarelle, die Serie mit den blauen Planeten und dazu noch die Computergrafiken mit GIMP. Das macht 4 Kunst-Blogs, und die sind alle proppevoll mit Bildern und meinen Texten dazu. Aber eben sauber nach Themen getrennt, sonst verzettelt man sich. Und auch die Besucher verzetteln sich wenn eine Webseite zu viele verschiedene Topics anbietet, da werden die Menüs und Untermenüs und Unter-Untermenüs so verschachtelt, dass kein Schwein mehr durchblickt, und die Besucher nicht wiederkommen, weil sie nichts wiederfinden.

Jetzt fahre ich da eine ganz klare Linie, und das hat für mich als viel-Bloggerin den Vorteil, dass ich sofort weiß wohin damit, wenn mir eine Idee zu einem neuen Beitrag kommt. Und meine Besucher kennen sich auch aus, da jeder Themenblog einen unverwechselbarenb Look&Feel hat, und man sofort weiß ob man auf der Handarbeitsseite oder im Inselfisch-Kochbuch gelandet ist. Ich bin ein Buchhalterkind, ich liebe strukturierte Ablagesysteme!

Damit sind wir ganz wunderbar beim nächsten Stichwort gelandet:

Strukturierung: h1, h2 und Co.: eigentlich HTML für Anfänger

Ob sie es glauben oder nicht, Textverarbeitung am Computer gab es schon lange vor Windows und WYSIWYG. Ich erinnere nur an TeX/LaTeX oder an Word für DOS, wo man mitnichten auf dem Bildschirm angezeigt bekam, was dann auf dem Drucker herauskam. Damals lernten wir alles über die Verwendung von sog. Textauszeichnungen, in Word für Windows heißen sie Formatvorlagen. Und da HTML nichts anderes als eine Textauszeichnungssprache ist, gibt es sie  hier genauso. Jeder kennt sie, kaum jemand wendet sie richtig an.  Für Überschriften sind h1..h6 vorgesehen, eine Tabelle formatiert man mit Hilfe des <table>-Tags, es gibt nummerierte Listen, es gibt Image-Tags für die Bilder… das sind viele, aber doch nicht endlos viele. Eine hübsche komplette Liste aller HTML5-Tags findet ihr hier bei MDN Web Docs

Trennung von Text und Formatierung

Die Idee dabei ist, Text und Formatierung sauber zu trennen. Ein einfaches Beispiel: eine Hauptüberschrift soll fett, in Arial und in 30 Punkt Größe angezeigt werden. Was macht der WYSIWYG-Anwender? Er markiert den betreffenden Textabschnitt, drückt auf das Icon für „fett“, wählt in der Dropdownliste für die Schriftart „Arial“ und scrollt in der Schriftgrößen-Zahleneingabe rauf bis 30. Das erzielt zwar den gewünschten Effekt, aber es ist textverarbeitungstechnisch nicht sauber. Wie gehts richtig? Die Überschrift kriegt die Tags <h1>…</h1>, und wenn man es nicht dem Browser überlassen will wie eine Überschrift erster Ordnung dargestellt wird, legt man es in seiner CSS-Datei fest. Hierhin kommen unsere Textattribute, wenn man es richtig machen will.

Saubere Gliederung

Das habe ich bei der Umarbeitung meiner Webseiten auf barrierefrei neu lernen müssen, bei mir hatte sich da über die Jahre auch eine gewisse Schlamperei eingeschlichen. Ich schreibe ja sehr viel Text, und lange Textwüsten auf einer Webseite sind absolutes Bildschirmgift, die liest kein Schwein. Also, umdenken, Text in kürzere logische Einheiten unterteilen, Zwischenüberschriften einfügen, wo es Sinn macht, Listen und Tabellen verwenden. Das erhöht die Lesbarkeit und hält den Besucher bei der Stange, weil er nicht von unstrukturierten Endlostexten gelangweilt wird.

Einfaches Beispiel: Rezepte mit Struktur

Ich hätte da wieder ein einfaches Beispiel: alle meine Rezepte im Inselfisch-Kochbuch haben die selbe logische Gliederung:

  • Einleitung
  • Zutaten
  • Zubereitung
  • Tipps

Diese Elemente sind als h2-Überschriften formatiert. H1 ist der Titel des jeweiligen Rezepts, das ist unser post_title aus WordPress. Der Text dazwischen ist einfach <p> wie Absatz. That’s all, nach diesem Muster schreibe ich alle meine Rezepte. Ich muß nicht drüber nachdenken wie ich es mache, und es hat bei meinem Publikum einen hohen Wiedererkennungswert und dient der allgemeinen Übersichtlichkeit und Verständlichkeit. Mehr ist nicht dran an der Strukturierung – machen muß man es halt!

Übrigens: Suchmaschinen lieben klar strukturierte HTML-Dokumente. Benutzer mit Handicap (Screenreader & Co.) lieben sie auch, weil sie so klar durch das Dokument navigieren können. Deswegen ist eine gute Textstrukturierung auch eine der wichtigsten Voraussetzungen der Barrierefreiheit nach WCAG.

Mehr ist nicht dran an meinem SEO-Programm

Mit dieser Strategie bin ich zu meinen stolzen Besucherzahlen gekommen, über alle Blogs gerechnet sind das jetzt insgesamt fast 50.000 seit Anfang des Jahres. Genug aus dem Nähkästchen geplaudert, ich mach hier mal die Kiste zu. Ich hab mir nämlich gerade ein neues Projekt in Sachen Barrierefreiheit angelacht, da hat der schwarze Pinguin jetzt ein bißchen Sendepause. Bis die Tage!

 

Exkurs über unsere Kundendaten

Ich wollte ja eigentlich als nächstes den Bestellvorgang beleuchten, aber rein logisch kommen erstmal unsere Kunden an die Reihe, deswegen zieh ich das hier mal kurz vor.

Anmelden oder nicht anmelden?

WooCommerce bietet den Kunden die Möglichkeit, auch ohne das Anmelden eines Kundenkontos mit Password und allem drum und dran in unserem Shop als „Gast“ einzukaufen. Und soll ich ihnen sagen, was ich bevorzuge, wenn mir ein Shop da die Wahl läßt? Ich werde auf jeden Fall die Option ohne Anmeldung wählen. Weil ich mir nicht noch ein Paßwort merken will, weil ich keinen Bock auf Newsletter und Werbesendungen habe, weil ich meine persönlichen Daten im Internet nur hergebe, wenn es unbedingt sein muß. Ehrlich, sie können darauf zählen daß ein hoher Prozentsatz ihrer Kunden genauso denkt und auch ohne Erstellung eines „offiziellen“ Kundenkontos bei ihnen einkauft.

Kundendaten sind Unternehmenskapital

Wir wollen aber an unsere Kundendaten rankommen, die Adressen, Telefonnummern und E-Mail-Adressen sind so gut wie bares Kapital für unsere Firma.

Wenn sich ein Kunde brav bei uns anmeldet, wird in der WordPress Benutzerverwaltung ein neuer User mit der Rolle „Kunde“ für ihn angelegt, das ist recht gut dokumentiert. Die Benutzer Kunden werden in der wp_users verwaltet, in der wp_usermeta findet man dann die zugehörigen Adressdaten, die sind über die User-ID verknüpft.

Aber wo stecken unsere nicht angemeldeten Kunden?

Da haben sich die wooCommerce-Programmierer eine ganz besonders pikante Lösung einfallen lassen. Die haben sie nämlich schamhaft in der wp_postmeta versteckt:

nicht_angemeldeter_kunde

nicht_angemeldeter_kunde

Als ein Feld, alle Adressdaten in einem einzigen matschigen Klumpen. Zur Bestellung über die post_id zugeordnet, kenntlich am Meta Key _billing_adress_index.

Da soll doch der Dunnerlittchen…. sorry, aber bei sowas werde ich echt sauer. Das ist richtige Stümperei auf der Datenbank, aus so einem Feld krieg ich nie und nimmer (oder nur mit hohem Programmieraufwand) meine Kundendaten sauber wieder raus. Ja klar kann man mit PHP und einem „explode“ in ein Array und dann zeilenweise auslesen… ja hört’s mir aber auf. Das ist Pfusch, richtiger Pfusch, da beißt die Maus kein Faden ab.

So, jetzt langts aber, genug gestänkert. Wir machen uns mal an die Bestellungen, im nächsten Artikel.

 

Kleiner Nachtrag zu den Produkten: wo steckt die Artikelnummer?

Da hab ich doch glatt noch was vergessen. Wir haben ja unsere CSV-Datei inklusive der Artikelnummern eingelesen, und die Feldzuordnung beim Import ging hier auf _sku. Das Feld _sku steckt in der wp_postmeta, und hier ist auch die post_id hinterlegt, die regelt zu welchem Produkt die betreffende Artikelnummer gehört.

Aber was ist, wenn man ein Produkt manuell eingibt – wo kommt da die Artikelnummer hin? Davon ist nämlich erst mal weit und breit nichts zu sehen.

Des Rätsels Lösung: man muß beim neu Eingeben eines Produkts den Reiter „Lager“ aktivieren, dann kann man eine Artikelnummer eingeben.

lager_sku

lager_sku

Falls sie übrigens in Versuchung kommen sollten, die Lagerverwaltung hier tatsächlich wooCommerce anzuvertrauen: tun sie’s nicht. Für sowas gibts professionelle ERP-Software (auch als Shareware), damit sind sie wesentlich besser bedient. Das aber nur mal so als kleiner Tipp am Rande.

 

Schuster, bleib bei deinem Leisten: die Stärken von wooCommerce

Also, mir machen jetzt mal eine kurze Erholungspause von der Datenbankschinderei und schauen uns unseren nagelneuen Online-Shop mal genauer an. Tun Waren in den Warenkorb, schauen uns den an und bearbeiten ihn gegebenenfalls, und dann gehen wir mal zur Kasse.

Halt stopp! Da fehlt noch eine Zahlungsart

WooCommerce kommt eigentlich mit sehr funktionalen Grundeinstallungen daher, der Bestellvorgang läuft so professionell wie man ihn sich nur wünschen kann, aber zum Austesten fehlt noch (mindestens) eine Zahlungsart. Die hinterlegen wir unter wooCommerce/Einstellungen/Kasse, hier ganz nach unten scrollen. Für Testzwecke aktivieren wir hier mal nur die Scheckzahlung und hinterlegen unsere Firmenadresse, das sieht so aus:

scheckzahlung

scheckzahlung

Mehr brauchts nicht, jetzt können wir Einkaufen gehen.

Der Einkaufs- und Bestellvorgang

Da muß ich nicht groß ausholen und erklären, das ist alles absolut professionell und funktioniert mit den Default-Einstellungen schon ganz hervorragend, Der Bestell- und Bezahlvorgang ist einleuchtend und leicht verständlich und ganz so wie man es von „grossen“ Shopsystemen gewohnt ist. Man kann den Warenkorb füllen und bearbeiten, man kann zur Kasse gehen und seine Kundendaten hinterlegen, es gibt E-Mail-Benachrichtigungen über den Bestellstatus usw usf., Ich möchte es jedem selber überlassen,  hier in die Feinheiten einzusteigen, probiert es einfach aus und schaut euch in den wooCommerce-Einstellungen mal um. Viel Spaß dabei, das ist ein sehr erfreuliches Kapitel!

Kunde hat bestellt – und nun?

Kann man die offenen Bestellungen unter wooCommerce/Bestellungen einsehen und bearbeiten. Aber was ist im Underground passiert? Wir werfen mal einen kurzen Blick auf die Datenbank. Relevant für die Bestellungen sind eigentlich nur drei Tabellen, die wp_woocommerce_order_itemmetaVerstecken und dieAuf-/ZuklappenStrukturwp_woocommerce_order_items sowie die wp_posts. Ja, das habt ihr schon richtig gelesen, die Bestellungen landen ebenfalls in der wp_posts, mit dem post_type shop_order. Wir schauen uns das jetzt mal der Reihe nach an, aber dazu gönnen wir uns einen neuen Beitrag.

 

 

 

 

Noch’n Déja vu: was ist das führende System?

Das, liebes Publikum, hatten wir  schon mal, als es um die Mitgliederdaten des Turnvereins Weiß-Blau ging – erinnert sich noch jemand? Man kann Massendaten per CSV-Upload in WordPress reinjagen, aber man muß vorher ganz klar entscheiden, was das führende System ist. Das ist jetzt noch nicht mal WordPress-spezifisch, diese Überlegung muß man immer wieder anstellen, wenn es um die elektronische Verarbeitung von Betriebsdaten geht. Dabei stellen sich immer wieder die folgenden Fragen:

  1. Was passiert, wenn nach dem ersten Load noch Datensätze dazukommen?
  2. Was passiert, wenn sich an den Stammdaten mal etwas ändert?
  3. Aus welchem System fährt man betriebliche Auswertungen und Statistiken?

Wir gehen es mal der Reihe nach durch und klopfen ab, ob sich wooCommerce als führendes System für unsere Artikelstammdaten eignet.

Hinzufügen von Datensätzen:

Wenn es wirklich nur einzelne Datensätze sind, kann man die tatsächlich per Hand einpflegen, das heißt in unserem Fall: vereinzelt dazukommende neue Artikel werden manuell in wooCommerce angelegt. Stammdaten einpflegen, Bild hochladen, fertig.
Sobald es aber mehr als sagen wir mal ein halbes Dutzend neue Datensätze pro Monat sind, ist das zu viel Aufwand und eben auch fehlerträchtig. Dann braucht man einen selektiven CSV-Upload, der die bereits existierenden Bestandsdaten unberührt läßt und nur die neu hinzugekommenen Artikel neu anlegt. Ob das funktioniert, muß man vorher abklären, ehe man sich für ein CSV-Upload-Plugin entscheidet.

Stammdaten Pflege:

Hier sieht es ähnlich aus wie oben, das kommt darauf an wieviele Änderungen man zu machen hat. Vereinzelte Datensätze kann man per Hand editieren, bei Massenänderungen an den Bestandsdaten geht man doch lieber an die Datenbank.

Ich nenne mal ein einfaches Beispiel für eine typische Massenänderung: nehmen wir mal an, die nickelfreien Ohrringhaken sind im Einkauf 20 % teurer geworden, und ich möchte in der Folge die Preise für alle Ohrringe in meinem Sortiment etwas anheben, sagen wir mal um pauschal 5 %. Das geht bei drei, vier Ohrringen in meinem Onlineshop noch per Hand, sobald das allerdings mehr werden ist eine manuelle Änderung nicht mehr zumutbar.

Was tut der EDV-Fuzzy in so einem Fall? Ja klar, wir fahren einen Update auf der Datenbank! Der SQL auf einer Produkt-Stammdaten-Tabelle sieht so oder ähnlich aus:

update products set products_price=products_price*1.05 where products_category like „Ohrringe“;

Wenn’s denn so einfach wäre! Ich erinnere mal kurz an den letzten Artikel: um allein an die Produktkategorie eines Artikels heranzukommen, brauche ich einen Join über mindestens 4 Tabellen, der sah so aus:

(„SELECT Wp_term_relationships.*,Wp_terms.* FROM Wp_term_relationship
LEFT JOIN Wp_posts  ON Wp_term_relationships.object_id = Wp_posts.ID
LEFT JOIN Wp_term_taxonomy ON Wp_term_taxonomy.term_taxonomy_id = Wp_term_relationships.term_taxonomy_id
LEFT JOIN Wp_terms ON Wp_terms.term_id = Wp_term_relationships.term_taxonomy_id
WHERE post_type = ‚product‘ AND taxonomy = ‚product_cat‘
AND  object_id = „.$aktuelleID.““)

Und das ist erst der Select für die Kategorie zu einem einzelnen Artikel. Einen Update auf den _regular_price aus der wp_postmeta (noch ein Join mehr) mit einer Where-Klausel wie „where wp_terms.name like „Ohrringe““ kann sich jeder selber daraus basteln.

Das, liebe alte Datenbankfüchse, ist zwar interessantes SQL, aber in der realen Anwendung eine Zumutung!

Betriebliche Auswertungen und Statistiken oder: was zum Donner ist denn nun unser führendes System?

Die Artikelliste ist mein führendes System. Ich meine diese hier:

artikelliste_excel

artikelliste_excel

Mir ist es nämlich echt zu mühselig, statistische Auswertungen meiner Stammdaten über die WordPress/wooCommerce-Tabellen zu fahren. Mein Kunde möchte zum Beispiel wissen, wieviele Ketten und Colliers über 15 € er im Sortiment hat. Oder auch nur die Anzahlen der Artikel zu den einzelnen Kategorien, oder so etwas in der Richtung. Das macht man im Zweifelsfall im Excel mit den entsprechenden Filtern, das ist ratzfatz erledigt. Über die WordPress-Datenbank geht es nur mit solchen akrobatischen Verrenkungen und Joins über mehrere Tabellen wie gerade eben gezeigt, das ist mir einfach zu umständlich.

Wie sieht das in der Praxis aus?

Stammdatenänderungen müßten dann ausschließlich in der Excel-Tabelle passieren, aber vielleicht laden wir sie ja in Access, dann gehen solche Sonderwünsche wie ein seleketiver Update auf den Preis in ein paar Minuten. Export nach CSV, selektiver Upload – da müßte man dann die Option haben, bestehende Datensätze zu aktualisieren, aber das bieten die meisten Import-Plugins schon an. WooCommerce wäre dann ganz klar das sekundäre System, und da gehört es auch hin, wenn sie mich fragen. Für eine Bestandsführung mit allem was dazugehört ist es nämlich schlicht nicht geeignet. Meine Meinung, und natürlich subjektiv aus der Sicht einer alten Datenbankerin.

Aber ich will wooCommerce nicht in Bausch und Bogen verdammen, es ist nämlich schon ein intelligenter Online-Shop und hat noch etliche interessante Features zu bieten. Dazu mehr im nächsten Artikel.

 

Kraut und Rüben auf der Datenbank: wo wooCommerce die Produktdaten speichert

Ein Produkt = Beitrag: ja, und der Rest?

Wie ihnen bei einem kurzen Blick auf die Datenbank vielleicht schon aufgefallen ist, speichert wooCommerce die Produkte in der wp_posts mit dem post_type „product“. Das kennen wir ja schon, die wp_posts muß oft für allerlei Datengemusel herhalten, das mit „posts“, also mit Beiträgen, nicht im entferntesten was zu tun hat.Die Produktbilder landen übrigens auch in der wp_posts, aber das kennen wir ja auch schon, WordPress macht das halt mit Bildern so, mit dem post_type „attachment“.

Über Sinn und Unsinn dieser Praxis kann man lange diskutieren, es wird halt oft so gemacht und sogar als Best Practice empfohlen. Und da wir uns für wooCommerce als Shopsoftware entschieden haben, leben wir halt damit. Ich mach das hier mal nur im Schnelldurchgang, die Details kann ja jeder selber nachschauen.

Kleine Wiederholung: unsere Produktdaten

  1. Feld in der CSV-Datei:
    Artikelnummer;Kategorie;Bezeichnung;Beschreibung;Format;Preis
  2. Feld in der Dropdown-Liste:
    sku; category; post_title; post_content; post_excerpt; regular_price

Die fett markierten Felder stecken in der wp_posts unter den bekannten Feldnamen. Aber wo sind die anderen? Gehen wir’s mal der Reihe nach durch.

  1. Artikelnummer: sku
    Die sku ist in der wp_postmeta abgespeichert, unter dem meta_key _sku. Wir filtern uns die mal im phpmyadmin raus:

    _sku

    _sku

    Zur Erinnerung: in der post_meta ist über die post_id zugeordnet, zu welchem Beitrag der meta_key gehört.

  2. Preis = _regular_price
    Auch der steckt in der wp_postmeta, eben unter dem meta_key _regular_price.
  3. Kategorie = category
    Obacht! Das sind von wooCommerce eigens angelegte Produktkategorien, nicht die altbekannten Beitragskategorien von WordPress. Und hier wirds jetzt richtig lustig, die zugehörigen Daten sind nämlich über die vier Terms-Tabellen verteilt. Um herauszufinden, welche Produktkategorie zu einem Produkt gehören, muß man einen Join über mindestens drei Tabellen fahren, da sieht dann der Select ungefähr so aus:

    („SELECT Wp_term_relationships.*,Wp_terms.* FROM Wp_term_relationships

                LEFT JOIN Wp_posts  ON Wp_term_relationships.object_id = Wp_posts.ID

                LEFT JOIN Wp_term_taxonomy ON Wp_term_taxonomy.term_taxonomy_id = Wp_term_relationships.term_taxonomy_id

                LEFT JOIN Wp_terms ON Wp_terms.term_id = Wp_term_relationships.term_taxonomy_id

                WHERE post_type = ‚product‘ AND taxonomy = ‚product_cat‘

                AND  object_id = „.$aktuelleID.““)

    Und das finde ich jetzt schon weniger lustig.

Und wenn ich mal alle relevanten Daten zu meinen Produkten brauche?

Ja, dann fahren wir halt einen Join über die wp_posts, die wp_postmeta und die bekannten Terms-Tabellen. Das wird dann so richtig übersichtlich. Darf ich bei dieser Gelegenheit mal daran erinnern, wie unsere Artikelliste ursprünglich mal aussah:

artikelliste_excel

artikelliste_excel

Ach, was war das noch schön einfach und übersichtlich! Ganz ehrlich, ich finde es schon ziemlich hanebüchen, welche Bauchaufzüge man machen muß um wooCommerce die eingegebenen Produktdaten auf Datenbankebene wieder zu entlocken.

Da kommt jetzt natürlich die berechtigte Frage: wer braucht das schon? Reicht doch, wenn wir die Produkt-Daten per CSV reinjagen und in wooCommerce verwalten. Das, liebes Publikum, ist eine extra Diskussion wert. In einem neuen Artikel.

Déja vu im Online-Shop: wollen wir das wirklich alles per Hand eingeben?

… natürlich nicht. Wie sie wahrscheinlich beim Erstellen der Test-Produkte gemerkt haben, hält das Prozedere ganz schön auf, und mehr als eine Handvoll Produkte per Hand in unseren nagelneuen Online-Shop einzupflegen ist eigentlich in der Praxis nicht zumutbar. Das dauert viel zu lang und ist auch ungeheuer fehleranfällig, das kann man keinem Kunden zumuten. Aber keine Bange, es ist Abhilfe in Sicht.

Produktliste – haben wir sehr wahrscheinlich schon

In jeder noch so kleinen Klitsche gibt es in irgendeiner Form eine Liste der Produkte für den Verkauf, dafür lege ich meine Hand ins Feuer. Das kann ein Word- oder Excel-Dokument sein, oder (im Idealfall) vielleicht sogar ein kleines Datenbankerl mit OpenOffice oder Access.

Jedenfalls haben wir mit an Sicherheit grenzender Wahrscheinlichkeit schon eine Liste unserer Verkaufsprodukte, und wahrscheinlich haben wir sogar schon einen Primärschlüssel, nämlich eine eindeutige Artikelnummer. In meinem Schmuckladen gibt es die allerdings tatsächlich nicht, da sind die Produkte nur über den (hoffentlich einmaligen) Namen eindeutig identifizierbar. Aber im Normalfall haben wir einen eindeutigen Identifikator, das kann eine EAN sein, oder eine fortlaufende Nummer, oder eine Kombination aus Zahlen und Buchstaben.

Liste? CSV, Import!

Genau! Wenn wir schon eine Produktliste haben, die wollen wir doch dem wooCommerce direkt einfüttern und uns einen Haufen Handarbeit sparen. Also dann, frisch ans Werk! Ich hab mir mal eine kleine Produktliste in Excel erstellt, die sieht so aus:

artikelliste_excel

artikelliste_excel

Wie kriegen wir die jetzt ins wooCommerce? Genau! Dafür gibt es Plugins! Zum Beispiel den

Woocommerce CSV importer v

Den installieren wir uns, und dann wird ausprobiert. Ich mach hier mal kurzen Prozess und beschreibe kurz, wie der Importer funktioniert.

  1. Man erstellt eine Header-Datei, das ist nichts anderes als ein CSV, das als einzige Zeile die Feldnamen mit Trennzeichen enthält. Das sieht so aus:

    header

    header

  2. Man erstellt sich die dazu passende Artikelliste als CSV

    schmuck_csv

    schmuck_csv

  3. Man wählt in den CSV Import Settings das richtige Trennzeichen (field seperator), wir haben ein „;“ (Semikolon)

Und dann kanns losgehen. Header laden, Feldzuordungen vornehmen, CSV-Artikelliste laden… aber mal langsam mit den jungen Pferden.

Die Feldzuordnungen beim CSV-Import: bin ich Hellseher?

Man kriegt hier in einer hübschen Dropdown-Liste die Feldnamen in WordPress/wooCommerce angezeigt, und kann hier entsprechen die Zuordnungen vornehmen. Dazu muß man alllerdings wissen, welches Feld in der Dropdownliste welchem Feld in der Artikelliste in unserer CSV-Datei entspricht.

header_feldzuordnung

header_feldzuordnung

Geht schon ganz oben los: das Feld „sku“ ist für die Artikelnummer vorgesehen, aber das muß man erstmal wissen. Jetzt wäre es halt verdammt nützlich, wenn man wüßte wie wooCommerce was in der Datenbank abspeichert, und das ist leider nicht unbedingt selbsterklärend. Das ist sogar ein kleiner Trip ins Datenchaos, aber dazu gibt es dann später einen neuen Beitrag.

Ich sag hier nur mal kurz, wie man unsere paar Import-Felder sinnvoll zuordnet. Die Logik ist wie folgt:

  1. Feld in der CSV-Datei:
    Artikelnummer;Kategorie;Bezeichnung;Beschreibung;Format;Preis
  2. Feld in der Dropdown-Liste:
    sku; category; post_title; post_content; post_excerpt; regular_price

Alles klar? Damit dürfte dem erfolgreichen Import nichts mehr im Wege stehen. Man bekommt sehr schön eine Preview angezeigt, und wenn die hinhaut, können wir die CSV-Datei laden.

import_preview

import_preview

Presto! Unsere neuen Artikel sind drin und auch gleich im Shop zu sehen.

neue_artikel

neue_artikel

Allerdings ohne Bilder. Und mit Duplikaten, weil es manche Artikel vorher schon gab, per Hand eingeklopft. Aber wer wird denn da kniefieselig sein? Ich schon. Die Duplikate kann man noch per Hand löschen, das waren nicht so viele. Und was ist mit den Bildern?

Plugins für den Bilder-Import: kosten Kohle

Es gibt unzählige Import-Plugins für wooCommerce, viele davon OpenSource und kostenlos. Ich hab allerdings noch kein freies Plugin gefunden, das auch Produktbilder importieren kann, und ich kaufe prinzipiell keine kostenpflichtigen Plugins. Sorry Freunde, aber hier ist das Ende der Fahnenstange.

Aber jetzt wirds Zeit uns mal drum zu kümmern, was wooCommerce auf der Datenbank macht, und dazu gibt es einen neuen Artikel.

 

 

 

Wir basteln uns einen kleinen Schmuckladen

Da ich mit konkreten Beispielen immer am Besten arbeite, basteln wir uns jetzt einen kleinen Online-Shop für meinen Glasperlenschmuck. Da haben wir übersichtliche Produktdaten und eine hübsche Fotoauswahl. Ich habe das Theme Twentysixteen genommen und mir gleich mal ein Child Theme erstellt, das brauchen wir bestimmt noch. Jetzt noch schnell wooCommerce installiert, und es kann losgehen.

Der erste Eindruck: sie sehen, daß sie nichts sehen

Woo legt uns ein paar neue Seiten an (näheres später) und stellt uns den Shop als Startseite ein. Da wir noch keine Waren in unserem Shop haben, sieht das Ganze erstmal ziemlich leer aus.

shop_leer

shop_leer

Ein kurzer Blick auf die Datenbank

Ach du liebes Lieschen, wie sieht dann das aus! Woo hat sage und schreibe 14 neue Tabellen erstellt!

woo_tabellen

woo_tabellen

Immer mit der Ruhe, die nehmen wir uns der Reihe nach vor, wie wir sie brauchen. Und ich kann ihnen gleich zur Beruhigung sagen: die meisten davon brauchen wir erstmal noch gar nicht. Ein wenig Geduld, wir machen schon noch ein bißchen Spaß auf der Datenbank. Jetzt füllen wir erstmal unseren Shop mit Leben.

Produkte hinzufügen

Woo beschert uns zwei neue Menüpunkte im Dashboard, „WooCommerce“ und „Produkte“.

woo_menus

woo_menus

Wir nehmen eine Abkürzung und gehen gleich mal auf „Produkt hinzufügen“, alles andere später. Der Produkteditor ist recht übersichtlich, das ist nix anderes als eine Variante des gewohnten Beitragseditors. Wir fügen jetzt mal ein paar Produkte hinzu, damit unser Shop lebendiger wird. Wir haben pro Produkt fünf Attribute, die wir in unseren Shop einpflegen wollen:

  • den Produktnamen
  • die Kategorie
  • die Beschreibung
  • Angaben zur Größe
  • den Preis

Das Produktfoto muß auch noch rein, aber das wars. Ich verteile meine Produktdaten wie folgt:

  1. Produktname in den Titel
  2. Beschreibung in den Text
  3. Preis in das Feld „regulärer Preis“

Und dann noch die Größenangabe… tscha, und da hakts schon zum ersten mal. Sollen wir dafür ein Benutzerdefiniertes Feld anlegen? Lieber nicht. Weiter unten gibt es noch ein Textfeld „Produkt Kurzbeschreibung“, das nehmen wir, das sieht freundlich aus.

produkt_kurzbeschreibung

produkt_kurzbeschreibung

Für die Produktkategorien gibt es rechts ein „Produktkategorien“-Untermenü, das nehmen wir natürlich auch gleich noch mit. Ich trage mal gleich ein paar Kategorien ein, die werden wir ja später noch brauchen… aber Obacht! Nichts verwechseln, das sind jetzt woo-eigene Kategorien, die nichts mit den gewohnten Beitragskategorien zu tun haben. Da lauert Verwechslungsgefahr, das muß man unterscheiden. Aber ich trag mal trotzdem hier was ein:

produkt_kategorien

produkt_kategorien

So, fehlt noch das Foto, das kommt rechts bei „Produktbild“ rein, die Produktgalerie lassen wir jetzt noch aussen vor. Alles drin? Dann werfen wir jetzt mal einen Blick auf unseren Shop.

Shop mit einem Produkt

Das sieht doch schon mal ganz nett aus.ein_produkt

ein_produkt

Wenn man auf das Produktbild draufklickt, kommt man in die Einzelansicht, hier werden auch die restlichen Daten zum Produkt angezeigt, und hier kann man das Produkt in gewünschter Stückzahl in den Warenkorb packen, oder auch eine Produktbewertung abgeben.

einzelansicht

einzelansicht

Momentchen noch: in meinem Schmuckladen gibt es nur Unikate, das heißt jedes Produkt ist genau einmal vorhanden. Da dürfte beim Warenkorb genau genommen keine Stückzahl > 1 angegeben werden – aber ja, ich hörs schon, sie haben recht, das sind Feinheiten, um die kümmern wir uns später.

Das reicht uns jetzt mal fürs erste, geben sie mal zwei, drei Produkte ein, und wenn sie das haben gehts weiter. In einem neuen Beitrag.

 

 

 

 

Das bekannteste eCommerce-Plugin: wooCommerce unter der Lupe

Warum WooCommerce so beliebt ist

Wer einen Online-Shop mit WordPress betreiben will, wird sich in den meisten Fällen erstmal für wooCommerce entscheiden. Erstens ist es kostenlos und trotzdem praxistauglich, zweitens reich an Features und nahezu unbegrenzt erweiterbar, und drittens gibt es hervorragenden (ebenfalls kostenlosen) Support dafür. Mit bis dato ca. 15 Millionen Downloads (schlag nach bei Wiki) eine echte OpenSource-Perle – möchte man meinen. Ich hab dazu eine eigene Meinung. Wir werden uns im Folgenden aus der zugegeben nicht unparteiischen Sicht einer alten Datenbankerin näher mit WooCommerce befassen, und ich denke ich werde im Verlauf dieses neuen Themas schon ein bißchen klar machen können, wo es meiner Meinung nach hakt.

WooCommerce: Pfusch auf der Datenbank?

Ja. Zwar auf sehr hohem Niveau, aber Pfusch bleibt Pfusch. WooCommerce klemmt sich nunmal ins enge, überalterte Datenkorsett von Madame WordPress, und da gibt es abenteuerliche Konstrukte – aber dazu später mehr. Seid ihr bereit für eine Achterbahnfahrt auf der Datenbank? Dann mal los, zieht euch eine neue WordPress-Instanz auf und installiert euch WooCommerce zum Testen, da ist nichts weiter dabei. Morgen gehts dann los – ich habe euch wieder ein bißchen Spaß auf Datenbank versprochen, aber ich kann nicht garantieren daß es nicht an manchen Stellen zur Kuriositätensammlung mutiert…