diff options
Diffstat (limited to 'modules/xmlrpc')
25 files changed, 9686 insertions, 0 deletions
diff --git a/modules/xmlrpc/ChangeLog b/modules/xmlrpc/ChangeLog new file mode 100644 index 00000000..05cf571e --- /dev/null +++ b/modules/xmlrpc/ChangeLog @@ -0,0 +1,263 @@ +2003-01-12 Andres Salomon <dilinger@voxel.net> + + * released 1.0.99.2. + * Makefile: separate doc/Makefile a bit more from Makefile, + and add clean rules. + +2003-01-10 Andres Salomon <dilinger@voxel.net> + + * xmlrpc.inc: xmlrpcresp and parseResponse cleanups; variable + name renames ('xv' to 'val', for example), type checking, and + stricter default values. + * xmlrpc.inc: fix xmlrpcresp's faultcode; return -1 for FAULT + responses from the server whose faultcodes don't reflect any + errors. + +2003-01-08 Andres Salomon <dilinger@voxel.net> + + * xmlrpc.inc: rename $_xh[$parser]['ha'] to + $_xh[$parser]['headers']. + * xmlrpc.inc: fix bugs related to $_xh[$parser]['headers]; + some places treated this as an array, others as a scalar. + Treat unconditionally as an array. Also wrap header debugging + output in PRE tags. + +2002-12-17 Andres Salomon <dilinger@voxel.net> + + * released 1.0.99. + * Makefile: changed the tarball format/dist rule to a more + conventional form, as well as normal release updates. + * xmlrpc.inc: added setSSLVerifyPeer and setSSLVerifyHost; as + of curl 7.10, various certificate checks are done (by default). + The default for CURLOPT_SSL_VERIFYHOST is to ensure the common + name on the cert matches the provided hostname. This breaks a + lot of stuff, so allow users to override it. + * doc/xmlrpc_php.sgml: updated documentation accordingly. + +2002-09-06 Geoffrey T. Dairiki <dairiki@dairiki.org> + + Add support for system.multicall() to both the client + and the server. + + * testsuite.php: Add new tests 'testServerMulticall', + and 'testClientMulticall'. + + * xmlrpc.inc: Added new error messages for system.multicall(). + * xmlrpcs.inc: Added new procedure call system.multicall(). + See http://www.xmlrpc.com/discuss/msgReader$1208 for details. + + * xmlrpc.inc: Added system.multicall functionality to + xmlrpc_client. xmlrpc_client::send can now take an array of + xmlrpcmsg's as an argument. In that case it will attempt + to execute the whole array of procure calls in a single + HTTP request using system.multicall(). (If that attempt fails, + then the calls will be excuted one at a time.) The return + value will be an array of xmlrpcresp's (or 0 upon transport + failure.) + +2001-11-29 Edd Dumbill <edd@usefulinc.com> + + * xmlrpc.inc: fixed problem with processing HTTP headers that + broke any payload with more than one consecutive newline in it. + also initialise the 'ac' array member to empty string at start. + * testsuite.php: added unit test to exercise above bug + * xmlrpcs.inc: fixed uninitialized variable $plist + +2001-09-25 Edd Dumbill <edd@usefulinc.com> + + * xmlrpc.inc: applied urgent security fixes as identified by Dan + Libby + +2001-08-27 Edd Dumbill <edd@usefulinc.com> + + * xmlrpc.inc: Merged in HTTPS support from Justin Miller, with a + few additions for better traceability of failure conditions. Added + small fix from Giancarlo Pinerolo. Bumped rev to 1.0. Changed + license to BSD license. + +2001-06-15 Edd Dumbill <edd@usefulinc.com> + + * xmlrpcs.inc: Added \r into return MIME headers for server class + +2001-04-25 Edd Dumbill <edd@usefulinc.com> + + * server.php: Added interop suite of methods. + +2001-04-24 Edd Dumbill <edd@usefulinc.com> + + * testsuite.php: added in test case for string handling bug. + + * xmlrpc.inc: merged in minor fixes from G Giunta to fix + noninitialization. Created new method, getval(), which includes + experimental support for recreating nested arrays, from Giunta and + Sofer. Fixed string handling bug where characters after </string> + but before </value> weren't ignored. Added in support for native + boolean type into xmlrpc_encode (Giunta). + + * xmlrpcs.inc: updated copyright notice + +2001-01-15 Edd Dumbill <edd@usefulinc.com> + + * xmlrpc.inc: fixed bug with creation of booleans. Put checks in + to ensure that numbers were really numeric. Fixed bug with + non-escaping of dollar signs in strings. + + * testsuite.php: created test suite. + +2000-08-26 Edd Dumbill <edd@usefulinc.com> + + * xmlrpcs.inc: added xmlrpc_debugmsg() function which outputs + debug information in comments inside the return payload XML + + * xmlrpc.inc: merged in some changes from Dan Libby which fix up + whitespace handling. + + * xmlrpcs.inc: added Content-length header on response (bug from + Jan Varga <varga@utcru.sk>. This means you can no longer print + during processing + + * xmlrpc.inc: changed ereg_replace to str_replace in several + places (thanks to Dan Libby <dan@libby.com> for this). + + * xmlrpc.inc: added xmlrpc_encode() and xmlrpc_decode() from Dan + Libby--these helper routines make it easier to work in native PHP + data structures. + +2000-07-21 Edd Dumbill <edd@usefulinc.com> + + * xmlrpc.inc: added xmlrpc_client::setCredentials method to pass + in authorization information, and modified sendPayload* methods to + send this OK. Thanks to Grant Rauscher for the impetus to do this. + Also, made the client send empty <params></params> if there are no + parameters set by the user. + + * doc/xmlrpc_php.sgml: updated documentation to reflect recent + changes + + +2000-07-18 Edd Dumbill <edd@usefulinc.com> + + * server.php: added examples.invertBooleans method to server as a + useful test method for boolean values. + + * xmlrpc.inc: rearranged the way booleans are handled to fix + outstanding problems. Fixed calling addScalar() on arrays so it + works. Finally fixed backslashification issues to remove the + problem will dollar signs disappearing. + + * booltest.php: really fixed booleans this time. + +2000-06-03 Edd Dumbill <edd@usefulinc.com> + + * xmlrpcs.inc: made signature verification more useful - now + returns what it found was wrong + + * xmlrpc.inc: fixed bug with decoding dateTimes. Also fixed a bug + which meant a PHP syntax error happened when attempting to receive + empty arrays or structs. Also fixed bug with booleans always being + interpreted as 'true'. + + * server.php: Added validator1 suite of tests to test against + validator.xmlrpc.com + + +2000-05-06 Edd Dumbill <edd@usefulinc.com> + + * released 1.0b6 + + * added test.pl and test.py, Perl and Python scripts that exercise + server.php somewhat (but not a lot) + + * added extra fault condition for a non 200 OK response from the + remote server. + + * added iso8601_encode() and iso8601_decode() to give some support + for passing dates around. They translate to and from UNIX + timestamps. Updated documentation accordingly. + + * fixed string backslashification -- was previously a little + overzealous! new behavior is '\' --> '\\' and '"' --> + '\"'. Everything else gets left alone. + +2000-04-12 Edd Dumbill <edd@usefulinc.com> + + * updated and bugfixed the documentation + + * fixed base 64 encoding to only happen at serialize() time, + rather than when a base64 value is created. This fixes the double + encoding bug reported by Nicolay Mausz + <castor@flying-dog.com>. The same approach ought to be taken with + encoding XML entities in the data - this is a TODO. + + * integrated further code from Peter Kocks: used his new code for + send(), adding a second, optional, parameter which is a timeout + parameter to fsockopen() + +1999-10-11 Edd Dumbill <edd@usefulinc.com> + + * added bug fixes from Peter Kocks <peter.kocks@baygate.com> + +1999-10-10 Edd Dumbill <edd@usefulinc.com> + + * updated the documentation + +1999-10-08 Edd Dumbill <edd@usefulinc.com> + + * added system.* methods and dispatcher, plus documentation + + * fixed bug which meant request::getNumParams was returning an + incorrect value + + * added signatures into the dispatch map. This BREAKS + COMPATIBILITY with previous releases of this code + +1999-08-18 Edd Dumbill <edd@usefulinc.com> + + * made entity encoding and decoding transparent now on string + passing. + + * de-globalised the globals in the parse routines, using an + associative array to hold all parser state $_xh + + * changed default input encoding to be UTF-8 to match expectation + + * separated out parseResponse into parseResponse and + parseResponseFile so that you can call parseResponse on a string + if you have one handy + +1999-07-20 Edd Dumbill <edd@usefulinc.com> + + * Moved documentation into Docbook format + +1999-07-19 Edd Dumbill <edd@usefulinc.com> + + * Added an echo server into server.php and echotest.php, a client + which will exercise the new echo routine. + + * Added test for no valid value returned: in this case will now + throw the error "invalid payload" + + * Added serialize() method to xmlrpcresp to return a string with + the response serialized as XML + + * Added automatic encoding and decoding for base64 types + + * Added setDebug() method to client to enable HTML output + debugging in the client + +1999-07-08 Edd Dumbill <edd@usefulinc.com> + + * Improved XML parse error reporting on the server side to send it + back in a faultCode packet. expat errors now begin at 100 + +1999-07-07 Edd Dumbill <edd@usefulinc.com> + + * Changed the structmem and arraymem methods of xmlrpcval to always + return xmlrpc vals whether they referred to scalars or complex + types. + + * Added the server class and demonstrations + + * Fixed bugs in the XML parsing and reworked it + +$Id: ChangeLog,v 1.12 2003/01/13 08:34:18 dilinger Exp $ diff --git a/modules/xmlrpc/README b/modules/xmlrpc/README new file mode 100644 index 00000000..790bbbc6 --- /dev/null +++ b/modules/xmlrpc/README @@ -0,0 +1,7 @@ +HTML documentation can be found in the doc/ directory. + +Recent changes in the ChangeLog + +Use of this software is subject to the terms in doc/index.html + +The passphrase for the rsakey.pem certificate is 'test'. diff --git a/modules/xmlrpc/doc/Makefile b/modules/xmlrpc/doc/Makefile new file mode 100755 index 00000000..77a47180 --- /dev/null +++ b/modules/xmlrpc/doc/Makefile @@ -0,0 +1,17 @@ +WEB=/var/www/xmlrpc/doc + +all: index.html + +index.html: xmlrpc_php.sgml + jade -t sgml -d custom.dsl xmlrpc_php.sgml + +clean: + rm -f *.html + +install: + mkdir -p ${WEB} + cp *.html ${WEB} + +web: + mkdir -p ${WEB} + cp *.html ${WEB} diff --git a/modules/xmlrpc/doc/apidocs.html b/modules/xmlrpc/doc/apidocs.html new file mode 100644 index 00000000..6178742e --- /dev/null +++ b/modules/xmlrpc/doc/apidocs.html @@ -0,0 +1,598 @@ +<HTML +><HEAD +><TITLE +>Class documentation</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="PREVIOUS" +TITLE="The Jellyfish Book" +HREF="jellyfish.html"><LINK +REL="NEXT" +TITLE="xmlrpcmsg" +HREF="xmlrpcmsg.html"></HEAD +><BODY +CLASS="CHAPTER" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="jellyfish.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="xmlrpcmsg.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="CHAPTER" +><H1 +><A +NAME="APIDOCS" +></A +>Chapter 5. Class documentation</H1 +><DIV +CLASS="TOC" +><DL +><DT +><B +>Table of Contents</B +></DT +><DT +><A +HREF="apidocs.html#XMLRPC-CLIENT" +>xmlrpc_client</A +></DT +><DT +><A +HREF="xmlrpcmsg.html" +>xmlrpcmsg</A +></DT +><DT +><A +HREF="xmlrpcresp.html" +>xmlrpcresp</A +></DT +><DT +><A +HREF="xmlrpcval.html" +>xmlrpcval</A +></DT +><DT +><A +HREF="xmlrpc-server.html" +>xmlrpc_server</A +></DT +></DL +></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="XMLRPC-CLIENT" +></A +>xmlrpc_client</H1 +><P +>This is the basic class used to represent a client of an + XML-RPC server.</P +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN174" +></A +>Creation</H2 +><P +>The constructor has the following syntax:</P +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN177" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$client=new xmlrpc_client</CODE +>($server_path, $server_hostname, $server_port);</CODE +></P +><P +></P +></DIV +><P +>Here's an example client set up to query Userland's XML-RPC + server at <SPAN +CLASS="emphasis" +><I +CLASS="EMPHASIS" +>betty.userland.com</I +></SPAN +>:</P +><PRE +CLASS="PROGRAMLISTING" +>$client=new xmlrpc_client("/RPC2", "betty.userland.com", 80);</PRE +><P +>The <TT +CLASS="PARAMETER" +><I +>server_port</I +></TT +> parameter is + optional, and if omitted will default to 80 when using + HTTP and 443 when using HTTPS (see the "send" method below.)</P +></DIV +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN191" +></A +>Methods</H2 +><P +>This class supports the following methods.</P +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="XMLRPC-CLIENT-SEND" +></A +>send</H3 +><P +>This method takes the form:</P +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN197" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$response=$client->send</CODE +>($xmlrpc_message, $timeout, $server_method);</CODE +></P +><P +></P +></DIV +><P +>Where <TT +CLASS="PARAMETER" +><I +>$xmlrpc_message</I +></TT +> is an + instance of <TT +CLASS="CLASSNAME" +>xmlrpcmsg</TT +> (see <A +HREF="xmlrpcmsg.html" +>xmlrpcmsg</A +>), and + <TT +CLASS="PARAMETER" +><I +>$response</I +></TT +> is an + instance of <TT +CLASS="CLASSNAME" +>xmlrpcresp</TT +> (see <A +HREF="xmlrpcresp.html" +>xmlrpcresp</A +>).</P +><P +>The <TT +CLASS="PARAMETER" +><I +>$timeout</I +></TT +> is optional, and + will be set to <TT +CLASS="LITERAL" +>0</TT +> (wait forever) if + omitted. This timeout value is passed to + <TT +CLASS="FUNCTION" +>fsockopen()</TT +>.</P +><P +>The <TT +CLASS="PARAMETER" +><I +>server_method</I +></TT +> parameter is + optional, and if omitted will default to 'http'. The only + other valid value is 'https', which will use an SSL HTTP + connection to connect to the remote server. Note that your + PHP must have the "curl" extensions compiled in in order to + use this feature. Note that when using SSL you should + normally set your port number to 443, unless the SSL server + you are contacting runs at any other port.</P +><DIV +CLASS="WARNING" +><P +></P +><TABLE +CLASS="WARNING" +BORDER="1" +WIDTH="100%" +><TR +><TD +ALIGN="CENTER" +><B +>Warning</B +></TD +></TR +><TR +><TD +ALIGN="LEFT" +><P +>PHP 4.0.2 or greater is required for SSL + functionality. + PHP 4.0.6 has a bug which prevents SSL + working.</P +></TD +></TR +></TABLE +></DIV +><P +>If the value of <TT +CLASS="PARAMETER" +><I +>$response</I +></TT +> is + <TT +CLASS="LITERAL" +>0</TT +> rather than an + <TT +CLASS="CLASSNAME" +>xmlrpcresp</TT +> object, then this + signifies an I/O error has occured. You can find out what + the I/O error was from the values + <TT +CLASS="FUNCTION" +>$client->errno</TT +> and + <TT +CLASS="FUNCTION" +>$client->errstring</TT +>. + </P +><P +>In addition to low-level errors, the XML-RPC server you + were querying may return an error in the + <TT +CLASS="CLASSNAME" +>xmlrpcresp</TT +> object. See <A +HREF="xmlrpcresp.html" +>xmlrpcresp</A +> for details of + how to handle these errors. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN230" +></A +>setCredentials</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN232" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$client->setCredentials</CODE +>($username, $password);</CODE +></P +><P +></P +></DIV +><P +>This method sets the username and password for authorizing the + client to a server. With the default (HTTP) transport, this + information is used for HTTP Basic authorization. + + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN240" +></A +>setCertificate</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN242" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$client->setCertificate</CODE +>($certificate, $passphrase);</CODE +></P +><P +></P +></DIV +><P +>This method sets the optional certificate and passphrase + used in SSL-enabled communication with a remote server + (when the <TT +CLASS="PARAMETER" +><I +>server_method</I +></TT +> is set to + 'https' in the client's construction). + </P +><P +>The <TT +CLASS="PARAMETER" +><I +>certificate</I +></TT +> parameter must + be the filename of a PEM formatted certificate. The + <TT +CLASS="PARAMETER" +><I +>passphrase</I +></TT +> parameter must contain + the password required to use the certificate.</P +><P +>This requires the "curl" extensions to be compiled + into your installation of PHP.</P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN255" +></A +>setSSLVerifyPeer</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN257" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$client->setSSLVerifyPeer</CODE +>($i);</CODE +></P +><P +></P +></DIV +><P +>This method defines whether connections made to XMLRPC + backends via HTTPS should verify the remote host's SSL + certificate, and cause the connection to fail if the cert + verification fails. $i should be a boolean value. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN263" +></A +>setSSLVerifyHost</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN265" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$client->setSSLVerifyHost</CODE +>($i);</CODE +></P +><P +></P +></DIV +><P +>This method defines whether connections made to XMLRPC + backends via HTTPS should verify the remote host's SSL + certificate's common name (CN). By default, only the existence + of a CN is checked. $i should be an integer value; 0 to not + check the CN at all, 1 to merely check for its existence, and + 2 to check that the CN on the certificate matches the hostname + that is being connected to. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN271" +></A +>setDebug</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN273" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$client->setDebug</CODE +>($debugOn);</CODE +></P +><P +></P +></DIV +><P +><TT +CLASS="PARAMETER" +><I +>$debugOn</I +></TT +> is either + <TT +CLASS="LITERAL" +>0</TT +> or <TT +CLASS="LITERAL" +>1</TT +> depending on + whether you require the client to print debugging + information to the browser. The default is not to output + this information.</P +><P +> The debugging information includes the raw data returned + from the XML-RPC server it was querying, and the PHP value + the client attempts to create to represent the value + returned by the server. This option can be very useful when + debugging servers as it allows you to see exactly what the + server returns. + </P +></DIV +></DIV +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="jellyfish.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="xmlrpcmsg.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>The Jellyfish Book</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>xmlrpcmsg</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/arrayuse.html b/modules/xmlrpc/doc/arrayuse.html new file mode 100644 index 00000000..e8011ed4 --- /dev/null +++ b/modules/xmlrpc/doc/arrayuse.html @@ -0,0 +1,253 @@ +<HTML +><HEAD +><TITLE +>Easy use with PHP arrays</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="UP" +TITLE="Helper functions" +HREF="helpers.html"><LINK +REL="PREVIOUS" +TITLE="Helper functions" +HREF="helpers.html"><LINK +REL="NEXT" +TITLE="Debugging aids" +HREF="debugging.html"></HEAD +><BODY +CLASS="SECT1" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="helpers.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +>Chapter 6. Helper functions</TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="debugging.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="ARRAYUSE" +></A +>Easy use with PHP arrays</H1 +><P +>Dan Libby was kind enough to contribute two helper functions + that make it easier to translate to and from PHP arrays. This + makes it easier to deal with complex structures. At the moment + support is limited to <SPAN +CLASS="TYPE" +>int</SPAN +>, <SPAN +CLASS="TYPE" +>double</SPAN +>, + <SPAN +CLASS="TYPE" +>string</SPAN +>, <SPAN +CLASS="TYPE" +>array</SPAN +> and <SPAN +CLASS="TYPE" +>struct</SPAN +> + datatypes; note also that all PHP arrays are encoded as structs + due to PHP not being able to tell the difference between a hash + and a linear array.</P +><P +>These functions reside in <TT +CLASS="FILENAME" +>xmlrpc.inc</TT +>.</P +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="XMLRPCDECODE" +></A +>xmlrpc_decode</H2 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN791" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$arr=xmlrpc_decode</CODE +>($xmlrpc_val);</CODE +></P +><P +></P +></DIV +><P +> Returns a PHP array stuffed with the values found in the + <SPAN +CLASS="TYPE" +>xmlrpcval</SPAN +> <TT +CLASS="PARAMETER" +><I +>$xmlrpc_val</I +></TT +>, + translated into native PHP types. + </P +></DIV +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="XMLRPCENCODE" +></A +>xmlrpc_encode</H2 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN801" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$xmlrpc_val=xmlrpc_encode</CODE +>($phpval);</CODE +></P +><P +></P +></DIV +><P +> Returns an <SPAN +CLASS="TYPE" +>xmlrpcval</SPAN +> populated with the PHP + values in <TT +CLASS="PARAMETER" +><I +>$phpval</I +></TT +>. Works recursively on + arrays and structs. Note that there's no support for non-base + types like base-64 values or date-times. + </P +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="helpers.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="debugging.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Helper functions</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="helpers.html" +ACCESSKEY="U" +>Up</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Debugging aids</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/bugs.html b/modules/xmlrpc/doc/bugs.html new file mode 100644 index 00000000..be925b65 --- /dev/null +++ b/modules/xmlrpc/doc/bugs.html @@ -0,0 +1,159 @@ +<HTML +><HEAD +><TITLE +>Bugs</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="PREVIOUS" +TITLE="Files in the distribution" +HREF="manifest.html"><LINK +REL="NEXT" +TITLE="Support" +HREF="support.html"></HEAD +><BODY +CLASS="CHAPTER" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="manifest.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="support.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="CHAPTER" +><H1 +><A +NAME="BUGS" +></A +>Chapter 3. Bugs</H1 +><P +>This is a bare framework. The "nice" bits haven't been put in + yet. Specifically, no HTTP response checking is performed, and no type + validation or coercion has been put in. PHP being a loosely-typed + language, this is going to have to be done explicitly.</P +><P +>dateTime.iso8601 is supported opaquely. It can't be done + natively as the XML-RPC specification explictly forbids passing of + timezone specifiers in ISO8601 format dates. You can, however, use + the <A +HREF="helpers.html#ISO8601ENCODE" +>iso8601_encode()</A +> and <A +HREF="helpers.html#ISO8601DECODE" +>iso8601_decode()</A +> functions to do the encoding and decoding for you.</P +><P +>If alternative character set encoding is sent in HTTP header + than it will be ignored for the moment. We speak only UTF-8...</P +><P +>If more than 32k of HTTP headers are encountered (like, why?) then the + response parsing code will break.</P +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="manifest.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="support.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Files in the distribution</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Support</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/custom.dsl b/modules/xmlrpc/doc/custom.dsl new file mode 100644 index 00000000..24d4b4bf --- /dev/null +++ b/modules/xmlrpc/doc/custom.dsl @@ -0,0 +1,25 @@ +<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [ +<!ENTITY dbstyle SYSTEM "/usr/lib/sgml/stylesheet/dsssl/docbook/nwalsh/html/docbook.dsl" CDATA DSSSL> +]> + +<style-sheet> +<style-specification use="docbook"> +<style-specification-body> + +(define %link-mailto-url% + "edd@usefulinc.com") + +(define %html-ext% + ".html") + +(define %use-id-as-filename% + #t) + +(define %root-filename% + "index") + + +</style-specification-body> +</style-specification> +<external-specification id="docbook" document="dbstyle"> +</style-sheet> diff --git a/modules/xmlrpc/doc/debugging.html b/modules/xmlrpc/doc/debugging.html new file mode 100644 index 00000000..7a0e567b --- /dev/null +++ b/modules/xmlrpc/doc/debugging.html @@ -0,0 +1,188 @@ +<HTML +><HEAD +><TITLE +>Debugging aids</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="UP" +TITLE="Helper functions" +HREF="helpers.html"><LINK +REL="PREVIOUS" +TITLE="Easy use with PHP arrays" +HREF="arrayuse.html"><LINK +REL="NEXT" +TITLE="Reserved methods" +HREF="reserved.html"></HEAD +><BODY +CLASS="SECT1" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="arrayuse.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +>Chapter 6. Helper functions</TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="reserved.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="DEBUGGING" +></A +>Debugging aids</H1 +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN811" +></A +>xmlrpc_debugmsg</H2 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN813" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>xmlrpc_debugmsg</CODE +>($debugstring);</CODE +></P +><P +></P +></DIV +><P +>Sends the contents of <TT +CLASS="PARAMETER" +><I +>$debugstring</I +></TT +> + in XML comments in the server return payload. If a PHP client + has debugging turned on, the user will be able to see server + debug information.</P +><P +>Use this function in your methods so you can pass back + diagnostic information. It is only available from + <TT +CLASS="FILENAME" +>xmlrpcs.inc</TT +>.</P +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="arrayuse.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="reserved.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Easy use with PHP arrays</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="helpers.html" +ACCESSKEY="U" +>Up</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Reserved methods</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/examples.html b/modules/xmlrpc/doc/examples.html new file mode 100644 index 00000000..e8d44415 --- /dev/null +++ b/modules/xmlrpc/doc/examples.html @@ -0,0 +1,159 @@ +<HTML +><HEAD +><TITLE +>Examples</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="PREVIOUS" +TITLE="system.methodHelp" +HREF="sysmethhelp.html"></HEAD +><BODY +CLASS="CHAPTER" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="sysmethhelp.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +> </TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="CHAPTER" +><H1 +><A +NAME="EXAMPLES" +></A +>Chapter 8. Examples</H1 +><P +>The best examples are to be found in the sample files + included with the distribution. Some are included here.</P +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="STATENAME" +></A +>XML-RPC client: state name query</H1 +><P +>Code to get the corresponding + state name from a number (1-50) from Dave Winer's server</P +><PRE +CLASS="PROGRAMLISTING" +> $f=new xmlrpcmsg('examples.getStateName', + array(new xmlrpcval($HTTP_POST_VARS["stateno"], "int"))); + $c=new xmlrpc_client("/RPC2", "betty.userland.com", 80); + $r=$c->send($f); + $v=$r->value(); + if (!$r->faultCode()) { + print "State number ". $HTTP_POST_VARS["stateno"] . " is " . + $v->scalarval() . "<BR>"; + print "<HR>I got this value back<BR><PRE>" . + htmlentities($r->serialize()). "</PRE><HR>\n"; + } else { + print "Fault: "; + print "Code: " . $r->faultCode() . + " Reason '" .$r->faultString()."'<BR>"; + } + </PRE +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="sysmethhelp.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +> </TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>system.methodHelp</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +> </TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/helpers.html b/modules/xmlrpc/doc/helpers.html new file mode 100644 index 00000000..4f0c1319 --- /dev/null +++ b/modules/xmlrpc/doc/helpers.html @@ -0,0 +1,318 @@ +<HTML +><HEAD +><TITLE +>Helper functions</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="PREVIOUS" +TITLE="xmlrpc_server" +HREF="xmlrpc-server.html"><LINK +REL="NEXT" +TITLE="Easy use with PHP arrays" +HREF="arrayuse.html"></HEAD +><BODY +CLASS="CHAPTER" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="xmlrpc-server.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="arrayuse.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="CHAPTER" +><H1 +><A +NAME="HELPERS" +></A +>Chapter 6. Helper functions</H1 +><DIV +CLASS="TOC" +><DL +><DT +><B +>Table of Contents</B +></DT +><DT +><A +HREF="helpers.html#AEN739" +>Date functions</A +></DT +><DT +><A +HREF="arrayuse.html" +>Easy use with PHP arrays</A +></DT +><DT +><A +HREF="debugging.html" +>Debugging aids</A +></DT +></DL +></DIV +><P +>XML-RPC for PHP contains some helper functions which you can + use to make processing of XML-RPC requests easier.</P +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="AEN739" +></A +>Date functions</H1 +><P +>The XML-RPC specification has this to say on dates:</P +><A +NAME="AEN742" +></A +><BLOCKQUOTE +CLASS="BLOCKQUOTE" +><P +>Don't assume a timezone. It should be specified by the server in its + documentation what assumptions it makes about timezones. </P +></BLOCKQUOTE +><P +>Unfortunately, this means that date processing isn't + straightforward. Although XML-RPC uses ISO 8601 format dates, it + doesn't use the timezone specifier.</P +><P +>We strongly recommend that in every case where you pass + dates in XML-RPC calls, you use UTC (GMT) as your timezone. Most computer + languages include routines for handling GMT times natively, and + you won't have to translate between timezones.</P +><P +>For more information about dates, see <A +HREF="http://www.uic.edu/year2000/datefmt.html" +TARGET="_top" +>ISO 8601: The Right Format for Dates</A +>, which has a handy link to a PDF of the ISO 8601 specification. Note that XML-RPC uses exactly one of the available representations: CCYYMMDDTHH:MM:SS.</P +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="ISO8601ENCODE" +></A +>iso8601_encode</H2 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN750" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$isoString=iso8601_encode</CODE +>($time_t, $utc=0);</CODE +></P +><P +></P +></DIV +><P +>Returns an ISO 8601 formatted date generated from the + UNIX timestamp <TT +CLASS="PARAMETER" +><I +>$time_t</I +></TT +>, as returned by + the PHP function <TT +CLASS="FUNCTION" +>time()</TT +>. </P +><P +>The argument <TT +CLASS="PARAMETER" +><I +>$utc</I +></TT +> can be omitted, + in which case it defaults to <TT +CLASS="LITERAL" +>0</TT +>. If it is + set to <TT +CLASS="LITERAL" +>1</TT +>, then the function corrects the + time passed in for UTC. Example: if you're in the GMT-6:00 + timezone and set <TT +CLASS="PARAMETER" +><I +>$utc</I +></TT +>, you will receive + a date representation six hours ahead of your local + time.</P +><P +>The included demo program <TT +CLASS="FILENAME" +>vardemo.php</TT +> + includes a demonstration of this function.</P +></DIV +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="ISO8601DECODE" +></A +>iso8601_decode</H2 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN768" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$time_t=iso8601_decode</CODE +>($isoString, $utc=0);</CODE +></P +><P +></P +></DIV +><P +>Returns a UNIX timestamp from an ISO 8601 encoded time and + date string passed in. If <TT +CLASS="PARAMETER" +><I +>$utc</I +></TT +> is + <TT +CLASS="LITERAL" +>1</TT +> then <TT +CLASS="PARAMETER" +><I +>$isoString</I +></TT +> is + assumed to be in the UTC timezone, and thus the + <TT +CLASS="PARAMETER" +><I +>$time_t</I +></TT +> result is also UTC: otherwise, + the timezone is assumed to be your local timezone and you receive a local timestamp.</P +></DIV +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="xmlrpc-server.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="arrayuse.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>xmlrpc_server</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Easy use with PHP arrays</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/index.html b/modules/xmlrpc/doc/index.html new file mode 100644 index 00000000..6e91b313 --- /dev/null +++ b/modules/xmlrpc/doc/index.html @@ -0,0 +1,453 @@ +<HTML +><HEAD +><TITLE +>XML-RPC for PHP</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="NEXT" +TITLE="Introduction" +HREF="introduction.html"></HEAD +><BODY +CLASS="BOOK" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="BOOK" +><A +NAME="AEN1" +></A +><DIV +CLASS="TITLEPAGE" +><H1 +CLASS="TITLE" +><A +NAME="AEN2" +></A +>XML-RPC for PHP</H1 +><H2 +CLASS="SUBTITLE" +>version 1.1</H2 +><H3 +CLASS="AUTHOR" +><A +NAME="AEN7" +></A +>Edd Dumbill</H3 +><DIV +CLASS="AFFILIATION" +><SPAN +CLASS="ORGNAME" +><A +HREF="http://usefulinc.com/" +TARGET="_top" +>Useful + Information Company</A +><BR></SPAN +><DIV +CLASS="ADDRESS" +><P +CLASS="ADDRESS" +> <TT +CLASS="EMAIL" +><<A +HREF="mailto:edd@usefulinc.com" +>edd@usefulinc.com</A +>></TT +><br> + </P +></DIV +></DIV +><P +CLASS="COPYRIGHT" +>Copyright © 1999,2000,2001 Edd Dumbill, Useful Information Company</P +><DIV +CLASS="LEGALNOTICE" +><A +NAME="AEN18" +></A +><P +></P +><P +> All rights reserved. + </P +><P +> Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + </P +><P +> <P +></P +><UL +><LI +><P +> Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + </P +></LI +><LI +><P +> 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. + </P +></LI +><LI +><P +> 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. + </P +></LI +></UL +> + </P +><P +> 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.</P +><P +></P +></DIV +><HR></DIV +><DIV +CLASS="TOC" +><DL +><DT +><B +>Table of Contents</B +></DT +><DT +>1. <A +HREF="introduction.html" +>Introduction</A +></DT +><DD +><DL +><DT +><A +HREF="introduction.html#AEN43" +>Acknowledgements</A +></DT +></DL +></DD +><DT +>2. <A +HREF="manifest.html" +>Files in the distribution</A +></DT +><DT +>3. <A +HREF="bugs.html" +>Bugs</A +></DT +><DT +>4. <A +HREF="support.html" +>Support</A +></DT +><DD +><DL +><DT +><A +HREF="support.html#AEN146" +>Online Support</A +></DT +><DT +><A +HREF="jellyfish.html" +>The Jellyfish Book</A +></DT +></DL +></DD +><DT +>5. <A +HREF="apidocs.html" +>Class documentation</A +></DT +><DD +><DL +><DT +><A +HREF="apidocs.html#XMLRPC-CLIENT" +>xmlrpc_client</A +></DT +><DD +><DL +><DT +><A +HREF="apidocs.html#AEN174" +>Creation</A +></DT +><DT +><A +HREF="apidocs.html#AEN191" +>Methods</A +></DT +></DL +></DD +><DT +><A +HREF="xmlrpcmsg.html" +>xmlrpcmsg</A +></DT +><DD +><DL +><DT +><A +HREF="xmlrpcmsg.html#AEN289" +>Creation</A +></DT +><DT +><A +HREF="xmlrpcmsg.html#AEN309" +>Methods</A +></DT +></DL +></DD +><DT +><A +HREF="xmlrpcresp.html" +>xmlrpcresp</A +></DT +><DD +><DL +><DT +><A +HREF="xmlrpcresp.html#AEN386" +>Creation</A +></DT +><DT +><A +HREF="xmlrpcresp.html#AEN408" +>Methods</A +></DT +></DL +></DD +><DT +><A +HREF="xmlrpcval.html" +>xmlrpcval</A +></DT +><DD +><DL +><DT +><A +HREF="xmlrpcval.html#AEN452" +>Notes on types</A +></DT +><DT +><A +HREF="xmlrpcval.html#XMLRPCVAL-CREATION" +>Creation</A +></DT +><DT +><A +HREF="xmlrpcval.html#XMLRPCVAL-METHODS" +>Methods</A +></DT +></DL +></DD +><DT +><A +HREF="xmlrpc-server.html" +>xmlrpc_server</A +></DT +><DD +><DL +><DT +><A +HREF="xmlrpc-server.html#AEN658" +>The dispatch map</A +></DT +><DT +><A +HREF="xmlrpc-server.html#SIGNATURES" +>Method signatures</A +></DT +><DT +><A +HREF="xmlrpc-server.html#AEN686" +>Delaying the server response</A +></DT +><DT +><A +HREF="xmlrpc-server.html#AEN692" +>Fault reporting</A +></DT +></DL +></DD +></DL +></DD +><DT +>6. <A +HREF="helpers.html" +>Helper functions</A +></DT +><DD +><DL +><DT +><A +HREF="helpers.html#AEN739" +>Date functions</A +></DT +><DD +><DL +><DT +><A +HREF="helpers.html#ISO8601ENCODE" +>iso8601_encode</A +></DT +><DT +><A +HREF="helpers.html#ISO8601DECODE" +>iso8601_decode</A +></DT +></DL +></DD +><DT +><A +HREF="arrayuse.html" +>Easy use with PHP arrays</A +></DT +><DD +><DL +><DT +><A +HREF="arrayuse.html#XMLRPCDECODE" +>xmlrpc_decode</A +></DT +><DT +><A +HREF="arrayuse.html#XMLRPCENCODE" +>xmlrpc_encode</A +></DT +></DL +></DD +><DT +><A +HREF="debugging.html" +>Debugging aids</A +></DT +><DD +><DL +><DT +><A +HREF="debugging.html#AEN811" +>xmlrpc_debugmsg</A +></DT +></DL +></DD +></DL +></DD +><DT +>7. <A +HREF="reserved.html" +>Reserved methods</A +></DT +><DD +><DL +><DT +><A +HREF="reserved.html#AEN827" +>system.listMethods</A +></DT +><DT +><A +HREF="sysmethodsig.html" +>system.methodSignature</A +></DT +><DT +><A +HREF="sysmethhelp.html" +>system.methodHelp</A +></DT +></DL +></DD +><DT +>8. <A +HREF="examples.html" +>Examples</A +></DT +><DD +><DL +><DT +><A +HREF="examples.html#STATENAME" +>XML-RPC client: state name query</A +></DT +></DL +></DD +></DL +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +> </TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="introduction.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +> </TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Introduction</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/introduction.html b/modules/xmlrpc/doc/introduction.html new file mode 100644 index 00000000..09b314e4 --- /dev/null +++ b/modules/xmlrpc/doc/introduction.html @@ -0,0 +1,280 @@ +<HTML +><HEAD +><TITLE +>Introduction</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="PREVIOUS" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="NEXT" +TITLE="Files in the distribution" +HREF="manifest.html"></HEAD +><BODY +CLASS="CHAPTER" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="index.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="manifest.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="CHAPTER" +><H1 +><A +NAME="INTRODUCTION" +></A +>Chapter 1. Introduction</H1 +><P +>XML-RPC is a format devised by <A +HREF="http://www.userland.com/" +TARGET="_top" +>Userland Software</A +> for + achieving remote procedure call via XML. XML-RPC has its own web + site, <A +HREF="http://www.xmlrpc.com/" +TARGET="_top" +>www.XmlRpc.com</A +></P +><P +>The most common implementations of XML-RPC available at the + moment use HTTP as the transport. A list of implementations for + other languages such as Perl and Python can be found on the + <A +HREF="http://www.xmlrpc.com/" +TARGET="_top" +>www.xmlrpc.com</A +>.</P +><P +>This collection of PHP classes provides a framework for + writing XML-RPC clients and servers in PHP.</P +><DIV +CLASS="WARNING" +><P +></P +><TABLE +CLASS="WARNING" +BORDER="1" +WIDTH="100%" +><TR +><TD +ALIGN="CENTER" +><B +>Warning</B +></TD +></TR +><TR +><TD +ALIGN="LEFT" +><P +>The <SPAN +CLASS="emphasis" +><I +CLASS="EMPHASIS" +>server code</I +></SPAN +> works only with versions of PHP3 + >= 3.0.12. The code is also known to work with PHP4. + </P +><P +>If you wish to use SSL to communicate with remote servers, + you need the "curl" extension compiled into your PHP + installation, this is available in PHP 4.0.2 and greater, + although 4.0.6 has a bug preventing SSL working.</P +></TD +></TR +></TABLE +></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="AEN43" +></A +>Acknowledgements</H1 +><P +>Jim Winstead <TT +CLASS="EMAIL" +><<A +HREF="mailto:jimw@php.net" +>jimw@php.net</A +>></TT +></P +><P +>Peter Kocks <TT +CLASS="EMAIL" +><<A +HREF="mailto:peter.kocks@baygate.com" +>peter.kocks@baygate.com</A +>></TT +></P +><P +>Nicolay Mausz <TT +CLASS="EMAIL" +><<A +HREF="mailto:mausz@flying-dog.com" +>mausz@flying-dog.com</A +>></TT +></P +><P +>Ben Margolin + <TT +CLASS="EMAIL" +><<A +HREF="mailto:ben@wendy.auctionwatch.com" +>ben@wendy.auctionwatch.com</A +>></TT +></P +><P +>Dan Libby <TT +CLASS="EMAIL" +><<A +HREF="mailto:dan@libby.com" +>dan@libby.com</A +>></TT +></P +><P +>Gaetano Giunta <TT +CLASS="EMAIL" +><<A +HREF="mailto:g.giunta@libero.it" +>g.giunta@libero.it</A +>></TT +></P +><P +>Idan Sofer <TT +CLASS="EMAIL" +><<A +HREF="mailto:i_sofer@yahoo.com" +>i_sofer@yahoo.com</A +>></TT +></P +><P +>Giancarlo Pinerolo <TT +CLASS="EMAIL" +><<A +HREF="mailto:ping@alt.it" +>ping@alt.it</A +>></TT +></P +><P +>Justin Miller <TT +CLASS="EMAIL" +><<A +HREF="mailto:justin@voxel.net" +>justin@voxel.net</A +>></TT +></P +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="manifest.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>XML-RPC for PHP</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Files in the distribution</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/jellyfish.html b/modules/xmlrpc/doc/jellyfish.html new file mode 100644 index 00000000..a4154100 --- /dev/null +++ b/modules/xmlrpc/doc/jellyfish.html @@ -0,0 +1,180 @@ +<HTML +><HEAD +><TITLE +>The Jellyfish Book</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="UP" +TITLE="Support" +HREF="support.html"><LINK +REL="PREVIOUS" +TITLE="Support" +HREF="support.html"><LINK +REL="NEXT" +TITLE="Class documentation" +HREF="apidocs.html"></HEAD +><BODY +CLASS="SECT1" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="support.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +>Chapter 4. Support</TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="apidocs.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="JELLYFISH" +></A +>The Jellyfish Book</H1 +><P +> + <P +><IMG +SRC="http://www.oreilly.com/catalog/covers/progxmlrpc.s.gif" +ALIGN="RIGHT" +WIDTH="145" +HEIGHT="190"></P +> + Together with Simon St.Laurent and Joe Johnston, I wrote a + book on XML-RPC for O'Reilly and Associates on XML-RPC. It + features a rather fetching jellyfish on the cover. + </P +><P +>Complete details of the book are + <A +HREF="http://www.oreilly.com/catalog/progxmlrpc/" +TARGET="_top" +>available + from O'Reilly's web site.</A +> + </P +><P +>I'm responsible for the chapter on PHP, which includes a + worked example of creating a forum server, and hooking it up + the O'Reilly's <A +HREF="http://meerkat.oreillynet.com/" +TARGET="_top" +>Meerkat</A +> service + in order to allow commenting on news stories from around the + Web.</P +><P +>If you've benefitted from the effort I've put into writing + this software, then please consider buying the book!</P +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="support.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="apidocs.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Support</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="support.html" +ACCESSKEY="U" +>Up</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Class documentation</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/manifest.html b/modules/xmlrpc/doc/manifest.html new file mode 100644 index 00000000..1586e41c --- /dev/null +++ b/modules/xmlrpc/doc/manifest.html @@ -0,0 +1,310 @@ +<HTML +><HEAD +><TITLE +>Files in the distribution</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="PREVIOUS" +TITLE="Introduction" +HREF="introduction.html"><LINK +REL="NEXT" +TITLE="Bugs" +HREF="bugs.html"></HEAD +><BODY +CLASS="CHAPTER" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="introduction.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="bugs.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="CHAPTER" +><H1 +><A +NAME="MANIFEST" +></A +>Chapter 2. Files in the distribution</H1 +><DIV +CLASS="GLOSSLIST" +><DL +><DT +><B +>xmlrpc.inc</B +></DT +><DD +><P +>the XML-RPC classes. <TT +CLASS="FUNCTION" +>include()</TT +> this in + your PHP files to use the classes.</P +></DD +><DT +><B +>xmlrpcs.inc</B +></DT +><DD +><P +>the XML-RPC server class. <TT +CLASS="FUNCTION" +>include()</TT +> + this in addition to xmlrpc.inc to get server + functionality</P +></DD +><DT +><B +>bettydemo.php</B +></DT +><DD +><P +>demo which retrieves a state name from a number using Dave + Winer's XML-RPC server at betty.userland.com</P +></DD +><DT +><B +>server.php</B +></DT +><DD +><P +>a sample server hosting three functions: a US State lookup + tool, a struct sorter and an echo function.</P +></DD +><DT +><B +>client.php, agesort.php, echotest.php</B +></DT +><DD +><P +>client code to exercise the various functions in + server.php</P +></DD +><DT +><B +>base64test.php, stringtest.php</B +></DT +><DD +><P +> Tests to verify that encoding and decoding of base 64 and + entities is functioning correctly. + </P +></DD +><DT +><B +>vardemo.php</B +></DT +><DD +><P +>examples of how to construct xmlrpcval types</P +></DD +><DT +><B +>demo1.txt, demo2.txt, demo3.txt</B +></DT +><DD +><P +>XML-RPC responses captured in a file for testing purposes (you + can use these to test the + <TT +CLASS="FUNCTION" +>xmlrpcmsg->parseResponse()</TT +> + method).</P +></DD +><DT +><B +>httptest.php</B +></DT +><DD +><P +>Testing that HTTP response detection works OK.</P +></DD +><DT +><B +>test.pl, test.py</B +></DT +><DD +><P +>Perl and Python programs to exercise server.php to test + that some of the methods work. + Make sure you point these at your server, not mine!</P +></DD +><DT +><B +>workspace.testPhpServer.fttb</B +></DT +><DD +><P +>Frontier scripts to exercise the demo server. Thanks to Dave + Winer for permission to include these. See <A +HREF="http://www.xmlrpc.com/discuss/msgReader$853" +TARGET="_top" +>Dave's announcement of these.</A +></P +></DD +><DT +><B +>phpunit.php</B +></DT +><DD +><P +>Fred Yankowski's unit test framework for PHP.</P +></DD +><DT +><B +>testsuite.php</B +></DT +><DD +><P +>Start of a unit test suite for this software + package. If you do development on this software, please + consider submitting tests for this suite.</P +></DD +><DT +><B +>which.php</B +></DT +><DD +><P +>A demo of the + <TT +CLASS="FUNCTION" +>interopEchoTests.whichToolkit</TT +> + method.</P +></DD +><DT +><B +>discuss.php, comment.php</B +></DT +><DD +><P +>Software used in the PHP chapter of <A +HREF="jellyfish.html" +>The Jellyfish Book</A +> to + provide a comment server and allow the attachment of + comments to stories from Meerkat's data store.</P +></DD +><DT +><B +>rsakey.pem</B +></DT +><DD +><P +>A test certificate for the SSL support. It has the + passphrase "test."</P +></DD +></DL +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="introduction.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="bugs.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Introduction</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Bugs</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/reserved.html b/modules/xmlrpc/doc/reserved.html new file mode 100644 index 00000000..d5525d6a --- /dev/null +++ b/modules/xmlrpc/doc/reserved.html @@ -0,0 +1,191 @@ +<HTML +><HEAD +><TITLE +>Reserved methods</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="PREVIOUS" +TITLE="Debugging aids" +HREF="debugging.html"><LINK +REL="NEXT" +TITLE="system.methodSignature" +HREF="sysmethodsig.html"></HEAD +><BODY +CLASS="CHAPTER" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="debugging.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="sysmethodsig.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="CHAPTER" +><H1 +><A +NAME="RESERVED" +></A +>Chapter 7. Reserved methods</H1 +><DIV +CLASS="TOC" +><DL +><DT +><B +>Table of Contents</B +></DT +><DT +><A +HREF="reserved.html#AEN827" +>system.listMethods</A +></DT +><DT +><A +HREF="sysmethodsig.html" +>system.methodSignature</A +></DT +><DT +><A +HREF="sysmethhelp.html" +>system.methodHelp</A +></DT +></DL +></DIV +><P +>In order to extend the functionality offered by XML-RPC + servers without impacting on the protocol, I've included + experimental support in this release for reserved methods.</P +><P +>All methods starting with <TT +CLASS="FUNCTION" +>system.</TT +> are + considered reserved by the server. PHP for XML-RPC itself provides + three special methods, detailed in this chapter.</P +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="AEN827" +></A +>system.listMethods</H1 +><P +>This method may be used to enumerate the methods implemented + by the XML-RPC server.</P +><P +>The <TT +CLASS="FUNCTION" +>system.listMethods</TT +> method requires + no parameters. It returns an array of strings, each of which is + the name of a method implemented by the server.</P +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="debugging.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="sysmethodsig.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Debugging aids</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>system.methodSignature</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/support.html b/modules/xmlrpc/doc/support.html new file mode 100644 index 00000000..6c60c9cb --- /dev/null +++ b/modules/xmlrpc/doc/support.html @@ -0,0 +1,209 @@ +<HTML +><HEAD +><TITLE +>Support</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="PREVIOUS" +TITLE="Bugs" +HREF="bugs.html"><LINK +REL="NEXT" +TITLE="The Jellyfish Book" +HREF="jellyfish.html"></HEAD +><BODY +CLASS="CHAPTER" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="bugs.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +></TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="jellyfish.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="CHAPTER" +><H1 +><A +NAME="SUPPORT" +></A +>Chapter 4. Support</H1 +><DIV +CLASS="TOC" +><DL +><DT +><B +>Table of Contents</B +></DT +><DT +><A +HREF="support.html#AEN146" +>Online Support</A +></DT +><DT +><A +HREF="jellyfish.html" +>The Jellyfish Book</A +></DT +></DL +></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="AEN146" +></A +>Online Support</H1 +><P +>XML-RPC for PHP is offered "as-is" without any warranty or + commitment to support. However, informal advice and help is + available via the XML-RPC for PHP mailing list and XML-RPC.com. + </P +><P +></P +><UL +><LI +><P +>The <SPAN +CLASS="emphasis" +><I +CLASS="EMPHASIS" +>PHP XML-RPC interest mailing list</I +></SPAN +> + is run by the author. More details <A +HREF="http://www.usefulinc.com/xmlrpc/list.html" +TARGET="_top" +>can be found + here</A +>.</P +></LI +><LI +><P +>For more general XML-RPC questions, there is a + Yahoo! Groups <A +HREF="http://groups.yahoo.com/group/xml-rpc/" +TARGET="_top" +>XML-RPC mailing list</A +>.</P +></LI +><LI +><P +>The <A +HREF="http://www.xmlrpc.com/discuss" +TARGET="_top" +>XML-RPC.com</A +> + discussion group is a useful place to get help with using + XML-RPC. This group is also gatewayed into the Yahoo! Groups mailing list.</P +></LI +></UL +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="bugs.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="jellyfish.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Bugs</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +> </TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>The Jellyfish Book</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/sysmethhelp.html b/modules/xmlrpc/doc/sysmethhelp.html new file mode 100644 index 00000000..151d8d16 --- /dev/null +++ b/modules/xmlrpc/doc/sysmethhelp.html @@ -0,0 +1,155 @@ +<HTML +><HEAD +><TITLE +>system.methodHelp</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="UP" +TITLE="Reserved methods" +HREF="reserved.html"><LINK +REL="PREVIOUS" +TITLE="system.methodSignature" +HREF="sysmethodsig.html"><LINK +REL="NEXT" +TITLE="Examples" +HREF="examples.html"></HEAD +><BODY +CLASS="SECT1" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="sysmethodsig.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +>Chapter 7. Reserved methods</TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="examples.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="SYSMETHHELP" +></A +>system.methodHelp</H1 +><P +>This method takes one parameter, the name of a method + implemented by the XML-RPC server.</P +><P +> It returns a documentation string describing the use of that + method. If no such string is available, an empty string is returned. + </P +><P +> The documentation string may contain HTML markup. + </P +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="sysmethodsig.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="examples.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>system.methodSignature</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="reserved.html" +ACCESSKEY="U" +>Up</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Examples</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/sysmethodsig.html b/modules/xmlrpc/doc/sysmethodsig.html new file mode 100644 index 00000000..bb0bb7ca --- /dev/null +++ b/modules/xmlrpc/doc/sysmethodsig.html @@ -0,0 +1,191 @@ +<HTML +><HEAD +><TITLE +>system.methodSignature</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="UP" +TITLE="Reserved methods" +HREF="reserved.html"><LINK +REL="PREVIOUS" +TITLE="Reserved methods" +HREF="reserved.html"><LINK +REL="NEXT" +TITLE="system.methodHelp" +HREF="sysmethhelp.html"></HEAD +><BODY +CLASS="SECT1" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="reserved.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +>Chapter 7. Reserved methods</TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="sysmethhelp.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="SYSMETHODSIG" +></A +>system.methodSignature</H1 +><P +>This method takes one parameter, the name of a method + implemented by the XML-RPC server.</P +><P +>It returns an array of possible signatures for this + method. A signature is an array of types. The first of these + types is the return type of the method, the rest are parameters.</P +><P +>Multiple signatures (ie. overloading) are permitted: this is + the reason that an array of signatures are returned by this + method.</P +><P +>Signatures themselves are restricted to the top level + parameters expected by a method. For instance if a method + expects one array of structs as a parameter, and it returns a + string, its signature is simply "string, array". If it expects + three integers, its signature is "string, int, int, + int".</P +><P +> If no signature is defined for the method, a none-array value is + returned. Therefore this is the way to test for a non-signature, + if <TT +CLASS="PARAMETER" +><I +>$resp</I +></TT +> below is the response object + from a method call to <TT +CLASS="FUNCTION" +>system.methodSignature</TT +>: + </P +><PRE +CLASS="PROGRAMLISTING" +>$v=$resp->value(); +if ($v->kindOf()!="array") { + // then the method did not have a signature defined +} + </PRE +><P +> See the <TT +CLASS="FILENAME" +>introspect.php</TT +> demo included in + this distribution for an example of using this method. + </P +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="reserved.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="sysmethhelp.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Reserved methods</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="reserved.html" +ACCESSKEY="U" +>Up</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>system.methodHelp</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/xmlrpc-server.html b/modules/xmlrpc/doc/xmlrpc-server.html new file mode 100644 index 00000000..da18e0f7 --- /dev/null +++ b/modules/xmlrpc/doc/xmlrpc-server.html @@ -0,0 +1,487 @@ +<HTML +><HEAD +><TITLE +>xmlrpc_server</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="UP" +TITLE="Class documentation" +HREF="apidocs.html"><LINK +REL="PREVIOUS" +TITLE="xmlrpcval" +HREF="xmlrpcval.html"><LINK +REL="NEXT" +TITLE="Helper functions" +HREF="helpers.html"></HEAD +><BODY +CLASS="SECT1" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="xmlrpcval.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +>Chapter 5. Class documentation</TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="helpers.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="XMLRPC-SERVER" +></A +>xmlrpc_server</H1 +><P +>The current implementation of this class has been + kept as simple as possible. The constructor for the server + basically does all the work. Here's a minimal example:</P +><PRE +CLASS="PROGRAMLISTING" +> function foo ($params) { + ... + } + + $s=new xmlrpc_server( array("examples.myFunc" => + array("function" => "foo"))); + </PRE +><P +> This performs everything you need to do with a server. The single + argument is an associative array from method names to function + names. The request is parsed and despatched to the relevant function, + which is reponsible for returning a + <TT +CLASS="CLASSNAME" +>xmlrpcresp</TT +> + object, which gets + serialized back to the caller. See server.php in this distribution for + examples of how to do this. + </P +><P +>Here is a more detailed look at what the handler function + <TT +CLASS="FUNCTION" +>foo</TT +> may do:</P +><PRE +CLASS="PROGRAMLISTING" +> function foo ($params) { + global $xmlrpcerruser; // import user errcode value + + // $params is an Array of xmlrpcval objects + + if ($err) { + // this is an error condition + return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 + "There's a problem, Captain"); + } else { + // this is a successful value being returned + return new xmlrpcresp(new xmlrpcval("All's fine!", "string")); + } + } + </PRE +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN658" +></A +>The dispatch map</H2 +><P +>The first argument to the + <TT +CLASS="FUNCTION" +>xmlrpc_server</TT +> constructor is an array, + called the <SPAN +CLASS="emphasis" +><I +CLASS="EMPHASIS" +>dispatch map</I +></SPAN +>. In this array is the + information the server needs to service the XML-RPC methods + you define.</P +><P +> The dispatch map takes the form of an associative array of + associative arrays: the outer array has one entry for each + method, the key being the method name. The corresponding value + is another associative array, which can have the following members: + </P +><P +></P +><UL +><LI +><P +><TT +CLASS="FUNCTION" +>function</TT +> - this entry is + mandatory. It must be a name of a function in the + global scope which services the XML-RPC method.</P +></LI +><LI +><P +><TT +CLASS="FUNCTION" +>signature</TT +> - this entry is an + array containg the possible signatures (see <A +HREF="xmlrpc-server.html#SIGNATURES" +>Signatures</A +>) for the method. If + this entry is present then the server will check that the + correct number and type of parameters have been sent for + this method before dispatching it. + </P +></LI +><LI +><P +> <TT +CLASS="FUNCTION" +>docstring</TT +> - this entry is a string + containing documentation for the method. The + documentation may contain HTML markup. + </P +></LI +></UL +><P +>Look at the <TT +CLASS="FILENAME" +>server.php</TT +> example in the + distribution to see what a dispatch map looks like.</P +></DIV +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="SIGNATURES" +></A +>Method signatures</H2 +><P +>A signature is a description of a method's return type and + its parameter types. A method may have more than one + signature.</P +><P +>Within a server's dispatch map, each method has an array + of possible signatures. Each signature is an array of + types. The first entry is the return type. For instance, the + method <PRE +CLASS="PROGRAMLISTING" +>string examples.getStateName(int)</PRE +> has the signature +<PRE +CLASS="PROGRAMLISTING" +>array($xmlrpcString, $xmlrpcInt)</PRE +> and, assuming that it the only possible signature for + the method, might be used like this in server creation: +<PRE +CLASS="PROGRAMLISTING" +>$findstate_sig=array(array($xmlrpcString, $xmlrpcInt)); + +$findstate_doc='When passed an integer between 1 and 51 returns the +name of a US state, where the integer is the index of that state name +in an alphabetic order.'; + +$s=new xmlrpc_server( array( "examples.getStateName" => + array("function" => "findstate", + "signature" => $findstate_sig, + "docstring" => $findstate_doc)));</PRE +> + + </P +><P +>For convenience the strings representing the XML-RPC types + have been encoded as global variables:<PRE +CLASS="PROGRAMLISTING" +>$xmlrpcI4="i4"; +$xmlrpcInt="int"; +$xmlrpcBoolean="boolean"; +$xmlrpcDouble="double"; +$xmlrpcString="string"; +$xmlrpcDateTime="dateTime.iso8601"; +$xmlrpcBase64="base64"; +$xmlrpcArray="array"; +$xmlrpcStruct="struct";</PRE +></P +></DIV +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN686" +></A +>Delaying the server response</H2 +><P +>You may want to construct the server, but for some reason + not fulfill the request immediately (security verification, for + instance). If you pass the constructor a second argument of + <TT +CLASS="LITERAL" +>0</TT +> this will have the desired effect. You + can then use the <TT +CLASS="FUNCTION" +>service()</TT +> method of the + server class to service the request. For example:</P +><PRE +CLASS="PROGRAMLISTING" +>$s=new xmlrpc_server($myDispMap, 0); + +// ... some code that does other stuff here + +$s->service();</PRE +></DIV +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN692" +></A +>Fault reporting</H2 +><P +>Fault codes for your servers should start at the + value indicated by + the global <TT +CLASS="LITERAL" +>$xmlrpcerruser</TT +> + 1.</P +><P +>Standard errors returned by the server include:</P +><P +></P +><DIV +CLASS="VARIABLELIST" +><DL +><DT +><TT +CLASS="LITERAL" +>1</TT +> <SPAN +CLASS="phrase" +><SPAN +CLASS="PHRASE" +>Unknown method</SPAN +></SPAN +></DT +><DD +><P +>Returned if the server was asked to dispatch a + method it didn't know about</P +></DD +><DT +><TT +CLASS="LITERAL" +>2</TT +> <SPAN +CLASS="phrase" +><SPAN +CLASS="PHRASE" +>Invalid return payload</SPAN +></SPAN +></DT +><DD +><P +>This error is actually generated by the client, not + server, code, but signifies that a server returned + something it couldn't understand.</P +></DD +><DT +><TT +CLASS="LITERAL" +>3</TT +> <SPAN +CLASS="phrase" +><SPAN +CLASS="PHRASE" +>Incorrect parameters</SPAN +></SPAN +></DT +><DD +><P +>This error is generated when the server has signature(s) + defined for a method, and the parameters passed by the + client do not match any of signatures.</P +></DD +><DT +><TT +CLASS="LITERAL" +>4</TT +> <SPAN +CLASS="phrase" +><SPAN +CLASS="PHRASE" +>Can't introspect: method unknown</SPAN +></SPAN +></DT +><DD +><P +>This error is generated by the builtin + <TT +CLASS="FUNCTION" +>system.*</TT +> methods when any kind of + introspection is attempted on a method undefined by the + server.</P +></DD +><DT +><TT +CLASS="LITERAL" +>5</TT +> <SPAN +CLASS="phrase" +><SPAN +CLASS="PHRASE" +>Didn't receive 200 OK from remote server</SPAN +></SPAN +></DT +><DD +><P +>This error is generated by the client when a remote server + doesn't return HTTP/1.1 200 OK in response to a + request. A more detailed error report is added onto the + end of the phrase above.</P +></DD +><DT +><TT +CLASS="LITERAL" +>100-</TT +> <SPAN +CLASS="phrase" +><SPAN +CLASS="PHRASE" +>XML parse errors</SPAN +></SPAN +></DT +><DD +><P +>Returns 100 plus the XML parser error code for the + fault that occurred. The + <TT +CLASS="FUNCTION" +>faultString</TT +> returned explains where + the parse error was in the incoming XML stream.</P +></DD +></DL +></DIV +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="xmlrpcval.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="helpers.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>xmlrpcval</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="apidocs.html" +ACCESSKEY="U" +>Up</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Helper functions</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/xmlrpc_php.sgml b/modules/xmlrpc/doc/xmlrpc_php.sgml new file mode 100644 index 00000000..4f9bc7b2 --- /dev/null +++ b/modules/xmlrpc/doc/xmlrpc_php.sgml @@ -0,0 +1,1487 @@ +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3//EN" []> +<book> + <bookinfo> + <title>XML-RPC for PHP</title> + <subtitle>version 1.1</subtitle> + <date>December 17, 2002</date> + <authorgroup> + <author> + <firstname>Edd</firstname> + <surname>Dumbill</surname> + <affiliation> + <orgname><ulink url="http://usefulinc.com/">Useful + Information Company</ulink></orgname> + <address> + <email>edd@usefulinc.com</email> + </address> + </affiliation> + </author> + </authorgroup> + <copyright> + <year>1999,2000,2001</year> + <holder>Edd Dumbill, Useful Information Company</holder> + </copyright> + <legalnotice> + <para> + All rights reserved. + </para> + <para> + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + </para> + + <para> + <itemizedlist> + <listitem> + <para> + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + </para> + </listitem> + + <listitem><para> + 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. + </para></listitem> + + <listitem><para> + 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. + </para></listitem> + </itemizedlist> + </para> + <para> 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.</para> + + </legalnotice> + </bookinfo> + <toc> + </toc> + <chapter id="introduction"> + + <title>Introduction</title> + + <para>XML-RPC is a format devised by <ulink + url="http://www.userland.com/">Userland Software</ulink> for + achieving remote procedure call via XML. XML-RPC has its own web + site, <ulink + url="http://www.xmlrpc.com/">www.XmlRpc.com</ulink></para> + <para>The most common implementations of XML-RPC available at the + moment use HTTP as the transport. A list of implementations for + other languages such as Perl and Python can be found on the + <ulink + url="http://www.xmlrpc.com/">www.xmlrpc.com</ulink>.</para> + <para>This collection of PHP classes provides a framework for + writing XML-RPC clients and servers in PHP.</para> + <warning> + <para>The <emphasis>server code</emphasis> works only with versions of PHP3 + >= 3.0.12. The code is also known to work with PHP4. + </para> + <para>If you wish to use SSL to communicate with remote servers, + you need the "curl" extension compiled into your PHP + installation, this is available in PHP 4.0.2 and greater, + although 4.0.6 has a bug preventing SSL working.</para> + </warning> + + <sect1> + <title>Acknowledgements</title> + <para>Jim Winstead <email>jimw@php.net</email></para> + <para>Peter Kocks <email>peter.kocks@baygate.com</email></para> + <para>Nicolay Mausz <email>mausz@flying-dog.com</email></para> + <para>Ben Margolin + <email>ben@wendy.auctionwatch.com</email></para> + <para>Dan Libby <email>dan@libby.com</email></para> + <para>Gaetano Giunta <email>g.giunta@libero.it</email></para> + <para>Idan Sofer <email>i_sofer@yahoo.com</email></para> + <para>Giancarlo Pinerolo <email>ping@alt.it</email></para> + <para>Justin Miller <email>justin@voxel.net</email></para> + </sect1> + </chapter> + + <chapter id="manifest"> + <title>Files in the distribution</title> + + <glosslist> + <glossentry> + <glossterm>xmlrpc.inc</glossterm> + <glossdef> + <para>the XML-RPC classes. <function>include()</function> this in + your PHP files to use the classes.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>xmlrpcs.inc</glossterm> + <glossdef> + <para>the XML-RPC server class. <function>include()</function> + this in addition to xmlrpc.inc to get server + functionality</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>bettydemo.php</glossterm> + <glossdef> + <para>demo which retrieves a state name from a number using Dave + Winer's XML-RPC server at betty.userland.com</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>server.php</glossterm> + <glossdef> + <para>a sample server hosting three functions: a US State lookup + tool, a struct sorter and an echo function.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>client.php, agesort.php, echotest.php</glossterm> + <glossdef> + <para>client code to exercise the various functions in + server.php</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>base64test.php, stringtest.php</glossterm> + <glossdef> + <para> + Tests to verify that encoding and decoding of base 64 and + entities is functioning correctly. + </para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>vardemo.php</glossterm> + <glossdef> + <para>examples of how to construct xmlrpcval types</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>demo1.txt, demo2.txt, demo3.txt</glossterm> + <glossdef> + <para>XML-RPC responses captured in a file for testing purposes (you + can use these to test the + <function>xmlrpcmsg->parseResponse()</function> + method).</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>httptest.php</glossterm> + <glossdef> + <para>Testing that HTTP response detection works OK.</para> + </glossdef> + </glossentry> + <glossentry> + <glossterm>test.pl, test.py</glossterm> + <glossdef> + <para>Perl and Python programs to exercise server.php to test + that some of the methods work. + Make sure you point these at your server, not mine!</para> + </glossdef> + </glossentry> + <glossentry> + <glossterm>workspace.testPhpServer.fttb</glossterm> + <glossdef> + <para>Frontier scripts to exercise the demo server. Thanks to Dave + Winer for permission to include these. See <ulink + url="http://www.xmlrpc.com/discuss/msgReader$853">Dave's announcement of these.</ulink></para> + + </glossdef> + </glossentry> + + <glossentry> + <glossterm>phpunit.php</glossterm> + <glossdef> + <para>Fred Yankowski's unit test framework for PHP.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>testsuite.php</glossterm> + <glossdef> + <para>Start of a unit test suite for this software + package. If you do development on this software, please + consider submitting tests for this suite.</para> + </glossdef> + </glossentry> + <glossentry> + <glossterm>which.php</glossterm> + <glossdef> + <para>A demo of the + <function>interopEchoTests.whichToolkit</function> + method.</para> + </glossdef> + </glossentry> + <glossentry> + <glossterm>discuss.php, comment.php</glossterm> + <glossdef> + <para>Software used in the PHP chapter of <xref linkend="jellyfish"> to + provide a comment server and allow the attachment of + comments to stories from Meerkat's data store.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>rsakey.pem</glossterm> + <glossdef> + <para>A test certificate for the SSL support. It has the + passphrase "test."</para> + </glossdef> + </glossentry> + </glosslist> + </chapter> + <chapter id="bugs"> + <title>Bugs</title> + <para>This is a bare framework. The "nice" bits haven't been put in + yet. Specifically, no HTTP response checking is performed, and no type + validation or coercion has been put in. PHP being a loosely-typed + language, this is going to have to be done explicitly.</para> + <para>dateTime.iso8601 is supported opaquely. It can't be done + natively as the XML-RPC specification explictly forbids passing of + timezone specifiers in ISO8601 format dates. You can, however, use + the <xref linkend="iso8601encode"> and <xref + linkend="iso8601decode"> functions to do the encoding and decoding for you.</para> + <para>If alternative character set encoding is sent in HTTP header + than it will be ignored for the moment. We speak only UTF-8...</para> + <para>If more than 32k of HTTP headers are encountered (like, why?) then the + response parsing code will break.</para> + + </chapter> + <chapter id="support"> + <title>Support</title> + <sect1> + <title>Online Support</title> + + <para>XML-RPC for PHP is offered "as-is" without any warranty or + commitment to support. However, informal advice and help is + available via the XML-RPC for PHP mailing list and XML-RPC.com. + </para> + <itemizedlist> + <listitem> + <para>The <emphasis>PHP XML-RPC interest mailing list</emphasis> + is run by the author. More details <ulink + url="http://www.usefulinc.com/xmlrpc/list.html">can be found + here</ulink>.</para> + </listitem> + <listitem><para>For more general XML-RPC questions, there is a + Yahoo! Groups <ulink + url="http://groups.yahoo.com/group/xml-rpc/">XML-RPC mailing list</ulink>.</para> + <listitem> + <para>The <ulink + url="http://www.xmlrpc.com/discuss">XML-RPC.com</ulink> + discussion group is a useful place to get help with using + XML-RPC. This group is also gatewayed into the Yahoo! Groups mailing list.</para> + </listitem> + </itemizedlist> + </sect1> + <sect1 id="jellyfish" xreflabel="The + Jellyfish Book"> + <title>The Jellyfish Book</title> + <para> + <graphic + fileref="http://www.oreilly.com/catalog/covers/progxmlrpc.s.gif" + format="gif" width="145" depth="190" align="right"></graphic> + Together with Simon St.Laurent and Joe Johnston, I wrote a + book on XML-RPC for O'Reilly and Associates on XML-RPC. It + features a rather fetching jellyfish on the cover. + </para> + <para>Complete details of the book are + <ulink + url="http://www.oreilly.com/catalog/progxmlrpc/">available + from O'Reilly's web site.</ulink> + </para> + <para>I'm responsible for the chapter on PHP, which includes a + worked example of creating a forum server, and hooking it up + the O'Reilly's <ulink + url="http://meerkat.oreillynet.com/">Meerkat</ulink> service + in order to allow commenting on news stories from around the + Web.</para> + <para>If you've benefitted from the effort I've put into writing + this software, then please consider buying the book!</para> + </sect1> + </chapter> + <chapter id="apidocs"> + <title>Class documentation</title> + <sect1 id="xmlrpc-client" xreflabel="xmlrpc_client"> + <title>xmlrpc_client</title> + <para>This is the basic class used to represent a client of an + XML-RPC server.</para> + <sect2> + <title>Creation</title> + <para>The constructor has the following syntax:</para> + <funcsynopsis> + <funcprototype> + <funcdef>$client=new xmlrpc_client</funcdef> + <paramdef><parameter>$server_path</parameter></paramdef> + <paramdef><parameter>$server_hostname</parameter></paramdef> + <paramdef><parameter>$server_port</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Here's an example client set up to query Userland's XML-RPC + server at <emphasis>betty.userland.com</emphasis>:</para> + <programlisting> +$client=new xmlrpc_client("/RPC2", "betty.userland.com", 80);</programlisting> + <para>The <parameter>server_port</parameter> parameter is + optional, and if omitted will default to 80 when using + HTTP and 443 when using HTTPS (see the "send" method below.)</para> + + </sect2> + <sect2> + <title>Methods</title> + <para>This class supports the following methods.</para> + <sect3 id="xmlrpc-client-send" xreflabel="xmlrpc_client->send"> + <title>send</title> + <para>This method takes the form:</para> + <funcsynopsis> + <funcprototype> + <funcdef>$response=$client->send</funcdef> + <paramdef><parameter>$xmlrpc_message</parameter></paramdef> + <paramdef><parameter>$timeout</parameter></paramdef> + <paramdef><parameter>$server_method</parameter></paramdef> + </funcprototype> + </funcsynopsis> + + <para>Where <parameter>$xmlrpc_message</parameter> is an + instance of <classname>xmlrpcmsg</classname> (see <xref + linkend="xmlrpcmsg">), and + <parameter>$response</parameter> is an + instance of <classname>xmlrpcresp</classname> (see <xref + linkend="xmlrpcresp">).</para> + + <para>The <parameter>$timeout</parameter> is optional, and + will be set to <literal>0</literal> (wait forever) if + omitted. This timeout value is passed to + <function>fsockopen()</function>.</para> + + <para>The <parameter>server_method</parameter> parameter is + optional, and if omitted will default to 'http'. The only + other valid value is 'https', which will use an SSL HTTP + connection to connect to the remote server. Note that your + PHP must have the "curl" extensions compiled in in order to + use this feature. Note that when using SSL you should + normally set your port number to 443, unless the SSL server + you are contacting runs at any other port.</para> + <warning> + <para>PHP 4.0.2 or greater is required for SSL + functionality. + PHP 4.0.6 has a bug which prevents SSL + working.</para> + </warning> + <para>If the value of <parameter>$response</parameter> is + <literal>0</literal> rather than an + <classname>xmlrpcresp</classname> object, then this + signifies an I/O error has occured. You can find out what + the I/O error was from the values + <function>$client->errno</function> and + <function>$client->errstring</function>. + </para> + <para>In addition to low-level errors, the XML-RPC server you + were querying may return an error in the + <classname>xmlrpcresp</classname> object. See <xref + linkend="xmlrpcresp"> for details of + how to handle these errors. + </para> + </sect3> + + <sect3> + <title>setCredentials</title> + <funcsynopsis> + <funcprototype> + <funcdef>$client->setCredentials</funcdef> + <paramdef><parameter>$username</parameter></paramdef> + <paramdef><parameter>$password</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>This method sets the username and password for authorizing the + client to a server. With the default (HTTP) transport, this + information is used for HTTP Basic authorization. + + </para> + </sect3> + <sect3> + <title>setCertificate</title> + <funcsynopsis> + <funcprototype> + <funcdef>$client->setCertificate</funcdef> + <paramdef><parameter>$certificate</parameter></paramdef> + <paramdef><parameter>$passphrase</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>This method sets the optional certificate and passphrase + used in SSL-enabled communication with a remote server + (when the <parameter>server_method</parameter> is set to + 'https' in the client's construction). + </para> + <para>The <parameter>certificate</parameter> parameter must + be the filename of a PEM formatted certificate. The + <parameter>passphrase</parameter> parameter must contain + the password required to use the certificate.</para> + <para>This requires the "curl" extensions to be compiled + into your installation of PHP.</para> + </sect3> + <sect3> + <title>setSSLVerifyPeer</title> + <funcsynopsis> + <funcprototype> + <funcdef>$client->setSSLVerifyPeer</funcdef> + <paramdef><parameter>$i</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>This method defines whether connections made to XMLRPC + backends via HTTPS should verify the remote host's SSL + certificate, and cause the connection to fail if the cert + verification fails. $i should be a boolean value. + </para> + </sect3> + <sect3> + <title>setSSLVerifyHost</title> + <funcsynopsis> + <funcprototype> + <funcdef>$client->setSSLVerifyHost</funcdef> + <paramdef><parameter>$i</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>This method defines whether connections made to XMLRPC + backends via HTTPS should verify the remote host's SSL + certificate's common name (CN). By default, only the existence + of a CN is checked. $i should be an integer value; 0 to not + check the CN at all, 1 to merely check for its existence, and + 2 to check that the CN on the certificate matches the hostname + that is being connected to. + </para> + </sect3> + + + <sect3> + <title>setDebug</title> + <funcsynopsis> + <funcprototype> + <funcdef>$client->setDebug</funcdef> + <paramdef><parameter>$debugOn</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para><parameter>$debugOn</parameter> is either + <literal>0</literal> or <literal>1</literal> depending on + whether you require the client to print debugging + information to the browser. The default is not to output + this information.</para> + <para> + The debugging information includes the raw data returned + from the XML-RPC server it was querying, and the PHP value + the client attempts to create to represent the value + returned by the server. This option can be very useful when + debugging servers as it allows you to see exactly what the + server returns. + </para> + </sect3> + </sect2> + </sect1> + <sect1 id="xmlrpcmsg" xreflabel="xmlrpcmsg"> + <title>xmlrpcmsg</title> + <para>This class provides a representation for a request to an + XML-RPC server. A client sends an + <classname>xmlrpcmsg</classname> to a server, and receives back + an <classname>xmlrpcresp</classname> (see <xref + linkend="xmlrpc-client-send">).</para> + <sect2> + <title>Creation</title> + <para>The constructor takes the following form:</para> + <funcsynopsis> + <!-- one of (funcprototype funcdef) --> + <funcprototype> + <funcdef>$msg=new xmlrpcmsg</funcdef> + <paramdef><parameter>$methodName</parameter></paramdef> + <paramdef><parameter>$parameterArray</parameter></paramdef> + </funcprototype> + </funcsynopsis> + + <para>Where <parameter>$methodName</parameter> is a string + indicating the name of the method you wish to invoke, and + <parameter>$parameterArray</parameter> is a simple + <classname>Array</classname> of + <classname>xmlrpcval</classname> objects. Here's an example + message to the <emphasis>US state name</emphasis> server: + </para> + <programlisting> +$msg=new xmlrpcmsg("examples.getStateName", + array(new xmlrpcval(23, "int"))); + </programlisting> + <para> + This example requests the name of state number 23. For more + information on <classname>xmlrpcval</classname> objects, see + <xref linkend="xmlrpcval">. + </para> + </sect2> + <sect2> + <title>Methods</title> + <sect3> + <title>serialize</title> + <funcsynopsis> + <funcprototype> + <funcdef>$outString=$msg->serialize</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para>Returns the an XML string representing the XML-RPC + message.</para> + </sect3> + <sect3> + <title>addParam</title> + <funcsynopsis> + <funcprototype> + <funcdef>$msg->addParam</funcdef> + <paramdef><parameter>$xmlrpcVal</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Adds the <classname>xmlrpcval</classname> + <parameter>$xmlrpcVal</parameter> to the parameter list for + this method call.</para> + </sect3> + <sect3> + <title>getParam</title> + <funcsynopsis> + <funcprototype> + <funcdef>$xmlrpcVal=$msg->getParam</funcdef> + <paramdef><parameter>$n</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Gets the <parameter>$n</parameter>th parameter in the + message. Use this method in server implementations. Returns + the <literal>undef</literal> value if no such parameter + exists.</para> + </sect3> + <sect3> + <title>getNumParams</title> + <funcsynopsis> + <funcprototype> + <funcdef>$n=$msg->getNumParams</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Returns the number of parameters attached to this message. + </para> + </sect3> + <sect3> + <title>method</title> + <funcsynopsis> + <funcprototype> + <funcdef>$methName=$msg->method</funcdef> + <paramdef></paramdef> + </funcprototype> + <funcprototype> + <funcdef>$msg->method</funcdef> + <paramdef><parameter>$methName</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Gets or sets the method contained in the XML-RPC message.</para> + </sect3> + <sect3> + <title>parseResponse</title> + <funcsynopsis> + + <funcprototype> + <funcdef>$response=$msg->parseResponse</funcdef> + <paramdef><parameter>$xmlString</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Given an incoming XML-RPC server response contained in + the string + <parameter>$xmlString</parameter>, this method constructs + an <classname>xmlrpcresp</classname> response object and + returns it, setting error codes as appropriate (see <xref + linkend="xmlrpc-client-send">). + </para> + <para> + This method processes any HTTP/MIME headers it finds. + </para> + </sect3> + <sect3> + <title>parseResponseFile</title> + <funcsynopsis> + <funcprototype> + <funcdef>$response=$msg->parseResponseFile</funcdef> + <paramdef><parameter>$fileHandle</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Given an incoming XML-RPC server response on the file handle + <parameter>$fileHandle</parameter>, this method reads the + data and passes it to <function>parseResponse</function> + </para> + <para> + This method is useful to construct responses from + pre-prepared files (see files <literal>demo1.txt, demo2.txt, + demo3.txt</literal> in this distribution). It processes + any HTTP headers it finds. + </para> + </sect3> + </sect2> + </sect1> + <sect1 id="xmlrpcresp" xreflabel="xmlrpcresp"> + <title>xmlrpcresp</title> + <para>This class is used to contain responses to XML-RPC + requests. A server method handler will construct an + <classname>xmlrpcresp</classname> and pass it as a return value. + This same value will be returned by the result of an invocation of + the <function>send</function> method of the + <classname>xmlrpc_client</classname> class.</para> + <sect2> + <title>Creation</title> + <funcsynopsis> + <!-- one of (funcprototype funcdef) --> + <funcprototype> + <funcdef>$resp=new xmlrpcresp</funcdef> + <!-- one of (paramdef varargs void) --> + <paramdef><parameter>$xmlrpcval</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>$resp=new xmlrpcresp</funcdef> + <paramdef><parameter>0</parameter></paramdef> + <paramdef><parameter + >$errcode</parameter></paramdef> + <paramdef><parameter + >$errstring</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>The first instance is used when execution has happened + without difficulty: <parameter>$xmlrpcval</parameter> is an + <classname>xmlrpcval</classname> value with the result of the + method execution contained in it.</para> + <para> + The second type of constructor is used in case of + failure. <parameter>$errcode</parameter> and + <parameter>$errstring</parameter> are used to provide + indication of what has gone wrong. See <xref + linkend="xmlrpc-server"> for more information on passing + error codes. + </para> + </sect2> + <sect2> + <title>Methods</title> + <sect3> + <title>faultCode</title> + <funcsynopsis> + <funcprototype> + <funcdef>$fn=$resp->faultCode</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para>Returns the integer fault code return from the XML-RPC + response <parameter>$resp</parameter>. + A zero value indicates success, any other value + indicates a failure response.</para> + </sect3> + <sect3> + <title>faultString</title> + <funcsynopsis> + <funcprototype> + <funcdef>$fs=$resp->faultString</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Returns the human readable explanation of the fault + indicated by <function>$resp->faultCode</function>. + </para> + </sect3> + <sect3> + <title>value</title> + <funcsynopsis> + <funcprototype> + <funcdef>$xmlrpcVal=$resp->value</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Returns an <classname>xmlrpcval</classname> object + containing the return value sent by the server. If the + response's <function>faultCode</function> is non-zero then + the value returned by this method should not be used (it may + not even be an object). + </para> + </sect3> + <sect3> + <title>serialize</title><para></para> + <funcsynopsis> + <funcprototype> + <funcdef>$outString=$resp->serialize</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para>Returns an XML string representation of the response.</para> + </sect3> + </sect2> + </sect1> + <sect1 id="xmlrpcval" xreflabel="xmlrpcval"> + <title>xmlrpcval</title> + <para>This is where a lot of the hard work gets done. This class + enables the creation and encapsulation of values for XML-RPC. + </para> + <para> + Ensure you've read the XML-RPC spec at <ulink + url="http://www.xmlrpc.com/stories/storyReader$7">http://www.xmlrpc.com/stories/storyReader$7</ulink> + before reading on as it will make things clearer. + </para> + <para>The <classname>xmlrpcval</classname> class can store + arbitrarily complicated values using the following types: + <literal>i4 int boolean string double dateTime.iso8601 base64 + array struct</literal>. You should refer to the <ulink + url="http://www.xmlrpc.com/stories/storyReader$7">spec</ulink> + for more information on what each of these types mean. + </para> + <sect2> + <title>Notes on types</title> + <sect3> + <title>int</title> + <para>The type <classname>i4</classname> is accepted as a + synonym for <classname>int</classname>. The value parsing + code will always convert <classname>i4</classname> to + <classname>int</classname>: <classname>int</classname> + is regarded by this implementation as the canonical name for + this type.</para> + </sect3> + <sect3> + <title>base64</title> + <para>Base 64 encoding is performed transparently to the + caller when using this type. Therefore you ought to + consider it as a "binary" data type, for use when you want + to pass none 7-bit clean data. Decoding is also + transparent. + </para> + </sect3> + <sect3> + <title>boolean</title> + <para>The values <literal>true</literal> and + <literal>1</literal> map to <literal>true</literal>. All + other values (including the empty string) + are converted to <literal>false</literal>. + </para> + </sect3> + <sect3> + <title>string</title> + <para> + The characters <literal>< > "</literal> and + <literal>&</literal> are converted to their entity + equivalents <literal>&lt; &gt; + &quot;</literal> and <literal>&amp;</literal> + for transport through XML-RPC. The current XML-RPC spec + recommends only encoding <literal>< &</literal> but + this implementation goes further, for reasons explained by + <ulink url="http://www.w3.org/TR/REC-xml#syntax">the XML 1.0 + recommendation</ulink>. + </para><para>TODO: <literal> &apos;</literal> entity not + yet supported</para> + </sect3> + </sect2> + <sect2 id="xmlrpcval-creation" xreflabel="xmlrpcval constructors"> + <title>Creation</title> + <para>The constructor is the normal way to create an + <classname>xmlrpcval</classname>. The constructor can take + these forms: + </para> + <funcsynopsis> + <!-- one of (funcprototype funcdef) --> + <funcprototype> + <funcdef>$myVal=new xmlrpcval</funcdef> + <!-- one of (paramdef varargs void) --> + <paramdef></paramdef> + </funcprototype> + <funcprototype> + <funcdef>$myVal=new xmlrpcval</funcdef> + <!-- one of (paramdef varargs void) --> + <paramdef><parameter>$stringVal</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>$myVal=new xmlrpcval</funcdef> + <!-- one of (paramdef varargs void) --> + <paramdef><parameter>$scalarVal</parameter></paramdef> + <paramdef><parameter>"int" | "boolean" | "string" | "double" | "dateTime.iso8601" | "base64"</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>$myVal=new xmlrpcval</funcdef> + <!-- one of (paramdef varargs void) --> + <paramdef><parameter>$arrayVal</parameter></paramdef> + <paramdef><parameter>"array" | "struct"</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>The first constructor creates an empty value, which must + be altered using the methods <function>addScalar</function>, + <function>addArray</function> or + <function>addStruct</function> before it can be used. + </para> + <para> + The second constructor creates a simple string value. + </para> + <para> + The third constructor is used to create a scalar value. The + second parameter must be a name of an XML-RPC type. Examples: + </para> + <programlisting> + $myInt=new xmlrpcvalue(1267, "int"); + $myString=new xmlrpcvalue("Hello, World!", "string"); + $myBool=new xmlrpcvalue(1, "boolean"); + </programlisting> + + <para> + The fourth constructor form can be used to compose complex + XML-RPC values. The first argument is either a simple array in + the case of an XML-RPC <classname>array</classname> or + an associative array in the case of a + <classname>struct</classname>. The elements of the array + <emphasis>must be <classname>xmlrpcval</classname> objects + themselves</emphasis>. + Examples:</para> + <programlisting> + $myArray=new xmlrpcval(array( + new xmlrpcval("Tom"), new xmlrpcval("Dick"), + new xmlrpcval("Harry")), "array"); + + $myStruct=new xmlrpcval(array( + "name" => new xmlrpcval("Tom"), + "age" => new xmlrpcval(34, "int"), + "geek" => new xmlrpcval(1, "boolean")), "struct"); + </programlisting> + <para>See the file <literal>vardemo.php</literal> in this + distribution for more examples.</para> + </sect2> + <sect2 id="xmlrpcval-methods" xreflabel="xmlrpcval methods"> + <title>Methods</title> + <sect3> + <title>addScalar</title> + <funcsynopsis> + <!-- one of (funcprototype funcdef) --> + <funcprototype> + <funcdef>$ok=$val->addScalar</funcdef> + <!-- one of (paramdef varargs void) --> + <paramdef><parameter>$stringVal</parameter></paramdef> + </funcprototype> + <funcprototype> + <funcdef>$ok=$val->addScalar</funcdef> + <!-- one of (paramdef varargs void) --> + <paramdef><parameter>$scalarVal</parameter></paramdef> + <paramdef><parameter>"int" | "boolean" | "string" | "double" | "dateTime.iso8601" | "base64"</parameter></paramdef> + </funcprototype> + + </funcsynopsis> + <para> + If <parameter>$val</parameter> is an empty + <classname>xmlrpcval</classname> this method makes it a + scalar value, and sets that value. If + <parameter>$val</parameter> is already a scalar value, then + no more scalars can be added and <literal>0</literal> is + returned. If all went OK, <literal>1</literal> is returned. + </para> + <para>There is a special case if <parameter>$val</parameter> + is an <classname>array</classname>: the scalar value passed + is appended to the array.</para> + </sect3> + <sect3> + <title>addArray</title> + <funcsynopsis> + <funcprototype> + <funcdef>$ok=$val->addArray</funcdef> + <paramdef><parameter>$arrayVal</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Turns an empty <classname>xmlrpcval</classname> into an + <classname>array</classname> with contents as specified by + <parameter>$arrayVal</parameter>. See the fourth + constructor form for more information.</para> + </sect3> + <sect3> + <title>addStruct</title> + <funcsynopsis> + <funcprototype> + <funcdef>$ok=$val->addArray</funcdef> + <paramdef><parameter>$assocArrayVal</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Turns an empty <classname>xmlrpcval</classname> into a + <classname>struct</classname> with contents as specified by + <parameter>$assocArrayVal</parameter>. See the fourth + constructor form for more information.</para> + </sect3> + <sect3> + <title>kindOf</title> + <funcsynopsis> + <funcprototype> + <funcdef>$kind=$val->kindOf</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Returns a string containing "struct", "array" or "scalar" + describing the base type of the value. If it returns + "undef" it means that the value hasn't been initialised. + </para> + </sect3> + <sect3> + <title>serialize</title> + <funcsynopsis> + <funcprototype> + <funcdef>$outString=$val->serialize</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Returns a string containing the XML-RPC representation of + this value. + </para> + </sect3> + <sect3> + <title>scalarval</title> + <funcsynopsis> + <funcprototype> + <funcdef>$scalarVal=$val->scalarval</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para> + If <function>$val->kindOf()=="scalar"</function>, this + method returns the actual PHP-language value of the scalar + (base 64 decoding is automatically handled here). + </para> + </sect3> + <sect3> + <title>scalartyp</title> + <funcsynopsis> + <funcprototype> + <funcdef>$typeName=$val->scalartyp</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para> + If <function>$val->kindOf()=="scalar"</function>, this + method returns a string denoting the type of the scalar. + As mentioned before, + <literal>i4</literal> is always coerced to <literal>int</literal>. + </para> + </sect3> + <sect3> + <title>arraymem</title> + <funcsynopsis> + <funcprototype> + <funcdef>$xmlrpcVal=$val->arraymem</funcdef> + <paramdef><parameter>$n</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Returns the <parameter>$n</parameter>th element in the array + represented by the value <parameter>$val</parameter>. The + value returned is an <classname>xmlrpcval</classname> object. + </para> + </sect3> + <sect3> + <title>arraysize</title> + <funcsynopsis> + <funcprototype> + <funcdef>$len=$val->arraysize</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para>If <parameter>$val</parameter> is an + <classname>array</classname>, returns the number of elements + in that array. + </para> + </sect3> + <sect3> + <title>structmem</title> + <funcsynopsis> + <funcprototype> + <funcdef>$xmlrpcVal=$val->structmem</funcdef> + <paramdef><parameter>$memberName</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Returns the element called + <parameter>$memberName</parameter> from the struct + represented by the value <parameter>$val</parameter>. The + value returned is an <classname>xmlrpcval</classname> object. + </para> + </sect3> + <sect3> + <title>structeach</title> + <funcsynopsis> + <funcprototype> + <funcdef>list($key,$value)=$val->structeach</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Returns the next (key,value) pair from the struct, when + <parameter>$val</parameter> is a struct. See also + <xref linkend="structreset">. + </para> + </sect3> + + <sect3 id="structreset" xreflabel="structreset()"> + <title>structreset</title> + <funcsynopsis> + <funcprototype> + <funcdef>$val->structreset</funcdef> + <paramdef></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Resets the internal pointer for + <function>structeach()</function> to the beginning of the + struct, where <parameter>$val</parameter> is a struct. + </para> + </sect3> + + </sect2> + </sect1> + <sect1 id="xmlrpc-server" xreflabel="xmlrpc_server"> + <title>xmlrpc_server</title> + <para>The current implementation of this class has been + kept as simple as possible. The constructor for the server + basically does all the work. Here's a minimal example:</para> + <programlisting> + function foo ($params) { + ... + } + + $s=new xmlrpc_server( array("examples.myFunc" => + array("function" => "foo"))); + </programlisting> + <para> + This performs everything you need to do with a server. The single + argument is an associative array from method names to function + names. The request is parsed and despatched to the relevant function, + which is reponsible for returning a + <classname>xmlrpcresp</classname> + object, which gets + serialized back to the caller. See server.php in this distribution for + examples of how to do this. + </para> + <para>Here is a more detailed look at what the handler function + <function>foo</function> may do:</para> + <programlisting> + + function foo ($params) { + global $xmlrpcerruser; // import user errcode value + + // $params is an Array of xmlrpcval objects + + if ($err) { + // this is an error condition + return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1 + "There's a problem, Captain"); + } else { + // this is a successful value being returned + return new xmlrpcresp(new xmlrpcval("All's fine!", "string")); + } + } + </programlisting> + <sect2> + <title>The dispatch map</title> + <para>The first argument to the + <function>xmlrpc_server</function> constructor is an array, + called the <emphasis>dispatch map</emphasis>. In this array is the + information the server needs to service the XML-RPC methods + you define.</para> + <para> + The dispatch map takes the form of an associative array of + associative arrays: the outer array has one entry for each + method, the key being the method name. The corresponding value + is another associative array, which can have the following members: + </para> + <itemizedlist> + <listitem> + <para><function>function</function> - this entry is + mandatory. It must be a name of a function in the + global scope which services the XML-RPC method.</para> + </listitem> + <listitem> + <para><function>signature</function> - this entry is an + array containg the possible signatures (see <xref + linkend="signatures">) for the method. If + this entry is present then the server will check that the + correct number and type of parameters have been sent for + this method before dispatching it. + </para> + </listitem> + <listitem> + <para> + <function>docstring</function> - this entry is a string + containing documentation for the method. The + documentation may contain HTML markup. + </para> + </listitem> + </itemizedlist> + <para>Look at the <filename>server.php</filename> example in the + distribution to see what a dispatch map looks like.</para> + </sect2> + <sect2 id="signatures" xreflabel="Signatures"><title>Method signatures</title> + <para>A signature is a description of a method's return type and + its parameter types. A method may have more than one + signature.</para> + <para>Within a server's dispatch map, each method has an array + of possible signatures. Each signature is an array of + types. The first entry is the return type. For instance, the + method <programlisting> +string examples.getStateName(int) +</programlisting> has the signature +<programlisting> +array($xmlrpcString, $xmlrpcInt) +</programlisting> and, assuming that it the only possible signature for + the method, might be used like this in server creation: +<programlisting> +$findstate_sig=array(array($xmlrpcString, $xmlrpcInt)); + +$findstate_doc='When passed an integer between 1 and 51 returns the +name of a US state, where the integer is the index of that state name +in an alphabetic order.'; + +$s=new xmlrpc_server( array( "examples.getStateName" => + array("function" => "findstate", + "signature" => $findstate_sig, + "docstring" => $findstate_doc))); +</programlisting> + + </para> + <para>For convenience the strings representing the XML-RPC types + have been encoded as global variables:<programlisting> +$xmlrpcI4="i4"; +$xmlrpcInt="int"; +$xmlrpcBoolean="boolean"; +$xmlrpcDouble="double"; +$xmlrpcString="string"; +$xmlrpcDateTime="dateTime.iso8601"; +$xmlrpcBase64="base64"; +$xmlrpcArray="array"; +$xmlrpcStruct="struct"; +</programlisting></para> + </sect2> + <sect2> + <title>Delaying the server response</title> + <para>You may want to construct the server, but for some reason + not fulfill the request immediately (security verification, for + instance). If you pass the constructor a second argument of + <literal>0</literal> this will have the desired effect. You + can then use the <function>service()</function> method of the + server class to service the request. For example:</para> + <programlisting> +$s=new xmlrpc_server($myDispMap, 0); + +// ... some code that does other stuff here + +$s->service(); +</programlisting> + </sect2> + <sect2> + <title>Fault reporting</title> + <para>Fault codes for your servers should start at the + value indicated by + the global <literal>$xmlrpcerruser</literal> + 1.</para> + <para>Standard errors returned by the server include:</para> + <variablelist> + <varlistentry> + <term><literal>1</literal> <phrase>Unknown method</phrase></term> + <listitem> + <para>Returned if the server was asked to dispatch a + method it didn't know about</para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>2</literal> <phrase>Invalid return payload</phrase></term> + <listitem> + <para>This error is actually generated by the client, not + server, code, but signifies that a server returned + something it couldn't understand.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>3</literal> <phrase>Incorrect parameters</phrase></term> + <listitem> + <para>This error is generated when the server has signature(s) + defined for a method, and the parameters passed by the + client do not match any of signatures.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>4</literal> <phrase>Can't introspect: method unknown</phrase></term> + <listitem> + <para>This error is generated by the builtin + <function>system.*</function> methods when any kind of + introspection is attempted on a method undefined by the + server.</para> + </listitem> + </varlistentry> +<varlistentry> + <term><literal>5</literal> <phrase>Didn't receive 200 OK from remote server</phrase></term> + <listitem> + <para>This error is generated by the client when a remote server + doesn't return HTTP/1.1 200 OK in response to a + request. A more detailed error report is added onto the + end of the phrase above.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>100-</literal> <phrase>XML parse errors</phrase></term> + <listitem> + <para>Returns 100 plus the XML parser error code for the + fault that occurred. The + <function>faultString</function> returned explains where + the parse error was in the incoming XML stream.</para> + </listitem> + </varlistentry> + </variablelist> + </sect2> + </sect1> + </chapter> + + <chapter id="helpers"> + <title>Helper functions</title> + <para>XML-RPC for PHP contains some helper functions which you can + use to make processing of XML-RPC requests easier.</para> + <sect1> + <title>Date functions</title> + <para>The XML-RPC specification has this to say on dates:</para> + <blockquote> + <para>Don't assume a timezone. It should be specified by the server in its + documentation what assumptions it makes about timezones. </para> + </blockquote> + <para>Unfortunately, this means that date processing isn't + straightforward. Although XML-RPC uses ISO 8601 format dates, it + doesn't use the timezone specifier.</para> + <para>We strongly recommend that in every case where you pass + dates in XML-RPC calls, you use UTC (GMT) as your timezone. Most computer + languages include routines for handling GMT times natively, and + you won't have to translate between timezones.</para> + <para>For more information about dates, see <ulink + url="http://www.uic.edu/year2000/datefmt.html">ISO 8601: The Right Format for Dates</ulink>, which has a handy link to a PDF of the ISO 8601 specification. Note that XML-RPC uses exactly one of the available representations: CCYYMMDDTHH:MM:SS.</para> + + <sect2 id="iso8601encode" xreflabel="iso8601_encode()"> + <title>iso8601_encode</title> + <funcsynopsis> + <funcprototype> + <funcdef>$isoString=iso8601_encode</funcdef> + <paramdef><parameter>$time_t</parameter><parameter>$utc=0</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Returns an ISO 8601 formatted date generated from the + UNIX timestamp <parameter>$time_t</parameter>, as returned by + the PHP function <function>time()</function>. </para> + <para>The argument <parameter>$utc</parameter> can be omitted, + in which case it defaults to <literal>0</literal>. If it is + set to <literal>1</literal>, then the function corrects the + time passed in for UTC. Example: if you're in the GMT-6:00 + timezone and set <parameter>$utc</parameter>, you will receive + a date representation six hours ahead of your local + time.</para> + <para>The included demo program <filename>vardemo.php</filename> + includes a demonstration of this function.</para> + </sect2> + <sect2 id="iso8601decode" xreflabel="iso8601_decode()"> + <title>iso8601_decode</title> + <funcsynopsis> + <funcprototype> + <funcdef>$time_t=iso8601_decode</funcdef> + <paramdef><parameter>$isoString</parameter><parameter>$utc=0</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Returns a UNIX timestamp from an ISO 8601 encoded time and + date string passed in. If <parameter>$utc</parameter> is + <literal>1</literal> then <parameter>$isoString</parameter> is + assumed to be in the UTC timezone, and thus the + <parameter>$time_t</parameter> result is also UTC: otherwise, + the timezone is assumed to be your local timezone and you receive a local timestamp.</para> + </sect2> + </sect1> + + <sect1 id="arrayuse"> + <title>Easy use with PHP arrays</title> + <para>Dan Libby was kind enough to contribute two helper functions + that make it easier to translate to and from PHP arrays. This + makes it easier to deal with complex structures. At the moment + support is limited to <type>int</type>, <type>double</type>, + <type>string</type>, <type>array</type> and <type>struct</type> + datatypes; note also that all PHP arrays are encoded as structs + due to PHP not being able to tell the difference between a hash + and a linear array.</para> + <para>These functions reside in <filename>xmlrpc.inc</filename>.</para> + <sect2 id="xmlrpcdecode"> + <title>xmlrpc_decode</title> + <funcsynopsis> + <funcprototype> + <funcdef>$arr=xmlrpc_decode</funcdef> + <paramdef><parameter>$xmlrpc_val</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Returns a PHP array stuffed with the values found in the + <type>xmlrpcval</type> <parameter>$xmlrpc_val</parameter>, + translated into native PHP types. + </para> + </sect2> + <sect2 id="xmlrpcencode"> + <title>xmlrpc_encode</title> + <funcsynopsis> + <funcprototype> + <funcdef>$xmlrpc_val=xmlrpc_encode</funcdef> + <paramdef><parameter>$phpval</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para> + Returns an <type>xmlrpcval</type> populated with the PHP + values in <parameter>$phpval</parameter>. Works recursively on + arrays and structs. Note that there's no support for non-base + types like base-64 values or date-times. + </para> + </sect2> + </sect1> + + <sect1 id="debugging"> + <title>Debugging aids</title> + <sect2> + <title>xmlrpc_debugmsg</title> + <funcsynopsis> + <funcprototype> + <funcdef>xmlrpc_debugmsg</funcdef> + <paramdef><parameter>$debugstring</parameter></paramdef> + </funcprototype> + </funcsynopsis> + <para>Sends the contents of <parameter>$debugstring</parameter> + in XML comments in the server return payload. If a PHP client + has debugging turned on, the user will be able to see server + debug information.</para> + <para>Use this function in your methods so you can pass back + diagnostic information. It is only available from + <filename>xmlrpcs.inc</filename>.</para> + </sect2> + </sect1> + + </chapter> + + <chapter id="reserved" xreflabel="Reserved methods"> + <title>Reserved methods</title> + <para>In order to extend the functionality offered by XML-RPC + servers without impacting on the protocol, I've included + experimental support in this release for reserved methods.</para> + <para>All methods starting with <function>system.</function> are + considered reserved by the server. PHP for XML-RPC itself provides + three special methods, detailed in this chapter.</para> + <sect1> + <title>system.listMethods</title> + <para>This method may be used to enumerate the methods implemented + by the XML-RPC server.</para> + <para>The <function>system.listMethods</function> method requires + no parameters. It returns an array of strings, each of which is + the name of a method implemented by the server.</para> + </sect1> + <sect1 id="sysmethodsig"> + <title>system.methodSignature</title> + <para>This method takes one parameter, the name of a method + implemented by the XML-RPC server.</para> + <para>It returns an array of possible signatures for this + method. A signature is an array of types. The first of these + types is the return type of the method, the rest are parameters.</para> + <para>Multiple signatures (ie. overloading) are permitted: this is + the reason that an array of signatures are returned by this + method.</para> + <para>Signatures themselves are restricted to the top level + parameters expected by a method. For instance if a method + expects one array of structs as a parameter, and it returns a + string, its signature is simply "string, array". If it expects + three integers, its signature is "string, int, int, + int".</para> + <para> + If no signature is defined for the method, a none-array value is + returned. Therefore this is the way to test for a non-signature, + if <parameter>$resp</parameter> below is the response object + from a method call to <function>system.methodSignature</function>: + </para> + + <programlisting> +$v=$resp->value(); +if ($v->kindOf()!="array") { + // then the method did not have a signature defined +} + </programlisting> + <para> + See the <filename>introspect.php</filename> demo included in + this distribution for an example of using this method. + </para> + </sect1> + <sect1 id="sysmethhelp"> + <title>system.methodHelp</title> + <para>This method takes one parameter, the name of a method + implemented by the XML-RPC server.</para> + <para> + It returns a documentation string describing the use of that + method. If no such string is available, an empty string is returned. + </para> + <para> + The documentation string may contain HTML markup. + </para> + </sect1> + </chapter> + + + <chapter id="examples" xreflabel="Examples"> + <title>Examples</title> + <para>The best examples are to be found in the sample files + included with the distribution. Some are included here.</para> + <sect1 id="statename"> + <title>XML-RPC client: state name query</title> + <para>Code to get the corresponding + state name from a number (1-50) from Dave Winer's server</para> + <programlisting> + $f=new xmlrpcmsg('examples.getStateName', + array(new xmlrpcval($HTTP_POST_VARS["stateno"], "int"))); + $c=new xmlrpc_client("/RPC2", "betty.userland.com", 80); + $r=$c->send($f); + $v=$r->value(); + if (!$r->faultCode()) { + print "State number ". $HTTP_POST_VARS["stateno"] . " is " . + $v->scalarval() . "<BR>"; + print "<HR>I got this value back<BR><PRE>" . + htmlentities($r->serialize()). "</PRE><HR>\n"; + } else { + print "Fault: "; + print "Code: " . $r->faultCode() . + " Reason '" .$r->faultString()."'<BR>"; + } + </programlisting> + </sect1> + </chapter> +</book> +<!-- Keep this comment at the end of the file +Local variables: +mode: sgml +sgml-omittag:nil +sgml-shorttag:t +sgml-minimize-attributes:nil +sgml-always-quote-attributes:t +sgml-indent-step:2 +sgml-indent-data:t +sgml-parent-document:nil +sgml-exposed-tags:nil +sgml-local-catalogs:nil +sgml-local-ecat-files:nil +sgml-namecase-general:t +sgml-general-insert-case:lower +End: +--> diff --git a/modules/xmlrpc/doc/xmlrpcmsg.html b/modules/xmlrpc/doc/xmlrpcmsg.html new file mode 100644 index 00000000..958ff3a2 --- /dev/null +++ b/modules/xmlrpc/doc/xmlrpcmsg.html @@ -0,0 +1,507 @@ +<HTML +><HEAD +><TITLE +>xmlrpcmsg</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="UP" +TITLE="Class documentation" +HREF="apidocs.html"><LINK +REL="PREVIOUS" +TITLE="Class documentation" +HREF="apidocs.html"><LINK +REL="NEXT" +TITLE="xmlrpcresp" +HREF="xmlrpcresp.html"></HEAD +><BODY +CLASS="SECT1" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="apidocs.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +>Chapter 5. Class documentation</TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="xmlrpcresp.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="XMLRPCMSG" +></A +>xmlrpcmsg</H1 +><P +>This class provides a representation for a request to an + XML-RPC server. A client sends an + <TT +CLASS="CLASSNAME" +>xmlrpcmsg</TT +> to a server, and receives back + an <TT +CLASS="CLASSNAME" +>xmlrpcresp</TT +> (see <A +HREF="apidocs.html#XMLRPC-CLIENT-SEND" +>xmlrpc_client->send</A +>).</P +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN289" +></A +>Creation</H2 +><P +>The constructor takes the following form:</P +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN292" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$msg=new xmlrpcmsg</CODE +>($methodName, $parameterArray);</CODE +></P +><P +></P +></DIV +><P +>Where <TT +CLASS="PARAMETER" +><I +>$methodName</I +></TT +> is a string + indicating the name of the method you wish to invoke, and + <TT +CLASS="PARAMETER" +><I +>$parameterArray</I +></TT +> is a simple + <TT +CLASS="CLASSNAME" +>Array</TT +> of + <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> objects. Here's an example + message to the <SPAN +CLASS="emphasis" +><I +CLASS="EMPHASIS" +>US state name</I +></SPAN +> server: + </P +><PRE +CLASS="PROGRAMLISTING" +>$msg=new xmlrpcmsg("examples.getStateName", + array(new xmlrpcval(23, "int"))); + </PRE +><P +> This example requests the name of state number 23. For more + information on <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> objects, see + <A +HREF="xmlrpcval.html" +>xmlrpcval</A +>. + </P +></DIV +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN309" +></A +>Methods</H2 +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN311" +></A +>serialize</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN313" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$outString=$msg->serialize</CODE +>();</CODE +></P +><P +></P +></DIV +><P +>Returns the an XML string representing the XML-RPC + message.</P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN318" +></A +>addParam</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN320" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$msg->addParam</CODE +>($xmlrpcVal);</CODE +></P +><P +></P +></DIV +><P +>Adds the <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> + <TT +CLASS="PARAMETER" +><I +>$xmlrpcVal</I +></TT +> to the parameter list for + this method call.</P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN328" +></A +>getParam</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN330" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$xmlrpcVal=$msg->getParam</CODE +>($n);</CODE +></P +><P +></P +></DIV +><P +>Gets the <TT +CLASS="PARAMETER" +><I +>$n</I +></TT +>th parameter in the + message. Use this method in server implementations. Returns + the <TT +CLASS="LITERAL" +>undef</TT +> value if no such parameter + exists.</P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN338" +></A +>getNumParams</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN340" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$n=$msg->getNumParams</CODE +>();</CODE +></P +><P +></P +></DIV +><P +> Returns the number of parameters attached to this message. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN345" +></A +>method</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN347" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$methName=$msg->method</CODE +>();</CODE +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$msg->method</CODE +>($methName);</CODE +></P +><P +></P +></DIV +><P +>Gets or sets the method contained in the XML-RPC message.</P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN356" +></A +>parseResponse</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN358" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$response=$msg->parseResponse</CODE +>($xmlString);</CODE +></P +><P +></P +></DIV +><P +>Given an incoming XML-RPC server response contained in + the string + <TT +CLASS="PARAMETER" +><I +>$xmlString</I +></TT +>, this method constructs + an <TT +CLASS="CLASSNAME" +>xmlrpcresp</TT +> response object and + returns it, setting error codes as appropriate (see <A +HREF="apidocs.html#XMLRPC-CLIENT-SEND" +>xmlrpc_client->send</A +>). + </P +><P +> This method processes any HTTP/MIME headers it finds. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN368" +></A +>parseResponseFile</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN370" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$response=$msg->parseResponseFile</CODE +>($fileHandle);</CODE +></P +><P +></P +></DIV +><P +>Given an incoming XML-RPC server response on the file handle + <TT +CLASS="PARAMETER" +><I +>$fileHandle</I +></TT +>, this method reads the + data and passes it to <TT +CLASS="FUNCTION" +>parseResponse</TT +> + </P +><P +> This method is useful to construct responses from + pre-prepared files (see files <TT +CLASS="LITERAL" +>demo1.txt, demo2.txt, + demo3.txt</TT +> in this distribution). It processes + any HTTP headers it finds. + </P +></DIV +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="apidocs.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="xmlrpcresp.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Class documentation</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="apidocs.html" +ACCESSKEY="U" +>Up</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>xmlrpcresp</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/xmlrpcresp.html b/modules/xmlrpc/doc/xmlrpcresp.html new file mode 100644 index 00000000..d48216e3 --- /dev/null +++ b/modules/xmlrpc/doc/xmlrpcresp.html @@ -0,0 +1,374 @@ +<HTML +><HEAD +><TITLE +>xmlrpcresp</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="UP" +TITLE="Class documentation" +HREF="apidocs.html"><LINK +REL="PREVIOUS" +TITLE="xmlrpcmsg" +HREF="xmlrpcmsg.html"><LINK +REL="NEXT" +TITLE="xmlrpcval" +HREF="xmlrpcval.html"></HEAD +><BODY +CLASS="SECT1" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="xmlrpcmsg.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +>Chapter 5. Class documentation</TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="xmlrpcval.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="XMLRPCRESP" +></A +>xmlrpcresp</H1 +><P +>This class is used to contain responses to XML-RPC + requests. A server method handler will construct an + <TT +CLASS="CLASSNAME" +>xmlrpcresp</TT +> and pass it as a return value. + This same value will be returned by the result of an invocation of + the <TT +CLASS="FUNCTION" +>send</TT +> method of the + <TT +CLASS="CLASSNAME" +>xmlrpc_client</TT +> class.</P +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN386" +></A +>Creation</H2 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN388" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$resp=new xmlrpcresp</CODE +>($xmlrpcval);</CODE +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$resp=new xmlrpcresp</CODE +>(0, $errcode, $errstring);</CODE +></P +><P +></P +></DIV +><P +>The first instance is used when execution has happened + without difficulty: <TT +CLASS="PARAMETER" +><I +>$xmlrpcval</I +></TT +> is an + <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> value with the result of the + method execution contained in it.</P +><P +> The second type of constructor is used in case of + failure. <TT +CLASS="PARAMETER" +><I +>$errcode</I +></TT +> and + <TT +CLASS="PARAMETER" +><I +>$errstring</I +></TT +> are used to provide + indication of what has gone wrong. See <A +HREF="xmlrpc-server.html" +>xmlrpc_server</A +> for more information on passing + error codes. + </P +></DIV +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN408" +></A +>Methods</H2 +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN410" +></A +>faultCode</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN412" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$fn=$resp->faultCode</CODE +>();</CODE +></P +><P +></P +></DIV +><P +>Returns the integer fault code return from the XML-RPC + response <TT +CLASS="PARAMETER" +><I +>$resp</I +></TT +>. + A zero value indicates success, any other value + indicates a failure response.</P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN418" +></A +>faultString</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN420" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$fs=$resp->faultString</CODE +>();</CODE +></P +><P +></P +></DIV +><P +> Returns the human readable explanation of the fault + indicated by <TT +CLASS="FUNCTION" +>$resp->faultCode</TT +>. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN426" +></A +>value</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN428" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$xmlrpcVal=$resp->value</CODE +>();</CODE +></P +><P +></P +></DIV +><P +> Returns an <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> object + containing the return value sent by the server. If the + response's <TT +CLASS="FUNCTION" +>faultCode</TT +> is non-zero then + the value returned by this method should not be used (it may + not even be an object). + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN435" +></A +>serialize</H3 +><P +></P +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN438" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$outString=$resp->serialize</CODE +>();</CODE +></P +><P +></P +></DIV +><P +>Returns an XML string representation of the response.</P +></DIV +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="xmlrpcmsg.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="xmlrpcval.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>xmlrpcmsg</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="apidocs.html" +ACCESSKEY="U" +>Up</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>xmlrpcval</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/doc/xmlrpcval.html b/modules/xmlrpc/doc/xmlrpcval.html new file mode 100644 index 00000000..68489699 --- /dev/null +++ b/modules/xmlrpc/doc/xmlrpcval.html @@ -0,0 +1,933 @@ +<HTML +><HEAD +><TITLE +>xmlrpcval</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.77+"><LINK +REV="MADE" +HREF="edd@usefulinc.com"><LINK +REL="HOME" +TITLE="XML-RPC for PHP" +HREF="index.html"><LINK +REL="UP" +TITLE="Class documentation" +HREF="apidocs.html"><LINK +REL="PREVIOUS" +TITLE="xmlrpcresp" +HREF="xmlrpcresp.html"><LINK +REL="NEXT" +TITLE="xmlrpc_server" +HREF="xmlrpc-server.html"></HEAD +><BODY +CLASS="SECT1" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>XML-RPC for PHP: version 1.1</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="xmlrpcresp.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +>Chapter 5. Class documentation</TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="xmlrpc-server.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="SECT1" +><H1 +CLASS="SECT1" +><A +NAME="XMLRPCVAL" +></A +>xmlrpcval</H1 +><P +>This is where a lot of the hard work gets done. This class + enables the creation and encapsulation of values for XML-RPC. + </P +><P +> Ensure you've read the XML-RPC spec at <A +HREF="http://www.xmlrpc.com/stories/storyReader$7" +TARGET="_top" +>http://www.xmlrpc.com/stories/storyReader$7</A +> + before reading on as it will make things clearer. + </P +><P +>The <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> class can store + arbitrarily complicated values using the following types: + <TT +CLASS="LITERAL" +>i4 int boolean string double dateTime.iso8601 base64 + array struct</TT +>. You should refer to the <A +HREF="http://www.xmlrpc.com/stories/storyReader$7" +TARGET="_top" +>spec</A +> + for more information on what each of these types mean. + </P +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="AEN452" +></A +>Notes on types</H2 +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN454" +></A +>int</H3 +><P +>The type <TT +CLASS="CLASSNAME" +>i4</TT +> is accepted as a + synonym for <TT +CLASS="CLASSNAME" +>int</TT +>. The value parsing + code will always convert <TT +CLASS="CLASSNAME" +>i4</TT +> to + <TT +CLASS="CLASSNAME" +>int</TT +>: <TT +CLASS="CLASSNAME" +>int</TT +> + is regarded by this implementation as the canonical name for + this type.</P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN462" +></A +>base64</H3 +><P +>Base 64 encoding is performed transparently to the + caller when using this type. Therefore you ought to + consider it as a "binary" data type, for use when you want + to pass none 7-bit clean data. Decoding is also + transparent. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN465" +></A +>boolean</H3 +><P +>The values <TT +CLASS="LITERAL" +>true</TT +> and + <TT +CLASS="LITERAL" +>1</TT +> map to <TT +CLASS="LITERAL" +>true</TT +>. All + other values (including the empty string) + are converted to <TT +CLASS="LITERAL" +>false</TT +>. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN472" +></A +>string</H3 +><P +> The characters <TT +CLASS="LITERAL" +>< > "</TT +> and + <TT +CLASS="LITERAL" +>&</TT +> are converted to their entity + equivalents <TT +CLASS="LITERAL" +>&lt; &gt; + &quot;</TT +> and <TT +CLASS="LITERAL" +>&amp;</TT +> + for transport through XML-RPC. The current XML-RPC spec + recommends only encoding <TT +CLASS="LITERAL" +>< &</TT +> but + this implementation goes further, for reasons explained by + <A +HREF="http://www.w3.org/TR/REC-xml#syntax" +TARGET="_top" +>the XML 1.0 + recommendation</A +>. + </P +><P +>TODO: <TT +CLASS="LITERAL" +> &apos;</TT +> entity not + yet supported</P +></DIV +></DIV +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="XMLRPCVAL-CREATION" +></A +>Creation</H2 +><P +>The constructor is the normal way to create an + <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +>. The constructor can take + these forms: + </P +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN487" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$myVal=new xmlrpcval</CODE +>();</CODE +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$myVal=new xmlrpcval</CODE +>($stringVal);</CODE +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$myVal=new xmlrpcval</CODE +>($scalarVal, "int" | "boolean" | "string" | "double" | "dateTime.iso8601" | "base64");</CODE +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$myVal=new xmlrpcval</CODE +>($arrayVal, "array" | "struct");</CODE +></P +><P +></P +></DIV +><P +>The first constructor creates an empty value, which must + be altered using the methods <TT +CLASS="FUNCTION" +>addScalar</TT +>, + <TT +CLASS="FUNCTION" +>addArray</TT +> or + <TT +CLASS="FUNCTION" +>addStruct</TT +> before it can be used. + </P +><P +> The second constructor creates a simple string value. + </P +><P +> The third constructor is used to create a scalar value. The + second parameter must be a name of an XML-RPC type. Examples: + </P +><PRE +CLASS="PROGRAMLISTING" +> $myInt=new xmlrpcvalue(1267, "int"); + $myString=new xmlrpcvalue("Hello, World!", "string"); + $myBool=new xmlrpcvalue(1, "boolean"); + </PRE +><P +> The fourth constructor form can be used to compose complex + XML-RPC values. The first argument is either a simple array in + the case of an XML-RPC <TT +CLASS="CLASSNAME" +>array</TT +> or + an associative array in the case of a + <TT +CLASS="CLASSNAME" +>struct</TT +>. The elements of the array + <SPAN +CLASS="emphasis" +><I +CLASS="EMPHASIS" +>must be <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> objects + themselves</I +></SPAN +>. + Examples:</P +><PRE +CLASS="PROGRAMLISTING" +> $myArray=new xmlrpcval(array( + new xmlrpcval("Tom"), new xmlrpcval("Dick"), + new xmlrpcval("Harry")), "array"); + + $myStruct=new xmlrpcval(array( + "name" => new xmlrpcval("Tom"), + "age" => new xmlrpcval(34, "int"), + "geek" => new xmlrpcval(1, "boolean")), "struct"); + </PRE +><P +>See the file <TT +CLASS="LITERAL" +>vardemo.php</TT +> in this + distribution for more examples.</P +></DIV +><DIV +CLASS="SECT2" +><H2 +CLASS="SECT2" +><A +NAME="XMLRPCVAL-METHODS" +></A +>Methods</H2 +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN524" +></A +>addScalar</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN526" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$ok=$val->addScalar</CODE +>($stringVal);</CODE +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$ok=$val->addScalar</CODE +>($scalarVal, "int" | "boolean" | "string" | "double" | "dateTime.iso8601" | "base64");</CODE +></P +><P +></P +></DIV +><P +> If <TT +CLASS="PARAMETER" +><I +>$val</I +></TT +> is an empty + <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> this method makes it a + scalar value, and sets that value. If + <TT +CLASS="PARAMETER" +><I +>$val</I +></TT +> is already a scalar value, then + no more scalars can be added and <TT +CLASS="LITERAL" +>0</TT +> is + returned. If all went OK, <TT +CLASS="LITERAL" +>1</TT +> is returned. + </P +><P +>There is a special case if <TT +CLASS="PARAMETER" +><I +>$val</I +></TT +> + is an <TT +CLASS="CLASSNAME" +>array</TT +>: the scalar value passed + is appended to the array.</P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN546" +></A +>addArray</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN548" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$ok=$val->addArray</CODE +>($arrayVal);</CODE +></P +><P +></P +></DIV +><P +>Turns an empty <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> into an + <TT +CLASS="CLASSNAME" +>array</TT +> with contents as specified by + <TT +CLASS="PARAMETER" +><I +>$arrayVal</I +></TT +>. See the fourth + constructor form for more information.</P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN557" +></A +>addStruct</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN559" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$ok=$val->addArray</CODE +>($assocArrayVal);</CODE +></P +><P +></P +></DIV +><P +>Turns an empty <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> into a + <TT +CLASS="CLASSNAME" +>struct</TT +> with contents as specified by + <TT +CLASS="PARAMETER" +><I +>$assocArrayVal</I +></TT +>. See the fourth + constructor form for more information.</P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN568" +></A +>kindOf</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN570" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$kind=$val->kindOf</CODE +>();</CODE +></P +><P +></P +></DIV +><P +> Returns a string containing "struct", "array" or "scalar" + describing the base type of the value. If it returns + "undef" it means that the value hasn't been initialised. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN575" +></A +>serialize</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN577" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$outString=$val->serialize</CODE +>();</CODE +></P +><P +></P +></DIV +><P +> Returns a string containing the XML-RPC representation of + this value. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN582" +></A +>scalarval</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN584" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$scalarVal=$val->scalarval</CODE +>();</CODE +></P +><P +></P +></DIV +><P +> If <TT +CLASS="FUNCTION" +>$val->kindOf()=="scalar"</TT +>, this + method returns the actual PHP-language value of the scalar + (base 64 decoding is automatically handled here). + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN590" +></A +>scalartyp</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN592" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$typeName=$val->scalartyp</CODE +>();</CODE +></P +><P +></P +></DIV +><P +> If <TT +CLASS="FUNCTION" +>$val->kindOf()=="scalar"</TT +>, this + method returns a string denoting the type of the scalar. + As mentioned before, + <TT +CLASS="LITERAL" +>i4</TT +> is always coerced to <TT +CLASS="LITERAL" +>int</TT +>. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN600" +></A +>arraymem</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN602" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$xmlrpcVal=$val->arraymem</CODE +>($n);</CODE +></P +><P +></P +></DIV +><P +> Returns the <TT +CLASS="PARAMETER" +><I +>$n</I +></TT +>th element in the array + represented by the value <TT +CLASS="PARAMETER" +><I +>$val</I +></TT +>. The + value returned is an <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> object. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN611" +></A +>arraysize</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN613" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$len=$val->arraysize</CODE +>();</CODE +></P +><P +></P +></DIV +><P +>If <TT +CLASS="PARAMETER" +><I +>$val</I +></TT +> is an + <TT +CLASS="CLASSNAME" +>array</TT +>, returns the number of elements + in that array. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN620" +></A +>structmem</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN622" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$xmlrpcVal=$val->structmem</CODE +>($memberName);</CODE +></P +><P +></P +></DIV +><P +> Returns the element called + <TT +CLASS="PARAMETER" +><I +>$memberName</I +></TT +> from the struct + represented by the value <TT +CLASS="PARAMETER" +><I +>$val</I +></TT +>. The + value returned is an <TT +CLASS="CLASSNAME" +>xmlrpcval</TT +> object. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="AEN631" +></A +>structeach</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN633" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>list($key,$value)=$val->structeach</CODE +>();</CODE +></P +><P +></P +></DIV +><P +> Returns the next (key,value) pair from the struct, when + <TT +CLASS="PARAMETER" +><I +>$val</I +></TT +> is a struct. See also + <A +HREF="xmlrpcval.html#STRUCTRESET" +>structreset()</A +>. + </P +></DIV +><DIV +CLASS="SECT3" +><H3 +CLASS="SECT3" +><A +NAME="STRUCTRESET" +></A +>structreset</H3 +><DIV +CLASS="FUNCSYNOPSIS" +><A +NAME="AEN642" +></A +><P +></P +><P +><CODE +><CODE +CLASS="FUNCDEF" +>$val->structreset</CODE +>();</CODE +></P +><P +></P +></DIV +><P +> Resets the internal pointer for + <TT +CLASS="FUNCTION" +>structeach()</TT +> to the beginning of the + struct, where <TT +CLASS="PARAMETER" +><I +>$val</I +></TT +> is a struct. + </P +></DIV +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="xmlrpcresp.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="xmlrpc-server.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>xmlrpcresp</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="apidocs.html" +ACCESSKEY="U" +>Up</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>xmlrpc_server</TD +></TR +></TABLE +></DIV +></BODY +></HTML +>
\ No newline at end of file diff --git a/modules/xmlrpc/xmlrpc.inc b/modules/xmlrpc/xmlrpc.inc new file mode 100755 index 00000000..5b4c0150 --- /dev/null +++ b/modules/xmlrpc/xmlrpc.inc @@ -0,0 +1,1476 @@ +<?php // -*-c++-*- +// by Edd Dumbill (C) 1999-2002 +// <edd@usefulinc.com> +// $Id: xmlrpc.inc,v 1.20 2003/01/10 22:01:56 dilinger Exp $ + + +// Copyright (c) 1999,2000,2002 Edd Dumbill. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * 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 (!function_exists('xml_parser_create')) + { + // Win 32 fix. From: 'Leo West' <lwest@imaginet.fr> + if($WINDIR) + { + dl('php3_xml.dll'); + } + else + { + dl('xml.so'); + } + } + + $xmlrpcI4='i4'; + $xmlrpcInt='int'; + $xmlrpcBoolean='boolean'; + $xmlrpcDouble='double'; + $xmlrpcString='string'; + $xmlrpcDateTime='dateTime.iso8601'; + $xmlrpcBase64='base64'; + $xmlrpcArray='array'; + $xmlrpcStruct='struct'; + + $xmlrpcTypes=array( + $xmlrpcI4 => 1, + $xmlrpcInt => 1, + $xmlrpcBoolean => 1, + $xmlrpcString => 1, + $xmlrpcDouble => 1, + $xmlrpcDateTime => 1, + $xmlrpcBase64 => 1, + $xmlrpcArray => 2, + $xmlrpcStruct => 3 + ); + + $xmlEntities=array( + 'amp' => '&', + 'quot' => '"', + 'lt' => '<', + 'gt' => '>', + 'apos' => "'" + ); + + $xmlrpcerr['unknown_method']=1; + $xmlrpcstr['unknown_method']='Unknown method'; + $xmlrpcerr['invalid_return']=2; + $xmlrpcstr['invalid_return']='Invalid return payload: enabling debugging to examine incoming payload'; + $xmlrpcerr['incorrect_params']=3; + $xmlrpcstr['incorrect_params']='Incorrect parameters passed to method'; + $xmlrpcerr['introspect_unknown']=4; + $xmlrpcstr['introspect_unknown']="Can't introspect: method unknown"; + $xmlrpcerr['http_error']=5; + $xmlrpcstr['http_error']="Didn't receive 200 OK from remote server."; + $xmlrpcerr['no_data']=6; + $xmlrpcstr['no_data']='No data received from server.'; + $xmlrpcerr['no_ssl']=7; + $xmlrpcstr['no_ssl']='No SSL support compiled in.'; + $xmlrpcerr['curl_fail']=8; + $xmlrpcstr['curl_fail']='CURL error'; + + + $xmlrpcerr['multicall_notstruct'] = 9; + $xmlrpcstr['multicall_notstruct'] = 'system.multicall expected struct'; + $xmlrpcerr['multicall_nomethod'] = 10; + $xmlrpcstr['multicall_nomethod'] = 'missing methodName'; + $xmlrpcerr['multicall_notstring'] = 11; + $xmlrpcstr['multicall_notstring'] = 'methodName is not a string'; + $xmlrpcerr['multicall_recursion'] = 12; + $xmlrpcstr['multicall_recursion'] = 'recursive system.multicall forbidden'; + $xmlrpcerr['multicall_noparams'] = 13; + $xmlrpcstr['multicall_noparams'] = 'missing params'; + $xmlrpcerr['multicall_notarray'] = 14; + $xmlrpcstr['multicall_notarray'] = 'params is not an array'; + + $xmlrpc_defencoding='UTF-8'; + + $xmlrpcName='XML-RPC for PHP'; + $xmlrpcVersion='1.0.99'; + + // let user errors start at 800 + $xmlrpcerruser=800; + // let XML parse errors start at 100 + $xmlrpcerrxml=100; + + // formulate backslashes for escaping regexp + $xmlrpc_backslash=chr(92).chr(92); + + // used to store state during parsing + // quick explanation of components: + // st - used to build up a string for evaluation + // ac - used to accumulate values + // qt - used to decide if quotes are needed for evaluation + // cm - used to denote struct or array (comma needed) + // isf - used to indicate a fault + // lv - used to indicate "looking for a value": implements + // the logic to allow values with no types to be strings + // params - used to store parameters in method calls + // method - used to store method name + + $_xh=array(); + + if (!function_exists('xmlrpc_entity_decode')) { + + function xmlrpc_entity_decode($string) + { + $top=split('&', $string); + $op=''; + $i=0; + while($i<sizeof($top)) + { + if (ereg("^([#a-zA-Z0-9]+);", $top[$i], $regs)) + { + $op.=ereg_replace("^[#a-zA-Z0-9]+;", + xmlrpc_lookup_entity($regs[1]), + $top[$i]); + } + else + { + if ($i==0) + { + $op=$top[$i]; + } + else + { + $op.='&' . $top[$i]; + } + } + $i++; + } + return $op; + } + + } // if xmlrpc_entity_decode doesn't exist + + function xmlrpc_lookup_entity($ent) + { + global $xmlEntities; + + if (isset($xmlEntities[strtolower($ent)])) + { + return $xmlEntities[strtolower($ent)]; + } + if (ereg("^#([0-9]+)$", $ent, $regs)) + { + return chr($regs[1]); + } + return '?'; + } + + function xmlrpc_se($parser, $name, $attrs) + { + global $_xh, $xmlrpcDateTime, $xmlrpcString; + + switch($name) + { + case 'STRUCT': + case 'ARRAY': + $_xh[$parser]['st'].='array('; + $_xh[$parser]['cm']++; + // this last line turns quoting off + // this means if we get an empty array we'll + // simply get a bit of whitespace in the eval + $_xh[$parser]['qt']=0; + break; + case 'NAME': + $_xh[$parser]['st'].="'"; $_xh[$parser]['ac']=''; + break; + case 'FAULT': + $_xh[$parser]['isf']=1; + break; + case 'PARAM': + $_xh[$parser]['st']=''; + break; + case 'VALUE': + $_xh[$parser]['st'].='new xmlrpcval('; + $_xh[$parser]['vt']=$xmlrpcString; + $_xh[$parser]['ac']=''; + $_xh[$parser]['qt']=0; + $_xh[$parser]['lv']=1; + // look for a value: if this is still 1 by the + // time we reach the first data segment then the type is string + // by implication and we need to add in a quote + break; + case 'I4': + case 'INT': + case 'STRING': + case 'BOOLEAN': + case 'DOUBLE': + case 'DATETIME.ISO8601': + case 'BASE64': + $_xh[$parser]['ac']=''; // reset the accumulator + + if ($name=='DATETIME.ISO8601' || $name=='STRING') + { + $_xh[$parser]['qt']=1; + if ($name=='DATETIME.ISO8601') + { + $_xh[$parser]['vt']=$xmlrpcDateTime; + } + } + elseif ($name=='BASE64') + { + $_xh[$parser]['qt']=2; + } + else + { + // No quoting is required here -- but + // at the end of the element we must check + // for data format errors. + $_xh[$parser]['qt']=0; + } + break; + case 'MEMBER': + $_xh[$parser]['ac']=''; + break; + default: + break; + } + + if ($name!='VALUE') + { + $_xh[$parser]['lv']=0; + } + } + + function xmlrpc_ee($parser, $name) + { + global $_xh,$xmlrpcTypes,$xmlrpcString; + + switch($name) + { + case 'STRUCT': + case 'ARRAY': + if ($_xh[$parser]['cm'] && substr($_xh[$parser]['st'], -1) ==',') + { + $_xh[$parser]['st']=substr($_xh[$parser]['st'],0,-1); + } + $_xh[$parser]['st'].=')'; + $_xh[$parser]['vt']=strtolower($name); + $_xh[$parser]['cm']--; + break; + case 'NAME': + $_xh[$parser]['st'].= $_xh[$parser]['ac'] . "' => "; + break; + case 'BOOLEAN': + // special case here: we translate boolean 1 or 0 into PHP + // constants true or false + if ($_xh[$parser]['ac']=='1') + { + $_xh[$parser]['ac']='true'; + } + else + { + $_xh[$parser]['ac']='false'; + $_xh[$parser]['vt']=strtolower($name); + // Drop through intentionally. + } + case 'I4': + case 'INT': + case 'STRING': + case 'DOUBLE': + case 'DATETIME.ISO8601': + case 'BASE64': + if ($_xh[$parser]['qt']==1) + { + // we use double quotes rather than single so backslashification works OK + $_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"'; + } + elseif ($_xh[$parser]['qt']==2) + { + $_xh[$parser]['st'].="base64_decode('". $_xh[$parser]['ac'] . "')"; + } + elseif ($name=='BOOLEAN') + { + $_xh[$parser]['st'].=$_xh[$parser]['ac']; + } + else + { + // we have an I4, INT or a DOUBLE + // we must check that only 0123456789-.<space> are characters here + if (!ereg("^\-?[0123456789 \t\.]+$", $_xh[$parser]['ac'])) + { + // TODO: find a better way of throwing an error + // than this! + error_log('XML-RPC: non numeric value received in INT or DOUBLE'); + $_xh[$parser]['st'].='ERROR_NON_NUMERIC_FOUND'; + } + else + { + // it's ok, add it on + $_xh[$parser]['st'].=$_xh[$parser]['ac']; + } + } + $_xh[$parser]['ac']=''; $_xh[$parser]['qt']=0; + $_xh[$parser]['lv']=3; // indicate we've found a value + break; + case 'VALUE': + // deal with a string value + if (strlen($_xh[$parser]['ac'])>0 && + $_xh[$parser]['vt']==$xmlrpcString) + { + $_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"'; + } + // This if() detects if no scalar was inside <VALUE></VALUE> + // and pads an empty ''. + if($_xh[$parser]['st'][strlen($_xh[$parser]['st'])-1] == '(') + { + $_xh[$parser]['st'].= '""'; + } + $_xh[$parser]['st'].=", '" . $_xh[$parser]['vt'] . "')"; + if ($_xh[$parser]['cm']) + { + $_xh[$parser]['st'].=','; + } + break; + case 'MEMBER': + $_xh[$parser]['ac']=''; $_xh[$parser]['qt']=0; + break; + case 'DATA': + $_xh[$parser]['ac']=''; $_xh[$parser]['qt']=0; + break; + case 'PARAM': + $_xh[$parser]['params'][]=$_xh[$parser]['st']; + break; + case 'METHODNAME': + $_xh[$parser]['method']=ereg_replace("^[\n\r\t ]+", '', $_xh[$parser]['ac']); + break; + case 'BOOLEAN': + // special case here: we translate boolean 1 or 0 into PHP + // constants true or false + if ($_xh[$parser]['ac']=='1') + { + $_xh[$parser]['ac']='true'; + } + else + { + $_xh[$parser]['ac']='false'; + $_xh[$parser]['vt']=strtolower($name); + } + break; + default: + break; + } + // if it's a valid type name, set the type + if (isset($xmlrpcTypes[strtolower($name)])) + { + $_xh[$parser]['vt']=strtolower($name); + } + } + + function xmlrpc_cd($parser, $data) + { + global $_xh, $xmlrpc_backslash; + + //if (ereg("^[\n\r \t]+$", $data)) return; + // print "adding [${data}]\n"; + + if ($_xh[$parser]['lv']!=3) + { + // "lookforvalue==3" means that we've found an entire value + // and should discard any further character data + if ($_xh[$parser]['lv']==1) + { + // if we've found text and we're just in a <value> then + // turn quoting on, as this will be a string + $_xh[$parser]['qt']=1; + // and say we've found a value + $_xh[$parser]['lv']=2; + } + if(!@isset($_xh[$parser]['ac'])) + { + $_xh[$parser]['ac'] = ''; + } + $_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data))); + } + } + + function xmlrpc_dh($parser, $data) + { + global $_xh; + if (substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';') + { + if ($_xh[$parser]['lv']==1) + { + $_xh[$parser]['qt']=1; + $_xh[$parser]['lv']=2; + } + $_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data))); + } + } + + class xmlrpc_client + { + var $path; + var $server; + var $port; + var $errno; + var $errstring; + var $debug=0; + var $username=''; + var $password=''; + var $cert=''; + var $certpass=''; + var $verifypeer=1; + var $verifyhost=1; + var $no_multicall=false; + + function xmlrpc_client($path, $server, $port=0) + { + $this->port=$port; $this->server=$server; $this->path=$path; + } + + function setDebug($in) + { + if ($in) + { + $this->debug=1; + } + else + { + $this->debug=0; + } + } + + function setCredentials($u, $p) + { + $this->username=$u; + $this->password=$p; + } + + function setCertificate($cert, $certpass) + { + $this->cert = $cert; + $this->certpass = $certpass; + } + + function setSSLVerifyPeer($i) + { + $this->verifypeer = $i; + } + + function setSSLVerifyHost($i) + { + $this->verifyhost = $i; + } + + function send($msg, $timeout=0, $method='http') + { + if (is_array($msg)) + { + // $msg is an array of xmlrpcmsg's + return $this->multicall($msg, $timeout, $method); + } + + // where msg is an xmlrpcmsg + $msg->debug=$this->debug; + + if ($method == 'https') + { + return $this->sendPayloadHTTPS($msg, + $this->server, + $this->port, $timeout, + $this->username, $this->password, + $this->cert, + $this->certpass); + } + else + { + return $this->sendPayloadHTTP10($msg, $this->server, $this->port, + $timeout, $this->username, + $this->password); + } + } + + function sendPayloadHTTP10($msg, $server, $port, $timeout=0,$username='', $password='') + { + global $xmlrpcerr, $xmlrpcstr; + if ($port==0) + { + $port=80; + } + if($timeout>0) + { + $fp=fsockopen($server, $port,$this->errno, $this->errstr, $timeout); + } + else + { + $fp=fsockopen($server, $port,$this->errno, $this->errstr); + } + if (!$fp) + { + $this->errstr='Connect error'; + $r=new xmlrpcresp(0, $xmlrpcerr['http_error'],$xmlrpcstr['http_error']); + return $r; + } + // Only create the payload if it was not created previously + if(empty($msg->payload)) + { + $msg->createPayload(); + } + + // thanks to Grant Rauscher <grant7@firstworld.net> + // for this + $credentials=''; + if ($username!='') + { + $credentials='Authorization: Basic ' . base64_encode($username . ':' . $password) . "\r\n"; + } + + $op= "POST " . $this->path. " HTTP/1.0\r\nUser-Agent: PHP XMLRPC 1.0\r\n" . + "Host: ". $this->server . "\r\n" . + $credentials . + "Content-Type: text/xml\r\nContent-Length: " . + strlen($msg->payload) . "\r\n\r\n" . + $msg->payload; + + if (!fputs($fp, $op, strlen($op))) + { + $this->errstr='Write error'; + $r=new xmlrpcresp(0, $xmlrpcerr['http_error'], $xmlrpcstr['http_error']); + return $r; + } + $resp=$msg->parseResponseFile($fp); + fclose($fp); + return $resp; + } + + // contributed by Justin Miller <justin@voxel.net> + // requires curl to be built into PHP + function sendPayloadHTTPS($msg, $server, $port, $timeout=0,$username='', $password='', $cert='',$certpass='') + { + global $xmlrpcerr, $xmlrpcstr; + if ($port == 0) + { + $port = 443; + } + + // Only create the payload if it was not created previously + if(empty($msg->payload)) + { + $msg->createPayload(); + } + + if (!function_exists('curl_init')) + { + $this->errstr='SSL unavailable on this install'; + $r=new xmlrpcresp(0, $xmlrpcerr['no_ssl'], $xmlrpcstr['no_ssl']); + return $r; + } + + $curl = curl_init('https://' . $server . ':' . $port . $this->path); + + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + // results into variable + if ($this->debug) + { + curl_setopt($curl, CURLOPT_VERBOSE, 1); + } + curl_setopt($curl, CURLOPT_USERAGENT, 'PHP XMLRPC 1.0'); + // required for XMLRPC + curl_setopt($curl, CURLOPT_POST, 1); + // post the data + curl_setopt($curl, CURLOPT_POSTFIELDS, $msg->payload); + // the data + curl_setopt($curl, CURLOPT_HEADER, 1); + // return the header too + curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: text/xml')); + // whether to verify remote host's cert + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verifypeer); + // whether to verify cert's common name (CN); 0 for no, 1 to verify that it exists, and 2 to verify that it matches the hostname used + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $this->verifyhost); + // required for XMLRPC + if ($timeout) + { + curl_setopt($curl, CURLOPT_TIMEOUT, $timeout == 1 ? 1 : $timeout - 1); + } + // timeout is borked + if ($username && $password) + { + curl_setopt($curl, CURLOPT_USERPWD,"$username:$password"); + } + // set auth stuff + if ($cert) + { + curl_setopt($curl, CURLOPT_SSLCERT, $cert); + } + // set cert file + if ($certpass) + { + curl_setopt($curl, CURLOPT_SSLCERTPASSWD,$certpass); + } + // set cert password + + $result = curl_exec($curl); + + if (!$result) + { + $this->errstr='no response'; + $resp=new xmlrpcresp(0, $xmlrpcerr['curl_fail'], $xmlrpcstr['curl_fail']. ': '. curl_error($curl)); + } + else + { + $resp = $msg->parseResponse($result); + } + curl_close($curl); + return $resp; + } + + function multicall($msgs, $timeout=0, $method='http') + { + $results = false; + + if (! $this->no_multicall) + { + $results = $this->_try_multicall($msgs, $timeout, $method); + /* TODO - this is not php3-friendly */ + // if($results !== false) + if($results != false) + { + // Either the system.multicall succeeded, or the send + // failed (e.g. due to HTTP timeout). In either case, + // we're done for now. + return $results; + } + else + { + // system.multicall unsupported by server, + // don't try it next time... + $this->no_multicall = true; + } + } + + // system.multicall is unupported by server: + // Emulate multicall via multiple requests + $results = array(); + //foreach($msgs as $msg) + @reset($msgs); + while(list(,$msg) = @each($msgs)) + { + $results[] = $this->send($msg, $timeout, $method); + } + return $results; + } + + // Attempt to boxcar $msgs via system.multicall. + function _try_multicall($msgs, $timeout, $method) + { + // Construct multicall message + $calls = array(); + //foreach($msgs as $msg) + @reset($msgs); + while(list(,$msg) = @each($msgs)) + { + $call['methodName'] = new xmlrpcval($msg->method(),'string'); + $numParams = $msg->getNumParams(); + $params = array(); + for ($i = 0; $i < $numParams; $i++) + { + $params[$i] = $msg->getParam($i); + } + $call['params'] = new xmlrpcval($params, 'array'); + $calls[] = new xmlrpcval($call, 'struct'); + } + $multicall = new xmlrpcmsg('system.multicall'); + $multicall->addParam(new xmlrpcval($calls, 'array')); + + // Attempt RPC call + $result = $this->send($multicall, $timeout, $method); + if (!is_object($result)) + return ($result || 0); // transport failed + + if ($result->faultCode() != 0) + return false; // system.multicall failed + + // Unpack responses. + $rets = $result->value(); + if ($rets->kindOf() != 'array') + return false; // bad return type from system.multicall + $numRets = $rets->arraysize(); + if ($numRets != count($msgs)) + return false; // wrong number of return values. + + $response = array(); + for ($i = 0; $i < $numRets; $i++) + { + $val = $rets->arraymem($i); + switch ($val->kindOf()) + { + case 'array': + if ($val->arraysize() != 1) + return false; // Bad value + // Normal return value + $response[$i] = new xmlrpcresp($val->arraymem(0)); + break; + case 'struct': + $code = $val->structmem('faultCode'); + if ($code->kindOf() != 'scalar' || $code->scalartyp() != 'int') + return false; + $str = $val->structmem('faultString'); + if ($str->kindOf() != 'scalar' || $str->scalartyp() != 'string') + return false; + $response[$i] = new xmlrpcresp(0, $code->scalarval(), $str->scalarval()); + break; + default: + return false; + } + } + return $response; + } + } // end class xmlrpc_client + + class xmlrpcresp + { + var $val = 0; + var $errno = 0; + var $errstr = ''; + var $hdrs = array(); + + function xmlrpcresp($val, $fcode = 0, $fstr = '') + { + if ($fcode != 0) + { + // error + $this->errno = $fcode; + $this->errstr = htmlspecialchars($fstr); // XXX: encoding probably shouldn't be done here; fix later. + } + else if (!is_object($val)) + { + // programmer error + error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to xmlrpcresp. Defaulting to empty value."); + $this->val = new xmlrpcval(); + } + else + { + // success + $this->val = $val; + } + } + + function faultCode() + { + return $this->errno; + } + + function faultString() + { + return $this->errstr; + } + + function value() + { + return $this->val; + } + + function serialize() + { + $result = "<methodResponse>\n"; + if ($this->errno) + { + $result .= '<fault> +<value> +<struct> +<member> +<name>faultCode</name> +<value><int>' . $this->errno . '</int></value> +</member> +<member> +<name>faultString</name> +<value><string>' . $this->errstr . '</string></value> +</member> +</struct> +</value> +</fault>'; + } + else + { + $result .= "<params>\n<param>\n" . + $this->val->serialize() . + "</param>\n</params>"; + } + $result .= "\n</methodResponse>"; + return $result; + } + } + + class xmlrpcmsg + { + var $payload; + var $methodname; + var $params=array(); + var $debug=0; + + function xmlrpcmsg($meth, $pars=0) + { + $this->methodname=$meth; + if (is_array($pars) && sizeof($pars)>0) + { + for($i=0; $i<sizeof($pars); $i++) + { + $this->addParam($pars[$i]); + } + } + } + + function xml_header() + { + return "<?xml version=\"1.0\"?>\n<methodCall>\n"; + } + + function xml_footer() + { + return "</methodCall>\n"; + } + + function createPayload() + { + $this->payload=$this->xml_header(); + $this->payload.='<methodName>' . $this->methodname . "</methodName>\n"; + // if (sizeof($this->params)) { + $this->payload.="<params>\n"; + for($i=0; $i<sizeof($this->params); $i++) + { + $p=$this->params[$i]; + $this->payload.="<param>\n" . $p->serialize() . + "</param>\n"; + } + $this->payload.="</params>\n"; + // } + $this->payload.=$this->xml_footer(); + $this->payload=str_replace("\n", "\r\n", $this->payload); + } + + function method($meth='') + { + if ($meth!='') + { + $this->methodname=$meth; + } + return $this->methodname; + } + + function serialize() + { + $this->createPayload(); + return $this->payload; + } + + function addParam($par) { $this->params[]=$par; } + function getParam($i) { return $this->params[$i]; } + function getNumParams() { return sizeof($this->params); } + + function parseResponseFile($fp) + { + $ipd=''; + while($data=fread($fp, 32768)) + { + $ipd.=$data; + } + return $this->parseResponse($ipd); + } + + function parseResponse($data='') + { + global $_xh,$xmlrpcerr,$xmlrpcstr; + global $xmlrpc_defencoding; + + $parser = xml_parser_create($xmlrpc_defencoding); + + $_xh[$parser]=array(); + + $_xh[$parser]['st']=''; + $_xh[$parser]['cm']=0; + $_xh[$parser]['isf']=0; + $_xh[$parser]['ac']=''; + $_xh[$parser]['qt']=''; + $_xh[$parser]['headers'] = array(); + + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); + xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee'); + xml_set_character_data_handler($parser, 'xmlrpc_cd'); + xml_set_default_handler($parser, 'xmlrpc_dh'); + $xmlrpc_value=new xmlrpcval; + + $hdrfnd = 0; + if($this->debug) + { + //by maHo, replaced htmlspecialchars with htmlentities + print "<PRE>---GOT---\n" . htmlentities($data) . "\n---END---\n</PRE>"; + } + + if($data == '') + { + error_log('No response received from server.'); + $r = new xmlrpcresp(0, $xmlrpcerr['no_data'], $xmlrpcstr['no_data']); + xml_parser_free($parser); + return $r; + } + // see if we got an HTTP 200 OK, else bomb + // but only do this if we're using the HTTP protocol. + if(ereg("^HTTP",$data) && !ereg("^HTTP/[0-9\.]+ 200 ", $data)) + { + $errstr= substr($data, 0, strpos($data, "\n")-1); + error_log('HTTP error, got response: ' .$errstr); + $r=new xmlrpcresp(0, $xmlrpcerr['http_error'], $xmlrpcstr['http_error']. ' (' . $errstr . ')'); + xml_parser_free($parser); + return $r; + } + + // separate HTTP headers from data + if (ereg("^HTTP", $data)) + { + $ar = split("\r\n", $data); + while (($line = array_shift($ar))) + { + if (strlen($line) < 1) + { + break; + } + $_xh[$parser]['headers'][] = $line; + } + $data = join("\r\n", $ar); + } + + if ($this->debug && count($_xh[$parser]['headers'])) + { + print "<PRE>"; + foreach ($_xh[$parser]['headers'] as $header) + { + print "HEADER: $header\n"; + } + print "</PRE>\n"; + } + + if (!xml_parse($parser, $data, sizeof($data))) + { + // thanks to Peter Kocks <peter.kocks@baygate.com> + if((xml_get_current_line_number($parser)) == 1) + { + $errstr = 'XML error at line 1, check URL'; + } + else + { + $errstr = sprintf('XML error: %s at line %d', + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser)); + error_log($errstr); + $r=new xmlrpcresp(0, $xmlrpcerr['invalid_return'], $xmlrpcstr['invalid_return']); + xml_parser_free($parser); + echo $errstr; + return $r; + } + } + xml_parser_free($parser); + if ($this->debug) + { + print "<PRE>---EVALING---[" . + strlen($_xh[$parser]['st']) . " chars]---\n" . + htmlspecialchars($_xh[$parser]['st']) . ";\n---END---</PRE>"; + } + if (strlen($_xh[$parser]['st'])==0) + { + // then something odd has happened + // and it's time to generate a client side error + // indicating something odd went on + $r=new xmlrpcresp(0, $xmlrpcerr['invalid_return'], + $xmlrpcstr['invalid_return']); + } + else + { + eval('$v=' . $_xh[$parser]['st'] . '; $allOK=1;'); + if ($_xh[$parser]['isf']) + { + $errno_v = $v->structmem('faultCode'); + $errstr_v = $v->structmem('faultString'); + $errno = $errno_v->scalarval(); + + if ($errno == 0) + { + // FAULT returned, errno needs to reflect that + $errno = -1; + } + + $r = new xmlrpcresp($v, $errno, $errstr_v->scalarval()); + } + else + { + $r=new xmlrpcresp($v); + } + } + + $r->hdrs = $_xh[$parser]['headers']; + return $r; + } + } + + class xmlrpcval + { + var $me=array(); + var $mytype=0; + + function xmlrpcval($val=-1, $type='') + { + global $xmlrpcTypes; + $this->me=array(); + $this->mytype=0; + if ($val!=-1 || $type!='') + { + if ($type=='') + { + $type='string'; + } + if ($xmlrpcTypes[$type]==1) + { + $this->addScalar($val,$type); + } + elseif ($xmlrpcTypes[$type]==2) + { + $this->addArray($val); + } + elseif ($xmlrpcTypes[$type]==3) + { + $this->addStruct($val); + } + } + } + + function addScalar($val, $type='string') + { + global $xmlrpcTypes, $xmlrpcBoolean; + + if ($this->mytype==1) + { + echo '<B>xmlrpcval</B>: scalar can have only one value<BR>'; + return 0; + } + $typeof=$xmlrpcTypes[$type]; + if ($typeof!=1) + { + echo '<B>xmlrpcval</B>: not a scalar type (${typeof})<BR>'; + return 0; + } + + if ($type==$xmlrpcBoolean) + { + if (strcasecmp($val,'true')==0 || $val==1 || ($val==true && strcasecmp($val,'false'))) + { + $val=1; + } + else + { + $val=0; + } + } + + if ($this->mytype==2) + { + // we're adding to an array here + $ar=$this->me['array']; + $ar[]=new xmlrpcval($val, $type); + $this->me['array']=$ar; + } + else + { + // a scalar, so set the value and remember we're scalar + $this->me[$type]=$val; + $this->mytype=$typeof; + } + return 1; + } + + function addArray($vals) + { + global $xmlrpcTypes; + if ($this->mytype!=0) + { + echo '<B>xmlrpcval</B>: already initialized as a [' . $this->kindOf() . ']<BR>'; + return 0; + } + + $this->mytype=$xmlrpcTypes['array']; + $this->me['array']=$vals; + return 1; + } + + function addStruct($vals) + { + global $xmlrpcTypes; + if ($this->mytype!=0) + { + echo '<B>xmlrpcval</B>: already initialized as a [' . $this->kindOf() . ']<BR>'; + return 0; + } + $this->mytype=$xmlrpcTypes['struct']; + $this->me['struct']=$vals; + return 1; + } + + function dump($ar) + { + reset($ar); + while ( list( $key, $val ) = each( $ar ) ) + { + echo "$key => $val<br>"; + if ($key == 'array') + { + while ( list( $key2, $val2 ) = each( $val ) ) + { + echo "-- $key2 => $val2<br>"; + } + } + } + } + + function kindOf() + { + switch($this->mytype) + { + case 3: + return 'struct'; + break; + case 2: + return 'array'; + break; + case 1: + return 'scalar'; + break; + default: + return 'undef'; + } + } + + function serializedata($typ, $val) + { + $rs=''; + global $xmlrpcTypes, $xmlrpcBase64, $xmlrpcString, + $xmlrpcBoolean; + switch($xmlrpcTypes[$typ]) + { + case 3: + // struct + $rs.="<struct>\n"; + reset($val); + while(list($key2, $val2)=each($val)) + { + $rs.="<member><name>${key2}</name>\n"; + $rs.=$this->serializeval($val2); + $rs.="</member>\n"; + } + $rs.='</struct>'; + break; + case 2: + // array + $rs.="<array>\n<data>\n"; + for($i=0; $i<sizeof($val); $i++) + { + $rs.=$this->serializeval($val[$i]); + } + $rs.="</data>\n</array>"; + break; + case 1: + switch ($typ) + { + case $xmlrpcBase64: + $rs.="<${typ}>" . base64_encode($val) . "</${typ}>"; + break; + case $xmlrpcBoolean: + $rs.="<${typ}>" . ($val ? '1' : '0') . "</${typ}>"; + break; + case $xmlrpcString: + $rs.="<${typ}>" . htmlspecialchars($val). "</${typ}>"; + break; + default: + $rs.="<${typ}>${val}</${typ}>"; + } + break; + default: + break; + } + return $rs; + } + + function serialize() + { + return $this->serializeval($this); + } + + function serializeval($o) + { + global $xmlrpcTypes; + $rs=''; + $ar=$o->me; + reset($ar); + list($typ, $val) = each($ar); + $rs.='<value>'; + $rs.=$this->serializedata($typ, $val); + $rs.="</value>\n"; + return $rs; + } + + function structmem($m) + { + $nv=$this->me['struct'][$m]; + return $nv; + } + + function structreset() + { + reset($this->me['struct']); + } + + function structeach() + { + return each($this->me['struct']); + } + + function getval() + { + // UNSTABLE + global $xmlrpcBoolean, $xmlrpcBase64; + reset($this->me); + list($a,$b)=each($this->me); + // contributed by I Sofer, 2001-03-24 + // add support for nested arrays to scalarval + // i've created a new method here, so as to + // preserve back compatibility + + if (is_array($b)) + { + @reset($b); + while(list($id,$cont) = @each($b)) + { + $b[$id] = $cont->scalarval(); + } + } + + // add support for structures directly encoding php objects + if (is_object($b)) + { + $t = get_object_vars($b); + @reset($t); + while(list($id,$cont) = @each($t)) + { + $t[$id] = $cont->scalarval(); + } + @reset($t); + while(list($id,$cont) = @each($t)) + { + eval('$b->'.$id.' = $cont;'); + } + } + // end contrib + return $b; + } + + function scalarval() + { + global $xmlrpcBoolean, $xmlrpcBase64; + reset($this->me); + list($a,$b)=each($this->me); + return $b; + } + + function scalartyp() + { + global $xmlrpcI4, $xmlrpcInt; + reset($this->me); + list($a,$b)=each($this->me); + if ($a==$xmlrpcI4) + { + $a=$xmlrpcInt; + } + return $a; + } + + function arraymem($m) + { + $nv=$this->me['array'][$m]; + return $nv; + } + + function arraysize() + { + reset($this->me); + list($a,$b)=each($this->me); + return sizeof($b); + } + } + + // date helpers + function iso8601_encode($timet, $utc=0) + { + // return an ISO8601 encoded string + // really, timezones ought to be supported + // but the XML-RPC spec says: + // + // "Don't assume a timezone. It should be specified by the server in its + // documentation what assumptions it makes about timezones." + // + // these routines always assume localtime unless + // $utc is set to 1, in which case UTC is assumed + // and an adjustment for locale is made when encoding + if (!$utc) + { + $t=strftime("%Y%m%dT%H:%M:%S", $timet); + } + else + { + if (function_exists('gmstrftime')) + { + // gmstrftime doesn't exist in some versions + // of PHP + $t=gmstrftime("%Y%m%dT%H:%M:%S", $timet); + } + else + { + $t=strftime("%Y%m%dT%H:%M:%S", $timet-date('Z')); + } + } + return $t; + } + + function iso8601_decode($idate, $utc=0) + { + // return a timet in the localtime, or UTC + $t=0; + if (ereg("([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})", $idate, $regs)) + { + if ($utc) + { + $t=gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); + } + else + { + $t=mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); + } + } + return $t; + } + + /**************************************************************** + * xmlrpc_decode takes a message in PHP xmlrpc object format and * + * tranlates it into native PHP types. * + * * + * author: Dan Libby (dan@libby.com) * + ****************************************************************/ + function old_xmlrpc_decode($xmlrpc_val) + { + $kind = $xmlrpc_val->kindOf(); + + if($kind == 'scalar') + { + return $xmlrpc_val->scalarval(); + } + elseif($kind == 'array') + { + $size = $xmlrpc_val->arraysize(); + $arr = array(); + + for($i = 0; $i < $size; $i++) + { + $arr[]=old_xmlrpc_decode($xmlrpc_val->arraymem($i)); + } + return $arr; + } + elseif($kind == 'struct') + { + $xmlrpc_val->structreset(); + $arr = array(); + + while(list($key,$value)=$xmlrpc_val->structeach()) + { + $arr[$key] = old_xmlrpc_decode($value); + } + return $arr; + } + } + + /**************************************************************** + * xmlrpc_encode takes native php types and encodes them into * + * xmlrpc PHP object format. * + * BUG: All sequential arrays are turned into structs. I don't * + * know of a good way to determine if an array is sequential * + * only. * + * * + * feature creep -- could support more types via optional type * + * argument. * + * * + * author: Dan Libby (dan@libby.com) * + ****************************************************************/ + function old_xmlrpc_encode($php_val) + { + global $xmlrpcInt; + global $xmlrpcDouble; + global $xmlrpcString; + global $xmlrpcArray; + global $xmlrpcStruct; + global $xmlrpcBoolean; + + $type = gettype($php_val); + $xmlrpc_val = new xmlrpcval; + + switch($type) + { + case 'array': + case 'object': + $arr = array(); + while (list($k,$v) = each($php_val)) + { + $arr[$k] = old_xmlrpc_encode($v); + } + $xmlrpc_val->addStruct($arr); + break; + case 'integer': + $xmlrpc_val->addScalar($php_val, $xmlrpcInt); + break; + case 'double': + $xmlrpc_val->addScalar($php_val, $xmlrpcDouble); + break; + case 'string': + $xmlrpc_val->addScalar($php_val, $xmlrpcString); + break; + // <G_Giunta_2001-02-29> + // Add support for encoding/decoding of booleans, since they are supported in PHP + case 'boolean': + $xmlrpc_val->addScalar($php_val, $xmlrpcBoolean); + break; + // </G_Giunta_2001-02-29> + case 'unknown type': + default: + // giancarlo pinerolo <ping@alt.it> + // it has to return + // an empty object in case (which is already + // at this point), not a boolean. + break; + } + return $xmlrpc_val; + } +?> diff --git a/modules/xmlrpc/xmlrpcs.inc b/modules/xmlrpc/xmlrpcs.inc new file mode 100755 index 00000000..51411712 --- /dev/null +++ b/modules/xmlrpc/xmlrpcs.inc @@ -0,0 +1,466 @@ +<?php +// by Edd Dumbill (C) 1999-2002 +// <edd@usefulinc.com> +// $Id: xmlrpcs.inc,v 1.7 2002/12/19 12:40:01 milosch Exp $ + +// Copyright (c) 1999,2000,2002 Edd Dumbill. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * 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. + + // XML RPC Server class + // requires: xmlrpc.inc + + // 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'; + function _xmlrpcs_listMethods($server, $m) + { + global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap; + $v=new xmlrpcval(); + $dmap=$server->dmap; + $outAr=array(); + for(reset($dmap); list($key, $val)=each($dmap); ) + { + $outAr[]=new xmlrpcval($key, 'string'); + } + $dmap=$_xmlrpcs_dmap; + for(reset($dmap); list($key, $val)=each($dmap); ) + { + $outAr[]=new xmlrpcval($key, 'string'); + } + $v->addArray($outAr); + return new xmlrpcresp($v); + } + + $_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)'; + function _xmlrpcs_methodSignature($server, $m) + { + global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap; + + $methName=$m->getParam(0); + $methName=$methName->scalarval(); + if (ereg("^system\.", $methName)) + { + $dmap=$_xmlrpcs_dmap; $sysCall=1; + } + else + { + $dmap=$server->dmap; $sysCall=0; + } + // print "<!-- ${methName} -->\n"; + if (isset($dmap[$methName])) + { + if ($dmap[$methName]['signature']) + { + $sigs=array(); + $thesigs=$dmap[$methName]['signature']; + for($i=0; $i<sizeof($thesigs); $i++) + { + $cursig=array(); + $inSig=$thesigs[$i]; + for($j=0; $j<sizeof($inSig); $j++) + { + $cursig[]=new xmlrpcval($inSig[$j], 'string'); + } + $sigs[]=new xmlrpcval($cursig, 'array'); + } + $r=new xmlrpcresp(new xmlrpcval($sigs, 'array')); + } + else + { + $r=new xmlrpcresp(new xmlrpcval('undef', 'string')); + } + } + else + { + $r=new xmlrpcresp(0,$xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']); + } + return $r; + } + + $_xmlrpcs_methodHelp_sig=array(array($xmlrpcString, $xmlrpcString)); + $_xmlrpcs_methodHelp_doc='Returns help text if defined for the method passed, otherwise returns an empty string'; + function _xmlrpcs_methodHelp($server, $m) + { + global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap; + + $methName=$m->getParam(0); + $methName=$methName->scalarval(); + if (ereg("^system\.", $methName)) + { + $dmap=$_xmlrpcs_dmap; $sysCall=1; + } + else + { + $dmap=$server->dmap; $sysCall=0; + } + // print "<!-- ${methName} -->\n"; + if (isset($dmap[$methName])) + { + if ($dmap[$methName]['docstring']) + { + $r=new xmlrpcresp(new xmlrpcval($dmap[$methName]['docstring']), 'string'); + } + else + { + $r=new xmlrpcresp(new xmlrpcval('', 'string')); + } + } + else + { + $r=new xmlrpcresp(0, $xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']); + } + return $r; + } + + $_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'; + + function _xmlrpcs_multicall_error($err) + { + if (is_string($err)) + { + global $xmlrpcerr, $xmlrpcstr; + $str = $xmlrpcstr["multicall_${err}"]; + $code = $xmlrpcerr["multicall_${err}"]; + } + else + { + $code = $err->faultCode(); + $str = $err->faultString(); + } + $struct['faultCode'] = new xmlrpcval($code, 'int'); + $struct['faultString'] = new xmlrpcval($str, 'string'); + return new xmlrpcval($struct, 'struct'); + } + + function _xmlrpcs_multicall_do_call($server, $call) + { + if ($call->kindOf() != 'struct') + { + return _xmlrpcs_multicall_error('notstruct'); + } + $methName = $call->structmem('methodName'); + if (!$methName) + { + return _xmlrpcs_multicall_error('nomethod'); + } + if ($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string') + { + return _xmlrpcs_multicall_error('notstring'); + } + if ($methName->scalarval() == 'system.multicall') + { + return _xmlrpcs_multicall_error('recursion'); + } + + $params = $call->structmem('params'); + if (!$params) + { + return _xmlrpcs_multicall_error('noparams'); + } + if ($params->kindOf() != 'array') + { + return _xmlrpcs_multicall_error('notarray'); + } + $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 _xmlrpcs_multicall_error($result); // Method returned fault. + } + + return new xmlrpcval(array($result->value()), 'array'); + } + + function _xmlrpcs_multicall($server, $m) + { + $calls = $m->getParam(0); + $numCalls = $calls->arraysize(); + $result = array(); + + for ($i = 0; $i < $numCalls; $i++) + { + $call = $calls->arraymem($i); + $result[$i] = _xmlrpcs_multicall_do_call($server, $call); + } + + return new xmlrpcresp(new xmlrpcval($result, 'array')); + } + + $_xmlrpcs_dmap=array( + '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 + ) + ); + + $_xmlrpc_debuginfo=''; + function xmlrpc_debugmsg($m) + { + global $_xmlrpc_debuginfo; + $_xmlrpc_debuginfo=$_xmlrpc_debuginfo . $m . "\n"; + } + + class xmlrpc_server + { + var $dmap=array(); + + function xmlrpc_server($dispMap='', $serviceNow=1) + { + global $HTTP_RAW_POST_DATA; + // dispMap is a dispatch array of methods + // mapped to function names and signatures + // if a method + // 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) + */ + if($dispMap) + { + $this->dmap = $dispMap; + if($serviceNow) + { + $this->service(); + } + } + } + + function serializeDebug() + { + global $_xmlrpc_debuginfo; + if ($_xmlrpc_debuginfo!='') + { + return "<!-- DEBUG INFO:\n\n" . $_xmlrpc_debuginfo . "\n-->\n"; + } + else + { + return ''; + } + } + + function service() + { + global $xmlrpc_defencoding; + + $r=$this->parseRequest(); + $payload='<?xml version="1.0" encoding="' . $xmlrpc_defencoding . '"?>' . "\n" + . $this->serializeDebug() + . $r->serialize(); + Header("Content-type: text/xml\r\nContent-length: " . + strlen($payload)); + print $payload; + } + + /* + add a method to the dispatch map + */ + function add_to_map($methodname,$function,$sig,$doc) + { + $this->dmap[$methodname] = array( + 'function' => $function, + 'signature' => $sig, + 'docstring' => $doc + ); + } + + function verifySignature($in, $sig) + { + for($i=0; $i<sizeof($sig); $i++) + { + // check each possible signature in turn + $cursig=$sig[$i]; + if (sizeof($cursig)==$in->getNumParams()+1) + { + $itsOK=1; + for($n=0; $n<$in->getNumParams(); $n++) + { + $p=$in->getParam($n); + // print "<!-- $p -->\n"; + if ($p->kindOf() == 'scalar') + { + $pt=$p->scalartyp(); + } + else + { + $pt=$p->kindOf(); + } + // $n+1 as first type of sig is return type + if ($pt != $cursig[$n+1]) + { + $itsOK=0; + $pno=$n+1; $wanted=$cursig[$n+1]; $got=$pt; + break; + } + } + if ($itsOK) + { + return array(1); + } + } + } + return array(0, "Wanted ${wanted}, got ${got} at param ${pno})"); + } + + function parseRequest($data='') + { + global $_xh,$HTTP_RAW_POST_DATA; + global $xmlrpcerr, $xmlrpcstr, $xmlrpcerrxml, $xmlrpc_defencoding, + $_xmlrpcs_dmap; + + if ($data=='') + { + $data=$HTTP_RAW_POST_DATA; + } + $parser = xml_parser_create($xmlrpc_defencoding); + + $_xh[$parser]=array(); + $_xh[$parser]['st']=''; + $_xh[$parser]['cm']=0; + $_xh[$parser]['isf']=0; + $_xh[$parser]['params']=array(); + $_xh[$parser]['method']=''; + + // decompose incoming XML into request structure + + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); + xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee'); + xml_set_character_data_handler($parser, 'xmlrpc_cd'); + xml_set_default_handler($parser, 'xmlrpc_dh'); + if (!xml_parse($parser, $data, 1)) + { + // return XML error as a faultCode + $r=new xmlrpcresp(0, + $xmlrpcerrxml+xml_get_error_code($parser), + sprintf('XML error: %s at line %d', + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser))); + xml_parser_free($parser); + } + else + { + xml_parser_free($parser); + $m=new xmlrpcmsg($_xh[$parser]['method']); + // now add parameters in + $plist=''; + 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]. ');'); + } + // uncomment this to really see what the server's getting! + // xmlrpc_debugmsg($plist); + + $r = $this->execute($m); + } + return $r; + } + + function execute ($m) + { + global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap; + // now to deal with the method + $methName = $m->method(); + $sysCall = ereg("^system\.", $methName); + $dmap = $sysCall ? $_xmlrpcs_dmap : $this->dmap; + + if (!isset($dmap[$methName]['function'])) + { + // No such method + return new xmlrpcresp(0, + $xmlrpcerr['unknown_method'], + $xmlrpcstr['unknown_method']); + } + + // Check signature. + if (isset($dmap[$methName]['signature'])) + { + $sig = $dmap[$methName]['signature']; + list ($ok, $errstr) = $this->verifySignature($m, $sig); + if (!$ok) + { + // Didn't match. + return new xmlrpcresp(0, + $xmlrpcerr['incorrect_params'], + $xmlrpcstr['incorrect_params'] . ": ${errstr}"); + } + } + + $func = $dmap[$methName]['function']; + + if ($sysCall) + { + return call_user_func($func, $this, $m); + } + else + { + return call_user_func($func, $m); + } + } + + function echoInput() + { + global $HTTP_RAW_POST_DATA; + + // a debugging routine: just echos back the input + // packet as a string value + + $r=new xmlrpcresp; + $r->xv=new xmlrpcval( "'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string'); + print $r->serialize(); + } + } +?> |