Wir standen letzens vor der Problemstellung, Newseinträge der alten Firmenpräsenz für einen Relaunch in ein Wordpress importieren zu müssen. Es liegt nahe, hierfür die xmlrpc-API von Wordpress zu verwenden; die API ist gut dokumentiert und die Instanzen müssen nicht auf der gleichen Maschine laufen, zudem ist es mit den Mitteln des Zend Frameworks mit ein paar Handgriffen erledigt. Leider hat die Sache einen Haken - die Dokumentation der Schnittstelle ist fehlerhaft, veraltet oder passt nicht zum Problem, jedenfalls reagierte Wordpress nicht wie beschrieben.
wp.newPost - das Problem mit post_date
Im Wordpress Codex wird der Parameter für das Erstellungsdatum wie folgt beschrieben: struct terms: Taxonomy names as keys, array of term IDs as values. Das ist etwas dürftig, es existiert aber der Hinweis: any other fields supported by wp_insert_post. Die verlinkte Seite spezifiziert das Feld post_date wie folgt: 'post_date' => [ Y-m-d H:i:s ] //The time post was made. Das mag für den direkten Aufruf der API-Funktion gelten, nicht aber für die Kapselung durch die XMLRPC-Schnittstelle, wie wir nach stundenlangem Herumprobieren und schliesslich Debugging im Source der Schnittstellen-Behandlung herausgefunden haben. Die Schnittstelle quittiert nämlich zu allem Überfluss, entgegen den Angaben in der Doku, jeglichen Fehler lapidar mit dem Status 403.
Die Lösung
Die XMLRPC-Schnittstelle erwartet ein Datum encodiert nach ISO.8601, dies wird im Aufruf signalisiert durch eine Kapselung des Datums in den Tags <date.iso8601> Diese Kapselung kann man aber nicht selbst vornehmen, da das Tag selbst encoded werden würde. Mit den Mitteln des Zend Frameworks (wenn man z.B. Zend_XmlRpc_Client verwendet) erreicht man die Encapsulation, in dem man Zend_XmlRpc_Value_DateTime als Datentyp verwendet. Das Zend Framework setzt dann beim Absetzen des Requests das Datum automatisch in die erforderlichen Tags. Hier ein Beispiel des Codes:
Ein Codebeispiel
// $date = "".date("Ymd\TH:i:se", time()).""; $date = new Zend_XmlRpc_Value_DateTime(time()); $content = array( "post_type" => "post", "post_status" => "publish", "post_title" => $news_info["titel"], "post_author" => 3, // Die ID des Wordpress-Users "post_content" => $news_info["text"], "post_date" => $date, "comment_status" => "closed", "ping_status" => "closed", "terms" => array("category" => array(1)) // Allgemeines ); $post_id = $client->call("wp.newPost", array(0, "USER", "PASSWORT", $content));