EUC-JPで運用しているWordPressをExportするとCDATAが文字化けする件の対応

 現在XServerの方で運用しているWordPressやんごとなき事情でEUC-JPで運用しているのですが、サーバ移転に伴いUTF-8が普通に使えるサーバに引っ越すことになりました。

 WordPressを移転する時にはデータをエクスポート→インポートするのが一番簡単なのですが、しかしWordPressをEUC-JPで運用している場合、エクスポート機能を使うとCDATAの中身が文字化けしてしまうという現象が発生します。割と既知のバグらしい。
 対応としてはphpmyadminから直接データをダンプするのが正解らしいのですが、「CDATAの部分だけ文字化けするなら、とりあえずその部分だけ何とかすれば良くね?」みたいなノリでエクスポートしているところを調べてみたところ、

wp-admin/include/export.php より

function wxr_cdata($str) {
	if ( seems_utf8($str) == false )
		$str = utf8_encode($str);

	// $str = ent2ncr(wp_specialchars($str));

	$str = "< ![CDATA[$str" . ( ( substr($str, -1) == ']' ) ? ' ' : '') . "]]>";

	return $str;
}

 が該当する処理を行っているところであることが判りました。
 この関数の先頭2行が明らかにUTF-8に変換しているっぽいので、この2行の先頭に「//」をつけてコメントアウトしたところ、CDATAで文字化けを起こすことはなくなりました。

 後はエクスポートしたXMLファイルの文字コードをUTF-8に変換+XMLファイルの先頭行の「encoding=”EUC-JP”」を「encoding=”UTF-8″」に書き換えて新しいWordPressにインポートすれば移行は完了する。はず(まだ未確認)。

 今回の教訓は、WordPressはUTF-8で運用するに限るということに尽きますね(結局)。

crossreviewから自分の書いたレビューを取得してブログに記事として貼り付けるスクリプト

 Dankogaiさんのこの記事に釣られてcrossreviewを始めてみました。

 crossreviewは基本的に「商品レビューに特化したTwitter」で、その最大の特徴は1つの商品に対して書ける「レビュー」の文字数が100文字に制限されていること。文字数が制限されている=壮大なレビューを書くことができないという訳で、これは要するに「Twitterでくっちゃべるノリで気軽にレビューを書いて投稿し、みんなで共有して楽しもうぜ!」という感覚を是とするサイトです。

 ブログでまとまった感想を書く時間も気力もないけど、Twitter上で買った本の感想を書くくらいの余裕ならあり、かつ感想書きたい本が溜まっている今の自分にとって、このcrossreviewはまさに渡りに船というか、レビューを書くためのモチベーションを与えてくれる理想のシステムでした。しばらくアクティブに使っていきたいと思ってます。

 それでcrossreviewはJavaScriptで書かれたブログパーツも用意されていて、自分が書いたレビューをブログに張ることもできるのですが、ただこのブログパーツを使った場合、RSSにレビュー文章が反映されないので、RSSリーダーからではブログに貼り付けたパーツに表示されたレビューを読めないという(個人的な)問題があります。
 この問題を解決するため、およびレビューの文章を自分のブログに貼り付けることでcrossreviewを自分のブログのフロントエンドとして利用できるようにするため、「crossreviewから自分の書いたレビューをRSSで取得し、ブログにエントリとして貼り付ける」スクリプトを作成しました。
 ちょっと前に作った「Wassrに投稿した写真をブログに貼り付けるスクリプト」とノリは一緒です。

crossreviewから自分の書いたレビューを取得してブログに記事として貼り付けるスクリプト (08/07/10版)
表示部分で使っているCSS
スクリプトを運用しているマンガ感想サイト

 このスクリプトによって投稿した記事の日時はレビューした日時と一緒になる様にしたかったので、ブログへの書き込みはmetaWeblog.newPost/editPostを使っています。
 そして書き込み先がWordPressの場合は(ここでも書きましたが)metaWeblogの処理に不具合があるっぽいので、もしこのスクリプトを使う場合は事前にxmlrpc.phpを修正して下さい。

 ちなみに自分のcrossreviewのアカウントはhttp://crossreview.jp/fukaz55です。
 お気にいりへの出し入れはご自由にどうぞー

WordPressでmetaWeblog.newPostに日付を渡して叩くと正常に動作しない件

 カラパー!(挨拶)

 現在、WordPressに対してmetaWeblog.newPost APIを叩いて記事を書き込むプログラムを作っているのですが、どうもWordPressのmetaWeblog.newPostおよびeditPostには、「dateCreatedを設定すると内部でエラーが発生する」および「categoiesに1つのカテゴリのみを指定した場合、カテゴリが設定されない」という不具合がある模様です。

dateCreatedを設定すると内部でエラーが発生する

WordPress › Support » posting via xmlrpc metaWeblog -> error in xmlrpc.php

 この記事に書かれているのですが、APIの dateCreated を解釈する部分にバグがあり、本来であれば日付をIXR_Date型に変換してからgetIso()するべきところを変換する前に呼び出してしまっているため、エラーが発生して投稿に失敗します。
 この記事は2.2時代のものらしいのですが、同様のエラーは2.5.1でも発生します。テストしてないんじゃないのかこれ。

 対処として、xmlrpc.phpの該当部分を以下の様に修正しました。

1306行以降(mw_newPost)、および1575行以降(mw_editPost)

// Do some timestamp voodoo
if ( !empty( $content_struct['date_created_gmt'] ) ) {
	$content_struct['date_created_gmt']  = new IXR_Date($content_struct['date_created_gmt']);
	$dateCreated = str_replace( 'Z', '', $content_struct['date_created_gmt']->getIso() ) . 'Z';
} elseif ( !empty( $content_struct['dateCreated']) ) {
	$content_struct['dateCreated']  = new IXR_Date($content_struct['dateCreated']);
	$dateCreated = $content_struct['dateCreated']->getIso();
}

 なお現在の実装では、IXR_Date型にタイムゾーンを含んだiso8601形式の文字列を渡した場合、タイムゾーンは処理されていないようです。なので、APIにdateCreatedを渡す場合は、JSTではなくGMTを渡した方が良いと思われます。
 ちなみにIXR_DateはUNIXタイムスタンプも値として受け取れるので、dateCreatedにtime()関数の戻り値を入れることが可能です。他のブログではどうなんだろう。

categoiesに1つのカテゴリのみを指定した場合、カテゴリが設定されない

 これは仕様上の動作だと思うのですが、XMLRPC::Liteを使ってcategoriesにカテゴリ名称文字列を1つだけ入れてAPIに渡すと、カテゴリが設定されません。これは、metaWeblog.newPostのcategoriesのデータ型が文字列の配列であることに起因するものと思われます。
 この現象を回避するため、xmlrpc.phpに以下の修正を行いました。

1324行以降(mw_newPost)、および1533行以降(mw_editPost)

if (is_array($catnames)) {
	foreach ($catnames as $cat) {
		$post_category[] = get_cat_ID($cat);
	}
} else {
	$post_category[] = get_cat_ID($catnames);
}

Wassrの自分の投稿から写真を抜き出してWordPressでフォトログっぽいことするスクリプト

 Yappoさんのこの発言に釣られてWassrを始めてみました。

 Wassrは基本的にTwitterコンパチなサービスなんですけど、Wassrには写真付きのメッセージをメールから投稿できるという特徴があるので、「Wassrに投稿した写真をAPI経由で拾ってWordPressのエントリにすることで、Wassrをこのブログのフォトログ的なフロントエンドとして使うことができるんじゃないの?」と思ってスクリプトを書いてみました。

 →Wassrの自分の投稿から写真を抜き出してWordPressでフォトログっぽいことするスクリプト(08/07/07版)
  ※7/7からXMLのフォーマットが変わったので対応
 →写真表示部分で使っているCSS

 昨日から上がってる「~の写真」というエントリが、これで作ったものです。

 WordPressにもメール経由で写真を投稿するプラグインは既にあるのですが、1日単位で写真をまとめて1エントリにしたかったので作った次第です。
 あと、Wassr API叩きたくて仕方がなかったのも動機。APIがあれば叩きたくなるのが普通ですよね(ですよね?)。

 ちなみに、自分のWassrのアカウントはhttp://wassr.jp/user/fukaz55です。
 購読・解除はご自由にどうぞー

WordPress2.5.1導入

 お久しぶりです(普通のエントリでは)。

 WordPressME2.2.3にしてからしばらくほったらかしていたこのブログですが、気が付いたら2.2系に対して「義務的なセキュリティ・アップグレード」が発生していてビビったので、2.5.1に更新しました。ついでにテーマも変えました。

 以上、生存報告でした。
 再びクリップブログに戻ります。