WordPressをMT(Movable Type)形式でエクスポートしてブログをお引越し。
wordpressで書いていたブログを、はてなに引っ越すことにしました。
はてなで既存ブログデータをインポートするには、Movable Type形式(MT形式)でデータをエクスポートする必要があります。
今使用しているwordpressのバージョンは2.6で、MT形式でデータをエクスポートするために、WordPressExportというプラグインを使用しました。
プラグインのインストール
インストール方法などはこちらをご覧ください
プラグインのインストール後、管理画面の「設定」タブから「Export」をクリックすると、MT形式でデータ表示されるはずでしたが、何も出てきませんでした。
プラグインの修正
調べてみると、MT.php内21行目付近の、SQLを発行している部分で、エラーがでていることがわかりました。
MT.phpの21行目付近
$query = "SELECT $wpdb->posts.post_date, $wpdb->posts.post_content, $wpdb->posts.post_title, $wpdb->users.user_nickname, $wpdb->posts.post_status, $wpdb->comments.comment_author, $wpdb->comments.comment_content, $wpdb->comments.comment_author_email, $wpdb->comments.comment_author_url, $wpdb->comments.comment_date, $wpdb->post2cat.category_id, $wpdb->categories.cat_name FROM $wpdb->comments RIGHT OUTER JOIN $wpdb->posts ON ( $wpdb->comments.comment_post_ID = $wpdb->posts.ID ) LEFT OUTER JOIN $wpdb->users ON ( $wpdb->posts.post_author = $wpdb->users.ID ) LEFT OUTER JOIN $wpdb->post2cat ON ( $wpdb->posts.ID = $wpdb->post2cat.post_id ) LEFT OUTER JOIN $wpdb->categories ON ($wpdb->post2cat.category_id = $wpdb->categories.cat_ID) ";
また、エラーがでている部分はeval()関数で実行されていたので、特にエラーなど出現せず、単に出力がない状態となっていたのです。
SQLをダンプすると以下のようになっていました。
SELECT wp_posts.post_date, wp_posts.post_content, wp_posts.post_title, wp_users.user_nicename, wp_posts.post_status, wp_comments.comment_author, wp_comments.comment_content, wp_comments.comment_author_email, wp_comments.comment_author_url, wp_comments.comment_date, wp_post2cat.category_id, wp_categories.cat_name FROM wp_comments RIGHT OUTER JOIN wp_posts ON ( wp_comments.comment_post_ID = wp_posts.ID ) LEFT OUTER JOIN wp_users ON ( wp_posts.post_author = wp_users.ID ) LEFT OUTER JOIN wp_post2cat ON ( wp_posts.ID = wp_post2cat.post_id ) LEFT OUTER JOIN wp_categories ON ( wp_post2cat.category_id = wp_categories.cat_ID )
このSQLでは、wp_categoriesと、wp_post2catというテーブルが見つからないためにエラーが発生しています。
いま使っているwordpress2.6では、これらのテーブルはありませんでした。
ただ、古いバージョンにはあったようなので、どこかのアップデートの段階でなくなったのだと思います。
プラグインが古くて、バージョンアップに対応していなかったのでしょうかね。
ということで、wp_categoriesとwp_post2catテーブル関連部分(SELECTとJOINのところ)、およびデータの書き出し部分で関係しているところを削除しました。
結果、SQLの部分は以下のようになりました。
$query = "SELECT $wpdb->posts.post_date, $wpdb->posts.post_content, $wpdb->posts.post_title, $wpdb->users.user_nicename, $wpdb->posts.post_status, $wpdb->comments.comment_author, $wpdb->comments.comment_content, $wpdb->comments.comment_author_email, $wpdb->comments.comment_author_url, $wpdb->comments.comment_date FROM $wpdb->comments RIGHT OUTER JOIN $wpdb->posts ON ( $wpdb->comments.comment_post_ID = $wpdb->posts.ID ) LEFT OUTER JOIN $wpdb->users ON ( $wpdb->posts.post_author = $wpdb->users.ID ) ";
さて、修正して再度エクスポートをしてみたのですが、まだ何もでてきませんでした。
次に怪しい部分は、23行目あたりからの、実際にクエリを投げてデータを取得する部分です。
MT.phpの23行目付近
$result = $wpdb->query($query); if ($result){ for ($i = 0; $i < $result; $i++) { $row = $wpdb->get_row(null,OBJECT,$i); if ($prev_entry == $row->post_date) { ...
$wpdp->query()でデータを取得して、$resultに取得した行数が帰ります。
それをfor文でまわして$wpdb->get_row()で一行づつ処理しようとしたのだと思います。
しかし、$wpdb->get_row()も途中で実装が変わったのか、第一引数にnullが指定されてしまうと、nullしかかえって来ません。
wp-includes/wp-db.php 733行目付近
function get_row($query = null, $output = OBJECT, $y = 0) { $this->func_call = "\$db->get_row(\"$query\",$output,$y)"; if ( $query ) $this->query($query); else return null; if ( !isset($this->last_result[$y]) ) return null; if ( $output == OBJECT ) { return $this->last_result[$y] ? $this->last_result[$y] : null; } elseif ( $output == ARRAY_A ) { ...
nullのかわりにSQL文を指定するのが正しい使用方法です。
ただ、$wpdb->get_row()は本当に一行だけ取得したい場合に使用するべきです。
なぜなら、$wpdb->get_row()は内部で$wpdb->query()を呼び出しているので、毎回クエリが発生してしまうので効率が悪いためです。
その代わりに、今回のように一度にデータを取得して、結果をfor文でまわすような場合には、$wpdb->get_result()を使用するのが正しいようです。
上記を踏まえ、以下のように処理を変更しました。
//$result = $wpdb->query($query); $result = $wpdb->get_results($query, OBJECT); if ($result){ //for ($i = 0; $i < $result; $i++) { foreach($result as $i=>$row) { //$row = $wpdb->get_row(null,OBJECT,$i); if ($prev_entry == $row->post_date) { ...
これのほかに、こちらにでも書いてありますが、エントリーの区切りが
-------- --------
のになってしまう件についても、
----- --------
になるように修正しました。
MT.php 73行目付近
//$output .= "--------\n"; $output .= "-----\n";
これでようやくMT形式でエクスポートできました。
ただし、ドラフト版もひとつのエントリーとして出力されてしまい、はてなではこれらもひとつの記事として公開されていて、具合が悪いです。
ということで、公開記事だけエクスポートされるように、wp_posts.post_status = 'publish'という条件をSQL文に付け加えました。
$query = "SELECT $wpdb->posts.post_date, $wpdb->posts.post_content, $wpdb->posts.post_title, $wpdb->users.user_nicename, $wpdb->posts.post_status, $wpdb->comments.comment_author, $wpdb->comments.comment_content, $wpdb->comments.comment_author_email, $wpdb->comments.comment_author_url, $wpdb->comments.comment_date FROM $wpdb->comments RIGHT OUTER JOIN $wpdb->posts ON ( $wpdb->comments.comment_post_ID = $wpdb->posts.ID ) LEFT OUTER JOIN $wpdb->users ON ( $wpdb->posts.post_author = $wpdb->users.ID ) WHERE $wpdb->posts.post_status ";
これで、公開されたバージョンのみインポートすることができました(手作業で修正しなければならないことがちょっと残っていますが...)。
修正したWordPressExportプラグインのMT.phpはこちらから。
ちなみに、以前のブログですが、普通の日記を更新していこうと思います。
技術的な記事はここで、それ以外は以前のところで、という棲み分けになります。