hi!
this thread is little bit older, but i don’t want to keep my solution private.
the problem is following:
you can’t override sendPayload(...) because it is in another class which also extends CI_Xmlrpc.
my solution was to extend the CI_Xmlrpc and override the server()-method.
class MY_Xmlrpc extends CI_Xmlrpc {
function MY_Xmlrpc($config = array()){
parent::CI_Xmlrpc($config);
}
function server($url, $port=80)
{
$parts = parse_url($url);
if(!isset($parts["scheme"]) || $parts["scheme"]== ''){
$url = "http://".$url;
}
$parts = parse_url($url);
$path = (!isset($parts['path'])) ? '/' : $parts['path'];
if (isset($parts['query']) && $parts['query'] != '')
{
$path .= '?'.$parts['query'];
}
$user = (!isset($parts['user'])) ? '' : $parts['user'];
$pass = (!isset($parts['pass'])) ? '' : $parts['pass'];
$this->client = new MY_XML_RPC_Client($path, $parts['host'], $port, $parts["scheme"]."://", $user, $pass);
}
}
(i know, that the implementation is not very well, but its necessary to run parse_url twice to allow various schemes (protocols))
now there is a problem with the XML_RPC_Client, because the fsockopen needs the protocol for ssl, but the protocol does not be part of the http-header. therefore i had to write my own XML_RPC_Client. Another reason for doing that, was to add http-authentication-functionality.
class MY_XML_RPC_Client extends MY_Xmlrpc
{
var $path = '';
var $server = '';
var $port = 80;
var $errno = '';
var $errstring = '';
var $timeout = 5;
var $no_multicall = false;
var $protocol = 'http://';
var $user = '';
var $password = '';
function MY_XML_RPC_Client($path, $server, $port=80, $protocol = 'http://', $user = "", $password = "")
{
parent::MY_Xmlrpc();
$this->protocol = $protocol;
$this->port = $port;
$this->server = $server;
$this->path = $path;
$this->user = $user;
$this->password = $password;
}
function send($msg)
{
if (is_array($msg))
{
// Multi-call disabled
$r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']);
return $r;
}
return $this->sendPayload($msg);
}
function sendPayload($msg)
{
$fp = fsockopen($this->protocol.$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";
$http_basic_auth = "";
if($this->user!=""){
$credentials = base64_encode("{$this->user}:{$this->password}");
$http_basic_auth = "Authorization: Basic {$credentials}$r";
}
$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";
$op .= $http_basic_auth;
$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;
}
}
with this solution i can connect also via urls like
$this->xmlrpc->server("ssl://max:1234@server-one.com",433);
//or
$this->xmlrpc->server("http://server-two.com/rpc");
//or
$this->xmlrpc->server("server-two.com/rpc");
//or something like that
(due to the $http_basic_auth - notation: i hate this short-if-notation to avoid unclear code…
)
most likely there is a better solution, so reply and comment
p.s.: overloading is not the same as override. in this case its override