| [ Index ] |
PHP Cross Reference of Wordpress 2.7.1 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * IXR - The Inutio XML-RPC Library 4 * 5 * @package IXR 6 * @since 1.5 7 * 8 * @copyright Incutio Ltd 2002-2005 9 * @version 1.7 (beta) 23rd May 2005 10 * @author Simon Willison 11 * @link http://scripts.incutio.com/xmlrpc/ Site 12 * @link http://scripts.incutio.com/xmlrpc/manual.php Manual 13 * @license BSD License http://www.opensource.org/licenses/bsd-license.php 14 */ 15 16 /** 17 * IXR_Value 18 * 19 * @package IXR 20 * @since 1.5 21 */ 22 class IXR_Value { 23 var $data; 24 var $type; 25 26 function IXR_Value ($data, $type = false) { 27 $this->data = $data; 28 if (!$type) { 29 $type = $this->calculateType(); 30 } 31 $this->type = $type; 32 if ($type == 'struct') { 33 /* Turn all the values in the array in to new IXR_Value objects */ 34 foreach ($this->data as $key => $value) { 35 $this->data[$key] = new IXR_Value($value); 36 } 37 } 38 if ($type == 'array') { 39 for ($i = 0, $j = count($this->data); $i < $j; $i++) { 40 $this->data[$i] = new IXR_Value($this->data[$i]); 41 } 42 } 43 } 44 45 function calculateType() { 46 if ($this->data === true || $this->data === false) { 47 return 'boolean'; 48 } 49 if (is_integer($this->data)) { 50 return 'int'; 51 } 52 if (is_double($this->data)) { 53 return 'double'; 54 } 55 // Deal with IXR object types base64 and date 56 if (is_object($this->data) && is_a($this->data, 'IXR_Date')) { 57 return 'date'; 58 } 59 if (is_object($this->data) && is_a($this->data, 'IXR_Base64')) { 60 return 'base64'; 61 } 62 // If it is a normal PHP object convert it in to a struct 63 if (is_object($this->data)) { 64 65 $this->data = get_object_vars($this->data); 66 return 'struct'; 67 } 68 if (!is_array($this->data)) { 69 return 'string'; 70 } 71 /* We have an array - is it an array or a struct ? */ 72 if ($this->isStruct($this->data)) { 73 return 'struct'; 74 } else { 75 return 'array'; 76 } 77 } 78 79 function getXml() { 80 /* Return XML for this value */ 81 switch ($this->type) { 82 case 'boolean': 83 return '<boolean>'.(($this->data) ? '1' : '0').'</boolean>'; 84 break; 85 case 'int': 86 return '<int>'.$this->data.'</int>'; 87 break; 88 case 'double': 89 return '<double>'.$this->data.'</double>'; 90 break; 91 case 'string': 92 return '<string>'.htmlspecialchars($this->data).'</string>'; 93 break; 94 case 'array': 95 $return = '<array><data>'."\n"; 96 foreach ($this->data as $item) { 97 $return .= ' <value>'.$item->getXml()."</value>\n"; 98 } 99 $return .= '</data></array>'; 100 return $return; 101 break; 102 case 'struct': 103 $return = '<struct>'."\n"; 104 foreach ($this->data as $name => $value) { 105 $name = htmlspecialchars($name); 106 $return .= " <member><name>$name</name><value>"; 107 $return .= $value->getXml()."</value></member>\n"; 108 } 109 $return .= '</struct>'; 110 return $return; 111 break; 112 case 'date': 113 case 'base64': 114 return $this->data->getXml(); 115 break; 116 } 117 return false; 118 } 119 120 function isStruct($array) { 121 /* Nasty function to check if an array is a struct or not */ 122 $expected = 0; 123 foreach ($array as $key => $value) { 124 if ((string)$key != (string)$expected) { 125 return true; 126 } 127 $expected++; 128 } 129 return false; 130 } 131 } 132 133 /** 134 * IXR_Message 135 * 136 * @package IXR 137 * @since 1.5 138 */ 139 class IXR_Message { 140 var $message; 141 var $messageType; // methodCall / methodResponse / fault 142 var $faultCode; 143 var $faultString; 144 var $methodName; 145 var $params; 146 // Current variable stacks 147 var $_arraystructs = array(); // The stack used to keep track of the current array/struct 148 var $_arraystructstypes = array(); // Stack keeping track of if things are structs or array 149 var $_currentStructName = array(); // A stack as well 150 var $_param; 151 var $_value; 152 var $_currentTag; 153 var $_currentTagContents; 154 // The XML parser 155 var $_parser; 156 function IXR_Message ($message) { 157 $this->message = $message; 158 } 159 function parse() { 160 // first remove the XML declaration 161 $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); 162 if (trim($this->message) == '') { 163 return false; 164 } 165 $this->_parser = xml_parser_create(); 166 // Set XML parser to take the case of tags in to account 167 xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); 168 // Set XML parser callback functions 169 xml_set_object($this->_parser, $this); 170 xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); 171 xml_set_character_data_handler($this->_parser, 'cdata'); 172 if (!xml_parse($this->_parser, $this->message)) { 173 /* die(sprintf('XML error: %s at line %d', 174 xml_error_string(xml_get_error_code($this->_parser)), 175 xml_get_current_line_number($this->_parser))); */ 176 return false; 177 } 178 xml_parser_free($this->_parser); 179 // Grab the error messages, if any 180 if ($this->messageType == 'fault') { 181 $this->faultCode = $this->params[0]['faultCode']; 182 $this->faultString = $this->params[0]['faultString']; 183 } 184 return true; 185 } 186 function tag_open($parser, $tag, $attr) { 187 $this->_currentTagContents = ''; 188 $this->currentTag = $tag; 189 switch($tag) { 190 case 'methodCall': 191 case 'methodResponse': 192 case 'fault': 193 $this->messageType = $tag; 194 break; 195 /* Deal with stacks of arrays and structs */ 196 case 'data': // data is to all intents and puposes more interesting than array 197 $this->_arraystructstypes[] = 'array'; 198 $this->_arraystructs[] = array(); 199 break; 200 case 'struct': 201 $this->_arraystructstypes[] = 'struct'; 202 $this->_arraystructs[] = array(); 203 break; 204 } 205 } 206 function cdata($parser, $cdata) { 207 $this->_currentTagContents .= $cdata; 208 } 209 function tag_close($parser, $tag) { 210 $valueFlag = false; 211 switch($tag) { 212 case 'int': 213 case 'i4': 214 $value = (int) trim($this->_currentTagContents); 215 $valueFlag = true; 216 break; 217 case 'double': 218 $value = (double) trim($this->_currentTagContents); 219 $valueFlag = true; 220 break; 221 case 'string': 222 $value = $this->_currentTagContents; 223 $valueFlag = true; 224 break; 225 case 'dateTime.iso8601': 226 $value = new IXR_Date(trim($this->_currentTagContents)); 227 // $value = $iso->getTimestamp(); 228 $valueFlag = true; 229 break; 230 case 'value': 231 // "If no type is indicated, the type is string." 232 if (trim($this->_currentTagContents) != '') { 233 $value = (string)$this->_currentTagContents; 234 $valueFlag = true; 235 } 236 break; 237 case 'boolean': 238 $value = (boolean) trim($this->_currentTagContents); 239 $valueFlag = true; 240 break; 241 case 'base64': 242 $value = base64_decode( trim( $this->_currentTagContents ) ); 243 $valueFlag = true; 244 break; 245 /* Deal with stacks of arrays and structs */ 246 case 'data': 247 case 'struct': 248 $value = array_pop($this->_arraystructs); 249 array_pop($this->_arraystructstypes); 250 $valueFlag = true; 251 break; 252 case 'member': 253 array_pop($this->_currentStructName); 254 break; 255 case 'name': 256 $this->_currentStructName[] = trim($this->_currentTagContents); 257 break; 258 case 'methodName': 259 $this->methodName = trim($this->_currentTagContents); 260 break; 261 } 262 if ($valueFlag) { 263 if (count($this->_arraystructs) > 0) { 264 // Add value to struct or array 265 if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { 266 // Add to struct 267 $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; 268 } else { 269 // Add to array 270 $this->_arraystructs[count($this->_arraystructs)-1][] = $value; 271 } 272 } else { 273 // Just add as a paramater 274 $this->params[] = $value; 275 } 276 } 277 $this->_currentTagContents = ''; 278 } 279 } 280 281 /** 282 * IXR_Server 283 * 284 * @package IXR 285 * @since 1.5 286 */ 287 class IXR_Server { 288 var $data; 289 var $callbacks = array(); 290 var $message; 291 var $capabilities; 292 function IXR_Server($callbacks = false, $data = false) { 293 $this->setCapabilities(); 294 if ($callbacks) { 295 $this->callbacks = $callbacks; 296 } 297 $this->setCallbacks(); 298 $this->serve($data); 299 } 300 function serve($data = false) { 301 if (!$data) { 302 global $HTTP_RAW_POST_DATA; 303 if (!$HTTP_RAW_POST_DATA) { 304 die('XML-RPC server accepts POST requests only.'); 305 } 306 $data = $HTTP_RAW_POST_DATA; 307 } 308 $this->message = new IXR_Message($data); 309 if (!$this->message->parse()) { 310 $this->error(-32700, 'parse error. not well formed'); 311 } 312 if ($this->message->messageType != 'methodCall') { 313 $this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall'); 314 } 315 $result = $this->call($this->message->methodName, $this->message->params); 316 // Is the result an error? 317 if (is_a($result, 'IXR_Error')) { 318 $this->error($result); 319 } 320 // Encode the result 321 $r = new IXR_Value($result); 322 $resultxml = $r->getXml(); 323 // Create the XML 324 $xml = <<<EOD 325 <methodResponse> 326 <params> 327 <param> 328 <value> 329 $resultxml 330 </value> 331 </param> 332 </params> 333 </methodResponse> 334 335 EOD; 336 // Send it 337 $this->output($xml); 338 } 339 function call($methodname, $args) { 340 if (!$this->hasMethod($methodname)) { 341 return new IXR_Error(-32601, 'server error. requested method '. 342 $methodname.' does not exist.'); 343 } 344 $method = $this->callbacks[$methodname]; 345 // Perform the callback and send the response 346 if (count($args) == 1) { 347 // If only one paramater just send that instead of the whole array 348 $args = $args[0]; 349 } 350 // Are we dealing with a function or a method? 351 if (substr($method, 0, 5) == 'this:') { 352 // It's a class method - check it exists 353 $method = substr($method, 5); 354 if (!method_exists($this, $method)) { 355 return new IXR_Error(-32601, 'server error. requested class method "'. 356 $method.'" does not exist.'); 357 } 358 // Call the method 359 $result = $this->$method($args); 360 } else { 361 // It's a function - does it exist? 362 if (is_array($method)) { 363 if (!method_exists($method[0], $method[1])) { 364 return new IXR_Error(-32601, 'server error. requested object method "'. 365 $method[1].'" does not exist.'); 366 } 367 } else if (!function_exists($method)) { 368 return new IXR_Error(-32601, 'server error. requested function "'. 369 $method.'" does not exist.'); 370 } 371 // Call the function 372 $result = call_user_func($method, $args); 373 } 374 return $result; 375 } 376 377 function error($error, $message = false) { 378 // Accepts either an error object or an error code and message 379 if ($message && !is_object($error)) { 380 $error = new IXR_Error($error, $message); 381 } 382 $this->output($error->getXml()); 383 } 384 function output($xml) { 385 $xml = '<?xml version="1.0"?>'."\n".$xml; 386 $length = strlen($xml); 387 header('Connection: close'); 388 header('Content-Length: '.$length); 389 header('Content-Type: text/xml'); 390 header('Date: '.date('r')); 391 echo $xml; 392 exit; 393 } 394 function hasMethod($method) { 395 return in_array($method, array_keys($this->callbacks)); 396 } 397 function setCapabilities() { 398 // Initialises capabilities array 399 $this->capabilities = array( 400 'xmlrpc' => array( 401 'specUrl' => 'http://www.xmlrpc.com/spec', 402 'specVersion' => 1 403 ), 404 'faults_interop' => array( 405 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php', 406 'specVersion' => 20010516 407 ), 408 'system.multicall' => array( 409 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208', 410 'specVersion' => 1 411 ), 412 ); 413 } 414 function getCapabilities($args) { 415 return $this->capabilities; 416 } 417 function setCallbacks() { 418 $this->callbacks['system.getCapabilities'] = 'this:getCapabilities'; 419 $this->callbacks['system.listMethods'] = 'this:listMethods'; 420 $this->callbacks['system.multicall'] = 'this:multiCall'; 421 } 422 function listMethods($args) { 423 // Returns a list of methods - uses array_reverse to ensure user defined 424 // methods are listed before server defined methods 425 return array_reverse(array_keys($this->callbacks)); 426 } 427 function multiCall($methodcalls) { 428 // See http://www.xmlrpc.com/discuss/msgReader$1208 429 $return = array(); 430 foreach ($methodcalls as $call) { 431 $method = $call['methodName']; 432 $params = $call['params']; 433 if ($method == 'system.multicall') { 434 $result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden'); 435 } else { 436 $result = $this->call($method, $params); 437 } 438 if (is_a($result, 'IXR_Error')) { 439 $return[] = array( 440 'faultCode' => $result->code, 441 'faultString' => $result->message 442 ); 443 } else { 444 $return[] = array($result); 445 } 446 } 447 return $return; 448 } 449 } 450 451 /** 452 * IXR_Request 453 * 454 * @package IXR 455 * @since 1.5 456 */ 457 class IXR_Request { 458 var $method; 459 var $args; 460 var $xml; 461 function IXR_Request($method, $args) { 462 $this->method = $method; 463 $this->args = $args; 464 $this->xml = <<<EOD 465 <?xml version="1.0"?> 466 <methodCall> 467 <methodName>{$this->method}</methodName> 468 <params> 469 470 EOD; 471 foreach ($this->args as $arg) { 472 $this->xml .= '<param><value>'; 473 $v = new IXR_Value($arg); 474 $this->xml .= $v->getXml(); 475 $this->xml .= "</value></param>\n"; 476 } 477 $this->xml .= '</params></methodCall>'; 478 } 479 function getLength() { 480 return strlen($this->xml); 481 } 482 function getXml() { 483 return $this->xml; 484 } 485 } 486 487 /** 488 * IXR_Client 489 * 490 * @package IXR 491 * @since 1.5 492 */ 493 class IXR_Client { 494 var $server; 495 var $port; 496 var $path; 497 var $useragent; 498 var $response; 499 var $message = false; 500 var $debug = false; 501 var $timeout; 502 // Storage place for an error message 503 var $error = false; 504 function IXR_Client($server, $path = false, $port = 80, $timeout = false) { 505 if (!$path) { 506 // Assume we have been given a URL instead 507 $bits = parse_url($server); 508 $this->server = $bits['host']; 509 $this->port = isset($bits['port']) ? $bits['port'] : 80; 510 $this->path = isset($bits['path']) ? $bits['path'] : '/'; 511 // Make absolutely sure we have a path 512 if (!$this->path) { 513 $this->path = '/'; 514 } 515 } else { 516 $this->server = $server; 517 $this->path = $path; 518 $this->port = $port; 519 } 520 $this->useragent = 'The Incutio XML-RPC PHP Library'; 521 $this->timeout = $timeout; 522 } 523 function query() { 524 $args = func_get_args(); 525 $method = array_shift($args); 526 $request = new IXR_Request($method, $args); 527 $length = $request->getLength(); 528 $xml = $request->getXml(); 529 $r = "\r\n"; 530 $request = "POST {$this->path} HTTP/1.0$r"; 531 $request .= "Host: {$this->server}$r"; 532 $request .= "Content-Type: text/xml$r"; 533 $request .= "User-Agent: {$this->useragent}$r"; 534 $request .= "Content-length: {$length}$r$r"; 535 $request .= $xml; 536 // Now send the request 537 if ($this->debug) { 538 echo '<pre>'.htmlspecialchars($request)."\n</pre>\n\n"; 539 } 540 if ($this->timeout) { 541 $fp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout); 542 } else { 543 $fp = @fsockopen($this->server, $this->port, $errno, $errstr); 544 } 545 if (!$fp) { 546 $this->error = new IXR_Error(-32300, "transport error - could not open socket: $errno $errstr"); 547 return false; 548 } 549 fputs($fp, $request); 550 $contents = ''; 551 $gotFirstLine = false; 552 $gettingHeaders = true; 553 while (!feof($fp)) { 554 $line = fgets($fp, 4096); 555 if (!$gotFirstLine) { 556 // Check line for '200' 557 if (strstr($line, '200') === false) { 558 $this->error = new IXR_Error(-32300, 'transport error - HTTP status code was not 200'); 559 return false; 560 } 561 $gotFirstLine = true; 562 } 563 if (trim($line) == '') { 564 $gettingHeaders = false; 565 } 566 if (!$gettingHeaders) { 567 $contents .= trim($line); 568 } 569 } 570 if ($this->debug) { 571 echo '<pre>'.htmlspecialchars($contents)."\n</pre>\n\n"; 572 } 573 // Now parse what we've got back 574 $this->message = new IXR_Message($contents); 575 if (!$this->message->parse()) { 576 // XML error 577 $this->error = new IXR_Error(-32700, 'parse error. not well formed'); 578 return false; 579 } 580 // Is the message a fault? 581 if ($this->message->messageType == 'fault') { 582 $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString); 583 return false; 584 } 585 // Message must be OK 586 return true; 587 } 588 function getResponse() { 589 // methodResponses can only have one param - return that 590 return $this->message->params[0]; 591 } 592 function isError() { 593 return (is_object($this->error)); 594 } 595 function getErrorCode() { 596 return $this->error->code; 597 } 598 function getErrorMessage() { 599 return $this->error->message; 600 } 601 } 602 603 /** 604 * IXR_Error 605 * 606 * @package IXR 607 * @since 1.5 608 */ 609 class IXR_Error { 610 var $code; 611 var $message; 612 function IXR_Error($code, $message) { 613 $this->code = $code; 614 // WP adds htmlspecialchars(). See #5666 615 $this->message = htmlspecialchars($message); 616 } 617 function getXml() { 618 $xml = <<<EOD 619 <methodResponse> 620 <fault> 621 <value> 622 <struct> 623 <member> 624 <name>faultCode</name> 625 <value><int>{$this->code}</int></value> 626 </member> 627 <member> 628 <name>faultString</name> 629 <value><string>{$this->message}</string></value> 630 </member> 631 </struct> 632 </value> 633 </fault> 634 </methodResponse> 635 636 EOD; 637 return $xml; 638 } 639 } 640 641 /** 642 * IXR_Date 643 * 644 * @package IXR 645 * @since 1.5 646 */ 647 class IXR_Date { 648 var $year; 649 var $month; 650 var $day; 651 var $hour; 652 var $minute; 653 var $second; 654 var $timezone; 655 function IXR_Date($time) { 656 // $time can be a PHP timestamp or an ISO one 657 if (is_numeric($time)) { 658 $this->parseTimestamp($time); 659 } else { 660 $this->parseIso($time); 661 } 662 } 663 function parseTimestamp($timestamp) { 664 $this->year = date('Y', $timestamp); 665 $this->month = date('m', $timestamp); 666 $this->day = date('d', $timestamp); 667 $this->hour = date('H', $timestamp); 668 $this->minute = date('i', $timestamp); 669 $this->second = date('s', $timestamp); 670 // WP adds timezone. See #2036 671 $this->timezone = ''; 672 } 673 function parseIso($iso) { 674 $this->year = substr($iso, 0, 4); 675 $this->month = substr($iso, 4, 2); 676 $this->day = substr($iso, 6, 2); 677 $this->hour = substr($iso, 9, 2); 678 $this->minute = substr($iso, 12, 2); 679 $this->second = substr($iso, 15, 2); 680 // WP adds timezone. See #2036 681 $this->timezone = substr($iso, 17); 682 } 683 function getIso() { 684 // WP adds timezone. See #2036 685 return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second.$this->timezone; 686 } 687 function getXml() { 688 return '<dateTime.iso8601>'.$this->getIso().'</dateTime.iso8601>'; 689 } 690 function getTimestamp() { 691 return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); 692 } 693 } 694 695 /** 696 * IXR_Base64 697 * 698 * @package IXR 699 * @since 1.5 700 */ 701 class IXR_Base64 { 702 var $data; 703 function IXR_Base64($data) { 704 $this->data = $data; 705 } 706 function getXml() { 707 return '<base64>'.base64_encode($this->data).'</base64>'; 708 } 709 } 710 711 /** 712 * IXR_IntrospectionServer 713 * 714 * @package IXR 715 * @since 1.5 716 */ 717 class IXR_IntrospectionServer extends IXR_Server { 718 var $signatures; 719 var $help; 720 function IXR_IntrospectionServer() { 721 $this->setCallbacks(); 722 $this->setCapabilities(); 723 $this->capabilities['introspection'] = array( 724 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html', 725 'specVersion' => 1 726 ); 727 $this->addCallback( 728 'system.methodSignature', 729 'this:methodSignature', 730 array('array', 'string'), 731 'Returns an array describing the return type and required parameters of a method' 732 ); 733 $this->addCallback( 734 'system.getCapabilities', 735 'this:getCapabilities', 736 array('struct'), 737 'Returns a struct describing the XML-RPC specifications supported by this server' 738 ); 739 $this->addCallback( 740 'system.listMethods', 741 'this:listMethods', 742 array('array'), 743 'Returns an array of available methods on this server' 744 ); 745 $this->addCallback( 746 'system.methodHelp', 747 'this:methodHelp', 748 array('string', 'string'), 749 'Returns a documentation string for the specified method' 750 ); 751 } 752 function addCallback($method, $callback, $args, $help) { 753 $this->callbacks[$method] = $callback; 754 $this->signatures[$method] = $args; 755 $this->help[$method] = $help; 756 } 757 function call($methodname, $args) { 758 // Make sure it's in an array 759 if ($args && !is_array($args)) { 760 $args = array($args); 761 } 762 // Over-rides default call method, adds signature check 763 if (!$this->hasMethod($methodname)) { 764 return new IXR_Error(-32601, 'server error. requested method "'.$this->message->methodName.'" not specified.'); 765 } 766 $method = $this->callbacks[$methodname]; 767 $signature = $this->signatures[$methodname]; 768 $returnType = array_shift($signature); 769 // Check the number of arguments 770 if (count($args) != count($signature)) { 771 return new IXR_Error(-32602, 'server error. wrong number of method parameters'); 772 } 773 // Check the argument types 774 $ok = true; 775 $argsbackup = $args; 776 for ($i = 0, $j = count($args); $i < $j; $i++) { 777 $arg = array_shift($args); 778 $type = array_shift($signature); 779 switch ($type) { 780 case 'int': 781 case 'i4': 782 if (is_array($arg) || !is_int($arg)) { 783 $ok = false; 784 } 785 break; 786 case 'base64': 787 case 'string': 788 if (!is_string($arg)) { 789 $ok = false; 790 } 791 break; 792 case 'boolean': 793 if ($arg !== false && $arg !== true) { 794 $ok = false; 795 } 796 break; 797 case 'float': 798 case 'double': 799 if (!is_float($arg)) { 800 $ok = false; 801 } 802 break; 803 case 'date': 804 case 'dateTime.iso8601': 805 if (!is_a($arg, 'IXR_Date')) { 806 $ok = false; 807 } 808 break; 809 } 810 if (!$ok) { 811 return new IXR_Error(-32602, 'server error. invalid method parameters'); 812 } 813 } 814 // It passed the test - run the "real" method call 815 return parent::call($methodname, $argsbackup); 816 } 817 function methodSignature($method) { 818 if (!$this->hasMethod($method)) { 819 return new IXR_Error(-32601, 'server error. requested method "'.$method.'" not specified.'); 820 } 821 // We should be returning an array of types 822 $types = $this->signatures[$method]; 823 $return = array(); 824 foreach ($types as $type) { 825 switch ($type) { 826 case 'string': 827 $return[] = 'string'; 828 break; 829 case 'int': 830 case 'i4': 831 $return[] = 42; 832 break; 833 case 'double': 834 $return[] = 3.1415; 835 break; 836 case 'dateTime.iso8601': 837 $return[] = new IXR_Date(time()); 838 break; 839 case 'boolean': 840 $return[] = true; 841 break; 842 case 'base64': 843 $return[] = new IXR_Base64('base64'); 844 break; 845 case 'array': 846 $return[] = array('array'); 847 break; 848 case 'struct': 849 $return[] = array('struct' => 'struct'); 850 break; 851 } 852 } 853 return $return; 854 } 855 function methodHelp($method) { 856 return $this->help[$method]; 857 } 858 } 859 860 /** 861 * IXR_ClientMulticall 862 * 863 * @package IXR 864 * @since 1.5 865 */ 866 class IXR_ClientMulticall extends IXR_Client { 867 var $calls = array(); 868 function IXR_ClientMulticall($server, $path = false, $port = 80) { 869 parent::IXR_Client($server, $path, $port); 870 $this->useragent = 'The Incutio XML-RPC PHP Library (multicall client)'; 871 } 872 function addCall() { 873 $args = func_get_args(); 874 $methodName = array_shift($args); 875 $struct = array( 876 'methodName' => $methodName, 877 'params' => $args 878 ); 879 $this->calls[] = $struct; 880 } 881 function query() { 882 // Prepare multicall, then call the parent::query() method 883 return parent::query('system.multicall', $this->calls); 884 } 885 } 886 887 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Mar 23 16:23:02 2009 | Cross-referenced by PHPXref 0.7 |