Blog

【WordPress】検索条件にカスタムタクソノミーなどを含める

2015/12/23

カスタム投稿 Wordpress

個人で制作している「食!相模原」というサイトで、
場所とジャンル(例えば、中央区、ラーメンなど)で検索をしたいため、
検索条件のカスタムが必要になります。

当初「Search Everything」というプラグインを使っていましたが、
検索結果が完全一致ではないため、どちらかの検索条件で全てがヒットしてしまいます。

というわけで、プラグインを無効にして、
カスタム方法を探していたところ、下記のサイトを見つけました。

検索対象にカスタムタクソノミーの文字列も含めたい

こちらのカスタムが使えたので備忘録として残します。

検索条件を追加するための詳しい説明については、上記サイトをご参照ください。

ます、上記のサイトを参考に検索結果を表示するsearch.phpに下記のソースコードを挿入しました。

<?php
 
//検索キーワードを取得
$keys = get_search_query();
//スペースが全角の場合、半角に変換
$keys = str_replace(' ', ' ', $keys);
//SQLインジェクション用
//$keys = mysql_real_escape_string($keys);//追記PHP 5.5.0 で非推奨になり、PHP 7.0.0 で削除されました
//検索キーワードを配列に変換
$keys_array = explode(' ', $keys);
 
//キーワードの数だけWHERE節を作成する
$sql_where = '';
foreach ($keys_array as $key => $value) {
  if(empty($sql_where)){
    $pre_str = 'WHERE ';
  }else{
    $pre_str = 'AND ';
  }
  $sql_where .= $pre_str . "(0<LOCATE('{$value}',posts.post_title) OR 0<LOCATE('{$value}',t_terms.name) OR 0<LOCATE('{$value}',t_terms.slug)) ";
}
 
//クエリを実行  
$objResult = $wpdb->get_results(
  $wpdb->prepare(
    "SELECT * FROM {$wpdb->posts} posts LEFT JOIN {$wpdb->term_relationships} t_rel  ON posts.ID = t_rel.object_id
    LEFT JOIN {$wpdb->term_taxonomy} t_term_tx ON t_rel.term_taxonomy_id = t_term_tx.term_taxonomy_id  
    LEFT JOIN {$wpdb->terms} t_terms ON t_term_tx.term_id = t_terms.term_id 
    "
    . $sql_where,null
));
 
 
//検索結果が0でなければ、ヒットした投稿のIDを指定してquery_postsで抽出する。
 
if (!empty($objResult)){
   
  $id_array = '';
  $i=0;
  foreach ($objResult as $key => $value) {
    $id_array[$i] = $value->ID;
    $i++;
  }
   
  $arg = array(
    'post__in'=>$id_array,
    'post_type'=>'対象のカスタム投稿タイプ' //対象のカスタム投稿タイプ
  );
   
  $posts = query_posts( $arg );
 
}
 
//検索結果が0なら、query_postsを行わない。その場合、標準の検索機能が自動的に動作する。
//そのため、何もヒットしなければ、標準の「ヒットしませんでした」画面も自動的に表示される。
 
?>
<?php  if ( have_posts()) : while(have_posts()) : the_post(); ?>
以下省略

実は参考サイトと一部だけソースコードが違います。

というのは、参考サイトのソースコードだけだと
Warning: Missing argument 2 for wpdb::prepare(), called in /フルパス/public_html/wp-content/themes/テーマ名/search.php on line 51 and defined in /フルパス/public_html/wp-includes/wp-db.php on line 1246
というエラーが出てしまいます。

そこでさらにエラーコードで調べたところ、
下記のサイトがヒットしました。

WordPressのバージョンアップ後に「Warning: Missing argument 2 for wpdb::prepare()」が発生

WordPressの3.5以上では「wp-db.php」で定義されているFunction「prepare」の引数の数が2つ必要になっています。

ということで下記の箇所を修正しています。

$wpdb->prepare(
  省略
    . $sql_where,null
)

上記のようにしたところ、エラーコードが表示されなくなりました。

検索結果も完全条件一致で表示されるようになりました。

同様でお悩みの方は参考にしてください。

2016.2.8 追記
phpのバージョンを上げたところ、エラーが表示されるようになりました。
mysql_real_escape_stringでPHP 5.5.0 で非推奨になり、PHP 7.0.0 で削除されたのが原因でした。
とりあえず、//でコメントアウトして対応をしていますが、
なぜか表示結果には問題が無いようです。
しかし、代わりの方法を模索中です。

2016.3.15追記
該当の箇所はSQLインジェクションになるため、
ここでソースコードを変更するというよりも根本的なセキュリティ対策をする形になります。

参考サイト
WordPressのセキュリティ対策でしておくべき11の項目

というわけで
「wp-config.php」のパーミッションを「400」にしてセキュリティ対策で対応をしました。

カテゴリー

月間アーカイブ

MORE

ミュージシャンズ・プラザ

神社仏閣ホームーページ制作

ホームページ制作問合せ