Приветствую всех!
Тема публикации работы с движком WordPress через XML-RPC протокол обсуждается довольно часто. Пожалуй, это самый удобный способ удаленной публикации постов. Но, если вы хоть раз использовали эту возможность, то, скорее всего, заметили, что встроенный XML-RPC сервер поддерживает далеко не все возможности движка.
К тому же в последних версиях появилась возможность создавать собственные типы данных, и было бы удобно иметь возможность нормально работать с ними через XML-RPC.
Сегодня я покажу небольшой пример создания собственного XML-RPC сервера для WP.
Примечание. Если вы раньше не работали с XML-RPC, то, думаю, вам будет интересно почитать статьи Публикация постов в WordPress с помощью XML-RPC и CodeIgniter и Отложенная публикация постов в WordPress с помощью XML-RPC.
Прежде всего, сформулируем задачу.
Допустим, нам нужно создать новый тип данных под названием example_products
и обеспечить возможность публикации записей этого типа через XML-RPC. Также добавим возможность организовывать записи в виде иерархической структуры.
Т.е. получается аналог страниц (Pages) WP, но для демонстрации идеи, думаю, этого будет достаточно.
Шаг 1. Создаём новый тип данных.
Для этого в файл functions.php
, который находится в папке вашей темы, добавляем следующий код.
add_action( 'init', 'create_post_type' ); function create_post_type() { register_post_type( 'example_product', array( 'labels' => array( 'name' => __( 'Products' ), 'singular_name' => __( 'Product' ) ), 'public' => true, 'hierarchical'=>true, 'supports'=>array( 'title', 'editor', 'page-attributes', ), ) ); }
Этот код практически полностью повторяет пример из кодекса.
Разница в том, что здесь включена поддержка иерархий ('hierarchical'=>true
).
В результате в админке появится новый пункт Products.
Шаг 2. Разрешаем работу через XML-RPC.
В целях безопасности, по-умолчанию, эта возможность отключена. Поэтому в настройках (Settings -> Writing) отмечаем чекбокс XML-RPC.
Шаг 3. Создаём XML-RPC сервер.
В принципе, можно добавить необходимые методы в стандартный сервер WP (файл xmlrpc.php). Но этот подход мне не нравится, т.к. потом придется патчить этот файл после каждого обновления движка.
Поэтому мы будем использовать свой сервер. Создаём в корне блога файл xmlrpc-extended.php
со следующим содержимым.
<?php define('XMLRPC_REQUEST', true); /** Include the bootstrap for setting up WordPress environment */ require_once('wp-load.php'); require_once(ABSPATH . 'wp-admin/includes/admin.php'); require_once(ABSPATH . WPINC . '/class-IXR.php'); class XMLRPCServerExtended extends IXR_Server { public function XMLRPCServerExtended() { $this->IXR_Server(array( 'wp_extended.create_product' => 'this:create_product', )); } /** * Создание страницы типа 'Product'. * * @param array $args массив с данными * $args[0] - имя пользователя * $args[1] - пароль * $args[2] - массив с данными для создания поста * (перечень полей здесь - http://codex.wordpress.org/Function_Reference/wp_insert_post) * @return - сообщение о результате создания страницы */ public function create_product($args) { $username = $args[0]; $userpass = $args[1]; $post_data = $args[2]; //проверяем логин/пароль if ( $this->login_pass_ok( $username, $userpass ) ) { //получаем id пользователя $user_data = get_userdatabylogin( $username ); $post_data['post_type'] = 'example_product'; $post_data['post_author'] = $user_data->ID; $post_data['ping_status'] = get_option( 'default_ping_status' ); //Добавляем пост if ( 0 !== ( $post_id = wp_insert_post( $post_data ) ) ) { return 'Created post '.$post_id; } return 'Post add error'; } } /** * Check user's credentials. * * @since 1.5.0 * * @param string $user_login User's username. * @param string $user_pass User's password. * @return bool Whether authentication passed. * @deprecated use wp_xmlrpc_server::login * @see wp_xmlrpc_server::login */ function login_pass_ok($user_login, $user_pass) { if ( !get_option( 'enable_xmlrpc' ) ) { $this->error = new IXR_Error( 405, sprintf( __( 'XML-RPC services are disabled on this site. An admin user can enable them at %s'), admin_url('options-writing.php') ) ); return false; } if (!user_pass_ok($user_login, $user_pass)) { $this->error = new IXR_Error(403, __('Bad login/pass combination.')); return false; } return true; } } $server = new XMLRPCServerExtended();
Принцип работы сервера довольно простой. В начале мы загружаем скрипты WP для того, чтобы получить доступ к встроенным функциям, и библиотеку Incutio XML-RPC Library (она входит в дистрибутив WP).
Затем создаём сервер. Для этого наследуем класс IXR_Server
. В конструкторе указываем массив с перечнем методов, которые поддерживает данный сервер. В этом примере метод только один — wp_extended.create_product
.
И создаём метод create_product
, который и добавляет запись. Этому методу мы передаём массив с данными для создания записи. Формат передачи данных произвольный, тут всё зависит от вас. Главное, соблюдать его при создании XML-RPC клиента.
Первыми элементами массива идут имя пользователя и пароль. Будьте внимательны, если вы забудете авторизовать пользователя, то кто угодно сможет публиковать записи.
Внутри метода create_product
мы проверяем полученные логин и пароль. Для этого используется метод login_pass_ok
. Я его просто скопировал из файла xmlrpc.php. В нём выполняется две проверки.
1) Разрешена ли работа через XML-RPC.
2) Проверяется логин и пароль пользователя.
Затем мы с помощью функции wp_insert_post создаём запись. При этом заполняем массив с данными. Часть этих данных (например, заголовок и текст записи) мы получаем от клиента, но некоторые поля заполняем на сервере. Сюда относятся:
1) post_type
– тип записи;
2) post_author
– id автора записи (для его получения используем логин пользователя);
3) ping_status
– указывает, разрешены или запрещены трекбеки и пингбеки для данной записи, используем текущие настройки для всего блога.
Если запись успешно создана, отправляем клиенту сообщение, включающее её id, если нет – описание ошибки.
Обратите внимание на последнюю строчку этого скрипта. Для того, чтобы запрос был обработан, необходимо создать экземпляр нашего класса.
Шаг 4. Создаём XML-RPC клиент.
Здесь я покажу только код добавления новой записи. Для полноценной работы нужно будет создать соответствующий интерфейс.
<?php include 'IXR_Library.php'; $client = new IXR_Client('http://sitename.domen/xmlrpc-extended.php'); $client->debug = true; $post_data = array( 'post_title' => 'Заголовок', 'post_content' => 'Текст моего поста', 'post_status' => 'publish', 'post_parent' => 19, ); if (!$client->query('wp_extended.create_product', 'admin', 'password', $post_data)) { die('Something went wrong - '.$client->getErrorCode().' : '.$client->getErrorMessage()); } echo $client->getResponse();
Здесь мы создаём объект IXR_Client
и указываем адрес нашего XML-RPC сервера.
Затем заполняем массив с данными новой записи и отправляем запрос. При этом указываем имя метода (wp_extended.create_product
), логин, пароль и массив с данными.
Если есть желание поэкспериментировать, качайте архив с этим примером.
SourceПеред использованием не забудьте добавить тип данных example_product
.
Как видите через XML-RPC, можно выполнить практически любые действия с блогом. Вам будут доступны все встроенные функции WP и, если необходимо, можно выполнять запросы к БД напрямую.
Интересно почитать
Полезный блог о создании, развитии и поддержке своих сайтов. Автор публикует подробные статьи с примерами кода.