技術情報

WordPressで日時を指定して予約削除/非公開するための3つの方法

2016.08.24


WordPressでは予約投稿という未来の日時を指定して記事を公開する機能がありますが、予約非公開や予約削除という機能はありません。

ブログを書いている人の立場からすれば、公開は予約しても、非公開は手動で十分という事なのでしょう。しかし、企業やサービスを提供している人がホームページを運営する時は、ある一定期間だけ公開して、あとは見れないようにしたい事があります。例えば・・・

  • 申し込み期限のある入力受付フォーム
  • 期間限定のイベント告知
  • ある期間だけユーザーの行動を計測するABテストのような実験ページ

時間が来た時に手動で非公開にしてもよいのですが、期限が深夜だったり、対応すべきページがたくさんあったりした時にとても大変ですね。

この記事ではまずテーマファイルに少し追加するだけで、予約削除ができるカスタマイズ方法、次にプラグインで解決する方法、さらに、本格的に複雑な動作を指定したい場合にスケジュールを設定する方法の3つの方法を順に説明します。

1. カスタムフィールドで日時を指定して表示切替

まずは簡単に思いつく一番手っ取り早い方法から説明します。カスタムフィールドに非表示にしたい日時を指定して、コンテンツを表示する時に、その日時が過ぎていたら、コンテンツを表示せずに期限が過ぎた旨のメッセージのみを表示します。

カスタムフィールドはデフォルトでは隠れているオプションですが、編集画面で右上の「表示」をクリックすると、チェック項目が表示されます。

blog_20160824_01

こちらをチェックすると、本文の編集ブロックの下に以下のようなブロックが表示されます。こちらにコンテンツを閉じる指定日時をいれます。

blog_20160824_07

キーワード 日時指定
close_time
※ できれば半角英数字で
2016-09-15 00:00:00
※半角数字で日付はハイフンでつなげます 時間はコロンで秒まで入れます。

こちらを入れたら[カスタムフィールドを追加]をクリックし保存。また念のため記事を保存します。

次は表示部分です。直接 個別記事表示のあるテンプレートに書いてみます。先ほどセットしたカスタムフィールドの値はget_post_metaという関数を利用します。

$meta_values = get_post_meta($post_id, $key, $single);

個別記事のコンテンツ表示部分ならsingle.phpを確認するか、固定ページならpage.phpを確認し、the_content()がある部分で以下のように変更します。

if (get_post_meta(get_the_ID(), 'close_time', true) != ''
&& date_i18n('Y-m-d H:i:s') > get_post_meta(get_the_ID(), 'close_time', true)) {
  echo '<p>この記事は表示期限を過ぎました</p>';
} else {
  the_content();
}

とします。すると指定時間を過ぎてからアクセスすると、以下のように表示されます。

期限が過ぎた時の投稿表示

表示しているテンプレートの箇所を見つけるのが面倒と思った方や固定ページでも期日指定を導入したいと思った方はfunctions.phpに以下を追記すればOKです。

function my_close_time_filter($content) {
   if (get_post_meta(get_the_ID(), 'close_time', true) != ''
      && date_i18n('Y-m-d H:i:s') > get_post_meta(get_the_ID(), 'close_time', true)) {
      $content = '<p>この記事は表示期限を過ぎました</p>';
   }
   return $content;
}
add_filter('the_content', 'my_close_time_filter');

これでカスタムフィールドでclose_timeを設定して期限を過ぎたコンテンツはすべて期限切れのメッセージが表示されるようになりました。

実際には投稿の状態を変えてないので、ちょっとタイトル詐欺のような気がしますが、このような方法であれば10分もかからずにできてしまいますので、要望が満たされるのであれば選択肢としてはありだと思います。

ただし、これはコンテンツの表示の時に作用していて新着一覧等にタイトルが表示されるので、いったん詳細ページを表示しなければ、コンテンツが表示できない事がわかりません。やっぱり削除・非表示がよいという場合には次に説明するプラグインを入れるのがよいでしょう。

2.予約削除非公開プラグインを導入する

予約削除・非公開プラグインはいくつかあるのですが、一番使われている Post Expiratorを紹介します。

プラグインの新規追加画面で「Post Expirator」と入力すると以下のが表示されますので、「インストール」をクリックして、有効化します。

blog_20160824_05

インストールが完了したら各投稿編集画面に 「Post Expirator] というブロックが表示されますので、そこで期限を設定します。

Post Expiratorのブロック

「Enable Post Expiration」 をチェックすると期限日時が設定できるようになります。

「How to expire」の項目では指定時間が来た時の動作を設定できます。

指定時間がきた場合に公開状態の記事を以下の状態に変更できます。

Draft 下書き
Delete 削除(ゴミ箱に残る)
private 非公開
Category: Replace カテゴリを付け替える
Category: Add カテゴリをを追加する
Category: Remove カテゴリを外す

注意点として Basic認証がかかっている場合には失敗します。これは予約投稿時でも同じです。
サイト構築中の方は一旦Basic認証を外して試してください。

正しく設定されているかは、 [設定] > 「Post Expirator」の View Debug logs をクリックして、設定した記事がスケジュール
に組み込まれているかを確認します。

blog_20160824_03

これで無事にタイトル通り日時指定で削除、非公開ができるようになりました。カテゴリーが付け替えられるのは便利ですね。例えばイベント開始前一覧のカテゴリと終了のカテゴリを作成して自動的に表示場所を変える事ができます。

このプラグインではレビュー待ち状態は選べません。一旦公開したのであまり必要ないかもしれませんが、レビュー状態にしたかったり、削除した事をメールで通知したり、いろいろと要望が出てくるかもしれません。そんな時は次に説明するwp cronを使った方法を試すとよいでしょう。

3. 再びプラグインを使わないできちんとスケジュールするカスタマイズ方法

Post Expiratorは wp-cronを利用して、スケジュールした時間に動くようになっています。実は1で紹介したカスタムフィールドを利用する方法はお手軽ですが表示する度に日付判定が入ってしまいます。せっかくなのでPost Expireを入れずに1で設定したカスタムフィールドを wp-cronを利用してスケジュールを設定方法に変更してみます。

wp-cronを利用したスケジュールには以下の関数を利用します。

  wp_schedule_single_event( $timestamp, $hook, $args );
  • $timestamp: スケジュールの時刻をGMT(グリニッジ標準時)で入れます
  • $hook: 設定したいイベントの関数名を指定します
  • $args: $hookに渡したい値がある場合に指定します

また記事/固定ページの状態を変えるためにwp_update_postを利用します。

以下の記述で、指定IDの記事が下書きになります。

wp_update_post(array( 'ID' => $id, 'post_status' => 'trash' ) );

post_statusにセットできる文字は投稿ステータス(wpdocs.osdn.jp)から選べます。承認待ちやゴミ箱行のステータスは 「Post Expirator」では選べないので、こちらのカスタマイズ方法を採用する価値は十分にあると思います。

draft 下書き
private 非公開
trash ゴミ箱
pending 承認待ち

また、完全削除をしたい場合は、wp_update_postの代わりにwp_delete_postを利用します。この2つの関数を利用して記事を編集した時にスケジュールをセットできるようにします。functions.phpに以下のコードを入れます。

function my_expire_event($pid) {
   if (get_post_meta($pid, 'close_time', true) != ''
      && date_i18n('Y-m-d H:i:s') < get_post_meta($pid, 'close_time', true)) {
      // 設定されていて未来の日付ならスケジュールをセット
      $time_stamp = strtotime(get_post_meta($pid, 'close_time', true) . ' JST');
      wp_schedule_single_event($time_stamp, 'my_new_event', array($pid));
   }
}

add_action('save_post','my_expire_event');

// スケジュールされる動作を記述
function my_update_post($pid) {
   wp_update_post(array( 'ID' => $pid, 'post_status' => 'trash' ) );
}
add_action('my_new_event', 'my_update_post');

strtotimeを使って現在のタイムスタンプを取得している部分ですが、 スケジュールにセットするのはGMT
でなければなりません。 そこでJSTという日本時間の文字を追加しておくとstrtotimeははGMTに変換してくれます。

これでめでたく、指定の記事を時間通りにゴミ箱に入れる事ができました。

以下は wp controlというプラグインでwordpress のスケジュール管理ができるプラグインで確認した所です。

blog_20160824_04

わかりやすいように簡略化していますが、大きな流れはPost Expireと同じ事をしています。

まとめ

今回の記事では記事の状態を変更するに留めましたが、イベントのスケジュールの仕方がわかると、時間が来た時にタイトルに[公開終了]と追加したり、カスタムフィールドで設定しておいたコンテンツに入れ替える、といった機能の追加もできるので覚えておくとよいでしょう。