LoginSignup
2
1

More than 5 years have passed since last update.

Wordpressのマルチサイトで全ブログを対象とした検索をする

Last updated at Posted at 2019-02-18

概要

WordPressのマルチサイトでは、全ブログを対象とした検索ができない。
そこで全ブログを検索するコードを作成しました。

方針

  • switch_to_blog()はペナルティが大きいらしく、サーバに負荷が掛かるようなのでやめる。
  • カテゴリー、タグも検索対象とする。Wordpressデフォルトでは、本文、記事タイトルのみが検索対象のため。

作成したコード

wp-content/themes/(テンプレート)/search.php を次のようにしました。

search.php
<?php get_header(); ?>
<!?// ここから書き換え----------------------------------------------- //?>
<?php
global $wpdb;//mysqlのデータベース情報を格納しているグローバル変数$wpdb
$searchfor = get_search_query(); // 検索キーワード取得
?>
<h2><?php echo $searchfor; ?>」の検索結果</h2>
<?php
$sql="SHOW TABLES FROM $wpdb->dbname"; //テーブル一覧を取得するSQL文を作成
$res_rows = $wpdb->get_results($sql); //テーブル一覧を$res_rowsに格納
if(!$res_rows){
    echo "【データベースエラー】テーブルリストの取得に失敗しました<br />\n";
    echo "MySQL Error: ".mysqli_error();
    exit;
}
$siteurl_chk_array=array(); //検出される記事のURLを重複を除外するためのチェック用配列(初期化)
foreach($res_rows as $data) { //$data にテーブルを格納するループ
    // $objectToArray = (array)$data;
    // print_r(  array_values($objectToArray)[0] );
    // オブジェクトを配列にして値取得
    $tablename = array_values( (array)$data )[0]; //テーブル名取得
    if( preg_match("/_posts/",$tablename) ) { //postsテーブルループ
        if( !preg_match("/v_posts/",$tablename) ) {
            # print($tablename);
            $siteid="";
            if (preg_match('/wp_(\d{1,4})/', $tablename, $tmp_match)){
                $siteid = $tmp_match[1]."_";
            }
            $term_relationships = "wp_".$siteid."term_relationships";
            $term_taxonomy = "wp_".$siteid."term_taxonomy";
            $terms = "wp_".$siteid."terms";
            $options = "wp_".$siteid."options";

            // 検索用SQL
            // 検索対象: 公開された記事で、記事本文(post_content), 記事タイトル(post_title), 
            // 記事カテゴリ/タグ名(wp_x_term.terms ), 抜粋(wp_x_term_taxonomy.description)
            //   → → 記事本文(post_content), 記事タイトル(post_title)で検索して見つかる記事 
            //            または、記事カテゴリ/タグ名を検索し該当の term_id を使用する記事
            $searchquery_posts = 
            "SELECT * FROM " .$tablename. " 
            WHERE post_status = 'publish' AND
            (post_type = 'post' OR post_type = 'page') AND 
            (post_content LIKE '%" .$searchfor. "%' OR post_title LIKE '%" .$searchfor. "%'
                OR ID IN (
                    SELECT distinct r.object_id
                    FROM ".$term_relationships." AS r
                    INNER JOIN ".$term_taxonomy." AS tt ON r.term_taxonomy_id = tt.term_taxonomy_id
                    INNER JOIN ".$terms." AS t ON tt.term_id = t.term_id
                    WHERE t.name LIKE '" .$searchfor. "'
                OR t.slug LIKE '" .$searchfor. "'
                OR tt.description LIKE '" .$searchfor. "'
                )
            )";
            // 検索SQLを実行
            $result_posts = $wpdb->get_results($searchquery_posts, ARRAY_A);
            $siteurl=""; //各ブログのURL
            if($result_posts===null){
                continue;
            }elseif ($result_posts) {
                // 各ブログのURLを見つけるSQL
                $searchquery_siteurl = "SELECT option_value FROM " .$options. " WHERE option_name = 'siteurl' ";
                $siteurl = $wpdb->get_var($searchquery_siteurl);
                if($siteurl===null){
                    continue;
                }
            }
        }
    }
    // print_r($result_posts);
    foreach($result_posts as $row)  {//検索結果を表示するHTMLを出力
        $tmpurl = $siteurl. "?page_id=" .$row['ID'];
        if (!in_array($tmpurl, $siteurl_chk_array)){
            echo "<div class='searchlink'><a href='";
            print($tmpurl);
            echo "'>「";
            print($row['post_title']);
            echo "」</a></div>";
            print(mb_substr(strip_tags($row['post_content']),0,200));//contentからHTMLタグを取り除き200文字のみ表示
            echo "<br />\n";
            // 記事のURLを重複を除外するためのチェック用配列に追加
            $siteurl_chk_array[] = $tmpurl;
        }
    }
}
// print_r($siteurl_chk_array);
?>
<!?// ここまで書き換え----------------------------------------------- //?>
<?php get_footer();

参考にしたサイト

課題

  • 検索結果が、一覧ですべて表示されます。ページネイション機能を入れて、ページ送りが必要です。
    • → これは必須の機能ですね。。。
  • 自作のHTMLのためWordpressデフォルトの検索結果ページデザインと異なってしまいます。検索結果ページをブログのデザインに合わせる必要があります。
  • 複数語の検索には未対応です。検索文字が「AAA, BBB, CCC」とあったら、「AAA」, 「BBB」, 「CCC」の全部の単語が見つかるように検索ではなく、「AAA, BBB, CCC」という文字列で検索します。
  • 検索結果は、見つかった順です。検出件数の多い順などでは、ありません。
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1