blob: 3b945769f9b61e872f39cc4851fecf033b63f76a [file] [log] [blame]
Derek Jones8ede1a22011-10-05 13:34:52 -05001##################################
2XML-RPC and XML-RPC Server Classes
3##################################
4
5CodeIgniter's XML-RPC classes permit you to send requests to another
6server, or set up your own XML-RPC server to receive requests.
7
8****************
9What is XML-RPC?
10****************
11
12Quite simply it is a way for two computers to communicate over the
13internet using XML. One computer, which we will call the client, sends
14an XML-RPC **request** to another computer, which we will call the
15server. Once the server receives and processes the request it will send
16back a **response** to the client.
17
18For example, using the MetaWeblog API, an XML-RPC Client (usually a
19desktop publishing tool) will send a request to an XML-RPC Server
20running on your site. This request might be a new weblog entry being
21sent for publication, or it could be a request for an existing entry for
22editing. When the XML-RPC Server receives this request it will examine
23it to determine which class/method should be called to process the
24request. Once processed, the server will then send back a response
25message.
26
27For detailed specifications, you can visit the
28`XML-RPC <http://www.xmlrpc.com/>`_ site.
29
30Initializing the Class
31======================
32
33Like most other classes in CodeIgniter, the XML-RPC and XML-RPCS classes
34are initialized in your controller using the $this->load->library
35function:
36
37To load the XML-RPC class you will use::
38
39 $this->load->library('xmlrpc');
40
41Once loaded, the xml-rpc library object will be available using:
42$this->xmlrpc
43
44To load the XML-RPC Server class you will use::
45
Derek Jones92763a52011-10-05 15:28:52 -050046 $this->load->library('xmlrpc');
47 $this->load->library('xmlrpcs');
Derek Jones8ede1a22011-10-05 13:34:52 -050048
49Once loaded, the xml-rpcs library object will be available using:
50$this->xmlrpcs
51
52.. note:: When using the XML-RPC Server class you must load BOTH the
53 XML-RPC class and the XML-RPC Server class.
54
55Sending XML-RPC Requests
56========================
57
58To send a request to an XML-RPC server you must specify the following
59information:
60
61- The URL of the server
62- The method on the server you wish to call
63- The *request* data (explained below).
64
65Here is a basic example that sends a simple Weblogs.com ping to the
66`Ping-o-Matic <http://pingomatic.com/>`_
67
68::
69
Derek Jones92763a52011-10-05 15:28:52 -050070 $this->load->library('xmlrpc');
71
72 $this->xmlrpc->server('http://rpc.pingomatic.com/', 80);
73 $this->xmlrpc->method('weblogUpdates.ping');
74
75 $request = array('My Photoblog', 'http://www.my-site.com/photoblog/');
76 $this->xmlrpc->request($request);
77
78 if ( ! $this->xmlrpc->send_request())
79 {
80 echo $this->xmlrpc->display_error();
81 }
Derek Jones8ede1a22011-10-05 13:34:52 -050082
83Explanation
84-----------
85
86The above code initializes the XML-RPC class, sets the server URL and
87method to be called (weblogUpdates.ping). The request (in this case, the
88title and URL of your site) is placed into an array for transportation,
89and compiled using the request() function. Lastly, the full request is
90sent. If the send_request() method returns false we will display the
91error message sent back from the XML-RPC Server.
92
93Anatomy of a Request
94====================
95
96An XML-RPC request is simply the data you are sending to the XML-RPC
97server. Each piece of data in a request is referred to as a request
98parameter. The above example has two parameters: The URL and title of
99your site. When the XML-RPC server receives your request, it will look
100for parameters it requires.
101
102Request parameters must be placed into an array for transportation, and
103each parameter can be one of seven data types (strings, numbers, dates,
104etc.). If your parameters are something other than strings you will have
105to include the data type in the request array.
106
107Here is an example of a simple array with three parameters::
108
Derek Jones92763a52011-10-05 15:28:52 -0500109 $request = array('John', 'Doe', 'www.some-site.com');
110 $this->xmlrpc->request($request);
Derek Jones8ede1a22011-10-05 13:34:52 -0500111
112If you use data types other than strings, or if you have several
113different data types, you will place each parameter into its own array,
114with the data type in the second position::
115
Derek Jones92763a52011-10-05 15:28:52 -0500116 $request = array (
117 array('John', 'string'),
118 array('Doe', 'string'),
119 array(FALSE, 'boolean'),
120 array(12345, 'int')
121 );
122 $this->xmlrpc->request($request);
Derek Jones8ede1a22011-10-05 13:34:52 -0500123
124The `Data Types <#datatypes>`_ section below has a full list of data
125types.
126Creating an XML-RPC Server
127==========================
128
129An XML-RPC Server acts as a traffic cop of sorts, waiting for incoming
130requests and redirecting them to the appropriate functions for
131processing.
132
133To create your own XML-RPC server involves initializing the XML-RPC
134Server class in your controller where you expect the incoming request to
135appear, then setting up an array with mapping instructions so that
136incoming requests can be sent to the appropriate class and method for
137processing.
138
139Here is an example to illustrate::
140
Derek Jones92763a52011-10-05 15:28:52 -0500141 $this->load->library('xmlrpc');
142 $this->load->library('xmlrpcs');
143
144 $config['functions']['new_post'] = array('function' => 'My_blog.new_entry'),
145 $config['functions']['update_post'] = array('function' => 'My_blog.update_entry');
146 $config['object'] = $this;
147
148 $this->xmlrpcs->initialize($config);
149 $this->xmlrpcs->serve();
Derek Jones8ede1a22011-10-05 13:34:52 -0500150
151The above example contains an array specifying two method requests that
152the Server allows. The allowed methods are on the left side of the
153array. When either of those are received, they will be mapped to the
154class and method on the right.
155
156The 'object' key is a special key that you pass an instantiated class
157object with, which is necessary when the method you are mapping to is
158not part of the CodeIgniter super object.
159
160In other words, if an XML-RPC Client sends a request for the new_post
161method, your server will load the My_blog class and call the new_entry
162function. If the request is for the update_post method, your server
163will load the My_blog class and call the update_entry function.
164
165The function names in the above example are arbitrary. You'll decide
166what they should be called on your server, or if you are using
167standardized APIs, like the Blogger or MetaWeblog API, you'll use their
168function names.
169
170There are two additional configuration keys you may make use of when
171initializing the server class: debug can be set to TRUE in order to
172enable debugging, and xss_clean may be set to FALSE to prevent sending
173data through the Security library's xss_clean function.
174
175Processing Server Requests
176==========================
177
178When the XML-RPC Server receives a request and loads the class/method
179for processing, it will pass an object to that method containing the
180data sent by the client.
181
182Using the above example, if the new_post method is requested, the
183server will expect a class to exist with this prototype::
184
Derek Jones92763a52011-10-05 15:28:52 -0500185 class My_blog extends CI_Controller {
186
187 function new_post($request)
188 {
189
190 }
191 }
Derek Jones8ede1a22011-10-05 13:34:52 -0500192
193The $request variable is an object compiled by the Server, which
194contains the data sent by the XML-RPC Client. Using this object you will
195have access to the *request parameters* enabling you to process the
196request. When you are done you will send a Response back to the Client.
197
198Below is a real-world example, using the Blogger API. One of the methods
199in the Blogger API is getUserInfo(). Using this method, an XML-RPC
200Client can send the Server a username and password, in return the Server
201sends back information about that particular user (nickname, user ID,
202email address, etc.). Here is how the processing function might look::
203
Derek Jones92763a52011-10-05 15:28:52 -0500204 class My_blog extends CI_Controller {
205
206 function getUserInfo($request)
207 {
208 $username = 'smitty';
209 $password = 'secretsmittypass';
210
211 $this->load->library('xmlrpc');
212
213 $parameters = $request->output_parameters();
214
215 if ($parameters['1'] != $username AND $parameters['2'] != $password)
216 {
217 return $this->xmlrpc->send_error_message('100', 'Invalid Access');
218 }
219
220 $response = array(array('nickname' => array('Smitty','string'),
221 'userid' => array('99','string'),
222 'url' => array('http://yoursite.com','string'),
223 'email' => array('jsmith@yoursite.com','string'),
224 'lastname' => array('Smith','string'),
225 'firstname' => array('John','string')
226 ),
227 'struct');
228
229 return $this->xmlrpc->send_response($response);
230 }
231 }
Derek Jones8ede1a22011-10-05 13:34:52 -0500232
233Notes:
234------
235
236The output_parameters() function retrieves an indexed array
237corresponding to the request parameters sent by the client. In the above
238example, the output parameters will be the username and password.
239
240If the username and password sent by the client were not valid, and
241error message is returned using send_error_message().
242
243If the operation was successful, the client will be sent back a response
244array containing the user's info.
245
246Formatting a Response
247=====================
248
249Similar to *Requests*, *Responses* must be formatted as an array.
250However, unlike requests, a response is an array **that contains a
251single item**. This item can be an array with several additional arrays,
252but there can be only one primary array index. In other words, the basic
253prototype is this::
254
255 $response = array('Response data', 'array');
256
257Responses, however, usually contain multiple pieces of information. In
258order to accomplish this we must put the response into its own array so
259that the primary array continues to contain a single piece of data.
260Here's an example showing how this might be accomplished::
261
Derek Jones92763a52011-10-05 15:28:52 -0500262 $response = array (
263 array(
264 'first_name' => array('John', 'string'),
265 'last_name' => array('Doe', 'string'),
266 'member_id' => array(123435, 'int'),
267 'todo_list' => array(array('clean house', 'call mom', 'water plants'), 'array'),
268 ),
269 'struct'
270 );
Derek Jones8ede1a22011-10-05 13:34:52 -0500271
272Notice that the above array is formatted as a struct. This is the most
273common data type for responses.
274
275As with Requests, a response can be one of the seven data types listed
276in the `Data Types <#datatypes>`_ section.
277
278Sending an Error Response
279=========================
280
281If you need to send the client an error response you will use the
282following::
283
284 return $this->xmlrpc->send_error_message('123', 'Requested data not available');
285
286The first parameter is the error number while the second parameter is
287the error message.
288
289Creating Your Own Client and Server
290===================================
291
292To help you understand everything we've covered thus far, let's create a
293couple controllers that act as XML-RPC Client and Server. You'll use the
294Client to send a request to the Server and receive a response.
295
296The Client
297----------
298
299Using a text editor, create a controller called xmlrpc_client.php. In
300it, place this code and save it to your applications/controllers/
Derek Jones92763a52011-10-05 15:28:52 -0500301folder::
Derek Jones8ede1a22011-10-05 13:34:52 -0500302
Derek Jones92763a52011-10-05 15:28:52 -0500303 <?php
Derek Jones8ede1a22011-10-05 13:34:52 -0500304
Derek Jones92763a52011-10-05 15:28:52 -0500305 class Xmlrpc_client extends CI_Controller {
Derek Jones8ede1a22011-10-05 13:34:52 -0500306
Derek Jones92763a52011-10-05 15:28:52 -0500307 function index()
308 {
309 $this->load->helper('url');
310 $server_url = site_url('xmlrpc_server');
311
312 $this->load->library('xmlrpc');
313
314 $this->xmlrpc->server($server_url, 80);
315 $this->xmlrpc->method('Greetings');
316
317 $request = array('How is it going?');
318 $this->xmlrpc->request($request);
319
320 if ( ! $this->xmlrpc->send_request())
321 {
322 echo $this->xmlrpc->display_error();
323 }
324 else
325 {
326 echo '<pre>';
327 print_r($this->xmlrpc->display_response());
328 echo '</pre>';
329 }
330 }
331 }
332 ?>
333
334.. note:: In the above code we are using a "url helper". You can find more
335 information in the :doc:`Helpers Functions <../general/helpers>` page.
Derek Jones8ede1a22011-10-05 13:34:52 -0500336
337The Server
338----------
339
340Using a text editor, create a controller called xmlrpc_server.php. In
341it, place this code and save it to your applications/controllers/
Derek Jones92763a52011-10-05 15:28:52 -0500342folder::
Derek Jones8ede1a22011-10-05 13:34:52 -0500343
Derek Jones92763a52011-10-05 15:28:52 -0500344 <?php
345
346 class Xmlrpc_server extends CI_Controller {
347
348 function index()
349 {
350 $this->load->library('xmlrpc');
351 $this->load->library('xmlrpcs');
352
353 $config['functions']['Greetings'] = array('function' => 'Xmlrpc_server.process');
354
355 $this->xmlrpcs->initialize($config);
356 $this->xmlrpcs->serve();
357 }
358
359
360 function process($request)
361 {
362 $parameters = $request->output_parameters();
363
364 $response = array(
365 array(
366 'you_said' => $parameters['0'],
367 'i_respond' => 'Not bad at all.'),
368 'struct');
369
370 return $this->xmlrpc->send_response($response);
371 }
372 }
373 ?>
374
375
Derek Jones8ede1a22011-10-05 13:34:52 -0500376Try it!
377-------
378
379Now visit the your site using a URL similar to this::
380
381 example.com/index.php/xmlrpc_client/
382
383You should now see the message you sent to the server, and its response
384back to you.
385
386The client you created sends a message ("How's is going?") to the
387server, along with a request for the "Greetings" method. The Server
388receives the request and maps it to the "process" function, where a
389response is sent back.
390
391Using Associative Arrays In a Request Parameter
392===============================================
393
394If you wish to use an associative array in your method parameters you
395will need to use a struct datatype::
396
Derek Jones92763a52011-10-05 15:28:52 -0500397 $request = array(
398 array(
399 // Param 0
400 array(
401 'name'=>'John'
402 ),
403 'struct'
404 ),
405 array(
406 // Param 1
407 array(
408 'size'=>'large',
409 'shape'=>'round'
410 ),
411 'struct'
412 )
413 );
414 $this->xmlrpc->request($request);
Derek Jones8ede1a22011-10-05 13:34:52 -0500415
416You can retrieve the associative array when processing the request in
417the Server.
418
419::
420
Derek Jones92763a52011-10-05 15:28:52 -0500421 $parameters = $request->output_parameters();
422 $name = $parameters['0']['name'];
423 $size = $parameters['1']['size'];
424 $size = $parameters['1']['shape'];
Derek Jones8ede1a22011-10-05 13:34:52 -0500425
426**************************
427XML-RPC Function Reference
428**************************
429
430$this->xmlrpc->server()
431=======================
432
433Sets the URL and port number of the server to which a request is to be
434sent::
435
436 $this->xmlrpc->server('http://www.sometimes.com/pings.php', 80);
437
438$this->xmlrpc->timeout()
439========================
440
441Set a time out period (in seconds) after which the request will be
442canceled::
443
444 $this->xmlrpc->timeout(6);
445
446$this->xmlrpc->method()
447=======================
448
449Sets the method that will be requested from the XML-RPC server::
450
451 $this->xmlrpc->method('method');
452
453Where method is the name of the method.
454
455$this->xmlrpc->request()
456========================
457
458Takes an array of data and builds request to be sent to XML-RPC server::
459
Derek Jones92763a52011-10-05 15:28:52 -0500460 $request = array(array('My Photoblog', 'string'), 'http://www.yoursite.com/photoblog/');
461 $this->xmlrpc->request($request);
Derek Jones8ede1a22011-10-05 13:34:52 -0500462
463$this->xmlrpc->send_request()
464==============================
465
466The request sending function. Returns boolean TRUE or FALSE based on
467success for failure, enabling it to be used conditionally.
468
469$this->xmlrpc->set_debug(TRUE);
470================================
471
472Enables debugging, which will display a variety of information and error
473data helpful during development.
474
475$this->xmlrpc->display_error()
476===============================
477
478Returns an error message as a string if your request failed for some
479reason.
480
481::
482
483 echo $this->xmlrpc->display_error();
484
485$this->xmlrpc->display_response()
486==================================
487
488Returns the response from the remote server once request is received.
489The response will typically be an associative array.
490
491::
492
493 $this->xmlrpc->display_response();
494
495$this->xmlrpc->send_error_message()
496=====================================
497
498This function lets you send an error message from your server to the
499client. First parameter is the error number while the second parameter
500is the error message.
501
502::
503
504 return $this->xmlrpc->send_error_message('123', 'Requested data not available');
505
506$this->xmlrpc->send_response()
507===============================
508
509Lets you send the response from your server to the client. An array of
510valid data values must be sent with this method.
511
512::
513
Derek Jones92763a52011-10-05 15:28:52 -0500514 $response = array(
515 array(
516 'flerror' => array(FALSE, 'boolean'),
517 'message' => "Thanks for the ping!"
518 )
519 'struct');
520 return $this->xmlrpc->send_response($response);
Derek Jones8ede1a22011-10-05 13:34:52 -0500521
522Data Types
523==========
524
525According to the `XML-RPC spec <http://www.xmlrpc.com/spec>`_ there are
526seven types of values that you can send via XML-RPC:
527
528- *int* or *i4*
529- *boolean*
530- *string*
531- *double*
532- *dateTime.iso8601*
533- *base64*
534- *struct* (contains array of values)
535- *array* (contains array of values)
536