web-dev-qa-db-ja.com

WP Cron - 次の3時間の特定の時間に15分ごとにCronを実行します

WordPressでは、特定の時間(午後6時)に自分の関数(フック)を実行し、その後15分後(6時15分)に再実行し、15分ごとに実行し続けるイベントをスケジュールします。 3時間(午後9時まで)その後、それは死にます。

// I have the following code which run after every 6 hours
function myprefix_custom_cron_schedule( $schedules ) {
    $schedules['every_six_hours'] = array(
        'interval' => 21600, // Every 6 hours
        'display'  => __( 'Every 6 hours' ),
    );
    return $schedules;
}
add_filter( 'cron_schedules', 'myprefix_custom_cron_schedule' );

// Schedule an action if it's not already scheduled
if ( ! wp_next_scheduled( 'myprefix_cron_hook' ) ) {
    wp_schedule_event( time(), 'every_six_hours', 'myprefix_cron_hook' );
}

// Hook into that action that'll fire every six hours
add_action( 'myprefix_cron_hook', 'myprefix_cron_function' );

// create your function, that runs on cron
function myprefix_cron_function() {
    // your function...
}
3
Thomas

セットアップWordPress Cronイベント

午後6時にcronを開始し、午後9時まで15分ごとに(3時間)cronを実行し続けたいとします。その後、すべてのcronが停止します。

注:実装を簡単にするため、CODEのすべてのタイムエントリはGMT/UTCと見なされます。

そのためには、2つのcronイベントをスケジュールする必要があります。1つは午後6時に開始され、午後6時から15分ごとに実行を続けます。もう1つは、午後9時に実行される1回限りのcronイベントです。これは他のcronを停止します。

プラグインCODEは次のようになります。

<?php
/*
Plugin Name:  WPSE Custom Cron
Plugin URI:   https://wordpress.stackexchange.com/a/309973/110572
Description:  Custom Cron Plugin
Version:      1.0.0
Author:       Fayaz Ahmed
Author URI:   https://www.fayazmiraz.com/
*/

add_action( 'wpse_custom_cron_event',        'wpse_custom_cron' );
add_action( 'wpse_custom_cron_event_stop',   'wpse_custom_cron_stop' );

function wpse_custom_cron() {
    // Your Custom Cron CODE HERE
}

function wpse_custom_cron_start() {
    // Calculate the start time: e.g. whenever the next 6:00PM (UTC) is.
    $cron_start_time = strtotime( "today 6:00pm" );
    // If 6PM has already passed today, set it to 6PM next day
    if( $cron_start_time < time() ) {
        $cron_start_time = $cron_start_time + 24 * HOUR_IN_SECONDS;
    }

    if ( ! wp_next_scheduled( 'wpse_custom_cron_event' ) ) {
        wp_schedule_event( $cron_start_time, 'fifteen_minutes', 'wpse_custom_cron_event' );
    }

    if ( ! wp_next_scheduled( 'wpse_custom_cron_event_stop' ) ) {
        // this 1 time cron will stop the original cron 'wpse_custom_cron_event' after 3 hours of starting 
        $cron_stop_time = $cron_start_time + 3 * HOUR_IN_SECONDS;
        wp_schedule_single_event( $cron_stop_time, 'wpse_custom_cron_event_stop' );
    }
}

function wpse_custom_cron_stop() {
    // removing all possible custom cron events named 'wpse_custom_cron_event'
    while( false !== wp_unschedule_event( wp_next_scheduled( 'wpse_custom_cron_event' ), 'wpse_custom_cron_event' ) ) {}
}

// Add a 15 minutes custom cron schedule
add_filter( 'cron_schedules', 'wpse_custom_cron_schedule' );
function wpse_custom_cron_schedule( $schedules ) {
    $schedules['fifteen_minutes'] = array(
        'interval' => 15 * 60,
        'display'  => esc_html__( 'Every Fifteen Minutes' ),
    );
    return $schedules;
}

// schedule the cron event on plugin activation
register_activation_hook( __FILE__, 'wpse_custom_cron_plugin_activation' );
function wpse_custom_cron_plugin_activation() {
    wpse_custom_cron_start();
}
// remove the cron event on plugin deactivation
register_deactivation_hook( __FILE__, 'wpse_custom_cron_plugin_deactivation' );
function wpse_custom_cron_plugin_deactivation() {
    wpse_custom_cron_stop();

    // in case the stop event didn't run yet
    while( false !== wp_unschedule_event( wp_next_scheduled( 'wpse_custom_cron_event_stop' ), 'wpse_custom_cron_event_stop' ) ) {}
}

このサンプルプラグインはプラグインのアクティブ化でcronを開始しますが、必要に応じて、wpse_custom_cron_start()関数を使用して他の方法(たとえば、管理パネルでボタンクリック)でCODEを編集してcronを開始できます。

また、同じcronを毎日6PM(アクティベーション後1回だけでなく)実行したい場合は、wpse_custom_cron_start()関数のwp_schedule_single_event呼び出しを次のように変更します。

wp_schedule_event( $cron_stop_time, 'daily', 'wpse_custom_cron_event_stop' );

注:引数付きで作成されたイベント/クローン

引数を指定してevent/cronを作成する場合、まったく同じ引数を使用してイベントを停止する必要もあります。

たとえば、次のようなイベントを作成した場合(上記のCODEのwpse_custom_cron_start()関数で):

....
wp_schedule_event( $cron_start_time, 'fifteen_minutes', 'wpse_custom_cron_event', $args1 );
....
wp_schedule_single_event( $cron_stop_time, 'wpse_custom_cron_event_stop', $args2 );

イベントを停止するときは、wp_next_scheduled()関数呼び出しでもまったく同じ引数を使用する必要があります。したがって、停止コードは次のようになります。

....
while( false !== wp_unschedule_event( wp_next_scheduled( 'wpse_custom_cron_event', $args1 ), 'wpse_custom_cron_event' ) ) {}
....
while( false !== wp_unschedule_event( wp_next_scheduled( 'wpse_custom_cron_event_stop', $args2 ), 'wpse_custom_cron_event_stop' ) ) {} 

繰り返しますが、正確に同じ引数である必要があることを忘れないでください。異なるデータ型でも機能しません。たとえば、次のCODEでは、$args1$args2ではなくと同じですが、$args1$args3は同じです:

$args1 = array( 'key' => 1 );
$args2 = array( 'key' => '1' );
$args3 = array( 'key' => 1 );

'1'は文字列であり、1は数値であるためです。

これは重要です。時にはデータベース内の引数をキーと値のペアとして保存しますが、後で再び使用するとデータベースの値が保存されないためです数値はデータベースから取得されたときに文字列に変換されるため、数値であった引数に対して機能します。そのため、wp_next_scheduled()関数に引数を渡すときに、それらを数値に戻す必要があります。

詳細については、ドキュメントを確認してください。

Cronの実行:

WordPress cronを実行する最良の方法は、wp-config.phpファイルでdefine('DISABLE_WP_CRON', true);を設定し、次に説明するようにシステムcrontabからcronを実行することです この投稿で

外部cronサービスを使用します。

Crontabを設定できない場合は、 cron-job.org などの外部cronサービスを使用し、それに応じてcronを設定できます。

たとえば、上記のcronイベントの場合、次のような設定で単一のcronジョブを設定できます。

cron-job.org settings

ここでは、Days of MonthDays of Week、およびMonthsのすべての値が選択されています。およびHours18, 19, 20に選択され、Minutes0, 15, 30, 45に選択されました。つまり、cronを毎日午後6時から午後9時まで(GTMはアカウント設定からタイムゾーンとして設定されます)0、15、30、および45分(つまり15分間隔)に実行します。

Cronチェック+手動cron:

WP Control pluginを使用して、cronが適切にスケジュールされているかどうかを確認できます。このプラグインは、カスタムcronイベントと間隔を設定するためにも使用できます。

4
Fayaz

そのためには、15分ごとに実行されるクーロンを用意してから、治療を行う時間か待機する時間かをテストすることをお勧めします。

あなたはそのようなことを試すことができます:

const ACTIVE_PERIOD = 3 * HOUR_IN_SECONDS;
const WAITING_PERIOD = 6 * HOUR_IN_SECONDS;

const TRANSIENT_STATE = "TestCron__state";
const TRANSIENT_TIMEOUT = "TestCron__timeout";


add_action("TestCron/cron/execution", function () {


    $state = get_transient(TRANSIENT_STATE);

    if (FALSE === $state) {
        set_transient(TRANSIENT_STATE, "waiting");
        set_transient(TRANSIENT_TIMEOUT, time() + WAITING_PERIOD);
    }


    if (get_transient(TRANSIENT_TIMEOUT) < time()) { // state change

        if ("waiting" === get_transient(TRANSIENT_STATE)) {
            set_transient(TRANSIENT_STATE, "active");
            set_transient(TRANSIENT_TIMEOUT, time() + ACTIVE_PERIOD);
        } else {
            set_transient(TRANSIENT_STATE, "waiting");
            set_transient(TRANSIENT_TIMEOUT, time() + WAITING_PERIOD);
        }

    }


    if ("waiting" === get_transient(TRANSIENT_STATE)) {
        // continue to sleep
        return;
    }


    // here actions to do
    do_action("myprefix_cron_hook");



});


add_action("wp_loaded", function () {

    if (!wp_next_scheduled("TestCron/cron/execution")) {
        wp_schedule_event(1, "15_minutes", "TestCron/cron/execution");
    }

});


add_filter("cron_schedules", function ($cron_schedules) {

    $cron_schedules["15_minutes"] = [
        "display" => "15 minutes",
        "interval" => 15 * MINUTE_IN_SECONDS,
    ];

    return $cron_schedules;

});
0
Kaperto