phpbar.de logo

Mailinglisten-Archive

[php] Wiki-Zugriff von PHP aus / dynamische Wiki-Inhalte - Lösung

[php] Wiki-Zugriff von PHP aus / dynamische Wiki-Inhalte - Lösung

Mario Haßler M.Hassler at gmx.de
Mo Jan 18 21:40:28 CET 2010


Hello again,

ich melde heute den Erfolg. Ausgehend von dem Script, das Klemens vor-
geschlagen hat (http://jeff.loiselles.com/projects/Bugzilla-0.5.phps),
habe ich meinem PHP-Skript beigebracht, Wiki-Seiten zu bearbeiten. Für
den Fall, dass es jemanden interessiert, hier meine Lösung:


// -- START --

require_once('HTTP/Client.php');

class WikiPage {
	public $wpTextbox1;
	public $wpSummary;
//	public $wpMinoredit;
//	public $wpWatchthis;
	public $wpSave;
//	public $wpSection;
	public $wpEdittime;
	public $wpEditToken;

	public function __construct($field_array = NULL) {
		if (is_array($field_array)) {
			foreach ($field_array as $k => $f) {
				$this->{$k} = $f;
			}
		}
	}

	public function __toArray() {
	return get_object_vars($this);
	}

	public function toArray() {
	return $this->__toArray();
	}
}

class Wiki {
	private $server;
	private $user;
	private $password;

	private $_http_client;
	private $login_ok;

	public function __construct($server, $user, $password) {
		$this->server   = $server;
		$this->user     = $user;
		$this->password = $password;

		$this->_http_client = new HTTP_Client();
		$this->_login();
	}

	private function _login() {
		$url = $this->server.'?title=Spezial:Userlogin';
		$preEncoded = TRUE;
		$params = array();
		$params['wpName']         = urlencode($this->user);
		$params['wpPassword']     = urlencode($this->password);
		$params['wpLoginattempt'] = 'Anmelden';
		$this->_http_client->post($url, $params, $preEncoded);
		// Login war erfolgreich, wenn die zurückgelieferte Seite kein "class='error'" enthält:
		$RESPONSE = $this->_http_client->currentResponse();
		$this->login_ok = (strpos($RESPONSE['body'], "class='error'") === false);
	}

	public function editPage($title, $WikiPage) {
		$url = $this->server.$title;
		// Vorbelegung für "wpEditToken" und "wpEdittime" ermitteln:
		$this->_http_client->get($url);
		$RESPONSE = $this->_http_client->currentResponse();
		$WikiPage->wpEditToken = preg_replace("/.*value=\"(.*?)\".*/", "$1", preg_replace("/.*(<input .*?wpEditToken.*?>).*/si", "$1", $RESPONSE['body']));
		$WikiPage->wpEdittime = preg_replace("/.*value=\"(.*?)\".*/", "$1", preg_replace("/.*(<input .*?wpEdittime.*?>).*/si", "$1", $RESPONSE['body']));
		// Seite speichern:
		$preEncoded = FALSE;
		$data = $WikiPage->toArray();
		$this->_http_client->post($url, $data, $preEncoded);
	}

	public function getLoginStatus() {
		return $this->login_ok;
	}
}


// Aufruf:
$wiki = new Wiki($wiki_url, $benutzer, $password);
if ($wiki->getLoginStatus()) {
	$wikipage = new WikiPage();
	$wikipage->wpTextbox1 = $text;
	$wikipage->wpSummary = "Automatisch erzeugter Inhalt";
	$wikipage->wpSave ="Artikel speichern";
	$wiki->editPage("?title=".$titel."&action=submit", $wikipage);
}

// -- ENDE --


Dazu ein paar Anmerkungen:

1. Belegt man die Felder "wpMinoredit" und "wpWatchthis" mit irgend-
einem Wert, sind die entsprechenden Funktionen ("nur Kleinigkeiten
wurden geändert" bzw. "Artikel beobachten") aktiv. Standardmäßig sind
sie daher auskommentiert.

2. Die Parameter werden dem HTTP-Client als Array übergeben und nicht
als "parameter=wert"-Text, um ein POST zu erzwingen und Konflikte mit
der URL zu vermeiden, die eigene Parameter-Wert-Kombinationen enthält.

3. Anders als beim ursprünglichen Beispiel (das für Bugzilla geschrie-
ben wurde) sagt der HTTP-Returncode nichts darüber aus, ob der Login
erfolgreich war. Auch bei fehlgeschlagenem Login wird eine gültige
Seite mit dem Code 200 (= OK) geliefert. Bei fehlgeschlagenem Login
enthält diese (zumindest in unserem Wiki) allerdings einen Fehler-
hinweis, der mit "class='error'" ausgezeichnet ist. Dies wertet die
Login-Funktion aus.

4. Wiki vergibt für jeden Edit-Aufruf einen Token, der beim Empfang
der geänderten Daten überprüft wird. Um den Inhalt dieses Tokens zu
ermitteln, ist mir nichts besseres eingefallen, als zunächst die Edit-
Seite aufzurufen und in den <input>-Elementen nach diesem Token zu
suchen und ihn auszulesen.

5. Beim Aufruf von editPage() ist zu beachten, dass die URL den Titel
der Seite als Parameter verlangt, und zwar in der Wiki-Notation (aus
dem Titel "Am Anfang" wird beispielsweise "?title=Am_Anfang").

Wie ich schon mal erwähnt habe, sind meine Programmiererfahrungen mit
"class"-Elementen gleich null. Es kann also sein, dass ich es hier und
da umständlicher gemacht habe als nötig. Wenn jemand noch etwas auf-
fällt, was einfacher, besser oder richtiger gemacht werden könnte:
Ich nehme jede Kritik gerne entgegen.

Abschließend nochmals vielen Dank für die Unterstützung!

Viele Grüße,

Mario Haßler

php::bar PHP Wiki   -   Listenarchive