WordPress でデータ連係するときのスニペット

実は、今夏にSBクリエイティブさんから発売される予定の「WordPress Plugin 本(タイトル仮)」を宮さん西川さん三好さん達と書いてました。
宮さんはすでにリーク済みですね。
管理画面におけるエラーメッセージの表示 | firegoby

僕が担当したのは、17章目の「プラグインクックブック」がメインになります。
ここでは WordPress プラグイン作成時に使ってるコードをサンプルコードとして提示して、それを説明するって感じで書いてます。
編集の人にも「一部公開しても良いよー」って言われたので、一部を公開しますね。


こんな感じで書いてます。

他サイトとの連携に関するレシピ

RSS フィードを拡張して JSON を返せるようにする

<?php
add_action("init", "add_feed_json");
function add_feed_json() {
  add_feed("json", "do_feed_json");
}
function do_feed_json() {
  if ( have_posts() ) {
    $json = array();
    while ( have_posts() ) {
      the_post();
      $json&#91;&#93; = array(
        "id"        => $intval($post->ID) ,
        "title"     => get_the_title() ,
        "permalink" => get_permalink(),
        "content"   => get_the_content(),
        "excerpt"   => get_the_excerpt(),
        "date"      => get_the_date("Y-m-d H:i:s","","",false) ,
        "author"    => get_the_author() ,
      );
    }
    nocache_headers();
    header("Content-Type: application/json; charset=" . get_bloginfo("charset"));
    echo $json_encode($json);
  } else {
    status_header('404');
    wp_die("404 Not Found");
  }
}

他サイトにデータを提供したいときに JSON 形式で投稿データを渡せると便利です。
WordPress ではフィードとして RSS形式や ATOM形式でデータを渡すことができますが、add_feed() を利用してこの機能を拡張することで、様々な形式でフィードを提供することができます。

add_feed() ではフィード名と、そのフィードにリクエストが来たときに呼ばれるコールバック関数を設定します。
これにより http://example.com/feed/json/ といったリクエストに対して JSON 形式でデータを返すことができるようになります。
add_feed() では JSON だけでなく、どんな形式のフィードも定義することができます。
たとえば WordPress の提供する RSS 形式では無く、独自に拡張された形式でフィードを渡さねば行けない場合などにも使えるでしょう。

一点注意したいのは add_feed() でフィード形式を追加した場合は flush_rewrite_rules() を実行してリライトルールを書き換えなければいけない点です。
これは非常に負荷のかかる処理なので、通常はプラグインが有効化されたときに一度だけ実行するようにします。
その処理は、以下のコードのようになるでしょう。

<?php
// プラグイン有効化時に flush_rewrite_rules() を呼び出してリライトルールを書き換える
register_activation_hook(__FILE__, "flush_rewrite_rules");

// プラグイン無効化時に flush_rewrite_rules() を呼び出して feed/json を削除する
register_deactivation_hook(__FILE__, "add_feed_json_deactivate");

function add_feed_json_deactivate() {
  global $wp_rewrite;

  // リライトルールのフィード関係から json を削除する
  $feeds = array();
  foreach ( $wp_rewrite->feeds as $feed ) {
    if ( $feed !== "json" ) {
      $feeds[] = $feed;
    }
  }
  $wp_rewrite->feeds = $feeds;
  flush_rewrite_rules();
}

他サイトからデータを取得する

<?php
$response = wp_remote_get("http://example.com/");
if( !is_wp_error( $response ) && $response&#91;"response"&#93;&#91;"code"&#93; === 200 ) {
  $response_body = $response&#91;"body"&#93;;
} else {
  // Handle error here.
}&#91;/php&#93;

他サイトからデータを取得するには curl や file_get_contents() などの PHP の関数を直接使わずに wp_remote_get() を使用すると便利です。
例えば、はてなブックマーク件数取得 API ( http://developer.hatena.ne.jp/ja/documents/bookmark/apis/getcount )を使ってページのはてなブックマーク数を取得したい場合は、以下のようなコードになるでしょう。

&#91;php&#93;<?php
$response = wp_remote_get("http://api.b.st-hatena.com/entry.count?url=".rawurlencode(get_permalink()));
if( !is_wp_error( $response ) && $response&#91;"response"&#93;&#91;"code"&#93; === 200 ) {
  $hatena_count = intval($response&#91;"body"&#93;);
} else {
  $hatena_count = 0;
}&#91;/php&#93;

ちなみにこのとき $response には、以下のような連想配列がセットされています。
&#91;text&#93;array(5) {
  &#91;"headers"&#93;=>
  array(10) {
    ["server"]=>
    string(5) "nginx"
    ["date"]=>
    string(29) "Sat, 26 Apr 2014 09:07:07 GMT"
    ["content-type"]=>
    string(10) "text/plain"
    ["content-length"]=>
    string(1) "2"
    ["connection"]=>
    string(5) "close"
    ["cache-control"]=>
    string(12) "max-age=1800"
    ["expires"]=>
    string(29) "Sat, 26 Apr 2014 09:37:07 GMT"
    ["x-varnish"]=>
    string(10) "1132724514"
    ["age"]=>
    string(1) "0"
    ["via"]=>
    string(11) "1.1 varnish"
  }
  ["body"]=>
  string(2) "82"
  ["response"]=>
  array(2) {
    ["code"]=>
    int(200)
    ["message"]=>
    string(2) "OK"
  }
  ["cookies"]=>
  array(0) {
  }
}[/text]

headers には相手先のサーバから送信された http ヘッダ、body にはレスポンスボディー、response には HTTP レスポンスコード (200 OK や、404 Not Found など)、cookies には cookie が格納されています。
wp_remote_get() ではエラーが発生した場合は WP_Error オブジェクトを返します、必ず is_wp_error() で確認してから使いましょう。


<h3>BASIC 認証がかかっているサイトからデータを取得する</h3>

[php]<?php
$user = "username";
$password = "password";
$args = array(
  "headers" => array(
    "Authorization" => "Basic ".base64_encode("$user:$password"),
  )
);
$response = wp_remote_get("http://example.com/", $args);

wp_remote_get() では、第二引数を与えることで任意の http ヘッダを送信することができます。
例えば BASIC 認証がかかっているサイトにユーザー名・パスワードを送信したい場合は Authorization: Basic ヘッダを渡せば良いです。
このときユーザー名、パスワードは : (コロン)で区切って base64 エンコードしなければいけません。

他サイトの RSS フィードからデータを取得する

<?php
include_once(ABSPATH . WPINC . "/feed.php");

$feed = fetch_feed("http://example.com/feed/rss/");
if ( !is_wp_error($feed) ) {
  $max = $feed->get_item_quantity(5);
  $items = array();
  for ($x = 0; $x < $max; $x++){
    $item = $feed->get_item($x);
    $items[] = array(
      "title"     => $item->get_title(),
      "permalink" => $item->get_permalink(),
      "datetime"  => $item->get_date("Y-m-d H:i:s e"),
      "excerpt"   => $item->get_description(),
    );
  }
} else {
  // Handle error here.
}

他サイトのフィードを取得してきて処理したい場合は fetch_feed() を利用すると便利です。
fetch_feed() では、正常にフィードが取得できた場合 SimplePie のオブジェクトを返します。
フィード取得に失敗した場合は WP_Error オブジェクトを返すので、必ず is_wp_error() で WP_Error オブジェクトが返ってきていないか確認してください。

サンプルコードでは、取得できたデータから最新5件のデータを $items という配列に格納しています。
まず get_item_quantity() メソッドで件数を取得し、その後 for ループを回しながら get_item() メソッドでデータを取得しています。

他サイトに XML-RPC で接続する

<?php
include_once( ABSPATH . WPINC . "/class-IXR.php" );
include_once( ABSPATH . WPINC . "/class-wp-http-ixr-client.php");

$blog_id = 1;
$user = "username";
$password = "password";
$post_id = 1;

$ixr_client = new WP_HTTP_IXR_Client("http://example.com/xmlrpc.php");
$ixr_client->query("wp.getPost", $blog_id, $user, $password, $post_id);
$response = $ixr_client->getResponse();
var_dump($response);
var_dump($ixr_client->isError());

他サイトとのデータ連係に XML-RPC を使用したい場合は WP_HTTP_IXR_Client クラスを用いるのが簡単です。
サンプルコードでは http://example.com という WordPress サイトの XML-RPC API をキックしています。

他の WordPress サイトと接続して XML-RPC API を使用したい場合は codex のXML-RPC WordPress API を参考にしてください。
また、Backlog などの XML-RPC API を用意している Web サービスとの連携にも使えるでしょう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください