Die Fernsehköche von damals, als es “Schmeckt nicht” noch gab. Mit diesem betont selbstverständlichen Tonfall “Auch das ‘abö iesch fürr Sie schonn vorrbö ‘eittöt” haben die immer quasi aus dem Nichts irgendetwas hervorgezogen … “Ja klar! Und wer soll das denn bitte so schnell hinkriegen?!”

Genau dieses fast ungläubige Staunen packt mich momentan immer wieder aufs Neue. Es fing relativ harmlos an - mit einer Datei, Endung “.xls” und einem Shop, der befüllt werden sollte. Aber je näher man hingeguckt hat (”Auch das ‘abö iesch fürr Sie schonn vorrbö ‘eittöt”), desto größer wurde sie, diese Excel-Datei …

Damit nicht genug: Kaum war das eine Problem gelöst, kam auch gleich das nächste.

 

Ausgangslage

In der Excel-Datei waren alle Produkte gespeichert. Natürlich nicht so, wie xt:Commerce das braucht, um sie importieren zu können. Produktnamen und Beschreibungstexte gab es ebenfalls nicht, diese sollten aus diversen Eigenschaften gewissermaßen “zusammengesetzt” werden. Alles in allem eine Art “Matrix”, aus der etwa 1.800 einzeln bestellbare Produkte gebildet werden.

 

Und nu?

Basteln - Mal wieder … Hier eine kurze Beschreibung der Arbeitsschritte, die vielleicht als Anregung interessant sein könnten. Ein allzu detaillierter Bericht wäre nicht so sinnvoll, da jeder bei solchen Arbeiten je nach Projekt sowieso auf andere Stolpersteine stoßen würde.

Und außerdem will ik ja och noch watt verkoofen.
:-)

Diesmal also kein “echtes Tutorial”, sondern eher ein “Denkmodell” und eine “Sammlung von Anregungen”.

 

Schritt 1: Excel-Datei als Text-Datei exportieren

Die Idee war schon mal gar nicht schlecht.

Es geht zwar auch einfacher, aber dazu muss man erst einmal wissen, was man braucht. Ich empfehle übrigens » dieses Freeware-Programm.

Aber da wir ja noch nicht so hundertprozentig genau wissen, was wir genau brauchen, probieren wir erst einmal mit dieser Text-Datei weiter herum …

Schritt 2: Text-Datei in GoLive reinladen

Denn dass die aus Excel exportierte CSV-Datei ganz und gar nicht so aussieht wie das, was xt:Commerce als Import-Datei erwartet, war sowieso klar. Die Idee war, daraus eine “echte” HTML-Tabelle zu machen, um nachher hier und da leichter irgendwelche Spalten einzufügen.

Adobe GoLive (und der DreamWeaver bestimmt auch, den hab ich nur nicht) beherrscht “Suchen und Ersetzen”-Funktionen mit regulären ausdrücken, eine HTML-Tabelle war schnell erstellt.

Naja. Nicht unbedingt “schnell”. In meinem Fall sind über 30.000 Zeilen herausgekommen, das dauert dann doch schon, bis der nöchste Kaffee fertig ist.

Es wäre zwar rein technisch möglich gewesen, die Tabelle auch nur mit den Ersetzungs-Funktionen für xt:Commerce passend aufzubereiten, aber nach dem zweiten mühsam zusammengefummelten regulären Ausdruck (der Rechner hat satte zwei Minuten gebraucht) war schon irgendwie klar, dass es SO nicht weitergehen kann.

Außerdem: Was für ein Ärger, wenn man nach x Minuten Rechenzeit (inzwischen war die Tabelle auf 50.000 Zeilen angewachsen) feststellt, dass die letzte “Aktion” Mist gewesen ist?

Fazit: Sackgasse. Also anders vorgehen …

Schritt 3: Aus der Text-Datei eine mySQL-Datei machen

Die Idee: So kann man sehr viel entspannter vorgehen und sich einfach ein paar PHP-Funktionen schreiben, die die “Original Produkt-Tabelle” Zeile für Zeile durchsteppen für jede Zeile genau die Anzahl Kommata, Single-Quotes, Tabulatoren etc. erzeugt, die eine xt:Commerce Import-Datei haben soll.

Und wenn mal etwas schief gelaufen ist, kann man einfach die Funktionen ein bisschen ändern. So bleibt die “Original Produkt-Tabelle” unangetastet, man hat keinen Ärger mit Aktionen, die man nicht mehr rückgängig machen kann - und der eigene Rechner gibt nicht dauernd auf, weil ja keine 1.800 Produkte gleichzeitig durchgebügelt werden, sondern brav eins nach dem anderen.

Was ebenfalls nicht zu verachten ist: Man kann, während der Server vor sich hin rechnet, seinen Web-Editor weiterbenutzen.

Man muss also nicht sehr viel mehr tun, als aus der ersten Zeile eine mySQL “create table”-Anweisung machen und dann vor jede folgenden Zeile die ganzen “insert into”-Befehle (natürlich inklusive Klammer auf, Klammer zu etc.) einzufügen.

Schritt 4: SQL-Datei in eine Online-Anwendung einbauen

Da ich so ziemlich alles mit WordPress mache (außer Kaffeekochen vielleicht) und in einem fertig installierten Blog schon alle Funktionen (Verbindung zur Datenbank etc.) zur Verfügung stehen, hab ich die SQL-Datei einfach zur Datenbank einer bereits bestehenden WordPress-Seite “hinzukopiert”.

Der weitere “Einbau” ist erfreulich einfach:

  1. Ein WordPress “Page-Template” erzeugen und hochladen
  2. Die WordPress-Loop kann man sich schenken, die braucht man nicht. Wir wollen ja nur eine Seite haben, die alle WP-Funktionen “kennt”, damit wir das nicht alles selbst noch mal programmieren müssen
  3. Kein get_header(); etc. - Nur die üblichen PHP-Kommentare, die üblichen Verfahrensweisen um ungewollte Besucher fernzuhalten (Also Abfrage, ob eine User-ID vorliegt, wenn nicht, auf die Startseite weiterleiten) - Und dann der Aufruf einer Funktion show_ShopTable('MeineImportDatei'); - Page-Template fertig
  4. Eine leere WordPress Page (Name z.B. “ShopTable”) erzeugen und ihr das neue Page-Template zuteilen. Nur zwischenspeichern - “draft” bzw. “Entwurf”: Als Admin kann man sie sehen, und für andere Besucher sowie in den Feeds bleibt sie versteckt
  5. Ein PlugIn schreiben … Bei mir hieß es “ShopTableFunctions”

… und die Arbeit geht dann im “neuen PlugIn” weiter.

Schritt 5: Schritt für Schritt PlugIn optimieren

Die Funktion show_ShopTable($TabellenName); beginnt mit einer normalen Datenbank-Abfrage an die Tabelle “MeineImportDatei” - und fragt bloß nach der ID, die jedes Produkt sinnvollerweise haben sollte. Kann auch ein Auto-Increment-Wert sein. Völlig wurscht.

Aus den IDs macht man eine Schleife, die eine weitere Funktion get_ShopTableRow($pID); aufruft. Und da ist es sinnvoll, eine xt:Commerce Export-Datei vorliegen zu haben, mit der man “vergleichen” kann, wie die Import-Datei genau auszusehen hat.

Die Funktion get_ShopTableRow($pID); hat in meinem Fall auf lauter weitere Minifunktionen zurückgegriffen, die beispielsweise " in " umwandeln, ein Leerzeichen vor allen Einheiten (wie mm, cm) einfügen - oder einen Artikelnamen aus den Werten “Größe”, “Breite”, “Material”, “Profil”, “passend für” zusammensetzen oder ggf. “Maßanfertigung” schreiben, wenn’s kein “passend für” gibt.

Man sollte jede Tabellenzeile gleich per echo ausgeben lassen. Denn wenn man alle Zeilen zunächst in einer Ausgabevariablen sammelt, ist der Server ab einer gewissen Größe einfach überfordert - und etliche Zeilen werden verschluckt.

Eventuell muss man zusätzlich so arbeiten, dass man bequem Produkt 600 bis 1200 auswählen kann, denn eine HTML-Ausgabe macht scheinbar nach einer gewissen Zeichen-Anzahl einfach “dicht”, so dass die restlichen Artikel verloren gehen könnten.

Und noch ein Tipp: Die Funktion get_ShopTableRow($pID); sollte eine “echte HTML-Tabellenzeile” erzeugen, denn so kann man optisch besser kontrollieren, ob alles korrekt gelaufen ist. Für die Ausgabe als xt:Commerce kompatible Datei sollte man eine separate transform_TableRow($Input) schreiben, die alle <td></td> in Singlequotes und Tabulator zurückwandelt.

Schritt 6: Ergebnis kopieren und rein damit!

Beinahe fertig: Nun muss man nur noch http://www.meinblog.de/shoptable/ aufrufen und kann sich locker den Quelltext kopieren. Das dann in einer “.txt”-Datei abspeichern, diese ins xt:Commerce Import-Verzeichnis hochladen … und nicht verzweifeln!

Ziemlich sicher wird xt:Commerce an etlichen Stellen irgendetwas auszusetzen haben. Aber genau deshalb ist es der Umweg über WordPress ja so praktisch. Da man mit den etwaigen Fehlermeldungen von xt:Commerce zur Abwechslung tatsächlich mal etwas anfangen kann, weiß man relativ genau, wo man sein “Konvertier-PlugIn” noch nachbessern muss.

Und was dabei Einiges an Programmier-Arbeit spart: Bei irgendwelchen Schwierigkeiten mit der Text-Formatierung stellt WordPress von Haus aus etliche Funktionen zur Verfügung, wie “wptexturize”. “wpautop” - und bei installiertem “Clean Umlauts”-PlugIn zusätzlich noch die Funktion o42_clean_umlauts(); - Was will man mehr?

Übrigens: Wenn man fertig ist und das Ergebnis kopiert - Es muss nicht unbedingt eine “.txt”-Datei sein. xt:Commerce importiert alles. Ob man die Import-Datei nun “.txt”, “.csv”, “.html” oder “.doc” nennt, ist total Banane. Sogar “.jpg” funktioniert (ich hab’s eben grad ausprobiert).

Apropos Benennung: Zusätzlich kann man den Server bei Bedarf auch noch “lahme Sau” nennen und seine friedlich auf dem Schoß schlafende Katze mit einem lauten “Hast jetzt Du’s jetzt endlich mal, Du Scheißding?! Es ist halb sieben!!” verscheuchen. Schneller wird’s dadurch zwar nicht, aber es geht nichts kaputt (ich hab’s eben grad auch ausprobiert).

 

Ein nützliches Tool: Der “DataKonverter”

Ein bisschen schneller funktioniert die Umwandlung von Excel nach mySQL mit dem kostenlos erhältlichen Programm » “DataKonverter”. Damit kann man “.xls”-Dateien direkt in mySQL-Anweisungen umwandeln.

Um diese Ergebnisse direkt über phpMyAdmin einfügen zu können, bleiben einige nachträgliche Bearbeitungen nicht aus. Zudem sollte man dafür sorgen, dass reine Zahlenwerte keine Kommata, sondern Punkte als “Dezimaltrenner” erhalten.

Aber der » “DataKonverter” kann dennoch ganz gut Zeit und Nerven sparen.

 

Wenn man schon mal dabei ist:
osCommerce nach xt:Commerce konvertieren

Auf ähnliche Weise habe ich auch einen kompletten Artikelbestand von osCommerce nach xt:Commerce übertragen. Die osCommerce Export-Funktion gibt allerdings keine “einfache” Artikelliste aus, sondern gleich den gesamten Shop-Inhalt.

Und in dem Fall müssen auch mehrere Tabellen miteinander in Verbindung gebracht werden, denn die Daten eines einzelnen Produktes sind (wie auch in xt:Commerce) über mehrere Tabellen verteilt, “gemeinsamer Nenner” ist die ID des jeweiligen Artikels.

 

Happy End?

Ein klares “Jein”. Es können immer noch etliche Probleme auftreten, die vom “Denk-Aufwand” her zwar relativ leicht zu lösen sind, aber einfach Zeit kosten.

Jedoch kostet es deutlich weniger Zeit (und Geld) als eine eventuell unmotivierte Aushilfe einzustellen, die über tausend Artikel im BackEnd “reinhackt”, sich hier und da mal verschreibt - und eine intensive Kontrolle vom “Schäffe” unerlässlich macht …

Was beim Import schief gehen kann:

  1. xt:Commerce schläft beim Import einfach ein?
    In dem Fall die Anzahl der importierten Artikel “aufteilen”. 1und1 schafft z.B. maximal 600 Artikel (mit Staffelpreisen) gleichzeitig.
  2. 1.800 Artikel importiert, aber der Shop hat nur einen einzigen neuen?
    Es ist kein Problem über das BackEnd von xt:Commerce Artikel anzulegen, die keine Artikelnummer haben. Möchte man aber Artikel importieren, braucht jeder eine eigene Artikelnummer. Sonst wird 1.800 Mal derselbe Artikel “überschrieben”.
  3. Staffelpreise werden nicht übernommen?
    … und das, obwohl es eigentlich klappen müsste? Keine Sorge. Das klappt schon. Beim ersten Import gehen wirklich viele Staffelpreise verloren. Das macht nichts. Einfach dieselbe Datei erneut importieren. Warum das mit den Staffelpreisen regelmäßig erst beim zweiten Versuch klappt, hab ich noch nicht herausgefunden, aber wenigstens klappt es beim zweiten Versuch wirklich zuverlässig.

 

Aher warum eigentlich die Überschrift
“Suchet, und Ihr werdet …?”

Dann suchen Sie doch einfach mal! Als ich mich gerade darüber freuen wollte, endlich alle Artikel sauber und ohne “Dupletten” importiert zu haben, durfte ich feststellen, dass die Suchfunktion (jedenfalls in xt:Commerce 3.04 SP1) ihre Probleme mit Umlauten hat.

Zum (ungläubig staunenden) näheren Testen habe ich bei einem Test-Produkt in die Kurzbeschreibung “ärgerlich” eingegeben, bei einem anderen in die lange Beschreibung “würgen” - beides Wörter, die in anderen Artikel-Texten ziemlich sicher nicht vorkommen, die ich aber garantiert eingegeben habe - und keines der beiden Wörter wurde über die xt:Commerce-Suche gefunden.

Ist das nicht toll?

 

“The Search goes …”

Zusätzlich hatte ich (weil die Import-Funktion sonst abschmiert) alle " in &quot; gewandelt. Und da funktioniert es witzigerweise wieder. Aber nur mit den Zoll-Angaben in der Produktbeschreibung. In Entites gewandelte Zoll-Angaben im Artikelnamen werden nicht gefunden.

Irgendwie ein merkwürdiges Feature: Die in Entities gewandelten Doublequotes werden in den Beschreibungs-Texten gefunden, während die in Entities gewandelten Umlaute im Artikeltext für die Suche unter den Tisch fallen.

Schön wenn man’s weiß. Aber es gibt (jedenfalls über das BackEnd) keine Möglichkeit, Umlaute einzugeben, OHNE dass sie in Entities gewandelt werden. Schade.

Über die Datenbank kann man dieses Verhalten zwar “reparieren”, damit die Suche wieder Sinn macht - aber insgesamt ist das wieder ein zusätzlicher Faktor, der die Nutzbarkeit des Admin-Bereiches von xt:Commerce für wirklich produktive Arbeit mehr als in Frage stellt …

Wenn man über “selbstgestrickte Importe” die Suche aushebeln kann, verstehe ich das ja noch. Nur dass es auch bei den vorgegebenen Eingabemöglichkeiten nicht möglich ist, Umlaute so zu benutzen, dass sie auch gefunden werden können, lässt mich staunen.

 

Und da war es wieder, dieses eingangs beschriebene Gefühl:

“Auch das ‘abö iesch fürr Sie schonn vorrbö ‘eittöt”

 

Nachtrag

Die Suchfunktion von xt:Commerce 3.04 SP2.1 findet inzwischen Umlaute und Sonderzeichen in Artikeltext und Kurzbeschreibung. Zeit für einige Upgrades.