2012-09-14 31 views
0

我試圖用動態生成的動作名稱來安排多個事件與WordPress Cron API。 add_action()每次只能添加一個事件,但不能超過一個。在WordPress中爲WP Cron安排多個任意事件

使用名爲Cron View的插件,我可以確認事件已註冊但函數未被調用。我猜測可能是動態生成的動作名稱在下一頁加載中消失,所以WordPress無法找到它們。我不知道。

以下代碼已準備好作爲插件運行並演示該問題。任何建議來解決這個問題,將不勝感激。

<?php 
/* Plugin Name: Sample Cron Scheduler */ 

add_action('admin_menu', 'sample_cron_menu'); 
function sample_cron_menu() { 
    add_options_page(
     'Sample Cron Scheduler', 
     'Sample Cron Scheduler', 
     'manage_options', 
     'sample_cron_scheduler', 
     'sample_cron_scheduler_admin'); 
} 
function sample_cron_scheduler_admin() { 
    ?> 
    <div class="wrap"> 
    <?php 
     // print the saved values 
     echo '<h3>Saved values</h3>'; 
     print_r(get_option('crontest')); 

     // do this ten times, meaning I want to register 10 events 
     $chars = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'); 
     for ($i=1; $i <= 10; $i++) { 

      // generate a random string 
      shuffle($chars); 
      $randomstring = implode($chars); 

      // schedule the next event 
      // wp_schedule_single_event(time(), 'myeventaction'); // <-- this only runs one job 
      add_action(sha1($randomstring),'myevent');    // so I want to add arbitrary multiple events but this doesn't work 
      wp_schedule_single_event(time(), sha1($randomstring));     
     } 
    ?> 
    </div> 
    <?php 
} 

add_action('myeventaction', 'myevent'); 
function myevent() { // this function just adds the current time to the option array 

    $arr = get_option('crontest') ? get_option('crontest') : array(); 
    array_push($arr, date("M d Y H:i:s", time()));  // adds the current time at the end of the array 
    array_splice($arr, 0, count($arr) - 20);   // reduce the number of elements to 20 to make it short 
    update_option('crontest', $arr); 

} 

回答

0

我的猜測是對的。 WordPress不記得在add_action()中傳遞的註冊動作名稱。所以我將它們保存在選項中,並在插件加載並將它們全部傳遞給add_action()時解決它。

<?php 
/* Plugin Name: Sample Cron Scheduler */ 

add_action('admin_menu', 'sample_cron_menu'); 
function sample_cron_menu() { 
    add_options_page(
     'Sample Cron Scheduler', 
     'Sample Cron Scheduler', 
     'manage_options', 
     'sample_cron_scheduler', 
     'sample_cron_scheduler_admin'); 
} 
function sample_cron_scheduler_admin() { 
    ?> 
    <div class="wrap"> 
    <?php 
     // print the saved values 
     echo '<h3>Saved values</h3>'; 
     echo '<h4>Actions</h4>'; 
     print_r(get_option('crontest_actions')); 
     echo '<h4>Jobs</h4>'; 
     print_r(get_option('crontest')); 

     // do this ten times, meaning I want to register 10 events 
     $arr = get_option('crontest_actions') ? get_option('crontest_actions') : array(); 
     $chars = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'); 
     for ($i=1; $i <= 10; $i++) { 

      // generate a random string 
      shuffle($chars); 
      $randomstring = implode($chars); 

      // schedule the next event 
      $actionname = sha1($randomstring); 
      array_push($arr, $actionname); 
      add_action($actionname,'myevent');    // so I want to add arbitrary multiple events but this doesn't work 
      wp_schedule_single_event(time(), $actionname);     
     } 
     update_option('crontest_actions', $arr); 
    ?> 
    </div> 
    <?php 
} 

$actions = get_option('crontest_actions') ? get_option('crontest_actions') : array(); 
foreach($actions as $key => $action) { 
    add_action($action, 'myevent'); 
} 

function myevent() { 

    $arr = get_option('crontest') ? get_option('crontest') : array(); 
    array_push($arr, date("M d Y H:i:s", time()));  // adds the current time at the end of the array 
    array_splice($arr, 0, count($arr) - 20);   // reduce the number of elements to 20 to make it short 
    update_option('crontest', $arr); 

    $actions = get_option('crontest_actions') ? get_option('crontest_actions') : array(); 
    array_splice($actions, 0, 1); // remove the first element 
    update_option('crontest_actions', $actions); 
} 

// use this to reset options 
// $arr = array(); 
// update_option('crontest', $arr); 
// update_option('crontest_actions', $arr);