これが私の問題です。カスタム分類法を適用するカスタム投稿タイプがあります。この分類法により、管理者はユーザーが検索したときに投稿が確実に見つかるような検索候補を提供できます。この分類法は、フロントエンドでこれらの提案で検索フィールドを自動補完するためにも使用されます。
用語がスラッシュ、スペースまたは他の「特殊」文字を含む場合を除いて、システムは正常に機能します。
<?php
$keyword = 'Ski-in%2FSki-out';//Submitted via $_GET
$keyword = urldecode($keyword); // (string)'Ski-in/Ski-out'
$taxQuery = new WP_Query(array(
'post_type' => 'ml_properties',
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'mc_tax_lifestyle',
'field' => 'name',
'terms' => array($keyword),
'operator' => 'IN'
)
)
));
?>
私はWordPressによって提供されているエスケープ機能を使用することを検討しました、しかしそこに運がありませんでした。これは単純な問題になると思いましたが、私のGoogle-fuは強力ではないか、または運がないだけです。
Ski-in/Ski-out
がMySQLに格納されている正確な文字列であることも確認しました。 esc_attr()
、$wpdb->esc_like()
、esc_sql()
の使い方を調べましたが、効果がありません。
明らかなものが足りないのでしょうか。
これがバグかどうかはわかりませんが、さらに調査が必要です。 tax_query
のname
フィールドで簡単なテストをいくつか実行しました。用語名に特殊文字が含まれる場合や、複数のWordが含まれる場合は、tax_query
がSQLクエリから除外されます。
ここでは2つの用語を使用しています。あなたの用語はSki-in/Ski-out
、私のテストサイトの用語はUit die koskas
です。今、私は私のカスタムクエリを次のように実行すると
$taxQuery = new \WP_Query(array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'name',
'terms' => 'Ski-in/Ski-out',
'operator' => 'IN'
)
)
));
?><pre><?php var_dump($taxQuery->request); ?></pre><?php
リクエストのvar_dump()
は私にこれを与えます
string(254) "SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
WHERE 1=1
AND (
0 = 1
)
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 4"
tax_query
はSQLクエリに追加されません
特殊文字を使用せずに単一のWord用語を使用すると、クエリは機能します。ここで私はOngekategoriseerd
と呼ばれる用語でテストしました
$taxQuery = new \WP_Query(array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'name',
'terms' => 'Ongekategoriseerd',
'operator' => 'IN'
)
)
));
?><pre><?php var_dump($taxQuery->request); ?></pre><?php
これは私に正しいSQLクエリを与えます
string(378) "SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
INNER JOIN wp_term_relationships
ON (wp_posts.ID = wp_term_relationships.object_id)
WHERE 1=1
AND (
wp_term_relationships.term_taxonomy_id
IN (1)
)
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 4"
これが意図的なものなのかバグなのかはまだわかりませんが、それまでの間にWP_Query
ソースコードを見て、tax_query
がどのようにビルドされているかを確認してください。私は近い将来それについても調べるでしょう
仕事に出る前に、私はすぐにWP_Query
クラスを調べました。クラスの終わりに向かって、WP_Query
はいくつかの後方互換性テストをします、そして目に見える価値からこれがすべてが失敗するところであるように思われるかもしれません。
私はこの問題についてのtracチケットを見つけることができません、もし誰かがリンクを持っているならば、私の答えを更新するか、またはコメントで投稿してください。
名前を使う必要があり、使わなければならない場合は、 get_term_by()
を使用して自分でヘルパー関数を作成する必要があります。その後、用語nameを使用して用語objectを取得し、そこから用語IDを使用してtax_query
で使用できます。
問題はWP_Query
自体にはありませんでした( これらのクラスを見ているとなんてめちゃくちゃになります )。 WP_Query
は WP_Tax_Query
を使用してtax_query
を構成します。 do_action
のparse_tax_query
メソッドのWP_Query
呼び出しの直前の最後の行を確認してください。
$this->tax_query = new WP_Tax_Query( $tax_query );
WP_Tax_Query
クラスに移動しました。このクラスには、単一のクエリをあるフィールドから別のフィールドに変換する次のメソッド、 transform_query
があります。 field
パラメータをname
に設定すると、すべてが壊れます。
field
をname
に設定すると、名前は sanitize_title_for_query
を使用してサニタイズされます。
$terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $query['terms'] ) ) . "'";
これはスラッシュを取り除き、空のスペースをハイフンに変換します。つまり、Ski-in/Ski-out
はski-inski-out
に変換され、Uit die koskas
はuit-die-koskas
に変換されます。あなたの用語名は無効なので、以下のクエリは用語IDとその子を取得します。
$terms = $wpdb->get_col( "
SELECT $wpdb->term_taxonomy.$resulting_field
FROM $wpdb->term_taxonomy
INNER JOIN $wpdb->terms USING (term_id)
WHERE taxonomy = '{$query['taxonomy']}'
AND $wpdb->terms.{$query['field']} IN ($terms)
" );
失敗し、空の配列を返します
array(0) {
}
私見、ここでの衛生は間違っていて、単一のスペースとスラッシュを可能にするより適切な方法と取り替えられるべきです。用語名を正しく使用できない場合にname
フィールドを使用する目的は何ですか。この公衆衛生は、上記の場合にtax_query
内のname
フィールドの使用を中止します。
すでに述べたように、用語名を使用する必要がある場合の最善の方法は、get_term_by()
を使用して用語からIDを取得し、そのIDをtax_query
で使用するというヘルパー関数を作成することです。
コメント内の@manifestphilのおかげで、 changeset#31346 がこのまさしくクレイジーな過剰サニタイズ問題にあります。これが将来のリリースで修正されることを願います。