[ Index ] |
|
Code source de Drupal 5.3 |
1 <?php 2 // $Id: xmlrpcs.inc,v 1.21 2006/07/05 11:45:51 dries Exp $ 3 4 /** 5 * The main entry point for XML-RPC requests. 6 * 7 * @param $callbacks 8 * Array of external XML-RPC method names with the callbacks they map to. 9 */ 10 function xmlrpc_server($callbacks) { 11 $xmlrpc_server = new stdClass(); 12 // Define built-in XML-RPC method names 13 $defaults = array( 14 'system.multicall' => 'xmlrpc_server_multicall', 15 array( 16 'system.methodSignature', 17 'xmlrpc_server_method_signature', 18 array('array', 'string'), 19 'Returns an array describing the return type and required parameters of a method.' 20 ), 21 array( 22 'system.getCapabilities', 23 'xmlrpc_server_get_capabilities', 24 array('struct'), 25 'Returns a struct describing the XML-RPC specifications supported by this server.' 26 ), 27 array( 28 'system.listMethods', 29 'xmlrpc_server_list_methods', 30 array('array'), 31 'Returns an array of available methods on this server.'), 32 array( 33 'system.methodHelp', 34 'xmlrpc_server_method_help', 35 array('string', 'string'), 36 'Returns a documentation string for the specified method.') 37 ); 38 // We build an array of all method names by combining the built-ins 39 // with those defined by modules implementing the _xmlrpc hook. 40 // Built-in methods are overridable. 41 foreach (array_merge($defaults, (array)$callbacks) as $key => $callback) { 42 // we could check for is_array($callback) 43 if (is_int($key)) { 44 $method = $callback[0]; 45 $xmlrpc_server->callbacks[$method] = $callback[1]; 46 $xmlrpc_server->signatures[$method] = $callback[2]; 47 $xmlrpc_server->help[$method] = $callback[3]; 48 } 49 else { 50 $xmlrpc_server->callbacks[$key] = $callback; 51 $xmlrpc_server->signatures[$key] = ''; 52 $xmlrpc_server->help[$key] = ''; 53 } 54 } 55 56 $data = file_get_contents('php://input'); 57 if (!$data) { 58 die('XML-RPC server accepts POST requests only.'); 59 } 60 $xmlrpc_server->message = xmlrpc_message($data); 61 if (!xmlrpc_message_parse($xmlrpc_server->message)) { 62 xmlrpc_server_error(-32700, t('Parse error. Request not well formed.')); 63 } 64 if ($xmlrpc_server->message->messagetype != 'methodCall') { 65 xmlrpc_server_error(-32600, t('Server error. Invalid XML-RPC. Request must be a methodCall.')); 66 } 67 xmlrpc_server_set($xmlrpc_server); 68 $result = xmlrpc_server_call($xmlrpc_server, $xmlrpc_server->message->methodname, $xmlrpc_server->message->params); 69 70 if ($result->is_error) { 71 xmlrpc_server_error($result); 72 } 73 // Encode the result 74 $r = xmlrpc_value($result); 75 // Create the XML 76 $xml = ' 77 <methodResponse> 78 <params> 79 <param> 80 <value>'. 81 xmlrpc_value_get_xml($r) 82 .'</value> 83 </param> 84 </params> 85 </methodResponse> 86 87 '; 88 // Send it 89 xmlrpc_server_output($xml); 90 } 91 92 /** 93 * Throw an XML-RPC error. 94 * 95 * @param $error 96 * an error object OR integer error code 97 * @param $message 98 * description of error, used only if integer error code was passed 99 */ 100 function xmlrpc_server_error($error, $message = FALSE) { 101 if ($message && !is_object($error)) { 102 $error = xmlrpc_error($error, $message); 103 } 104 xmlrpc_server_output(xmlrpc_error_get_xml($error)); 105 } 106 107 function xmlrpc_server_output($xml) { 108 $xml = '<?xml version="1.0"?>'."\n". $xml; 109 header('Connection: close'); 110 header('Content-Length: '. strlen($xml)); 111 header('Content-Type: text/xml'); 112 header('Date: '.date('r')); 113 echo $xml; 114 exit; 115 } 116 117 /** 118 * Store a copy of the request temporarily. 119 * 120 * @param $xmlrpc_server 121 * Request object created by xmlrpc_server(). 122 */ 123 function xmlrpc_server_set($xmlrpc_server = NULL) { 124 static $server; 125 if (!isset($server)) { 126 $server = $xmlrpc_server; 127 } 128 return $server; 129 } 130 131 // Retrieve the stored request. 132 function xmlrpc_server_get() { 133 return xmlrpc_server_set(); 134 } 135 136 /** 137 * Dispatch the request and any parameters to the appropriate handler. 138 * 139 * @param $xmlrpc_server 140 * @param $methodname 141 * The external XML-RPC method name, e.g. 'system.methodHelp' 142 * @param $args 143 * Array containing any parameters that were sent along with the request. 144 */ 145 function xmlrpc_server_call($xmlrpc_server, $methodname, $args) { 146 // Make sure parameters are in an array 147 if ($args && !is_array($args)) { 148 $args = array($args); 149 } 150 // Has this method been mapped to a Drupal function by us or by modules? 151 if (!isset($xmlrpc_server->callbacks[$methodname])) { 152 return xmlrpc_error(-32601, t('Server error. Requested method %methodname not specified.', array("%methodname" => $xmlrpc_server->message->methodname))); 153 } 154 $method = $xmlrpc_server->callbacks[$methodname]; 155 $signature = $xmlrpc_server->signatures[$methodname]; 156 157 // If the method has a signature, validate the request against the signature 158 if (is_array($signature)) { 159 $ok = TRUE; 160 $return_type = array_shift($signature); 161 // Check the number of arguments 162 if (count($args) != count($signature)) { 163 return xmlrpc_error(-32602, t('Server error. Wrong number of method parameters.')); 164 } 165 // Check the argument types 166 foreach ($signature as $key => $type) { 167 $arg = $args[$key]; 168 switch ($type) { 169 case 'int': 170 case 'i4': 171 if (is_array($arg) || !is_int($arg)) { 172 $ok = FALSE; 173 } 174 break; 175 case 'base64': 176 case 'string': 177 if (!is_string($arg)) { 178 $ok = FALSE; 179 } 180 break; 181 case 'boolean': 182 if ($arg !== FALSE && $arg !== TRUE) { 183 $ok = FALSE; 184 } 185 break; 186 case 'float': 187 case 'double': 188 if (!is_float($arg)) { 189 $ok = FALSE; 190 } 191 break; 192 case 'date': 193 case 'dateTime.iso8601': 194 if (!$arg->is_date) { 195 $ok = FALSE; 196 } 197 break; 198 } 199 if (!$ok) { 200 return xmlrpc_error(-32602, t('Server error. Invalid method parameters.')); 201 } 202 } 203 } 204 /* 205 if (count($args) == 1) { 206 // If only one parameter just send that instead of the whole array 207 $args = $args[0]; 208 } 209 */ 210 if (!function_exists($method)) { 211 return xmlrpc_error(-32601, t('Server error. Requested function %method does not exist.', array("%method" => $method))); 212 } 213 // Call the mapped function 214 return call_user_func_array($method, $args); 215 } 216 217 function xmlrpc_server_multicall($methodcalls) { 218 // See http://www.xmlrpc.com/discuss/msgReader$1208 219 $return = array(); 220 $xmlrpc_server = xmlrpc_server_get(); 221 foreach ($methodcalls as $call) { 222 $ok = TRUE; 223 if (!isset($call['methodName']) || !isset($call['params'])) { 224 $result = xmlrpc_error(3, t('Invalid syntax for system.multicall.')); 225 $ok = FALSE; 226 } 227 $method = $call['methodName']; 228 $params = $call['params']; 229 if ($method == 'system.multicall') { 230 $result = xmlrpc_error(-32600, t('Recursive calls to system.multicall are forbidden.')); 231 } 232 elseif ($ok) { 233 $result = xmlrpc_server_call($xmlrpc_server, $method, $params); 234 } 235 if ($result->is_error) { 236 $return[] = array( 237 'faultCode' => $result->code, 238 'faultString' => $result->message 239 ); 240 } 241 else { 242 $return[] = $result; 243 } 244 } 245 return $return; 246 } 247 248 249 /** 250 * XML-RPC method system.listMethods maps to this function. 251 */ 252 function xmlrpc_server_list_methods() { 253 $xmlrpc_server = xmlrpc_server_get(); 254 return array_keys($xmlrpc_server->callbacks); 255 } 256 257 /** 258 * XML-RPC method system.getCapabilities maps to this function. 259 * See http://groups.yahoo.com/group/xml-rpc/message/2897 260 */ 261 function xmlrpc_server_get_capabilities() { 262 return array( 263 'xmlrpc' => array( 264 'specUrl' => 'http://www.xmlrpc.com/spec', 265 'specVersion' => 1 266 ), 267 'faults_interop' => array( 268 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php', 269 'specVersion' => 20010516 270 ), 271 'system.multicall' => array( 272 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208', 273 'specVersion' => 1 274 ), 275 'introspection' => array( 276 'specUrl' => 'http://scripts.incutio.com/xmlrpc/introspection.html', 277 'specVersion' => 1 278 ) 279 ); 280 } 281 282 /** 283 * XML-RPC method system.methodSignature maps to this function. 284 * 285 * @param $methodname 286 * Name of method for which we return a method signature. 287 * @return array 288 * An array of types representing the method signature of the 289 * function that the methodname maps to. The methodSignature of 290 * this function is 'array', 'string' because it takes an array 291 * and returns a string. 292 */ 293 function xmlrpc_server_method_signature($methodname) { 294 $xmlrpc_server = xmlrpc_server_get(); 295 if (!isset($xmlrpc_server->callbacks[$methodname])) { 296 return xmlrpc_error(-32601, t('Server error. Requested method %methodname not specified.', array("%methodname" => $methodname))); 297 } 298 if (!is_array($xmlrpc_server->signatures[$methodname])) { 299 return xmlrpc_error(-32601, t('Server error. Requested method %methodname signature not specified.', array("%methodname" => $methodname))); 300 } 301 // We array of types 302 $return = array(); 303 foreach ($xmlrpc_server->signatures[$methodname] as $type) { 304 $return[] = $type; 305 } 306 return $return; 307 } 308 309 /** 310 * XML-RPC method system.methodHelp maps to this function. 311 * 312 * @param $method 313 * Name of method for which we return a help string. 314 */ 315 function xmlrpc_server_method_help($method) { 316 $xmlrpc_server = xmlrpc_server_get(); 317 return $xmlrpc_server->help[$method]; 318 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Nov 30 16:20:15 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |