work.log

元エンジニアの備忘録的ブログ

PerlのRPC::XML::ClientでWordPressへ記事を投稿するメモ

投稿:2014-04-24 18:40  更新:

Perl モジュール RPC::XML::Client のメモ。

以前に、このモジュールを使って WordPress への接続と投稿記事の取得について書きましたが、今回はこれで WordPress へ記事を投稿してみたいと思います。

認証の処理だったり、サーバへリクエストを送信する処理だったりというのは前回書いたので、今回は投稿に関する部分のみをメモ。

そんな訳でまずは、コードから。

use RPC::XML::Client;
use Time::Local;

## datetime_iso8601 メソッドがこのモジュールに依存
use DateTime::Format::ISO8601;


    ## 投稿に設定するカテゴリとタグの ID を指定
    my @cat = ('1', '2');
    my @tag = ('11', '12', '13');

    ## 投稿するデータ
    my $post = {
           title          => '投稿タイトル',
           content        => '投稿内容',
           thumbnail      => 1234,
           date           => time(),
           category       => \@cat,
           post_tag       => \@tag,
           post_status    => 'open',
           ping_status    => 'open',
           comment_status => 'open'
       };

    ## 接続認証情報
    my $xml = .....

    ## XML-RPC クライアントのオブジェクトを取得する処理
    my $xmlrpc = .....

    ## 投稿
    my $res = &wp_new_post($post);

    print "$res\n";

sub wp_new_post {

    my $data = shift;
    my $method = 'wp.newPost';
    my $req = '';
    my $res = '';
    my $terms = {};

    ## unixtime を JST -9 して "yyyymmddThhmmss" の形式に変換
    $data->{date} = &convert_utc($data->{date});

    ## カテゴリとタグの処理
    foreach my $key (keys $data) {

        if ($key =~ /^(category|post_tag)$/) {

            my @array = ();

            foreach (@{$data->{$key}}) {
                push(@array, RPC::XML::int->new($_));
            }

            if (scalar(@array)) {
                $terms->{$key} = RPC::XML::array->new(@array);
            }

        }
    }

    ## リクエストの作成
    $req = RPC::XML::request->new(
        $method,
        $xml->{blog},
        $xml->{user},
        $xml->{pass},
        RPC::XML::struct->new({
            'post_title'     => RPC::XML::string->new($data->{title}),
            'post_content'   => RPC::XML::string->new($data->{content}),
            'post_date_gmt'  => RPC::XML::datetime_iso8601->new($data->{date}),
            'post_thumbnail' => RPC::XML::int->new($data->{thumbnail}),
            'post_status'    => RPC::XML::string->new($data->{post_status}),
            'ping_status'    => RPC::XML::string->new($data->{ping_status}),
            'comment_status' => RPC::XML::string->new($data->{comment_status}),
            'terms'          => RPC::XML::struct->new($terms)
        })
    );

    ## リクエストを送信するサブルーチンに投げる (関連記事に記載)
    $res = &send_xmldata($xmlrpc, $req);

    return($res);

}

sub convert_utc {

    my $utime = shift;
    my $utc = '';

    $utime -= 3600 * 9;
    my ($sec, $min, $hour, $mday, $mon, $year) = localtime($utime);

    $year = $year + 1900;
    $mon++;

    $utc = sprintf("%04d%02d%02dT%02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);

    return($utc);
}

$req をダンプするとこんなデータになっている。

bless( {
	'name' => 'wp.newPost',
	'args' => [
		bless( do{\(my $o = '1')}, 'RPC::XML::string' ),
		bless( do{\(my $o = 'user')}, 'RPC::XML::string' ),
		bless( do{\(my $o = 'pass')}, 'RPC::XML::string' ),
		bless( {
			'comment_status' => bless( do{\(my $o = 'closed')}, 'RPC::XML::string' ),
			'post_title' => bless( do{\(my $o = 'title')}, 'RPC::XML::string' ),
			'terms' => bless( {
				'post_tag' => bless( [
					bless( do{\(my $o = '122')}, 'RPC::XML::int' ),
					bless( do{\(my $o = '123')}, 'RPC::XML::int' ),
					bless( do{\(my $o = '124')}, 'RPC::XML::int' )
				], 'RPC::XML::array' ),
				'category' => bless( [
					bless( do{\(my $o = '125')}, 'RPC::XML::int' )
				], 'RPC::XML::array' )
			}, 'RPC::XML::struct' ),
			'ping_status' => bless( do{\(my $o = 'closed')}, 'RPC::XML::string' ),
			'post_status' => bless( do{\(my $o = 'publish')}, 'RPC::XML::string' ),
			'post_date_gmt' => bless( do{\(my $o = '20140424T08:45:00')}, 'RPC::XML::datetime_iso8601' ),
			'post_thumbnail' => bless( do{\(my $o = 1911)}, 'RPC::XML::int' ),
			'post_content' => bless( do{\(my $o = 'body')}, 'RPC::XML::string' )
		}, 'RPC::XML::struct' )
	]
}, 'RPC::XML::request' );

これを WordPres の xmlrpc.php に投げて、投稿 ID が返ってくれば処理は成功です。

以前に、PHP で書いた時もそうでしたがカテゴリとタグの処理にまたハマったのと、datetime_iso8601 の部分でややハマったのでメモです。

簡単ですが RPC::XML::Client のメモ書きはこれで以上です。