WP Crontrol - Version 1.2.3

Version Description

  • Tweaks to i18n and date and args formatting
  • Properly escape the crontrol_message query var (props Julio Potier)
Download this release

Release Info

Developer johnbillion
Plugin Icon 128x128 WP Crontrol
Version 1.2.3
Comparing to
See all releases

Code changes from version 1.2.2 to 1.2.3

Files changed (3) hide show
  1. class-wp-cli.php +16 -4
  2. readme.txt +12 -8
  3. wp-crontrol.php +99 -91
class-wp-cli.php CHANGED
@@ -21,8 +21,14 @@ class Crontrol_Command extends WP_CLI_Command {
21
  *
22
  * @alias list
23
  * @subcommand list-events
 
24
  */
25
- public function list_events() {
 
 
 
 
 
26
 
27
  $events = $this->crontrol->get_cron_events();
28
 
@@ -39,7 +45,7 @@ class Crontrol_Command extends WP_CLI_Command {
39
  'recurrence'
40
  );
41
 
42
- \WP_CLI\Utils\format_items( 'table', $events, $fields );
43
 
44
  }
45
 
@@ -111,8 +117,14 @@ class Crontrol_Command extends WP_CLI_Command {
111
  * @since 1.2
112
  *
113
  * @subcommand list-schedules
 
114
  */
115
- public function list_schedules() {
 
 
 
 
 
116
 
117
  $schedules = $this->crontrol->get_schedules();
118
  $schedules = array_map( array( $this, '_map_schedule' ), $schedules, array_keys( $schedules ) );
@@ -123,7 +135,7 @@ class Crontrol_Command extends WP_CLI_Command {
123
  'interval'
124
  );
125
 
126
- \WP_CLI\Utils\format_items( 'table', $schedules, $fields );
127
 
128
  }
129
 
21
  *
22
  * @alias list
23
  * @subcommand list-events
24
+ * @synopsis [--format=<format>]
25
  */
26
+ public function list_events( $args, $assoc_args ) {
27
+
28
+ $defaults = array(
29
+ 'format' => 'table',
30
+ );
31
+ $values = wp_parse_args( $assoc_args, $defaults );
32
 
33
  $events = $this->crontrol->get_cron_events();
34
 
45
  'recurrence'
46
  );
47
 
48
+ \WP_CLI\Utils\format_items( $values['format'], $events, $fields );
49
 
50
  }
51
 
117
  * @since 1.2
118
  *
119
  * @subcommand list-schedules
120
+ * @synopsis [--format=<format>]
121
  */
122
+ public function list_schedules( $args, $assoc_args ) {
123
+
124
+ $defaults = array(
125
+ 'format' => 'table',
126
+ );
127
+ $values = wp_parse_args( $assoc_args, $defaults );
128
 
129
  $schedules = $this->crontrol->get_schedules();
130
  $schedules = array_map( array( $this, '_map_schedule' ), $schedules, array_keys( $schedules ) );
135
  'interval'
136
  );
137
 
138
+ \WP_CLI\Utils\format_items( $values['format'], $schedules, $fields );
139
 
140
  }
141
 
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: scompt, johnbillion
3
  Tags: admin, cron, plugin, control, wp-cron, crontrol, wp-cli
4
  Requires at least: 3.0
5
- Tested up to: 3.6
6
- Stable tag: 1.2.2
7
 
8
  WP Crontrol lets you view and control what's happening in the WP-Cron system.
9
 
@@ -17,9 +17,9 @@ WP Crontrol lets you view and control what's happening in the WP-Cron system. Fr
17
 
18
  The admin screen will show you a warning message if your cron system doesn't appear to be working (for example if your server can't connect to itself to fire scheduled cron events).
19
 
20
- From the settings screen you can also add, edit and remove cron schedues.
21
 
22
- Now supports [WP-CLI](http://wp-cli.org/)!
23
 
24
  == Installation ==
25
 
@@ -74,10 +74,10 @@ No, you can get rid of the whole directory and just use `wp-crontrol.php` if you
74
  = Which WP-CLI commands are available? =
75
 
76
  * `wp crontrol list-events` Lists the scheduled events on your site.
77
- * `wp crontrol list-schedules` Lists the available WP-Cron schedules on your site.
78
- * `wp crontrol test` Performs a WP-Cron spawning test to make sure WP-Cron can function as expected.
79
  * `wp crontrol run-event <hook>` Runs the next scheduled WP-Cron event for the given hook
80
  * `wp crontrol delete-event <hook>` Deletes the next scheduled WP-Cron event for the given hook
 
 
81
 
82
  Note that WP-CLI support is a work in progress and will be improved over time. Feedback welcome!
83
 
@@ -89,12 +89,16 @@ Note that WP-CLI support is a work in progress and will be improved over time. F
89
  == Upgrade Notice ==
90
 
91
  = 1.2.2 =
92
- * Added `crontrol run-event` and `crontrol delete-event` WP-CLI commands
93
 
94
  == Changelog ==
95
 
 
 
 
 
96
  = 1.2.2 =
97
- * Added `crontrol run-event` and `crontrol delete-event` WP-CLI commands
98
  * Clarify language regarding hooks/entries/events
99
 
100
  = 1.2.1 =
2
  Contributors: scompt, johnbillion
3
  Tags: admin, cron, plugin, control, wp-cron, crontrol, wp-cli
4
  Requires at least: 3.0
5
+ Tested up to: 4.0
6
+ Stable tag: 1.2.3
7
 
8
  WP Crontrol lets you view and control what's happening in the WP-Cron system.
9
 
17
 
18
  The admin screen will show you a warning message if your cron system doesn't appear to be working (for example if your server can't connect to itself to fire scheduled cron events).
19
 
20
+ From the settings screen you can also add, edit and remove cron schedules.
21
 
22
+ WP Crontrol includes commands for [WP-CLI](http://wp-cli.org/). See the FAQ or type `wp help crontrol` for more details.
23
 
24
  == Installation ==
25
 
74
  = Which WP-CLI commands are available? =
75
 
76
  * `wp crontrol list-events` Lists the scheduled events on your site.
 
 
77
  * `wp crontrol run-event <hook>` Runs the next scheduled WP-Cron event for the given hook
78
  * `wp crontrol delete-event <hook>` Deletes the next scheduled WP-Cron event for the given hook
79
+ * `wp crontrol list-schedules` Lists the available WP-Cron schedules on your site.
80
+ * `wp crontrol test` Performs a WP-Cron spawning test to make sure WP-Cron can function as expected.
81
 
82
  Note that WP-CLI support is a work in progress and will be improved over time. Feedback welcome!
83
 
89
  == Upgrade Notice ==
90
 
91
  = 1.2.2 =
92
+ * Added `wp crontrol run-event` and `wp crontrol delete-event` WP-CLI commands
93
 
94
  == Changelog ==
95
 
96
+ = 1.2.3 =
97
+ * Tweaks to i18n and date and args formatting
98
+ * Properly escape the `crontrol_message` query var (props Julio Potier)
99
+
100
  = 1.2.2 =
101
+ * Added `wp crontrol run-event` and `wp crontrol delete-event` WP-CLI commands
102
  * Clarify language regarding hooks/entries/events
103
 
104
  = 1.2.1 =
wp-crontrol.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /*
3
  * Plugin Name: WP Crontrol
4
- * Plugin URI: http://wordpress.org/plugins/wp-crontrol/
5
  * Description: WP Crontrol lets you view and control what's happening in the WP-Cron system.
6
- * Author: <a href="http://www.scompt.com/">Edward Dale</a> & <a href="http://lud.icro.us/">John Blackbourn</a>
7
- * Version: 1.2.2
8
- * Text Domain: crontrol
9
  * Domain Path: /gettext/
10
  */
11
 
@@ -33,7 +33,7 @@
33
  * @author Edward Dale <scompt@scompt.com> & John Blackbourn <john@johnblackbourn.com>
34
  * @copyright Copyright 2013 Edward Dale & John Blackbourn
35
  * @license http://www.gnu.org/licenses/gpl.txt GPL 2.0
36
- * @link http://wordpress.org/plugins/wp-crontrol/
37
  * @since 0.2
38
  */
39
 
@@ -45,17 +45,14 @@ class Crontrol {
45
  * Hook onto all of the actions and filters needed by the plugin.
46
  */
47
  protected function __construct() {
48
- add_action('init', array(&$this, 'action_init'));
49
- add_action('init', array(&$this, 'action_handle_posts'));
50
- add_action('admin_menu', array(&$this, 'action_admin_menu'));
51
 
52
- // Make sure the activation works from subdirectories as well as
53
- // directly in the plugin directory.
54
- $activate_action = str_replace(ABSPATH.PLUGINDIR.'/', 'activate_', __FILE__);
55
- add_action($activate_action, array(&$this, 'action_activate'));
56
 
57
- add_filter('cron_schedules', array(&$this, 'filter_cron_schedules'));
58
- add_action('crontrol_cron_job', array(&$this, 'action_php_cron_event'));
59
  }
60
 
61
  /**
@@ -69,15 +66,15 @@ class Crontrol {
69
  * Run using the 'init' action.
70
  */
71
  function action_init() {
72
- load_plugin_textdomain( 'crontrol', false, dirname( plugin_basename( __FILE__ ) ) . '/gettext' );
73
  }
74
 
75
  /**
76
- * Handles any POSTs made by the plugin. Run using the 'init' action.
77
  */
78
  function action_handle_posts() {
79
  if( isset($_POST['new_cron']) ) {
80
- if( !current_user_can('manage_options') ) die(__('You are not allowed to add new cron events.', 'crontrol'));
81
  check_admin_referer("new-cron");
82
  extract($_POST, EXTR_PREFIX_ALL, 'in');
83
  $in_args = json_decode(stripslashes($in_args),true);
@@ -85,7 +82,7 @@ class Crontrol {
85
  wp_redirect("tools.php?page=crontrol_admin_manage_page&crontrol_message=5&crontrol_name={$in_hookname}");
86
 
87
  } else if( isset($_POST['new_php_cron']) ) {
88
- if( !current_user_can('manage_options') ) die(__('You are not allowed to add new cron events.', 'crontrol'));
89
  check_admin_referer("new-cron");
90
  extract($_POST, EXTR_PREFIX_ALL, 'in');
91
  $args = array('code'=>stripslashes($in_hookcode));
@@ -93,7 +90,7 @@ class Crontrol {
93
  wp_redirect("tools.php?page=crontrol_admin_manage_page&crontrol_message=5&crontrol_name={$in_hookname}");
94
 
95
  } else if( isset($_POST['edit_cron']) ) {
96
- if( !current_user_can('manage_options') ) die(__('You are not allowed to edit cron events.', 'crontrol'));
97
 
98
  extract($_POST, EXTR_PREFIX_ALL, 'in');
99
  check_admin_referer("edit-cron_{$in_original_hookname}_{$in_original_sig}_{$in_original_next_run}");
@@ -103,7 +100,7 @@ class Crontrol {
103
  wp_redirect("tools.php?page=crontrol_admin_manage_page&crontrol_message=4&crontrol_name={$in_hookname}");
104
 
105
  } else if( isset($_POST['edit_php_cron']) ) {
106
- if( !current_user_can('manage_options') ) die(__('You are not allowed to edit cron events.', 'crontrol'));
107
 
108
  extract($_POST, EXTR_PREFIX_ALL, 'in');
109
  check_admin_referer("edit-cron_{$in_original_hookname}_{$in_original_sig}_{$in_original_next_run}");
@@ -114,7 +111,7 @@ class Crontrol {
114
  wp_redirect("tools.php?page=crontrol_admin_manage_page&crontrol_message=4&crontrol_name={$in_hookname}");
115
 
116
  } else if( isset($_POST['new_schedule']) ) {
117
- if( !current_user_can('manage_options') ) die(__('You are not allowed to add new cron schedules.', 'crontrol'));
118
  check_admin_referer("new-sched");
119
  $name = $_POST['internal_name'];
120
  $interval = $_POST['interval'];
@@ -139,14 +136,14 @@ class Crontrol {
139
  wp_redirect("options-general.php?page=crontrol_admin_options_page&crontrol_message=3&crontrol_name=$name");
140
 
141
  } else if( isset($_GET['action']) && $_GET['action']=='delete-sched') {
142
- if( !current_user_can('manage_options') ) die(__('You are not allowed to delete cron schedules.', 'crontrol'));
143
  $id = $_GET['id'];
144
  check_admin_referer("delete-sched_{$id}");
145
  $this->delete_schedule($id);
146
  wp_redirect("options-general.php?page=crontrol_admin_options_page&crontrol_message=2&crontrol_name=$id");
147
 
148
  } else if( isset($_GET['action']) && $_GET['action']=='delete-cron') {
149
- if( !current_user_can('manage_options') ) die(__('You are not allowed to delete cron events.', 'crontrol'));
150
  $id = $_GET['id'];
151
  $sig = $_GET['sig'];
152
  $next_run = $_GET['next_run'];
@@ -158,7 +155,7 @@ class Crontrol {
158
  };
159
 
160
  } else if( isset($_GET['action']) && $_GET['action']=='run-cron') {
161
- if( !current_user_can('manage_options') ) die(__('You are not allowed to run cron events.', 'crontrol'));
162
  $id = $_GET['id'];
163
  $sig = $_GET['sig'];
164
  check_admin_referer("run-cron_{$id}_{$sig}");
@@ -255,7 +252,7 @@ class Crontrol {
255
  * Run using the 'activate_' action.
256
  */
257
  function action_activate() {
258
- $extra_scheds = array('twicedaily'=>array('interval'=>43200, 'display'=>__('Twice Daily', 'crontrol')));
259
  add_option('crontrol_schedules', $extra_scheds);
260
 
261
  // if there's never been a cron event, _get_cron_array will return FALSE
@@ -270,8 +267,8 @@ class Crontrol {
270
  * Run using the 'admin_menu' action.
271
  */
272
  function action_admin_menu() {
273
- $page = add_options_page('Cron Schedules', 'Cron Schedules', 'manage_options', 'crontrol_admin_options_page', array(&$this, 'admin_options_page') );
274
- $page = add_management_page('Crontrol', "Crontrol", 'manage_options', 'crontrol_admin_manage_page', array(&$this, 'admin_manage_page') );
275
  }
276
 
277
  /**
@@ -279,7 +276,7 @@ class Crontrol {
279
  *
280
  * Called by the 'cron_schedules' filter.
281
  *
282
- * @param array $scheds The current cron schedules. Usually an empty array.
283
  * @return array The existing cron schedules along with the plugin's schedules.
284
  */
285
  function filter_cron_schedules($scheds) {
@@ -296,11 +293,13 @@ class Crontrol {
296
  $custom_keys = array_keys($custom_schedules);
297
 
298
  if( isset($_GET['crontrol_message']) ) {
299
- $messages = array( '2' => __("Successfully deleted the cron schedule <b>%s</b>", 'crontrol'),
300
- '3' => __("Successfully added the cron schedule <b>%s</b>", 'crontrol'),
301
- '7' => __("Cron schedule not added because there was a problem parsing <b>%s</b>", 'crontrol'));
302
- $hook = $_GET['crontrol_name'];
303
- $msg = sprintf($messages[$_GET['crontrol_message']], $hook);
 
 
304
 
305
  echo "<div id=\"message\" class=\"updated fade\"><p>$msg</p></div>";
306
  }
@@ -309,14 +308,14 @@ class Crontrol {
309
  <div class="wrap">
310
  <?php screen_icon(); ?>
311
  <h2><?php _e("Cron Schedules", "crontrol"); ?></h2>
312
- <p><?php _e('Cron schedules are the time intervals that are available to WordPress and plugin developers to schedule events. You can only delete cron schedules that you have created with WP Crontrol.', 'crontrol'); ?></p>
313
  <div id="ajax-response"></div>
314
  <table class="widefat">
315
  <thead>
316
  <tr>
317
- <th><?php _e('Name', 'crontrol'); ?></th>
318
- <th><?php _e('Interval', 'crontrol'); ?></th>
319
- <th><?php _e('Display Name', 'crontrol'); ?></th>
320
  <th>&nbsp;</th>
321
  </tr>
322
  </thead>
@@ -324,7 +323,7 @@ class Crontrol {
324
  <?php
325
  if( empty($schedules) ) {
326
  ?>
327
- <tr colspan="4"><td><?php _e('You currently have no cron schedules. Add one below!', 'crontrol') ?></td></tr>
328
  <?php
329
  } else {
330
  $class = "";
@@ -348,25 +347,25 @@ class Crontrol {
348
  </div>
349
  <div class="wrap narrow">
350
  <?php screen_icon(); ?>
351
- <h2><?php _e('Add new cron schedule', 'crontrol'); ?></h2>
352
- <p><?php _e('Adding a new cron schedule will allow you to schedule events that re-occur at the given interval.', 'crontrol'); ?></p>
353
  <form method="post" action="options-general.php?page=crontrol_admin_options_page">
354
  <table width="100%" cellspacing="2" cellpadding="5" class="editform form-table">
355
  <tbody>
356
  <tr>
357
- <th width="33%" valign="top" scope="row"><label for="cron_internal_name"><?php _e('Internal name', 'crontrol'); ?>:</label></th>
358
  <td width="67%"><input type="text" size="40" value="" id="cron_internal_name" name="internal_name"/></td>
359
  </tr>
360
  <tr>
361
- <th width="33%" valign="top" scope="row"><label for="cron_interval"><?php _e('Interval (seconds)', 'crontrol'); ?>:</label></th>
362
  <td width="67%"><input type="text" size="40" value="" id="cron_interval" name="interval"/></td>
363
  </tr>
364
  <tr>
365
- <th width="33%" valign="top" scope="row"><label for="cron_display_name"><?php _e('Display name', 'crontrol'); ?>:</label></th>
366
  <td width="67%"><input type="text" size="40" value="" id="cron_display_name" name="display_name"/></td>
367
  </tr>
368
  </tbody></table>
369
- <p class="submit"><input id="schedadd-submit" type="submit" class="button-primary" value="<?php _e('Add Cron Schedule &raquo;', 'crontrol'); ?>" name="new_schedule"/></p>
370
  <?php wp_nonce_field('new-sched') ?>
371
  </form>
372
  </div>
@@ -391,7 +390,7 @@ class Crontrol {
391
  $schedules = $this->get_schedules();
392
  ?>
393
  <select class="postform" name="schedule">
394
- <option <?php selected($current, '_oneoff') ?> value="_oneoff"><?php _e('Non-repeating', 'crontrol') ?></option>
395
  <?php foreach( $schedules as $sched_name=>$sched_data ) { ?>
396
  <option <?php selected($current, $sched_name) ?> value="<?php echo $sched_name ?>">
397
  <?php echo $sched_data['display'] ?> (<?php echo $this->interval($sched_data['interval']) ?>)
@@ -451,7 +450,7 @@ class Crontrol {
451
  if ( is_wp_error( $status ) ) {
452
  ?>
453
  <div id="cron-status-error" class="error">
454
- <p><?php printf( __( 'There was a problem spawning a call to the WP-Cron system on your site. This means WP-Cron jobs on your site may not work. The problem was:<br /><strong>%s</strong>', 'crontrol' ), esc_html( $status->get_error_message() ) ); ?></p>
455
  </div>
456
  <?php
457
  }
@@ -466,11 +465,16 @@ class Crontrol {
466
  */
467
  function show_cron_form($is_php, $existing) {
468
  if( $is_php ) {
469
- $helper_text = __('Cron events trigger actions in your code. Using the form below, you can enter the schedule of the action, as well as the PHP code for the action itself. Alternatively, the schedule can be specified from within WordPress and the code for the action in a file on on your server using <a href="tools.php?page=crontrol_admin_manage_page&action=new-cron#crontrol_form">this form</a>.', 'crontrol');
470
- $link = ' (<a href="tools.php?page=crontrol_admin_manage_page#crontrol_form">'. __('Add new event', 'crontrol') .'</a>)';
 
 
471
  } else {
472
- $helper_text = __('Cron events trigger actions in your code. A cron event added using the form below needs a corresponding action hook somewhere in code, perhaps the <code>functions.php</code> file in your theme. It is also possible to create your action hook from within WordPress using <a href="tools.php?page=crontrol_admin_manage_page&action=new-php-cron#crontrol_form">this form</a>.', 'crontrol');
473
- $link = ' (<a href="tools.php?page=crontrol_admin_manage_page&amp;action=new-php-cron#crontrol_form">'. __('Add new PHP event', 'crontrol') .'</a>)';
 
 
 
474
  }
475
  if( is_array($existing) ) {
476
  $other_fields = wp_nonce_field( "edit-cron_{$existing['hookname']}_{$existing['sig']}_{$existing['next_run']}", "_wpnonce", true, false );
@@ -480,13 +484,13 @@ class Crontrol {
480
  $existing['args'] = $is_php ? $existing['args']['code'] : json_encode($existing['args']);
481
  $existing['next_run'] = date('Y-m-d H:i:s', $existing['next_run']);
482
  $action = $is_php ? 'edit_php_cron' : 'edit_cron';
483
- $button = $is_php ? __('Modify PHP Cron Event', 'crontrol') : __('Modify Cron Event', 'crontrol');
484
  $link = false;
485
  } else {
486
  $other_fields = wp_nonce_field( "new-cron", "_wpnonce", true, false );
487
  $existing = array('hookname'=>'','hookcode'=>'','args'=>'','next_run'=>'now','schedule'=>false);
488
  $action = $is_php ? 'new_php_cron' : 'new_cron';
489
- $button = $is_php ? __('Add PHP Cron Event', 'crontrol') : __('Add Cron Event', 'crontrol');
490
  }
491
  ?>
492
  <div id="crontrol_form" class="wrap narrow">
@@ -498,24 +502,24 @@ class Crontrol {
498
  <table width="100%" cellspacing="2" cellpadding="5" class="editform form-table"><tbody>
499
  <?php if( $is_php ): ?>
500
  <tr>
501
- <th width="33%" valign="top" scope="row"><label for="hookcode"><?php _e('Hook code', 'crontrol'); ?>:</label></th>
502
  <td width="67%"><textarea style="width:95%" class="code" rows="5" name="hookcode"><?php echo esc_textarea( $existing['args'] ); ?></textarea></td>
503
  </tr>
504
  <?php else: ?>
505
  <tr>
506
- <th width="33%" valign="top" scope="row"><label for="hookname"><?php _e('Hook name', 'crontrol'); ?>:</label></th>
507
  <td width="67%"><input type="text" size="40" id="hookname" name="hookname" value="<?php echo esc_attr( $existing['hookname'] ); ?>"/></td>
508
  </tr>
509
  <tr>
510
- <th width="33%" valign="top" scope="row"><label for="args"><?php _e('Arguments', 'crontrol'); ?>:</label><br /><span style="font-size:xx-small"><?php _e('e.g., [], [25], ["asdf"], or ["i","want",25,"cakes"]', 'crontrol') ?></span></th>
511
  <td width="67%"><input type="text" size="40" id="args" name="args" value="<?php echo esc_textarea( $existing['args'] ); ?>"/></td>
512
  </tr>
513
  <?php endif; ?>
514
  <tr>
515
- <th width="33%" valign="top" scope="row"><label for="next_run"><?php _e('Next run (UTC)', 'crontrol'); ?>:</label><br /><span style="font-size:xx-small"><?php _e('e.g., "now", "tomorrow", "+2 days", or "06/04/08 15:27:09"', 'crontrol') ?></th>
516
  <td width="67%"><input type="text" size="40" id="next_run" name="next_run" value="<?php echo esc_attr( $existing['next_run'] ); ?>"/></td>
517
  </tr><tr>
518
- <th valign="top" scope="row"><label for="schedule"><?php _e('Event schedule', 'crontrol'); ?>:</label></th>
519
  <td>
520
  <?php $this->schedules_dropdown($existing['schedule']) ?>
521
  </td>
@@ -535,7 +539,7 @@ class Crontrol {
535
  if ( empty( $crons ) ) {
536
  return new WP_Error(
537
  'no_events',
538
- __( 'You currently have no scheduled cron events.', 'crontrol' )
539
  );
540
  }
541
 
@@ -566,20 +570,22 @@ class Crontrol {
566
  */
567
  function admin_manage_page() {
568
  if( isset($_GET['crontrol_message']) ) {
569
- $messages = array( '1' => __('Successfully executed the cron event <b>%s</b>', 'crontrol'),
570
- '4' => __('Successfully edited the cron event <b>%s</b>', 'crontrol'),
571
- '5' => __('Successfully created the cron event <b>%s</b>', 'crontrol'),
572
- '6' => __('Successfully deleted the cron event <b>%s</b>', 'crontrol'),
573
- '7' => __('Failed to the delete the cron event <b>%s</b>', 'crontrol'),
574
- '8' => __('Failed to the execute the cron event <b>%s</b>', 'crontrol'));
575
- $hook = $_GET['crontrol_name'];
576
- $msg = sprintf($messages[$_GET['crontrol_message']], $hook);
 
 
577
 
578
  echo "<div id=\"message\" class=\"updated fade\"><p>$msg</p></div>";
579
  }
580
  $events = $this->get_cron_events();
581
  $doing_edit = (isset( $_GET['action']) && $_GET['action']=='edit-cron') ? $_GET['id'] : false ;
582
- $time_format = 'Y/m/d H:i:s';
583
 
584
  $tzstring = get_option( 'timezone_string' );
585
  $current_offset = get_option( 'gmt_offset' );
@@ -597,15 +603,15 @@ class Crontrol {
597
  ?>
598
  <div class="wrap">
599
  <?php screen_icon(); ?>
600
- <h2><?php _e('WP-Cron Events', 'crontrol'); ?></h2>
601
  <p></p>
602
  <table class="widefat">
603
  <thead>
604
  <tr>
605
- <th><?php _e('Hook Name', 'crontrol'); ?></th>
606
- <th><?php _e('Arguments', 'crontrol'); ?></th>
607
- <th><?php _e('Next Run', 'crontrol'); ?></th>
608
- <th><?php _e('Recurrence', 'crontrol'); ?></th>
609
  <th colspan="3">&nbsp;</th>
610
  </tr>
611
  </thead>
@@ -629,14 +635,16 @@ class Crontrol {
629
  );
630
  }
631
 
 
 
632
  echo "<tr id=\"cron-{$id}\" class=\"{$class}\">";
633
- echo "<td>".($event->hook=='crontrol_cron_job' ? __('<i>PHP Cron</i>', 'crontrol') : $event->hook)."</td>";
634
- echo "<td>".($event->hook=='crontrol_cron_job' ? __('<i>PHP Code</i>', 'crontrol') : json_encode($event->args))."</td>";
635
  echo "<td>".get_date_from_gmt(date('Y-m-d H:i:s',$event->time),$time_format)." (".$this->time_since(time(), $event->time).")</td>";
636
- echo "<td>".($event->schedule ? $this->interval($event->interval) : __('Non-repeating', 'crontrol'))."</td>";
637
- echo "<td><a class='view' href='tools.php?page=crontrol_admin_manage_page&amp;action=edit-cron&amp;id={$event->hook}&amp;sig={$event->sig}&amp;next_run={$event->time}#crontrol_form'>Edit</a></td>";
638
- echo "<td><a class='view' href='".wp_nonce_url("tools.php?page=crontrol_admin_manage_page&amp;action=run-cron&amp;id={$event->hook}&amp;sig={$event->sig}", "run-cron_{$event->hook}_{$event->sig}")."'>Run Now</a></td>";
639
- echo "<td><a class='delete' href='".wp_nonce_url("tools.php?page=crontrol_admin_manage_page&amp;action=delete-cron&amp;id={$event->hook}&amp;sig={$event->sig}&amp;next_run={$event->time}", "delete-cron_{$event->hook}_{$event->sig}_{$event->time}")."'>Delete</a></td>";
640
  echo "</tr>";
641
  $class = empty($class)?"alternate":"";
642
 
@@ -648,9 +656,9 @@ class Crontrol {
648
 
649
  <div class="tablenav">
650
  <p class="description">
651
- <?php printf(__('Local timezone is <code>%s</code>', 'crontrol'), $tz ); ?>
652
- <span id="utc-time"><?php printf(__('UTC time is <code>%s</code>', 'crontrol'), date_i18n($time_format, false, true)); ?></span>
653
- <span id="local-time"><?php printf(__('Local time is <code>%s</code>', 'crontrol'), date_i18n($time_format)); ?></span>
654
  </p>
655
  </div>
656
 
@@ -678,18 +686,18 @@ class Crontrol {
678
  function interval( $since ) {
679
  // array of time period chunks
680
  $chunks = array(
681
- array(60 * 60 * 24 * 365 , _n_noop('%s year', '%s years', 'crontrol')),
682
- array(60 * 60 * 24 * 30 , _n_noop('%s month', '%s months', 'crontrol')),
683
- array(60 * 60 * 24 * 7, _n_noop('%s week', '%s weeks', 'crontrol')),
684
- array(60 * 60 * 24 , _n_noop('%s day', '%s days', 'crontrol')),
685
- array(60 * 60 , _n_noop('%s hour', '%s hours', 'crontrol')),
686
- array(60 , _n_noop('%s minute', '%s minutes', 'crontrol')),
687
- array( 1 , _n_noop('%s second', '%s seconds', 'crontrol')),
688
  );
689
 
690
 
691
  if( $since <= 0 ) {
692
- return __('now', 'crontrol');
693
  }
694
 
695
  // we only want to output two chunks of time here, eg:
@@ -711,7 +719,7 @@ class Crontrol {
711
  }
712
 
713
  // set output var
714
- $output = sprintf(_n($name[0], $name[1], $count, 'crontrol'), $count);
715
 
716
  // step two: the second chunk
717
  if ($i + 1 < $j)
@@ -722,7 +730,7 @@ class Crontrol {
722
  if (($count2 = floor(($since - ($seconds * $count)) / $seconds2)) != 0)
723
  {
724
  // add to output var
725
- $output .= ' '.sprintf(_n($name2[0], $name2[1], $count2, 'crontrol'), $count2);
726
  }
727
  }
728
 
1
  <?php
2
  /*
3
  * Plugin Name: WP Crontrol
4
+ * Plugin URI: https://wordpress.org/plugins/wp-crontrol/
5
  * Description: WP Crontrol lets you view and control what's happening in the WP-Cron system.
6
+ * Author: <a href="http://www.scompt.com/">Edward Dale</a> & <a href="https://johnblackbourn.com/">John Blackbourn</a>
7
+ * Version: 1.2.3
8
+ * Text Domain: wp-crontrol
9
  * Domain Path: /gettext/
10
  */
11
 
33
  * @author Edward Dale <scompt@scompt.com> & John Blackbourn <john@johnblackbourn.com>
34
  * @copyright Copyright 2013 Edward Dale & John Blackbourn
35
  * @license http://www.gnu.org/licenses/gpl.txt GPL 2.0
36
+ * @link https://wordpress.org/plugins/wp-crontrol/
37
  * @since 0.2
38
  */
39
 
45
  * Hook onto all of the actions and filters needed by the plugin.
46
  */
47
  protected function __construct() {
48
+ add_action('init', array($this, 'action_init'));
49
+ add_action('init', array($this, 'action_handle_posts'));
50
+ add_action('admin_menu', array($this, 'action_admin_menu'));
51
 
52
+ register_activation_hook( __FILE__, array($this, 'action_activate') );
 
 
 
53
 
54
+ add_filter('cron_schedules', array($this, 'filter_cron_schedules'));
55
+ add_action('crontrol_cron_job', array($this, 'action_php_cron_event'));
56
  }
57
 
58
  /**
66
  * Run using the 'init' action.
67
  */
68
  function action_init() {
69
+ load_plugin_textdomain( 'wp-crontrol', false, dirname( plugin_basename( __FILE__ ) ) . '/gettext' );
70
  }
71
 
72
  /**
73
+ * Handles any POSTs made by the plugin. Run using the 'init' action.
74
  */
75
  function action_handle_posts() {
76
  if( isset($_POST['new_cron']) ) {
77
+ if( !current_user_can('manage_options') ) die(__('You are not allowed to add new cron events.', 'wp-crontrol'));
78
  check_admin_referer("new-cron");
79
  extract($_POST, EXTR_PREFIX_ALL, 'in');
80
  $in_args = json_decode(stripslashes($in_args),true);
82
  wp_redirect("tools.php?page=crontrol_admin_manage_page&crontrol_message=5&crontrol_name={$in_hookname}");
83
 
84
  } else if( isset($_POST['new_php_cron']) ) {
85
+ if( !current_user_can('manage_options') ) die(__('You are not allowed to add new cron events.', 'wp-crontrol'));
86
  check_admin_referer("new-cron");
87
  extract($_POST, EXTR_PREFIX_ALL, 'in');
88
  $args = array('code'=>stripslashes($in_hookcode));
90
  wp_redirect("tools.php?page=crontrol_admin_manage_page&crontrol_message=5&crontrol_name={$in_hookname}");
91
 
92
  } else if( isset($_POST['edit_cron']) ) {
93
+ if( !current_user_can('manage_options') ) die(__('You are not allowed to edit cron events.', 'wp-crontrol'));
94
 
95
  extract($_POST, EXTR_PREFIX_ALL, 'in');
96
  check_admin_referer("edit-cron_{$in_original_hookname}_{$in_original_sig}_{$in_original_next_run}");
100
  wp_redirect("tools.php?page=crontrol_admin_manage_page&crontrol_message=4&crontrol_name={$in_hookname}");
101
 
102
  } else if( isset($_POST['edit_php_cron']) ) {
103
+ if( !current_user_can('manage_options') ) die(__('You are not allowed to edit cron events.', 'wp-crontrol'));
104
 
105
  extract($_POST, EXTR_PREFIX_ALL, 'in');
106
  check_admin_referer("edit-cron_{$in_original_hookname}_{$in_original_sig}_{$in_original_next_run}");
111
  wp_redirect("tools.php?page=crontrol_admin_manage_page&crontrol_message=4&crontrol_name={$in_hookname}");
112
 
113
  } else if( isset($_POST['new_schedule']) ) {
114
+ if( !current_user_can('manage_options') ) die(__('You are not allowed to add new cron schedules.', 'wp-crontrol'));
115
  check_admin_referer("new-sched");
116
  $name = $_POST['internal_name'];
117
  $interval = $_POST['interval'];
136
  wp_redirect("options-general.php?page=crontrol_admin_options_page&crontrol_message=3&crontrol_name=$name");
137
 
138
  } else if( isset($_GET['action']) && $_GET['action']=='delete-sched') {
139
+ if( !current_user_can('manage_options') ) die(__('You are not allowed to delete cron schedules.', 'wp-crontrol'));
140
  $id = $_GET['id'];
141
  check_admin_referer("delete-sched_{$id}");
142
  $this->delete_schedule($id);
143
  wp_redirect("options-general.php?page=crontrol_admin_options_page&crontrol_message=2&crontrol_name=$id");
144
 
145
  } else if( isset($_GET['action']) && $_GET['action']=='delete-cron') {
146
+ if( !current_user_can('manage_options') ) die(__('You are not allowed to delete cron events.', 'wp-crontrol'));
147
  $id = $_GET['id'];
148
  $sig = $_GET['sig'];
149
  $next_run = $_GET['next_run'];
155
  };
156
 
157
  } else if( isset($_GET['action']) && $_GET['action']=='run-cron') {
158
+ if( !current_user_can('manage_options') ) die(__('You are not allowed to run cron events.', 'wp-crontrol'));
159
  $id = $_GET['id'];
160
  $sig = $_GET['sig'];
161
  check_admin_referer("run-cron_{$id}_{$sig}");
252
  * Run using the 'activate_' action.
253
  */
254
  function action_activate() {
255
+ $extra_scheds = array('twicedaily'=>array('interval'=>43200, 'display'=>__('Twice Daily', 'wp-crontrol')));
256
  add_option('crontrol_schedules', $extra_scheds);
257
 
258
  // if there's never been a cron event, _get_cron_array will return FALSE
267
  * Run using the 'admin_menu' action.
268
  */
269
  function action_admin_menu() {
270
+ $page = add_options_page('Cron Schedules', 'Cron Schedules', 'manage_options', 'crontrol_admin_options_page', array($this, 'admin_options_page') );
271
+ $page = add_management_page('Crontrol', "Crontrol", 'manage_options', 'crontrol_admin_manage_page', array($this, 'admin_manage_page') );
272
  }
273
 
274
  /**
276
  *
277
  * Called by the 'cron_schedules' filter.
278
  *
279
+ * @param array $scheds The current cron schedules. Usually an empty array.
280
  * @return array The existing cron schedules along with the plugin's schedules.
281
  */
282
  function filter_cron_schedules($scheds) {
293
  $custom_keys = array_keys($custom_schedules);
294
 
295
  if( isset($_GET['crontrol_message']) ) {
296
+ $messages = array(
297
+ '2' => __( 'Successfully deleted the cron schedule %s', 'wp-crontrol' ),
298
+ '3' => __( 'Successfully added the cron schedule %s', 'wp-crontrol' ),
299
+ '7' => __( 'Cron schedule not added because there was a problem parsing %s', 'wp-crontrol' )
300
+ );
301
+ $hook = stripslashes( $_GET['crontrol_name'] );
302
+ $msg = sprintf($messages[$_GET['crontrol_message']], '<strong>' . esc_html( $hook ) . '</strong>' );
303
 
304
  echo "<div id=\"message\" class=\"updated fade\"><p>$msg</p></div>";
305
  }
308
  <div class="wrap">
309
  <?php screen_icon(); ?>
310
  <h2><?php _e("Cron Schedules", "crontrol"); ?></h2>
311
+ <p><?php _e('Cron schedules are the time intervals that are available to WordPress and plugin developers to schedule events. You can only delete cron schedules that you have created with WP Crontrol.', 'wp-crontrol'); ?></p>
312
  <div id="ajax-response"></div>
313
  <table class="widefat">
314
  <thead>
315
  <tr>
316
+ <th><?php _e('Name', 'wp-crontrol'); ?></th>
317
+ <th><?php _e('Interval', 'wp-crontrol'); ?></th>
318
+ <th><?php _e('Display Name', 'wp-crontrol'); ?></th>
319
  <th>&nbsp;</th>
320
  </tr>
321
  </thead>
323
  <?php
324
  if( empty($schedules) ) {
325
  ?>
326
+ <tr colspan="4"><td><?php _e('You currently have no cron schedules. Add one below!', 'wp-crontrol') ?></td></tr>
327
  <?php
328
  } else {
329
  $class = "";
347
  </div>
348
  <div class="wrap narrow">
349
  <?php screen_icon(); ?>
350
+ <h2><?php _e('Add new cron schedule', 'wp-crontrol'); ?></h2>
351
+ <p><?php _e('Adding a new cron schedule will allow you to schedule events that re-occur at the given interval.', 'wp-crontrol'); ?></p>
352
  <form method="post" action="options-general.php?page=crontrol_admin_options_page">
353
  <table width="100%" cellspacing="2" cellpadding="5" class="editform form-table">
354
  <tbody>
355
  <tr>
356
+ <th width="33%" valign="top" scope="row"><label for="cron_internal_name"><?php _e('Internal name', 'wp-crontrol'); ?>:</label></th>
357
  <td width="67%"><input type="text" size="40" value="" id="cron_internal_name" name="internal_name"/></td>
358
  </tr>
359
  <tr>
360
+ <th width="33%" valign="top" scope="row"><label for="cron_interval"><?php _e('Interval (seconds)', 'wp-crontrol'); ?>:</label></th>
361
  <td width="67%"><input type="text" size="40" value="" id="cron_interval" name="interval"/></td>
362
  </tr>
363
  <tr>
364
+ <th width="33%" valign="top" scope="row"><label for="cron_display_name"><?php _e('Display name', 'wp-crontrol'); ?>:</label></th>
365
  <td width="67%"><input type="text" size="40" value="" id="cron_display_name" name="display_name"/></td>
366
  </tr>
367
  </tbody></table>
368
+ <p class="submit"><input id="schedadd-submit" type="submit" class="button-primary" value="<?php _e('Add Cron Schedule &raquo;', 'wp-crontrol'); ?>" name="new_schedule"/></p>
369
  <?php wp_nonce_field('new-sched') ?>
370
  </form>
371
  </div>
390
  $schedules = $this->get_schedules();
391
  ?>
392
  <select class="postform" name="schedule">
393
+ <option <?php selected($current, '_oneoff') ?> value="_oneoff"><?php _e('Non-repeating', 'wp-crontrol') ?></option>
394
  <?php foreach( $schedules as $sched_name=>$sched_data ) { ?>
395
  <option <?php selected($current, $sched_name) ?> value="<?php echo $sched_name ?>">
396
  <?php echo $sched_data['display'] ?> (<?php echo $this->interval($sched_data['interval']) ?>)
450
  if ( is_wp_error( $status ) ) {
451
  ?>
452
  <div id="cron-status-error" class="error">
453
+ <p><?php printf( __( 'There was a problem spawning a call to the WP-Cron system on your site. This means WP-Cron jobs on your site may not work. The problem was: %s', 'wp-crontrol' ), '<br><strong>' . esc_html( $status->get_error_message() ) . '</strong>' ); ?></p>
454
  </div>
455
  <?php
456
  }
465
  */
466
  function show_cron_form($is_php, $existing) {
467
  if( $is_php ) {
468
+ $helper_text = sprintf( __( 'Cron events trigger actions in your code. Using the form below, you can enter the schedule of the action, as well as the PHP code for the action itself. Alternatively, the schedule can be specified from within WordPress and the code for the action in a file on on your server using <a href="%1$s">this form</a>.', 'wp-crontrol' ),
469
+ admin_url( 'tools.php?page=crontrol_admin_manage_page&action=new-cron#crontrol_form' )
470
+ );
471
+ $link = ' (<a href="tools.php?page=crontrol_admin_manage_page#crontrol_form">'. __('Add new event', 'wp-crontrol') .'</a>)';
472
  } else {
473
+ $helper_text = sprintf( __( 'Cron events trigger actions in your code. A cron event added using the form below needs a corresponding action hook somewhere in code, perhaps the %1$s file in your theme. It is also possible to create your action hook from within WordPress using <a href="%2$s">this form</a>.', 'wp-crontrol' ),
474
+ '<code>functions.php</code>',
475
+ admin_url( 'tools.php?page=crontrol_admin_manage_page&action=new-php-cron#crontrol_form' )
476
+ );
477
+ $link = ' (<a href="tools.php?page=crontrol_admin_manage_page&amp;action=new-php-cron#crontrol_form">'. __('Add new PHP event', 'wp-crontrol') .'</a>)';
478
  }
479
  if( is_array($existing) ) {
480
  $other_fields = wp_nonce_field( "edit-cron_{$existing['hookname']}_{$existing['sig']}_{$existing['next_run']}", "_wpnonce", true, false );
484
  $existing['args'] = $is_php ? $existing['args']['code'] : json_encode($existing['args']);
485
  $existing['next_run'] = date('Y-m-d H:i:s', $existing['next_run']);
486
  $action = $is_php ? 'edit_php_cron' : 'edit_cron';
487
+ $button = $is_php ? __('Modify PHP Cron Event', 'wp-crontrol') : __('Modify Cron Event', 'wp-crontrol');
488
  $link = false;
489
  } else {
490
  $other_fields = wp_nonce_field( "new-cron", "_wpnonce", true, false );
491
  $existing = array('hookname'=>'','hookcode'=>'','args'=>'','next_run'=>'now','schedule'=>false);
492
  $action = $is_php ? 'new_php_cron' : 'new_cron';
493
+ $button = $is_php ? __('Add PHP Cron Event', 'wp-crontrol') : __('Add Cron Event', 'wp-crontrol');
494
  }
495
  ?>
496
  <div id="crontrol_form" class="wrap narrow">
502
  <table width="100%" cellspacing="2" cellpadding="5" class="editform form-table"><tbody>
503
  <?php if( $is_php ): ?>
504
  <tr>
505
+ <th width="33%" valign="top" scope="row"><label for="hookcode"><?php _e('Hook code', 'wp-crontrol'); ?>:</label></th>
506
  <td width="67%"><textarea style="width:95%" class="code" rows="5" name="hookcode"><?php echo esc_textarea( $existing['args'] ); ?></textarea></td>
507
  </tr>
508
  <?php else: ?>
509
  <tr>
510
+ <th width="33%" valign="top" scope="row"><label for="hookname"><?php _e('Hook name', 'wp-crontrol'); ?>:</label></th>
511
  <td width="67%"><input type="text" size="40" id="hookname" name="hookname" value="<?php echo esc_attr( $existing['hookname'] ); ?>"/></td>
512
  </tr>
513
  <tr>
514
+ <th width="33%" valign="top" scope="row"><label for="args"><?php _e('Arguments', 'wp-crontrol'); ?>:</label><br /><span style="font-size:xx-small"><?php _e('e.g., [], [25], ["asdf"], or ["i","want",25,"cakes"]', 'wp-crontrol') ?></span></th>
515
  <td width="67%"><input type="text" size="40" id="args" name="args" value="<?php echo esc_textarea( $existing['args'] ); ?>"/></td>
516
  </tr>
517
  <?php endif; ?>
518
  <tr>
519
+ <th width="33%" valign="top" scope="row"><label for="next_run"><?php _e('Next run (UTC)', 'wp-crontrol'); ?>:</label><br /><span style="font-size:xx-small"><?php _e( 'e.g., "now", "tomorrow", "+2 days", or "25-02-2014 15:27:09"', 'wp-crontrol' ) ?></th>
520
  <td width="67%"><input type="text" size="40" id="next_run" name="next_run" value="<?php echo esc_attr( $existing['next_run'] ); ?>"/></td>
521
  </tr><tr>
522
+ <th valign="top" scope="row"><label for="schedule"><?php _e('Event schedule', 'wp-crontrol'); ?>:</label></th>
523
  <td>
524
  <?php $this->schedules_dropdown($existing['schedule']) ?>
525
  </td>
539
  if ( empty( $crons ) ) {
540
  return new WP_Error(
541
  'no_events',
542
+ __( 'You currently have no scheduled cron events.', 'wp-crontrol' )
543
  );
544
  }
545
 
570
  */
571
  function admin_manage_page() {
572
  if( isset($_GET['crontrol_message']) ) {
573
+ $messages = array(
574
+ '1' => __( 'Successfully executed the cron event %s', 'wp-crontrol' ),
575
+ '4' => __( 'Successfully edited the cron event %s', 'wp-crontrol' ),
576
+ '5' => __( 'Successfully created the cron event %s', 'wp-crontrol' ),
577
+ '6' => __( 'Successfully deleted the cron event %s', 'wp-crontrol' ),
578
+ '7' => __( 'Failed to the delete the cron event %s', 'wp-crontrol' ),
579
+ '8' => __( 'Failed to the execute the cron event %s', 'wp-crontrol ')
580
+ );
581
+ $hook = stripslashes( $_GET['crontrol_name'] );
582
+ $msg = sprintf($messages[$_GET['crontrol_message']], '<strong>' . esc_html( $hook ) . '</strong>' );
583
 
584
  echo "<div id=\"message\" class=\"updated fade\"><p>$msg</p></div>";
585
  }
586
  $events = $this->get_cron_events();
587
  $doing_edit = (isset( $_GET['action']) && $_GET['action']=='edit-cron') ? $_GET['id'] : false ;
588
+ $time_format = 'Y-m-d H:i:s';
589
 
590
  $tzstring = get_option( 'timezone_string' );
591
  $current_offset = get_option( 'gmt_offset' );
603
  ?>
604
  <div class="wrap">
605
  <?php screen_icon(); ?>
606
+ <h2><?php _e('WP-Cron Events', 'wp-crontrol'); ?></h2>
607
  <p></p>
608
  <table class="widefat">
609
  <thead>
610
  <tr>
611
+ <th><?php _e('Hook Name', 'wp-crontrol'); ?></th>
612
+ <th><?php _e('Arguments', 'wp-crontrol'); ?></th>
613
+ <th><?php _e('Next Run', 'wp-crontrol'); ?></th>
614
+ <th><?php _e('Recurrence', 'wp-crontrol'); ?></th>
615
  <th colspan="3">&nbsp;</th>
616
  </tr>
617
  </thead>
635
  );
636
  }
637
 
638
+ $args = empty( $event->args ) ? '<em>' . __( 'None', 'wp-crontrol' ) . '</em>' : json_encode( $event->args );
639
+
640
  echo "<tr id=\"cron-{$id}\" class=\"{$class}\">";
641
+ echo "<td>".($event->hook=='crontrol_cron_job' ? '<em>' . __( 'PHP Cron', 'wp-crontrol' ) . '</em>' : $event->hook)."</td>";
642
+ echo "<td>".($event->hook=='crontrol_cron_job' ? '<em>' . __( 'PHP Code', 'wp-crontrol' ) . '</em>' : $args )."</td>";
643
  echo "<td>".get_date_from_gmt(date('Y-m-d H:i:s',$event->time),$time_format)." (".$this->time_since(time(), $event->time).")</td>";
644
+ echo "<td>".($event->schedule ? $this->interval($event->interval) : __('Non-repeating', 'wp-crontrol'))."</td>";
645
+ echo "<td><a class='view' href='tools.php?page=crontrol_admin_manage_page&amp;action=edit-cron&amp;id={$event->hook}&amp;sig={$event->sig}&amp;next_run={$event->time}#crontrol_form'>" . __( 'Edit', 'wp-crontrol' ) . "</a></td>";
646
+ echo "<td><a class='view' href='".wp_nonce_url("tools.php?page=crontrol_admin_manage_page&amp;action=run-cron&amp;id={$event->hook}&amp;sig={$event->sig}", "run-cron_{$event->hook}_{$event->sig}")."'>" . __( 'Run Now', 'wp-crontrol' ) . "</a></td>";
647
+ echo "<td><a class='delete' href='".wp_nonce_url("tools.php?page=crontrol_admin_manage_page&amp;action=delete-cron&amp;id={$event->hook}&amp;sig={$event->sig}&amp;next_run={$event->time}", "delete-cron_{$event->hook}_{$event->sig}_{$event->time}")."'>" . __( 'Delete', 'wp-crontrol' ) . "</a></td>";
648
  echo "</tr>";
649
  $class = empty($class)?"alternate":"";
650
 
656
 
657
  <div class="tablenav">
658
  <p class="description">
659
+ <?php printf( __( 'Local timezone is %s', 'wp-crontrol' ), '<code>' . $tz . '</code>' ); ?>
660
+ <span id="utc-time"><?php printf( __( 'UTC time is %s', 'wp-crontrol' ), '<code>' . date_i18n( $time_format, false, true ) . '</code>' ); ?></span>
661
+ <span id="local-time"><?php printf( __( 'Local time is %s', 'wp-crontrol' ), '<code>' . date_i18n( $time_format ) . '</code>' ); ?></span>
662
  </p>
663
  </div>
664
 
686
  function interval( $since ) {
687
  // array of time period chunks
688
  $chunks = array(
689
+ array(60 * 60 * 24 * 365 , _n_noop('%s year', '%s years', 'wp-crontrol')),
690
+ array(60 * 60 * 24 * 30 , _n_noop('%s month', '%s months', 'wp-crontrol')),
691
+ array(60 * 60 * 24 * 7, _n_noop('%s week', '%s weeks', 'wp-crontrol')),
692
+ array(60 * 60 * 24 , _n_noop('%s day', '%s days', 'wp-crontrol')),
693
+ array(60 * 60 , _n_noop('%s hour', '%s hours', 'wp-crontrol')),
694
+ array(60 , _n_noop('%s minute', '%s minutes', 'wp-crontrol')),
695
+ array( 1 , _n_noop('%s second', '%s seconds', 'wp-crontrol')),
696
  );
697
 
698
 
699
  if( $since <= 0 ) {
700
+ return __('now', 'wp-crontrol');
701
  }
702
 
703
  // we only want to output two chunks of time here, eg:
719
  }
720
 
721
  // set output var
722
+ $output = sprintf(_n($name[0], $name[1], $count, 'wp-crontrol'), $count);
723
 
724
  // step two: the second chunk
725
  if ($i + 1 < $j)
730
  if (($count2 = floor(($since - ($seconds * $count)) / $seconds2)) != 0)
731
  {
732
  // add to output var
733
+ $output .= ' '.sprintf(_n($name2[0], $name2[1], $count2, 'wp-crontrol'), $count2);
734
  }
735
  }
736