Utilisateur:Amgine/mwAPI.php

<?php
/**
 * mwAPI class
 **
 * Class to hold methods re: Mediawiki API
 * 
 * This class has several dependencies/assumptions
 * 		* PHP libcurl module is enabled
 * 		* script has read/write privileges in the folder where it is run.
 * 		  (allowing it to store cookies)
 * 		* mwApiXmlParse class (in mwApiXmlParse.php)
 **
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 *  more details.
 *
 *  You should have received a copy of the GNU General Public License along with
 *  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 *  Place - Suite 330, Boston, MA 02111-1307, USA.
 *  http://www.gnu.org/copyleft/gpl.html
 **
 * @author Amgine <amgine.saewyc@gmail.com>
 * @copyright 2009, 2010 by Amgine <amgine.saewyc@gmail.com>
 */
class mwAPI{
	/**
	 * @var	string	qualified domain/path to api
	 **/
	protected $address = '';
	
	/**
	 * @var	array	Cookie management/storage
	 **/
	public $cookieJar = array();
	
	/**
	 * @var	string	cURL handle
	 **/
	private $ch = '';
	
	/**
	 * @var	string	Contents of the output buffer from cURL action.
	 **
	 * WARNING:	this buffer is over-written with every execCurl.
	 **/
	public $curlBuffer = '';
	
	/**
	 * @var	string	xml parser reference
	 **/
	public $xml_parser = '';
	
	/**
	 * @var object	mwApiXmlItem
	 */
	public $item = array();
	
	/**
	 * @var	$editToken	string	url-encoded edit token
	 **/
	public $editToken = '';
	
	/**
	 * __construct method
	 **
	 * The construction method is called when the class is instantiated.
	 **
	 * @param	$mwUser	string	Mediawiki username
	 * @param	$mwPass	string	Mediawiki user password
	 * @param	$site	string	qualified url/path to api.php
	 **/
	function __construct( $mwUser, $mwPass, $mwSite ){
		// Insure mwApiXmlParse is available
		require_once( 'mwApiXmlParse.php' );
		// $mwSite should be validated here.
		// it *must* be in the form http://domain.com/path/, including
		// the trailing /.
		$this->ch = curl_init( $mwSite );
		$this->mwLogin( $mwUser, $mwPass );
	}
	
	/**
	 * __destruct method
	 **
	 * To insure resources are released.
	 **/
	function __destruct(){
		curl_close( $this->ch );
		xml_parser_free( $this->xml_parser );
	}
	
	/**
	 * doParse method
	 **
	 * doParse processes the curlBuffer as an xml format string
	 * 
	 * WARNING: the length of the xml which can be managed is limited to the
	 * length of a PHP string - 
	 */
	private function doParse(){
		if( strlen( $this->mwXmlFunctions->allElements ) ){
			$this->mwXmlFunctions->allElements = '';
		}
		$this->xml_parser = xml_parser_create();
		xml_set_object( $this->xml_parser, $this->mwXmlFunctions );
		xml_set_element_handler( $this->xml_parser, 'startElement', 'endElement' );
		xml_parser_set_option( $this->xml_parser, XML_OPTION_CASE_FOLDING, false );
		if (!xml_parse( $this->xml_parser, $this->curlBuffer, true ) ) {
			die( sprintf( 
				"XML error: %s at line %d",
				xml_error_string( xml_get_error_code( $this->xml_parser ) ),
				xml_get_current_line_number( $this->xml_parser ) 
			) );
		}
	}
	
	/**
	 * execCurl method
	 **
	 * Executes a curl instance after turning off buffers, retrieves
	 * buffer into $this->curlBuffer, and returns result of execution
	 * as value.
	 * 
	 * Examples of use:
	 * 		$val = execCurl();
	 **
	 * @return	bool	Return value of curl_exec();
	 **/
	public function execCurl( $postvars ){
		$this->setCurlOpts( $postvars );
		$this->curlBuffer = curl_exec( $this->ch );
		return $this->curlBuffer;
	}
	
	/**
	 * getEditToken method
	 **
	 * getEditToken queries the MediaWiki API for an edit token, as per
	 * http://www.mediawiki.org/wiki/API:Edit_-_Create%26Edit_pages#Token 
	 **/
	function getEditToken(){
		$postvars = array(
			'action'	=> 'query',
			'prop'		=> 'info|revisions',
			'intoken'	=> 'edit',
			'titles'	=> 'Main Page',
			'format'	=> 'xml',
		);
		
		$val = $this->execCurl( $postvars );
		
		if( false != strlen( $val ) ){
			// Parse xml? grab cookies?
			$this->doParse();
			$this->editToken = $this->mwXmlFunctions->item->edittoken;
			return $this->editToken;
		}else{
			return false;
		}
	}
	
	/**
	 * getQuery method
	 **
	 * Retrieve and parse a query action
	 **
	 * @param	$query	array	Query parameters, as described at
	 * 							http://www.mediawiki.org/wiki/API:Query
	 **/
	public function getQuery( $query ){
		if( false != isset( $query['titles'] ) || false != isset( $query['pageids'] ) || false != isset( $query['revids']) ){
			$postvars = array();
			foreach( $edit AS $key => $val ){
				$postvars[$key] = $val;
			}
			// set after the foreach to insure the correct token, format
			$postvars['action'] = 'query';
			$postvars['token'] = $this->editToken;
			$postvars['format'] = 'xml';
			
			$val = $this->execCurl( $postvars );
			$this->doParse();
			return $val;
		}
	}
	
	/**
	 * mwLogin method
	 **
	 * Establishes connection/session with mwAPI server
	 **
	 * @param $mwUser	string	Mediawiki account name
	 * @param $mwPass	string	Mediawiki account password
	 * @param $mwSite	string	Qualified url/path
	 **/
	private function mwLogin( $mwUser, $mwPass ){
		$postvars = array(
			'action' 		=> 'login',
			'lgname' 		=> $mwUser,
			'lgpassword'	=> $mwPass,
			'format'		=> 'xml',
		);
		
		$val = $this->execCurl( $postvars );
		
		if( false != strlen( $val ) ){
			// Parse xml? grab cookies?
			$this->mwXmlFunctions = new mwApiXmlParse;
			$this->doParse();
		}
		
	}
	
	/**
	 * mwLogout method
	 **
	 * Get a logout from the MediaWiki API, destroying the login token
	 */
	private function mwLogout(){
		$postvars = array(
			'action'	=> 'logout',
			'format'	=> 'xml',
		);
		
		$val = $this->execCurl( $postvars );
		$this->doParse();
	}
	
	/**
	 * setCurlOpts method
	 **
	 * Set the usual cURL options, plus postvars if passed.
	 **
	 * @param	$postvars	array	variable number of POST variables
	 * 								for API.
	 **/
	public function setCurlOpts( $postvars ){
		if( is_array( $postvars) ){
			// FINDOUT: do we need to urlencode these?
			curl_setopt( $this->ch, CURLOPT_POST, true );
			curl_setopt( $this->ch, CURLOPT_POSTFIELDS, $postvars );
		}
		curl_setopt( $this->ch, CURLOPT_COOKIESESSION, true );
		curl_setopt( $this->ch, CURLOPT_COOKIEJAR, 'cookies.txt' );
		curl_setopt( $this->ch, CURLOPT_RETURNTRANSFER, true );
	}
	
	/**
	 * setEdit method
	 **
	 * Send an edit to the API after simple validation.
	 * 	title	required	Page title
	 * 	text	required	Raw wiki syntax
	 * 	
	 **
	 * @param	$edit	array	An array of edit parameters, described above.
	 * @return	bool	false = error returned from API
	 **/
	public function setEdit( $edit ){
		$val = false;
		// Check that at least page title, page content, and edit token are set.
		if( false != strlen( $edit['title'] ) && false != strlen( $edit['text'] )  && false != strlen( $this->editToken ) ){
			$postvars = array();
			foreach( $edit AS $key => $val ){
				$postvars[$key] = $val;
			}
			// set after the foreach to insure the correct token, format
			$postvars['action'] = 'edit';
			$postvars['token'] = $this->editToken;
			$postvars['format'] = 'xml';
			
			$val = $this->execCurl( $postvars );
			$this->doParse();
			return $val;
			
		}
	}
}