WPDBでの検索結果をWPループに渡す。SQLもすっきり♪

カスタム


Database

WordPressで検索のカスタマイズをする様々なケース

search.phpテンプレートでの検索のカスタマイズやpostsモデルのデータを絞り込み検索させ
たり、カスタム投稿やtaxonomyで検索するケースなどがあると思います。

posts_joinやposts_request、posts_whereをフックして出来たSQLを見てみると不要な
コードが混入していたり。。

ページングやループに渡したりするのが面倒くさそうだなー。とカスタムを断念した経験が
ある方もいらっしゃると思います。

$wpdbの結果をquery_posts()に渡してしまう

シンプルに$wpdbで検索して、WPループに渡してページングまで実装する最短のやり方を模索
してみたのでご紹介です。

<?php
// パラメーターの取得
$cat_num = $_REQUEST['cat'] ? $_REQUEST['cat'] : false;
$query_s = $_REQUEST['s'] ? $_REQUEST['s'] : false;
$paged   = $_REQUEST['paged'] ? $_REQUEST['paged'] : false;


global $wpdb;

$cat_query    = '';
$join_table   = '';
$com_category = '';

// カテゴリがある
if ( !empty($cat_num) )
{

	$join_table = "
INNER JOIN wp_term_relationships AS tr
ON tr.object_id = post.ID 

INNER JOIN wp_term_taxonomy AS tt
ON tt.term_taxonomy_id = tr.term_taxonomy_id

INNER JOIN wp_terms AS t
ON t.term_id = tt.term_id
	";

	$com_category = " tt.taxonomy IN ('使っているタクソノミー名')";
	$cat_query    = " AND tt.term_id = $cat_num";
	$cat_query    = esc_sql($cat_query);
}


$word_query = '';

// クエリワードがある
if ( !empty($query_s) )
{
	$and_str    = $cat_num ? ' AND' : '';
	$query_s    = esc_sql($query_s);
	$word_query = $and_str. " (((post.post_title LIKE '%$query_s%') OR (post.post_content LIKE '%$query_s%')))";
}


// SQL
$query_str = "
SELECT
   post.ID
FROM
    wp_posts AS post
".
$join_table.
"
WHERE
".
$com_category.
$cat_query .
$word_query .
"
AND post.post_type IN ('page', 'カスタム投稿名') // 検索対象
AND (post.post_status = 'publish'
OR post.post_author = 1
AND post.post_status = 'private') 
";

$results = $wpdb->get_results($query_str);
$ids = NULL;
foreach ($results as $value) {
	$ids[] = $value->ID;
}

// 結果IDを query_posts() に渡しでループを回す
$args['post__in'] = $ids;
$args['post_type'] = array('page', 'カスタム投稿名');
if ( !empty($paged) ) $args['paged'] = $paged;

query_posts($args);
?>

これで様々な検索に対応できます。
※ 上記ソースは参考までに

カスタム

関連記事