XML - RPC protocol was originally created by web developer Dave Winner from "UserLand software company" in cooperation with Microsoft in 1998. However, Microsoft Corp. soon found this protocol too simplistic, and started to expand its functionality (that later resulted in establishing the extended protocol SOAP). Despite the rejection by Microsoft, XML - RPC standard, with its extraordinary simplicity, has so far charmed many web developers. (Wikipedia)
In Drupal XML - RPC began it's existence in 4.6 version. Some minor changes in its operation occurred after the release of Drupal 7.
First, let's set the tasks to ourselves and try to suggest the idea what we can utilize the XML - RPC protocol for. We've got 2 websites at our disposal:
- website "A"
- website "B"
The tasks are as follows:
1. learning all possible site "B's methods while staying onsite "A"
2. creating the functional for the content quantity output. Staying on site "A" we're supposed to control the numbers of nodes on site "B" and vica verse.
3. creating a content functional of the site "B" while you stay on site "A" and vica verse
Task#1
Drupal has a list of system methods, which are available immediately after the installation's done. The list of standard methods is as follows:
1. system.multicall- a systematic method, that allows for activating additional methods.
2. system.methodSignature- returns an array, the description of the data return type and the required data type for the selected method.
3. system.getCapabilities- returns a description of the XML - RPC specification supported by this server.
4. system.listMethods- displays a list of available methods.
5. system.methodHelp- displays the description line for the specified method.
For solving the problem we need a method system, listMethods which displays all the methods of the site.
Reguest of any method is performed by using xmlrpc($url, $args, $options = array()).
Let's look at the function arguments, there are only three of them:
1. $url -the absolute addresses for file request, like «/example.com/xmlrpc.php».
2. $args -associative array whose keys reflected the methods which arguments are passing to the appropriate method. If several methods are not specified, system.multicall are not satisfied too.
3. $options(not obvious argument) - the parameters of the query.
The only thing to do to get all site "B" methods is just to write the following line of code:
php $methods = xmlrpc('http://site-b.com/xmlrpc.php', array('system.listMethods' => array())
As a result of the query, we will print an array with all available methods for site "B". Also, you can get all available methods of the current site. You need only one argument of XML - RPC function to be changed that is to change website to which you address.
Task # 2
In order to get the number of nodes on another site, we should create our own method. Method can be created using hook_xmlrpc().
In hook, we must return an array that has a name of method, the output type of argument (if any) and the description of the method (not obligatory).
In the method we can send data types:
- boolean
- double
- int
- array
- struct
- data;
- base 64
- string
Example of hook_xmlrpc() realization:
php function internetdevels_xmlrpc_xmlrpc() { $methods[] = array( 'id_xmlrpc.node_count', // указываем название метода '_id_xmlrpc_node_count', // функция, которая запускаеться при вызове метода array('int'), // 1 значением массива обозначаем тип данных, 2 значение массива будет 1 аргументом в функции метода, 3 значение будет 2 аргументом фунукции и т.д. t('Return count of node') // описание к методу ); return $methods; }
So, we have announced our hook_xmlrpc. The function will perform a simple select to the database and will return the number of records from the table node. Here is the function itself:
php function _id_xmlrpc_node_count() { return db_select('node', 'n') ->fields('n') ->execute() ->rowCount(); }
Pay attention that the method and function should be the same as on the site "A" and the site "B".
Now we can get the number of entries in the table of site "A" begin on site "B". In my case, the query would be:
php $ncount = xmlrpc('http://site-b.com/xmlrpc.php', array('id_xmlrpc.node_count' => array()));
in $ncount in case of successfull request, we will have a number, that will show the amount of records in the table node on site "B".
Task #3
In this task, we also need to declare a method. In my case, I will ask hook_xmlrpc the following method:
php $methods[] = array( 'id_xmlrpc.node_new_page', '_id_xmlrpc_node_new_page', array('string', 'array'), t('Return count of node') );
we will return a reference to the created material, the function will have one argument that will contain an array of :
php function _id_xmlrpc_node_new_page($data) { $node = new stdClass; $node->title = $data['title']; $node->type = 'page'; $node->created = REQUEST_TIME; $node->status = 1; $node->body['und'][0]['value'] = $data['body']; node_save($node); if (is_numeric($node->nid)) { return url('node/' . $node->nid, array('absolute' => TRUE)); } else { return ''; } }
Then we can call the method that will create content and if the content successfully create, in response to a request we will get a link.
Now being on the site "A" we can create a new node on the site "B". In my case, to create a content on another site, I will describe function in this way:
php $options = array('id_xmlrpc.node_new_page' => array( // создаем переменную с названием метода и опциями запроса array( 'title' => 'Title of the new node', // заголовок контента 'body' => 'Body of the new node' // текст контента ) )); // запускаем функцию xmlrpc $node_link = xmlrpc('http://site-b.com/xmlrpc.php', $options);
If the request successful, in $node_link we will have a link on the content, which we created.
Summary:
Despite the fact that XML- RPC protocol has been long since designed, it is still relevant. It can help solve various problems of (2 or more) sites' simultaneous interaction. It is going to take just one function to build a query, with some simple parameters specified, to eventually make the work with the XML - RPC protocol easy and smooth.