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
2003-08-28 16:31:11 +02:00
// License is granted to use or modify this software ("XML-RPC for PHP")
2001-08-08 01:04:05 +02:00
// 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.
2001-12-04 14:46:53 +01:00
/* $Id$ */
2001-08-08 01:04:05 +02:00
if ( ! function_exists ( 'xml_parser_create' ))
{
2003-08-28 16:31:11 +02:00
// Win 32 fix. From: "Leo West" <lwest@imaginet.fr>
2001-08-08 01:04:05 +02:00
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-12-28 19:41:33 +01:00
$GLOBALS [ 'xmlrpcerr' ][ 'no_access' ] = 9 ;
$GLOBALS [ 'xmlrpcstr' ][ 'no_access' ] = 'Access denied' ;
2004-03-07 10:55:43 +01:00
$GLOBALS [ 'xmlrpcerr' ][ 'not_existent' ] = 10 ;
$GLOBALS [ 'xmlrpcstr' ][ 'not_existent' ] = 'Entry does not (longer) exist!' ;
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
2001-11-29 23:07:28 +01:00
/*!
@ function xmlrpcfault
@ abstract Error reporting for XML - RPC
@ discussion Author : jengo < br >
Returns XML - RPC fault and stops this execution of the application . < br >
Syntax : void xmlrpcfault ( string ) < br >
Example1 : xmlrpcfault ( 'Session could not be verifed' ); < br >
@ param $string Error message to be returned .
*/
function xmlrpcfault ( $string )
{
$r = CreateObject ( 'phpgwapi.xmlrpcresp' ,
CreateObject ( 'phpgwapi.xmlrpcval' ),
$GLOBALS [ 'xmlrpcerr' ][ 'unknown_method' ],
$string
);
$payload = '<?xml version="1.0"?>' . " \n " . $r -> serialize ();
Header ( 'Content-type: text/xml' );
Header ( 'Content-length: ' . strlen ( $payload ));
print $payload ;
2003-08-28 16:31:11 +02:00
$GLOBALS [ 'phpgw' ] -> common -> phpgw_exit ( False );
2001-11-29 23:07:28 +01:00
}
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
2003-08-28 16:31:11 +02:00
// lv - used to indicate "looking for a value": implements
2001-08-08 01:04:05 +02:00
// 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
}
2001-12-28 07:02:30 +01:00
elseif ( $name == 'BOOLEAN' )
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
}
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
}
}
2003-08-28 16:31:11 +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>
2003-08-28 16:31:11 +02:00
// 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
{
2003-08-28 16:31:11 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'st' ] .= " , " ;
2001-08-08 01:04:05 +02:00
}
break ;
case 'MEMBER' :
2003-08-28 16:31:11 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = " " ;
2001-08-09 04:54:56 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'qt' ] = 0 ;
break ;
2001-08-08 01:04:05 +02:00
case 'DATA' :
2003-08-28 16:31:11 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] = " " ;
2001-08-09 04:54:56 +02:00
$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' :
2003-08-28 16:31:11 +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
{
2003-08-28 16:31:11 +02:00
// "lookforvalue==3" means that we've found an entire value
2001-08-08 01:04:05 +02:00
// 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-09-25 16:42:43 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] .= str_replace ( '$' , '\$' ,
str_replace ( '"' , '\"' ,
str_replace ( chr ( 92 ), $GLOBALS [ 'xmlrpc_backslash' ], $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-09-25 16:42:43 +02:00
$GLOBALS [ '_xh' ][ $parser ][ 'ac' ] .= str_replace ( '$' , '\$' ,
str_replace ( '"' , '\"' ,
str_replace ( chr ( 92 ), $GLOBALS [ 'xmlrpc_backslash' ], $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 )
{
2003-08-28 16:31:11 +02:00
$t = strftime ( " %Y%m%dT%H:%M:%S " , $timet );
2001-08-08 01:04:05 +02:00
}
else
{
2003-08-28 16:31:11 +02:00
if ( function_exists ( " gmstrftime " ))
2001-08-08 01:04:05 +02:00
{
// gmstrftime doesn't exist in some versions
// of PHP
2003-08-28 16:31:11 +02:00
$t = gmstrftime ( " %Y%m%dT%H:%M:%S " , $timet );
2001-08-08 01:04:05 +02:00
}
else
{
2003-08-28 16:31:11 +02:00
$t = strftime ( " %Y%m%dT%H:%M:%S " , $timet - date ( " Z " ));
2001-08-08 01:04:05 +02:00
}
}
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 ) *
****************************************************************/
2003-08-28 16:31:11 +02:00
function phpgw_xmlrpc_decode ( $xmlrpc_val )
2001-08-08 01:04:05 +02:00
{
2003-08-28 16:31:11 +02:00
$kind = @ $xmlrpc_val -> kindOf ();
if ( $kind == " scalar " )
{
return $xmlrpc_val -> scalarval ();
}
elseif ( $kind == " array " )
2001-08-08 01:04:05 +02:00
{
2003-08-28 16:31:11 +02:00
$size = $xmlrpc_val -> arraysize ();
$arr = array ();
2001-08-08 01:04:05 +02:00
2003-08-28 16:31:11 +02:00
for ( $i = 0 ; $i < $size ; $i ++ )
2003-05-10 10:53:43 +02:00
{
2003-08-28 16:31:11 +02:00
$arr [] = phpgw_xmlrpc_decode ( $xmlrpc_val -> arraymem ( $i ));
2003-05-10 10:53:43 +02:00
}
2003-08-28 16:31:11 +02:00
return $arr ;
}
elseif ( $kind == " struct " )
{
$xmlrpc_val -> structreset ();
$arr = array ();
2003-05-10 10:53:43 +02:00
2003-08-28 16:31:11 +02:00
while ( list ( $key , $value ) = $xmlrpc_val -> structeach ())
{
$arr [ $key ] = phpgw_xmlrpc_decode ( $value );
2001-08-08 01:04:05 +02:00
}
2003-08-28 16:31:11 +02:00
return $arr ;
2001-08-08 01:04:05 +02:00
}
}
/****************************************************************
* 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 ) *
****************************************************************/
2003-08-28 16:31:11 +02:00
function phpgw_xmlrpc_encode ( $php_val )
2001-08-08 01:04:05 +02:00
{
2003-08-28 16:31:11 +02:00
$type = gettype ( $php_val );
$xmlrpc_val = CreateObject ( 'phpgwapi.xmlrpcval' );
2003-05-10 10:53:43 +02:00
2003-08-28 16:31:11 +02:00
switch ( $type )
{
case " array " :
case " object " :
$arr = array ();
while ( list ( $k , $v ) = each ( $php_val ))
{
$arr [ $k ] = phpgw_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 :
$xmlrpc_val = false ;
break ;
2001-08-08 01:04:05 +02:00
}
2003-08-28 16:31:11 +02:00
return $xmlrpc_val ;
2001-08-08 01:04:05 +02:00
}
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-12-04 14:46:53 +01:00
2003-08-28 16:31:11 +02:00
/*
$GLOBALS [ '_xmlrpcs_listApps_sig' ] = array ( array ( xmlrpcStruct , xmlrpcString ));
$GLOBALS [ '_xmlrpcs_listApps_doc' ] = 'Returns a list of installed phpgw apps' ;
function _xmlrpcs_listApps ( $server , $m )
{
$m -> getParam ( 0 );
$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' );
$version = $GLOBALS [ 'phpgw' ] -> db -> f ( 'app_version' );
$apps [ $name ] = CreateObject ( 'phpgwapi.xmlrpcval' ,
array (
'title' => CreateObject ( 'phpgwapi.xmlrpcval' , $title , 'string' ),
'name' => CreateObject ( 'phpgwapi.xmlrpcval' , $name , 'string' ),
'status' => CreateObject ( 'phpgwapi.xmlrpcval' , $status , 'string' ),
'version' => CreateObject ( 'phpgwapi.xmlrpcval' , $version , 'string' )
),
'struct'
);
}
}
return CreateObject ( 'phpgwapi.xmlrpcresp' , CreateObject ( 'phpgwapi.xmlrpcval' , $apps , 'struct' ));
}
*/
2001-08-20 18:33:26 +02:00
$GLOBALS [ '_xmlrpcs_login_sig' ] = array ( array ( xmlrpcStruct , xmlrpcStruct ));
2004-08-09 15:46:03 +02:00
$GLOBALS [ '_xmlrpcs_login_doc' ] = 'eGroupWare 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
{
2003-08-28 16:31:11 +02:00
list ( $sessionid , $kp3 ) = $GLOBALS [ 'phpgw' ] -> session -> create_server ( $username . '@' . $server_name , $password , " text " );
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 ;
}
2003-08-28 16:31:11 +02:00
$sessionid = $GLOBALS [ 'phpgw' ] -> session -> create ( $user , $password , " text " );
2001-08-22 22:01:05 +02:00
$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
}
2003-08-28 16:31:11 +02:00
$GLOBALS [ '_xmlrpcs_phpgw_api_version_sig' ] = array ( array ( xmlrpcString , xmlrpcString ));
2004-08-09 15:46:03 +02:00
$GLOBALS [ '_xmlrpcs_phpgw_api_version_doc' ] = 'Returns the eGroupWare API version' ;
2003-08-28 16:31:11 +02:00
function _xmlrpcs_phpgw_api_version ( $server , $m )
{
$version = $GLOBALS [ 'phpgw_info' ][ 'server' ][ 'versions' ][ 'phpgwapi' ];
return CreateObject ( 'phpgwapi.xmlrpcresp' , CreateObject ( 'phpgwapi.xmlrpcval' , $version , 'string' ));
}
2001-08-20 18:33:26 +02:00
$GLOBALS [ '_xmlrpcs_logout_sig' ] = array ( array ( xmlrpcStruct , xmlrpcStruct ));
2004-08-09 15:46:03 +02:00
$GLOBALS [ '_xmlrpcs_logout_doc' ] = 'eGroupWare client or server logout via XML-RPC' ;
2001-08-20 02:28:36 +02:00
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
2001-11-12 19:28:57 +01:00
if ( $later )
2001-08-20 02:28:36 +02:00
{
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-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
),
2003-08-28 16:31:11 +02:00
'system.methodHelp' => array (
'function' => '_xmlrpcs_methodHelp' ,
'signature' => $GLOBALS [ '_xmlrpcs_methodHelp_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_methodHelp_doc' ]
),
2002-03-01 11:34:12 +01:00
'system.methodSignature' => array (
'function' => '_xmlrpcs_methodSignature' ,
'signature' => $GLOBALS [ '_xmlrpcs_methodSignature_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_methodSignature_doc' ]
),
2003-08-28 16:31:11 +02:00
/*
'system.listApps' => array (
'function' => '_xmlrpcs_listApps' ,
'signature' => $GLOBALS [ '_xmlrpcs_listApps_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_listApps_doc' ]
2001-08-09 01:28:03 +02:00
),
2003-08-28 16:31:11 +02:00
*/
2002-03-01 11:34:12 +01:00
'system.login' => array (
'function' => '_xmlrpcs_login' ,
'signature' => $GLOBALS [ '_xmlrpcs_login_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_login_doc' ]
),
'system.logout' => array (
'function' => '_xmlrpcs_logout' ,
'signature' => $GLOBALS [ '_xmlrpcs_logout_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_logout_doc' ]
2001-08-09 17:51:06 +02:00
),
2003-08-28 16:31:11 +02:00
'system.phpgw_api_version' => array (
'function' => '_xmlrpcs_phpgw_api_version' ,
'signature' => $GLOBALS [ '_xmlrpcs_phpgw_api_version_sig' ],
'docstring' => $GLOBALS [ '_xmlrpcs_phpgw_api_version_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
?>