WordPress でブログ移行してきた記事内の画像をうまくインポートする
標準のインポート/エクスポートが貧弱
WordPress には標準で記事、固定ページ等のインポート/エクスポート機能が存在していますが、XML 形式による出力のため、そのままでは上手く移行出来ない事が多いです。
具体的には、
- アイキャッチが引き継がれない
- メディア内の画像が引き継がれない
- 記事内の画像が引き継がれない
- パーマリンクを別で管理しているので、調整する必要がある
等、の問題が起こりやすいです。
賢明な方々であれば、All In One WP Migration の拡張を購入し、移行作業を行っていると思います。
ただ、事情により管理画面を渡してもらえない事も多いと思います。
記事内画像だけでもきちんと引き継ごう
アイキャッチについては、例えば記事内の最初の画像があれば、Auto Featured Image のようなプラグインを利用して再設定が可能です。
記事内画像は、元サイトと同一ドメインでの移行であっても、画像データの取得が必要です。
画像データの取得
影響が無いように、WordPress 設置フォルダ以下に、「_dev」フォルダのような名前で設置し、以下のようなスクリプトで動かします。
$wp_path = realpath("../");
require_once ($wp_path . '/wp-load.php');
$args = [
'posts_per_page' => -1,
];
$the_query = new WP_Query( $args );
if ($the_query->have_posts()) : while ($the_query->have_posts()) : $the_query->the_post();
$post_id = $the_query->post->ID;
$post_content = get_post_field('post_content', $post_id);
$first_img = '';
ob_start();
ob_end_clean();
$output = preg_match_all('/<img.*?src\s*=\s*[\"|\'](.*?)[\"|\'].*?>/i', $post_content, $matches);
$i = 0;
foreach($matches[1] as $match_s){
$ext_point = strrpos($match_s, ".");
//gifは除外
if($ext_point !== false){
$str_point = $ext_point + 1;
$ext_str = substr($match_s, $str_point);
if($ext_str === 'gif') continue;
}
$ext_str = parse_url($ext_str, PHP_URL_PATH);
save_filesrc(regex_url($match_s), $post->ID.'-'.$i.'.'.$ext_str);
++$i;
}
endwhile;
else:
endif;
wp_reset_postdata();
最初に WordPress 設置フォルダに対して wp-load.php
をインクルードさせ、関数を使えるようにします。
通常投稿を全件取得して、記事内の「img src」を探して、URLを取得します。
Ameba とかからの移行だと、顔文字等が gif になっていたりして、要件的に削除する必要があったりするので、除外する場合を想定しています。
上記に使う独自関数は以下です。
/**
* ファイルを保存
*
*/
function save_filesrc(string $url, string $post_name)
{
$thumb_raw = curl_get_contents($url);
$file_name_tmp = explode( '/', $url );
$file_name_tmp = array_reverse( $file_name_tmp );
$file_name = $file_name_tmp[0];
$dir_list = scandir('./');
if(!in_array('src',$dir_list,true)){
mkdir('./src', 0705);
}
$save_dir_path = realpath('').'/src/';
// // 画像保存
if ( $thumb_raw )
{
$res = file_put_contents( $save_dir_path . $post_name, $thumb_raw );
}
}
function curl_get_contents($url,$timeout = 60){
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_HEADER,false);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_TIMEOUT,$timeout);
curl_setopt($ch,CURLOPT_FAILONERROR,true);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
作業フォルダ内に「src」フォルダを作成し、そこに画像ファイルを吐き出します。
画像ファイルは日本語ファイルとかだと文字化けして面倒なので、記事ID-記事内順番.ext
という名前付けをして、取得しています。
上記内容で一回実行して、きちんとsrcフォルダに取得出来たかを確認します。
本文内URLを書き換える
次に取得した画像URLに本文を書き換える必要があります。
先ほど画像ファイル名も変更したため、同名に書き換える必要があります。
また、作業フォルダとは別に wp-content/uploads/old_data/
等の名前でフォルダを作成し、そこに設置する想定で変更します。
$args = [
'posts_per_page' => -1,
];
$the_query = new WP_Query( $args );
if ($the_query->have_posts()) : while ($the_query->have_posts()) : $the_query->the_post();
$post_id = $the_query->post->ID;
$post_content = get_post_field('post_content', $post_id);
$first_img = '';
ob_start();
ob_end_clean();
$output = preg_match_all('/<img.*?src\s*=\s*[\"|\'](.*?)[\"|\'].*?>/i', $post_content, $matches);
$i = 0;
foreach($matches[1] as $match_s){
$ext_point = strrpos($match_s, ".");
//gifは除外
if($ext_point !== false){
$str_point = $ext_point + 1;
$ext_str = substr($match_s, $str_point);
if($ext_str === 'gif') continue;
}
$ext_str = parse_url($ext_str, PHP_URL_PATH);
$rp_title = home_url('/').'wp-content/uploads/old_data/'.$post->ID.'-'.$i.'.'.$ext_str;
$post_content = str_replace($match_s, $rp_title, $post_content);
++$i;
}
global $wpdb;
$result = $wpdb->update(
$wpdb->posts,
[
'post_content' => $post_content,
],
[
'ID' => $post_id,
],
['%s'],
['%d']
);
endwhile;
else:
endif;
wp_reset_postdata();
全件取得するループは同一ですが、$rp_title
と、$post_content
によって、本文内の画像URL書き換えを準備します。
次に wpdb Class を利用して本文を書き換えます。
書き換え後、srcフォルダ内の画像を wp-content/uploads/old_data/
に移動すれば完了です。
適時デバッグしながら進めると安全です。
Discussion