blob: a43c488379b0c9957ff64f7f9016b3b1597e611f [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
Andrey Andreevd8e1ac72012-03-26 22:22:37 +0300187 public function new_post($request)
188 {
Derek Jones92763a52011-10-05 15:28:52 -0500189
Andrey Andreevd8e1ac72012-03-26 22:22:37 +0300190 }
Derek Jones92763a52011-10-05 15:28:52 -0500191 }
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
Alan Jenkinsa51f8ec2012-11-19 10:29:52 +0000300it, place this code and save it to your application/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
Andrey Andreevd8e1ac72012-03-26 22:22:37 +0300307 public function index()
Derek Jones92763a52011-10-05 15:28:52 -0500308 {
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
Alan Jenkinsa51f8ec2012-11-19 10:29:52 +0000341it, place this code and save it to your application/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
Andrey Andreevd8e1ac72012-03-26 22:22:37 +0300348 public function index()
Derek Jones92763a52011-10-05 15:28:52 -0500349 {
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
Andrey Andreevd8e1ac72012-03-26 22:22:37 +0300360 public function process($request)
Derek Jones92763a52011-10-05 15:28:52 -0500361 {
362 $parameters = $request->output_parameters();
363
364 $response = array(
Andrey Andreevd8e1ac72012-03-26 22:22:37 +0300365 array(
366 'you_said' => $parameters[0],
367 'i_respond' => 'Not bad at all.'
368 ),
369 'struct'
370 );
Derek Jones92763a52011-10-05 15:28:52 -0500371
372 return $this->xmlrpc->send_response($response);
373 }
374 }
375 ?>
376
377
Derek Jones8ede1a22011-10-05 13:34:52 -0500378Try it!
379-------
380
381Now visit the your site using a URL similar to this::
382
383 example.com/index.php/xmlrpc_client/
384
385You should now see the message you sent to the server, and its response
386back to you.
387
388The client you created sends a message ("How's is going?") to the
389server, along with a request for the "Greetings" method. The Server
390receives the request and maps it to the "process" function, where a
391response is sent back.
392
393Using Associative Arrays In a Request Parameter
394===============================================
395
396If you wish to use an associative array in your method parameters you
397will need to use a struct datatype::
398
Derek Jones92763a52011-10-05 15:28:52 -0500399 $request = array(
400 array(
401 // Param 0
402 array(
403 'name'=>'John'
404 ),
405 'struct'
406 ),
407 array(
408 // Param 1
409 array(
410 'size'=>'large',
411 'shape'=>'round'
412 ),
413 'struct'
414 )
415 );
416 $this->xmlrpc->request($request);
Derek Jones8ede1a22011-10-05 13:34:52 -0500417
418You can retrieve the associative array when processing the request in
419the Server.
420
421::
422
Derek Jones92763a52011-10-05 15:28:52 -0500423 $parameters = $request->output_parameters();
Andrey Andreevd8e1ac72012-03-26 22:22:37 +0300424 $name = $parameters[0]['name'];
425 $size = $parameters[1]['size'];
Michael Zimmerd6b7cde2013-06-20 11:54:07 +0200426 $shape = $parameters[1]['shape'];
Derek Jones8ede1a22011-10-05 13:34:52 -0500427
428**************************
429XML-RPC Function Reference
430**************************
431
432$this->xmlrpc->server()
433=======================
434
435Sets the URL and port number of the server to which a request is to be
436sent::
437
438 $this->xmlrpc->server('http://www.sometimes.com/pings.php', 80);
439
440$this->xmlrpc->timeout()
441========================
442
443Set a time out period (in seconds) after which the request will be
444canceled::
445
446 $this->xmlrpc->timeout(6);
447
448$this->xmlrpc->method()
449=======================
450
451Sets the method that will be requested from the XML-RPC server::
452
453 $this->xmlrpc->method('method');
454
455Where method is the name of the method.
456
457$this->xmlrpc->request()
458========================
459
460Takes an array of data and builds request to be sent to XML-RPC server::
461
Derek Jones92763a52011-10-05 15:28:52 -0500462 $request = array(array('My Photoblog', 'string'), 'http://www.yoursite.com/photoblog/');
463 $this->xmlrpc->request($request);
Derek Jones8ede1a22011-10-05 13:34:52 -0500464
465$this->xmlrpc->send_request()
466==============================
467
468The request sending function. Returns boolean TRUE or FALSE based on
469success for failure, enabling it to be used conditionally.
470
471$this->xmlrpc->set_debug(TRUE);
472================================
473
474Enables debugging, which will display a variety of information and error
475data helpful during development.
476
477$this->xmlrpc->display_error()
478===============================
479
480Returns an error message as a string if your request failed for some
481reason.
482
483::
484
485 echo $this->xmlrpc->display_error();
486
487$this->xmlrpc->display_response()
488==================================
489
490Returns the response from the remote server once request is received.
491The response will typically be an associative array.
492
493::
494
495 $this->xmlrpc->display_response();
496
497$this->xmlrpc->send_error_message()
498=====================================
499
500This function lets you send an error message from your server to the
501client. First parameter is the error number while the second parameter
502is the error message.
503
504::
505
506 return $this->xmlrpc->send_error_message('123', 'Requested data not available');
507
508$this->xmlrpc->send_response()
509===============================
510
511Lets you send the response from your server to the client. An array of
512valid data values must be sent with this method.
513
514::
515
Derek Jones92763a52011-10-05 15:28:52 -0500516 $response = array(
517 array(
518 'flerror' => array(FALSE, 'boolean'),
519 'message' => "Thanks for the ping!"
520 )
521 'struct');
522 return $this->xmlrpc->send_response($response);
Derek Jones8ede1a22011-10-05 13:34:52 -0500523
524Data Types
525==========
526
527According to the `XML-RPC spec <http://www.xmlrpc.com/spec>`_ there are
528seven types of values that you can send via XML-RPC:
529
530- *int* or *i4*
531- *boolean*
532- *string*
533- *double*
534- *dateTime.iso8601*
535- *base64*
536- *struct* (contains array of values)
537- *array* (contains array of values)
538