[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/phpgwapi/inc/ -> xml_functions.inc.php (source)

   1  <?php
   2      // by Edd Dumbill (C) 1999-2001
   3      // <edd@usefulinc.com>
   4      // xmlrpc.inc,v 1.18 2001/07/06 18:23:57 edmundd
   5  
   6      // License is granted to use or modify this software ("XML-RPC for PHP")
   7      // for commercial or non-commercial use provided the copyright of the author
   8      // is preserved in any distributed or derivative work.
   9  
  10      // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
  11      // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12      // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  13      // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  14      // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  15      // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16      // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  17      // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18      // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  19      // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20  
  21      /* $Id: xml_functions.inc.php 20496 2006-03-08 19:40:11Z ralfbecker $ */
  22  
  23      if (!function_exists('xml_parser_create'))
  24      {
  25          // Win 32 fix. From: "Leo West" <lwest@imaginet.fr>
  26          if($WINDIR)
  27          {
  28              dl('php3_xml.dll');
  29          }
  30          else
  31          {
  32              dl('xml.so');
  33          }
  34      }
  35  
  36      $GLOBALS['xmlrpc_valid_parents'] = array(
  37          'BOOLEAN' => array('VALUE'),
  38          'I4' => array('VALUE'),
  39          'INT' => array('VALUE'),
  40          'STRING' => array('VALUE'),
  41          'DOUBLE' => array('VALUE'),
  42          'DATETIME.ISO8601' => array('VALUE'),
  43          'BASE64' => array('VALUE'),
  44          'ARRAY' => array('VALUE'),
  45          'STRUCT' => array('VALUE'),
  46          'PARAM' => array('PARAMS'),
  47          'METHODNAME' => array('METHODCALL'),
  48          'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),
  49          'MEMBER' => array('STRUCT'),
  50          'NAME' => array('MEMBER'),
  51          'DATA' => array('ARRAY'),
  52          'FAULT' => array('METHODRESPONSE'),
  53          'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'),
  54      );
  55  
  56      define('xmlrpcI4','i4');
  57      define('xmlrpcInt','int');
  58      define('xmlrpcBoolean','boolean');
  59      define('xmlrpcDouble','double');
  60      define('xmlrpcString','string');
  61      define('xmlrpcDateTime','dateTime.iso8601');
  62      define('xmlrpcBase64','base64');
  63      define('xmlrpcArray','array');
  64      define('xmlrpcStruct','struct');
  65  
  66      $GLOBALS['xmlrpcTypes'] = array(
  67          xmlrpcI4       => 1,
  68          xmlrpcInt      => 1,
  69          xmlrpcBoolean  => 1,
  70          xmlrpcString   => 1,
  71          xmlrpcDouble   => 1,
  72          xmlrpcDateTime => 1,
  73          xmlrpcBase64   => 1,
  74          xmlrpcArray    => 2,
  75          xmlrpcStruct   => 3
  76      );
  77  
  78      $GLOBALS['xmlEntities']=array(
  79          'amp'  => '&',
  80          'quot' => '"',
  81          'lt'   => '<',
  82          'gt'   => '>',
  83          'apos' => "'"
  84      );
  85  
  86      $GLOBALS['xmlrpcerr']['unknown_method']=1;
  87      $GLOBALS['xmlrpcstr']['unknown_method']='Unknown method';
  88      $GLOBALS['xmlrpcerr']['invalid_return']=2;
  89      $GLOBALS['xmlrpcstr']['invalid_return']='Invalid return payload: enable debugging to examine incoming payload';
  90      $GLOBALS['xmlrpcerr']['incorrect_params']=3;
  91      $GLOBALS['xmlrpcstr']['incorrect_params']='Incorrect parameters passed to method';
  92      $GLOBALS['xmlrpcerr']['introspect_unknown']=4;
  93      $GLOBALS['xmlrpcstr']['introspect_unknown']="Can't introspect: method unknown";
  94      $GLOBALS['xmlrpcerr']['http_error']=5;
  95      $GLOBALS['xmlrpcstr']['http_error']="Didn't receive 200 OK from remote server.";
  96      $GLOBALS['xmlrpcerr']['no_data']=6;
  97      $GLOBALS['xmlrpcstr']['no_data']='No data received from server.';
  98      $GLOBALS['xmlrpcerr']['no_ssl']=7;
  99      $GLOBALS['xmlrpcstr']['no_ssl']='No SSL support compiled in.';
 100      $GLOBALS['xmlrpcerr']['curl_fail']=8;
 101      $GLOBALS['xmlrpcstr']['curl_fail']='CURL error';
 102      $GLOBALS['xmlrpcerr']['multicall_notstruct'] = 9;
 103      $GLOBALS['xmlrpcstr']['multicall_notstruct'] = 'system.multicall expected struct';
 104      $GLOBALS['xmlrpcerr']['multicall_nomethod']  = 10;
 105      $GLOBALS['xmlrpcstr']['multicall_nomethod']  = 'missing methodName';
 106      $GLOBALS['xmlrpcerr']['multicall_notstring'] = 11;
 107      $GLOBALS['xmlrpcstr']['multicall_notstring'] = 'methodName is not a string';
 108      $GLOBALS['xmlrpcerr']['multicall_recursion'] = 12;
 109      $GLOBALS['xmlrpcstr']['multicall_recursion'] = 'recursive system.multicall forbidden';
 110      $GLOBALS['xmlrpcerr']['multicall_noparams']  = 13;
 111      $GLOBALS['xmlrpcstr']['multicall_noparams']  = 'missing params';
 112      $GLOBALS['xmlrpcerr']['multicall_notarray']  = 14;
 113      $GLOBALS['xmlrpcstr']['multicall_notarray']  = 'params is not an array';
 114  
 115      $GLOBALS['xmlrpcerr']['invalid_request']=15;
 116      $GLOBALS['xmlrpcstr']['invalid_request']='Invalid request payload';
 117      $GLOBALS['xmlrpcerr']['no_curl']=16;
 118      $GLOBALS['xmlrpcstr']['no_curl']='No CURL support compiled in.';
 119      $GLOBALS['xmlrpcerr']['server_error']=17;
 120      $GLOBALS['xmlrpcstr']['server_error']='Internal server error';
 121  
 122      $GLOBALS['xmlrpcerr']['no_access']          = 18;
 123      $GLOBALS['xmlrpcstr']['no_access']          = 'Access denied';
 124      $GLOBALS['xmlrpcerr']['not_existent']       = 19;
 125      $GLOBALS['xmlrpcstr']['not_existent']       = 'Entry does not (longer) exist!';
 126  
 127      $GLOBALS['xmlrpcerr']['cannot_decompress']=103;
 128      $GLOBALS['xmlrpcstr']['cannot_decompress']='Received from server compressed HTTP and cannot decompress';
 129      $GLOBALS['xmlrpcerr']['decompress_fail']=104;
 130      $GLOBALS['xmlrpcstr']['decompress_fail']='Received from server invalid compressed HTTP';
 131      $GLOBALS['xmlrpcerr']['dechunk_fail']=105;
 132      $GLOBALS['xmlrpcstr']['dechunk_fail']='Received from server invalid chunked HTTP';
 133      $GLOBALS['xmlrpcerr']['server_cannot_decompress']=106;
 134      $GLOBALS['xmlrpcstr']['server_cannot_decompress']='Received from client compressed HTTP request and cannot decompress';
 135      $GLOBALS['xmlrpcerr']['server_decompress_fail']=107;
 136      $GLOBALS['xmlrpcstr']['server_decompress_fail']='Received from client invalid compressed HTTP request';
 137  
 138      $GLOBALS['xmlrpc_defencoding'] = 'UTF-8';
 139      $GLOBALS['xmlrpc_internalencoding']='ISO-8859-1';
 140  
 141      $GLOBALS['xmlrpcName']    = 'XML-RPC for PHP';
 142      $GLOBALS['xmlrpcVersion'] = '2.0';
 143  
 144      // let user errors start at 800
 145      $GLOBALS['xmlrpcerruser'] = 800;
 146      // let XML parse errors start at 100
 147      $GLOBALS['xmlrpcerrxml'] = 100;
 148  
 149      // formulate backslashes for escaping regexp
 150      $GLOBALS['xmlrpc_backslash'] = chr(92) . chr(92);
 151  
 152      /*!
 153      @function xmlrpcfault
 154      @abstract Error reporting for XML-RPC
 155      @discussion Author: jengo <br>
 156      Returns XML-RPC fault and stops this execution of the application. <br>
 157      Syntax: void xmlrpcfault(string) <br>
 158      Example1: xmlrpcfault('Session could not be verifed'); <br>
 159      @param $string Error message to be returned.
 160      */
 161  	function xmlrpcfault($string)
 162      {
 163          $r = CreateObject('phpgwapi.xmlrpcresp',
 164              CreateObject('phpgwapi.xmlrpcval'),
 165              $GLOBALS['xmlrpcerr']['unknown_method'],
 166              $string
 167          );
 168          $payload = '<?xml version="1.0"?>' . "\n" . $r->serialize();
 169          Header('Content-type: text/xml');
 170          Header('Content-length: ' . strlen($payload));
 171          print $payload;
 172          $GLOBALS['egw']->common->phpgw_exit(False);
 173      }
 174  
 175      // used to store state during parsing
 176      // quick explanation of components:
 177      //   ac - used to accumulate values
 178      //   isf - used to indicate a fault
 179      //   lv - used to indicate "looking for a value": implements
 180      //        the logic to allow values with no types to be strings
 181      //   params - used to store parameters in method calls
 182      //   method - used to store method name
 183      //   stack - array with genealogy of xml elements names:
 184      //           used to validate nesting of xmlrpc elements
 185      $GLOBALS['_xh'] = null;
 186  
 187      /**
 188      * To help correct communication of non-ascii chars inside strings, regardless
 189      * of the charset used when sending requests, parsing them, sending responses
 190      * and parsing responses, convert all non-ascii chars present in the message
 191      * into their equivalent 'charset entity'. Charset entities enumerated this way
 192      * are independent of the charset encoding used to transmit them, and all XML
 193      * parsers are bound to understand them.
 194      */
 195  	function xmlrpc_encode_entitites($data)
 196      {
 197          $length = strlen($data);
 198          $escapeddata = "";
 199          for($position = 0; $position < $length; $position++)
 200          {
 201              $character = substr($data, $position, 1);
 202              $code = Ord($character);
 203              switch($code)
 204              {
 205                  case 34:
 206                      $character = "&quot;";
 207                      break;
 208                  case 38:
 209                      $character = "&amp;";
 210                      break;
 211                  case 39:
 212                      $character = "&apos;";
 213                      break;
 214                  case 60:
 215                      $character = "&lt;";
 216                      break;
 217                  case 62:
 218                      $character = "&gt;";
 219                      break;
 220                  default:
 221                      if($code < 32 || $code > 159)
 222                      {
 223                          $character = ("&#".strval($code).";");
 224                      }
 225                      break;
 226              }
 227              $escapeddata .= $character;
 228          }
 229          return $escapeddata;
 230      }
 231  
 232  	function xmlrpc_entity_decode($string)
 233      {
 234          $top = split('&', $string);
 235          $op  = '';
 236          $i   = 0;
 237          while($i<sizeof($top))
 238          {
 239              if (ereg("^([#a-zA-Z0-9]+);", $top[$i], $regs))
 240              {
 241                  $op .= ereg_replace("^[#a-zA-Z0-9]+;",
 242                      xmlrpc_lookup_entity($regs[1]), $top[$i]);
 243              }
 244              else
 245              {
 246                  if ($i == 0)
 247                  {
 248                      $op = $top[$i];
 249                  }
 250                  else
 251                  {
 252                      $op .= '&' . $top[$i];
 253                  }
 254              }
 255              $i++;
 256          }
 257          return $op;
 258      }
 259  
 260  	function xmlrpc_lookup_entity($ent)
 261      {
 262          if (isset($GLOBALS['xmlEntities'][strtolower($ent)]))
 263          {
 264              return $GLOBALS['xmlEntities'][strtolower($ent)];
 265          }
 266          if (ereg("^#([0-9]+)$", $ent, $regs))
 267          {
 268              return chr($regs[1]);
 269          }
 270          return '?';
 271      }
 272  
 273  	function xmlrpc_se($parser, $name, $attrs)
 274      {
 275          // if invalid xmlrpc already detected, skip all processing
 276          if ($GLOBALS['_xh'][$parser]['isf'] < 2)
 277          {
 278              // check for correct element nesting
 279              // top level element can only be of 2 types
 280              if (count($GLOBALS['_xh'][$parser]['stack']) == 0)
 281              {
 282                  if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')
 283                  {
 284                      $GLOBALS['_xh'][$parser]['isf'] = 2;
 285                      $GLOBALS['_xh'][$parser]['isf_reason'] = 'missing top level xmlrpc element';
 286                      return;
 287                  }
 288              }
 289              else
 290              {
 291                  // not top level element: see if parent is OK
 292                  if (!in_array($GLOBALS['_xh'][$parser]['stack'][0], $GLOBALS['xmlrpc_valid_parents'][$name]))
 293                  {
 294                      $GLOBALS['_xh'][$parser]['isf'] = 2;
 295                      $GLOBALS['_xh'][$parser]['isf_reason'] = "xmlrpc element $name cannot be child of {$GLOBALS['_xh'][$parser]['stack'][0]}";
 296                      return;
 297                  }
 298              }
 299  
 300              switch($name)
 301              {
 302                  case 'STRUCT':
 303                  case 'ARRAY':
 304                      // create an empty array to hold child values, and push it onto appropriate stack
 305                      $cur_val = array();
 306                      $cur_val['values'] = array();
 307                      $cur_val['type'] = $name;
 308                      @array_unshift($GLOBALS['_xh'][$parser]['valuestack'], $cur_val);
 309                      break;
 310                  case 'DATA':
 311                  case 'METHODCALL':
 312                  case 'METHODRESPONSE':
 313                  case 'PARAMS':
 314                      // valid elements that add little to processing
 315                      break;
 316                  case 'METHODNAME':
 317                  case 'NAME':
 318                      $GLOBALS['_xh'][$parser]['ac']='';
 319                      break;
 320                  case 'FAULT':
 321                      $GLOBALS['_xh'][$parser]['isf']=1;
 322                      break;
 323                  case 'VALUE':
 324                      $GLOBALS['_xh'][$parser]['vt']='value'; // indicator: no value found yet
 325                      $GLOBALS['_xh'][$parser]['ac']='';
 326                      $GLOBALS['_xh'][$parser]['lv']=1;
 327                      break;
 328                  case 'I4':
 329                  case 'INT':
 330                  case 'STRING':
 331                  case 'BOOLEAN':
 332                  case 'DOUBLE':
 333                  case 'DATETIME.ISO8601':
 334                  case 'BASE64':
 335                      if ($GLOBALS['_xh'][$parser]['vt']!='value')
 336                      {
 337                          //two data elements inside a value: an error occurred!
 338                          $GLOBALS['_xh'][$parser]['isf'] = 2;
 339                          $GLOBALS['_xh'][$parser]['isf_reason'] = "$name element following a {$GLOBALS['_xh'][$parser]['vt']} element inside a single value";
 340                          return;
 341                      }
 342  
 343                      $GLOBALS['_xh'][$parser]['ac']=''; // reset the accumulator
 344                      break;
 345                  case 'MEMBER':
 346                      $GLOBALS['_xh'][$parser]['valuestack'][0]['name']=''; // set member name to null, in case we do not find in the xml later on
 347                      //$GLOBALS['_xh'][$parser]['ac']='';
 348                      // Drop trough intentionally
 349                  case 'PARAM':
 350                      // clear value, so we can check later if no value will passed for this param/member
 351                      $GLOBALS['_xh'][$parser]['value']=null;
 352                      break;
 353                  default:
 354                      /// INVALID ELEMENT: RAISE ISF so that it is later recognized!!!
 355                      $GLOBALS['_xh'][$parser]['isf'] = 2;
 356                      $GLOBALS['_xh'][$parser]['isf_reason'] = "found not-xmlrpc xml element $name";
 357                      break;
 358              }
 359  
 360              // Save current element name to stack, to validate nesting
 361              @array_unshift($GLOBALS['_xh'][$parser]['stack'], $name);
 362  
 363              if($name!='VALUE')
 364              {
 365                  $GLOBALS['_xh'][$parser]['lv']=0;
 366              }
 367          }
 368      }
 369  
 370  	function xmlrpc_ee($parser, $name)
 371      {
 372          if ($GLOBALS['_xh'][$parser]['isf'] < 2)
 373          {
 374              // push this element name from stack
 375              // NB: if XML validates, correct opening/closing is guaranteed and
 376              // we do not have to check for $name == $curr_elem.
 377              // we also checked for proper nesting at start of elements...
 378              $curr_elem = array_shift($GLOBALS['_xh'][$parser]['stack']);
 379  
 380              switch($name)
 381              {
 382                  case 'STRUCT':
 383                  case 'ARRAY':
 384                      // fetch out of stack array of values, and promote it to current value
 385                      $curr_val = array_shift($GLOBALS['_xh'][$parser]['valuestack']);
 386                      $GLOBALS['_xh'][$parser]['value'] = $curr_val['values'];
 387  
 388                      $GLOBALS['_xh'][$parser]['vt']=strtolower($name);
 389                      break;
 390                  case 'NAME':
 391                      $GLOBALS['_xh'][$parser]['valuestack'][0]['name'] = $GLOBALS['_xh'][$parser]['ac'];
 392                      break;
 393                  case 'BOOLEAN':
 394                  case 'I4':
 395                  case 'INT':
 396                  case 'STRING':
 397                  case 'DOUBLE':
 398                  case 'DATETIME.ISO8601':
 399                  case 'BASE64':
 400                      $GLOBALS['_xh'][$parser]['vt']=strtolower($name);
 401                      if ($name=='STRING')
 402                      {
 403                          $GLOBALS['_xh'][$parser]['value']=$GLOBALS['_xh'][$parser]['ac'];
 404                      }
 405                      elseif ($name=='DATETIME.ISO8601')
 406                      {
 407                          $GLOBALS['_xh'][$parser]['vt'] = xmlrpcDateTime;
 408                          $GLOBALS['_xh'][$parser]['value']=$GLOBALS['_xh'][$parser]['ac'];
 409                      }
 410                      elseif ($name=='BASE64')
 411                      {
 412                          ///@todo check for failure of base64 decoding / catch warnings
 413                          $GLOBALS['_xh'][$parser]['value'] = base64_decode($GLOBALS['_xh'][$parser]['ac']);
 414                      }
 415                      elseif ($name=='BOOLEAN')
 416                      {
 417                          // special case here: we translate boolean 1 or 0 into PHP
 418                              // constants true or false
 419                              // NB: this simple checks helps a lot sanitizing input, ie no
 420                              // security problems around here
 421                              if ($GLOBALS['_xh'][$parser]['ac']=='1')
 422                              {
 423                                  $GLOBALS['_xh'][$parser]['value']=true;
 424                              }
 425                              else
 426                              {
 427                                  // log if receiveing something strange, even though we set the value to false anyway
 428                                  if ($GLOBALS['_xh'][$parser]['ac']!='0')
 429                                  error_log('XML-RPC: invalid value received in BOOLEAN: '.$GLOBALS['_xh'][$parser]['ac']);
 430                                  $GLOBALS['_xh'][$parser]['value']=false;
 431                              }
 432                      }
 433                      elseif ($name=='DOUBLE')
 434                      {
 435                          // we have a DOUBLE
 436                          // we must check that only 0123456789-.<space> are characters here
 437                          if (!ereg("^[+-]?[eE0123456789 \\t\\.]+$", $GLOBALS['_xh'][$parser]['ac']))
 438                          {
 439                              // TODO: find a better way of throwing an error
 440                              // than this!
 441                              error_log('XML-RPC: non numeric value received in DOUBLE: '.$GLOBALS['_xh'][$parser]['ac']);
 442                              $GLOBALS['_xh'][$parser]['value']='ERROR_NON_NUMERIC_FOUND';
 443                          }
 444                          else
 445                          {
 446                              // it's ok, add it on
 447                              $GLOBALS['_xh'][$parser]['value']=(double)$GLOBALS['_xh'][$parser]['ac'];
 448                          }
 449                      }
 450                      else
 451                      {
 452                          // we have an I4/INT
 453                          // we must check that only 0123456789-<space> are characters here
 454                          if (!ereg("^[+-]?[0123456789 \\t]+$", $GLOBALS['_xh'][$parser]['ac']))
 455                          {
 456                              // TODO: find a better way of throwing an error
 457                              // than this!
 458                              error_log('XML-RPC: non numeric value received in INT: '.$GLOBALS['_xh'][$parser]['ac']);
 459                              $GLOBALS['_xh'][$parser]['value']='ERROR_NON_NUMERIC_FOUND';
 460                          }
 461                          else
 462                          {
 463                              // it's ok, add it on
 464                              $GLOBALS['_xh'][$parser]['value'] = (int)$GLOBALS['_xh'][$parser]['ac'];
 465                          }
 466                      }
 467                      $GLOBALS['_xh'][$parser]['ac']=''; // is this necessary?
 468                      $GLOBALS['_xh'][$parser]['lv']=3; // indicate we've found a value
 469                      break;
 470                  case 'VALUE':
 471                      // This if() detects if no scalar was inside <VALUE></VALUE>
 472                      if ($GLOBALS['_xh'][$parser]['vt'] == 'value')
 473                      {
 474                          $GLOBALS['_xh'][$parser]['value'] = $GLOBALS['_xh'][$parser]['ac'];
 475                          $GLOBALS['_xh'][$parser]['vt'] = xmlrpcString;
 476                      }
 477  
 478                      // build the xmlrpc val out of the data received, and substitute it
 479                      $temp =& CreateObject('phpgwapi.xmlrpcval',$GLOBALS['_xh'][$parser]['value'], $GLOBALS['_xh'][$parser]['vt']);
 480                      // check if we are inside an array or struct:
 481                      // if value just built is inside an array, let's move it into array on the stack
 482                      if (count($GLOBALS['_xh'][$parser]['valuestack']) && $GLOBALS['_xh'][$parser]['valuestack'][0]['type']=='ARRAY')
 483                      {
 484                          $GLOBALS['_xh'][$parser]['valuestack'][0]['values'][] = $temp;
 485                      }
 486                      else
 487                      {
 488                          $GLOBALS['_xh'][$parser]['value'] = $temp;
 489                      }
 490                      break;
 491                  case 'MEMBER':
 492                      $GLOBALS['_xh'][$parser]['ac']=''; // is this necessary?
 493                      // add to array in the stack the last element built,
 494                      // unless no VALUE was found
 495                      if ($GLOBALS['_xh'][$parser]['value'])
 496                      $GLOBALS['_xh'][$parser]['valuestack'][0]['values'][$GLOBALS['_xh'][$parser]['valuestack'][0]['name']] = $GLOBALS['_xh'][$parser]['value'];
 497                      else
 498                      error_log('XML-RPC: missing VALUE inside STRUCT in received xml');
 499                      break;
 500                  case 'DATA':
 501                      $GLOBALS['_xh'][$parser]['ac']=''; // is this necessary?
 502                      break;
 503                  case 'PARAM':
 504                      // add to array of params the current value,
 505                      // unless no VALUE was found
 506                      if ($GLOBALS['_xh'][$parser]['value'])
 507                      $GLOBALS['_xh'][$parser]['params'][]=$GLOBALS['_xh'][$parser]['value'];
 508                      else
 509                      error_log('XML-RPC: missing VALUE inside PARAM in received xml');
 510                      break;
 511                  case 'METHODNAME':
 512                      $GLOBALS['_xh'][$parser]['method']=ereg_replace("^[\n\r\t ]+", '', $GLOBALS['_xh'][$parser]['ac']);
 513                      break;
 514                  case 'PARAMS':
 515                  case 'FAULT':
 516                  case 'METHODCALL':
 517                  case 'METHORESPONSE':
 518                      break;
 519                  default:
 520                      // End of INVALID ELEMENT!
 521                      // shall we add an assert here for unreachable code???
 522                      break;
 523              }
 524          }
 525      }
 526  
 527  	function xmlrpc_cd($parser, $data)
 528      {
 529          //if(ereg("^[\n\r \t]+$", $data)) return;
 530          // print "adding [${data}]\n";
 531  
 532          // skip processing if xml fault already detected
 533          if ($GLOBALS['_xh'][$parser]['isf'] < 2)
 534          {
 535              if($GLOBALS['_xh'][$parser]['lv']!=3)
 536              {
 537                  // "lookforvalue==3" means that we've found an entire value
 538                  // and should discard any further character data
 539                  if($GLOBALS['_xh'][$parser]['lv']==1)
 540                  {
 541                      // if we've found text and we're just in a <value> then
 542                      // say we've found a value
 543                      $GLOBALS['_xh'][$parser]['lv']=2;
 544                  }
 545                  if(!@isset($GLOBALS['_xh'][$parser]['ac']))
 546                  {
 547                      $GLOBALS['_xh'][$parser]['ac'] = '';
 548                  }
 549                  $GLOBALS['_xh'][$parser]['ac'].=$data;
 550              }
 551          }
 552      }
 553  
 554  	function xmlrpc_dh($parser, $data)
 555      {
 556          // skip processing if xml fault already detected
 557          if ($GLOBALS['_xh'][$parser]['isf'] < 2)
 558          {
 559              if(substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';')
 560              {
 561                  if($GLOBALS['_xh'][$parser]['lv']==1)
 562                  {
 563                      $GLOBALS['_xh'][$parser]['lv']=2;
 564                  }
 565                  $GLOBALS['_xh'][$parser]['ac'].=$data;
 566              }
 567          }
 568      }
 569  
 570      // date helpers
 571  	function iso8601_encode($timet, $utc=0)
 572      {
 573          // return an ISO8601 encoded string
 574          // really, timezones ought to be supported
 575          // but the XML-RPC spec says:
 576          //
 577          // "Don't assume a timezone. It should be specified by the server in its
 578          // documentation what assumptions it makes about timezones."
 579          //
 580          // these routines always assume localtime unless
 581          // $utc is set to 1, in which case UTC is assumed
 582          // and an adjustment for locale is made when encoding
 583          if (!$utc)
 584          {
 585              $t=strftime("%Y%m%dT%H:%M:%S", $timet);
 586          }
 587          else
 588          {
 589              if(function_exists('gmstrftime'))
 590              {
 591                  // gmstrftime doesn't exist in some versions
 592                  // of PHP
 593                  $t = gmstrftime("%Y%m%dT%H:%M:%S", $timet);
 594              }
 595              else
 596              {
 597                  $t = strftime('%Y%m%dT%H:%M:%S', $timet-date('Z'));
 598              }
 599          }
 600          return $t;
 601      }
 602  
 603  	function iso8601_decode($idate, $utc=0)
 604      {
 605          // return a time in the localtime, or UTC
 606          $t = 0;
 607          if (ereg("([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})",$idate, $regs))
 608          {
 609              if ($utc)
 610              {
 611                  $t=gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
 612              }
 613              else
 614              {
 615                  $t=mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
 616              }
 617          }
 618          return $t;
 619      }
 620  
 621      /****************************************************************
 622      * xmlrpc_decode takes a message in PHP xmlrpc object format and *
 623      * tranlates it into native PHP types.                           *
 624      *                                                               *
 625      * author: Dan Libby (dan@libby.com)                             *
 626      ****************************************************************/
 627  	function phpgw_xmlrpc_decode($xmlrpc_val)
 628      {
 629          $kind = @$xmlrpc_val->kindOf();
 630  
 631          if($kind == 'scalar')
 632          {
 633              return $xmlrpc_val->scalarval();
 634          }
 635          elseif($kind == 'array')
 636          {
 637              $size = $xmlrpc_val->arraysize();
 638              $arr = array();
 639  
 640              for($i = 0; $i < $size; $i++)
 641              {
 642                  $arr[] = phpgw_xmlrpc_decode($xmlrpc_val->arraymem($i));
 643              }
 644              return $arr;
 645          }
 646          elseif($kind == 'struct')
 647          {
 648              $xmlrpc_val->structreset();
 649              $arr = array();
 650  
 651              while(list($key,$value)=$xmlrpc_val->structeach())
 652              {
 653                  $arr[$key] = phpgw_xmlrpc_decode($value);
 654              }
 655              return $arr;
 656          }
 657      }
 658  
 659      /****************************************************************
 660      * xmlrpc_encode takes native php types and encodes them into    *
 661      * xmlrpc PHP object format.                                     *
 662      * BUG: All sequential arrays are turned into structs.  I don't  *
 663      * know of a good way to determine if an array is sequential     *
 664      * only.                                                         *
 665      *                                                               *
 666      * feature creep -- could support more types via optional type   *
 667      * argument.                                                     *
 668      *                                                               *
 669      * author: Dan Libby (dan@libby.com)                             *
 670      ****************************************************************/
 671  	function phpgw_xmlrpc_encode($php_val)
 672      {
 673          $type = gettype($php_val);
 674          $xmlrpc_val = CreateObject('phpgwapi.xmlrpcval');
 675  
 676          switch($type)
 677          {
 678              case 'array':
 679              case 'object':
 680                  $arr = array();
 681                  while(list($k,$v) = each($php_val))
 682                  {
 683                      $arr[$k] = phpgw_xmlrpc_encode($v);
 684                  }
 685                  $xmlrpc_val->addStruct($arr);
 686                  break;
 687              case 'integer':
 688                  $xmlrpc_val->addScalar($php_val, xmlrpcInt);
 689                  break;
 690              case 'double':
 691                  $xmlrpc_val->addScalar($php_val, xmlrpcDouble);
 692                  break;
 693              case 'string':
 694                  $xmlrpc_val->addScalar($php_val, xmlrpcString);
 695                  break;
 696              // <G_Giunta_2001-02-29>
 697              // Add support for encoding/decoding of booleans, since they are supported in PHP
 698              case 'boolean':
 699                  $xmlrpc_val->addScalar($php_val, xmlrpcBoolean);
 700                  break;
 701              // </G_Giunta_2001-02-29>
 702              case 'unknown type':
 703              default:
 704                  $xmlrpc_val = False;
 705                  break;
 706          }
 707          return $xmlrpc_val;
 708      }
 709  
 710      /* The following functions are the system functions for login, logout, etc.
 711       * They are added to the server map at the end of this file.
 712       */
 713  
 714      $GLOBALS['_xmlrpcs_listMethods_sig'] = array(array(xmlrpcArray, xmlrpcString), array(xmlrpcArray));
 715      $GLOBALS['_xmlrpcs_listMethods_doc'] = 'This method lists all the methods that the XML-RPC server knows how to dispatch';
 716  	function _xmlrpcs_listMethods($server, $m)
 717      {
 718          $v     =  CreateObject('phpgwapi.xmlrpcval');
 719          $dmap  = $server->dmap;
 720          $outAr = array();
 721          for(reset($dmap); list($key, $val) = each($dmap); )
 722          {
 723              $outAr[] = CreateObject('phpgwapi.xmlrpcval',$key, 'string');
 724          }
 725          $dmap = $GLOBALS['_xmlrpcs_dmap'];
 726          for(reset($dmap); list($key, $val) = each($dmap); )
 727          {
 728              $outAr[] = CreateObject('phpgwapi.xmlrpcval',$key, 'string');
 729          }
 730          $v->addArray($outAr);
 731          return CreateObject('phpgwapi.xmlrpcresp',$v);
 732      }
 733  
 734      $GLOBALS['_xmlrpcs_methodSignature_sig']=array(array(xmlrpcArray, xmlrpcString));
 735      $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)';
 736  	function _xmlrpcs_methodSignature($server, $m)
 737      {
 738          $methName = $m->getParam(0);
 739          $methName = $methName->scalarval();
 740          if (ereg("^system\.", $methName))
 741          {
 742              $dmap = $GLOBALS['_xmlrpcs_dmap'];
 743              $sysCall = 1;
 744          }
 745          else
 746          {
 747              $dmap = $server->dmap;
 748              $sysCall = 0;
 749          }
 750          //    print "<!-- ${methName} -->\n";
 751          if (isset($dmap[$methName]))
 752          {
 753              if ($dmap[$methName]['signature'])
 754              {
 755                  $sigs = array();
 756                  $thesigs=$dmap[$methName]['signature'];
 757                  for($i=0; $i<sizeof($thesigs); $i++)
 758                  {
 759                      $cursig = array();
 760                      $inSig  = $thesigs[$i];
 761                      for($j=0; $j<sizeof($inSig); $j++)
 762                      {
 763                          $cursig[] = CreateObject('phpgwapi.xmlrpcval',$inSig[$j], 'string');
 764                      }
 765                      $sigs[] = CreateObject('phpgwapi.xmlrpcval',$cursig, 'array');
 766                  }
 767                  $r = CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$sigs, 'array'));
 768              }
 769              else
 770              {
 771                  $r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval','undef', 'string'));
 772              }
 773          }
 774          else
 775          {
 776              $r = CreateObject('phpgwapi.xmlrpcresp',0,$GLOBALS['xmlrpcerr']['introspect_unknown'],$GLOBALS['xmlrpcstr']['introspect_unknown']);
 777          }
 778          return $r;
 779      }
 780  
 781      $GLOBALS['_xmlrpcs_methodHelp_sig'] = array(array(xmlrpcString, xmlrpcString));
 782      $GLOBALS['_xmlrpcs_methodHelp_doc'] = 'Returns help text if defined for the method passed, otherwise returns an empty string';
 783  	function _xmlrpcs_methodHelp($server, $m)
 784      {
 785          $methName = $m->getParam(0);
 786          $methName = $methName->scalarval();
 787          if (ereg("^system\.", $methName))
 788          {
 789              $dmap = $GLOBALS['_xmlrpcs_dmap'];
 790              $sysCall=1;
 791          }
 792          else
 793          {
 794              $dmap = $server->dmap;
 795              $sysCall=0;
 796          }
 797          //    print "<!-- ${methName} -->\n";
 798          if (isset($dmap[$methName]))
 799          {
 800              if ($dmap[$methName]['docstring'])
 801              {
 802                  $r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval',$dmap[$methName]['docstring']),'string');
 803              }
 804              else
 805              {
 806                  $r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval'), 'string');
 807              }
 808          }
 809          else
 810          {
 811              $r = CreateObject('phpgwapi.xmlrpcresp',0,$GLOBALS['xmlrpcerr']['introspect_unknown'],$GLOBALS['xmlrpcstr']['introspect_unknown']);
 812          }
 813          return $r;
 814      }
 815  
 816      $GLOBALS['_xmlrpcs_login_sig'] = array(array(xmlrpcStruct,xmlrpcStruct));
 817      $GLOBALS['_xmlrpcs_login_doc'] = 'eGroupWare client or server login via XML-RPC';
 818  	function _xmlrpcs_login($server,$m)
 819      {
 820          $rdata = $m->getParam(0);
 821          $data = $rdata->scalarval();
 822  
 823          if($data['server_name'])
 824          {
 825              $server_name = $data['server_name']->scalarval();
 826          }
 827          if($data['domain'])
 828          {
 829              $domain = $data['domain']->scalarval();
 830          }
 831          $username = $data['username']->scalarval();
 832          $password = $data['password']->scalarval();
 833  
 834          if($server_name)
 835          {
 836              list($sessionid,$kp3) = $GLOBALS['egw']->session->create_server($username.'@'.$server_name,$password,"text");
 837          }
 838          else
 839          {
 840              if($domain)
 841              {
 842                  $user = $username.'@'.$domain;
 843              }
 844              else
 845              {
 846                  $user = $username;
 847              }
 848              $GLOBALS['login'] = $user;
 849  
 850              $sessionid = $GLOBALS['egw']->session->create($user,$password,"text");
 851              $kp3 = $GLOBALS['egw']->session->kp3;
 852              $domain = $GLOBALS['egw']->session->account_domain;
 853          }
 854  
 855          if($sessionid && $kp3)
 856          {
 857              $rtrn['domain'] = CreateObject('phpgwapi.xmlrpcval',$domain,'string');
 858              $rtrn['sessionid'] = CreateObject('phpgwapi.xmlrpcval',$sessionid,'string');
 859              $rtrn['kp3'] = CreateObject('phpgwapi.xmlrpcval',$kp3,'string');
 860          }
 861          else
 862          {
 863              $rtrn['GOAWAY'] = CreateObject('phpgwapi.xmlrpcval','XOXO','string');
 864          }
 865          return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$rtrn,'struct'));
 866      }
 867  
 868      $GLOBALS['_xmlrpcs_logout_sig'] = array(array(xmlrpcStruct,xmlrpcStruct));
 869      $GLOBALS['_xmlrpcs_logout_doc'] = 'eGroupWare client or server logout via XML-RPC';
 870  	function _xmlrpcs_logout($server,$m)
 871      {
 872          $rdata = $m->getParam(0);
 873          $data = $rdata->scalarval();
 874  
 875          $sessionid = $data['sessionid']->scalarval();
 876          $kp3       = $data['kp3']->scalarval();
 877  
 878          $later = $GLOBALS['egw']->session->destroy($sessionid,$kp3);
 879  
 880          if ($later)
 881          {
 882              $rtrn['GOODBYE'] = CreateObject('phpgwapi.xmlrpcval','XOXO','string');
 883          }
 884          else
 885          {
 886              /* This never happens, yet */
 887              $rtrn['OOPS'] = CreateObject('phpgwapi.xmlrpcval','WHAT?','string');
 888          }
 889          return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$rtrn,'struct'));
 890      }
 891  
 892      $GLOBALS['_xmlrpcs_phpgw_api_version_sig'] = array(array(xmlrpcString));
 893      $GLOBALS['_xmlrpcs_phpgw_api_version_doc'] = 'Returns the eGroupWare API version';
 894  	function _xmlrpcs_phpgw_api_version($server,$m)
 895      {
 896          $version = $GLOBALS['egw_info']['server']['versions']['phpgwapi'];
 897  
 898          return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$version,'string'));
 899      }
 900  
 901      /*
 902      $GLOBALS['_xmlrpcs_listApps_sig'] = array(array(xmlrpcStruct,xmlrpcString));
 903      $GLOBALS['_xmlrpcs_listApps_doc'] = 'Returns a list of installed phpgw apps';
 904      function _xmlrpcs_listApps($server,$m)
 905      {
 906          $m->getParam(0);
 907          $GLOBALS['egw']->db->query("SELECT * FROM egw_applications WHERE app_enabled<3",__LINE__,__FILE__);
 908          if($GLOBALS['egw']->db->num_rows())
 909          {
 910              while($GLOBALS['egw']->db->next_record())
 911              {
 912                  $name   = $GLOBALS['egw']->db->f('app_name');
 913                  $title  = $GLOBALS['egw']->db->f('app_title');
 914                  $status = $GLOBALS['egw']->db->f('app_enabled');
 915                  $version= $GLOBALS['egw']->db->f('app_version');
 916                  $apps[$name] = CreateObject('phpgwapi.xmlrpcval',
 917                      array(
 918                          'title'  => CreateObject('phpgwapi.xmlrpcval',$title,'string'),
 919                          'name'   => CreateObject('phpgwapi.xmlrpcval',$name,'string'),
 920                          'status' => CreateObject('phpgwapi.xmlrpcval',$status,'string'),
 921                          'version'=> CreateObject('phpgwapi.xmlrpcval',$version,'string')
 922                      ),
 923                      'struct'
 924                  );
 925              }
 926          }
 927          return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$apps, 'struct'));
 928      }
 929      */
 930  
 931      $GLOBALS['_xmlrpcs_egw_time_sig'] = array(array(xmlrpcStruct));
 932      $GLOBALS['_xmlrpcs_egw_time_doc'] = 'returns system-time and -timezone and if loged in user-time and timezone';
 933  	function _xmlrpcs_time($server,$m)
 934      {
 935          $return = array(
 936              'system' => $GLOBALS['server']->date2iso8601(time()),
 937              'system_tz_offset' => (int) date('Z'),
 938          );
 939          if ($GLOBALS['server']->authed)
 940          {
 941              $tz_offset_s = 3600 * (int) $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'];
 942              $return += array(
 943                  'user' => $GLOBALS['server']->date2iso8601(time()+$tz_offset_s),
 944                  'user_tz_offset' => (int) date('Z') + $tz_offset_s,
 945              );
 946          }
 947          return CreateObject(
 948              'phpgwapi.xmlrpcresp',
 949              $GLOBALS['server']->build_resp($return,true)
 950          );
 951      }
 952  
 953      /* Add the system functions to the server map */
 954      $GLOBALS['_xmlrpcs_dmap'] = array(
 955          'system.listMethods' => array(
 956              'function'  => '_xmlrpcs_listMethods',
 957              'signature' => $GLOBALS['_xmlrpcs_listMethods_sig'],
 958              'docstring' => $GLOBALS['_xmlrpcs_listMethods_doc']
 959          ),
 960          'system.methodHelp' => array(
 961              'function'  => '_xmlrpcs_methodHelp',
 962              'signature' => $GLOBALS['_xmlrpcs_methodHelp_sig'],
 963              'docstring' => $GLOBALS['_xmlrpcs_methodHelp_doc']
 964          ),
 965          'system.methodSignature' => array(
 966              'function'  => '_xmlrpcs_methodSignature',
 967              'signature' => $GLOBALS['_xmlrpcs_methodSignature_sig'],
 968              'docstring' => $GLOBALS['_xmlrpcs_methodSignature_doc']
 969          ),
 970          'system.login'  => array(
 971              'function'  => '_xmlrpcs_login',
 972              'signature' => $GLOBALS['_xmlrpcs_login_sig'],
 973              'docstring' => $GLOBALS['_xmlrpcs_login_doc']
 974          ),
 975          'system.logout'  => array(
 976              'function'  => '_xmlrpcs_logout',
 977              'signature' => $GLOBALS['_xmlrpcs_logout_sig'],
 978              'docstring' => $GLOBALS['_xmlrpcs_logout_doc']
 979          ),
 980          'system.phpgw_api_version' => array(
 981              'function'  => '_xmlrpcs_phpgw_api_version',
 982              'signature' => $GLOBALS['_xmlrpcs_phpgw_api_version_sig'],
 983              'docstring' => $GLOBALS['_xmlrpcs_phpgw_api_version_doc']
 984          ),
 985          /*
 986          'system.listApps' => array(
 987              'function'  => '_xmlrpcs_listApps',
 988              'signature' => $GLOBALS['_xmlrpcs_listApps_sig'],
 989              'docstring' => $GLOBALS['_xmlrpcs_listApps_doc']
 990          ),
 991          */
 992          'system.time'  => array(
 993              'function'  => '_xmlrpcs_time',
 994              'signature' => $GLOBALS['_xmlrpcs_egw_time_sig'],
 995              'docstring' => $GLOBALS['_xmlrpcs_egw_time_doc']
 996          )
 997      );
 998  
 999      $GLOBALS['_xmlrpc_debuginfo'] = '';
1000  	function xmlrpc_debugmsg($m)
1001      {
1002          $GLOBALS['_xmlrpc_debuginfo'] .= $m . "\n";
1003      }
1004  ?>


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7