web-dev-qa-db-ja.com

Wordpress 4.2.1で日付ピッカーフィルタを使用して日付間のクエリを分割する

元の投稿: 日付選択フィールドを使った日付間のクエリ

私はもともと同じ問題について昨年投稿しましたが、WP v4.2.1へのアップデートで私のフィルタが壊れたようです。まとめると、Eventsカスタム投稿タイプでACFと日付選択プラグインを使用しています。開始日と終了日の間にイベントをクエリしようとしています。私も数ヶ月に及ぶことができるイベントがあります。たとえば、イベントは4月に始まり6月に終わることがあります。そのイベントを4月、5月、6月に表示します。

私はこれがワードプレスのv3.9でフィルタを使って働いていました。私はすべてのWebサイトでワードプレスをアップデートしようとしていますが、v4.2.1にアップデートするとこのフィルタは機能しなくなります。これは、WP 4.2.1をアップデートした後、およびACFを最新バージョンの4にアップデートした後にも発生しました。それ以降、ACF PRO v5.2.3にアップデートしました。

誰もが修正について知っていますか?

これはWP v3.9でうまくいったコードです。

私のイベントウィジェットテンプレート:

<?php
/* Template Name: Events Widget */
$today = date('Ymd');

if (isset($_GET['_m'])) {

    $current_month = str_pad($_GET['_m'], 2, '0', STR_PAD_LEFT);
    $current_day = "01"; // day one
    $current_year = $_GET['_y'];

    $get_last_day = $current_year.$current_month.$current_day;
    $lastday = date("t", strtotime($get_last_day));

    $tempstartday = $current_year.$current_month.$current_day;
    $tempendday = $current_year.$current_month.$lastday;

    $startday = date('Ymd', strtotime($tempstartday));
    $endday = date('Ymd', strtotime($tempendday));

} else {

    $current_month = str_pad(date('m'), 2, '0', STR_PAD_LEFT);
    $current_day = "01"; // day one
    $current_year = date('Y');

    $get_last_day = $current_year.$current_month.$current_day;
    $lastday = date("t", strtotime($get_last_day));

    $tempstartday = $current_year.$current_month.$current_day;
    $tempendday = $current_year.$current_month.$lastday;

    $startday = date('Ymd', strtotime($tempstartday));
    $endday = date('Ymd', strtotime($tempendday));
}

add_filter( 'get_meta_sql', 'get_meta_sql_date', 10, 2 );

$qryevents = array(
    'post_type' => 'events',
    'posts_per_page' => 50,
    'status' => 'published',
    'meta_key' => 'event_start_date',
    'orderby' => 'meta_value',
    'order' => 'ASC',

    // produces meta join and where clauses for the query
    // which will be filtered in functions.php
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'key'     => 'event_start_date',
            'compare' => '>=',
            'value'   => $startday,
            'type' => 'DATE'
        ),
        array(
            'key'     => 'event_end_date',
            'compare' => '<=',
            'value'   => $endday,
            'type' => 'DATE'
        )
    )
);

$loop = new WP_Query( $qryevents );
remove_filter( 'get_meta_sql', 'get_meta_sql_date', 10, 2 );

if ( $loop->have_posts() ) :
while ( $loop->have_posts() ) : $loop->the_post();

// Let's format the dates
$get_start_date = get_field('event_start_date');
$get_end_date = get_field('event_end_date');
$event_start_date = DateTime::createFromFormat('Ymd', $get_start_date);
$event_end_date = DateTime::createFromFormat('Ymd', $get_end_date);
// End of date definitions

// Let's get the event start and end times
$get_start_time = get_field('event_start_time');
$get_end_time = get_field('event_end_time');
// end of times

// Let's get the times of the events now
$specify_event_time = "";

$show_event_times = get_field('specify_event_times');
if($show_event_times){
        foreach($show_event_times as $specify_event_time){
            // Do nothing; this puts the yes value into the varible for us to later on the page.
            // echo $specify_event_time;
        }
}
// End of the specify times


$event_month_spans = get_field('event_month_span');
?>

<div class="<?php echo (++$j % 2 == 0) ? 'full row' : 'full row alt'; ?>">
<p><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></p>
    <?php if($specify_event_time == "yes"): ?>
    <p class="event-date"><a href="<?php the_permalink(); ?>"><?php echo $event_start_date->format('M d, Y'); ?> <?php echo $get_start_time; ?> - <?php echo $event_end_date->format('M d, Y'); ?> <?php echo $get_end_time; ?></a></p>
  <?php else: ?>
    <p class="event-date"><a href="<?php the_permalink(); ?>"><?php echo $event_start_date->format('M d, Y'); ?> - <?php echo $event_end_date->format('M d, Y'); ?></a></p>
  <?php endif; ?>
</div>   

<?php
endwhile;

else:
?>
<p>No scheduled events.</p>
<?php endif; wp_reset_query(); ?>

私のfunctions.phpファイルで、私はこの機能を持っています:

function get_meta_sql_date( $pieces, $queries ) {
    global $wpdb;

    // get start and end date from query
    foreach ( $queries as $q ) {

        if ( !isset( $q['key'] ) ) {
            return $pieces;
        }

        if ( 'event_start_date' === $q['key'] ) {
            $start_date = isset( $q['value'] ) ?  $q['value'] : '';
        }
        if ( 'event_end_date' === $q['key'] ) {
            $end_date = isset( $q['value'] ) ?  $q['value'] : '';
        }
    }

    if ( ( '' === $start_date ) || ( '' === $end_date ) ) {
        return $pieces;
    }

    $query = "";

    // after start date AND before end date
    $_query = " AND (
        ( $wpdb->postmeta.meta_key = 'event_start_date' AND ( CAST($wpdb->postmeta.meta_value AS DATE) >= %s) )
        AND ( mt1.meta_key = 'event_end_date' AND ( CAST(mt1.meta_value AS DATE) <= %s) )
    )";
    $query .= $wpdb->prepare( $_query, $start_date, $end_date );

    // OR before start date AND after end date
    $_query = " OR (
        ( $wpdb->postmeta.meta_key = 'event_start_date' AND ( CAST($wpdb->postmeta.meta_value AS DATE) <= %s) )
        AND ( mt1.meta_key = 'event_end_date' AND ( CAST(mt1.meta_value AS DATE) >= %s) )
    )";
    $query .= $wpdb->prepare( $_query, $start_date, $end_date );

    // OR before start date AND (before end date AND end date after start date)
    $_query = " OR (
        ( $wpdb->postmeta.meta_key = 'event_start_date' AND ( CAST($wpdb->postmeta.meta_value AS DATE) <= %s) )
        AND ( mt1.meta_key = 'event_end_date'
            AND ( CAST(mt1.meta_value AS DATE) <= %s )
            AND ( CAST(mt1.meta_value AS DATE) >= %s )
        )
    )";
    $query .= $wpdb->prepare( $_query, $start_date, $end_date, $start_date );

    // OR after end date AND (after start date AND start date before end date) )
    $_query = "OR (
        ( mt1.meta_key = 'event_end_date' AND ( CAST(mt1.meta_value AS DATE) >= %s ) )
        AND ( $wpdb->postmeta.meta_key = 'event_start_date'
            AND ( CAST($wpdb->postmeta.meta_value AS DATE) >= %s )
            AND ( CAST($wpdb->postmeta.meta_value AS DATE) <= %s )
        )
    )";
    $query .= $wpdb->prepare( $_query, $end_date, $start_date, $end_date );

    $pieces['where'] = $query;

    return $pieces;
}
1
Robbiegod

カスタムのメタSQLフィルタは必要ありません。日付をYmdの形式で格納することの利点は、日付を数値的に扱うことができることです。MySQLは、与えられた「範囲」内のイベントを見つけて昇順/降順にソートできます。

開始日/終了日にACFを使用して、最近別のサイトでこれを行いました。

if ( ! empty( $_GET['_y'] ) )
    $year = absint( $_GET['_y'] );
else
    $year = date( 'Y ');

if ( ! empty( $_GET['_m'] ) && in_array( $month = absint( $_GET['_m'] ), range( 1, 12 ) ) )
    $month = zeroise( $month, 2 );
else
    $month = date( 'm' );

$qryevents = array(
    'post_type'      => 'events',
    'posts_per_page' => 50,
    'post_status'    => 'publish',
    'orderby'        => 'meta_value_num', // Ensure order is numerically based
    'order'          => 'ASC',

    'meta_query'     => array(
        'relation' => 'AND',
        array(
            'key'     => 'event_start_date',
            'compare' => '>=',
            'value'   => "{$year}{$month}01",
            'type'    => 'NUMERIC',
        ),
        array(
            'key'     => 'event_end_date',
            'compare' => '<=',
            'value'   => "{$year}{$month}31", // Doesn't matter if there aren't 31 days in this month, will still work,
            'type'    => 'NUMERIC',
        )
    )
);

過度に複雑な日付文字列の計算も、フィルタも必要ありません。

3
TheDeadMedic

日付と時刻のユーティリティは、日付と時刻のパターンの分離を利用します。 date ()ユーティリティは、「YYYY-MM-DD」というパターンで日付を再検討します。

SQL日付関数Oracle

0
Swati Sharma