[ Index ] |
|
Code source de Dolibarr 2.0.1 |
1 <?php 2 /* 3 An XML-RPC implementation by Keith Devens, version 2.5f. 4 http://www.keithdevens.com/software/xmlrpc/ 5 6 Release history available at: 7 http://www.keithdevens.com/software/xmlrpc/history/ 8 9 This code is Open Source, released under terms similar to the Artistic License. 10 Read the license at http://www.keithdevens.com/software/license/ 11 12 Note: this code requires version 4.1.0 or higher of PHP. 13 */ 14 15 function & XML_serialize(&$data, $level = 0, $prior_key = NULL){ 16 #assumes a hash, keys are the variable names 17 $xml_serialized_string = ""; 18 while(list($key, $value) = each($data)){ 19 $inline = false; 20 $numeric_array = false; 21 $attributes = ""; 22 #echo "My current key is '$key', called with prior key '$prior_key'<br>"; 23 if(!strstr($key, " attr")){ #if it's not an attribute 24 if(array_key_exists("$key attr", $data)){ 25 while(list($attr_name, $attr_value) = each($data["$key attr"])){ 26 #echo "Found attribute $attribute_name with value $attribute_value<br>"; 27 $attr_value = &htmlspecialchars($attr_value, ENT_QUOTES); 28 $attributes .= " $attr_name=\"$attr_value\""; 29 } 30 } 31 32 if(is_numeric($key)){ 33 #echo "My current key ($key) is numeric. My parent key is '$prior_key'<br>"; 34 $key = $prior_key; 35 }else{ 36 #you can't have numeric keys at two levels in a row, so this is ok 37 #echo "Checking to see if a numeric key exists in data."; 38 if(is_array($value) and array_key_exists(0, $value)){ 39 # echo " It does! Calling myself as a result of a numeric array.<br>"; 40 $numeric_array = true; 41 $xml_serialized_string .= XML_serialize($value, $level, $key); 42 } 43 #echo "<br>"; 44 } 45 46 if(!$numeric_array){ 47 $xml_serialized_string .= str_repeat("\t", $level) . "<$key$attributes>"; 48 49 if(is_array($value)){ 50 $xml_serialized_string .= "\r\n" . XML_serialize($value, $level+1); 51 }else{ 52 $inline = true; 53 $xml_serialized_string .= htmlspecialchars($value); 54 } 55 56 $xml_serialized_string .= (!$inline ? str_repeat("\t", $level) : "") . "</$key>\r\n"; 57 } 58 }else{ 59 #echo "Skipping attribute record for key $key<bR>"; 60 } 61 } 62 if($level == 0){ 63 $xml_serialized_string = "<?xml version=\"1.0\" ?>\r\n" . $xml_serialized_string; 64 return $xml_serialized_string; 65 }else{ 66 return $xml_serialized_string; 67 } 68 } 69 70 class XML { 71 var $parser; #a reference to the XML parser 72 var $document; #the entire XML structure built up so far 73 var $current; #a pointer to the current item - what is this 74 var $parent; #a pointer to the current parent - the parent will be an array 75 var $parents; #an array of the most recent parent at each level 76 77 var $last_opened_tag; 78 79 function XML($data=null){ 80 $this->parser = xml_parser_create(); 81 82 xml_parser_set_option ($this->parser, XML_OPTION_CASE_FOLDING, 0); 83 xml_set_object($this->parser, &$this); 84 xml_set_element_handler($this->parser, "open", "close"); 85 xml_set_character_data_handler($this->parser, "data"); 86 # register_shutdown_function(array(&$this, 'destruct')); 87 } 88 89 function destruct(){ 90 xml_parser_free($this->parser); 91 } 92 93 function parse($data){ 94 $this->document = array(); 95 $this->parent = &$this->document; 96 $this->parents = array(); 97 $this->last_opened_tag = NULL; 98 xml_parse($this->parser, $data); 99 return $this->document; 100 } 101 102 function open($parser, $tag, $attributes){ 103 #echo "Opening tag $tag<br>\n"; 104 $this->data = ""; 105 $this->last_opened_tag = $tag; #tag is a string 106 if(array_key_exists($tag, $this->parent)){ 107 #echo "There's already an instance of '$tag' at the current level ($level)<br>\n"; 108 if(is_array($this->parent[$tag]) and array_key_exists(0, $this->parent[$tag])){ #if the keys are numeric 109 #need to make sure they're numeric (account for attributes) 110 $key = count_numeric_items($this->parent[$tag]); 111 #echo "There are $key instances: the keys are numeric.<br>\n"; 112 }else{ 113 #echo "There is only one instance. Shifting everything around<br>\n"; 114 $temp = &$this->parent[$tag]; 115 unset($this->parent[$tag]); 116 $this->parent[$tag][0] = &$temp; 117 118 if(array_key_exists("$tag attr", $this->parent)){ 119 #shift the attributes around too if they exist 120 $temp = &$this->parent["$tag attr"]; 121 unset($this->parent["$tag attr"]); 122 $this->parent[$tag]["0 attr"] = &$temp; 123 } 124 $key = 1; 125 } 126 $this->parent = &$this->parent[$tag]; 127 }else{ 128 $key = $tag; 129 } 130 if($attributes){ 131 $this->parent["$key attr"] = $attributes; 132 } 133 134 $this->parent[$key] = array(); 135 $this->parent = &$this->parent[$key]; 136 array_unshift($this->parents, &$this->parent); 137 } 138 139 function data($parser, $data){ 140 #echo "Data is '", htmlspecialchars($data), "'<br>\n"; 141 if($this->last_opened_tag != NULL){ 142 $this->data .= $data; 143 } 144 } 145 146 function close($parser, $tag){ 147 #echo "Close tag $tag<br>\n"; 148 if($this->last_opened_tag == $tag){ 149 $this->parent = $this->data; 150 $this->last_opened_tag = NULL; 151 } 152 array_shift($this->parents); 153 $this->parent = &$this->parents[0]; 154 } 155 } 156 157 function & XML_unserialize(&$xml){ 158 $xml_parser = new XML(); 159 $data = &$xml_parser->parse(&$xml); 160 $xml_parser->destruct(); 161 return $data; 162 } 163 164 function & XMLRPC_parse(&$request){ 165 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 166 XMLRPC_debug('XMLRPC_parse', "<p>Received the following raw request:</p>" . XMLRPC_show($request, 'print_r', true)); 167 } 168 $data = &XML_unserialize(&$request); 169 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 170 XMLRPC_debug('XMLRPC_parse', "<p>Returning the following parsed request:</p>" . XMLRPC_show($data, 'print_r', true)); 171 } 172 return $data; 173 } 174 175 function & XMLRPC_prepare($data, $type = NULL){ 176 if(is_array($data)){ 177 $num_elements = count($data); 178 if((array_key_exists(0, $data) or !$num_elements) and $type != 'struct'){ #it's an array 179 if(!$num_elements){ #if the array is empty 180 $returnvalue = array('array' => array('data' => NULL)); 181 }else{ 182 $returnvalue['array']['data']['value'] = array(); 183 $temp = &$returnvalue['array']['data']['value']; 184 $count = count_numeric_items($data); 185 for($n=0; $n<$count; $n++){ 186 $type = NULL; 187 if(array_key_exists("$n type", $data)){ 188 $type = $data["$n type"]; 189 } 190 $temp[$n] = XMLRPC_prepare(&$data[$n], $type); 191 } 192 } 193 }else{ #it's a struct 194 if(!$num_elements){ #if the struct is empty 195 $returnvalue = array('struct' => NULL); 196 }else{ 197 $returnvalue['struct']['member'] = array(); 198 $temp = &$returnvalue['struct']['member']; 199 while(list($key, $value) = each($data)){ 200 if(substr($key, -5) != ' type'){ #if it's not a type specifier 201 $type = NULL; 202 if(array_key_exists("$key type", $data)){ 203 $type = $data["$key type"]; 204 } 205 $temp[] = array('name' => $key, 'value' => XMLRPC_prepare(&$value, $type)); 206 } 207 } 208 } 209 } 210 }else{ #it's a scalar 211 if(!$type){ 212 if(is_int($data)){ 213 $returnvalue['int'] = $data; 214 return $returnvalue; 215 }elseif(is_float($data)){ 216 $returnvalue['double'] = $data; 217 return $returnvalue; 218 }elseif(is_bool($data)){ 219 $returnvalue['boolean'] = ($data ? 1 : 0); 220 return $returnvalue; 221 }elseif(preg_match('/^\d{8}T\d{2}:\d{2}:\d{2}$/', $data, $matches)){ #it's a date 222 $returnvalue['dateTime.iso8601'] = $data; 223 return $returnvalue; 224 }elseif(is_string($data)){ 225 $returnvalue['string'] = htmlspecialchars($data); 226 return $returnvalue; 227 } 228 }else{ 229 $returnvalue[$type] = htmlspecialchars($data); 230 } 231 } 232 return $returnvalue; 233 } 234 235 function & XMLRPC_adjustValue(&$current_node){ 236 if(is_array($current_node)){ 237 if(isset($current_node['array'])){ 238 if(!is_array($current_node['array']['data'])){ 239 #If there are no elements, return an empty array 240 return array(); 241 }else{ 242 #echo "Getting rid of array -> data -> value<br>\n"; 243 $temp = &$current_node['array']['data']['value']; 244 if(is_array($temp) and array_key_exists(0, $temp)){ 245 $count = count($temp); 246 for($n=0;$n<$count;$n++){ 247 $temp2[$n] = &XMLRPC_adjustValue(&$temp[$n]); 248 } 249 $temp = &$temp2; 250 }else{ 251 $temp2 = &XMLRPC_adjustValue(&$temp); 252 $temp = array(&$temp2); 253 #I do the temp assignment because it avoids copying, 254 # since I can put a reference in the array 255 #PHP's reference model is a bit silly, and I can't just say: 256 # $temp = array(&XMLRPC_adjustValue(&$temp)); 257 } 258 } 259 }elseif(isset($current_node['struct'])){ 260 if(!is_array($current_node['struct'])){ 261 #If there are no members, return an empty array 262 return array(); 263 }else{ 264 #echo "Getting rid of struct -> member<br>\n"; 265 $temp = &$current_node['struct']['member']; 266 if(is_array($temp) and array_key_exists(0, $temp)){ 267 $count = count($temp); 268 for($n=0;$n<$count;$n++){ 269 #echo "Passing name {$temp[$n][name]}. Value is: " . show($temp[$n][value], var_dump, true) . "<br>\n"; 270 $temp2[$temp[$n]['name']] = &XMLRPC_adjustValue(&$temp[$n]['value']); 271 #echo "adjustValue(): After assigning, the value is " . show($temp2[$temp[$n]['name']], var_dump, true) . "<br>\n"; 272 } 273 }else{ 274 #echo "Passing name $temp[name]<br>\n"; 275 $temp2[$temp['name']] = &XMLRPC_adjustValue(&$temp['value']); 276 } 277 $temp = &$temp2; 278 } 279 }else{ 280 $types = array('string', 'int', 'i4', 'double', 'dateTime.iso8601', 'base64', 'boolean'); 281 $fell_through = true; 282 foreach($types as $type){ 283 if(array_key_exists($type, $current_node)){ 284 #echo "Getting rid of '$type'<br>\n"; 285 $temp = &$current_node[$type]; 286 #echo "adjustValue(): The current node is set with a type of $type<br>\n"; 287 $fell_through = false; 288 break; 289 } 290 } 291 if($fell_through){ 292 $type = 'string'; 293 #echo "Fell through! Type is $type<br>\n"; 294 } 295 switch ($type){ 296 case 'int': case 'i4': $temp = (int)$temp; break; 297 case 'string': $temp = (string)$temp; break; 298 case 'double': $temp = (double)$temp; break; 299 case 'boolean': $temp = (bool)$temp; break; 300 } 301 } 302 }else{ 303 $temp = (string)$current_node; 304 } 305 return $temp; 306 } 307 308 function XMLRPC_getParams($request){ 309 if(!is_array($request['methodCall']['params'])){ 310 #If there are no parameters, return an empty array 311 return array(); 312 }else{ 313 #echo "Getting rid of methodCall -> params -> param<br>\n"; 314 $temp = &$request['methodCall']['params']['param']; 315 if(is_array($temp) and array_key_exists(0, $temp)){ 316 $count = count($temp); 317 for($n = 0; $n < $count; $n++){ 318 #echo "Serializing parameter $n<br>"; 319 $temp2[$n] = &XMLRPC_adjustValue(&$temp[$n]['value']); 320 } 321 }else{ 322 $temp2[0] = &XMLRPC_adjustValue($temp['value']); 323 } 324 $temp = &$temp2; 325 return $temp; 326 } 327 } 328 329 function XMLRPC_getMethodName($methodCall){ 330 #returns the method name 331 return $methodCall['methodCall']['methodName']; 332 } 333 334 function XMLRPC_request($site, $location, $methodName, $params = NULL, $user_agent = NULL){ 335 $site = explode(':', $site); 336 if(isset($site[1]) and is_numeric($site[1])){ 337 $port = $site[1]; 338 }else{ 339 $port = 80; 340 } 341 $site = $site[0]; 342 343 $data["methodCall"]["methodName"] = $methodName; 344 $param_count = count($params); 345 if(!$param_count){ 346 $data["methodCall"]["params"] = NULL; 347 }else{ 348 for($n = 0; $n<$param_count; $n++){ 349 $data["methodCall"]["params"]["param"][$n]["value"] = $params[$n]; 350 } 351 } 352 $data = XML_serialize($data); 353 354 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 355 XMLRPC_debug('XMLRPC_request', "<p>Received the following parameter list to send:</p>" . XMLRPC_show($params, 'print_r', true)); 356 } 357 $conn = fsockopen ($site, $port); #open the connection 358 if(!$conn){ #if the connection was not opened successfully 359 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 360 XMLRPC_debug('XMLRPC_request', "<p>Connection failed: Couldn't make the connection to $site.</p>"); 361 } 362 return array(false, array('faultCode'=>10532, 'faultString'=>"Connection failed: Couldn't make the connection to $site.")); 363 }else{ 364 $headers = 365 "POST $location HTTP/1.0\r\n" . 366 "Host: $site\r\n" . 367 "Connection: close\r\n" . 368 ($user_agent ? "User-Agent: $user_agent\r\n" : '') . 369 "Content-Type: text/xml\r\n" . 370 "Content-Length: " . strlen($data) . "\r\n\r\n"; 371 372 fputs($conn, "$headers"); 373 fputs($conn, $data); 374 375 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 376 XMLRPC_debug('XMLRPC_request', "<p>Sent the following request:</p>\n\n" . XMLRPC_show($headers . $data, 'print_r', true)); 377 } 378 379 #socket_set_blocking ($conn, false); 380 $response = ""; 381 while(!feof($conn)){ 382 $response .= fgets($conn, 1024); 383 } 384 fclose($conn); 385 386 #strip headers off of response 387 $data = XML_unserialize(substr($response, strpos($response, "\r\n\r\n")+4)); 388 389 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 390 XMLRPC_debug('XMLRPC_request', "<p>Received the following response:</p>\n\n" . XMLRPC_show($response, 'print_r', true) . "<p>Which was serialized into the following data:</p>\n\n" . XMLRPC_show($data, 'print_r', true)); 391 } 392 if(isset($data['methodResponse']['fault'])){ 393 $return = array(false, XMLRPC_adjustValue(&$data['methodResponse']['fault']['value'])); 394 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 395 XMLRPC_debug('XMLRPC_request', "<p>Returning:</p>\n\n" . XMLRPC_show($return, 'var_dump', true)); 396 } 397 return $return; 398 }else{ 399 $return = array(true, XMLRPC_adjustValue(&$data['methodResponse']['params']['param']['value'])); 400 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 401 XMLRPC_debug('XMLRPC_request', "<p>Returning:</p>\n\n" . XMLRPC_show($return, 'var_dump', true)); 402 } 403 return $return; 404 } 405 } 406 } 407 408 function XMLRPC_response($return_value, $server = NULL){ 409 $data["methodResponse"]["params"]["param"]["value"] = &$return_value; 410 $return = XML_serialize(&$data); 411 412 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 413 XMLRPC_debug('XMLRPC_response', "<p>Received the following data to return:</p>\n\n" . XMLRPC_show($return_value, 'print_r', true)); 414 } 415 416 header("Connection: close"); 417 header("Content-Length: " . strlen($return)); 418 header("Content-Type: text/xml"); 419 header("Date: " . date("r")); 420 if($server){ 421 header("Server: $server"); 422 } 423 424 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 425 XMLRPC_debug('XMLRPC_response', "<p>Sent the following response:</p>\n\n" . XMLRPC_show($return, 'print_r', true)); 426 } 427 echo $return; 428 } 429 430 function XMLRPC_error($faultCode, $faultString, $server = NULL){ 431 $array["methodResponse"]["fault"]["value"]["struct"]["member"] = array(); 432 $temp = &$array["methodResponse"]["fault"]["value"]["struct"]["member"]; 433 $temp[0]["name"] = "faultCode"; 434 $temp[0]["value"]["int"] = $faultCode; 435 $temp[1]["name"] = "faultString"; 436 $temp[1]["value"]["string"] = $faultString; 437 438 $return = XML_serialize($array); 439 440 header("Connection: close"); 441 header("Content-Length: " . strlen($return)); 442 header("Content-Type: text/xml"); 443 header("Date: " . date("r")); 444 if($server){ 445 header("Server: $server"); 446 } 447 if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){ 448 XMLRPC_debug('XMLRPC_error', "<p>Sent the following error response:</p>\n\n" . XMLRPC_show($return, 'print_r', true)); 449 } 450 echo $return; 451 } 452 453 function XMLRPC_convert_timestamp_to_iso8601($timestamp){ 454 #takes a unix timestamp and converts it to iso8601 required by XMLRPC 455 #an example iso8601 datetime is "20010822T03:14:33" 456 return date("Ymd\TH:i:s", $timestamp); 457 } 458 459 function XMLRPC_convert_iso8601_to_timestamp($iso8601){ 460 return strtotime($iso8601); 461 } 462 463 function count_numeric_items(&$array){ 464 return is_array($array) ? count(array_filter(array_keys($array), 'is_numeric')) : 0; 465 } 466 467 function XMLRPC_debug($function_name, $debug_message){ 468 $GLOBALS['XMLRPC_DEBUG_INFO'][] = array($function_name, $debug_message); 469 } 470 471 function XMLRPC_debug_print(){ 472 if($GLOBALS['XMLRPC_DEBUG_INFO']){ 473 echo "<table border=\"1\" width=\"100%\">\n"; 474 foreach($GLOBALS['XMLRPC_DEBUG_INFO'] as $debug){ 475 echo "<tr><th style=\"vertical-align: top\">$debug[0]</th><td>$debug[1]</td></tr>\n"; 476 } 477 echo "</table>\n"; 478 unset($GLOBALS['XMLRPC_DEBUG_INFO']); 479 }else{ 480 echo "<p>No debugging information available yet.</p>"; 481 } 482 } 483 484 function XMLRPC_show($data, $func = "print_r", $return_str = false){ 485 ob_start(); 486 $func($data); 487 $output = ob_get_contents(); 488 ob_end_clean(); 489 if($return_str){ 490 return "<pre>" . htmlspecialchars($output) . "</pre>\n"; 491 }else{ 492 echo "<pre>", htmlspecialchars($output), "</pre>\n"; 493 } 494 } 495 496 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Mon Nov 26 12:29:37 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |