ようこそのお運びで、厚く御礼申し上げます。
84日目です。今回は、WordPressのクローン(wp_cron)を使ってみたいと思います。
定期的(1日おきに)に、設定した時間に自動で新しい記事を投稿する。
WordPressには「wp_cron」という「なんちゃってクローン」があります。
(ブラウザでアクセス時間をもとに実行される・正確な指定した時間ではない)
信頼性がないとか、色々言われているのもあるのですが・・・、
コレを使って今回、定期的(1日おき)に記事を追加してみようと思います。
今回の仕様
- ソースコードで実行する時間を設定する
- unix時間ではなく、設定したタイムゾーンで設定できるようにする
※今回は13:00に実行する - 一日おきに、新しい記事を追加する(下書き)
※今回、内容は適当です。 - タスクのゴミはなるべく残さない。
画面の流れ
今回は、設定の画面フローはありません。
設定:処理の実行時間ははソースコードに記載します
登録した時間以降にブラウザでアクセスするとタスク処理が実行されます。
新しい記事が一つで来ました(下書き)
登録されているスケジュールの確認方法
意外と重要なことですね。
データベースのwp_optionsのテーブルの内部にも「cron」で記載していますが、わざわざDBを見るのも面倒くさい人もいるかなと思います。
「WP-Cron Dashboard」というプラグインもあるので、こちらを使えば登録されているスケジュールの一覧を管理画面から参照することができますので、一度使ってみてください。
http://wordpress.org/plugins/wp-cron-dashboard/
今回は、まずはfunctions.phpに書いてみます。
今回は「functions.php」に書く場合と、プラグインファイルに書く場合の2つのコードの書き方を紹介します。
少し書き方が違うので、2種類説明したいと思います。
「wp_cron」を使ってみる
WordPressのクローン「wp_cron」に登録するには「wp_schedule_event()」を使います
WordPress Codex:wp_schedule_event(英語)
使い方はこんな感じです。
//既にタスク「paka3_task_post_hook」が登録されているか検証 //なければタスクを登録する。 if ( ! wp_next_scheduled( 'paka3_task_post_hook' ) ) { wp_schedule_event( $timestamp, 'daily', paka3_task_post_hook ); } //タスクをフックします。 add_action( 'paka3_task_post_hook', 'paka3_task_function' ); function paka3_task_function( ) { //処理の実行 }
wp_schedule_event()
- 第1引数:$timestampは最初に処理を実行する時間です(UNIX時間)
- 第2引数:処理の間隔です。今回はdaily。(hourly, twicedaily,daily)から選択
- 第3引数:処理を実行する関数です
- *第4引数で、値を実行する関数に渡すことができます(array():省略可)
タスクが既に登録されている場合の回避方法
上記のままでも実行は可能ですが、
「WordPress Codex」のサンプルには以下のように設定されています。
//既にタスクがあるか検証・なければタスクを登録する add_action( 'wp', 'prefix_setup_schedule' ); function prefix_setup_schedule(){ if ( ! wp_next_scheduled( 'paka3_task_post_hook' ) ) { wp_schedule_event( timestamp(), 'daily', paka3_task_post_hook ); } } //タスクをアクションフック add_action( 'paka3_task_post_hook', 'paka3_task_post_function' ); function paka3_task_function( ) { //処理の実行 }
wpをアクションフックして、タスクを検証しています。
こちらは関数として整理されているので、視覚的・動作的にわかりやすいかもしれません。
時差の問題を解決しよう。
あくまでもこのタスクは「UNIX時間」(UTC時差なし)です。
なので時差を設定する必要があります。
WordPress内の処理は、基本(UTC)で動いているみたい。
time()とかdate()とか実行しても時差なしで取得されます。
あまりコアな部分はあたりたくないので、時差を計算して設定みることにします。
WordPressのcurrent_time()で、「設定」画面で設定したタイムゾーンの時間が取得できます。
//時差をもとめる(設定されている時間(秒)-UTC(秒)) $p = ( current_time( 'timestamp' ) - time( ) ) / 3600;
タスクを実行する時間を設定する
(今日から)毎日タスクを実行する時間を設定します。
ここでは、毎日13:00に投稿されるようにします。
function prefix_setup_schedule(){ if ( ! wp_next_scheduled( 'paka3_task_post_hook' ) ) { //時差を求める $p = ( current_time( 'timestamp' ) - time( ) ) / 3600; //(今日から)毎日タスクを実行する時間を設定する //管理>設定されたタイムゾーンでの時間を設定する(13:00) $my_time = date( 'Y-m-d 13:00:00', current_time( 'timestamp' ) ); //時差を引いて、UNIX時間(UTC:秒)に合わせる $task_time = strtotime( -1 * $p." hour", strtotime( $my_time ) ); wp_schedule_event( $task_time, 'daily', paka3_task_post_hook ,array(strtotime( $my_time ))); } }
実行する関数をかきます(paka3_task_post_function)。
今回は「新しく記事を追加する」関数を準備し、それに値を渡し呼び出す関数を作成します。
ここのデータ作成処理は今回は適当です。
RSSやTwitterのデータをここで生成しても良いかもしれません。
function paka3_task_post_function() { $i = rand(0,2); $c = array( '今日は元気だよ' , '今日はきついよ' , '今日はねる' ); //処理の実行 $post = array( 'title' => "本日の気分" , 'content' => $c[$i] , ); new_my_post($post, $catID); }
新しく記事を追加する関数について
「新しく記事を追加する」関数は、前々回の使い回しです。
新規に投稿する関数「new_my_post」
function new_my_post($post, $catID ) { $my_post = array( ); $my_post[ 'post_title' ] = $post['title']; $my_post[ 'post_content' ] = $post['content']; $my_post[ 'post_status' ] = 'draft'; //下書き $my_post[ 'post_author' ] = 1; $my_post[ 'post_date' ] = date( 'Y-m-d H:i:s', current_time('timestamp') ); $my_post[ 'post_category' ] = array( $catID ); // データベースに投稿を追加 $res = wp_insert_post( $my_post ); if( $res != 0 ) { return $res; //post_id }else{ return false; } }
*functions.phpに書く場合のコード。
※注意:プラグイン用のコードは、最後に掲載します。
ただしfunctions.phpに書く場合、 このコードを削除時に「タスクの削除処理」を別途用意する必要があるかもしれません。
プラグインファイルにした場合の処理について
今回はプラグインディレクトリに「paka3_task_post/paka3_task_post.php」というディレクトリとファイルを作成しました。
プラグインファイルにする場合、以下の2つの処理が簡単にできます。
- 有効時にタスクの実行
- 削除時にタスクの終了(削除)
プラグインの動作について、こちらの記事を参考にしてください。
プラグイン有効化した時にタスクの実行
時差やスケジュールの登録処理の内容については変わりません。
プラグインを有効にしたとき関数「paka3_plugin_start」が実行されるので、スケジュールの登録はここで全部してしまいます。
//プラグインを有効化したとき if(function_exists('register_activation_hook')) { register_activation_hook (__FILE__, 'paka3_plugin_start'); } function paka3_plugin_start(){ //時差を求める $p = ( current_time( 'timestamp' ) - time( ) ) / 3600; //(今日から)毎日タスクを実行する時間を設定する //管理>設定されたタイムゾーンでの時間を設定する(13:00) $my_time = date( 'Y-m-d 13:00:00', current_time( 'timestamp' ) ); //時差を引いて、UNIX時間(UTC:秒)に合わせる $task_time = strtotime( -1 * $p." hour", strtotime( $my_time ) ); wp_schedule_event( $task_time, 'daily', paka3_task_post_hook ); }
プラグイン停止時にタスクの終了(削除)
プラグインを停止したときに関数「paka3_plugin_stop」が実行されます。
ここでは、登録しているスケジュールを残しておくとゴミになるので「wp_clear_scheduled_hook()」を使ってスケジュールの削除してしまいます。
//プラグインをストップしたとき if(function_exists('register_deactivation_hook')) { register_deactivation_hook (__FILE__, 'paka3_plugin_stop'); } function paka3_plugin_stop(){ wp_clear_scheduled_hook( 'paka3_task_post_hook' ); }
※余談ですが、wp_schedule_eventで第4引数を設定した場合、wp_clear_scheduled_hookでその値を第2引数に設定をしてあげないとスケジュールが消えてくれません。
プラグインファイル用のコード
プラグインファイル用のコードは以下のようになります。
※functions.phpに書いても動きません。
クラス化したものはこちらです。
まとめ
定期的にメールを送信するサンプルはたくさんあるので、今回は定期的に投稿するサンプルを作ってみました。
時間等、サーバーの設定等で動きが変わってくるかもしれませんので、よく検証をして使ってみましょう。