2001-08-08 01:04:05 +02:00
< ? php
// by Edd Dumbill (C) 1999-2001
// <edd@usefulinc.com>
// 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.
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' );
}
}
2001-08-09 04:54:56 +02:00
define ( 'xmlrpcI4' , 'i4' );
define ( 'xmlrpcInt' , 'int' );
define ( 'xmlrpcBoolean' , 'boolean' );
define ( 'xmlrpcDouble' , 'double' );
define ( 'xmlrpcString' , 'string' );
define ( 'xmlrpcDateTime' , 'dateTime.iso8601' );
define ( 'xmlrpcBase64' , 'base64' );
define ( 'xmlrpcArray' , 'array' );
define ( 'xmlrpcStruct' , 'struct' );
$GLOBALS [ 'xmlrpcTypes' ] = array (
xmlrpcI4 => 1 ,
xmlrpcInt => 1 ,
xmlrpcBoolean => 1 ,
xmlrpcString => 1 ,
xmlrpcDouble => 1 ,
xmlrpcDateTime => 1 ,
xmlrpcBase64 => 1 ,
xmlrpcArray => 2 ,
xmlrpcStruct => 3
2001-08-08 01:04:05 +02:00
);
2001-08-09 04:54:56 +02:00
$GLOBALS [ 'xmlEntities' ] = array (
2001-08-08 01:04:05 +02:00
'amp' => '&' ,
'quot' => '"' ,
'lt' => '<' ,
'gt' => '>' ,
'apos' => " ' "
);
2001-08-09 04:54:56 +02:00
$GLOBALS [ 'xmlrpcerr' ][ 'unknown_method' ] = 1 ;
$GLOBALS [ 'xmlrpcstr' ][ 'unknown_method' ] = 'Unknown method' ;
$GLOBALS [ 'xmlrpcerr' ][ 'invalid_return' ] = 2 ;
$GLOBALS [ 'xmlrpcstr' ][ 'invalid_return' ] = 'Invalid return payload: enabling debugging to examine incoming payload' ;
$GLOBALS [ 'xmlrpcerr' ][ 'incorrect_params' ] = 3 ;
$GLOBALS [ 'xmlrpcstr' ][ 'incorrect_params' ] = 'Incorrect parameters passed to method' ;
$GLOBALS [ 'xmlrpcerr' ][ 'introspect_unknown' ] = 4 ;
$GLOBALS [ 'xmlrpcstr' ][ 'introspect_unknown' ] = " Can't introspect: method unknown " ;
$GLOBALS [ 'xmlrpcerr' ][ 'http_error' ] = 5 ;
$GLOBALS [ 'xmlrpcstr' ][ 'http_error' ] = " Didn't receive 200 OK from remote server. " ;
2001-08-30 02:29:55 +02:00
$GLOBALS [ 'xmlrpcerr' ][ 'no_data' ] = 6 ;
$GLOBALS [ 'xmlrpcstr' ][ 'no_data' ] = 'No data received from server.' ;
$GLOBALS [ 'xmlrpcerr' ][ 'no_ssl' ] = 7 ;
$GLOBALS [ 'xmlrpcstr' ][ 'no_ssl' ] = 'No SSL support compiled in.' ;
$GLOBALS [ 'xmlrpcerr' ][ 'curl_fail' ] = 8 ;
$GLOBALS [ 'xmlrpcstr' ][ 'curl_fail' ] = 'CURL error' ;
2001-08-08 01:04:05 +02:00
2001-08-09 04:54:56 +02:00
$GLOBALS [ 'xmlrpc_defencoding' ] = 'UTF-8' ;
2001-08-08 01:04:05 +02:00
2001-08-09 04:54:56 +02:00
$GLOBALS [ 'xmlrpcName' ] = 'XML-RPC for PHP' ;
$GLOBALS [ 'xmlrpcVersion' ] = '1.0b9' ;
2001-08-08 01:04:05 +02:00
// let user errors start at 800
2001-08-09 04:54:56 +02:00
$GLOBALS [ 'xmlrpcerruser' ] = 800 ;
2001-08-08 01:04:05 +02:00
// let XML parse errors start at 100
2001-08-09 04:54:56 +02:00
$GLOBALS [ 'xmlrpcerrxml' ] = 100 ;
2001-08-08 01:04:05 +02:00
// formulate backslashes for escaping regexp
2001-08-09 04:54:56 +02:00
$GLOBALS [ 'xmlrpc_backslash' ] = chr ( 92 ) . chr ( 92 );
2001-08-08 01:04:05 +02:00
// 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
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ] = array ();
2001-08-08 01:04:05 +02:00
function xmlrpc_entity_decode ( $string )
{
2001-08-09 04:54:56 +02:00
$top = split ( '&' , $string );
2001-08-08 01:04:05 +02:00
$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 ;
}
function xmlrpc_lookup_entity ( $ent )
{
2001-08-09 04:54:56 +02:00
if ( isset ( $GLOBALS [ 'xmlEntities' ][ strtolower ( $ent )]))
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
return $GLOBALS [ 'xmlEntities' ][ strtolower ( $ent )];
2001-08-08 01:04:05 +02:00
}
if ( ereg ( " ^#([0-9]+) $ " , $ent , $regs ))
{
return chr ( $regs [ 1 ]);
}
return '?' ;
}
function xmlrpc_se ( $parser , $name , $attrs )
{
switch ( $name )
{
case 'STRUCT' :
case 'ARRAY' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= 'array(' ;
$GLOBALS [ '_xh' ][ $parser ][ 'cm' ] ++ ;
2001-08-08 01:04:05 +02:00
// 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
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 0 ;
2001-08-08 01:04:05 +02:00
break ;
case 'NAME' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= " ' " ;
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = '' ;
2001-08-08 01:04:05 +02:00
break ;
case 'FAULT' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'isf' ] = 1 ;
2001-08-08 01:04:05 +02:00
break ;
case 'PARAM' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] = '' ;
2001-08-08 01:04:05 +02:00
break ;
case 'VALUE' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= " CreateObject('phpgwapi.xmlrpcval', " ;
$GLOBALS [ '_xh' ][ $parser ][ 'vt' ] = xmlrpcString ;
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = '' ;
$GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 0 ;
$GLOBALS [ '_xh' ][ $parser ][ 'lv' ] = 1 ;
2001-08-08 01:04:05 +02:00
// 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' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = '' ; // reset the accumulator
2001-08-08 01:04:05 +02:00
if ( $name == 'DATETIME.ISO8601' || $name == 'STRING' )
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 1 ;
2001-08-08 01:04:05 +02:00
if ( $name == 'DATETIME.ISO8601' )
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'vt' ] = xmlrpcDateTime ;
2001-08-08 01:04:05 +02:00
}
}
elseif ( $name == 'BASE64' )
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 2 ;
2001-08-08 01:04:05 +02:00
}
else
{
// No quoting is required here -- but
// at the end of the element we must check
// for data format errors.
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 0 ;
2001-08-08 01:04:05 +02:00
}
break ;
case 'MEMBER' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = '' ;
2001-08-08 01:04:05 +02:00
break ;
default :
break ;
}
if ( $name != 'VALUE' )
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'lv' ] = 0 ;
2001-08-08 01:04:05 +02:00
}
}
function xmlrpc_ee ( $parser , $name )
{
switch ( $name )
{
case 'STRUCT' :
case 'ARRAY' :
2001-08-09 04:54:56 +02:00
if ( $GLOBALS [ '_xh' ][ $parser ][ 'cm' ] && substr ( $GLOBALS [ '_xh' ][ $parser ][ 'st' ], - 1 ) == ',' )
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] = substr ( $GLOBALS [ '_xh' ][ $parser ][ 'st' ], 0 , - 1 );
2001-08-08 01:04:05 +02:00
}
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= ')' ;
$GLOBALS [ '_xh' ][ $parser ][ 'vt' ] = strtolower ( $name );
$GLOBALS [ '_xh' ][ $parser ][ 'cm' ] -- ;
2001-08-08 01:04:05 +02:00
break ;
case 'NAME' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= $GLOBALS [ '_xh' ][ $parser ][ 'ac' ] . " ' => " ;
2001-08-08 01:04:05 +02:00
break ;
case 'BOOLEAN' :
// special case here: we translate boolean 1 or 0 into PHP
// constants true or false
2001-08-09 04:54:56 +02:00
if ( $GLOBALS [ '_xh' ][ $parser ][ 'ac' ] == '1' )
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = 'True' ;
2001-08-08 01:04:05 +02:00
}
else
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = 'false' ;
2001-08-08 01:04:05 +02:00
}
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'vt' ] = strtolower ( $name );
2001-08-08 01:04:05 +02:00
// Drop through intentionally.
case 'I4' :
case 'INT' :
case 'STRING' :
case 'DOUBLE' :
case 'DATETIME.ISO8601' :
case 'BASE64' :
2001-08-09 04:54:56 +02:00
if ( $GLOBALS [ '_xh' ][ $parser ][ 'qt' ] == 1 )
2001-08-08 01:04:05 +02:00
{
// we use double quotes rather than single so backslashification works OK
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= '"' . $GLOBALS [ '_xh' ][ $parser ][ 'ac' ] . '"' ;
2001-08-08 01:04:05 +02:00
}
2001-08-09 04:54:56 +02:00
elseif ( $GLOBALS [ '_xh' ][ $parser ][ 'qt' ] == 2 )
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= " base64_decode(' " . $GLOBALS [ '_xh' ][ $parser ][ 'ac' ] . " ') " ;
2001-08-08 01:04:05 +02:00
}
else if ( $name == 'BOOLEAN' )
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= $GLOBALS [ '_xh' ][ $parser ][ 'ac' ];
2001-08-08 01:04:05 +02:00
}
else
{
// we have an I4, INT or a DOUBLE
// we must check that only 0123456789-.<space> are characters here
2001-08-09 04:54:56 +02:00
if ( ! ereg ( " ^ \ -?[0123456789 \t \ .]+ $ " , $GLOBALS [ '_xh' ][ $parser ][ 'ac' ]))
2001-08-08 01:04:05 +02:00
{
// TODO: find a better way of throwing an error
// than this!
2001-08-09 04:54:56 +02:00
error_log ( 'XML-RPC: non numeric value received in INT or DOUBLE' );
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= 'ERROR_NON_NUMERIC_FOUND' ;
2001-08-08 01:04:05 +02:00
}
else
{
// it's ok, add it on
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= $GLOBALS [ '_xh' ][ $parser ][ 'ac' ];
2001-08-08 01:04:05 +02:00
}
}
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = " " ; $GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 0 ;
$GLOBALS [ '_xh' ][ $parser ][ 'lv' ] = 3 ; // indicate we've found a value
2001-08-08 01:04:05 +02:00
break ;
case 'VALUE' :
// deal with a string value
2001-08-09 04:54:56 +02:00
if ( strlen ( $GLOBALS [ '_xh' ][ $parser ][ 'ac' ]) > 0 &&
$GLOBALS [ '_xh' ][ $parser ][ 'vt' ] == xmlrpcString )
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= '"' . $GLOBALS [ '_xh' ][ $parser ][ 'ac' ] . '"' ;
2001-08-08 01:04:05 +02:00
}
// This if() detects if no scalar was inside <VALUE></VALUE>
// and pads an empty "".
2001-08-09 04:54:56 +02:00
if ( $GLOBALS [ '_xh' ][ $parser ][ 'st' ][ strlen ( $GLOBALS [ '_xh' ][ $parser ][ 'st' ]) - 1 ] == '(' )
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= '""' ;
2001-08-08 01:04:05 +02:00
}
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= " , ' " . $GLOBALS [ '_xh' ][ $parser ][ 'vt' ] . " ') " ;
if ( $GLOBALS [ '_xh' ][ $parser ][ 'cm' ])
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= " , " ;
2001-08-08 01:04:05 +02:00
}
break ;
case 'MEMBER' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = " " ;
$GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 0 ;
break ;
2001-08-08 01:04:05 +02:00
case 'DATA' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = " " ;
$GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 0 ;
2001-08-08 01:04:05 +02:00
break ;
case 'PARAM' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'params' ][] = $GLOBALS [ '_xh' ][ $parser ][ 'st' ];
2001-08-08 01:04:05 +02:00
break ;
case 'METHODNAME' :
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'method' ] = ereg_replace ( " ^[ \n \r \t ]+ " , " " , $GLOBALS [ '_xh' ][ $parser ][ 'ac' ]);
2001-08-08 01:04:05 +02:00
break ;
case 'BOOLEAN' :
// special case here: we translate boolean 1 or 0 into PHP
// constants true or false
2001-08-09 04:54:56 +02:00
if ( $GLOBALS [ '_xh' ][ $parser ][ 'ac' ] == '1' )
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = 'True' ;
2001-08-08 01:04:05 +02:00
}
else
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = 'false' ;
2001-08-08 01:04:05 +02:00
}
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'vt' ] = strtolower ( $name );
2001-08-08 01:04:05 +02:00
break ;
default :
break ;
}
// if it's a valid type name, set the type
2001-08-09 04:54:56 +02:00
if ( isset ( $GLOBALS [ 'xmlrpcTypes' ][ strtolower ( $name )]))
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'vt' ] = strtolower ( $name );
2001-08-08 01:04:05 +02:00
}
}
function xmlrpc_cd ( $parser , $data )
{
//if (ereg("^[\n\r \t]+$", $data)) return;
// print "adding [${data}]\n";
2001-08-09 04:54:56 +02:00
if ( $GLOBALS [ '_xh' ][ $parser ][ 'lv' ] != 3 )
2001-08-08 01:04:05 +02:00
{
// "lookforvalue==3" means that we've found an entire value
// and should discard any further character data
2001-08-09 04:54:56 +02:00
if ( $GLOBALS [ '_xh' ][ $parser ][ 'lv' ] == 1 )
2001-08-08 01:04:05 +02:00
{
// if we've found text and we're just in a <value> then
// turn quoting on, as this will be a string
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 1 ;
2001-08-08 01:04:05 +02:00
// and say we've found a value
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'lv' ] = 2 ;
2001-08-08 01:04:05 +02:00
}
2001-08-09 04:54:56 +02:00
if ( isset ( $GLOBALS [ '_xh' ][ $parser ][ 'qt' ]) && $GLOBALS [ '_xh' ][ $parser ][ 'qt' ])
2001-08-08 01:04:05 +02:00
{
// quoted string: replace characters that eval would
// do special things with
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] .= str_replace ( '$' , '\$' ,
2001-08-08 01:04:05 +02:00
str_replace ( '"' , '\"' ,
2001-08-09 17:51:06 +02:00
str_replace ( chr ( 92 ), $GLOBALS [ 'xmlrpc_backslash' ], $data )));
2001-08-08 01:04:05 +02:00
}
else
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] .= $data ;
2001-08-08 01:04:05 +02:00
}
}
}
function xmlrpc_dh ( $parser , $data )
{
2001-08-09 04:54:56 +02:00
if ( substr ( $data , 0 , 1 ) == '&' && substr ( $data , - 1 , 1 ) == ';' )
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
if ( $GLOBALS [ '_xh' ][ $parser ][ 'lv' ] == 1 )
2001-08-08 01:04:05 +02:00
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 1 ;
$GLOBALS [ '_xh' ][ $parser ][ 'lv' ] = 2 ;
2001-08-08 01:04:05 +02:00
}
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] .= $data ;
2001-08-08 01:04:05 +02:00
}
}
// 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 xmlrpc_decode ( $xmlrpc_val )
{
2001-08-09 01:28:03 +02:00
$kind = @ $xmlrpc_val -> kindOf ();
2001-08-08 01:04:05 +02:00
if ( $kind == " scalar " )
{
return $xmlrpc_val -> scalarval ();
}
elseif ( $kind == " array " )
{
$size = $xmlrpc_val -> arraysize ();
$arr = array ();
for ( $i = 0 ; $i < $size ; $i ++ )
{
$arr [] = 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 ] = 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 xmlrpc_encode ( $php_val )
{
$type = gettype ( $php_val );
$xmlrpc_val = CreateObject ( 'phpgwapi.xmlrpcval' );
switch ( $type )
{
case " array " :
case " object " :
$arr = array ();
while ( list ( $k , $v ) = each ( $php_val ))
{
$arr [ $k ] = xmlrpc_encode ( $v );
}
$xmlrpc_val -> addStruct ( $arr );
break ;
case " integer " :
2001-08-09 04:54:56 +02:00
$xmlrpc_val -> addScalar ( $php_val , xmlrpcInt );
2001-08-08 01:04:05 +02:00
break ;
case " double " :
2001-08-09 04:54:56 +02:00
$xmlrpc_val -> addScalar ( $php_val , xmlrpcDouble );
2001-08-08 01:04:05 +02:00
break ;
case " string " :
2001-08-09 04:54:56 +02:00
$xmlrpc_val -> addScalar ( $php_val , xmlrpcString );
2001-08-08 01:04:05 +02:00
break ;
// <G_Giunta_2001-02-29>
// Add support for encoding/decoding of booleans, since they are supported in PHP
case " boolean " :
2001-08-09 04:54:56 +02:00
$xmlrpc_val -> addScalar ( $php_val , xmlrpcBoolean );
2001-08-08 01:04:05 +02:00
break ;
// </G_Giunta_2001-02-29>
case " unknown type " :
default :
$xmlrpc_val = false ;
break ;
}
return $xmlrpc_val ;
}
2001-08-09 01:28:03 +02:00
// listMethods: either a string, or nothing
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xmlrpcs_listMethods_sig' ] = array ( array ( xmlrpcArray , xmlrpcString ), array ( xmlrpcArray ));
$GLOBALS [ '_xmlrpcs_listMethods_doc' ] = 'This method lists all the methods that the XML-RPC server knows how to dispatch' ;
2001-08-09 01:28:03 +02:00
function _xmlrpcs_listMethods ( $server , $m )
{
$v = CreateObject ( 'phpgwapi.xmlrpcval' );
$dmap = $server -> dmap ;
$outAr = array ();
for ( reset ( $dmap ); list ( $key , $val ) = each ( $dmap ); )
{
$outAr [] = CreateObject ( 'phpgwapi.xmlrpcval' , $key , 'string' );
}
2001-08-09 04:54:56 +02:00
$dmap = $GLOBALS [ '_xmlrpcs_dmap' ];
2001-08-09 01:28:03 +02:00
for ( reset ( $dmap ); list ( $key , $val ) = each ( $dmap ); )
{
$outAr [] = CreateObject ( 'phpgwapi.xmlrpcval' , $key , 'string' );
}
$v -> addArray ( $outAr );
return CreateObject ( 'phpgwapi.xmlrpcresp' , $v );
}
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xmlrpcs_methodSignature_sig' ] = array ( array ( xmlrpcArray , xmlrpcString ));
$GLOBALS [ '_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)' ;
2001-08-09 01:28:03 +02:00
function _xmlrpcs_methodSignature ( $server , $m )
{
$methName = $m -> getParam ( 0 );
$methName = $methName -> scalarval ();
if ( ereg ( " ^system \ . " , $methName ))
{
2001-08-09 04:54:56 +02:00
$dmap = $GLOBALS [ '_xmlrpcs_dmap' ];
2001-08-09 01:28:03 +02:00
$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 [] = CreateObject ( 'phpgwapi.xmlrpcval' , $inSig [ $j ], 'string' );
}
$sigs [] = CreateObject ( 'phpgwapi.xmlrpcval' , $cursig , 'array' );
}
$r = CreateObject ( 'phpgwapi.xmlrpcresp' , CreateObject ( 'phpgwapi.xmlrpcval' , $sigs , 'array' ));
}
else
{
$r = CreateObject ( 'phpgwapi.xmlrpcresp' , CreateObject ( 'phpgwapi.xmlrpcval' , 'undef' , 'string' ));
}
}
else
{
2001-08-09 04:54:56 +02:00
$r = CreateObject ( 'phpgwapi.xmlrpcresp' , 0 , $GLOBALS [ 'xmlrpcerr' ][ 'introspect_unknown' ], $GLOBALS [ 'xmlrpcstr' ][ 'introspect_unknown' ]);
2001-08-09 01:28:03 +02:00
}
return $r ;
}
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xmlrpcs_methodHelp_sig' ] = array ( array ( xmlrpcString , xmlrpcString ));
$GLOBALS [ '_xmlrpcs_methodHelp_doc' ] = 'Returns help text if defined for the method passed, otherwise returns an empty string' ;
2001-08-09 01:28:03 +02:00
function _xmlrpcs_methodHelp ( $server , $m )
{
$methName = $m -> getParam ( 0 );
$methName = $methName -> scalarval ();
if ( ereg ( " ^system \ . " , $methName ))
{
2001-08-09 04:54:56 +02:00
$dmap = $GLOBALS [ '_xmlrpcs_dmap' ];
$sysCall = 1 ;
2001-08-09 01:28:03 +02:00
}
else
{
2001-08-09 04:54:56 +02:00
$dmap = $server -> dmap ;
$sysCall = 0 ;
2001-08-09 01:28:03 +02:00
}
// print "<!-- ${methName} -->\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
{
2001-08-09 04:54:56 +02:00
$r = CreateObject ( 'phpgwapi.xmlrpcresp' , 0 , $GLOBALS [ 'xmlrpcerr' ][ 'introspect_unknown' ], $GLOBALS [ 'xmlrpcstr' ][ 'introspect_unknown' ]);
2001-08-09 01:28:03 +02:00
}
return $r ;
}
2001-08-20 01:55:58 +02:00
/*
2001-08-09 17:51:06 +02:00
$GLOBALS [ '_xmlrpcs_listApps_sig' ] = array ( array ( xmlrpcString , xmlrpcString ));
$GLOBALS [ '_xmlrpcs_listApps_doc' ] = 'Returns a list of installed phpgw apps' ;
2001-08-20 01:55:58 +02:00
function _xmlrpcs_listApps ( $server , $m )
2001-08-09 17:51:06 +02:00
{
2001-08-20 01:55:58 +02:00
$m -> getParam ( 0 );
2001-08-09 17:51:06 +02:00
$GLOBALS [ 'phpgw' ] -> db -> query ( " SELECT * FROM phpgw_applications WHERE app_enabled<3 " , __LINE__ , __FILE__ );
if ( $GLOBALS [ 'phpgw' ] -> db -> num_rows ())
{
while ( $GLOBALS [ 'phpgw' ] -> db -> next_record ())
{
$name = $GLOBALS [ 'phpgw' ] -> db -> f ( 'app_name' );
$title = $GLOBALS [ 'phpgw' ] -> db -> f ( 'app_title' );
$status = $GLOBALS [ 'phpgw' ] -> db -> f ( 'app_enabled' );
$apps [ $name ] = array (
'title' => $title ,
'name' => $name ,
'status' => $status
);
}
}
2001-08-20 01:55:58 +02:00
return CreateObject ( 'phpgwapi.xmlrpcresp' , CreateObject ( 'phpgwapi.xmlrpcval' , $apps , 'struct' ));
2001-08-09 17:51:06 +02:00
}
2001-08-20 01:55:58 +02:00
$GLOBALS [ '_xmlrpcs_listUsers_sig' ] = array ( array ( xmlrpcString , xmlrpcString ));
$GLOBALS [ '_xmlrpcs_listUsers_doc' ] = 'Returns a list of phpgw users' ;
function _xmlrpcs_listUsers ( $server , $m )
{
$m -> getParam ( 0 );
$accounts = $GLOBALS [ 'phpgw' ] -> accounts -> get_list ( 'accounts' );
while ( list ( $key , $acct ) = @ each ( $accounts ))
{
$r = CreateObject ( 'phpgwapi.xmlrpcval' , 'account_lid' , 'string' );
$s = CreateObject ( 'phpgwapi.xmlrpcval' , $acct [ 'account_lid' ], 'string' );
$acct_data [] = $r ;
$acct_data [] = $s ;
}
return CreateObject ( 'phpgwapi.xmlrpcresp' , CreateObject ( 'phpgwapi.xmlrpcval' , $acct_data , 'struct' ));
}
*/
2001-08-20 18:33:26 +02:00
$GLOBALS [ '_xmlrpcs_login_sig' ] = array ( array ( xmlrpcStruct , xmlrpcStruct ));
2001-08-20 02:28:36 +02:00
$GLOBALS [ '_xmlrpcs_login_doc' ] = 'phpGroupWare client or server login via XML-RPC' ;
2001-08-20 01:55:58 +02:00
function _xmlrpcs_login ( $server , $m )
2001-08-13 18:24:03 +02:00
{
2001-08-20 18:33:26 +02:00
$rdata = $m -> getParam ( 0 );
$data = $rdata -> scalarval ();
2001-08-22 22:01:05 +02:00
if ( $data [ 'server_name' ])
{
$server_name = $data [ 'server_name' ] -> scalarval ();
}
2001-08-27 11:42:33 +02:00
if ( $data [ 'domain' ])
{
$domain = $data [ 'domain' ] -> scalarval ();
}
2001-08-20 18:33:26 +02:00
$username = $data [ 'username' ] -> scalarval ();
$password = $data [ 'password' ] -> scalarval ();
2001-08-13 18:24:03 +02:00
2001-08-27 11:42:33 +02:00
if ( $server_name )
2001-08-15 05:54:15 +02:00
{
2001-08-20 18:33:26 +02:00
list ( $sessionid , $kp3 ) = $GLOBALS [ 'phpgw' ] -> session -> create_server ( $username . '@' . $server_name , $password );
2001-08-15 05:54:15 +02:00
}
else
{
2001-08-27 11:42:33 +02:00
if ( $domain )
2001-08-20 18:33:26 +02:00
{
2001-08-27 11:42:33 +02:00
$user = $username . '@' . $domain ;
2001-08-20 18:33:26 +02:00
}
else
{
$user = $username ;
}
2001-08-22 22:01:05 +02:00
$sessionid = $GLOBALS [ 'phpgw' ] -> session -> create ( $user , $password );
$kp3 = $GLOBALS [ 'phpgw' ] -> session -> kp3 ;
2001-08-27 11:42:33 +02:00
$domain = $GLOBALS [ 'phpgw' ] -> session -> account_domain ;
2001-08-15 05:54:15 +02:00
}
2001-08-20 01:55:58 +02:00
if ( $sessionid && $kp3 )
2001-08-13 18:24:03 +02:00
{
2001-08-27 11:42:33 +02:00
$rtrn [ 'domain' ] = CreateObject ( 'phpgwapi.xmlrpcval' , $domain , 'string' );
2001-08-20 18:33:26 +02:00
$rtrn [ 'sessionid' ] = CreateObject ( 'phpgwapi.xmlrpcval' , $sessionid , 'string' );
$rtrn [ 'kp3' ] = CreateObject ( 'phpgwapi.xmlrpcval' , $kp3 , 'string' );
2001-08-13 18:24:03 +02:00
}
else
{
2001-08-20 18:33:26 +02:00
$rtrn [ 'GOAWAY' ] = CreateObject ( 'phpgwapi.xmlrpcval' , 'XOXO' , 'string' );
2001-08-13 18:24:03 +02:00
}
2001-08-20 01:55:58 +02:00
return CreateObject ( 'phpgwapi.xmlrpcresp' , CreateObject ( 'phpgwapi.xmlrpcval' , $rtrn , 'struct' ));
2001-08-13 18:24:03 +02:00
}
2001-08-20 18:33:26 +02:00
$GLOBALS [ '_xmlrpcs_logout_sig' ] = array ( array ( xmlrpcStruct , xmlrpcStruct ));
2001-08-20 02:28:36 +02:00
$GLOBALS [ '_xmlrpcs_logout_doc' ] = 'phpGroupWare client or server logout via XML-RPC' ;
function _xmlrpcs_logout ( $server , $m )
{
2001-08-20 18:33:26 +02:00
$rdata = $m -> getParam ( 0 );
$data = $rdata -> scalarval ();
$sessionid = $data [ 'sessionid' ] -> scalarval ();
$kp3 = $data [ 'kp3' ] -> scalarval ();
2001-08-20 02:28:36 +02:00
2001-08-23 04:54:25 +02:00
$later = $GLOBALS [ 'phpgw' ] -> session -> destroy ( $sessionid , $kp3 );
2001-08-20 02:28:36 +02:00
if ( $later )
{
2001-08-20 18:33:26 +02:00
$rtrn [ 'GOODBYE' ] = CreateObject ( 'phpgwapi.xmlrpcval' , 'XOXO' , 'string' );
2001-08-20 02:28:36 +02:00
}
else
{
2001-08-20 18:33:26 +02:00
/* This never happens, yet */
$rtrn [ 'OOPS' ] = CreateObject ( 'phpgwapi.xmlrpcval' , 'WHAT?' , 'string' );
2001-08-20 02:28:36 +02:00
}
return CreateObject ( 'phpgwapi.xmlrpcresp' , CreateObject ( 'phpgwapi.xmlrpcval' , $rtrn , 'struct' ));
}
2001-08-20 01:55:58 +02:00
/*
2001-08-09 17:51:06 +02:00
$GLOBALS [ '_xmlrpcs_dmap' ] = array (
2001-08-09 01:28:03 +02:00
'system.listMethods' => array (
'function' => '_xmlrpcs_listMethods' ,
2001-08-09 04:54:56 +02:00
'signature' => $GLOBALS [ '_xmlrpcs_listMethods_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_listMethods_doc' ]
2001-08-09 01:28:03 +02:00
),
'system.methodHelp' => array (
'function' => '_xmlrpcs_methodHelp' ,
2001-08-09 04:54:56 +02:00
'signature' => $GLOBALS [ '_xmlrpcs_methodHelp_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_methodHelp_doc' ]
2001-08-09 01:28:03 +02:00
),
'system.methodSignature' => array (
'function' => '_xmlrpcs_methodSignature' ,
2001-08-09 04:54:56 +02:00
'signature' => $GLOBALS [ '_xmlrpcs_methodSignature_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_methodSignature_doc' ]
2001-08-09 17:51:06 +02:00
),
'system.listApps' => array (
'function' => '_xmlrpcs_listApps' ,
'signature' => $GLOBALS [ '_xmlrpcs_listApps_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_listApps_doc' ]
2001-08-13 18:24:03 +02:00
),
2001-08-20 01:55:58 +02:00
'system.listUsers' => array (
'function' => '_xmlrpcs_listUsers' ,
'signature' => $GLOBALS [ '_xmlrpcs_listUsers_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_listUsers_doc' ]
),
'system.login' => array (
'function' => '_xmlrpcs_login' ,
'signature' => $GLOBALS [ '_xmlrpcs_login_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_login_doc' ]
)
);
*/
$GLOBALS [ '_xmlrpcs_dmap' ] = array (
'system.listMethods' => array (
'function' => '_xmlrpcs_listMethods' ,
'signature' => $GLOBALS [ '_xmlrpcs_listMethods_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_listMethods_doc' ]
),
'system.methodHelp' => array (
'function' => '_xmlrpcs_methodHelp' ,
'signature' => $GLOBALS [ '_xmlrpcs_methodHelp_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_methodHelp_doc' ]
),
'system.methodSignature' => array (
'function' => '_xmlrpcs_methodSignature' ,
'signature' => $GLOBALS [ '_xmlrpcs_methodSignature_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_methodSignature_doc' ]
2001-08-15 05:54:15 +02:00
),
2001-08-20 01:55:58 +02:00
'system.login' => array (
'function' => '_xmlrpcs_login' ,
'signature' => $GLOBALS [ '_xmlrpcs_login_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_login_doc' ]
2001-08-20 02:28:36 +02:00
),
'system.logout' => array (
'function' => '_xmlrpcs_logout' ,
'signature' => $GLOBALS [ '_xmlrpcs_logout_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_logout_doc' ]
2001-08-09 01:28:03 +02:00
)
);
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xmlrpc_debuginfo' ] = '' ;
2001-08-09 01:28:03 +02:00
function xmlrpc_debugmsg ( $m )
{
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xmlrpc_debuginfo' ] .= $m . " \n " ;
2001-08-09 01:28:03 +02:00
}
2001-08-08 01:04:05 +02:00
?>