diff --git a/phpgwapi/inc/class.xmlrpc_client.inc.php b/phpgwapi/inc/class.xmlrpc_client.inc.php new file mode 100644 index 0000000000..fd24db7eff --- /dev/null +++ b/phpgwapi/inc/class.xmlrpc_client.inc.php @@ -0,0 +1,114 @@ + + // xmlrpc.inc,v 1.18 2001/07/06 18:23:57 edmundd + + // License is granted to use or modify this software ("XML-RPC for PHP") + // for commercial or non-commercial use provided the copyright of the author + // is preserved in any distributed or derivative work. + + // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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 AUTHOR 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. + + class xmlrpc_client + { + var $path; + var $server; + var $port; + var $errno; + var $errstring; + var $debug=0; + var $username=""; + var $password=""; + + function xmlrpc_client($path='', $server='', $port=80) + { + $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 send($msg, $timeout=0) + { + // where msg is an xmlrpcmsg + $msg->debug=$this->debug; + return $this->sendPayloadHTTP10( + $msg, + $this->server, $this->port, + $timeout, $this->username, + $this->password + ); + } + + function sendPayloadHTTP10($msg, $server, $port, $timeout=0,$username="", $password="") + { + if($timeout>0) + { + $fp=fsockopen($server, $port,&$this->errno, &$this->errstr, $timeout); + } + else + { + $fp=fsockopen($server, $port,&$this->errno, &$this->errstr); + } + if (!$fp) + { + return 0; + } + // Only create the payload if it was not created previously + if(empty($msg->payload)) + { + $msg->createPayload(); + } + + // thanks to Grant Rauscher + // 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"; + return 0; + } + $resp=$msg->parseResponseFile($fp); + fclose($fp); + return $resp; + } + } +?> diff --git a/phpgwapi/inc/class.xmlrpc_server.inc.php b/phpgwapi/inc/class.xmlrpc_server.inc.php new file mode 100644 index 0000000000..46da0cca18 --- /dev/null +++ b/phpgwapi/inc/class.xmlrpc_server.inc.php @@ -0,0 +1,345 @@ + + // $Id$ + + // License is granted to use or modify this software ("XML-RPC for PHP") + // for commercial or non-commercial use provided the copyright of the author + // is preserved in any distributed or derivative work. + + // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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 AUTHOR 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 = CreateObject('phpgwapi.xmlrpcval'); + $dmap = $server->dmap; + $outAr = array(); + for(reset($dmap); list($key, $val) = each($dmap); ) + { + $outAr[] = CreateObject('phpgwapi.xmlrpcval',$key, 'string'); + } + $dmap = $_xmlrpcs_dmap; + for(reset($dmap); list($key, $val) = each($dmap); ) + { + $outAr[] = CreateObject('phpgwapi.xmlrpcval',$key, 'string'); + } + $v->addArray($outAr); + return CreateObject('phpgwapi.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 "\n"; + if (isset($dmap[$methName])) + { + if ($dmap[$methName]['signature']) + { + $sigs = array(); + $thesigs=$dmap[$methName]['signature']; + for($i=0; $igetParam(0); + $methName = $methName->scalarval(); + if (ereg("^system\.", $methName)) + { + $dmap = $_xmlrpcs_dmap; $sysCall=1; + } + else + { + $dmap = $server->dmap; $sysCall=0; + } + // print "\n"; + if (isset($dmap[$methName])) + { + if ($dmap[$methName]['docstring']) + { + $r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval',$dmap[$methName]['docstring']),'string'); + } + else + { + $r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval'), 'string'); + } + } + else + { + $r = CreateObject('phpgwapi.xmlrpcresp',0,$xmlrpcerr['introspect_unknown'],$xmlrpcstr['introspect_unknown']); + } + return $r; + } + + $_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 + ) + ); + + $_xmlrpc_debuginfo = ''; + function xmlrpc_debugmsg($m) + { + global $_xmlrpc_debuginfo; + $_xmlrpc_debuginfo = $_xmlrpc_debuginfo . $m . "\n"; + } + + /* BEGIN server class */ + class xmlrpc_server + { + var $dmap = array(); + + function xmlrpc_server($dispMap, $serviceNow=1) + { + global $HTTP_RAW_POST_DATA; + // dispMap is a despatch 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 + $this->dmap = $dispMap; + if ($serviceNow) + { + $this->service(); + } + } + + function serializeDebug() + { + global $_xmlrpc_debuginfo; + if ($_xmlrpc_debuginfo != '') + { + return "\n"; + } + else + { + return ''; + } + } + + function service() + { + $r = $this->parseRequest(); + $payload = "\n" . $this->serializeDebug() . $r->serialize(); + Header("Content-type: text/xml\r\nContent-length: " . strlen($payload)); + print $payload; + } + + function verifySignature($in, $sig) + { + for($i=0; $igetNumParams()+1) + { + $itsOK = 1; + for($n=0; $n<$in->getNumParams(); $n++) + { + $p = $in->getParam($n); + // print "\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 = CreateObject('phpgwapi.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 = CreateObject('phpgwapi.xmlrpcmsg',$_xh[$parser]['method']); + // now add parameters in + for($i=0; $i\n"; + $plist .= "$i - " . $_xh[$parser]['params'][$i]. " \n"; + $code = '$m->addParam(' . $_xh[$parser]['params'][$i] . ');'; + $code = ereg_replace(',,',",'',",$code); + eval($code); + } + // uncomment this to really see what the server's getting! + // xmlrpc_debugmsg($plist); + // now to deal with the method + $methName = $_xh[$parser]['method']; + if (ereg("^system\.", $methName)) + { + $dmap = $_xmlrpcs_dmap; $sysCall=1; + } + else + { + $dmap = $this->dmap; $sysCall=0; + } + if (isset($dmap[$methName]['function'])) + { + // dispatch if exists + if (isset($dmap[$methName]['signature'])) + { + $sr = $this->verifySignature($m, $dmap[$methName]['signature'] ); + } + if ( (!isset($dmap[$methName]['signature'])) || $sr[0]) + { + // if no signature or correct signature + if ($sysCall) + { + $code = '$r=' . $dmap[$methName]['function'] . '($this, $m);'; + $code = ereg_replace(',,',",'',",$code); + eval($code); + } + else + { + $code = '$r=' . $dmap[$methName]['function'] . '($m);'; + $code = ereg_replace(',,',",'',",$code); + eval($code); + } + } + else + { + $r= CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval'),$xmlrpcerr['incorrect_params'],$xmlrpcstr['incorrect_params'].': ' . $sr[1] + ); + } + } + else + { + // else prepare error response + $r= CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval'),$xmlrpcerr['unknown_method'],$xmlrpcstr['unknown_method']); + } + } + return $r; + } + + function echoInput() + { + global $HTTP_RAW_POST_DATA; + + // a debugging routine: just echos back the input + // packet as a string value + + $r = CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',"'Aha said I: '" . $HTTP_RAW_POST_DATA,'string')); + echo $r->serialize(); + } + } +?> diff --git a/phpgwapi/inc/class.xmlrpcmsg.inc.php b/phpgwapi/inc/class.xmlrpcmsg.inc.php new file mode 100644 index 0000000000..78d5df9101 --- /dev/null +++ b/phpgwapi/inc/class.xmlrpcmsg.inc.php @@ -0,0 +1,192 @@ + + // xmlrpc.inc,v 1.18 2001/07/06 18:23:57 edmundd + + // License is granted to use or modify this software ("XML-RPC for PHP") + // for commercial or non-commercial use provided the copyright of the author + // is preserved in any distributed or derivative work. + + // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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 AUTHOR 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. + + 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; $iaddParam($pars[$i]); + } + } + } + + function xml_header() + { + return "\n\n"; + } + + function xml_footer() + { + return "\n"; + } + + function createPayload() + { + $this->payload=$this->xml_header(); + $this->payload.="" . $this->methodname . "\n"; + // if (sizeof($this->params)) { + $this->payload.="\n"; + for($i=0; $iparams); $i++) + { + $p=$this->params[$i]; + $this->payload.="\n" . $p->serialize() . "\n"; + } + $this->payload.="\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'] = ''; + + 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 = CreateObject('phpgwapi.xmlrpcval'); + + $hdrfnd=0; + if ($this->debug) + { + print "
---GOT---\n" . htmlspecialchars($data) . "\n---END---\n
"; + } + // 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 = CreateObject('phpgwapi.xmlrpcresp',0, $xmlrpcerr['http_error'], + $xmlrpcstr['http_error'] . " (" . $errstr . ")"); + xml_parser_free($parser); + return $r; + } + // gotta get rid of headers here + if ((!$hdrfnd) && ereg("^(.*)\r\n\r\n",$data,$_xh[$parser]['ha'])) + { + $data=ereg_replace("^.*\r\n\r\n", "", $data); + $hdrfnd=1; + } + + if (!xml_parse($parser, $data, sizeof($data))) + { + // thanks to Peter Kocks + 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 = CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval'), $xmlrpcerr['invalid_return'],$xmlrpcstr['invalid_return']); + xml_parser_free($parser); + return $r; + } + xml_parser_free($parser); + if ($this->debug) + { + print "
---EVALING---[" . 
+					strlen($_xh[$parser]['st']) . " chars]---\n" . 
+					htmlspecialchars($_xh[$parser]['st']) . ";\n---END---
"; + } + 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 = CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval'), $xmlrpcerr['invalid_return'],$xmlrpcstr['invalid_return']); + } + else + { + $code = '$v=' . $_xh[$parser]['st'] . '; $allOK=1;'; + $code = ereg_replace(',,',",'',",$code); + eval($code); + if ($_xh[$parser]['isf']) + { + $f = $v->structmem("faultCode"); + $fs = $v->structmem("faultString"); + $r = CreateObject('phpgwapi.xmlrpcresp',$v, $f->scalarval(), $fs->scalarval()); + } + else + { + $r = CreateObject('phpgwapi.xmlrpcresp',$v); + } + } + $r->hdrs=split("\r?\n", $_xh[$parser]['ha'][1]); + return $r; + } + } +?> diff --git a/phpgwapi/inc/class.xmlrpcresp.inc.php b/phpgwapi/inc/class.xmlrpcresp.inc.php new file mode 100644 index 0000000000..b63a6ab902 --- /dev/null +++ b/phpgwapi/inc/class.xmlrpcresp.inc.php @@ -0,0 +1,95 @@ + + // xmlrpc.inc,v 1.18 2001/07/06 18:23:57 edmundd + + // License is granted to use or modify this software ("XML-RPC for PHP") + // for commercial or non-commercial use provided the copyright of the author + // is preserved in any distributed or derivative work. + + // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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 AUTHOR 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. + + class xmlrpcresp + { + var $xv = array(); + var $fn; + var $fs; + var $hdrs; + + function xmlrpcresp($val='', $fcode=0, $fstr='') + { + if ($fcode!=0) + { + $this->fn = $fcode; + $this->fs = htmlspecialchars($fstr); + } + else + { + if($val) + { + $this->xv = $val; + } + $this->fn = 0; + } + } + + function faultCode() + { + if (isset($this->fn)) + { + return $this->fn; + } + else + { + return 0; + } + } + + function faultString() + { + return $this->fs; + } + + function value() + { + return $this->xv; + } + + function serialize() + { + $rs="\n"; + if ($this->fn) + { + $rs .= " + + + + faultCode + " . $this->fn . " + + + faultString + " . $this->fs . " + + + +"; + } + else + { + $rs .= "\n\n" . @$this->xv->serialize() . "\n"; + } + $rs.="\n"; + return $rs; + } + } +?> diff --git a/phpgwapi/inc/class.xmlrpcval.inc.php b/phpgwapi/inc/class.xmlrpcval.inc.php new file mode 100644 index 0000000000..a83226f156 --- /dev/null +++ b/phpgwapi/inc/class.xmlrpcval.inc.php @@ -0,0 +1,315 @@ + + // xmlrpc.inc,v 1.18 2001/07/06 18:23:57 edmundd + + // License is granted to use or modify this software ("XML-RPC for PHP") + // for commercial or non-commercial use provided the copyright of the author + // is preserved in any distributed or derivative work. + + // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED 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 AUTHOR 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. + + 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 "xmlrpcval: scalar can have only one value
"; + return 0; + } + $typeof=$xmlrpcTypes[$type]; + if ($typeof!=1) + { + echo "xmlrpcval: not a scalar type (${typeof})
"; + 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[] = CreateObject('phpgwapi.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 "xmlrpcval: already initialized as a [" . $this->kindOf() . "]
"; + return 0; + } + + $this->mytype=$xmlrpcTypes["array"]; + $this->me["array"]=$vals; + return 1; + } + + function addStruct($vals) + { + global $xmlrpcTypes; + if ($this->mytype!=0) + { + echo "xmlrpcval: already initialized as a [" . $this->kindOf() . "]
"; + 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
"; + if ($key == 'array') + { + while (list($key2,$val2) = each($val)) + { + echo "-- $key2 => $val2
"; + } + } + } + } + + 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; + + if($typ) + { + switch($xmlrpcTypes[$typ]) + { + case 3: + // struct + $rs.="\n"; + reset($val); + while(list($key2, $val2)=each($val)) + { + $rs .= "${key2}\n"; + $rs .= $this->serializeval($val2); + $rs .= "\n"; + } + $rs.=""; + break; + case 2: + // array + $rs.="\n\n"; + for($i=0; $iserializeval($val[$i]); + } + $rs.="\n"; + break; + case 1: + switch ($typ) + { + case $xmlrpcBase64: + $rs.="<${typ}>" . base64_encode($val) . ""; + break; + case $xmlrpcBoolean: + $rs.="<${typ}>" . ($val ? "1" : "0") . ""; + break; + case $xmlrpcString: + $rs.="<${typ}>" . htmlspecialchars($val). ""; + break; + default: + $rs.="<${typ}>${val}"; + } + 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.=""; + $rs.=$this->serializedata($typ, $val); + $rs.="\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)) + { + foreach ($b as $id => $cont) + { + $b[$id] = $cont->scalarval(); + } + } + + // add support for structures directly encoding php objects + if (is_object($b)) + { + $t = get_object_vars($b); + foreach ($t as $id => $cont) + { + $t[$id] = $cont->scalarval(); + } + foreach ($t as $id => $cont) + { + 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); + } + } +?>