<?php

  // Most simple test program
  // (adds "Hallo" to the german Spielwiese, summary is "Testedit")
  // $mwbot = new MwBot("de.wikipedia.org", "Username", "password");
  // $mwbot->savePage("Wikipedia:Spielwiese", $mwbot->readPage("Wikipedia:Spielwiese") . "\nHallo", "Testedit");

   class MwBot {
    protected $host;
    protected $username;
    protected $password;
    protected $cookies;

    public $bot = 1; // set to 0 if this edit should not be marked as bot edit

    public function MwBot($host, $username, $password) {
      $this->host     = $host;
      $this->username = $username;
      $this->password = $password;
      $this->cookies  = "";
	  
      $this->login();
    }
		
    protected function login() {
      // first step: get login token
      $data = "action=query&format=php&meta=tokens&type=login";
      $website = $this->PostToHost($this->host, "/w/api.php", $data);
      $this->cookies = $this->GetCookies($website);
      $website = trim(substr($website, strpos($website, "\n\r\n")));
      $answer = unserialize($website);  
      $login_token = $answer['query']['tokens']['logintoken'];
	  if ($login_token == "") {
	    trigger_error("Cannot get valid login token\n", E_USER_ERROR);
	  }
      
      // second step: perform login
      $data = "action=login&format=php&lgname=" . urlencode($this->username) . "&lgpassword=" . urlencode($this->password) . "&lgtoken=" . urlencode($login_token);
      $website = $this->PostToHost($this->host, "/w/api.php", $data);
	  $this->cookies = $this->GetCookies($website);
    }
		
    public function savePage($title, $content, $summary) {
      // get edit token
      $data = "action=query&format=php&meta=tokens&type=csrf";
      $website = $this->PostToHost($this->host, "/w/api.php", $data);
      $website = trim(substr($website, strpos($website, "\n\r\n"))); // remove header
      $answer = unserialize($website);
      $token = $answer['query']['tokens']['csrftoken'];
    
      // now save using the edit token
      $data = "action=edit&format=php&title=" . urlencode($title) . "&text=" . urlencode($content) . "&token=" . urlencode($token) . "&summary=" . urlencode($summary) . "&bot=" . $this->bot;
      $website = $this->PostToHost($this->host, "/w/api.php", $data);
    }
    
    public function readPage($title) {
      $crl = curl_init();
      curl_setopt ($crl, CURLOPT_URL, "https://" . $this->host . "/w/index.php?title=" . urlencode($title) . "&action=raw");
      curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, 5); // 5 seconds
      curl_setopt ($crl, CURLOPT_USERAGENT, "MwBot"); 
      $ret = curl_exec($crl);
      curl_close($crl);
      return $ret;
    }
		
    // POST-Funktion
    protected function PostToHost($host, $path, $data) {
      $fp = fsockopen("ssl://" . $host, 443, $errno, $errstr, 30);
      if (!$fp) { 
	    trigger_error("Cannot create fsock:" . $errstr . " (" . $errno . ")\n", E_USER_ERROR); 
	  }
	  $str  = "POST " . $path . " HTTP/1.0\r\n";
	  $str .= "Host: " . $host . "\r\n";
	  $str .= "User-Agent: MwBot\r\n";
	  $str .= "Connection: close\r\n";
	  $str .= "Content-type: application/x-www-form-urlencoded\r\n";
	  $str .= "Content-length: ". strlen($data) ."\r\n";
      if ($this->cookies != "") {
	    $str .= $this->cookies;
	  }
	  $str .= "\r\n";
	  $str .= $data;
      fputs($fp, $str);
      $res = "";
      while (!feof($fp)) {
	    $res .= fgets($fp, 128);
	  }
      fclose($fp);
      return $res;
    }
    
    protected function GetCookies($website) {
      $cookies = "";
      $regexp = "/Set-Cookie: ([^;]+)/";
      preg_match_all($regexp, $website, $treffer, PREG_SET_ORDER);
      foreach ($treffer as $wert) {
	    if (trim($wert[1]) != "" && strpos($wert[1], "=deleted") == false) {
	      $cookies .= "" . $wert[1] . "; ";
	    }
	  }
      return "Cookie: " . $cookies . "\r\n"; 
    }
  }

?>