私はこれで棒で月を求めているかもしれないと思います、しかし:
shows
カスタム投稿タイプ用のフィルタがあります。フィルタはshows
に添付された標準的な分類法を使用しますが、各番組のメタ値であるVenueによって、または各番組に開始日が添付されているので月ごとにフィルタすることもできます。
私が遭遇した問題はいくつかのショーが複数の月にまたがるかもしれないということです。そのため、2014年11月に実行を開始し、12月に終了します。このために、メタ値を次のように格納しています。
startdate => 20141225
enddate => 20141224
理想的には、誰かが2014年12月の番組にフィルタをかけた場合、両方とも12月中に始まる番組、または12月末までの番組を表示します。問題は、venue
meta_valueもrelation => 'AND'
でチェックしているため、[pseudocode]をチェックする方法がわからないことです。 WHERE venue == 'royal-playhouse' AND ((startdate BETWEEN array(20141201, 20141231)) OR (enddate BETWEEN array(20141201, 20141231)))
。
私は渡されたpre_get_posts
引数を修正するために$query
フィルタを使用しています、そしてフィルタと共に使用されるさらに2つのmeta_valueフィールドがあることに注目する価値があります(show type、accessibilityなど)。これが私のコードを簡略化したものです(現在は完全に機能しますが、startdate
に対してのみチェックされます)。
function showDates_orderQuery($query) {
if ($query->is_main_query() && !is_admin() && is_post_type_archive('showdates')) {
$queryVenue = $query->query_vars['venue'];
$queryMonth = $query->query_vars['month'];
$metaQuery = array();
// Venue meta
if ($queryVenue) {
$metaQuery[] = array(
'key' => 'venue',
'value' => array($queryVenue),
'compare' => 'IN',
);
}
// Month meta
if ($queryMonth) {
$monthEpoch = strtotime($queryMonth);
$formattedQueryMonth = date('Ymd', $monthEpoch);
$formattedEndOfQueryMonth = date('Ymt', $monthEpoch);
$metaQuery['relation'] = 'AND'; // Set because we want to check for shows from a venue AND by the given month
$metaQuery[] = array(
'key' => 'startdate',
'value' => array($formattedQueryMonth, $formattedEndOfQueryMonth),
'compare' => 'BETWEEN',
'type' => 'DATE'
);
}
if ($metaQuery) {
$query->set('meta_query', $metaQuery);
}
$query->set('meta_key', 'startdate');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
}
}
add_action('pre_get_posts', 'showDates_orderQuery');
私がこれを達成することができる方法についてのどんな考えでも感謝して受け取られるでしょう。
私は完全な馬鹿なので、私は 基本的に1年以上前に私自身の質問に答えました を完全に忘れてしまったようです。
私はposts_join
フィルタを動作させるのに苦労していました(私は一般的にとにかくINNER JOIN
sに問題があります)ので、代わりにposts_where
フィルタを探しました。これに関する主な問題は、既存の$where
条件以外に引数を渡すことができないということです。この例では、非グローバル変数を使用したいと思いました。
答えは、posts_where
フィルタにインラインの無名Lambda関数を使用することでした。
if ($queryMonth) {
$monthEpoch = strtotime($queryMonth);
$formattedQueryMonth = date('Ymd', $monthEpoch);
$formattedEndOfQueryMonth = date('Ymt', $monthEpoch);
$monthOptions = array(
'monthstart' => $formattedQueryMonth,
'monthend' => $formattedEndOfQueryMonth,
);
$monthFilter = function ($where = '') use ($monthOptions) {
global $wpdb;
$where .= " AND (($wpdb->postmeta.meta_key = 'startdate' AND $wpdb->postmeta.meta_value >= '" . $monthOptions['monthstart'] . "') AND ($wpdb->postmeta.meta_key = 'startdate' AND $wpdb->postmeta.meta_value <= '" . $monthOptions['monthend'] . "')) ";
$where .= " OR (($wpdb->postmeta.meta_key = 'enddate' AND $wpdb->postmeta.meta_value >= '" . $monthOptions['monthstart'] . "') AND ($wpdb->postmeta.meta_key = 'enddate' AND $wpdb->postmeta.meta_value <= '" . $monthOptions['monthend'] . "')) ";
return $where;
};
add_filter('posts_where', $monthFilter);
}
運が良ければ、 今後の4.1のリリース のおかげでこのメソッドは実際には次の数週間で完全に冗長になるはずです ヘッドアップ .
あなたのタイムラインやあなたがEdgeでどれだけ生きたいかに応じて、4.1に導入されるように設定されているいくつかの大きな改善がありました。 Edgeを少し使いたい場合は、4.1ベータ版で開発して起動時にそのリリースに切り替えることができます(見つかった場合は必ずバグレポートを提出してください)。
これはもう少し詳しく説明するmake postへのリンクです: https://make.wordpress.org/core/2014/10/20/update-on-query-improvements -in-4-1 /
そのような方法がないのでそれをする方法を把握できません。そのようなANDとORをmeta_queryと混在させることはできません。クエリシステムは素晴らしいですが、すべてを網羅しているわけではありません。複数のクエリを使用するか、SQLを自分でフィルタリングする必要があります。