私はWordPressにカスタム投稿タイプevent
を持っています、そして私は$current_date
を比較して今後のevent
posts
を問い合わせる必要があります。
照会条件は以下のとおりです。
start_date
は常に有効なdate
ですend_date
は、有効なdate
、null
、またはempty
の文字列です。end_date
がdbレコード内の有効なdate
である場合、end_date >= $current_date
を比較します。end_date
がnull
またはempty
の場合、start_date >=$current_date
と比較してください。end_date
がオプションではない場合は、以下のコードを使用して目的の結果を得ることができます。
$args= array();
$args['post_type'] = "event";
$args['meta_query'] = array(
array(
'key' => 'end_date',
'compare' => '>=',
'value' => date("Ymd",$current_date),
)
);
$post_query = new WP_Query();
$posts_list = $post_query->query($args);
私の問題は、上記のコードでオプションのend_date
をどのように処理するかです。
前もって感謝します。
編集:上記のコードとテキストを見やすくするために再フォーマット
これを達成するためにカスタムSQLクエリを作成する必要はありません。バージョン4.1以降、WordPressのクエリクラスは 複雑な/入れ子になったメタクエリをサポートしました だからあなたはこのようなクエリを作成することができます:
$args['meta_query'] = array(
// Use an OR relationship between the query in this array and the one in
// the next array. (AND is the default.)
'relation' => 'OR',
// If an end_date exists, check that it is upcoming.
array(
'key' => 'end_date',
'compare' => '>=',
'value' => date( 'Ymd', $current_date ),
),
// OR!
array(
// A nested set of conditions for when the above condition is false.
array(
// We use another, nested set of conditions, for if the end_date
// value is empty, OR if it is null/not set at all.
'relation' => 'OR',
array(
'key' => 'end_date',
'compare' => '=',
'value' => '',
),
array(
'key' => 'end_date',
'compare' => 'NOT EXISTS',
),
),
// AND, if the start date is upcoming.
array(
'key' => 'start_date',
'compare' => '>=',
'value' => date( 'Ymd', $current_date ),
),
),
);
私はこれをテストしました、そしてそれは完全に動作します。私のPHPUnitテストケース:
/**
* Tests something.
*/
class My_Plugin_Test extends WP_UnitTestCase {
public function test_wpse() {
$current_time = current_time( 'timestamp' );
$current_date = date( 'Ymd', $current_time );
$yesterday_date = date( 'Ymd', strtotime( 'yesterday' ) );
$post_ids = $this->factory->post->create_many( 6 );
$post_with_end_past = $post_ids[0];
$post_with_end_now = $post_ids[1];
$post_empty_end_past = $post_ids[2];
$post_empty_end_now = $post_ids[3];
$post_null_end_past = $post_ids[4];
$post_null_end_now = $post_ids[5];
// This post has an end date in the past.
update_post_meta( $post_with_end_past, 'start_date', $yesterday_date );
update_post_meta( $post_with_end_past, 'end_date', $yesterday_date );
// This post has an end date in the present.
update_post_meta( $post_with_end_now, 'start_date', $yesterday_date );
update_post_meta( $post_with_end_now, 'end_date', $current_date );
// This post has no end date, but a start date in the past.
update_post_meta( $post_empty_end_past, 'start_date', $yesterday_date );
update_post_meta( $post_empty_end_past, 'end_date', '' );
// This post has an empty end date, but the start date is now.
update_post_meta( $post_empty_end_now, 'start_date', $current_date );
update_post_meta( $post_empty_end_now, 'end_date', '' );
// This post has no end date set at all, and the start date is past.
update_post_meta( $post_null_end_past, 'start_date', $yesterday_date );
// This post has no end date set at all, but the start date is now.
update_post_meta( $post_null_end_now, 'start_date', $current_date );
$args = array();
$args['fields'] = 'ids';
$args['meta_query'] = array(
// Use an OR relationship between the query in this array and the one in
// the next array. (AND is the default.)
'relation' => 'OR',
// If an end_date exists, check that it is upcoming.
array(
'key' => 'end_date',
'compare' => '>=',
'value' => $current_date,
),
// OR!
array(
// If an end_date does not exist.
array(
// We use another, nested set of conditions, for if the end_date
// value is empty, OR if it is null/not set at all.
'relation' => 'OR',
array(
'key' => 'end_date',
'compare' => '=',
'value' => '',
),
array(
'key' => 'end_date',
'compare' => 'NOT EXISTS',
),
),
// AND, if the start date is upcoming.
array(
'key' => 'start_date',
'compare' => '>=',
'value' => $current_date,
),
),
);
$post_query = new WP_Query();
$posts_list = $post_query->query( $args );
// Only the "now" posts should be returned.
$this->assertSame(
array( $post_with_end_now, $post_empty_end_now, $post_null_end_now )
, $posts_list
);
}
}
私はあなたが何を経験しているのか知っていると思います...私は最近私が(とりわけ)存在するかもしれないしないかもしれないメタ値を比較していた状況に対処しなければなりませんでした。
私が見つけた解決策は、WHERE IF句を含む非常に狂ったSQl文を含んでいました。
あなたの場合、それはこのように見えるでしょう(下記の説明):
global $wpdb;
// prepare SQL statement
$sql = $wpdb->prepare("
SELECT *
FROM $wpdb->posts
INNER JOIN $wpdb->postmeta
ON $wpdb->posts.ID = $wpdb->postmeta.post_id
WHERE post_type = 'event'
AND post_status = 'publish'
AND IF(
(
SELECT COUNT( post_id)
FROM $wpdb->postmeta
WHERE meta_key = 'end_date'
AND post_id = ID
) > 0,
meta_key = 'end_date',
meta_key = 'start_date'
)
AND meta_value >= %s
LIMIT %d
", date( 'Ymd'), 10 );
// get results
$results = $wpdb->get_results( $sql );
// iterate through results
foreach( $results as $result ) {
setup_postdata( $result );
// your loop
}
(これは同様の設定でテストされていますが、あなたの正確な投稿メタフィールドではテストされていません。ちょっとした調整が必要かもしれません)。
最初に、生のワードプレスデータベースにアクセスするためのグローバルなwpdb
変数を取得します。
それから、投稿を取得し、それらを投稿メタ値と結合するSQLクエリを準備します(比較のために)
しかし。これがトリックです。 WHEREステートメントにはmeta_key
、meta_value
の両方があります。
meta_value
は常に同じ、つまり現在の日付です。
meta_key
では、現在の投稿IDのメタキーが 'end_date'に等しい場合に、投稿メタ行の数を確認するIFステートメントを実行します。
行数が0を超える場合はmeta_key
を 'end_date'(IF関数の2番目の引数)に設定し、それ以外の場合は 'start_date'(3番目の引数)に設定します。
また、投稿の種類を確認し、投稿が公開されていることを確認し、返品を10件(または希望するもの)に制限します。
最後に、結果を取り出して必要に応じて使用します。
ちょっとしたハックを知っていますが、うまくいきます。それはまた少し遅いので、結果をキャッシュする価値があるかもしれません
それがあなたが探しているものであることを願っています!そして、あなたがより良い解決策を見つけたら、私に知らせてください:)
私はあなたの問題に対してこの質問をします。ご確認ください。それがうまくいっているか教えてください。
$global $wpdb;
$qry = "SELECT * from $wpdb->posts t1 WHERE t1.post_type='event' and t1.ID IN (SELECT t2.post_id from $wpdb->postmeta t2 WHERE ( CASE WHEN t2.meta_key = 'end_date' AND t2.meta_value IS NULL THEN t2.meta_key = 'start_date' AND t2.meta_value >= '". $currentdate ."' ELSE t2.meta_key = 'end_date' AND t2.meta_key >= '". $currentdate ."' END ))"
$post_query = new WP_Query();
$posts_list = $post_query->query($qry);
私はここでいくつかの素晴らしい解決策を見ています。しかし、私たちはそれを考え直すことができますか?
これでうまくいくでしょうか...
$args= array();
$args['post_type'] = "event";
$args['meta_query'] = array();
if (!empty($end_date) && strtotime($end_date)) {
$args['meta_query'][] = array(
'key' => 'end_date',
'compare' => '>=',
'value' => date("Ymd",$current_date),
);
} elseif (!empty($start_date) && strtotime($start_date)) {
$args['meta_query'][] = array(
'key' => 'start_date ',
'compare' => '>=',
'value' => date("Ymd",$current_date),
)
}
$post_query = new WP_Query();
$posts_list = $post_query->query($args);
// $startday, $endday - format YYYY-MM-DD and field format: YYYY-MM-DD
$args= array();
$args['post_type'] = "event";
$args['meta_query'] = array(
relation' => 'OR',
array(
'key' => 'end_date',
'value' => array( $startday, $endday ),
'type' => 'DATE',
'compare' => 'BETWEEN'
),
array(
'key' => 'start_date',
'value' => array( $startday, $endday ),
'type' => 'DATE',
'compare' => 'BETWEEN'
)
);
$post_query = new WP_Query();
$posts_list = $post_query->query($args);
おそらくまた私はあなたを理解していませんでした