Wenn Sie mit einer WaWi(Warenwirtschaft) arbeiten, möchten Sie sicherlich die Auftragsdaten auch in Ihre WaWi importieren/einspielen. Wenn möglich sollten die Daten in Realtime, als sobald eine Bestellung erfolgt übertragen werden. Man könnte nun die dafür zuständige Klasse überschreiben – an dieser Stelle möchte ich aber zeigen, dass es auch noch eine andere Möglichkeit gibt. Magento löst bei bestimmten Aktionen sogenannte Events/Ereignisse aus. Diese kann man abfragen und eigene Funktionen hinterlegen.

Aber – man muss dafür ein eigenes Modul erstellen. Wie immer beim Erstellen eines Magento-Moduls, befindet sich die Basisdefintion in der config.xml.

<config>
...
  <frontend>
    <events>
      <EVENT>
        <observers>
          <bezeichnung>
            <type>singleton></type>
            <class>model/observer</class>
            <method>funktionsname</method>
          </bezeichnung>
        </observers>
      </EVENT>
    </events>
  </frontend>
...
</config>

Bei EVENTS muss ein Ereignis eingetragen werden, welches man überwachen und auswerten möchten. In meinem Fall verwende ich das Ereignis checkout_onepage_controller_success_action, welches bei Neubestellungen im Frontend ausgelöst wird. Wie Sebastian (unten in den Kommentaren) angeregt hat kann man alternativ auch die Ereignissse checkout_type_onepage_save_order_after oder sales_order_save_after verwenden.

Branko Ajzele hat eine Übersicht aller Events von Magento 1.3.0 erstellt – es lohnt sich diese genauser anzusehen.
Die Bezeichnung kann frei gewählt werden. Der Typ kann model oder singelton sein. Bei einem Model-Observer wird vor jedem Aufruf der Methode eine neue Instanz des Observers erstellt, wobei bei einem Singelton-Observer nur eine Instanz erstellt wird. Die Klassendefintion (class) beinhaltet die Model-Defintionen mit der dazugehörenden PHP-Datei. Die Defintion des aufzurufenden Methode erklärt sich ja von selbst.

Nach dieser trockenen Theorie wollen wir uns doch gleich an ein praktisches Beispiel wagen. Mit meiner Erweiterung möchte ich nach einem erfolgreichen Bestellprozess die Bestelldaten auslesen und als Datei abspeichern. Sie haben nach Fertigstellung dieses Tutorials ein komplettes Grundgerüst für die Verarbeitung von Bestelldaten nach dem Absenden eines neuen Auftrages im Onlineshop.

Umsetzung

1. app/etx/modules/Mxperts_CheckoutSuccess.xml

<?xml version="1.0"?>
<config>
  <modules>
    <Mxperts_CheckoutSuccess>
      <active>true</active>
      <codePool>local</codePool>
    </Mxperts_CheckoutSuccess>
  </modules>
</config>

Als erstes müssen wir unsere Erweiterung bei Magento registrieren. Dies erfolgt mit der oben aufgeführen Datei. Links finden Sie den kompletten Verzeichnisbaum, der für dieses Tutorial benötigt wird. Ich füge diese Erweiterung wieder in unsere Mxperts-Serie ein. Falls Sie Fragen zur Programmierung von Extensions haben, möchte ich sie an dieser Stelle auf unsere Reihe Extension Tutorial Teil1-Teil10 verweisen.

2. app/code/local/Mxperts/CheckoutSuccess/etc/config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>

  <modules>
    <Mxperts_CheckoutSuccess>
        <version>1.0.0</version>
    </Mxperts_CheckoutSuccess>
  </modules>

  <global>
    <models>
      <checkoutsuccess>
        <class>Mxperts_CheckoutSuccess_Model</class>
      </checkoutsuccess>
    </models>
  </global>

  <frontend>
    <events>
      <checkout_onepage_controller_success_action>
        <observers>
	  <beliebige_bezeichnung>
            <type>singleton</type>
            <class>checkoutsuccess/observer</class>
            <method>meine_funktion</method>
          </beliebige_bezeichnung>
        </observers>
      </checkout_onepage_controller_success_action>
    </events>
  </frontend>

</config>

Der Aufbau der Datei erfolgt wie bereits weiter oben beschrieben. In einigen Beispielen im Magento-Forum hat die Models-Defintion gefehlt. Dies führte zwangsläufig zu Fehlermeldungen, da Magento die PHP-Datei dann im Core sucht.
Wenn wir die Models-Defintion weglassen, erhält man folgende Fehlermeldung:

Warning: include(Mage/Checkoutsuccess/Model/Observer.php) [function.include]: failed to open stream: No such file or directory  in /var/www/vhosts/mxperts.de/subdomains/shop/httpdocs/app/code/core/Mage/Core/functions.php on line 70
Trace:
#0 /var/www/vhosts/mxperts.de/subdomains/shop/httpdocs/app/code/core/Mage/Core/functions.php(70): mageCoreErrorHandler(2, 'include(Mage/Ch...', '/var/www/vhosts...', 70, Array)
#1 /var/www/vhosts/mxperts.de/subdomains/shop/httpdocs/app/code/core/Mage/Core/functions.php(70): __autoload()
#2 [internal function]: __autoload('Mage_Checkoutsu...')
...

3. app\code\local\Mxperts\CheckoutSuccess\Model\Observer.php

<?php
  class Mxperts_CheckoutSuccess_Model_Observer extends Mage_Core_Model_Abstract {

    public function __construct()
    {
        $fp = fopen('obs_created.txt','w+');
        fwrite($fp, "Objekt Mxperts_CheckoutSuccess_Model_Observer erstellt!! ".date("Y-m-d H:i:s")."\n");
        fclose($fp);
    }

    public function meine_funktion($observer)
    {
        $event = $observer->getEvent();
//        !-fehlercode!();
        $fp = fopen('obs_order.txt','w+');
        fwrite($fp, "------------[Neuer Auftrag]-----------------\n");

        $orderId = Mage::getSingleton('checkout/type_onepage')->getCheckout()->getLastOrderId();
        $order = Mage::getModel('sales/order')->load($orderId);
        $items = $order->getAllItems();

        fwrite($fp, "\n".'$event ='."\n");
        fwrite($fp, print_r($event, true) );

        fwrite($fp, "\n".'$order ='."\n");
        fwrite($fp, print_r($order, true) );

        fwrite($fp, "\n".'$items ='."\n");
        fwrite($fp, print_r($items, true) );

        fwrite($fp, "\n".'$_SESSION ='."\n");
        fwrite($fp, print_r($_SESSION, true) );

        fclose($fp);
    }

  }
?>

Nachdem wir unsere Klasse definiert haben, muss nur noch der Cache aktualisiert werden. Erstellen Sie in Ihrem Magento-Shop nun einen neuen Auftrag. Danach sollten sich im Root-Verzeichnis die beiden Datein obs_created.txt und obs_ordered.txt mit entsprechenden Daten befinden. Falls Sie kein Ergebnis bekommen, entfernen Sie den Kommentar bei !-fehlercode!();. Bei nochmaliger Bestellung sollten Sie einen Fehler erhalten. Its dies nicht der Falls kontrollieren Sie nochmals Ihre config.xml.

WICHTIG: Löscht nach der Testphase die erzeugten Textdatein, da sich darin auch Daten aus der Konfiguration von Magento befinden!

Nun können Sie die Funktion mit vernünftigem Inhalte füllen. In unserem Falls ist das eine spezielle Formatierung und die Weiterleitung an eine Warenwirtschaft.

Download aller Dateien: event_observer.zip

Viele Grüße
Johannes Teitge