[eluser]Rob Pomeroy[/eluser]
Just to expand on pistolPete's excellent suggestion, here's how I implemented the entire extended class (save as application/libraries/MY_Xmlrpc.php):
Code:
<?php (defined('BASEPATH')) OR exit('No direct script access allowed');
/**
* XMLRPC client extension
*
* Adapted from the CodeIgniter Core Classes
* @link http://codeigniter.com
*
* Description:
* This library extends the CodeIgniter XMLRPC class.
*
* Install this file as application/libraries/MY_Xmlrpc.php
*
**/
/**
* XML-RPC Client class extended to include HTTP authentication capability
* @link http://ellislab.com/forums/viewthread/111201/
*/
class MY_Xmlrpc extends CI_Xmlrpc {
function server($url, $port=80)
{
if (substr($url, 0, 4) != "http")
{
$url = "http://".$url;
}
$parts = parse_url($url);
$path = ( ! isset($parts['path'])) ? '/' : $parts['path'];
if (isset($parts['query']) && $parts['query'] != '')
{
$path .= '?'.$parts['query'];
}
$this->client = new MY_XML_RPC_Client($path, $parts['host'], $port); // Use extended XML client class instead of core
}
// Pass through HTTP authentication credentials to extended XML client
function setCredentials($username, $password) {
$this->client->setCredentials($username, $password);
}
} // END MY_XML_RPC Class
class MY_XML_RPC_Client extends XML_RPC_Client
{
// Extra variables for authentication
var $username = '';
var $password = '';
function setCredentials($username, $password) {
$this->username = $username;
$this->password = $password;
}
function sendPayload($msg)
{
$fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);
if ( ! is_resource($fp))
{
error_log($this->xmlrpcstr['http_error']);
$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']);
return $r;
}
if(empty($msg->payload))
{
// $msg = XML_RPC_Messages
$msg->createPayload();
}
$r = "\r\n";
$op = "POST {$this->path} HTTP/1.0$r";
$op .= "Host: {$this->server}$r";
$op .= "Content-Type: text/xml$r";
$op .= "User-Agent: {$this->xmlrpcName}$r";
// This is where we're extending the base class, to include HTTP auth (basic)
if ($this->username != '' && $this->password != '') {
$op .= "Authorization: Basic ".base64_encode($this->username.':'.$this->password).$r;
}
$op .= "Content-Length: ".strlen($msg->payload). "$r$r";
$op .= $msg->payload;
if ( ! fputs($fp, $op, strlen($op)))
{
error_log($this->xmlrpcstr['http_error']);
$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
return $r;
}
$resp = $msg->parseResponse($fp);
fclose($fp);
return $resp;
}
} // end class MY_XML_RPC_Client
/* End of file MY_Xmlrpc.php */
/* Location: ./system/applications/libraries/MY_Xmlrpc.php */
You can then call it like this:
Code:
function testRPC() {
$this->load->library('xmlrpc'); // This auto-loads the custom extension MY_Xmlrpc too.
$this->xmlrpc->server("http://some.url.or.other/rpc/", 80);
$this->xmlrpc->setCredentials('my_username', 'my_password');
$this->xmlrpc->method('my_method');
$request = array('my_parameter');
$this->xmlrpc->request($request);
if ( ! $this->xmlrpc->send_request()) {
echo $this->xmlrpc->display_error();
} else {
// Do neat stuff
}
}