Bereits seit längerem hatte ich im Forum von Magento einen Artikel über die Automatisierung von Lägerbeständen geschrieben. Aktuell muss ich dies für einen Kunden wieder aufgreifen, weshalb ich Euch das auf keinen Fall vorenthalten möchte.
Bei Mxperts habe ich bisher das Thema API noch nicht angesprochen. Aus diesem Grund werde ich dieses Tutorial mit der Magento-API realisieren. Die Aufgabenstellung ist zeimlich einfach. Es soll der Warenbestand unseres Onlineshops von einem externen System neu eingelesen werden. Da wir mit fiktiven Daten arbeiten, erstelle ich zuerst ein Script, welches mit Zufallszahlen als Lagerbestand liefert.
Datei: getStock.php

<?php
  mt_srand((double)microtime()*1000000);
  if ($_POST['sku'] != '') {
    echo mt_rand(0, 1000);
  } else {
    echo 'ERROR';
  }
?>

Was wir als nächstes benötigen wir eine Funktion um Post-Requests senden und auswerten zu können.
Datei: fn_post.php

<?php
function PostRequest($url, $referer, $_data) {

    // Variables Array in String konvertieren
    $data = array();
    while(list($n,$v) = each($_data)){
        $data[] = "$n=$v";
    }
    $data = implode('&', $data);
    // format --> test1=a&test2=b etc.

    // URL parsen
    $url = parse_url($url);
    if ($url['scheme'] != 'http') {
        die('Only HTTP request are supported !');
    }

    // Host und Path auslesen
    $host = $url['host'];
    $path = $url['path'];

    // Sockt-Verbindung auf Port 80 herstellen
    $fp = fsockopen($host, 80);

    // Header-Requerst senden
    fputs($fp, "POST $path HTTP/1.1\r\n");
    fputs($fp, "Host: $host\r\n");
    fputs($fp, "Referer: $referer\r\n");
    fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
    fputs($fp, "Content-length: ". strlen($data) ."\r\n");
    fputs($fp, "Connection: close\r\n\r\n");
    fputs($fp, $data);

    $result = '';
    while(!feof($fp)) {
        // Ergebnisse des Requests auslesen
        $result .= fgets($fp, 128);
    }

    // Socket schliessen
    fclose($fp);

    // Header und Inhalt trennen
    $result = explode("\r\n\r\n", $result, 2);

    $header = isset($result[0]) ? $result[0] : '';
    $content = isset($result[1]) ? $result[1] : '';

    // Array zurückgeben
    return array($header, $content);
}
?>

Nun haben wir die Möglichkeit Lagerbestände via HTTP-Request von externen Seiten zu beziehen. Sie müssen die Übergabeparameter und die Auswertung nur noch den Bedürfnissen Ihrer Lieferanten anpassen. Nun folgt das Herzstück – die Steuerung über die Magento-API.
Datei: update_stock.php

<?php
  require 'fn_post.php'; // Funktion für HTTP-Request

  // Template für die Ausgabe
  $template = '<div style="background-color:#%s;font-family:Verdana;font-size:11px;margin-bottom:4px;padding:2px;">';
  $template .= '<div style="float:left;width:150px;">Position:</div><div>%s</div>';
  $template .= '<div style="float:left;width:150px;">Produkt-ID:</div><div>%s</div>';
  $template .= '<div style="float:left;width:150px;">Artikelnummer:</div><div>%s</div>';
  $template .= '<div style="float:left;width:150px;">alter Lagerbestand:</div><div>%s</div>';
  $template .= '<div style="float:left;width:150px;">neuer Lagerbestand:</div><div>%s</div>';
  $template .= '<div style="float:left;width:150px;">Lieferbar alt:</div><div>%s</div>';
  $template .= '<div style="float:left;width:150px;">Lieferbar neu:</div><div>%s</div>';
  $template .= '</div';

  $proxy = new SoapClient('http://domain.de/api/soap/?wsdl'); // ÄNDERN
  $sessionId = $proxy->login('apiUser', 'apiKey'); // ÄNDERN

  // Produktliste auslesen
  $products = $proxy->call($sessionId, 'product.list');

  $i = 0;
  foreach ($products as $product) {
    $products_id = $product['product_id'];
    $sku = $product['sku'];
    $i++;
    $data = array('sku' => $sku);

    // Lagerbestand extern via HTTP-Request einholen
    list($header, $content) = PostRequest("http://seifert.tmedia-shop.de/getStock.php","http://seifert.tmedia-shop.de",$data);
    $stock = $content;

    // Wenn Bestand > 0 Lieferbar, sonst nicht
    if ($stock > 0) { $in_stock = 1; } else { $in_stock = 0; }

    // auslesen des alten Lagerbestandes
    $old_stock = ($proxy->call($sessionId, 'product_stock.list', $products_id));
    // Neuer Lagerbestand und Lieferstatus schreiben
    $proxy->call($sessionId, 'product_stock.update', array($products_id, array('qty'=>$stock, 'is_in_stock'=>$in_stock)));

    // alternierende Farben für die Ausgabe
    if ($i % 2 == 0) { $color = 'DDD'; } else { $color = 'AAA'; }
    // Werte ausgeben
    printf($template,$color,$i,$products_id,$sku,$old_stock[0]['qty'],$stock,$old_stock[0]['is_in_stock'],$in_stock);
    flush;
  }
?>

Den Sourcecode habe ich dokumentiert und ich hoffe das ist selbsterklärend. Falls nicht – einfach eine PM an mich senden.

Um die API zu benutzen muss man im Backend zuerst einen Webservice erstellen.
Folgende Zeilen müssen dann im Sourcecode noch angepasst werden:

$proxy = new SoapClient(‘http://domain.de/api/soap/?wsdl‘); // ÄNDERN
$sessionId = $proxy->login(’apiUser‘, ’apiKey‘); // ÄNDERN

Die Ausgabe ist dann wie folgt:

Die Ausgabe und das Einlesen des alten Betsandes kann man natürlich weglassen. Ich würde im Livebetrieb ein Log-File erstellen oder einen Mailer mit Reporting.



Viele Grüße
Johannes Teitge