14
DECEMBER
ウェブTHURSDAY 2023 / 12 / 14
LazyBlocksプラグインのRepeaterフィールド内の文字列が検索対象とならない問題への対応
Text by Hiroyuki Matsumoto
WordPressのブロックエディタにおいて、簡単にオリジナルブロックを作成できる LazyBlocks ですが、繰り返し項目の作成をするReapterフィールドにおいて入力した文字は、検索をしても対象となりません。
※厳密には「対象とならないことがあります」です。半角文字ならいけるはずです。
これは管理画面内での投稿検索およびパブリックな検索機能のいずれでも同様です。
直接の原因はRepeaterフィールドが保存される際に、入力された値がURLエンコードされるためです。
例えばRepeaterフィールド内にカミナリと入力すると、
保存時には%E3%82%AB%E3%83%9F%E3%83%8A%E3%83%AAとして保存されます。
公式フォーラムによると、LazyBlocksではブロックの破損を防ぐなどの理由で、複雑なフィールドについてはこのようにURLエンコードして保存する仕様となっているということです。
簡単な対処法としては、元のキーワードをURLエンコードした後のキーワードに変換し、それで検索すれば普通に検索結果に表示されます。しかしRepeaterフィールド以外に元のキーワードがある場合には当然検索結果に出てきません。そのため適切に検索するためには
「元のキーワード」 OR 「URLエンコードしたキーワード」
のように検索する必要があります。
今回はフィルターフックを使用して、直接検索クエリを書き換えることで上記の検索を自動的に行う処理を書いてみました。
function custom_posts_search_admin($search, $wp_query){ if($wp_query->is_admin && $wp_query->is_search){ global $wpdb; $wildcard_symbol = esc_sql('%'); // ワイルドカード扱いとなる %記号は、セキュリティ保護のため毎回違うキーワードとなる。例){2e0333de4ffac1bf86b76524d2bfe5eea5ca07cf68578d8978a7dbc9e2e190ca} $keyword_raw = get_search_query(false); // 検索キーワードを無加工の状態で取得 $keyword = urlencode($keyword_raw); // LazyBlocks の Repeaterフィールドでの保存形式となるURLエンコードされた状態に変換 $keyword = str_replace('%', '\\\\%', $keyword); // % を \\% にエスケープする(% はワイルドカードとならず、% という文字として扱われる) $keyword = $wpdb->_escape($keyword); // SQLインジェクション対策を実施 $keyword = $wildcard_symbol . $keyword . $wildcard_symbol; // 前後ワイルドカード付きのキーワードを生成 $field_posts = $wpdb->posts . '.post_content'; $add_sql_where = " OR ({$field_posts} LIKE '{$keyword}')"; $search = preg_replace('/^ AND \(/i', ' AND ((', $search); $search = preg_replace('/$/', $add_sql_where . ')', $search); } return $search; } add_filter('posts_search', 'custom_posts_search_admin', 10, 2);
注意
2行目にあるように is_admin を使い管理画面内でしか使えないコードにしています。
一応SQLインジェクション対策はしているつもりですが、知識を数年はアップデートされていないので、外部公開した際にDB書き換え等の被害に遭う可能性が否定できません。
本番環境では is_admin の条件は外さず使う、またはセキュリティの専門家にコードレビューを受ける等の対策をしてください。
TEXT by
松本 博之(まつもとひろゆき)
1978年、鳥取県米子市生まれ。
株式会社マジックワード WEBシステムの開発・運用を担当。
WordPressの実績多数。表面的な使用方法を把握するだけでなく、WordPressのソースコードを読み解いて対応できます。
国家資格の応用情報処理技術者をなんとなくとりました。