#やりたいこと
同一サーバー内にマルチドメインで作成した2つのWordpressサイト(サイトA,サイトB)のそれぞれの投稿記事をまとめて一カ所に投稿日順で出力したい。
##前提スキル
Wordpressサイトの構築は実務で3年弱の経験があるが、PHPやSQL発行は初心者。
##アプローチ
サイトA側でWordpressのwpdbクラスを使いつつ、サイトAとサイトBのクエリデータを結合した上で、それぞれの投稿をまとめて出力する。
feedを使う方法も検討しましたが、カスタムフィールドの取得や、ドメイン移管前という環境もあり断念しました。
##function.php
/**
* switch_blog 用に wp_upload_dir() の返り値を書き換え
*/
function _switch_blog_upload_dir( $upload_dir ) {
$pattern = '/^(https?:\/\/[^\/]+)/';
$replacement = home_url();
$upload_dir['url'] = preg_replace( $pattern, $replacement, $upload_dir['url'] );
$upload_dir['baseurl'] = preg_replace( $pattern, $replacement, $upload_dir['baseurl'] );
return $upload_dir;
}
/**
* サイトBに切り替え
*/
function switch_blog() {
global $wpdb, $backup_wpdb;
$backup_wpdb = $wpdb;
$wpdb = new wpdb( 'データベースユーザー名', 'データベースパスワード', 'データベース名', 'データベースホスト名' );
wp_set_wpdb_vars();
wp_cache_init();
add_filter( 'upload_dir', '_switch_blog_upload_dir', 10 );
}
/**
* サイトAに設定を戻す
* switch_blog した後は必ずこのメソッドでリセットが必要
*/
function restore_current_site() {
global $wpdb, $backup_wpdb;
$wpdb = $backup_wpdb;
wp_cache_init();
remove_filter( 'upload_dir', '_switch_blog_upload_dir', 10 );
}
functionコードは下記記事を参考にさせて頂きました。
https://2inc.org/blog/2015/10/23/5059/
##post.php
<div class="other-project">
<h2 class="other-project-title">Recently Project</h2>
<?php //サイトAのクエリを設定
$query = <<<SQL
SELECT *,0 as flag
FROM {$wpdb->posts}
WHERE {$wpdb->posts}.post_status = 'publish'
AND {$wpdb->posts}.post_type = 'post'
SQL;
switch_blog(); //サイトBに切り替え
$db_name = "サイトBのデータベース名";
$query .= <<<HERE //サイトBのクエリを結合
UNION
SELECT *,1 as flag
FROM $db_name.{$wpdb->posts}
WHERE $db_name.{$wpdb->posts}.post_type = 'post'
AND $db_name.{$wpdb->posts}.post_status = 'publish'
ORDER BY post_date DESC
HERE;
restore_current_site(); //サイトAに戻す
?>
<?php $posts = $wpdb->get_results($query); ?>
<div class="prjslider">
<?php
foreach ($posts as $post): //ループ開始
setup_postdata($post);
if ($post->flag == 1) { //サイトA,Bを判定
switch_blog(); //サイトBなら切り替え実行
}
get_template_part('loop', 'module');
restore_current_site(); //サイトAに設定を戻す
endforeach; //ループ終了
wp_reset_postdata();
?>
</div>
<!-- /prjslider -->
</div>
<!-- /other-project -->
##まとめ
会社の先輩に助けてもらいつつ、何とかやりたい事はできました。
ですが、冗長なコードを書いている気がするのと、
そもそももっと手軽な方法があるのでは、と思っております。
優しい諸先輩方がいたら指摘いただけると幸いです。