元の投稿: 日付選択フィールドを使った日付間のクエリ
私はもともと同じ問題について昨年投稿しましたが、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;
}
カスタムのメタ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',
)
)
);
過度に複雑な日付文字列の計算も、フィルタも必要ありません。
日付と時刻のユーティリティは、日付と時刻のパターンの分離を利用します。 date ()
ユーティリティは、「YYYY-MM-DD」というパターンで日付を再検討します。