Source for file _functions_xmlrpcs.php
Documentation is available at _functions_xmlrpcs.php
* @subpackage xmlrpc {@link http://xmlrpc.usefulinc.com/doc/}
* @copyright Edd Dumbill <edd@usefulinc.com> (C) 1999-2002
// by Edd Dumbill (C) 1999-2002
// $Id: _functions_xmlrpcs.php,v 1.4.2.6 2005/08/31 19:32:31 fplanque Exp $
// Copyright (c) 1999,2000,2002 Edd Dumbill.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of the "XML-RPC for PHP" nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
if( !defined('DB_USER') ) die( 'Please, do not access this page directly.' );
// listMethods: either a string, or nothing
$_xmlrpcs_listMethods_sig=
array(array($xmlrpcArray, $xmlrpcString), array($xmlrpcArray));
$_xmlrpcs_listMethods_doc=
'This method lists all the methods that the XML-RPC server knows how to dispatch';
* listMethods: either a string, or nothing
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
for(reset($dmap); list
($key, $val)=
each($dmap); )
for(reset($dmap); list
($key, $val)=
each($dmap); )
$_xmlrpcs_methodSignature_sig=
array(array($xmlrpcArray, $xmlrpcString));
$_xmlrpcs_methodSignature_doc=
'Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';
* {@internal _xmlrpcs_methodSignature(-)}}
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
$methName=
$m->getParam(0);
$methName=
$methName->scalarval();
if (ereg("^system\.", $methName))
$dmap=
$_xmlrpcs_dmap; $sysCall=
1;
$dmap=
$server->dmap; $sysCall=
0;
// print "<!-- ${methName} -->\n";
if (isset
($dmap[$methName]))
if ($dmap[$methName]['signature'])
$thesigs=
$dmap[$methName]['signature'];
for($i=
0; $i<
sizeof($thesigs); $i++
)
for($j=
0; $j<
sizeof($inSig); $j++
)
$cursig[]=
new xmlrpcval($inSig[$j], 'string');
$r=
new xmlrpcresp(0,$xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']);
$_xmlrpcs_methodHelp_sig=
array(array($xmlrpcString, $xmlrpcString));
$_xmlrpcs_methodHelp_doc=
'Returns help text if defined for the method passed, otherwise returns an empty string';
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
$methName=
$m->getParam(0);
$methName=
$methName->scalarval();
if (ereg("^system\.", $methName))
$dmap=
$_xmlrpcs_dmap; $sysCall=
1;
$dmap=
$server->dmap; $sysCall=
0;
// print "<!-- ${methName} -->\n";
if (isset
($dmap[$methName]))
if ($dmap[$methName]['docstring'])
$r=
new xmlrpcresp(0, $xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']);
$_xmlrpcs_multicall_sig =
array(array($xmlrpcArray, $xmlrpcArray));
$_xmlrpcs_multicall_doc =
'Boxcar multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details';
global $xmlrpcerr, $xmlrpcstr;
$str =
$xmlrpcstr["multicall_${err}"];
$code =
$xmlrpcerr["multicall_${err}"];
$code =
$err->faultCode();
$str =
$err->faultString();
$struct['faultCode'] =
new xmlrpcval($code, 'int');
$struct['faultString'] =
new xmlrpcval($str, 'string');
if ($call->kindOf() !=
'struct')
$methName =
$call->structmem('methodName');
if ($methName->kindOf() !=
'scalar' ||
$methName->scalartyp() !=
'string')
if ($methName->scalarval() ==
'system.multicall')
$params =
$call->structmem('params');
if ($params->kindOf() !=
'array')
$numParams =
$params->arraysize();
$msg =
new xmlrpcmsg($methName->scalarval());
for ($i =
0; $i <
$numParams; $i++
)
$msg->addParam($params->arraymem($i));
$result =
$server->execute($msg);
if ($result->faultCode() !=
0)
return new xmlrpcval(array($result->value()), 'array');
$calls =
$m->getParam(0);
$numCalls =
$calls->arraysize();
for ($i =
0; $i <
$numCalls; $i++
)
$call =
$calls->arraymem($i);
'system.listMethods' =>
array(
'function' =>
'_xmlrpcs_listMethods',
'signature' =>
$_xmlrpcs_listMethods_sig,
'docstring' =>
$_xmlrpcs_listMethods_doc),
'system.methodHelp' =>
array(
'function' =>
'_xmlrpcs_methodHelp',
'signature' =>
$_xmlrpcs_methodHelp_sig,
'docstring' =>
$_xmlrpcs_methodHelp_doc),
'system.methodSignature' =>
array(
'function' =>
'_xmlrpcs_methodSignature',
'signature' =>
$_xmlrpcs_methodSignature_sig,
'docstring' =>
$_xmlrpcs_methodSignature_doc),
'system.multicall' =>
array(
'function' =>
'_xmlrpcs_multicall',
'signature' =>
$_xmlrpcs_multicall_sig,
'docstring' =>
$_xmlrpcs_multicall_doc
* Register a debugging message to be sent back in output
* evocore addition: make debug output optional
global $_xmlrpc_debuginfo;
$_xmlrpc_debuginfo=
$_xmlrpc_debuginfo .
$m .
"\n";
global $HTTP_RAW_POST_DATA;
// dispMap is a dispatch array of methods
// mapped to function names and signatures
// doesn't appear in the map then an unknown
// method error is generated
/* milosch - changed to make passing dispMap optional.
* instead, you can use the class add_to_map() function
* to add functions manually (borrowed from SOAPX4)
global $_xmlrpc_debuginfo;
if ($_xmlrpc_debuginfo!=
'')
//global $xmlrpc_defencoding;
//$payload='<?xml version="1.0" encoding="' . $xmlrpc_defencoding . '"?' . '>' . "\n"
// TODO: charset: encoding=\"iso-8859-1\"
$payload=
'<?xml version="1.0" ?' .
'>' .
"\n"
header('Content-Type: text/xml');
* add a method to the dispatch map
function add_to_map($methodname,$function,$sig,$doc)
$this->dmap[$methodname] =
array(
for($i=
0; $i<
sizeof($sig); $i++
)
// check each possible signature in turn
if (sizeof($cursig)==
$in->getNumParams()+
1)
for($n=
0; $n<
$in->getNumParams(); $n++
)
// print "<!-- $p -->\n";
if ($p->kindOf() ==
'scalar')
// $n+1 as first type of sig is return type
if ($pt !=
$cursig[$n+
1])
$pno=
$n+
1; $wanted=
$cursig[$n+
1]; $got=
$pt;
return array(0, "Wanted ${wanted}, got ${got} at param ${pno})");
return array(0, "No method signature matches number of parameters");
* {@internal parseRequest(-) }}
global $_xh,$HTTP_RAW_POST_DATA;
global $xmlrpcerr, $xmlrpcstr, $xmlrpcerrxml, $xmlrpc_defencoding,
$_xmlrpcs_dmap, $xmlrpc_internalencoding;
$data=
$HTTP_RAW_POST_DATA;
// xmlrpc_debugmsg( 'Data received: ['.$data.']' );
// G. Giunta 2005/02/13: we do NOT expect to receive html entities
// so we do not try to convert them into xml character entities
//$data = xmlrpc_html_entity_xlate($data);
//$_xh[$parser]['st']='';
$_xh[$parser]['isf_reason']=
'';
$_xh[$parser]['params']=
array();
$_xh[$parser]['stack']=
array();
$_xh[$parser]['valuestack'] =
array();
$_xh[$parser]['method']=
'';
// decompose incoming XML into request structure
// G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell
// the xml parser to give us back data in the expected charset
// return XML error as a faultCode
sprintf('XML error: %s at line %d',
if ($_xh[$parser]['isf'])
$xmlrpcerr['invalid_request'],
$xmlrpcstr['invalid_request'] .
' ' .
$_xh[$parser]['isf_reason']);
for($i=
0; $i<
sizeof($_xh[$parser]['params']); $i++
)
//print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n";
$plist.=
"$i - " .
$_xh[$parser]['params'][$i].
";\n";
//@eval('$m->addParam(' . $_xh[$parser]['params'][$i]. '); $allOK=1;');
@$m->addParam($_xh[$parser]['params'][$i]);
// uncomment this to really see what the server's getting!
// xmlrpc_debugmsg($plist);
// $r = new xmlrpcresp(0,
// $xmlrpcerr['incorrect_params'],
// $xmlrpcstr['incorrect_params'] . ": xml error in param " . $i);
global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;
// now to deal with the method
$methName =
$m->method();
logIO( 'I', 'Called method:'.
$methName );
$sysCall =
ereg("^system\.", $methName);
$dmap =
$sysCall ?
$_xmlrpcs_dmap :
$this->dmap;
if (!isset
($dmap[$methName]['function']))
$xmlrpcerr['unknown_method'],
$xmlrpcstr['unknown_method']);
if (isset
($dmap[$methName]['signature']))
$sig =
$dmap[$methName]['signature'];
$xmlrpcerr['incorrect_params'],
$xmlrpcstr['incorrect_params'] .
": ${errstr}"
$func =
$dmap[$methName]['function'];
global $HTTP_RAW_POST_DATA;
// a debugging routine: just echos back the input
// packet as a string value
$r->xv=
new xmlrpcval( "'Aha said I: '" .
$HTTP_RAW_POST_DATA, 'string');