XMLRPCでWordPressに投稿する

XMLRPCを使用してWordpressに投稿する場合、
基本は、http://blog.syuhari.jp/archives/1373こちらのソースをそのまま使用すればOK。

コンテンツ内に画像を入れたいとかは、イメージアップロード後のURLをdescriptionに結合して投稿すれば、表示される。
本文の中に画像があるとかのHTMLエディタみたいな仕様だと、Replaceするしかないと思う。

タグは「mt_keywords」を使用して

$mt_keywords = array(
    new XML_RPC_Value("タグ1", "string"),
    new XML_RPC_Value("タグ2", "string")
);
$content = new XML_RPC_Value(
    array(
        'title' => new XML_RPC_Value($title, 'string'),
        'categories' => new XML_RPC_Value($categories, 'array'),
        'description' => new XML_RPC_Value($description, 'string'),
        'mt_keywords' => new XML_RPC_Value($mt_keywords, 'string'),
        'dateCreated' => new XML_RPC_Value(time(), 'dateTime.iso8601')
    ),
    'struct'
);

スラッグは「wp_slug」を使用する。

カスタムフィールドは

$custom_fields = array();
$custom_fields[] = new XML_RPC_Value(
                        array(
                            'key'=> new XML_RPC_Value('フィールド名', 'string'),
                            'value'=> new XML_RPC_Value('フィールド値', 'string')
                        ),
                        'struct'
);
$content = new XML_RPC_Value(
    array(
        'title' => new XML_RPC_Value($title, 'string'),
        'categories' => new XML_RPC_Value($categories, 'array'),
        'description' => new XML_RPC_Value($description, 'string'),
        'custom_fields' => new XML_RPC_Value($custom_fields, 'struct'),
        'dateCreated' => new XML_RPC_Value(time(), 'dateTime.iso8601')
    ),
    'struct'
);

で、問題はアイキャッチの投稿。
アイキャッチは、Wordpress上ではカスタムフィールドと同じようにpost_metaに分類。
キーは「_thumbnail_id」、値は「アタッチメントのID(画像ID)」になる。
画像をアップロードすると、返り値は「ファイル名」「画像URL」「画像タイプ」になる。
画像IDないじゃん!!となるんだけれど、
http://blog.sbw.be/2011/07/19/calling-xmlrpc-of-wordpress-with-zend-framework-zend_xmlrpc_client-and-adding-the-default-thumbnail-to-a-post/
こちらを参考に変更。
「wp-include/class-wp-xml-rpc.php」「wp-includes/meta.php」を変更するので、Wordpressをアップデートすると元に戻ってしまうと思います。
なので、プラグインにしてしまうか、function.phpに書く方が無難ではないかと思うので、function.phpに追加。

add_filter('is_protected_meta', 'my_is_protected_meta_filter', 10, 2);
function my_is_protected_meta_filter( $meta_key, $meta_type = null ) {
    if ($meta_key == '_thumbnail_id') {
        $protected=false;
    } else {
        $protected = (  '_' == $meta_key[0] );
    }
}

include_once(ABSPATH . WPINC . '/class-IXR.php');
include_once(ABSPATH . WPINC . '/class-wp-xmlrpc-server.php');
// WordPress の XMLRPC を拡張する
function wpex_xmlrpc_server($class_name) {
    return 'wpex_xmlrpc_server';
}
add_filter('wp_xmlrpc_server_class', 'wpex_xmlrpc_server');

class wpex_xmlrpc_server extends wp_xmlrpc_server {
    function __construct() {
        parent::__construct();
        $this->methods['wpex.newMediaObject'] = 'this:wpex_newMediaObject';
    }

    function wpex_newMediaObject($args) {
        global $wpdb;

        $blog_ID     = (int) $args[0];
        $username  = $wpdb->escape($args[1]);
        $password   = $wpdb->escape($args[2]);
        $data        = $args[3];

        $name = sanitize_file_name( $data['name'] );
        $type = $data['type'];
        $bits = $data['bits'];

        logIO('O', '(MW) Received '.strlen($bits).' bytes');

        if ( !$user = $this->login($username, $password) )
            return $this->error;

        do_action('xmlrpc_call', 'metaWeblog.newMediaObject');

        if ( !current_user_can('upload_files') ) {
            logIO('O', '(MW) User does not have upload_files capability');
            $this->error = new IXR_Error(401, __('You are not allowed to upload files to this site.'));
            return $this->error;
        }

        if ( $upload_err = apply_filters( 'pre_upload_error', false ) )
            return new IXR_Error(500, $upload_err);

        if ( !empty($data['overwrite']) && ($data['overwrite'] == true) ) {
            // Get postmeta info on the object.
            $old_file = $wpdb->get_row("
                SELECT ID
                FROM {$wpdb->posts}
                WHERE post_title = '{$name}'
                    AND post_type = 'attachment'
            ");

            // Delete previous file.
            wp_delete_attachment($old_file->ID);

            // Make sure the new name is different by pre-pending the
            // previous post id.
            $filename = preg_replace('/^wpid\d+-/', '', $name);
            $name = "wpid{$old_file->ID}-{$filename}";
        }

        $upload = wp_upload_bits($name, NULL, $bits);
        if ( ! empty($upload['error']) ) {
            $errorString = sprintf(__('Could not write file %1$s (%2$s)'), $name, $upload['error']);
            logIO('O', '(MW) ' . $errorString);
            return new IXR_Error(500, $errorString);
        }
        // Construct the attachment array
        // attach to post_id 0
        $post_id = 0;
        $attachment = array(
            'post_title' => $name,
            'post_content' => '',
            'post_type' => 'attachment',
            'post_parent' => $post_id,
            'post_mime_type' => $type,
            'guid' => $upload[ 'url' ]
        );

        // Save the data
        $id = wp_insert_attachment( $attachment, $upload[ 'file' ], $post_id );
        wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );

        return apply_filters( 'wp_handle_upload', array( 'file' => $name, 'url' => $upload[ 'url' ], 'type' => $type, 'id' => $id ), 'upload' );
    }
}

「WordPress の XMLRPC を拡張する」部分は
http://wokamoto.wordpress.com/2011/07/22/extended-xmlrpc/
を参考。

$message = new XML_RPC_Message(
                'wpex.newMediaObject',
                array($blog_id, $username, $passwd, $file)
);
$result = $c->send($message);
if( !$result ){
    exit('Could not connect to the server. ImageUP');
} else if( $result->faultCode() ){
    exit($result->faultString());
}
$resp = XML_RPC_decode($result->value());
$image_id = $resp['id'];

「$image_id」に画像IDが入るので、カスタムフィールドと同じく、

$custom_fields[] = new XML_RPC_Value(
                        array(
                            'key'=> new XML_RPC_Value('_thumbnail_id','string'),
                            'value'=> new XML_RPC_Value($image_id,'string')
                        ),
                        'struct'
);

で投稿。

コメントを残す

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

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)