Pull to refresh

Zend_XmlRpc_Client и кросспостинг в LiveJournal

Reading time5 min
Views2.5K
На новый год один добрый человек подарил мне домен. Если есть домен значит там что то должно быть. Решил сделать себе блог. Но так как последние года 2 я использовал livejournal я захотел чтобы мои сообщения синхронизировались с ЖЖ.
Программирую я при помощи любимого Zend Framework.

Часть API живого журнала основанно на протоколе XML-RPC, описание этого API можно найти здесь.
Для того чтобы добавить новый пост в ЖЖ сначала нам нужно получить challenge.
Будем использовать компонент Zend_XmlRpc_Client из Zend Framework.
Создаём его объект —
$xmlRpcClient = new Zend_XmlRpc_Client('http://www.livejournal.com/interface/xmlrpc'); 

входящим параметром у нас передаётся сервер к которому мы будем обращаться в данном случае у нас указан сервер LJ.
Отправляем запрос к серверу:

$chalengeResponse = $xmlRpcClient->call('LJ.XMLRPC.getchallenge');


Этот запрос возвратит нам ответ сервера — это массив в котором и будет указан и challenge, он будет хэшироваться вместе с вашим паролем от ЖЖ и отправляться на сервер — ведь так будет более безопасно передавать пароли. Так же в этом массиве вы получите время сервера ЖЖ и время когда истекает ваш challenge. Мы не будем ждать пока он истечет и сразу же отправим пост.
Но сначала требуется правильно сформировать запрос.
Если вы загляните сюда то найдёте пример нужного xml файла который следует отправить, вы так же должны заметить что он содержит единственный параметр struct типа.

В Zend_XmlRpc_Client — все типы данных из php автоматически переводяться в нужные для XML-RPC.
Ну мы на всякий случай возьмём ещё один компонент это Zend_XmlRpc_Value а именно Zend_XmlRpc_Value_Struct для нашего случая. Как и всякий Zend_XmlRpc_Value этот компонент имеет метод getAsDOM() который вернёт вам объект класса DOMDocument который включён в php. Так же есть метод saveXML() — c помощью которого можно получить xml. В нашем случае мы можем вывести на экран то что у нас получается посмотреть отличия от примера и внести какие то поправки.
В конструктор Zend_XmlRpc_Value_Struct принимает ассоциативный массив.
ну примерно это мы и сделаем например так:

  $postOptions = new Zend_XmlRpc_Value_Struct(
      array(
            'username'    => $ljUsername,
            'auth_method'  => 'challenge',
            'auth_challenge' => $chalengeResponse['challenge'],
            'auth_response' => md5($chalengeResponse['challenge'] . md5($this->_ljPassword)),
            'ver'      =>'1',
            'event'     => 'Этот пост был написан с использованием протокола xml-rpc',
            'subject'    => 'xml-rpc test',
            'year'      => 2010,
            'mon'      => 1,
            'day'      => 3,
            'hour'      => 4,
            'min'      => 33,
            'props'     => array(
                      'opt_preformatted' => true,
                      'taglist'     => 'tag1, tag2, tag3'
            ),
            'security'    =>'public'
            ));


* This source code was highlighted with Source Code Highlighter.


В конструктор мы передали массив параметров, давайте разбираться что же там были за параметры:
  • username — имя жж пользователя
  • auth_method — метод авторизации
  • auth_challenge — challenge который мы получили
  • auth_response — зашифрованный функцией md5 challange вместе с зашифрованным же паролем от ЖЖ
  • event — текст нашего топика
  • subject — заголовок топика
  • следующие 5 параметров указывают дату публикации топика (да-да можно поставить задним числом :) )
    props — это параметры топика их достаточно много все перечислять долго можете прочесть о них здесь.
  • security — права доступа могут быть public, private и usemask если вы используете последний то нужно будет обязательно указать параметр allowmask. я указал то что мне нужно сохранять форматирование и теги.
    этот параметр тоже — struct.


Теперь осталось создать наш запрос и выполнить его:

$request = new Zend_XmlRpc_Request();
$request->setMethod('LJ.XMLRPC.postevent');
$request->addParam($postOptions);
$xmlRpcClient->doRequest($request);



Мы создали объект запроса Zend_XmlRpc_Request установили для него метод LJ.XMLRPC.postevent, добавили параметр, и выполнили запрос на сервер.
У класса Zend_XmlRpc_Request так же есть метод toXml который возвращает сгенерированный xml, на случай если нам нужно его использовать где то ещё, например сохранить и подарить другу напамять.

мы так же хотим получить id поста в ЖЖ и его ссылку
воспользуемся методом getLastResponse(), а затем получим то что ответил нам сервер методом getReturnValue()
$newPost = $xmlRpcClient->getLastResponse()->getReturnValue();


В массиве $newPost оказался ответ сервера, который в себе содержит ссылку на пост в ЖЖ и его id.

На самом деле могло быть всё гораздо проще я намеренно усложнил всё чтобы показать другие компоненты учавствующие в работе Zend_XmlRpc_Client.
Могло быть так:
$newPost = $xmlRpcClient->call('LJ.XMLRPC.getchallenge', array(/*здесь массив параметров*/));

В массив параметров мы могли бы засунуть все параметры которые нам нужны только
стоит помнить как преобразуются типы данных из php в xml-rpc ибо они будут преобразовываться автоматически по данной табличке:
Тип в PHP Тип в XML-RPC
integer int
double double
boolean boolean
string string
array array
array (ассоциативный) struct
object array


Для того чтобы отредактировать пост, вам достаточно точно так же отправить запрос LJ.XMLRPC.editevent с такими же параметрами как при добавлении поста, только добавить ещё itemid который возвращается вам при добавлении поста.
А чтобы удалить пост вам нужно его отредактировать но без subject и event.

Всем спасибо, надеюсь кому-то пригодиться. Может быть в следующий раз напишу про Zend_XmlRpc_Server если придумаю зачем его использовать :).
Tags:
Hubs:
Total votes 14: ↑11 and ↓3+8
Comments11

Articles