XML-RPC в Drupal 7

Версия Drupal: 
7.x

XML-RPC – простой протокол вызова удаленных процедур. XML-RPC является прародителем одного из популярных протоколов SOAP и, не смотря на свой возраст (реализован в 1998 году), XML-RPC не канул в лету, а напротив, очень даже часто используется в наши дни. Не является исключением использование XML-RPC также и в движке Drupal.

ПротоколXML-RPCбыл изначально разработан Дэйвом Винером из компании «UserLand Software» в сотрудничестве с Майкрософт'ом в 1998 году. Однако корпорация Майкрософт вскоре сочла этот протокол слишком упрощённым, и занялась расширением его функциональности (и как следствие был создан расширенный протоколSOAP). Но, не взирая на холодность со стороны Майкрософт, стандартXML-RPC очаровал многих программистов своей необычайной простотой, благодаря которой он по сей день существует и, даже, постепенно набирает популярность. (Википедия)

ВDrupal XML-RPC начал существовать с версии 4.6. Небольшие изменения в работе функции произошли с выходом 7 версии Drupal.

Для начала давайте поставим себе задачи, то есть прикинем, для чего мы можем использовать протоколXML-RPC.

В нашем распоряжении 2 сайта:

  • сайт «А»
  • сайт «B»

Задачи перед нами следующие:

  1. Узнать все возможные методы сайта «В» находясь на сайте «А».
  2. Создать функционал вывода количества контента. Находясь на сайте «А» мы должны узнать количество нод на сайте «В» и наоборот.
  3. Создать функционал создания контента на сайте «В» находясь на сайте «А» и наоборот.

Задача 1

В друпале есть список системных методов, которые становятся доступными сразу же после его установки. Список стандартных методов такой:

  1. system.multicall– системный метод, который позволит нам вызвать несколько других методов. 
  2. system.methodSignature– возвращает массив, с описанием типа возврата данных и типа требуемых данных для выбранного метода. 
  3. system.getCapabilities- возвращает структуру описания XML-RPC спецификации поддерживаются этим сервером. 
  4. system.listMethods– выводит список доступных методов. 
  5. system.methodHelp– выводит строку описания для указанного метода.

Для решения задачи нам потребуется метод system.listMethods, который выведет все методы сайта.

Запрос любого метода исполняется с помощью функции xmlrpc ($url, $args, $options = array()).

Давайте разберем аргументы функции, их всего 3:

  1. $url– абсолютный адрес к файлу запросов, например «http://example.com/xmlrpc.php». 
  2. $args- ассоциативный массив, ключи которого являются методы, значения которых аргументы для передачи соответствующим методом. Если несколько методов не указаны, system.multicall не выполняется. 
  3. $options(не обязательный аргумент) – параметры выполнения запроса.

Чтобы получить все методы сайта «В» нам потребуется всего то лишь написать следующую строчку кода:

php
$methods = xmlrpc('http://site-b.com/xmlrpc.php', array('system.listMethods' => array())

результатом выполнения запроса у нас выведется массив со всеми доступными методами сайта «В». Так же можно получить все доступные методы на текущем сайте, стоит лишь поменять 1 аргумент функции xmlrpc, то есть поменять сайт, к которому обращаемся.

Задача 2

Для того что бы получить количество нод на другом сайте, нам следует создать свой метод. Методы создаются с помощью hook_xmlrpc().

В хуке мы должны возвращать массив, в котором есть название метода, тип выходных данных, тип аргументов (если они есть) и описание метода (не является обязательным).

В методы мы можем передавать данные следующих типов:

 

  • boolean
  • double
  • int
  • array
  • struct
  • date
  • base64
  • string

Пример реализации hook_xmlrpc().

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;   
} 

Итак, мы объявили свой hook_xmlrpc. Функция будет исполнять простой селект в БД и возвращать количество записей из таблицы node. Вот и сама функция:

php
function _id_xmlrpc_node_count() {   
  return db_select('node', 'n')   
    ->fields('n')   
    ->execute()   
    ->rowCount();   
} 

Обратите внимание на то, что метод и функция должна быть как на сайте «А» та и на сайте «В».

Теперь мы можем получить количество записей в таблице сайта «А» находясь на сайте «В». В моем случае запрос будет такой:

php
$ncount  = xmlrpc('http://site-b.com/xmlrpc.php', array('id_xmlrpc.node_count' => array()));

в $ncount при удачном запросе у нас будет число, которое и будет показывать количество записей в таблице node на сайте «В».

Задача 3

В данной задаче нам также потребуется объявить свой метод, в моем случае я буду в hook_xmlrpc задавать следующий метод:

php
$methods[] =  array(   
    'id_xmlrpc.node_new_page',   
    '_id_xmlrpc_node_new_page',   
    array('string', 'array'),   
    t('Return count of node')   
  ); 

возвращать будем ссылку на созданный материал, у функции будет 1 аргумент содержащий в себе массив

Функция вызова метода следующая:

 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 '';   
  }   
} 

Дальше мы можем вызывать метод, который создаст нам контент, и если контент будет успешно создан, в ответе на запрос мы получим на его ссылку.

Теперь, находясь на сайте «А», мы можем создать новую ноду на сайте «В». Обратите внимание на то, что такой метод должен находиться на сайте «В». В моем случае, для того чтобы создать контент на другом сайте, я прописываю функцию так:

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); 

при успешном выполнении запроса, в $node_link мы будем иметь ссылку на контент, который создали.

Итог

Не смотря на то что протокол XML-RPC создан уже достаточно давно, он по сей день актуален, поскольку с его помощью можно решиать различные задачи, требующие взаимодействия 2-х (и более) сайтов между собой. Для построения запроса понадобится использовать всего лишь одну функцию, в которой нужно указать простые параметры, что и упрощает работу с протоколом XML-RPC.