web-dev-qa-db-ja.com

関係を持つmeta_queryを使用するWP_Query OR そしてorderby meta_valueは機能しません

私は数時間バグにぶつかっています、そして私のエラーを見つけることができないようです。 WordPressのリレーションタイプ 'OR'にバグがありますか?

$evenements = new WP_Query(array(
    'post_type'     => 'evenements',
    'orderby'       => 'meta_value',
    'meta_key'      => 'startDate',
    'order'         => 'ASC',
    'meta_query'    => array(
        'relation'  => 'OR',
        array(
            'key'       => 'startDate',
            'value'     => date('Ymd'),
            'compare'   => '>=',
        ),
        array(
            'key'       => 'endDate',
            'value'     => date('Ymd'),
            'compare'   => '>=',
        ),
    ),
));

奇妙なのは、私が 'AND'に関連づけた場合、それは意図したとおりに機能するということです。両方の記述が当てはまる場合は、投稿が表示されます。私が 'OR'に関連づけると、すべての投稿が表示され、何らかの理由で注文が正しく機能しません。 「順序」を「ASC」から「DESC」に変更しても、結果の順序は変わりません。

クエリを理解するために、正確に何をしようとしているのか詳細を示します。

進行中または未来のイベントを見せたい。 2つのメタは、イベントの開始日(startDate)とイベントの終了日(endDate)です。

そのため、開始日が今日よりも大きいか等しい場合(今日のイベントが発生しているかどうかを確認するため)、終了日が今日より高いか等しい場合は、投稿を表示します。

2番目の部分(終了日付き)は進行中のイベントが表示されるように作成されます。イベントが1日だけ続く場合、クライアントはstartDateメタデータのみを入力するため、最初の部分(開始日付き)は削除できません。

すべてのプラグインを無効にしてもまだバグが残っていたので、プラグインからのバグを破棄しました。

これが私がecho $evenements->requestならどうなるかです。

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
INNER JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id
INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id)
INNER JOIN wp_postmeta AS mt2 ON (wp_posts.ID = mt2.post_id)
JOIN wp_icl_translations t
  ON wp_posts.ID = t.element_id AND t.element_type = 'post_evenements'
JOIN wp_icl_languages l ON t.language_code=l.code AND l.active=1
WHERE 1=1
AND wp_posts.post_type = 'evenements'
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
AND (
 wp_postmeta.meta_key = 'startDate'
 OR ( mt1.meta_key = 'startDate' AND CAST(mt1.meta_value AS CHAR) >= '20140305' )
 OR ( mt2.meta_key = 'endDate' AND CAST(mt2.meta_value AS CHAR) >= '20140305' )
)
AND t.language_code='fr'
GROUP BY wp_posts.ID
ORDER BY wp_postmeta.meta_value ASC
LIMIT 0, 10
3
Fredy31

問題は、WordPressがメタ値に関係なく、 'startDate'メタキーを持つすべての投稿を取得していることです。

あなたはそれが要求のこの部分を形成することを理解することができます:

...
AND (
 wp_postmeta.meta_key = 'startDate'
 OR ( mt1.meta_key = 'startDate' AND CAST(mt1.meta_value AS CHAR) >= '20140305' )
 OR ( mt2.meta_key = 'endDate' AND CAST(mt2.meta_value AS CHAR) >= '20140305' )
)
...

そのため、投稿にmeta_key 'startDate'がある場合はそれが返されます。

この動作の原因は、'meta_key'引数です。

...
new WP_Query( array(
    'post_type'     => 'evenements',
    'orderby'       => 'meta_value',
    'meta_key'      => 'startDate', // <-- this is the culprit
    ...

ただし、削除すると、メタ値で並べ替えることができなくなります。WordPressがそうであることがあります...(私は英語の用語を知らない、自分で文章を完成させる)。

解決策は、(開始日に関する)メタクエリの最初の部分をプレーン引数(meta_queryの一部ではない)として、2番目の部分(終了日に関する)をmeta_query配列に入れることです。

$evenements = new WP_Query(array(
  'post_type'      => 'evenements',
  'meta_key'       => 'startDate',
  'meta_value'     => date('Ymd'),
  'meta_type'      => 'NUMERIC',
  'meta_compare'   => '>=',
  'orderby'        => 'meta_value',
  'order'          => 'ASC',
  'meta_query'     => array(
    'relation'  => 'OR',
     array (
       'key'     => 'endDate',
       'value'   => date('Ymd'),
       'compare' => '>=',
       'type'    => 'NUMERIC'
     )
  )
));

あなたの設定は私がそれを正確にテストさせるには複雑すぎるので、自分で試して私に知らせてください。

5
gmazzap