XML-RPC: постинг в WORDPRESS
В современном мире, чтобы быть лучшим, чтобы вырваться в лидеры, чтобы захватить большую часть рынка, другими словами, чтобы стать успешным, нужно предлагать пользователю как можно больше функциональных возможностей. В наше время, WordPress является самым популярным блоговым движком. И популярным он стал не благодаря раскрутке, а по большей части благодаря тому, что смог предложить блоггерам максимально удобную среду, а также достаточную функциональность для успешного ведения блогов. Среди прочей функциональности, можно выделить удаленную работу с записями посредством XML-RPC. В WordPress достаточно богатый API, который позволяет работать с записями, категориями, тегами и т.д. Т.е. практически полноценный API, который позволяет публиковать, редактировать, удалять записи, теги, категории и т.д.
Сегодня продолжим рассматривать примеры вызова процедур XML-RPC. На этот раз, как все уже догадались, рассмотрим постинг в WordPress.
Постинг
Сервер для постинга расположен по адресу /xmlrpc.php
Для постинга вызывается процедура metaWeblog.newPost. Полное описание всех параметров, которые передаются процедуре лучше всего смотреть в файле /xmlrpc.php.
Рассмотрим некоторые параметры, которые описаны в движке 2.9
metaWeblog.newPost(int $blog_ID, string $username, string $password, struct $content_struct, boolean $publish)
- int $blog_ID – идентификатор блога. Имеет значение только для многоблоговых движков. В случае с одним блогом, пишем 0;
- string $username – имя пользователя;
- string $password – пароль. Никак не зашифрованный =(;
- struct $content_struct – структура с данными для постинга (см. ниже);
- boolean $publish – если true, то публикация поста, если false, то редактирование.
Теперь рассмотрим некоторые основные составляющие структуры $content_struct.
- post_type – тип записи. Может быть «post» или «page». Если будет другое значение, то вернет ошибку. Данное поле обязательно;
- wp_password – пароль на запись. Если установлено, то запись будет доступна только по паролю. Данное поле не обязательно;
- wp_page_parent_id – идентификатор предка страницы. Устанавливается только для страниц, которые имеют предков;
- wp_page_order – порядок страницы в меню. Обязательно только для страниц;
- wp_author_id – идентификатор автора записи. Если автором записи является не $username (см. выше), то в этом поле указывается идентификатор автора записи. Данное поле не обязательно для записи;
- title – наименование записи. Вообще-то проверок на присутствие данного поля нет в коде, но вы видели где-нибудь нормальную запись без наименования? Вот и я не видел. Поэтому это поле лучше всего заполнить;
- description – текст записи. Дела с этим полем обстоят как и с предыдущим;
- mt_excerpt – выдержка из текста, которая будет отображаться на главной под наименованием поста (в зависимости от темы). Поле не обязательно для заполнения;
- mt_text_more – текст после тега <!–more–>. Если это поле заполнено, то пост будет иметь такую структуру: сначала будет идти description, после него mt_text_more. Поле не обязательно для заполнения;
- mt_keywords – массив тегов. Поле не обязательно для заполнения;
- mt_allow_comments – статус комментариев к записе. closed, 0 или 2 – запрещены, open или 1 – разрешены. Не обязательно для заполнения. Если не будет заполнена, то будет взята из базы опция default_comment_status;
- mt_allow_pings – статус пингов и трэкбэков. closed или 0 – запрещены, open или 1 – разрешены. Не обязательна для заполнения. Если не будет заполнена, то будет взята из базы опция default_ping_status;
- mt_tb_ping_urls – массив url-адресов, которые нужно пропинговать. Не обязательно для заполнения;
- date_created_gmt и dateCreated – дата создания записи. По Гринвичу и по локальному времени. Одно из полей желательно для заполнения. Если не будет заполнено ни одно из них, то будет взята текущая дата из СУРБД MySQL
- categories – массив категорий, в которых находится запись. Категории, как и теги должны быть записаны в текстовом формате. Поле не обязательно для заполнения;
Процедура, в случае успеха, вернет идентификатор добавленной записи. В случае неудачи, вернет ошибку.
Настройки
По умолчанию, возможность удаленного постинга через XML-RPC отключена. Для включения нужно перейти в админку, в раздел Настройки->Написание и в разделе «Удаленная» публикация нужно поставить галку напротив XML-RPC и нажать на кнопку Сохранить изменения
XML-RPC for PHP
Попробуем написать код, который запостит в блог через XML-RPC, посредством библиотеки XML-RPC for PHP.
xml-rpc.php
<?php //подключаем библиотеку include_once 'xml-rpc/lib/xmlrpc.inc'; //чтоб не было проблем с кодировкой $GLOBALS['xmlrpc_internalencoding'] = 'UTF-8'; header('Content-type:text/html;charset=utf-8'); //логин и пароль $u_name = 'admin'; $u_pass = 'admin'; //обращаемся к test.wordpress.loc/xmlrpc.php $wp = new xmlrpc_client('/xmlrpc.php','test.wordpress.loc',80); //кодировка клиента $wp->request_charset_encoding = 'UTF-8'; //чтоб возвращал в виде php-переменных $wp->return_type = 'phpvals'; $struct = array(); //тип записи: page - страница, post - пост $struct['post_type'] = new xmlrpcval('post', 'string'); //наименование статьи $struct['title'] = new xmlrpcval('Заголовок статьи', 'string'); //сама статья отформатированная в html $struct['description'] = new xmlrpcval( 'В черном-черном городе, на черной-черной улице, '. 'в черном-черном доме,в черно-черной квартире сидит '. 'черный-черный мужик и говорит: - Никогда больше '. 'не буду <strong>сам заправлять картриджи!</strong>', 'string'); //краткое описание, которое будет отображено на главной $struct['mt_excerpt'] = new xmlrpcval( 'Краткое описание статьи', 'string'); //массив с тегами $struct['mt_keywords'] = new xmlrpcval(array( new xmlrpcval('анекдот', 'string'), new xmlrpcval('юмор', 'string')), 'array'); //комментарии: 0 - запрещены, 1 - разрешены $struct['mt_allow_comments'] = new xmlrpcval(1, 'int'); //пинги: 0 - запрещены, 1 - разрешены $struct['mt_allow_pings'] = new xmlrpcval(1, 'int'); //вместо таймштампа можно передать //объект класса DateTime $struct['dateCreated'] = new xmlrpcval( time(), 'dateTime.iso8601'); //статуст записи: publish - публичная, private - приватная $struct['post_status'] = new xmlrpcval('publish', 'string'); //массив с категориями: все категории должны существовать $struct['categories'] = new xmlrpcval(array( new xmlrpcval('Uncategorized', 'string')), 'array'); //собираем все в кучу $params = array( //ид блога new xmlrpcval(0, 'int'), //логин new xmlrpcval($u_name, 'string'), //пароль new xmlrpcval($u_pass, 'string'), //данные new xmlrpcval($struct, 'struct'), //публикация: true - опубликована, //false - не опубликована new xmlrpcval(true, 'boolean')); //вызываем процедуру metaWeblog.newPost $r = $wp->send(new xmlrpcmsg('metaWeblog.newPost', $params)); //если ошибка, сообщаем об ошибке постинга if ($r->faultCode()) { die('Ошибка постинга:' . $r->faultString()); } //WP вернет идентификатор поста в случае успеха $p = $r->value(); echo 'Запостили пост успешно. Его идентификатор '. 'имеет номер ' . $p .'. Прочитать статью можно'. ' <a href="http://test.wordpress.loc/?p=' . $p . '">здесь</a> ';
В результате успешной публикации, перейдя по ссылке, можем видеть текст опубликованной записи.
PEAR XML_RPC2
Теперь напишем код, который запостит с помощью библиотеки PEAR XML_RPC2.
xml_rpc2.php
<?php //подключаем библиотеку include_once 'XML/RPC2/Client.php'; header('Content-type:text/html;charset=utf-8'); //логин и пароль $u_name = 'admin'; $u_pass = 'admin'; //массив опций $options = array( //префикс 'prefix' => 'metaWeblog.', //кодировка 'encoding' => 'utf-8', //если нужен дебаг //'debug'=>true ); //создаем клиента $client = XML_RPC2_Client::create( 'http://test.wordpress.loc/xmlrpc.php', $options); try { $struct = array(); //тип записи: page - страница, post - пост $struct['post_type'] = 'post'; //наименование статьи $struct['title'] = 'Заголовок статьи'; //сама статья отформатированная в html $struct['description'] = '- Алло? '. '- Алло! Доброе утро, молодой человек! '. 'Умоляю вас, <strong>не кладите трубку</strong>! ' . 'Скажите мне - <strong>кто</strong> я?! <strong>Где</strong> я сейчас?!'. ' <strong>Куда</strong> мне идти?!' . ' Дорогие радиослушатели, вы прослушали'. ' короткую радиопостановку "Утро DHCP сервера".'; //краткое описание, которое будет отображено на главной $struct['mt_excerpt'] = 'Краткое описание статьи'; //массив с тегами $struct['mt_keywords'] = array('анекдот', 'юмор'); //комментарии: 0 - запрещены, 1 - разрешены $struct['mt_allow_comments'] = 1; //пинги: 0 - запрещены, 1 - разрешены $struct['mt_allow_pings'] = 1; //$struct['dateCreated'] = date('c',time()); //статуст записи: publish - публичная, private - приватная $struct['post_status'] = 'publish'; //массив с категориями: все категории //должны существовать $struct['categories'] = array('Uncategorized'); //ид блога $id = 0; //публикация: true - опубликована, //false - не опубликована $public = true; //вызываем процедуру $p = $client->newPost($id, $u_name, $u_pass, $struct, $public); echo 'Запостили пост успешно. Его идентификатор'. ' имеет номер ' . $p .'. Прочитать статью можно'. ' <a href="http://test.wordpress.loc/?p=' . $p .'">здесь</a> '; } catch (XML_RPC2_FaultException $e) { die('Exception #' . $e->getFaultCode() . ' : ' . $e->getFaultString()); } catch (exception $e) { die('Exception : ' . $e->getMessage()); } ?>
В результате имеем новую статью
Читайте все статьи цикла:
- XML-RPC: библиотеки для взаимодействия с удаленными сервисами
- XML-RPC: Постинг в LiveJournal
- XML-RPC: постинг в WORDPRESS
- XML-RPC: работа с помощью Zend Framework
Популярность: 18%
Интересное из других блогов:
2leep.comИ не забывайте комментировать статью.
Добавляйся в группу во вконтакте, чтобы самым первым узнавать все новости сайта


Автор: vredin, 8 марта 2010 в 14:17
используетпрошу прощения, я еще только разбираюсь
1. какой из способов “лучше”? либо результат один и тот же а просто инструменты разные?
2. я правильно понял что эти скрипты надо запускать из той же папки где установлен wp? а как сделать если я хочу с локальной машины постить на удаленный сервер?
Автор: vredin, 8 марта 2010 в 14:28
используетага, добрался до 2-го примера.. скопировал его себе в денвер, изменил параметры для постинга в один из моих блогов, запустил – пустое окно
что может быть причиной? wp версии 2.3.3, xmlrpc.php на сервере существует
Автор: web-junior, 8 марта 2010 в 14:40
используетдля второго примера вам нужна библиотека PEAR XML_RPC2 вместе со всеми зависимыми пакетами.
Автор: vredin, 8 марта 2010 в 15:08
используетя ее закачал и подставил под структуру как в скрипте после первого же запуска.. но на странице всё равно ничего не выводится
причем вставлял echo сразу после XML_RPC2_Client::create чтобы отловить дошел ли скрипт до этого места + включал debug в массиве опций – ничего не помогло..
Автор: web-junior, 8 марта 2010 в 15:33
используетНичего не выводит скорее из-за того, что происходит какая-то ошибка.
Текст ошибки не выводится скорее из-за настроек php.
Напишите в самом начале скрипта
error_reporting(E_ALL&E_NOTICE);
ini_set(‘display_errors’,’1′);
или сделайте соответствующие настройки в php.ini
Автор: vredin, 8 марта 2010 в 22:54
используетдумаю, это изза того что я использую Денвер.. на реальном сервере ошибки выводятся и кстати результат вашего скрипта “XML_RPC2_FaultException #-32700 : parse error. not well formedException #-32700 : parse error. not well formed”
Автор: web-junior, 9 марта 2010 в 09:43
используетэта ошибка означает, что был передан XML не тот, который ожидался. Скорее всего API XML-RPC у WP различается в версиях 2.3 и 2.9
Вам нужно самостоятельно открыть файл /xmlrpc.php в WP, найти там процедуру newPost и посмотреть какие данные он требует
Автор: vredin, 10 марта 2010 в 16:23
используетура! поставил виртуальную машину, на нее дебиан и связку apache+mysql+php5 – постинг сработал с первого раза с помощью xml-rpc2
но
подскажите, как проследить на каком этапе ломается кодировка?
база у меня однозначно utf8_general_ci, скрипт выполняется в cp1252(HTML-Entities → CP1252 → CP1251 декодер лебедева показал), хотя я принудительно указал header(‘Content-type:text/html;charset=utf-8′) + для metaWeblog encoding => utf-8
пост добавился и на странице редактирования поста он отображается в cp1252(cp1252->cp1251 опять же через декодер)
p.s. обожаю блоги, где после забывания ввода каптчи тебя кидает назад и твой текст остается на месте!
Автор: vredin, 10 марта 2010 в 16:41
используети при этом странность ситуации что при выполнении вашего 2-го листинга до 62-й строки текста выводится как “ÑžÐ¼Ð¾Ñ€” (HTML-Entities → ISO-8859-1 → UTF-8 ) а вывод 62-й строки уже нормальный, в utf-8
помогите, пожалуйста, почти все ссылки по этой теме ведут на ваш блог
Автор: web-junior, 10 марта 2010 в 17:46
используеттекст, который вы вставили до 62-й строки был написан не в утф-8. А 62-я в утф-8. И при этом все выводилось в утф-8.
Автор: vredin, 10 марта 2010 в 18:01
используетдо 62-й строки вывод был изза включения debug==true в 14 строке, хотя когда я эту же строку вывел сразу после 62-й строки, она вывелась как utf8.. я в растерянности
Автор: web-junior, 10 марта 2010 в 17:44
используетв этом случае, наверное единственный способ – это включить дебаг в XML_RPC2. Это делается с помощью раскоментирования опции debug=>true.
Вообще, лучший способ избавиться от проблем с кодировкой – это работать непосредственно с утф-8. Или принудительно кодировать в утф-8 с помощью php.
Автор: vredin, 10 марта 2010 в 17:58
используетладно, пойду искать другой вариант забить всё в базу..
я как раз из дебага и вытаскивал строки.. везде уже указан этот утф8.. сам скрипт преобразовал в нотепад++ в утф8, в скрипте указан утф8, база блога в утф8 и сам блог в утф8, какого ** оно показывается непонятно как.. уже даже в xml/rpc2/client.php менял с iso на utf8 – не помогло..
http://pics4u.ru/image-7A47_4B97C0A8.jpg
ладно, спасибо за помощь.. буду искать как напрямую в базу вбивать
Автор: vredin, 10 марта 2010 в 19:32
используетпрошу прощения если надоел, но проблема скорее всего в окружении.. попробовал на другом сервере этот же скрипт для того же блога – всё пучком, никаких крокозябл
Автор: web-junior, 10 марта 2010 в 20:40
используетне стоит извиняться: вы ведь не виноваты в том, что все так сложно устроено с кодировками =)
Если у вас получится понять в чем была причина проблем с кодировками, пожалуйста, расскажите мне и всем читателям блога об этом.
Автор: Swagger, 3 мая 2010 в 09:03
используетА возможно ли через XML-RPC постить комментарии в WordPress?
Автор: web-junior, 3 мая 2010 в 18:58
используетможно. Для этого нужно вызывать процедуру wp.newComment. Таким образом могут комментировать только зарегистрированные пользователи.
Если хотите, чтобы на вашем сайте могли оставлять анонимные комментарии, то можете поставить плагин Anonymous XMLRPC Comments
Автор: Олег, 11 июня 2010 в 21:27
используетПо первому способу всегда возвращает “No data received from server.”
Уже 100 раз все перепроверил, не хочет постить
Автор: Саша, 26 июля 2010 в 11:06
используеткак реализовать такое для dle?
Автор: web-junior, 26 июля 2010 в 12:10
используетУ DLE удаленных публикаций с помощью XML-RPC нет. Можете попробовать самостоятельно написать модуль для DLE, который реализует необходимый функционал.
Автор: alant, 12 января 2011 в 16:08
используета в первом то примере код не полностью.
такой прикол? или вытерся?
Автор: web-junior, 15 января 2011 в 13:50
используеткод там полностью. Закрывающийся ?> не обязателен, если нет html кода после инструкций php
Автор: DNS, 3 июня 2011 в 13:50
используетпри запуске первой версии скрипта выбивает следующие ошибки wp и скрипт на денвере в одном домене скрипт в корне(тамже где и вп) xml-rpc вроде бы включен
Warning: include_once(xml-rpc/lib/xmlrpc.inc) [function.include-once]: failed to open stream: No such file or directory in X:\home\game1.lc\www\post1.php on line 3
Warning: include_once() [function.include]: Failed opening ‘xml-rpc/lib/xmlrpc.inc’ for inclusion (include_path=’.;/usr/local/php5/PEAR’) in X:\home\game1.lc\www\post1.php on line 3
Warning: Cannot modify header information – headers already sent by (output started at X:\home\game1.lc\www\post1.php:3) in X:\home\game1.lc\www\post1.php on line 6
Fatal error: Class ‘xmlrpc_client’ not found in X:\home\game1.lc\www\post1.php on line 13
подскажите как править?