une tour de varisale

Die folgenden Infos sollte jeder, der mit varisale ein Projekt umsetzen möchte, unbedingt gelesen und verstanden haben. Dann gibt es später kein böses Erwachen, wenn Dinge in varisale anders laufen als in OXID oder xt:commerce :-)

API-only

varisale gibt bewusst kein Frontend vor, sondern nur eine Verwaltung der Shopinhalte sowie eine umfangreiche API, um auf diese zuzugreifen. Das bedeutet, dass es keinen Demoshop gibt, den man einfach installiert, etwas CSS anpasst und dann online stellt. Jeder Shop in varisale ist eine (teilweise) Neuentwicklung, die direkt auf das Projekt zugeschnitten ist.

Dies ist dem Umstand geschuldet, dass varisale-Shops in Websites integriert werden sollen, und nicht abgetrennte Bereiche sein sollen.

Es gibt allerdings sehr wohl ein Demo-Template, das allerdings nur zum Testen geeignet ist und bestenfalls als kleine API-Demo herhalten kann. Es ist nicht dazu gedacht, produktiv verwendet zu werden.

Exceptions

varisale wird bei jedem Fehler eine Exception werfen. Wird auf ein nicht existierendes Produkt zugegriffen, fliegt eine Exception. Wird eine fehlende Kategorie aufgerufen, fliegt eine Exception. Es ist daher wichtig, die Calls zur API jeweils in einen try-catch-Block zu verpacken, damit Besucher nicht über manipulierte URLs (z.B. index.php?product=-34726242) Fehler provozieren können!

Sicherheit

varisale wird alle Daten, die in die API eingegeben werden, selbstständig casten und sicherstellen, dass Strings nur über Prepared Statements an die Datenbank geschickt werden. Das Frontend kann also an dieser Stelle recht entspannt gehalten werden. Ein Call wie $varisaleObject->getFoo($_GET['...']) ist daher kein Problem. varisale kümmert sich.

Produkte sind “Key-Value-Pairs”

Ein Produkt ist in varisale ein Objekt, das beliebige Eigenschaften haben kann. Dies entspricht dem Konzept, das auch Meta Info und FrontendUser verwenden. Produkte werden über Datentypen konfigurierbar gemacht, wobei die Produkttypen dazu dienen, unterschiedliche Produkte zu verwalten. So kann ein Produkttyp Buch ganz andere Eigenschaften haben als ein Produkttyp Laptop.

Produkttypen und die Eigenschaften (“Attribute” in varisale-Sprech) werden in der Datei develop/config/varisale.yml definiert. Wie genau das aussieht, soll hier jedoch nicht von Belang sein.

Besondere Attribute

Der Preis und der Steuersatz eines Produkts sind besondere Attribute, da varisale sie zur Preisberechnung benötigt. Sie werden daher im Backend abgetrennt von den restlichen Attributen angezeigt. Wie sie heißen und welcher Datentyp sie verwaltet, ist dabei quasi egal. Welche Attribute genau die beiden Informationen bereitstellen, ist konfigurierbar, standardmäßig handelt es sich um das “price”- und “taxrate”-Attribut.

Preise werden generell als Netto in der Datenbank abgelegt. Sollte die Eingabe im Backend in Brutto erfolgen, kann der Datentyp entsprechend konfiguriert werden.

Variable Attribute

Standardmäßig sind alle Attribute fixiert, das heißt vom Betreiber vorgegeben. Sie werden dabei im Backend eingegeben und können vom Kunden im Frontend nicht geändert werden.

Attribute können allerdings (siehe Konfiguration) auch als variabel markiert werden. Dann sind sie im Backend nicht verwaltbar und stehen nur für den Kunden zur Verfügung. Dies kann benutzt werden, um z.B. beim Kauf eines T-Shirts die Farbe vom Kunden auswählbar zu machen (in diesem Fall wird man zwei Attribute haben: eines, das die Liste der verfügbaren Farben angibt (vom Betreiber eingestellt = fixiert) und eines, das die vom Kunden gewählte Farbe enthält).

Produktvarianten

Von jedem Produkt können beliebig viele Varianten angelegt werden. Dabei handelt es sich quasi um Kopien (echte Kopien von Produkten sind natürlich auch möglich), die mit dem Mutterprodukt verbunden sind. Varianten können dann unterschiedliche Werte für die Attribute annehmen. Ein Beispiel verdeutlicht dies:

  • Produkt: CD Blumentopf - Musikmaschine (Preis: 15 EUR)
  • Variante 1: CD Blumentopf - Musikmaschine Deluxe Edition (Preis: 25 EUR)
  • Variante 2: CD Blumentopf - Musikmaschine MP3-only (Preis: 5 EUR)

Kategorien

varisale verwendet seinen eigenen Kategorie-Baum zur Strukturierung von Produkten. Kategorien können beliebig verschachtelt und einzeln online/offline geschaltet werden.

Mehrsprachigkeit

varisale unterstützt Mehrsprachigkeit nativ. Das heißt, dass Produkte, Kategorien, Länder, Liefermethoden, ... mehrsprachig gepflegt werden können, mit den folgenden Einschränkungen:

  • Jedes Element existiert in jeder Sprache. Dies entspricht der Artikelverwaltung aus SallyCMS, bei der auch jeder Artikel in jeder Sprache existiert.
  • Die Kategoriestruktur ist in allen Sprachen identisch, bis auf ihre Sortierung (da “Roman” und “Erotik” beides Kategorien sind, die unterhalb von “Bücher” liegen sollten, dort ab je nach Sprache anders sortiert sein können). Das gleiche gilt für Produkte.
  • Die online/offline-Stati aller Elemente werden pro Sprache gesetzt.

Die Sprache bestimmt im Frontend auch, in welcher Währung die Preise angezeigt werden, ebenso wie welches Land als Standard für das Liefer- und Rechnungsland bei Bestellungen angenommen wird (dies ist wichtig, wenn man bedenkt, dass Kunden gern sofort Bruttopreise sehen möchten, und diese von dem Steuersatz abhängig sind).

Länder

varisale bringt seine eigene Verwaltung von Ländern mit. Darin lassen sich die Länder verwalten, in die der Shop seine Produkte versendet oder die als Rechnungsland dienen können. Länder können pro Sprache benannt werden.

Steuersätze

Steuern werden in varisale pro Lieferland verwaltet. Jedem Produkt wird genau ein Steuersatz zugewiesen. Plain and simple.

Versand- und Bezahlmethoden

Beide Methoden sind abstrakte Informationen, die bis auf ihren Preis (“DHL Übernacht-Express” ist teurer als “Bimmelbahn”) keine besondere Bedeutung für varisale haben. Sie werden primär im Frontend ausgewertet, um nicht in Templates die verfügbaren Methoden hardcoded reinzuschreiben (und damit im Backend verwaltbar zu machen).

Die Methoden sind nicht mit irgendwelchen Plugins (wie PayPal oder sofortüberweisung.de) verknüpft. Diese Verknüpfung muss im Frontend im jeweiligen Code, der den Bestellprozess steuert, hergestellt werden.

Währungen

varisale kann frei zwischen den von der Europäischen Zentralbank bereitgestellten Währungen konvertieren. Der Preis eines Produkts kann also im Backend in EUR eingegeben werden und dann im Frontend auf der japanischen Seite automatisch in YEN und auf der polnischen automatisch in PLN angezeigt werden.

Warenkorb

Der Warenkorb (“Cart” in varisale-Sprech) ist eine Sammlung von Produkten, Versandmethode etc. (siehe weiter unten für die Eigenschaften einer Bestellung). Er verwaltet die zu kaufenden Produkte als sog. “Items”.

Für Besucher, die nicht eingeloggt (FrontendUser-Login, nicht Backend-Login!) sind, liegt der Warenkorb in der Session. Wird diese beendet, ist der Warenkorb weg. Damit können anonyme Besucher nicht die Datenbank zumüllen.

Der Warenkorb eingeloggter Benutzer liegt in der Datenbank und wird beim Login wiederhergestellt.

varisale kümmert sich selbst darum, bei Login/Logout den Warenkorb entsprechend zu verschieben.

Bestellungen

Ah, Bestellungen... was wäre ein Shop ohne sie? An dieser Stelle wird das bisher so einfache Konzept von varisale kompliziert. varisale muss sicherstellen, dass Änderungen an den Daten (Produktpreise, Steuersätze, ...) sich nicht auf bereits getätigte Bestellungen auswirken. Andere Systeme stellen dies sicher, indem sie einfach nur eine Bestell-eMail generieren und diese in der Datenbank ablegen.

Versionierung

varisale geht hier einen anderen Weg und verwendet eine Bedarfsversionierung. Das Konzept ist eigentlich ganz einfach zu verstehen: Immer, wenn eine Bestellung ausgeführt wird, werden alle relevanten Informationen kopiert. Da dies jedoch im Laufe der Zeit bei Shops, in denen sich selten Daten ändern, zu einem enormen Overhead führen würde, werden die Daten nur dann kopiert, wenn sie sich geändert haben.

Nehmen wir ein Produkt als Beispiel. Es wird im Backend eingestellt und steht zum Verkauf. Beim ersten Käufer werden alle Attribute, der Titel, Steuersatz, ... kopiert und mit einer Versionsnummer versehen. Bei jeder nachfolgenden Bestellung wird nur noch auf diese Version verwiesen (“Kunde hat Produkt X in Version 5 gekauft.”). Ändert sich etwas an dem Produkt, wird die Version auf @NULL zurückgesetzt, wodurch beim nächsten Bestellvorgang wieder eine neue Version erzeugt wird.

Dabei werden alle Daten einzeln versioniert. Steuersatz, Versandmethode, Bezahlmethode, Umrechnungskurse für Währungen (ja, sogar die!), Produktattribute (jeweils einzeln!) usw.

Dieses Konzept führt dazu, dass bei Shops, in denen sich selten Produkte ändern, auch nur selten Daten kopiert werden. Shops, die sich hingegen häufig ändern (aber in denen selten etwas bestellt wird), erzeugen nicht für jede Änderung immer wieder eine unnötige Version. Es entsteht also nur die minimal notwendige Menge an Daten.

API

In der API spiegelt sich dieses Konzept wider, indem es von vielen Klassen zwei Versionen gibt: Varisale_Model_XY_Live und Varisale_Model_XY_Versioned. Da man selten bis nie die Klassen direkt anspricht (d.h. anstelle von Varisale_Model_Product_Live::getInstance() wird man eher Varisale::getProduct() aufrufen), stellt dies kein Problem dar.

Inhalt einer Bestellung

Jede Bestellung besteht aus den folgenden Informationen (die im Bestellprozess entsprechend über die API gesetzt werden müssen!):

  • Menge von Produkten (Produkte im Warenkorb heißen “Items”)
  • Versandmethode
  • Liefermethode
  • Kunde (anonyme Bestellungen sind nur über Umwege möglich)

Erst, wenn alle vier Teile vorhanden sind (d.h. leere Bestellungen ohne Produkte sind nicht erlaubt), kann ein Warenkorb über @->checkout()@ in eine Bestellung umgeformt werden. Sollte eine Information fehlen, wird die Methode eine Exception werfen.

Key-Value-Pairs

Jede Bestellung enthält einen Key-Value-Store, über den projektspezifisch weitere Informationen abgelegt werden können. Dies ist zum Beispiel für Bezahlplugins nützlich: Das PayPal-Plugin wird dort u.a. die Transaktionsnummer abspeichern. Andere mögliche Einsatzzwecke sind Angaben wie Liefergebiet, Hinweise vom Kunden o.ä. Damit ist es leicht möglich, Bestellungen um weitere Angaben zu ergänzen.

Plugins

Plugins, die z.B. PayPal oder andere Bezahlmethoden bereitstellen, müssen im Frontend manuell aufgerufen werden. Die meisten Plugin stellen dazu eine ::execute()-Methode bereit. Siehe die dazu vorhandene Dokumentation beim Plugin.

Benutzer / Kunden

Kunden werden in varisale nicht verwaltet. Das gesamte Handling von Benutzern wird von FrontendUser übernommen. Dies hat zwei wichtige Folgen:

  1. varisale benötigt die Information, in welchem Benutzer-Attribut das Liefer- und das Rechnungsland kodiert. Dies ist in der YAML-Datei von varisale konfigurierbar.
  2. Zu jeder Bestellung muss ein Benutzer existieren. Shops, die anonyme Checkouts umsetzen wollen, müssen dies tun, indem sie im Hintergrund einen Dummy-Account anlegen (dessen Login und Passwort einfache Zufallsstrings sein können).

Da varisale nicht weiß, welche Eigenschaften ein Benutzer hat, ist das Format, das verwendet wird, um z.B. dessen Namen auszugeben, im Backend über Platzhalter (z.B. "#FIRSTNAME# #LASTNAME#") konfigurierbar.