Türchen 01: Konfiguration unnötig

Es ist schon wieder Dezember und mit Freude, darf ich dieses Jahr wieder den Anfang machen, lieber Tobi, lieber Ingo, danke für die Gelegenheit. Ich möchte mit einer kleinen Geschichte anfangen. Ich hatte letzte Woche eine Unterhaltung mit einem Kunden, der HTML und CSS Dateien direkt auf dem Live-Server bearbeitet hat. Wir waren uns darin einig, dass das leider keine gute Idee war, denn die Dateien und Änderungen landen nicht in der Versionskontrolle. Diese Unterhaltungen werden glücklicherweise seltener. Wir verwalten unseren Code im git oder SVN und liefern ihn kontrolliert mit aus, mit einem git pull, cap deploy (capistrano) oder svn up. Es gibt sicher noch ein paar andere schöne Skripte, aber im großen und ganzen ist das Problem des inkonsisten Codes auf Dateiebene gelöst.

Änderungen in der Datenbank

Aber Dateien sind ja nur die eine Hälfte von Magento. Die andere Hälfte, sprich die Datenbank, ist leider nicht so leicht zu kontrollieren und zu versionieren.

Konsequent benutzte Install-Skripte können hier einige der größten Probleme lösen. Attribute, auch solche für Produkte, sollten nur mit Skripten angelegt werden, Kategorien, Kategoriebäume, Websites, Storegroups und Stores werden auch nur mit Skripten erzeugt. Mit diesem Vorgehen hat man schon einen relativ konsistenten Stand zwischen Entwicklungsumgebung, Testsystem, Staging und Live-System. (An dieser Stelle denken wir uns beliebige andere Systeme, z.B. ein Contionous-Integration System auf dem die Tests laufen oder beliebig viele Entwicklungssysteme für die einzelnen Entwickler). Das Problem ist, dass alle Tests, ob automatisiert oder durch einen Menschen, wenig verlässlich sind, wenn die Systeme nicht gleich konfiguriert sind. Daneben bleiben noch einige Bereiche: unter anderem alles unter

System > Konfiguration
.

Dieser Blogbeitrag soll sich aber der Konfiguration widmen und eine Methode vorstellen, die euch hoffentlich in der täglichen Arbeit hilft. Ich bin noch nicht überzeugt, dass das folgende eine gute Idee ist. Ich freue mich über eine rege Diskussion in den Kommentaren.

Mage_Core_Model_Config

Die Magentokonfiguration speist sich aus vielen verschiedenen Quellen, Carmen aka neoshops hat im letzten Jahr einen tollen Beitrag zu dem Thema geschrieben, der weiter in die Tiefe geht als ich jetzt.

Konfigurationsquellen

Kurz gesagt, Magento lädt folgende Dateien:

app/etc/local.xml
app/etc/*.xml
app/etc/modules/*.xml
app/code/<codePool>/<Namespace>/<Module>/etc/config.xml
app/etc/local.xml

Man beachte hierbei, dass am Ende des Prozesses die local.xml noch einmal geladen wird. Das hat zur Konsequenz, das alles was in der
local.xml
steht garantiert in der Konfiguration landet - mit einer Ausnahme: Konfigurationswerte aus der Datenbank.

Scope

Die Konfiguration hat drei Scopes:

  • Storeview
  • Website
  • Default

Magento bietet die Möglichkeit Konfigurationswerte, also z.B. die Base-URL, den Namen des Stores oder die verwendete Sprache auf verschiedenen Ebenen zu definieren. Die Ebenen vererben die Einstellungen an ihre Kinder.

Default
|-- DVD und Video Shop (Website)
|   |-- deutscher Shop (Store Group / Store)
|   |   |-- deutsch (Store / Store View)
|   |   +-- englisch (Store / Store View)    
|   +-- schweizer Shop (Store Group / Store)
|       |-- französisch (Store / Store View)
|       |-- italienisch (Store / Store View)
|       +-- schweizerdeutsch (Store / Store View)
|
+-- Shirt und Pullover Shop (Website)
...

Leider hat Magento irgendwann die Bezeichnungen getautscht. So ist im Code von Website, Storegroup und Store die Rede, aber im Backend von Website, Store und Store View.

alt         |   neu
Website     |   Website
Store Group |   Store
Store       |   Store View

Beispiel:

Das Impressum für die beiden Websites ist gleich (default), aber beide Websites haben unterschiedliche Namen. Diese werden allerdings an alle Storeviews vererbt. Abschließend stellen wir unabhängig von Website und Default auf Storeview-Ebene die Sprache ein.

System > Konfiguration

Bei den meisten Shops läuft es so, dass jemand in das Backend geht und die Einstellungen macht. Diese werden dann in der Datenbank gespeichert. Im besten Fall, wird die Datenbank kopiert und auf die verschiedenen Systeme gespielt. Im schlimmsten Fall, "kopiert" jemand die Einstellungen manuell und vergisst dabei hoffentlich keine. Ich möchte eine Alternative dazu vorstellen.

Konfigurationsvariablen

Alan Storm hat einen langen, langen Artikel zum Thema Konfigurationsvariablen geschrieben, wer also mehr technischen Hintergrund haben möchte zu dem folgenden, einfach dem Link folgen.

Aufbau der Konfiguration

Die verschiedenen Scopes werden in der Konfiguration folgendermaßen abgebildet:

<config>
    <default>
    </default>
    <websites>
        <admin></admin>
        <base></base>
    </websites>
    <stores>
        <admin></admin>
        <default></default>
    </stores>
</config>

Magento kümmert sich beim Laden der Konfiguration bereits darum, die Vererbung durch kopieren der Knoten zu realisieren, d.h. wenn folgende Knoten und Werte gibt
default/general/imprint/shop_name        => Mein cooler Shopname
websites/admin/general/imprint/shop_name => Adminshop

aber keine Knoten
websites/base/general/imprint/shop_name
stores/admin/general/imprint/shop_name
stores/default/general/imprint/shop_name

kopiert Magento die Werte an die entsprechenden Stellen unterhalb der Vererbungshierarchie:
stores/admin/general/imprint/shop_name   => Adminshop
websites/base/general/imprint/shop_name  => Mein cooler Shopname
stores/default/general/imprint/shop_name => Mein cooler Shopname

Mage_Core_Model_Config->_xml

Die Konfiguration innerhalb des Konfigurationsmodels wird auch nach dem zusammenführen aller Quellen weiter als XML behandelt. Wichtig hierbei ist, dass wir jeden Knoten innerhalb der Konfiguration aus vielen XML-Dateien beinflussen können.

local.xml, *.xml, config.xml, local.xml

Insbesondere halte ich hier die

app/etc/local.xml
, alle anderen XML-Dateien in
app/etc/*.xml
und alle
config.xml
-Dateien der verschiedenen Module für erwähnenswert. Theoretisch geht auch eine beliebige
app/etc/modules/*.xml
, aber um Himmels willen, lasst das sein, an dieser Stelle sucht NIEMAND, wenn es Probleme gibt! Die Grundkonfiguration kann entweder in einer
config.xml
stehen oder in einer beliebigen XML-Datei in
app/etc/
. Die Konfiguration kann z.B. so aussehen:
<?xml version="1.0"?>
<config>
    <stores>
        <de>
            <general>
                <store_information>
                    <name>Deutscher Store View</name>
                </store_information>
            </general>                        
        </de>
    </stores>
    <websites>
        <another_website>
        </another_website>
        <websiteA>
            <general>
                <store_information>
                    <name>Website A</name>
                </store_information>
            </general>
        </websiteA>
    </websites>
    <default>
        <admin>
            <security>
                <use_form_key>1</use_form_key>
                <use_case_sensitive_login>1</use_case_sensitive_login>
            </security>
            <dashboard>
                <enable_charts>1</enable_charts>
            </dashboard>
            <captcha>
                <enable>0</enable>
            </captcha>
        </admin>
    </default>
</config>

Diese Konfiguration, die für alle Instanzen gelten soll, wird also in
app/etc/local.live.xml
gespeichert. Alle Daten, die in den Instanzen unterschiedich sind, also z.B. URLs und Datenbankzugangsdaten werden zusätzlich in
app/code/local.xml
gespeichert. Auf diese Weise wandert die komplette Konfiguration auch in die Versionsverwaltung.

Tipps zum Ende

Um die Konfiguration das erste Mal in die Datei zu kriegen, kann man diese im Backend erstellen und ein kleines Script schreiben um die Datei zu erzeugen. Ich habe bisher die Datei immer von Hand erstellt, weil es mich furchtbar nervt mich durch das Backend zu klicken. Falls jemand ein kleines Script hat, einfach rein in die Kommentare.



Ein Beitrag von Fabian Blechschmidt
Fabian's avatar

Fabian Blechschmidt entwickelt seit 2004 mit PHP. Vier Jahre später hat er sich damit selbstständig gemacht und ist seit 2011 auf Magento fokusiert. Im Oktober 2011 hat er erfolgreich die Prüfung zum Magento Certified Developer absolviert. In seiner Freizeit besucht er gerne Magento Stammtische und hält unter anderem dort Vorträge. Außerdem organisiert er mit an den Magento Hackathons.

Alle Beiträge von Fabian

Kommentare
Webguys Magento Adventskalender | Mag-tutorials.de am

[…] Türchen 01: Konfiguration unnötig […]

Linktip: Der Webguys Adventskalender 2013 » Kai Köpke am

[…] gestern ging es los mit Türchen 01: Konfiguration unnötig - einem Artikel von Fabian Blechschmidt (über Install-Skripte für Attribute, Kategorien, […]

Magento-Neuigkeiten der Woche 48/2013 am

[…] Webguys-Magento-Adventkalenders findet seit gestern ihre Fortsetzung. Die bisherigen Themen: “Konfiguration unnötig” und “PhpStorm – besser, schneller, […]

Jan Brinkmann am

Das ist wirklich eine tolle Idee, gerade für das Deployment von Änderungen bei größeren Projekten. Wenn da Änderungen erst nach einigen Wochen online gehen, evt. sogar durch fremde Hände, hat das enormes Fehlerpotential.

Carmen am

Danke Fabian aka Schrank (an Schrank-fährt-Zug-Tagen auch aka Schrank1, Schrank2, Schrank3 im IRC) für die nette Erwähnung! Ich habe bis Mitternacht mitgefiebert, ob Du das Eröffner-Türchen noch schaffst und bin sehr froh, dass Du es noch hinbekommen hast!

Marc Jakubowski am

Oder mal https://github.com/2Boys1Shop/Twoboysoneshop_Configr anschauen, damit bekommt man eine Config Historie aus der man Update Scripte generieren oder Änderungen zurückrollen kann.

Francesco am

Ein möglicher Nachteil ist, dass Module auch oft die default-Werte für die Einstellungen in deren config.xml definieren. Magento lädt die Dateien unter app/etc vor den config.xml untern app/code. Deshalb ist es nicht möglich, diese default-Werte zu überschreiben. Man kann aber ein neues Modul anlegen - zB Projektname_Core - und hier die gesamten Einstellungen definieren. Durch Abhängigkeit kann man auch sicherstellen, dass die Module in der richtigen Reihenfolge geladen werden.

Hier ein kleines Skript :-) https://gist.github.com/fmarangi/7730443

Christian Münch am

Vielleicht interessannt... es ist auch Möglich die Konfiguration im Magento Admin vorzunehmen und dann ein Setup Script automatisch über n98-magerun erstellen zu lassen.

Beispiel:

n98-magerun.phar config:get "web/*" --update-script

Das erstellt dann ein Script aller manuellen Einstellungen aus der Sektion "web".

Tobias Vogt am

Danke für den Beitrag. Sehr gute Hinweise. Gerade bei fremden shops würde ich mir häufiger ein paar gute vorlagen zum entwickeln wünschen :-)

Vlt wird es ja so besser!

Dein Kommentar