[ Index ] |
|
Code source de Dotclear 2.0-beta6 |
1 <?php 2 # ***** BEGIN LICENSE BLOCK ***** 3 # This file is part of Clearbricks. 4 # Copyright (c) 2007 Olivier Meunier and contributors. 5 # All rights reserved. 6 # 7 # Clearbricks is free software; you can redistribute it and/or modify 8 # it under the terms of the GNU General Public License as published by 9 # the Free Software Foundation; either version 2 of the License, or 10 # (at your option) any later version. 11 # 12 # Clearbricks is distributed in the hope that it will be useful, 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # GNU General Public License for more details. 16 # 17 # You should have received a copy of the GNU General Public License 18 # along with Clearbricks; if not, write to the Free Software 19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 # 21 # ***** END LICENSE BLOCK ***** 22 23 class xmlrpcException extends Exception 24 { 25 public function __construct($message,$code=0) 26 { 27 parent::__construct($message,$code); 28 } 29 } 30 31 class xmlrpcValue 32 { 33 protected $data; 34 protected $type; 35 36 public function __construct($data, $type = false) 37 { 38 $this->data = $data; 39 if (!$type) { 40 $type = $this->calculateType(); 41 } 42 $this->type = $type; 43 if ($type == 'struct') { 44 # Turn all the values in the array in to new xmlrpcValue objects 45 foreach ($this->data as $key => $value) { 46 $this->data[$key] = new xmlrpcValue($value); 47 } 48 } 49 if ($type == 'array') { 50 for ($i = 0, $j = count($this->data); $i < $j; $i++) { 51 $this->data[$i] = new xmlrpcValue($this->data[$i]); 52 } 53 } 54 } 55 56 public function getXml() 57 { 58 # Return XML for this value 59 switch ($this->type) 60 { 61 case 'boolean': 62 return '<boolean>'.(($this->data) ? '1' : '0').'</boolean>'; 63 break; 64 case 'int': 65 return '<int>'.$this->data.'</int>'; 66 break; 67 case 'double': 68 return '<double>'.$this->data.'</double>'; 69 break; 70 case 'string': 71 return '<string>'.htmlspecialchars($this->data).'</string>'; 72 break; 73 case 'array': 74 $return = '<array><data>'."\n"; 75 foreach ($this->data as $item) { 76 $return .= ' <value>'.$item->getXml()."</value>\n"; 77 } 78 $return .= '</data></array>'; 79 return $return; 80 break; 81 case 'struct': 82 $return = '<struct>'."\n"; 83 foreach ($this->data as $name => $value) { 84 $return .= " <member><name>$name</name><value>"; 85 $return .= $value->getXml()."</value></member>\n"; 86 } 87 $return .= '</struct>'; 88 return $return; 89 break; 90 case 'date': 91 case 'base64': 92 return $this->data->getXml(); 93 break; 94 } 95 return false; 96 } 97 98 protected function calculateType() 99 { 100 if ($this->data === true || $this->data === false) { 101 return 'boolean'; 102 } 103 if (is_integer($this->data)) { 104 return 'int'; 105 } 106 if (is_double($this->data)) { 107 return 'double'; 108 } 109 # Deal with xmlrpc object types base64 and date 110 if (is_object($this->data) && $this->data instanceof xmlrpcDate) { 111 return 'date'; 112 } 113 if (is_object($this->data) && $this->data instanceof xmlrpcBase64) { 114 return 'base64'; 115 } 116 # If it is a normal PHP object convert it in to a struct 117 if (is_object($this->data)) { 118 $this->data = get_object_vars($this->data); 119 return 'struct'; 120 } 121 if (!is_array($this->data)) { 122 return 'string'; 123 } 124 # We have an array - is it an array or a struct ? 125 if ($this->isStruct($this->data)) { 126 return 'struct'; 127 } else { 128 return 'array'; 129 } 130 } 131 132 protected function isStruct($array) 133 { 134 # Nasty function to check if an array is a struct or not 135 $expected = 0; 136 foreach ($array as $key => $value) { 137 if ((string)$key != (string)$expected) { 138 return true; 139 } 140 $expected++; 141 } 142 return false; 143 } 144 } 145 146 class xmlrpcMessage 147 { 148 protected $brutxml; 149 protected $message; 150 151 public $messageType; # methodCall / methodResponse / fault 152 public $faultCode; 153 public $faultString; 154 public $methodName; 155 public $params; 156 157 # Current variable stacks 158 protected $_arraystructs = array(); # The stack used to keep track of the current array/struct 159 protected $_arraystructstypes = array(); # Stack keeping track of if things are structs or array 160 protected $_currentStructName = array(); # A stack as well 161 protected $_param; 162 protected $_value; 163 protected $_currentTag; 164 protected $_currentTagContents; 165 166 # The XML parser 167 protected $_parser; 168 169 public function __construct($message) 170 { 171 $this->brutxml = $this->message = $message; 172 } 173 174 public function parse() 175 { 176 // first remove the XML declaration 177 $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); 178 179 if (trim($this->message) == '') { 180 throw new Exception('XML Parser Error. Empty message'); 181 } 182 183 $this->_parser = xml_parser_create(); 184 185 # Set XML parser to take the case of tags in to account 186 xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); 187 188 # Set XML parser callback functions 189 xml_set_object($this->_parser, $this); 190 xml_set_element_handler($this->_parser, 'tag_open','tag_close'); 191 xml_set_character_data_handler($this->_parser, 'cdata'); 192 193 if (!xml_parse($this->_parser, $this->message)) 194 { 195 $c = xml_get_error_code($this->_parser); 196 $e = xml_error_string($c); 197 $e .= ' on line '.xml_get_current_line_number($this->_parser); 198 throw new Exception('XML Parser Error. '.$e,$c); 199 } 200 201 xml_parser_free($this->_parser); 202 203 # Grab the error messages, if any 204 if ($this->messageType == 'fault') 205 { 206 $this->faultCode = $this->params[0]['faultCode']; 207 $this->faultString = $this->params[0]['faultString']; 208 } 209 return true; 210 } 211 212 protected function tag_open($parser,$tag,$attr) 213 { 214 $this->currentTag = $tag; 215 216 switch($tag) 217 { 218 case 'methodCall': 219 case 'methodResponse': 220 case 'fault': 221 $this->messageType = $tag; 222 break; 223 # Deal with stacks of arrays and structs 224 case 'data': # data is to all intents and puposes more interesting than array 225 $this->_arraystructstypes[] = 'array'; 226 $this->_arraystructs[] = array(); 227 break; 228 case 'struct': 229 $this->_arraystructstypes[] = 'struct'; 230 $this->_arraystructs[] = array(); 231 break; 232 } 233 } 234 235 protected function cdata($parser,$cdata) 236 { 237 $this->_currentTagContents .= $cdata; 238 } 239 240 protected function tag_close($parser,$tag) 241 { 242 $valueFlag = false; 243 244 switch($tag) 245 { 246 case 'int': 247 case 'i4': 248 $value = (int)trim($this->_currentTagContents); 249 $this->_currentTagContents = ''; 250 $valueFlag = true; 251 break; 252 case 'double': 253 $value = (double)trim($this->_currentTagContents); 254 $this->_currentTagContents = ''; 255 $valueFlag = true; 256 break; 257 case 'string': 258 $value = (string)trim($this->_currentTagContents); 259 $this->_currentTagContents = ''; 260 $valueFlag = true; 261 break; 262 case 'dateTime.iso8601': 263 $value = new xmlrpcDate(trim($this->_currentTagContents)); 264 # $value = $iso->getTimestamp(); 265 $this->_currentTagContents = ''; 266 $valueFlag = true; 267 break; 268 case 'value': 269 # "If no type is indicated, the type is string." 270 if (trim($this->_currentTagContents) != '') 271 { 272 $value = (string)$this->_currentTagContents; 273 $this->_currentTagContents = ''; 274 $valueFlag = true; 275 } 276 break; 277 case 'boolean': 278 $value = (boolean)trim($this->_currentTagContents); 279 $this->_currentTagContents = ''; 280 $valueFlag = true; 281 break; 282 case 'base64': 283 $value = base64_decode($this->_currentTagContents); 284 $this->_currentTagContents = ''; 285 $valueFlag = true; 286 break; 287 # Deal with stacks of arrays and structs 288 case 'data': 289 case 'struct': 290 $value = array_pop($this->_arraystructs); 291 array_pop($this->_arraystructstypes); 292 $valueFlag = true; 293 break; 294 case 'member': 295 array_pop($this->_currentStructName); 296 break; 297 case 'name': 298 $this->_currentStructName[] = trim($this->_currentTagContents); 299 $this->_currentTagContents = ''; 300 break; 301 case 'methodName': 302 $this->methodName = trim($this->_currentTagContents); 303 $this->_currentTagContents = ''; 304 break; 305 } 306 307 if ($valueFlag) 308 { 309 if (count($this->_arraystructs) > 0) 310 { 311 # Add value to struct or array 312 if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { 313 # Add to struct 314 $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; 315 } else { 316 # Add to array 317 $this->_arraystructs[count($this->_arraystructs)-1][] = $value; 318 } 319 } 320 else 321 { 322 # Just add as a paramater 323 $this->params[] = $value; 324 } 325 } 326 } 327 } 328 329 class xmlrpcRequest 330 { 331 public $method; 332 public $args; 333 public $xml; 334 335 function __construct($method, $args) 336 { 337 $this->method = $method; 338 $this->args = $args; 339 340 $this->xml = 341 '<?xml version="1.0"?>'."\n". 342 "<methodCall>\n". 343 ' <methodName>'.$this->method."</methodName>\n". 344 " <params>\n"; 345 346 foreach ($this->args as $arg) 347 { 348 $this->xml .= ' <param><value>'; 349 $v = new xmlrpcValue($arg); 350 $this->xml .= $v->getXml(); 351 $this->xml .= "</value></param>\n"; 352 } 353 354 $this->xml .= ' </params></methodCall>'; 355 } 356 357 public function getLength() 358 { 359 return strlen($this->xml); 360 } 361 362 public function getXml() 363 { 364 return $this->xml; 365 } 366 } 367 368 class xmlrpcDate 369 { 370 protected $year; 371 protected $month; 372 protected $day; 373 protected $hour; 374 protected $minute; 375 protected $second; 376 377 public function __construct($time) 378 { 379 # $time can be a PHP timestamp or an ISO one 380 if (is_numeric($time)) { 381 $this->parseTimestamp($time); 382 } else { 383 $this->parseTimestamp(strtotime($time)); 384 } 385 } 386 387 protected function parseTimestamp($timestamp) 388 { 389 $this->year = date('Y', $timestamp); 390 $this->month = date('m', $timestamp); 391 $this->day = date('d', $timestamp); 392 $this->hour = date('H', $timestamp); 393 $this->minute = date('i', $timestamp); 394 $this->second = date('s', $timestamp); 395 $this->ts = $timestamp; 396 } 397 398 public function getIso() 399 { 400 return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second; 401 } 402 403 public function getXml() 404 { 405 return '<dateTime.iso8601>'.$this->getIso().'</dateTime.iso8601>'; 406 } 407 408 public function getTimestamp() 409 { 410 return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); 411 } 412 } 413 414 class xmlrpcBase64 415 { 416 protected $data; 417 418 public function __construct($data) 419 { 420 $this->data = $data; 421 } 422 423 public function getXml() 424 { 425 return '<base64>'.base64_encode($this->data).'</base64>'; 426 } 427 } 428 429 class xmlrpcClient extends netHttp 430 { 431 protected $request; 432 protected $message; 433 434 public function __construct($url) 435 { 436 if (!$this->readUrl($url,$ssl,$host,$port,$path,$user,$pass)) { 437 return false; 438 } 439 440 parent::__construct($host,$port); 441 $this->useSSL($ssl); 442 $this->setAuthorization($user,$pass); 443 444 $this->path = $path; 445 $this->user_agent = 'Clearbricks XML/RPC Client'; 446 } 447 448 public function query() 449 { 450 $args = func_get_args(); 451 $method = array_shift($args); 452 $this->request = new xmlrpcRequest($method, $args); 453 454 $this->doRequest(); 455 456 if ($this->status != 200) { 457 throw new Exception('HTTP Error. '.$this->status.' '.$this->status_string); 458 } 459 460 # Now parse what we've got back 461 $this->message = new xmlrpcMessage($this->content); 462 $this->message->parse(); 463 464 # Is the message a fault? 465 if ($this->message->messageType == 'fault') 466 { 467 throw new xmlrpcException($this->message->faultString,$this->message->faultCode); 468 } 469 470 return $this->message->params[0]; 471 } 472 473 # Overloading netHttp::buildRequest method, we don't need all the stuff of 474 # HTTP client. 475 protected function buildRequest() 476 { 477 if ($this->proxy_host) { 478 $path = $this->getRequestURL(); 479 } else { 480 $path = $this->path; 481 } 482 483 return array( 484 'POST '.$path.' HTTP/1.0', 485 'Host: '.$this->host, 486 'Content-Type: text/xml', 487 'User-Agent: '.$this->user_agent, 488 'Content-Length: '.$this->request->getLength(), 489 '', 490 $this->request->getXML() 491 ); 492 } 493 } 494 495 class xmlrpcClientMulticall extends xmlrpcClient 496 { 497 protected $calls = array(); 498 499 function __construct($url) 500 { 501 parent::__construct($url); 502 } 503 504 function addCall() 505 { 506 $args = func_get_args(); 507 $methodName = array_shift($args); 508 509 $struct = array( 510 'methodName' => $methodName, 511 'params' => $args 512 ); 513 514 $this->calls[] = $struct; 515 } 516 517 function query() 518 { 519 # Prepare multicall, then call the parent::query() method 520 return parent::query('system.multicall',$this->calls); 521 } 522 } 523 524 class xmlrpcServer 525 { 526 protected $callbacks = array(); 527 protected $data; 528 protected $encoding; 529 protected $message; 530 protected $capabilities; 531 532 public $strict_check = false; 533 534 public function __construct($callbacks=false,$data=false,$encoding='UTF-8') 535 { 536 $this->encoding = $encoding; 537 $this->setCapabilities(); 538 if ($callbacks) { 539 $this->callbacks = $callbacks; 540 } 541 $this->setCallbacks(); 542 $this->serve($data); 543 } 544 545 public function serve($data=false) 546 { 547 if (!$data) 548 { 549 try 550 { 551 # Check HTTP Method 552 if ($_SERVER['REQUEST_METHOD'] != 'POST') { 553 throw new Exception('XML-RPC server accepts POST requests only.',405); 554 } 555 556 # Check HTTP_HOST 557 if (!isset($_SERVER['HTTP_HOST'])) { 558 throw new Exception('No Host Specified',400); 559 } 560 561 global $HTTP_RAW_POST_DATA; 562 if (!$HTTP_RAW_POST_DATA) { 563 throw new Exception('No Message',400); 564 } 565 566 if ($strict_check) 567 { 568 # Check USER_AGENT 569 if (!isset($_SERVER['HTTP_USER_AGENT'])) { 570 throw new Exception('No User Agent Specified',400); 571 } 572 573 # Check CONTENT_TYPE 574 if (!isset($_SERVER['CONTENT_TYPE']) || strpos($_SERVER['CONTENT_TYPE'],'text/xml') !== 0) { 575 throw new Exception('Invalid Content-Type',400); 576 } 577 578 # Check CONTENT_LENGTH 579 if (!isset($_SERVER['CONTENT_LENGTH']) || $_SERVER['CONTENT_LENGTH'] != strlen($HTTP_RAW_POST_DATA)) { 580 throw new Exception('Invalid Content-Lenth',400); 581 } 582 } 583 584 $data = $HTTP_RAW_POST_DATA; 585 } 586 catch (Exception $e) 587 { 588 if ($e->getCode() == 400) { 589 $this->head(400,'Bad Request'); 590 } elseif ($e->getCode() == 405) { 591 $this->head(405,'Method Not Allowed'); 592 header('Allow: POST'); 593 } 594 595 header('Content-Type: text/plain'); 596 echo $e->getMessage(); 597 exit; 598 } 599 } 600 601 $this->message = new xmlrpcMessage($data); 602 603 try 604 { 605 $this->message->parse(); 606 607 if ($this->message->messageType != 'methodCall') { 608 throw new xmlrpcException('Server error. Invalid xml-rpc. not conforming to spec. Request must be a methodCall',-32600); 609 } 610 611 $result = $this->call($this->message->methodName,$this->message->params); 612 } 613 catch (Exception $e) 614 { 615 $this->error($e); 616 } 617 618 # Encode the result 619 $r = new xmlrpcValue($result); 620 $resultxml = $r->getXml(); 621 622 # Create the XML 623 $xml = 624 "<methodResponse>\n". 625 "<params>\n". 626 "<param>\n". 627 " <value>\n". 628 ' '.$resultxml."\n". 629 " </value>\n". 630 "</param>\n". 631 "</params>\n". 632 "</methodResponse>"; 633 634 # Send it 635 $this->output($xml); 636 } 637 638 protected function head($code,$msg) 639 { 640 $status_mode = preg_match('/cgi/',php_sapi_name()); 641 642 if ($status_mode) { 643 header('Status: '.$code.' '.$msg); 644 } else { 645 if (version_compare(phpversion(),'4.3.0','>=')) { 646 header($msg,true,$code); 647 } else { 648 header('HTTP/1.x '.$code.' '.$msg); 649 } 650 } 651 } 652 653 protected function call($methodname,$args) 654 { 655 if (!$this->hasMethod($methodname)) { 656 throw new xmlrpcException('server error. requested method "'.$methodname.'" does not exist.',-32601); 657 } 658 659 $method = $this->callbacks[$methodname]; 660 661 # Perform the callback and send the response 662 if (!is_callable($method)) { 663 throw new xmlrpcException('server error. internal requested function for "'.$methodname.'" does not exist.',-32601); 664 } 665 666 return call_user_func_array($method,$args); 667 } 668 669 protected function error($e) 670 { 671 $msg = $e->getMessage(); 672 673 $this->output( 674 "<methodResponse>\n". 675 " <fault>\n". 676 " <value>\n". 677 " <struct>\n". 678 " <member>\n". 679 " <name>faultCode</name>\n". 680 ' <value><int>'.$e->getCode()."</int></value>\n". 681 " </member>\n". 682 " <member>\n". 683 " <name>faultString</name>\n". 684 ' <value><string>'.$msg."</string></value>\n". 685 " </member>\n". 686 " </struct>\n". 687 " </value>\n". 688 " </fault>\n". 689 "</methodResponse>\n" 690 ); 691 } 692 693 protected function output($xml) 694 { 695 $xml = '<?xml version="1.0" encoding="'.$this->encoding.'"?>'."\n".$xml; 696 $length = strlen($xml); 697 header('Connection: close'); 698 header('Content-Length: '.$length); 699 header('Content-Type: text/xml'); 700 header('Date: '.date('r')); 701 echo $xml; 702 exit; 703 } 704 705 protected function hasMethod($method) 706 { 707 return in_array($method, array_keys($this->callbacks)); 708 } 709 710 protected function setCapabilities() 711 { 712 # Initialises capabilities array 713 $this->capabilities = array( 714 'xmlrpc' => array( 715 'specUrl' => 'http://www.xmlrpc.com/spec', 716 'specVersion' => 1 717 ), 718 'faults_interop' => array( 719 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php', 720 'specVersion' => 20010516 721 ), 722 'system.multicall' => array( 723 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208', 724 'specVersion' => 1 725 ), 726 ); 727 } 728 729 protected function getCapabilities() 730 { 731 return $this->capabilities; 732 } 733 734 protected function setCallbacks() 735 { 736 $this->callbacks['system.getCapabilities'] = array($this,'getCapabilities'); 737 $this->callbacks['system.listMethods'] = array($this,'listMethods'); 738 $this->callbacks['system.multicall'] = array($this,'multiCall'); 739 } 740 741 protected function listMethods() 742 { 743 # Returns a list of methods - uses array_reverse to ensure user defined 744 # methods are listed before server defined methods 745 return array_reverse(array_keys($this->callbacks)); 746 } 747 748 protected function multiCall($methodcalls) 749 { 750 # See http://www.xmlrpc.com/discuss/msgReader$1208 751 $return = array(); 752 foreach ($methodcalls as $call) 753 { 754 $method = $call['methodName']; 755 $params = $call['params']; 756 757 try 758 { 759 if ($method == 'system.multicall') { 760 throw new xmlrpcException('Recursive calls to system.multicall are forbidden',-32600); 761 } 762 763 $result = $this->call($method, $params); 764 $return[] = array($result); 765 } 766 catch (Exception $e) 767 { 768 $return[] = array( 769 'faultCode' => $e->getCode(), 770 'faultString' => $e->getMessage() 771 ); 772 } 773 } 774 775 return $return; 776 } 777 } 778 779 class xmlrpcIntrospectionServer extends xmlrpcServer 780 { 781 protected $signatures; 782 protected $help; 783 784 public function __construct($encoding='UTF-8') 785 { 786 $this->encoding = $encoding; 787 $this->setCallbacks(); 788 $this->setCapabilities(); 789 790 $this->capabilities['introspection'] = array ( 791 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html', 792 'specVersion' => 1 793 ); 794 795 $this->addCallback( 796 'system.methodSignature', 797 array($this,'methodSignature'), 798 array('array','string'), 799 'Returns an array describing the return type and required parameters of a method' 800 ); 801 802 $this->addCallback( 803 'system.getCapabilities', 804 array($this,'getCapabilities'), 805 array('struct'), 806 'Returns a struct describing the XML-RPC specifications supported by this server' 807 ); 808 809 $this->addCallback( 810 'system.listMethods', 811 array($this,'listMethods'), 812 array('array'), 813 'Returns an array of available methods on this server' 814 ); 815 816 $this->addCallback( 817 'system.methodHelp', 818 array($this,'methodHelp'), 819 array('string','string'), 820 'Returns a documentation string for the specified method' 821 ); 822 823 $this->addCallback( 824 'system.multicall', 825 array($this,'multiCall'), 826 array('struct','array'), 827 'Returns result of multiple methods calls' 828 ); 829 } 830 831 protected function addCallback($method, $callback, $args, $help) 832 { 833 $this->callbacks[$method] = $callback; 834 $this->signatures[$method] = $args; 835 $this->help[$method] = $help; 836 } 837 838 protected function call($methodname,$args) 839 { 840 # Make sure it's in an array 841 if ($args && !is_array($args)) { 842 $args = array($args); 843 } 844 845 # Over-rides default call method, adds signature check 846 if (!$this->hasMethod($methodname)) { 847 throw new xmlrpcException('Server error. Requested method "'.$methodname.'" not specified.',-32601); 848 } 849 850 $method = $this->callbacks[$methodname]; 851 $signature = $this->signatures[$methodname]; 852 853 if (!is_array($signature)) { 854 throw new xmlrpcException('Server error. Wrong method signature',-36600); 855 } 856 857 $return_type = array_shift($signature); 858 859 # Check the number of arguments 860 if (count($args) != count($signature)) { 861 throw new xmlrpcException('Server error. Wrong number of method parameters',-32602); 862 } 863 864 # Check the argument types 865 if (!$this->checkArgs($args,$signature)) { 866 throw new xmlrpcException('Server error. Invalid method parameters',-32602); 867 } 868 869 # It passed the test - run the "real" method call 870 return parent::call($methodname, $args); 871 } 872 873 protected function checkArgs($args,$signature) 874 { 875 for ($i = 0, $j = count($args); $i < $j; $i++) 876 { 877 $arg = array_shift($args); 878 $type = array_shift($signature); 879 880 switch ($type) 881 { 882 case 'int': 883 case 'i4': 884 if (is_array($arg) || !is_int($arg)) { 885 return false; 886 } 887 break; 888 case 'base64': 889 case 'string': 890 if (!is_string($arg)) { 891 return false; 892 } 893 break; 894 case 'boolean': 895 if ($arg !== false && $arg !== true) { 896 return false; 897 } 898 break; 899 case 'float': 900 case 'double': 901 if (!is_float($arg)) { 902 return false; 903 } 904 break; 905 case 'date': 906 case 'dateTime.iso8601': 907 if (!($arg instanceof xmlrpcDate)) { 908 return false; 909 } 910 break; 911 } 912 } 913 return true; 914 } 915 916 protected function methodSignature($method) 917 { 918 if (!$this->hasMethod($method)) { 919 throw new xmlrpcException('Server error. Requested method "'.$method.'" not specified.',-32601); 920 921 } 922 923 # We should be returning an array of types 924 $types = $this->signatures[$method]; 925 $return = array(); 926 927 foreach ($types as $type) 928 { 929 switch ($type) 930 { 931 case 'string': 932 $return[] = 'string'; 933 break; 934 case 'int': 935 case 'i4': 936 $return[] = 42; 937 break; 938 case 'double': 939 $return[] = 3.1415; 940 break; 941 case 'dateTime.iso8601': 942 $return[] = new xmlrpcDate(time()); 943 break; 944 case 'boolean': 945 $return[] = true; 946 break; 947 case 'base64': 948 $return[] = new xmlrpcBase64('base64'); 949 break; 950 case 'array': 951 $return[] = array('array'); 952 break; 953 case 'struct': 954 $return[] = array('struct' => 'struct'); 955 break; 956 } 957 } 958 return $return; 959 } 960 961 protected function methodHelp($method) 962 { 963 return $this->help[$method]; 964 } 965 } 966 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Feb 23 22:16:06 2007 | par Balluche grâce à PHPXref 0.7 |