プラグインなしで人気記事一覧ウィジェット化-WordPress cronで月初めにPVをクリア

2018年2月7日

プラグインなしで人気記事一覧ウィジェット化

プラグインなしで人気記事一覧ウィジェット化ということで、前回はページビューを計測し保存するコードとページビューを取得するコードをfunctions.phpに追加、テンプレート(single.php)にページビューを計測保存するコードを追加した。

今回は、WordPressのwp_schedule_eventをつかって擬似cron的に月初めにページビューをクリアする(0にする)コードを追加する。要するに月間人記事ランキングということになる。そのままPVを累計していってもいいのだが、ランキングが固定してくると面白くないので月間で区切ることにした。

add_actionでイベントmy_hourly_event作成 my_hourly_actionに動作・処理を書く

// イベント作成
add_action('my_hourly_event', 'my_hourly_action');
// イベントの動作処理
function my_hourly_action() {
$args = array('posts_per_page' => -1,'post_type' => array('post','page'));
$the_query = new WP_Query($args);
$count_key = 'post_views_count';
delete_post_meta_by_key('post_views_count');
if ($the_query->have_posts()) : while ($the_query->have_posts()) : $the_query->the_post();
$post_id = $the_query->post->ID;
$count = get_post_meta($post_id, $count_key, true);
if(empty($count)){
$count = 0;
delete_post_meta($post_id, $count_key);
add_post_meta($post_id, $count_key, '0');               
}else{
$count++;
update_post_meta($post_id, $count_key, 0);
}
endwhile;endif;
}

2行目でイベント名my_hourly_eventというイベントを作成し、my_hourly_eventではmy_hourly_actionという動作処理を行いますよと指定している。

4行目からはmy_hourly_actionは実際どのような処理・動作をするのか書いている。5行目のposts_per_page' => -1,は投稿記事を全取得している。

WP_Queryサブループで、全記事のカスタムーフィールドpost_views_countの値を0に処理を行っている。post_views_countが無かった場合も結局は0という値になる。

Nextmonthというイベント発生までの時間(秒数)を追加

add_filter('cron_schedules', 'my_interval' );
function my_interval($schedules) {
date_default_timezone_set( 'Asia/Tokyo' );
$dt = new DateTime('now');
$dt_2 = new DateTime('midnight first day of next month');
$d = $dt_2->diff($dt, true);
$dt_array = get_object_vars($d);
$day = $dt_array["d"] * 24 * 60 * 60;
$hour = $dt_array["h"] * 60 * 60;
$minutes = $dt_array["i"] * 60;
$second = $dt_array["s"];
$difftime = $day + $hour + $minutes + $second + 60;
$schedules['Nextmonth'] = array(
'interval' => $difftime,
'display' => 'Nextmonth'
);
return $schedules;
}

説明がややこしいが、現在時間と次の月の午前0時0分までの時間差(秒数)プラス60秒をNextmonthとして返しますよということ。Nextmonthと聞いたら、$difftime秒と答える(説明が変だな)

なんでプラス60秒なのかというと、何らかの理由でタイムラグが発生して月末日の23:59などにイベントが実行されるのを防ぐために、翌月になって60秒と設定している。

イベント my_hourly_eventを登録 wp_schedule_event

// イベントが登録されてなかったら登録する
function my_activation() {
if(!wp_next_scheduled('my_hourly_event')){
wp_schedule_event(time(), 'Nextmonth', 'my_hourly_event');
}
}
add_action('wp', 'my_activation');

WordPressの擬似cron・スケジュールに、my_hourly_eventが登録されてなかったら、wp_schedule_eventを使ってNextmonthのインターバルで登録してねといった感じ。

イベントを削除

// イベント排除
register_deactivation_hook(__FILE__, 'my_deactivation');
function my_deactivation() {
wp_clear_scheduled_hook('my_hourly_event');
}

ここがよくわからない。登録したイベントをなぜ削除するんだろうか・・・まあいいか、上の4つをfunctions.phpに貼り付ける。月初めの午前0時0分プラス60秒以降でサイトにアクセス(管理画面も含む)があった時に、全ての投稿のページビューが0にリセットされる。アクセスがないとずっとページビュー0ということ。

イベント my_hourly_event が登録されてるか確認 WP Crontrol

イベント my_hourly_event が登録されてるか確認 WP Crontrol
イベント my_hourly_event が登録されてるか確認 WP Crontrol

イベント my_hourly_event がちゃんと登録されているかどうかは、プラグイン WP Crontrol で確認した。次の実行は3月1日となっている。時間が8時51分となってるのが気がかりだけどまあ気にしないでおこう。

以上、WordPress cronで月初めにPVをクリアする手順でした。ここまでの2回で下準備は終了。次3回目は人気記事ランキングウィジェットを表示させる備忘録。全記事での人気記事ウィジェットをサイドバーに、投稿ページにはその記事が属するカテゴリー内での人気記事をページ内に表示させるようにウィジェット化する。