前回でSQL文の準備ができたので、wordpress側で記事の取得と表示をしていきたいと思います。

wordpressのマルチサイトで各サイト(ブログ)の記事を混ぜて一覧表示する

  1. wordpressのマルチサイトで各サイトの記事を混ぜて表示する方法を考える
  2. MySQL – サイト毎に分かれている投稿テーブルを1つにまとめる
  3. MySQL – ブログIDを追加する
  4. MySQL – 1つにまとめたデータを投稿日順に並び替える
  5. MySQL – 1つにまとめたデータに取得件数を指定する
  6. 完成版(ページングなし) – wordpressのマルチサイトで各サイトの記事を混ぜて一覧表示する

スポンサーリンク

はじめに

前回までのつづき

今回やりたいこと

  • 前回までで作成したSQL文を使用して、wordpress側で記事を取得して表示する

シリーズを通してやりたいこと / ゴール

  • マルチサイトで親サイトに、各サイトの記事を混ぜて日付順で一覧表示する

制作環境 / テスト環境

  • wordpress サブディレクトリ型のマルチサイト

情報

今回は、下記の条件・情報でおこないたいと思います。

SQL文を使用してwordpressで記事を取得して表示する

前回までで、「$wpdb->prepare」に入れるSQL文を作成しました。

今回は、SQL文を使用してwordpress側で記事を取得して表示します。

SQLインジェクション対策 「$wpdb->prepare」のプレースホルダーに変更

まず、前回までで作成したSQL文で、SQL文はほぼ完成なのですが、SQLインジェクション対策としてSQL文の中の変数を入れる箇所を「prepare」のプレースホルダーに変更します。

「$wpdb->prepare」プレースホルダー

変数が文字列の場合は「%s」を、整数の場合は「%d」を入れます。

  • 「%s」・・・文字列で代入する箇所に使用する
  • 「%d」・・・整数で代入する箇所に使用する
  • 「%f」・・・小数点で代入する箇所に使用する

詳しくは、下記を参照してください。
wpdb Class – WordPress Codex 日本語版

SELECT *
	FROM
	(
		SELECT
			wp_posts.ID,
			wp_posts.post_date,
			wp_blogs.blog_id
		FROM wp_posts
		INNER JOIN wp_blogs
			ON (
				wp_blogs.blog_id = %d
			)
		WHERE post_status = %s
		AND post_type = %s

		UNION ALL

		SELECT
			wp_2_posts.ID,
			wp_2_posts.post_date,
			wp_blogs.blog_id
		FROM wp_2_posts
		INNER JOIN wp_blogs
			ON (
				wp_blogs.blog_id = %d
			)
		WHERE post_status = %s
		AND post_type = %s

		UNION ALL

		SELECT
			wp_3_posts.ID,
			wp_3_posts.post_date,
			wp_blogs.blog_id
		FROM wp_3_posts
		INNER JOIN wp_blogs
			ON (
				wp_blogs.blog_id = %d
			)
		WHERE post_status = %s
		AND post_type = %s
	) u
	ORDER BY u.post_date DESC
	LIMIT %d

このSQL文内の「%s」は、あとからwordpressの「$wpdb->prepare」で取得する際に使用するプレースホルダーです。

代入する値は、あとで設定することにします。

これで、「$wpdb->prepare」に入れるSQL文が用意できました!

次に、wordpressでDBからデータを取得します。

wordpressでDBからデータを取得できる関数が用意されているので、それを利用します。

データを取得するのに・・・「$wpdb->get_results()」
SQLのインジェクション対策・・・「$wpdb->prepare()」

global $wpdb;

$results = $wpdb->get_results (
	$wpdb->prepare (
		$sql,// SQL文
		// プレースホルダーに代入する値など。。
	)
);

SQL文の箇所には、先ほど作成したSQL文を入れます。

その次に、「プレースホルダーに代入する値」をカンマ区切りで入れていきます。

「プレースホルダーに代入する値」とは、先ほどSQL文に「%s」や「%d」などのプレースホルダーに変更した箇所がありました。
その部分に代入する値を定義していきます。
順番は、SQLの「%s」や「%d」に変更した箇所を上から(出てきた順番)順番に、カンマ区切りで入れていきます。

global $wpdb;

$results = $wpdb->get_results (
	$wpdb->prepare (
		$sql,
		1,
		'publish',
		'news',
		2,
		'publish',
		'post',
		3,
		'publish',
		'info',
		5
	)
);

これで、DBから取ってきた情報が$resultsへ入っているので、あとは$resultsをforeachなどで回して出力すればできそうです。

完成版(ページングなし) 記事の取得&表示コード

global $wpdb;

$sql = "
	SELECT *
		FROM
		(
			SELECT
				wp_posts.ID,
				wp_posts.post_date,
				wp_blogs.blog_id
			FROM wp_posts
			INNER JOIN wp_blogs
				ON (
					wp_blogs.blog_id = %d
				)
			WHERE post_status = %s
			AND post_type = %s

			UNION ALL

			SELECT
				wp_2_posts.ID,
				wp_2_posts.post_date,
				wp_blogs.blog_id
			FROM wp_2_posts
			INNER JOIN wp_blogs
				ON (
					wp_blogs.blog_id = %d
				)
			WHERE post_status = %s
			AND post_type = %s

			UNION ALL

			SELECT
				wp_3_posts.ID,
				wp_3_posts.post_date,
				wp_blogs.blog_id
			FROM wp_3_posts
			INNER JOIN wp_blogs
				ON (
					wp_blogs.blog_id = %d
				)
			WHERE post_status = %s
			AND post_type = %s
		) u
		ORDER BY u.post_date DESC
		LIMIT %d
";

// 記事の取得
$results = $wpdb->get_results (
	$wpdb->prepare (
		$sql,
		1,
		'publish',
		'news',
		2,
		'publish',
		'post',
		3,
		'publish',
		'info',
		5
	)
);

// 記事の表示
foreach ( $results as $result )
{
	// ブログ ID
	$blog_id = $result->blog_id;
	// 投稿 ID
	$post_id = $result->ID;
	
	switch_to_blog( $blog_id );// ブログ切り替え
		// 投稿IDを指定して、投稿の情報を取得する

		// 投稿日
		echo esc_html( get_the_time( 'Y.m.d', $post_id ) );
		// 投稿タイトル
		echo esc_html( get_the_title( $post_id ) );
		// 投稿パーマリンク
		echo esc_url( get_permalink( $post_id ) );

		// ACF カスタムフィールド テスト
		echo esc_html( get_field( 'test_text', $post_id ) );
	restore_current_blog();// ブログ切り替え終了
}

 
「blog_id」をつけてDBから取得しているので、「blog_id」でブログを切り替えながら投稿IDを指定してタイトルなどを取得していきます。

本当は、取得したい情報は全部SQLで加工してから取得したほうがよかったかもなのですが、タクソノミーやカスタムフィールドなども入ってくるとSQL不慣れな自分にとってはいっぱいいっぱいだったので、SQLは最低限にして、wordpress出力の方でやる方法にしました。

まとめ

これでとりあえず、親サイト・子サイトを混ぜて表示することができました!

今回は、ページングがないもので書きましたが、ページング対応版もあるので、そのうち書こうと思います。

wordpressのマルチサイトで各サイト(ブログ)の記事を混ぜて一覧表示する

  1. wordpressのマルチサイトで各サイトの記事を混ぜて表示する方法を考える
  2. MySQL – サイト毎に分かれている投稿テーブルを1つにまとめる
  3. MySQL – ブログIDを追加する
  4. MySQL – 1つにまとめたデータを投稿日順に並び替える
  5. MySQL – 1つにまとめたデータに取得件数を指定する
  6. 完成版(ページングなし) - wordpressのマルチサイトで各サイトの記事を混ぜて一覧表示する

参考にさせていただきました


スポンサーリンク