Practical example 04

指定日時で
表示を切り替える

Date / Timeフィールドに開始日時と終了日時を入力し、テンプレート側で「開始前」「受付中」「終了後」を切り替える実装例です。

01

この実装でできること

  • 開始前は「年月日(曜日) 何時から受付を開始します」と表示する。
  • 受付中は「年月日(曜日) 何時まで受付ています」と表示し、フォームやボタンを出す。
  • 終了後は「年月日(曜日) 何時に受付を終了しました」に切り替える。
利用する仕組み

日時の保存は既存の Date / Time フィールドを使い、現在時刻との比較はWordPressのタイムゾーン設定を使って行います。

02

フィールドを用意する

受付やイベントを管理する投稿タイプに、次のフィールドを追加します。終了日時を使わない場合は、終了用の2項目は省略できます。

reception_start_date
Date/受付開始日
reception_start_time
Time/受付開始時刻
reception_end_date
Date/受付終了日
reception_end_time
Time/受付終了時刻

日付だけで運用したい場合も、締切時刻を明示できるように Time フィールドを分けておくと運用ミスが少なくなります。

03

日時判定用の関数を追加する

テーマの functions.php またはサイト専用プラグインへ追加します。フィールド値は CFS()->get() で取得し、WordPressの「設定 → 一般 → タイムゾーン」に合わせて比較します。

functions.php

PHP / Schedule
<?php
function my_cfs_datetime_timestamp( $date_field, $time_field, $post_id = null ) {
  $date = CFS()->get( $date_field, $post_id, array( 'format' => 'raw' ) );
  $time = CFS()->get( $time_field, $post_id, array( 'format' => 'raw' ) );

  if ( empty( $date ) || empty( $time ) ) {
    return null;
  }

  $datetime = DateTimeImmutable::createFromFormat(
    'Y-m-d H:i',
    $date . ' ' . $time,
    wp_timezone()
  );

  if ( ! $datetime ) {
    return null;
  }

  return $datetime->getTimestamp();
}

function my_cfs_datetime_label( $date_field, $time_field, $post_id = null ) {
  $timestamp = my_cfs_datetime_timestamp( $date_field, $time_field, $post_id );

  if ( ! $timestamp ) {
    return '';
  }

  return wp_date( 'Y年n月j日(D) G時i分', $timestamp, wp_timezone() );
}

function my_cfs_schedule_status( $post_id = null ) {
  $now   = ( new DateTimeImmutable( 'now', wp_timezone() ) )->getTimestamp();
  $start = my_cfs_datetime_timestamp(
    'reception_start_date',
    'reception_start_time',
    $post_id
  );
  $end = my_cfs_datetime_timestamp(
    'reception_end_date',
    'reception_end_time',
    $post_id
  );

  if ( $start && $now < $start ) {
    return 'before';
  }

  if ( $end && $now >= $end ) {
    return 'ended';
  }

  return 'active';
}
終了日時を空にすると、開始後はずっと active として扱います。開始日時を空にすると、終了前までは active になります。
04

テンプレートで3状態を出し分ける

投稿テンプレートや固定ページテンプレートで、状態に応じて文言やフォームを切り替えます。表示用の日時は、設定値から Y年n月j日(D) G時i分 形式で作ります。

single-event.php

PHP / Template
<?php
$status = my_cfs_schedule_status( get_the_ID() );
$start_label = my_cfs_datetime_label(
  'reception_start_date',
  'reception_start_time',
  get_the_ID()
);
$end_label = my_cfs_datetime_label(
  'reception_end_date',
  'reception_end_time',
  get_the_ID()
);
?>

<section class="reception-box">
  <?php if ( 'before' === $status ) : ?>
    <p>
      <?php echo esc_html( $start_label ); ?>
      から受付を開始します。
    </p>

  <?php elseif ( 'ended' === $status ) : ?>
    <p>
      <?php echo esc_html( $end_label ); ?>
      に受付を終了しました。
    </p>

  <?php else : ?>
    <p>
      <?php echo esc_html( $end_label ); ?>
      まで受付ています。
    </p>
    <?php echo do_shortcode( '[contact-form-7 id="123" title="受付フォーム"]' ); ?>
  <?php endif; ?>
</section>
CFSのショートコードフィールドと組み合わせる場合

フォーム部分を Shortcode フィールドにしている場合は、echo CFS()->get( 'form_shortcode' ); のように出力できます。ショートコードの編集権限と、表示タイミングの判定は別々に管理できます。

05

よく使う表示パターン

指定日時まで表示する

before のときだけ案内を表示し、開始後は非表示にします。

指定日時後に表示する

active のときだけフォーム、ボタン、ダウンロードリンクなどを表示します。

指定日時から指定日時まで表示する

開始日時と終了日時の両方を入力し、active の期間だけ受付コンテンツを表示します。

終了後の案内を残す

ended のときに受付終了メッセージや次回案内へのリンクを表示します。

06

ページキャッシュを使う場合

この実装はページ表示時に現在時刻を判定します。ページキャッシュやCDNを使っている場合、切り替え時刻を過ぎても古いHTMLが配信されることがあります。

  • 受付ページだけキャッシュ時間を短くする。
  • 開始・終了時刻の直後にキャッシュを削除する運用にする。
  • 厳密な切り替えが必要なフォームは、送信処理側でも受付期間を再チェックする。
重要

フォームを非表示にするだけでは、直接送信を防げません。受付期間外に保存や送信を拒否したい場合は、送信先のPHP側でも同じ日時判定を行ってください。