- このトピックには10件の返信、2人の参加者があり、最後に
原子恭一により22時間、 24分前に更新されました。
-
投稿者投稿
-
2025年5月23日 10:46 PM #145266
【お使いの Snow Monkey のバージョン】29.0.0
【お使いの Snow Monkey Blocks のバージョン】24.0.4
【お使いの Snow Monkey Editor のバージョン】11.0.1
【お使いのブラウザ】Google Chrome
【当該サイトのURL】いつも大変お世話になっております。
Snow Monkey Search を使用した検索機能において、またまた壁に突き当たりました。
現在、Snow Monkey Search プラグインを利用して、カスタム投稿タイプ「レストラン」(スラッグ:restaurant)の検索システムを構築しております。
この検索システムにおいて、Advanced Custom Fields (ACF) プラグイン(無料版)で作成したカスタムフィールドを、「カスタムフィールド検索」ブロックの絞り込み条件として利用したいと考えております。具体的には、以下のようなACFフィールドを絞り込み条件に追加したいです。
最寄駅:
フィールド名(スラッグ): access
保存されている値の例: yaizu, shizuoka (これらを「焼津駅」「静岡駅」といったラベルで表示したい)
対応言語:フィールド名(スラッグ): supported_languages
保存されている値の例: english, chinese (これらを「英語」「中国語」といったラベルで表示したい)発生している問題:
ブロックエディタで検索フォームを作成する際に、「カスタムフィールド検索」ブロックを配置し、「ブロック設定」内の「キー」のプルダウンを確認したところ、上記で作成したACFのフィールド名(access や supported_languages)が選択肢として表示されません。プルダウンには、ACF以外のメタキーと思われるものしか表示されない状況です。試したこと(解決には至りませんでした):
子テーマの functions.php に add_filter( ‘snow_monkey_search_meta_keys’, …) や register_meta() を使用してACFフィールドキーを登録するようなコードを追記してみましたが、状況は改善されませんでした。
また、REST APIエンドポイント (/wp-json/snow-monkey-search/v1/post-meta-keys/restaurant) に管理者としてログインした状態でブラウザから直接アクセスしたところ、401エラー(権限がありません)となり、キーのリストを確認できませんでした。ご教示いただきたい点:
1:Snow Monkey Search の「カスタムフィールド検索」ブロックの「キー」プルダウンに、ACFで作成したカスタムフィールド名を表示させ、絞り込み条件として利用するための正しい手順をはどのようなものでしょうか。
2:子テーマの functions.php へのカスタマイズが必要な場合、推奨される具体的なコードはどこかに記載されていますでしょうか。
3:その他、ACFフィールドを絞り込み条件として利用するにあたり、注意すべき点や推奨される設定などがあれば、アドバイスいただけますと幸いです。毎度大変恐縮ですが、
どうぞよろしくお願いいたします。♥ 0Who liked: No user2025年5月23日 11:16 PM #145267んむー、なんでしょうね。
管理画面で選択肢に表示するキーのリストは下記の部分で取得しています。
具体的には、
$wp_meta_keys
というグローバル変数を参照して返却している感じです。register_meta()
で登録したメタキーは$wp_meta_keys
に追加されるので参照できるはずですが、ACF が内部的にregister_meta()
しているのかどうかは気になりますね。ACF に詳しくないためそのあたりは僕はわからないです…。試しに ACF を使わずに、
access
をregister_meta()
で追加したらどうなるか確認してみると良いかもです。♥ 0Who liked: No user2025年5月24日 8:03 AM #145268昨夜はありがとうございました。
おかげさまで、子テーマの
functions.php
でregister_meta()
を使用し、対象のACFフィールドキーを明示的に登録(特にshow_in_rest
を適切に設定)することで、無事「キー」プルダウンにACFフィールド名が表示されるようになりました!
ただし、新たな問題が起きました。新たに発生している問題:ACF複数選択チェックボックスでの絞り込みが機能しない
キーの表示問題は解決したのですが、次に、ACFの複数選択チェックボックスで作成した「対応言語 (Language)」フィールドの絞り込みがうまく機能しないという問題に直面しております。
現在の状況:
1:ACFフィールド「対応言語 (Language)」の設定:
- フィールドタイプ: チェックボックス(複数選択可)
- 返り値: 値 (Value) (例:
english
,chinese
) - データベース (wp_postmeta) 保存形式:
a:2:{i:0;s:7:"english";i:1;s:7:"chinese";}
のようなシリアライズされた - 配列文字列として正しく保存されていることを確認済みです。
2:
functions.php
でのregister_meta
設定:register_meta( 'post', 'Language', [ 'object_subtype' => 'restaurant', // 対象の投稿タイプ 'single' => false, 'type' => 'array', 'auth_callback' => function() { return current_user_can( 'edit_posts' ); }, 'show_in_rest' => [ 'schema' => [ 'type' => 'array', 'items' => [ 'type' => 'string' ], ], ], ] );
(他の単一選択のACFフィールド(ラジオボタン等)は、同様に
register_meta
で登録し、Snow Monkey Search で問題なく絞り込みできています。)3:Snow Monkey Search 「カスタムフィールド検索」ブロック(Language 用)の設定:
キー: Language
フロー: 「チェックボックス」
選択肢: “english”: “英語”, “chinese”: “中国語” のように設定。
タイプ: 「CHAR (文字列)」
比較: 「LIKE」4:Query Monitor で確認したSQLの問題点:
上記のSnow Monkey Searchの設定で検索を実行したところ、メインクエリのmeta_query
部分で、Language フィールドに対するSQL条件が以下のようになっていることを確認しました。
(例:フロントで「英語」と「中国語」をチェックして検索した場合)AND ( ( wp_postmeta.meta_key = 'Language' ) AND ( wp_postmeta.meta_value IN ('english','chinese') ) )
このSQLでは、
meta_value
が単純な文字列 ‘english’ または ‘chinese’ と完全一致するものを探しているため、シリアライズされた配列文字列(例:a:2:{...s:7:"english";...s:7:"chinese";...}
) にはヒットせず、検索結果が0件になってしまいます。実現したいこと:
ACFの複数選択チェックボックスで選択された複数の言語(例:英語と中国語)に対応しているレストランを正しく絞り込みたいです。
理想的には、SQLがwp_postmeta.meta_value LIKE '%"english"%' AND wp_postmeta.meta_value LIKE '%"chinese"%'
(AND検索の場合) や、あるいは(wp_postmeta.meta_value LIKE '%"english"%' OR wp_postmeta.meta_value LIKE '%"chinese"%')
(OR検索の場合) のように、シリアライズされた配列文字列の中から選択された値の存在をLIKE
で確認する形になることです。ご教示いただきたい点:
1:Snow Monkey Search の「カスタムフィールド検索」ブロックは、ACFの複数選択チェックボックス(値がシリアライズされた配列としてDBに保存される)の値を、上記のような LIKE 検索で正しく絞り込むための標準的な設定方法(「タイプ」や「比較」の適切な組み合わせなど)はございますでしょうか。
2:もし標準機能での対応が難しい場合、
pre_get_posts
アクションフックなどを利用してmeta_query
をカスタマイズする方法について、Snow Monkey Search と連携する上での推奨されるアプローチや注意点(例えば、Snow Monkey Search が生成するmeta_query
のどの部分を、どのように変更すればこのLIKE
検索を実現できるかなど)がございましたら、ヒントだけでもご教示いただけますと大変助かります。長文となり恐縮ですが、何卒よろしくお願いいたします。
♥ 0Who liked: No user2025年5月24日 10:30 AM #1452691:Snow Monkey Search の「カスタムフィールド検索」ブロックは、ACFの複数選択チェックボックス(値がシリアライズされた配列としてDBに保存される)の値を、上記のような LIKE 検索で正しく絞り込むための標準的な設定方法(「タイプ」や「比較」の適切な組み合わせなど)はございますでしょうか。
本来だと同じキーのメタデータが複数登録された状態になるので、シリアライズして保存するというのが ACF の独自仕様なんですよね。なのでこれをどうにかする標準的な方法というのはなくて(強いて言えば標準的な形でメタデータを保存するプラグインに乗り換える)、基本的にはご想像の通りフックでクエリーを書き換えるという形になるのかなと思います。
Snow Monkey Search の場合だと
pre_get_posts
よりsnow_monkey_search_pre_get_posts
を使うほうが良いです。僕もやったことがないのでわからないのですが、
meta_query
の部分を参照して、書き換えた必要なメタキーが含まれていたら書き換えるというアプローチになるのかなぁと想像します。が、Snow Monkey Search の他に ACF にネイティブに対応している検索系プラグインがあるようなら、それを使うほうがリスクは低いかもですね…。
♥ 0Who liked: No user2025年5月24日 10:38 AM #145270と、ここまで書いて気づきましたが、「3:Snow Monkey Search 「カスタムフィールド検索」ブロック」にかかれているように、「比較」は「LIKE」にされてるんですよね?
それなのに SQL では
IN
になっちゃうというのであれば、Snow Monkey Search 側に不具合があるのかな…?♥ 0Who liked: No user2025年5月24日 10:45 AM #145271はい。「比較」は「LIKE」なのに、SQL では IN になっちゃうのです。ここが大問題ですよね…
♥ 0Who liked: No user2025年5月24日 10:48 AM #145272試してみましたが、僕の環境だと正しく
LIKE
になっているようでした。クエリーをカスタマイズするコードを既に追加されているのであれば、一旦それを全部消してみると変化があるか確認してみてください。
♥ 0Who liked: No user2025年5月24日 11:13 AM #145273ご確認いただきありがとうございます。
キタジマさんの環境で LIKE になったとのこと、承知いたしました。
追加で恐縮ですが、その際にテストされたカスタムフィールドは、
Advanced Custom Fields (ACF) プラグインを使って作成されたフィールドでしょうか?
それとも、ACFを使わずにWordPressの標準機能で追加されたカスタムフィールドでしょうか?私の環境では、ACFで作成したフィールド(値はカンマ区切りの単純な文字列としてデータベースに保存し、register_meta でも type: ‘string’, single: true で登録)に対して、
Snow Monkey Search のカスタムフィールド検索ブロックで「タイプ:CHAR」「比較:LIKE」と設定しても、SQLが meta_value IN (‘検索語句’) となってしまいます。もし、キタジマさんがテストされたのがACFフィールドでない場合、
ACFフィールドに対してSnow Monkey Search の LIKE 検索が期待通りに機能しない可能性も考えられるかと思いました…♥ 0Who liked: No user2025年5月24日 4:05 PM #145276Advanced Custom Fields (ACF) プラグインを使って作成されたフィールドでしょうか?
それとも、ACFを使わずにWordPressの標準機能で追加されたカスタムフィールドでしょうか?ACF ではなくて、
register_meta()
で追加したものです。Snow Monkey Search のクエリー操作を見直していて気づいたのですが、検索ボックスから特定のキーに対して複数の値が送信されてきたとき(例:チェックボックスで複数のチェックがされたとき)は、強制的に
IN
になるようにしてるみたいでした。なんで、チェックボックス検索にされているのならこれが影響しているのかも?これを消したらどうなるか一度試してみてください!
♥ 0Who liked: No user2025年5月24日 5:38 PM #145277ご丁寧なアドバイスをいただき、ありがとうございました。
【結果のご報告】
ご教示いただいた内容に基づき、さらに詳細な検証を行った結果、以下の点が判明いたしました。
1:Query.php の該当箇所について:
ご指摘の if ( is_array( $meta_value ) ) { $meta_compare = ‘IN’; } の部分をコメントアウトしてテストしたところ、ACFの複数選択チェックボックスから送られてくる配列の $meta_value と、LIKE 検索の組み合わせでは、WordPressの WP_Meta_Query がエラーを発生させることが確認できました(wpdb->esc_like() が配列を処理できないため)。
このことから、あのコードブロックは、配列の値に対して IN 句で検索を行うための意図的な実装であったと理解いたしました。2:ACF複数選択チェックボックス(値がシリアライズ配列またはカンマ区切り文字列)と Snow Monkey Search の連携について:
現在の Snow Monkey Search の「カスタムフィールド検索」ブロックの標準機能では、データベースにシリアライズされた配列文字列やカンマ区切り文字列として保存されているACFの複数選択チェックボックスの値を、期待するような柔軟な LIKE 検索(例:選択された複数の値をOR条件やAND条件で部分一致検索する)で絞り込むことは難しい、という結論に至りました。
(「比較:LIKE」と設定しても、実際には IN 句や、単純な文字列との完全一致に近いSQLが生成されてしまうため)【今後の対応について】
1:このような複数選択が望ましい項目は、ACFのカスタムフィールドではなく、カスタムタクソノミーとして再設計し、Snow Monkey Search の「タクソノミー検索」ブロックを利用する?
2:または、機能要件を調整し、単一選択のラジオボタンで絞り込みを行う?pre_get_posts フック等での高度なカスタマイズについては、とうてい私のできうる範囲ではありませんので、今回はより安定した標準的な方法を選択することになると思います。
今回の件では、お忙しい中、何度もご丁寧にご回答いただき、ありがとうございました。
♥ 0Who liked: No user2025年5月24日 9:29 PM #145278その後、AIが考えた以下のコードで、LIKE 検索問題は解決したかに見えましたが、
AND検索の答えが間違っていたりして、非常に不可解な状況が続き、ここまでかな、という結論になりました。
休日にも関わらず返信いた、だきありがとうございました。<?php
// 対象のカスタムフィールドキー
$target_field_keys = array( ‘Language’, ‘veggie-halal’ /* , 他のチェックボックス系フィールド */ );function fix_sms_checkbox_like_query( $query ) {
if ( is_null( filter_input( INPUT_GET, ‘snow-monkey-search’ ) ) ) {
return;
}$meta_query = $query->get( ‘meta_query’ );
if ( ! is_array( $meta_query ) || empty( $meta_query ) ) {
return;
}// GETパラメータからSnow Monkey Searchのカスタムフィールド設定を取得
$post_metas_from_get = filter_input( INPUT_GET, ‘sms-post-meta’, FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
if ( ! $post_metas_from_get ) {
return;
}global $target_field_keys; // グローバル変数として定義した場合、または関数内で定義
$modified = false;foreach ( $meta_query as $index => &$meta_condition ) { // 参照渡し
if ( is_array( $meta_condition ) && isset( $meta_condition[‘key’] ) &&
in_array( $meta_condition[‘key’], $target_field_keys ) &&
isset( $post_metas_from_get[ $meta_condition[‘key’] ][‘compare’] ) &&
$post_metas_from_get[ $meta_condition[‘key’] ][‘compare’] === ‘LIKE’ ) {if ( isset( $meta_condition[‘value’] ) && is_array( $meta_condition[‘value’] ) ) {
$current_field_key = $meta_condition[‘key’];
$values_from_condition = $meta_condition[‘value’];if ( count( $values_from_condition ) === 1 ) {
$meta_condition[‘compare’] = ‘LIKE’;
$meta_condition[‘value’] = $values_from_condition[0];
$modified = true;
} else if ( count( $values_from_condition ) > 1 ) {
$or_conditions = array( ‘relation’ => ‘OR’ );
foreach ( $values_from_condition as $value_item ) {
$or_conditions[] = array(
‘key’ => $current_field_key,
‘value’ => $value_item,
‘compare’ => ‘LIKE’,
‘type’ => ‘CHAR’,
);
}
$meta_condition = $or_conditions; // 元の条件をORグループで置き換え
$modified = true;
}
}
}
}
unset( $meta_condition );if ( $modified ) {
// meta_query全体のrelation調整(複数の条件グループがある場合)
$actual_conditions_count = 0;
foreach ($meta_query as $mq_key => $mq_value) {
if (is_int($mq_key)) {
$actual_conditions_count++;
}
}
if ($actual_conditions_count > 1 && !isset($meta_query[‘relation’])) {
$meta_query[‘relation’] = ‘AND’;
} elseif ($actual_conditions_count <= 1 && isset($meta_query[‘relation’])) {
unset($meta_query[‘relation’]);
}
$query->set( ‘meta_query’, $meta_query );
}
// error_log(‘Final Fixed Meta Query by fix_sms_checkbox_like_query: ‘ . print_r($query->get(‘meta_query’), true));
}
add_action( ‘snow_monkey_search_pre_get_posts’, ‘fix_sms_checkbox_like_query’, 10 );
?>♥ 0Who liked: No user -
投稿者投稿
- このトピックに返信するにはログインが必要です。