WordPress 自動投稿ツール作成の関連記事です。
肝心の「自動」部分を未だに書けずにいるのですが、今回は XML-RPC で wp_options を操作するメモを残したいと思います。
wp_options にはブログの設定情報や、プラグインのデータ、その他色々入っている WordPress のテーブルで、ちょっとしたデータを保存するのにも便利で何かと重宝します。
設定値何かはリモートから一元管理できたらさぞ便利だろうなと思ったので、XML-RPC のカスタムメソッドを書いてみました。
目次
スポンサーリンク
WordPress XML-RPC サーバの拡張
実の所、wp_options 関連メソッドとして「wp.getOptions」と「wp.setOptions」が用意されています。ですが、WordPress の基本設定以外は操作できないみたいだったので、オリジナルのメソッドを作成してみます。
メソッドの拡張は以下のコードを functions.php に追加します。
function add_wp_methods( $methods ) {
$methods['my.getWpOptions'] = 'my_get_options';
$methods['my.setWpOptions'] = 'my_set_options';
$methods['my.delWpOptions'] = 'my_del_options';
return $methods;
}
add_filter( 'xmlrpc_methods', 'add_wp_methods' );
function my_get_options( $args ) {
if ( ! isset( $args[3]['opt_name'] ) ) { return FALSE; }
return get_option( $args[3]['opt_name'] );
}
function my_del_options( $args ) {
if ( ! isset( $args[3]['opt_name'] ) ) { return FALSE; }
return delete_option( $args[3]['opt_name'] );
}
function my_set_options( $args ) {
if ( ! isset( $args[3]['opt_name'], $args[3]['opt_value'] ) ) { return FALSE; }
update_option( $args[3]['opt_name'], $args[3]['opt_value'] );
if ( get_option( $args[3]['opt_name'] ) === $args[3]['opt_value'] ) {
return TRUE;
} else {
return FALSE;
}
}
こんな感じに XML-RPC クライアントからオプションを渡して get_option 等で操作するという単純な処理です。
「取得、設定、削除」と 3 つのメソッドを追加してサーバ側の拡張はお終いです。今回は functions.php に書いていますが、できればプラグイン化して有効化させといたほうが理想だと思います。
ちなみにですが、デフォルトのメソッドでは以下のパラメータを操作できるようです。
software_name software_version blog_url home_url login_url admin_url image_default_link_type image_default_size image_default_align template stylesheet post_thumbnail time_zone blog_title blog_tagline date_format time_format users_can_register thumbnail_size_h thumbnail_crop medium_size_w medium_size_h large_size_w large_size_h default_comment_status default_ping_status
XML-RPC クライアントの拡張
次に、クライアント側を拡張します。以下の記事で書いたクラスを元にコードを書き足します。
関連記事
書き足すのは以下のクライアント用メソッドです。
/*
* Usage: $get = $wp->wp_ope_options( array( 'opt_ope' => 'get', 'opt_name' => 'name' );
* $del = $wp->wp_ope_options( array( 'opt_ope' => 'del', 'opt_name' => 'name' );
* $set = $wp->wp_ope_options( array( 'opt_ope' => 'del', 'opt_name' => 'name', 'opt_value' => 'value' );
*
* wp_options の「取得,削除,設定」操作
*/
public function wp_ope_options( $p = FALSE ) {
if ( ! $p || ! isset( $p['opt_name'], $p['opt_ope'] ) ) { return FALSE; }
if ( $p['opt_ope'] === 'set' && ! isset( $p['opt_value'] ) ) { return FALSE; }
// value タイプのデフォルトは 'string'
if ( $p['opt_ope'] === 'set' && ! isset( $p['opt_type'] ) ) { $p['opt_type'] = 'string'; }
// 操作するメソッド名を設定
$xmlrpc_method = 'my.' . $p['opt_ope'] . 'WpOptions';
// 送信する XML データの作成
$options = array(
'opt_name' => new XML_RPC_Value( $p['opt_name'], 'string' )
);
// set の場合に value と type を追加
if ( $p['opt_ope'] === 'set' ) {
$options['opt_value'] = new XML_RPC_Value( $p['opt_value'], $p['opt_type'] );
}
$options = new XML_RPC_Value( $options, 'struct' );
$xmldata = new XML_RPC_Message(
$xmlrpc_method,
array( $this->wp_id, $this->wp_user, $this->wp_pass, $options )
);
$result = $this->rpc_send( $xmldata );
$result = XML_RPC_decode( $result->value() );
return $result;
}
こんな感じのコードで、全ての操作をオプションで切り替えるようにまとめてみました。
これを使って早速テストしていきます。実際に DB を触るので念のためバックアップも忘れずに。
XML-RPC で wp_options を操作するテスト
テスト用のクライアントは以下のように書いてみました。ファイル名は仮に xml-conn.php とします。
<?php
require_once("class-xmlrpc-wp-client.php");
$param = array(
'host' => 'example.jp',
'port' => '80',
'path' => '/xmlrpc.php',
'user' => 'user',
'pass' => 'password',
);
$options = array(
'opt_ope' => 'set', /* <get|del|set> */
'opt_name' => 'test_option',
'opt_value' => 'test_value',
'opt_type' => 'string' /* <int|string|boolean> */
);
$wp = new WordPressRpc( $param );
$result = $wp->wp_ope_options( $options );
var_dump( $result );
?>
$options[‘opt_ope’] に操作内容、$options[‘opt_name’] に操作対象のオプション名を指定します。
$options[‘opt_ope’] が set の場合は、$options[‘opt_value’] と$options[‘opt_type’] も指定する必要があります。
存在しないオプションを GET
# php xml-conn.php int(0)
オプション名が存在しない場合には 0 が返ります。
オプション名 test_option を SET
# php xml-conn.php int(1)
オプションの設定に成功すると 1、失敗すると 0 が返ります。mysql を SELECT してみるとちゃんと登録されているのを確認できます。
mysql> SELECT * FROM wp_options WHERE option_name = 'test_option'; +-----------+-------------+--------------+----------+ | option_id | option_name | option_value | autoload | +-----------+-------------+--------------+----------+ | 5250 | test_option | test_value | yes | +-----------+-------------+--------------+----------+
存在するオプションを GET
# php xml-conn.php string(10) "test_value"
上記で登録したので、もう一度情報を取得してみます。成功すると設定値が返ってきます。
オプションを DEL
# php xml-conn.php int(1)
オプションの削除に成功すると 1、失敗すると 0 が返ってきます。
簡単ですがこんな感じにできました。
XML-RPC のセキュリティについて
最後に、おまけ程度ですが WordPress の XML-RPC に関するセキュリティについて。
拡張次第でリモートから何でもできて便利な XML-RPC ですが、セキュリティ機構がパスワード認証だけというのはちょっと危なっかしい感じがしています。
最近では、wp-login.php への総当り攻撃も増えているみたいなので .htacess 等でログインできる対象を絞っている人も多いかと思いますが XML-RPC への対処はあまり見ないです。
wp-login.php の対処だけじゃ不完全なんですよね。これとは別に動くので。
という事で以下のように XML-RPC サーバ側に「接続ホスト制限」を追加してみました。
function add_wp_methods( $methods ) {
if ( $_SERVER['REMOTE_ADDR'] !== '192.168.0.1' ) {
add_filter( 'xmlrpc_enabled', '__return_false' );
}
$methods['my.getWpOptions'] = 'my_get_options';
$methods['my.setWpOptions'] = 'my_set_options';
$methods['my.delWpOptions'] = 'my_del_options';
return $methods;
}
add_filter( 'xmlrpc_methods', 'add_wp_methods' );
この状態で許可されていないホストからアクセスすると以下のようになります。
# php xml-conn.php このサイト上では XML-RPC サービスが無効になっています。
アチコチから XML-RPC に接続して操作するという事がなければこれで大体 OK です。ただ、ピンバックも強制的に受け付けなくなるのでそこは注意です。(もしかしたら他にも影響が)
本当は、ピンバックだけは許可したいんだけど当面はこんな感じで。
また何かわかったら別記事で書きたいと思います。