WP Crontrol - Version 1.4

Version Description

Download this release

Release Info

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

Code changes from version 1.3.1 to 1.4

Files changed (3) hide show
  1. languages/wp-crontrol.pot +0 -351
  2. readme.txt +1 -1
  3. wp-crontrol.php +188 -76
languages/wp-crontrol.pot DELETED
@@ -1,351 +0,0 @@
1
- # Copyright (C) 2015 John Blackbourn & Edward Dale
2
- # This file is distributed under the GPL v2 or later.
3
- msgid ""
4
- msgstr ""
5
- "Project-Id-Version: WP Crontrol 1.3\n"
6
- "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-crontrol\n"
7
- "POT-Creation-Date: 2015-10-02 12:38:03+00:00\n"
8
- "MIME-Version: 1.0\n"
9
- "Content-Type: text/plain; charset=utf-8\n"
10
- "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
12
- "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
- "Language-Team: LANGUAGE <LL@li.org>\n"
14
- "X-Generator: grunt-wp-i18n 0.5.3\n"
15
- "X-Poedit-KeywordsList: "
16
- "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
17
- "attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
18
- "Language: en\n"
19
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
20
- "X-Poedit-Country: United States\n"
21
- "X-Poedit-SourceCharset: UTF-8\n"
22
- "X-Poedit-Basepath: ../\n"
23
- "X-Poedit-SearchPath-0: .\n"
24
- "X-Poedit-Bookmarks: \n"
25
- "X-Textdomain-Support: yes\n"
26
-
27
- #: wp-crontrol.php:84
28
- msgid "You are not allowed to add new cron events."
29
- msgstr ""
30
-
31
- #: wp-crontrol.php:98
32
- msgid "You are not allowed to add new PHP cron events."
33
- msgstr ""
34
-
35
- #: wp-crontrol.php:112 wp-crontrol.php:128
36
- msgid "You are not allowed to edit cron events."
37
- msgstr ""
38
-
39
- #: wp-crontrol.php:145
40
- msgid "You are not allowed to add new cron schedules."
41
- msgstr ""
42
-
43
- #: wp-crontrol.php:186
44
- msgid "You are not allowed to delete cron schedules."
45
- msgstr ""
46
-
47
- #: wp-crontrol.php:199
48
- msgid "You are not allowed to delete cron events."
49
- msgstr ""
50
-
51
- #: wp-crontrol.php:224
52
- msgid "You are not allowed to run cron events."
53
- msgstr ""
54
-
55
- #: wp-crontrol.php:347 wp-crontrol.php:360
56
- msgid "Cron Schedules"
57
- msgstr ""
58
-
59
- #: wp-crontrol.php:348 wp-crontrol.php:355
60
- msgid "Cron Events"
61
- msgstr ""
62
-
63
- #: wp-crontrol.php:387
64
- msgid "Successfully deleted the cron schedule %s."
65
- msgstr ""
66
-
67
- #: wp-crontrol.php:388
68
- msgid "Successfully added the cron schedule %s."
69
- msgstr ""
70
-
71
- #: wp-crontrol.php:389
72
- msgid "Cron schedule not added because there was a problem parsing %s."
73
- msgstr ""
74
-
75
- #: wp-crontrol.php:400
76
- msgid "WP-Cron Schedules"
77
- msgstr ""
78
-
79
- #: wp-crontrol.php:401
80
- msgid ""
81
- "WP-Cron schedules are the time intervals that are available for scheduling "
82
- "events. You can only delete custom schedules."
83
- msgstr ""
84
-
85
- #: wp-crontrol.php:406
86
- msgid "Name"
87
- msgstr ""
88
-
89
- #: wp-crontrol.php:407
90
- msgid "Interval"
91
- msgstr ""
92
-
93
- #: wp-crontrol.php:408
94
- msgid "Display Name"
95
- msgstr ""
96
-
97
- #: wp-crontrol.php:416
98
- msgid "You currently have no schedules. Add one below."
99
- msgstr ""
100
-
101
- #: wp-crontrol.php:442 wp-crontrol.php:829
102
- msgid "Delete"
103
- msgstr ""
104
-
105
- #: wp-crontrol.php:455
106
- msgid "Add new cron schedule"
107
- msgstr ""
108
-
109
- #: wp-crontrol.php:456
110
- msgid ""
111
- "Adding a new cron schedule will allow you to schedule events that re-occur "
112
- "at the given interval."
113
- msgstr ""
114
-
115
- #: wp-crontrol.php:461
116
- msgid "Internal name"
117
- msgstr ""
118
-
119
- #: wp-crontrol.php:465
120
- msgid "Interval (seconds)"
121
- msgstr ""
122
-
123
- #: wp-crontrol.php:469
124
- msgid "Display name"
125
- msgstr ""
126
-
127
- #: wp-crontrol.php:473
128
- msgid "Add Cron Schedule"
129
- msgstr ""
130
-
131
- #: wp-crontrol.php:498 wp-crontrol.php:797
132
- msgid "Non-repeating"
133
- msgstr ""
134
-
135
- #: wp-crontrol.php:519
136
- msgid "The DISABLE_WP_CRON constant is set to true. WP-Cron spawning is disabled."
137
- msgstr ""
138
-
139
- #: wp-crontrol.php:551
140
- msgid "Unexpected HTTP response code: %s"
141
- msgstr ""
142
-
143
- #: wp-crontrol.php:572
144
- msgid ""
145
- "There was a problem spawning a call to the WP-Cron system on your site. "
146
- "This means WP-Cron events on your site may not work. The problem was: %s"
147
- msgstr ""
148
-
149
- #: wp-crontrol.php:587
150
- msgid "Add Cron Event"
151
- msgstr ""
152
-
153
- #: wp-crontrol.php:588
154
- msgid "Add PHP Cron Event"
155
- msgstr ""
156
-
157
- #: wp-crontrol.php:591
158
- msgid "Modify Cron Event"
159
- msgstr ""
160
-
161
- #: wp-crontrol.php:592
162
- msgid "Modify PHP Cron Event"
163
- msgstr ""
164
-
165
- #: wp-crontrol.php:599
166
- msgid ""
167
- "Cron events trigger actions in your code. Using the form below, you can "
168
- "enter the schedule of the action, as well as the PHP code for the action "
169
- "itself."
170
- msgstr ""
171
-
172
- #: wp-crontrol.php:602
173
- msgid ""
174
- "Cron events trigger actions in your code. A cron event added using the form "
175
- "below needs a corresponding action hook somewhere in code, perhaps the %1$s "
176
- "file in your theme."
177
- msgstr ""
178
-
179
- #: wp-crontrol.php:646
180
- msgid "Hook code:"
181
- msgstr ""
182
-
183
- #: wp-crontrol.php:651
184
- msgid "Hook name:"
185
- msgstr ""
186
-
187
- #: wp-crontrol.php:655
188
- msgid "Arguments:"
189
- msgstr ""
190
-
191
- #: wp-crontrol.php:658
192
- msgid "e.g. [25], ['asdf'], or ['i','want',25,'cakes']"
193
- msgstr ""
194
-
195
- #: wp-crontrol.php:663
196
- msgid "Next run (UTC):"
197
- msgstr ""
198
-
199
- #: wp-crontrol.php:666
200
- msgid "e.g. 'now', 'tomorrow', '+2 days', or '25-02-2020 12:34:00'"
201
- msgstr ""
202
-
203
- #: wp-crontrol.php:669
204
- msgid "Event schedule:"
205
- msgstr ""
206
-
207
- #: wp-crontrol.php:689
208
- msgid "You currently have no scheduled cron events."
209
- msgstr ""
210
-
211
- #: wp-crontrol.php:720
212
- msgid "Successfully executed the cron event %s"
213
- msgstr ""
214
-
215
- #: wp-crontrol.php:721
216
- msgid "Successfully edited the cron event %s"
217
- msgstr ""
218
-
219
- #: wp-crontrol.php:722
220
- msgid "Successfully created the cron event %s"
221
- msgstr ""
222
-
223
- #: wp-crontrol.php:723
224
- msgid "Successfully deleted the cron event %s"
225
- msgstr ""
226
-
227
- #: wp-crontrol.php:724
228
- msgid "Failed to the delete the cron event %s"
229
- msgstr ""
230
-
231
- #: wp-crontrol.php:725
232
- msgid "Failed to the execute the cron event %s"
233
- msgstr ""
234
-
235
- #: wp-crontrol.php:752
236
- msgid "WP-Cron Events"
237
- msgstr ""
238
-
239
- #: wp-crontrol.php:757
240
- msgid "Hook Name"
241
- msgstr ""
242
-
243
- #: wp-crontrol.php:758
244
- msgid "Arguments"
245
- msgstr ""
246
-
247
- #: wp-crontrol.php:759
248
- msgid "Next Run"
249
- msgstr ""
250
-
251
- #: wp-crontrol.php:760
252
- msgid "Recurrence"
253
- msgstr ""
254
-
255
- #: wp-crontrol.php:784
256
- msgid "None"
257
- msgstr ""
258
-
259
- #: wp-crontrol.php:794
260
- msgid "PHP Cron"
261
- msgstr ""
262
-
263
- #: wp-crontrol.php:795
264
- msgid "PHP Code"
265
- msgstr ""
266
-
267
- #: wp-crontrol.php:807
268
- msgid "Edit"
269
- msgstr ""
270
-
271
- #: wp-crontrol.php:818
272
- msgid "Run Now"
273
- msgstr ""
274
-
275
- #: wp-crontrol.php:841
276
- msgid "Local timezone is %s"
277
- msgstr ""
278
-
279
- #: wp-crontrol.php:842
280
- msgid "UTC time is %s"
281
- msgstr ""
282
-
283
- #: wp-crontrol.php:843
284
- msgid "Local time is %s"
285
- msgstr ""
286
-
287
- #: wp-crontrol.php:871
288
- msgid "%s year"
289
- msgid_plural "%s years"
290
- msgstr[0] ""
291
- msgstr[1] ""
292
-
293
- #: wp-crontrol.php:872
294
- msgid "%s month"
295
- msgid_plural "%s months"
296
- msgstr[0] ""
297
- msgstr[1] ""
298
-
299
- #: wp-crontrol.php:873
300
- msgid "%s week"
301
- msgid_plural "%s weeks"
302
- msgstr[0] ""
303
- msgstr[1] ""
304
-
305
- #: wp-crontrol.php:874
306
- msgid "%s day"
307
- msgid_plural "%s days"
308
- msgstr[0] ""
309
- msgstr[1] ""
310
-
311
- #: wp-crontrol.php:875
312
- msgid "%s hour"
313
- msgid_plural "%s hours"
314
- msgstr[0] ""
315
- msgstr[1] ""
316
-
317
- #: wp-crontrol.php:876
318
- msgid "%s minute"
319
- msgid_plural "%s minutes"
320
- msgstr[0] ""
321
- msgstr[1] ""
322
-
323
- #: wp-crontrol.php:877
324
- msgid "%s second"
325
- msgid_plural "%s seconds"
326
- msgstr[0] ""
327
- msgstr[1] ""
328
-
329
- #: wp-crontrol.php:882
330
- msgid "now"
331
- msgstr ""
332
-
333
- #. Plugin Name of the plugin/theme
334
- msgid "WP Crontrol"
335
- msgstr ""
336
-
337
- #. Plugin URI of the plugin/theme
338
- msgid "https://wordpress.org/plugins/wp-crontrol/"
339
- msgstr ""
340
-
341
- #. Description of the plugin/theme
342
- msgid ""
343
- "WP Crontrol lets you view and control what's happening in the WP-Cron "
344
- "system."
345
- msgstr ""
346
-
347
- #. Author of the plugin/theme
348
- msgid ""
349
- "<a href=\"https://johnblackbourn.com/\">John Blackbourn</a> & <a "
350
- "href=\"http://www.scompt.com/\">Edward Dale</a>"
351
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: johnbillion, scompt
3
  Tags: admin, cron, plugin, control, wp-cron, crontrol
4
  Requires at least: 4.1
5
  Tested up to: 4.7
6
- Stable tag: 1.3.1
7
 
8
  WP Crontrol lets you view and control what's happening in the WP-Cron system.
9
 
3
  Tags: admin, cron, plugin, control, wp-cron, crontrol
4
  Requires at least: 4.1
5
  Tested up to: 4.7
6
+ Stable tag: 1.4
7
 
8
  WP Crontrol lets you view and control what's happening in the WP-Cron system.
9
 
wp-crontrol.php CHANGED
@@ -4,7 +4,7 @@
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="https://johnblackbourn.com/">John Blackbourn</a> & <a href="http://www.scompt.com/">Edward Dale</a>
7
- * Version: 1.3.1
8
  * Text Domain: wp-crontrol
9
  * Domain Path: /languages/
10
  * License: GPL v2 or later
@@ -85,7 +85,8 @@ class Crontrol {
85
  check_admin_referer( 'new-cron' );
86
  extract( wp_unslash( $_POST ), EXTR_PREFIX_ALL, 'in' );
87
  $in_args = json_decode( $in_args, true );
88
- $this->add_cron( $in_next_run, $in_schedule, $in_hookname, $in_args );
 
89
  $redirect = array(
90
  'page' => 'crontrol_admin_manage_page',
91
  'crontrol_message' => '5',
@@ -100,8 +101,12 @@ class Crontrol {
100
  }
101
  check_admin_referer( 'new-cron' );
102
  extract( wp_unslash( $_POST ), EXTR_PREFIX_ALL, 'in' );
103
- $args = array( 'code' => $in_hookcode );
104
- $this->add_cron( $in_next_run, $in_schedule, 'crontrol_cron_job', $args );
 
 
 
 
105
  $redirect = array(
106
  'page' => 'crontrol_admin_manage_page',
107
  'crontrol_message' => '5',
@@ -119,7 +124,8 @@ class Crontrol {
119
  check_admin_referer( "edit-cron_{$in_original_hookname}_{$in_original_sig}_{$in_original_next_run}" );
120
  $in_args = json_decode( $in_args, true );
121
  $i = $this->delete_cron( $in_original_hookname, $in_original_sig, $in_original_next_run );
122
- $i = $this->add_cron( $in_next_run, $in_schedule, $in_hookname, $in_args );
 
123
  $redirect = array(
124
  'page' => 'crontrol_admin_manage_page',
125
  'crontrol_message' => '4',
@@ -129,16 +135,21 @@ class Crontrol {
129
  exit;
130
 
131
  } else if ( isset( $_POST['edit_php_cron'] ) ) {
132
- if ( ! current_user_can( 'manage_options' ) ) {
133
  wp_die( esc_html__( 'You are not allowed to edit cron events.', 'wp-crontrol' ) );
134
  }
135
 
136
  extract( wp_unslash( $_POST ), EXTR_PREFIX_ALL, 'in' );
137
  check_admin_referer( "edit-cron_{$in_original_hookname}_{$in_original_sig}_{$in_original_next_run}" );
138
  $args['code'] = $in_hookcode;
139
- $args = array( 'code' => $in_hookcode );
 
 
 
 
140
  $i = $this->delete_cron( $in_original_hookname, $in_original_sig, $in_original_next_run );
141
- $i = $this->add_cron( $in_next_run, $in_schedule, 'crontrol_cron_job', $args );
 
142
  $redirect = array(
143
  'page' => 'crontrol_admin_manage_page',
144
  'crontrol_message' => '4',
@@ -283,15 +294,17 @@ class Crontrol {
283
  /**
284
  * Adds a new cron event.
285
  *
286
- * @param string $next_run A human-readable (strtotime) time that the event should be run at
287
  * @param string $schedule The recurrence of the cron event
288
  * @param string $hookname The name of the hook to execute
289
  * @param array $args Arguments to add to the cron event
290
  */
291
  public function add_cron( $next_run, $schedule, $hookname, $args ) {
292
  $next_run = strtotime( $next_run );
293
- if ( false === $next_run || -1 == $next_run ) {
294
  $next_run = time();
 
 
295
  }
296
  if ( ! is_array( $args ) ) {
297
  $args = array();
@@ -402,8 +415,11 @@ class Crontrol {
402
  $custom_keys = array_keys( $custom_schedules );
403
 
404
  $messages = array(
 
405
  '2' => __( 'Successfully deleted the cron schedule %s.', 'wp-crontrol' ),
 
406
  '3' => __( 'Successfully added the cron schedule %s.', 'wp-crontrol' ),
 
407
  '7' => __( 'Cron schedule not added because there was a problem parsing %s.', 'wp-crontrol' ),
408
  );
409
  if ( isset( $_GET['crontrol_message'] ) && isset( $_GET['crontrol_name'] ) && isset( $messages[ $_GET['crontrol_message'] ] ) ) {
@@ -454,7 +470,7 @@ class Crontrol {
454
  'id' => urlencode( $name ),
455
  ), admin_url( 'options-general.php' ) );
456
  $url = wp_nonce_url( $url, 'delete-sched_' . $name );
457
- printf( '<td><a href="%s" class="delete">%s</a></td>',
458
  esc_url( $url ),
459
  esc_html__( 'Delete', 'wp-crontrol' )
460
  );
@@ -475,16 +491,16 @@ class Crontrol {
475
  <table class="form-table">
476
  <tbody>
477
  <tr>
478
- <th valign="top" scope="row"><label for="cron_internal_name"><?php esc_html_e( 'Internal name', 'wp-crontrol' ); ?>:</label></th>
479
- <td><input type="text" class="regular-text" value="" id="cron_internal_name" name="internal_name"/></td>
480
  </tr>
481
  <tr>
482
- <th valign="top" scope="row"><label for="cron_interval"><?php esc_html_e( 'Interval (seconds)', 'wp-crontrol' ); ?>:</label></th>
483
- <td><input type="text" class="regular-text" value="" id="cron_interval" name="interval"/></td>
484
  </tr>
485
  <tr>
486
- <th valign="top" scope="row"><label for="cron_display_name"><?php esc_html_e( 'Display name', 'wp-crontrol' ); ?>:</label></th>
487
- <td><input type="text" class="regular-text" value="" id="cron_display_name" name="display_name"/></td>
488
  </tr>
489
  </tbody></table>
490
  <p class="submit"><input id="schedadd-submit" type="submit" class="button-primary" value="<?php esc_attr_e( 'Add Cron Schedule', 'wp-crontrol' ); ?>" name="new_schedule"/></p>
@@ -511,7 +527,7 @@ class Crontrol {
511
  public function schedules_dropdown( $current = false ) {
512
  $schedules = $this->get_schedules();
513
  ?>
514
- <select class="postform" name="schedule" id="schedule">
515
  <option <?php selected( $current, '_oneoff' ); ?> value="_oneoff"><?php esc_html_e( 'Non-repeating', 'wp-crontrol' ); ?></option>
516
  <?php foreach ( $schedules as $sched_name => $sched_data ) { ?>
517
  <option <?php selected( $current, $sched_name ); ?> value="<?php echo esc_attr( $sched_name ); ?>">
@@ -536,10 +552,12 @@ class Crontrol {
536
  global $wp_version;
537
 
538
  if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
 
539
  return new WP_Error( 'crontrol_info', sprintf( __( 'The %s constant is set to true. WP-Cron spawning is disabled.', 'wp-crontrol' ), 'DISABLE_WP_CRON' ) );
540
  }
541
 
542
  if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
 
543
  return new WP_Error( 'crontrol_info', sprintf( __( 'The %s constant is set to true.', 'wp-crontrol' ), 'ALTERNATE_WP_CRON' ) );
544
  }
545
 
@@ -570,6 +588,7 @@ class Crontrol {
570
  return $result;
571
  } else if ( wp_remote_retrieve_response_code( $result ) >= 300 ) {
572
  return new WP_Error( 'unexpected_http_response_code', sprintf(
 
573
  __( 'Unexpected HTTP response code: %s', 'wp-crontrol' ),
574
  intval( wp_remote_retrieve_response_code( $result ) )
575
  ) );
@@ -598,7 +617,12 @@ class Crontrol {
598
  } else {
599
  ?>
600
  <div id="cron-status-error" class="error">
601
- <p><?php printf( esc_html__( 'There was a problem spawning a call to the WP-Cron system on your site. This means WP-Cron events on your site may not work. The problem was: %s', 'wp-crontrol' ), '<br><strong>' . esc_html( $status->get_error_message() ) . '</strong>' ); ?></p>
 
 
 
 
 
602
  </div>
603
  <?php
604
  }
@@ -606,6 +630,28 @@ class Crontrol {
606
 
607
  }
608
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
609
  /**
610
  * Shows the form used to add/edit cron events.
611
  *
@@ -625,11 +671,12 @@ class Crontrol {
625
  'cron' => admin_url( 'tools.php?page=crontrol_admin_manage_page&action=new-cron' ) . '#crontrol_form',
626
  'php-cron' => admin_url( 'tools.php?page=crontrol_admin_manage_page&action=new-php-cron' ) . '#crontrol_form',
627
  );
 
628
  if ( $is_php ) {
629
- $helper_text = esc_html__( '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.', 'wp-crontrol' );
630
  } else {
631
  $helper_text = sprintf(
632
- esc_html__( '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.', 'wp-crontrol' ),
633
  '<code>functions.php</code>'
634
  );
635
  }
@@ -644,59 +691,109 @@ class Crontrol {
644
  $other_fields .= sprintf( '<input name="original_next_run" type="hidden" value="%s" />',
645
  esc_attr( $existing['next_run'] )
646
  );
647
- $existing['args'] = $is_php ? $existing['args']['code'] : wp_json_encode( $existing['args'] );
648
- $existing['next_run'] = date( 'Y-m-d H:i:s', $existing['next_run'] );
 
649
  $action = $is_php ? 'edit_php_cron' : 'edit_cron';
650
  $button = $is_php ? $modify_tabs['php-cron'] : $modify_tabs['cron'];
651
  $show_edit_tab = true;
 
652
  } else {
653
  $other_fields = wp_nonce_field( 'new-cron', '_wpnonce', true, false );
654
- $existing = array( 'hookname' => '', 'hookcode' => '', 'args' => '', 'next_run' => 'now', 'schedule' => false );
655
  $action = $is_php ? 'new_php_cron' : 'new_cron';
656
  $button = $is_php ? $new_tabs['php-cron'] : $new_tabs['cron'];
657
  $show_edit_tab = false;
 
 
 
 
 
 
 
 
 
658
  }
 
 
659
  ?>
660
  <div id="crontrol_form" class="wrap narrow">
661
  <h2 class="nav-tab-wrapper">
662
  <a href="<?php echo esc_url( $new_links['cron'] ); ?>" class="nav-tab<?php if ( ! $show_edit_tab && ! $is_php ) { echo ' nav-tab-active'; } ?>"><?php echo esc_html( $new_tabs['cron'] ); ?></a>
663
- <?php if ( current_user_can( 'edit_files' ) ) { ?>
664
- <a href="<?php echo esc_url( $new_links['php-cron'] ); ?>" class="nav-tab<?php if ( ! $show_edit_tab && $is_php ) { echo ' nav-tab-active'; } ?>"><?php echo esc_html( $new_tabs['php-cron'] ); ?></a>
665
- <?php } ?>
666
  <?php if ( $show_edit_tab ) { ?>
667
  <span class="nav-tab nav-tab-active"><?php echo esc_html( $button ); ?></span>
668
  <?php } ?>
669
  </h2>
 
670
  <p><?php echo $helper_text; // WPCS:: XSS ok. ?></p>
671
  <form method="post" action="<?php echo esc_url( admin_url( 'tools.php?page=crontrol_admin_manage_page' ) ); ?>">
672
  <?php echo $other_fields; // WPCS:: XSS ok. ?>
673
  <table class="form-table"><tbody>
674
  <?php if ( $is_php ) : ?>
675
  <tr>
676
- <th valign="top" scope="row"><label for="hookcode"><?php esc_html_e( 'Hook code:', 'wp-crontrol' ); ?></label></th>
677
- <td><textarea class="large-text code" rows="10" cols="50" id="hookcode" name="hookcode"><?php echo esc_textarea( $existing['args'] ); ?></textarea></td>
 
 
 
 
678
  </tr>
679
  <?php else : ?>
680
  <tr>
681
- <th valign="top" scope="row"><label for="hookname"><?php esc_html_e( 'Hook name:', 'wp-crontrol' ); ?></label></th>
682
- <td><input type="text" class="regular-text" id="hookname" name="hookname" value="<?php echo esc_attr( $existing['hookname'] ); ?>"/></td>
683
  </tr>
684
  <tr>
685
- <th valign="top" scope="row"><label for="args"><?php esc_html_e( 'Arguments:', 'wp-crontrol' ); ?></label></th>
686
  <td>
687
- <input type="text" class="regular-text" id="args" name="args" value="<?php echo esc_attr( $existing['args'] ); ?>"/>
688
- <p class="description"><?php esc_html_e( 'e.g. [25], ["asdf"], or ["i","want",25,"cakes"]', 'wp-crontrol' ); ?></p>
 
 
 
 
 
 
 
 
689
  </td>
690
  </tr>
691
  <?php endif; ?>
692
  <tr>
693
- <th valign="top" scope="row"><label for="next_run"><?php esc_html_e( 'Next run (UTC):', 'wp-crontrol' ); ?></label></th>
694
  <td>
695
- <input type="text" class="regular-text" id="next_run" name="next_run" value="<?php echo esc_attr( $existing['next_run'] ); ?>"/>
696
- <p class="description"><?php esc_html_e( "e.g. 'now', 'tomorrow', '+2 days', or '25-02-2020 12:34:00'", 'wp-crontrol' ); ?></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
697
  </td>
698
  </tr><tr>
699
- <th valign="top" scope="row"><label for="schedule"><?php esc_html_e( 'Event schedule:', 'wp-crontrol' ); ?></label></th>
700
  <td>
701
  <?php $this->schedules_dropdown( $existing['schedule'] ); ?>
702
  </td>
@@ -704,6 +801,11 @@ class Crontrol {
704
  </tbody></table>
705
  <p class="submit"><input type="submit" class="button-primary" value="<?php echo esc_attr( $button ); ?>" name="<?php echo esc_attr( $action ); ?>"/></p>
706
  </form>
 
 
 
 
 
707
  </div>
708
  <?php
709
  }
@@ -747,12 +849,18 @@ class Crontrol {
747
  */
748
  public function admin_manage_page() {
749
  $messages = array(
750
- '1' => __( 'Successfully executed the cron event %s', 'wp-crontrol' ),
751
- '4' => __( 'Successfully edited the cron event %s', 'wp-crontrol' ),
752
- '5' => __( 'Successfully created the cron event %s', 'wp-crontrol' ),
753
- '6' => __( 'Successfully deleted the cron event %s', 'wp-crontrol' ),
754
- '7' => __( 'Failed to the delete the cron event %s', 'wp-crontrol' ),
755
- '8' => __( 'Failed to the execute the cron event %s', 'wp-crontrol' ),
 
 
 
 
 
 
756
  );
757
  if ( isset( $_GET['crontrol_name'] ) && isset( $_GET['crontrol_message'] ) && isset( $messages[ $_GET['crontrol_message'] ] ) ) {
758
  $hook = wp_unslash( $_GET['crontrol_name'] );
@@ -764,19 +872,6 @@ class Crontrol {
764
  $doing_edit = ( isset( $_GET['action'] ) && 'edit-cron' == $_GET['action'] ) ? wp_unslash( $_GET['id'] ) : false ;
765
  $time_format = 'Y-m-d H:i:s';
766
 
767
- $tzstring = get_option( 'timezone_string' );
768
- $current_offset = get_option( 'gmt_offset' );
769
-
770
- if ( $current_offset >= 0 ) {
771
- $current_offset = '+' . $current_offset;
772
- }
773
-
774
- if ( '' === $tzstring ) {
775
- $tz = sprintf( 'UTC%s', $current_offset );
776
- } else {
777
- $tz = sprintf( '%s (UTC%s)', str_replace( '_', ' ', $tzstring ), $current_offset );
778
- }
779
-
780
  $this->show_cron_status();
781
 
782
  ?>
@@ -785,11 +880,11 @@ class Crontrol {
785
  <table class="widefat striped">
786
  <thead>
787
  <tr>
788
- <th><?php esc_html_e( 'Hook Name', 'wp-crontrol' ); ?></th>
789
- <th><?php esc_html_e( 'Arguments', 'wp-crontrol' ); ?></th>
790
- <th><?php esc_html_e( 'Next Run', 'wp-crontrol' ); ?></th>
791
- <th><?php esc_html_e( 'Recurrence', 'wp-crontrol' ); ?></th>
792
- <th colspan="3">&nbsp;</th>
793
  </tr>
794
  </thead>
795
  <tbody>
@@ -824,7 +919,12 @@ class Crontrol {
824
  echo '<tr id="cron-' . esc_attr( $id ) . '" class="">';
825
 
826
  if ( 'crontrol_cron_job' == $event->hook ) {
827
- echo '<td><em>' . esc_html__( 'PHP Cron', 'wp-crontrol' ) . '</em></td>';
 
 
 
 
 
828
  echo '<td><em>' . esc_html__( 'PHP Code', 'wp-crontrol' ) . '</em></td>';
829
  } else {
830
  echo '<td>' . esc_html( $event->hook ) . '</td>';
@@ -856,7 +956,8 @@ class Crontrol {
856
  'next_run' => urlencode( $event->time ),
857
  );
858
  $link = add_query_arg( $link, admin_url( 'tools.php' ) ) . '#crontrol_form';
859
- echo "<td><a class='view' href='" . esc_url( $link ) . "'>" . esc_html__( 'Edit', 'wp-crontrol' ) . '</a></td>';
 
860
 
861
  $link = array(
862
  'page' => 'crontrol_admin_manage_page',
@@ -867,7 +968,7 @@ class Crontrol {
867
  );
868
  $link = add_query_arg( $link, admin_url( 'tools.php' ) );
869
  $link = wp_nonce_url( $link, "run-cron_{$event->hook}_{$event->sig}" );
870
- echo "<td><a class='view' href='". esc_url( $link ) ."'>" . esc_html__( 'Run Now', 'wp-crontrol' ) . '</a></td>';
871
 
872
  $link = array(
873
  'page' => 'crontrol_admin_manage_page',
@@ -878,7 +979,8 @@ class Crontrol {
878
  );
879
  $link = add_query_arg( $link, admin_url( 'tools.php' ) );
880
  $link = wp_nonce_url( $link, "delete-cron_{$event->hook}_{$event->sig}_{$event->time}" );
881
- echo "<td><a class='delete' href='".esc_url( $link )."'>" . esc_html__( 'Delete', 'wp-crontrol' ) . '</a></td>';
 
882
 
883
  echo '</tr>';
884
 
@@ -888,14 +990,6 @@ class Crontrol {
888
  </tbody>
889
  </table>
890
 
891
- <div class="tablenav">
892
- <p class="description">
893
- <?php printf( esc_html__( 'Local timezone is %s', 'wp-crontrol' ), '<code>' . esc_html( $tz ) . '</code>' ); ?>
894
- <span id="utc-time"><?php printf( esc_html__( 'UTC time is %s', 'wp-crontrol' ), '<code>' . esc_html( date_i18n( $time_format, false, true ) ) . '</code>' ); ?></span>
895
- <span id="local-time"><?php printf( esc_html__( 'Local time is %s', 'wp-crontrol' ), '<code>' . esc_html( date_i18n( $time_format ) ) . '</code>' ); ?></span>
896
- </p>
897
- </div>
898
-
899
  </div>
900
  <?php
901
  if ( is_array( $doing_edit ) ) {
@@ -908,8 +1002,8 @@ class Crontrol {
908
  /**
909
  * Pretty-prints the difference in two times.
910
  *
911
- * @param time $older_date
912
- * @param time $newer_date
913
  * @return string The pretty time_since value
914
  * @link http://binarybonsai.com/code/timesince.txt
915
  */
@@ -917,15 +1011,33 @@ class Crontrol {
917
  return $this->interval( $newer_date - $older_date );
918
  }
919
 
 
 
 
 
 
 
 
 
 
 
 
920
  public function interval( $since ) {
921
  // array of time period chunks
922
  $chunks = array(
 
923
  array( 60 * 60 * 24 * 365, _n_noop( '%s year', '%s years', 'wp-crontrol' ) ),
 
924
  array( 60 * 60 * 24 * 30, _n_noop( '%s month', '%s months', 'wp-crontrol' ) ),
 
925
  array( 60 * 60 * 24 * 7, _n_noop( '%s week', '%s weeks', 'wp-crontrol' ) ),
 
926
  array( 60 * 60 * 24, _n_noop( '%s day', '%s days', 'wp-crontrol' ) ),
 
927
  array( 60 * 60, _n_noop( '%s hour', '%s hours', 'wp-crontrol' ) ),
 
928
  array( 60, _n_noop( '%s minute', '%s minutes', 'wp-crontrol' ) ),
 
929
  array( 1, _n_noop( '%s second', '%s seconds', 'wp-crontrol' ) ),
930
  );
931
 
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="https://johnblackbourn.com/">John Blackbourn</a> & <a href="http://www.scompt.com/">Edward Dale</a>
7
+ * Version: 1.4
8
  * Text Domain: wp-crontrol
9
  * Domain Path: /languages/
10
  * License: GPL v2 or later
85
  check_admin_referer( 'new-cron' );
86
  extract( wp_unslash( $_POST ), EXTR_PREFIX_ALL, 'in' );
87
  $in_args = json_decode( $in_args, true );
88
+ $next_run = $in_next_run_date . ' ' . $in_next_run_time;
89
+ $this->add_cron( $next_run, $in_schedule, $in_hookname, $in_args );
90
  $redirect = array(
91
  'page' => 'crontrol_admin_manage_page',
92
  'crontrol_message' => '5',
101
  }
102
  check_admin_referer( 'new-cron' );
103
  extract( wp_unslash( $_POST ), EXTR_PREFIX_ALL, 'in' );
104
+ $args = array(
105
+ 'code' => $in_hookcode,
106
+ 'name' => $in_eventname,
107
+ );
108
+ $next_run = $in_next_run_date . ' ' . $in_next_run_time;
109
+ $this->add_cron( $next_run, $in_schedule, 'crontrol_cron_job', $args );
110
  $redirect = array(
111
  'page' => 'crontrol_admin_manage_page',
112
  'crontrol_message' => '5',
124
  check_admin_referer( "edit-cron_{$in_original_hookname}_{$in_original_sig}_{$in_original_next_run}" );
125
  $in_args = json_decode( $in_args, true );
126
  $i = $this->delete_cron( $in_original_hookname, $in_original_sig, $in_original_next_run );
127
+ $next_run = $in_next_run_date . ' ' . $in_next_run_time;
128
+ $i = $this->add_cron( $next_run, $in_schedule, $in_hookname, $in_args );
129
  $redirect = array(
130
  'page' => 'crontrol_admin_manage_page',
131
  'crontrol_message' => '4',
135
  exit;
136
 
137
  } else if ( isset( $_POST['edit_php_cron'] ) ) {
138
+ if ( ! current_user_can( 'edit_files' ) ) {
139
  wp_die( esc_html__( 'You are not allowed to edit cron events.', 'wp-crontrol' ) );
140
  }
141
 
142
  extract( wp_unslash( $_POST ), EXTR_PREFIX_ALL, 'in' );
143
  check_admin_referer( "edit-cron_{$in_original_hookname}_{$in_original_sig}_{$in_original_next_run}" );
144
  $args['code'] = $in_hookcode;
145
+ $args['name'] = $in_eventname;
146
+ $args = array(
147
+ 'code' => $in_hookcode,
148
+ 'name' => $in_eventname,
149
+ );
150
  $i = $this->delete_cron( $in_original_hookname, $in_original_sig, $in_original_next_run );
151
+ $next_run = $in_next_run_date . ' ' . $in_next_run_time;
152
+ $i = $this->add_cron( $next_run, $in_schedule, 'crontrol_cron_job', $args );
153
  $redirect = array(
154
  'page' => 'crontrol_admin_manage_page',
155
  'crontrol_message' => '4',
294
  /**
295
  * Adds a new cron event.
296
  *
297
+ * @param string $next_run A human-readable (strtotime) time that the event should be run at, in the local timezone
298
  * @param string $schedule The recurrence of the cron event
299
  * @param string $hookname The name of the hook to execute
300
  * @param array $args Arguments to add to the cron event
301
  */
302
  public function add_cron( $next_run, $schedule, $hookname, $args ) {
303
  $next_run = strtotime( $next_run );
304
+ if ( false === $next_run ) {
305
  $next_run = time();
306
+ } else {
307
+ $next_run = get_gmt_from_date( date( 'Y-m-d H:i:s', $next_run ), 'U' );
308
  }
309
  if ( ! is_array( $args ) ) {
310
  $args = array();
415
  $custom_keys = array_keys( $custom_schedules );
416
 
417
  $messages = array(
418
+ /* translators: 1: The name of the cron schedule. */
419
  '2' => __( 'Successfully deleted the cron schedule %s.', 'wp-crontrol' ),
420
+ /* translators: 1: The name of the cron schedule. */
421
  '3' => __( 'Successfully added the cron schedule %s.', 'wp-crontrol' ),
422
+ /* translators: 1: The name of the cron schedule. */
423
  '7' => __( 'Cron schedule not added because there was a problem parsing %s.', 'wp-crontrol' ),
424
  );
425
  if ( isset( $_GET['crontrol_message'] ) && isset( $_GET['crontrol_name'] ) && isset( $messages[ $_GET['crontrol_message'] ] ) ) {
470
  'id' => urlencode( $name ),
471
  ), admin_url( 'options-general.php' ) );
472
  $url = wp_nonce_url( $url, 'delete-sched_' . $name );
473
+ printf( '<td><span class="row-actions visible"><span class="delete"><a href="%s">%s</a></span></span></td>',
474
  esc_url( $url ),
475
  esc_html__( 'Delete', 'wp-crontrol' )
476
  );
491
  <table class="form-table">
492
  <tbody>
493
  <tr>
494
+ <th valign="top" scope="row"><label for="cron_internal_name"><?php esc_html_e( 'Internal name', 'wp-crontrol' ); ?></label></th>
495
+ <td><input type="text" class="regular-text" value="" id="cron_internal_name" name="internal_name" required/></td>
496
  </tr>
497
  <tr>
498
+ <th valign="top" scope="row"><label for="cron_interval"><?php esc_html_e( 'Interval (seconds)', 'wp-crontrol' ); ?></label></th>
499
+ <td><input type="number" class="regular-text" value="" id="cron_interval" name="interval" min="1" step="1" required/></td>
500
  </tr>
501
  <tr>
502
+ <th valign="top" scope="row"><label for="cron_display_name"><?php esc_html_e( 'Display name', 'wp-crontrol' ); ?></label></th>
503
+ <td><input type="text" class="regular-text" value="" id="cron_display_name" name="display_name" required/></td>
504
  </tr>
505
  </tbody></table>
506
  <p class="submit"><input id="schedadd-submit" type="submit" class="button-primary" value="<?php esc_attr_e( 'Add Cron Schedule', 'wp-crontrol' ); ?>" name="new_schedule"/></p>
527
  public function schedules_dropdown( $current = false ) {
528
  $schedules = $this->get_schedules();
529
  ?>
530
+ <select class="postform" name="schedule" id="schedule" required>
531
  <option <?php selected( $current, '_oneoff' ); ?> value="_oneoff"><?php esc_html_e( 'Non-repeating', 'wp-crontrol' ); ?></option>
532
  <?php foreach ( $schedules as $sched_name => $sched_data ) { ?>
533
  <option <?php selected( $current, $sched_name ); ?> value="<?php echo esc_attr( $sched_name ); ?>">
552
  global $wp_version;
553
 
554
  if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
555
+ /* translators: 1: The name of the PHP constant that is set. */
556
  return new WP_Error( 'crontrol_info', sprintf( __( 'The %s constant is set to true. WP-Cron spawning is disabled.', 'wp-crontrol' ), 'DISABLE_WP_CRON' ) );
557
  }
558
 
559
  if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
560
+ /* translators: 1: The name of the PHP constant that is set. */
561
  return new WP_Error( 'crontrol_info', sprintf( __( 'The %s constant is set to true.', 'wp-crontrol' ), 'ALTERNATE_WP_CRON' ) );
562
  }
563
 
588
  return $result;
589
  } else if ( wp_remote_retrieve_response_code( $result ) >= 300 ) {
590
  return new WP_Error( 'unexpected_http_response_code', sprintf(
591
+ /* translators: 1: The HTTP response code. */
592
  __( 'Unexpected HTTP response code: %s', 'wp-crontrol' ),
593
  intval( wp_remote_retrieve_response_code( $result ) )
594
  ) );
617
  } else {
618
  ?>
619
  <div id="cron-status-error" class="error">
620
+ <p><?php
621
+ printf(
622
+ /* translators: 1: Error message text. */
623
+ esc_html__( 'There was a problem spawning a call to the WP-Cron system on your site. This means WP-Cron events on your site may not work. The problem was: %s', 'wp-crontrol' ),
624
+ '<br><strong>' . esc_html( $status->get_error_message() ) . '</strong>' );
625
+ ?></p>
626
  </div>
627
  <?php
628
  }
630
 
631
  }
632
 
633
+ /**
634
+ * Get the display name for the site's timezone.
635
+ *
636
+ * @return string The name and UTC offset for the site's timezone.
637
+ */
638
+ public function get_timezone_name() {
639
+ $timezone_string = get_option( 'timezone_string', '' );
640
+ $gmt_offset = get_option( 'gmt_offset', 0 );
641
+
642
+ if ( $gmt_offset >= 0 ) {
643
+ $gmt_offset = '+' . $gmt_offset;
644
+ }
645
+
646
+ if ( '' === $timezone_string ) {
647
+ $name = sprintf( 'UTC%s', $gmt_offset );
648
+ } else {
649
+ $name = sprintf( '%s (UTC%s)', str_replace( '_', ' ', $timezone_string ), $gmt_offset );
650
+ }
651
+
652
+ return $name;
653
+ }
654
+
655
  /**
656
  * Shows the form used to add/edit cron events.
657
  *
671
  'cron' => admin_url( 'tools.php?page=crontrol_admin_manage_page&action=new-cron' ) . '#crontrol_form',
672
  'php-cron' => admin_url( 'tools.php?page=crontrol_admin_manage_page&action=new-php-cron' ) . '#crontrol_form',
673
  );
674
+ $display_args = '';
675
  if ( $is_php ) {
676
+ $helper_text = esc_html__( 'Cron events trigger actions in your code. Enter the schedule of the event, as well as the PHP code to execute when the action is triggered.', 'wp-crontrol' );
677
  } else {
678
  $helper_text = sprintf(
679
+ esc_html__( 'Cron events trigger actions in your code. A cron event needs a corresponding action hook somewhere in code, e.g. the %1$s file in your theme.', 'wp-crontrol' ),
680
  '<code>functions.php</code>'
681
  );
682
  }
691
  $other_fields .= sprintf( '<input name="original_next_run" type="hidden" value="%s" />',
692
  esc_attr( $existing['next_run'] )
693
  );
694
+ if ( ! empty( $existing['args'] ) ) {
695
+ $display_args = wp_json_encode( $existing['args'] );
696
+ }
697
  $action = $is_php ? 'edit_php_cron' : 'edit_cron';
698
  $button = $is_php ? $modify_tabs['php-cron'] : $modify_tabs['cron'];
699
  $show_edit_tab = true;
700
+ list( $next_run_date, $next_run_time ) = explode( ' ', get_date_from_gmt( date( 'Y-m-d H:i:s', $existing['next_run'] ), 'Y-m-d H:i:s' ) );
701
  } else {
702
  $other_fields = wp_nonce_field( 'new-cron', '_wpnonce', true, false );
703
+ $existing = array( 'hookname' => '', 'args' => array(), 'next_run' => 'now', 'schedule' => false );
704
  $action = $is_php ? 'new_php_cron' : 'new_cron';
705
  $button = $is_php ? $new_tabs['php-cron'] : $new_tabs['cron'];
706
  $show_edit_tab = false;
707
+ $next_run_time = $next_run_date = '';
708
+ }
709
+ if ( $is_php ) {
710
+ if ( ! isset( $existing['args']['code'] ) ) {
711
+ $existing['args']['code'] = '';
712
+ }
713
+ if ( ! isset( $existing['args']['name'] ) ) {
714
+ $existing['args']['name'] = '';
715
+ }
716
  }
717
+
718
+ $allowed = ( ! $is_php || current_user_can( 'edit_files' ) );
719
  ?>
720
  <div id="crontrol_form" class="wrap narrow">
721
  <h2 class="nav-tab-wrapper">
722
  <a href="<?php echo esc_url( $new_links['cron'] ); ?>" class="nav-tab<?php if ( ! $show_edit_tab && ! $is_php ) { echo ' nav-tab-active'; } ?>"><?php echo esc_html( $new_tabs['cron'] ); ?></a>
723
+ <a href="<?php echo esc_url( $new_links['php-cron'] ); ?>" class="nav-tab<?php if ( ! $show_edit_tab && $is_php ) { echo ' nav-tab-active'; } ?>"><?php echo esc_html( $new_tabs['php-cron'] ); ?></a>
 
 
724
  <?php if ( $show_edit_tab ) { ?>
725
  <span class="nav-tab nav-tab-active"><?php echo esc_html( $button ); ?></span>
726
  <?php } ?>
727
  </h2>
728
+ <?php if ( $allowed ) { ?>
729
  <p><?php echo $helper_text; // WPCS:: XSS ok. ?></p>
730
  <form method="post" action="<?php echo esc_url( admin_url( 'tools.php?page=crontrol_admin_manage_page' ) ); ?>">
731
  <?php echo $other_fields; // WPCS:: XSS ok. ?>
732
  <table class="form-table"><tbody>
733
  <?php if ( $is_php ) : ?>
734
  <tr>
735
+ <th valign="top" scope="row"><label for="hookcode"><?php esc_html_e( 'PHP Code', 'wp-crontrol' ); ?></label></th>
736
+ <td><textarea class="large-text code" rows="10" cols="50" id="hookcode" name="hookcode" required><?php echo esc_textarea( $existing['args']['code'] ); ?></textarea></td>
737
+ </tr>
738
+ <tr>
739
+ <th valign="top" scope="row"><label for="eventname"><?php esc_html_e( 'Event Name (optional)', 'wp-crontrol' ); ?></label></th>
740
+ <td><input type="text" class="regular-text" id="eventname" name="eventname" value="<?php echo esc_attr( $existing['args']['name'] ); ?>"/></td>
741
  </tr>
742
  <?php else : ?>
743
  <tr>
744
+ <th valign="top" scope="row"><label for="hookname"><?php esc_html_e( 'Action Name', 'wp-crontrol' ); ?></label></th>
745
+ <td><input type="text" class="regular-text" id="hookname" name="hookname" value="<?php echo esc_attr( $existing['hookname'] ); ?>" required /></td>
746
  </tr>
747
  <tr>
748
+ <th valign="top" scope="row"><label for="args"><?php esc_html_e( 'Arguments (optional)', 'wp-crontrol' ); ?></label></th>
749
  <td>
750
+ <input type="text" class="regular-text" id="args" name="args" value="<?php echo esc_attr( $display_args ); ?>"/>
751
+ <p class="description"><?php
752
+ /* translators: 1, 2, and 3: Example values for an input field. */
753
+ echo esc_html( sprintf(
754
+ __( 'e.g. %s, %s, or %s', 'wp-crontrol' ),
755
+ '[25]',
756
+ '["asdf"]',
757
+ '["i","want",25,"cakes"]'
758
+ ) );
759
+ ?></p>
760
  </td>
761
  </tr>
762
  <?php endif; ?>
763
  <tr>
764
+ <th valign="top" scope="row"><label for="next_run_date"><?php esc_html_e( 'Next Run', 'wp-crontrol' ); ?></label></th>
765
  <td>
766
+ <script>
767
+ jQuery( function( $ ) {
768
+ var isDateInputSupported = function() {
769
+ var elem = document.createElement( 'input' );
770
+ elem.setAttribute( 'type', 'date' );
771
+ elem.value = 'foo';
772
+ return ( elem.type == 'date' && elem.value != 'foo' );
773
+ }
774
+
775
+ if ( ! isDateInputSupported() ) {
776
+ $( '.datetime-fallback' ).show();
777
+ }
778
+ } );
779
+ </script>
780
+ <input type="date" placeholder="YYYY-MM-DD" id="next_run_date" name="next_run_date" value="<?php echo esc_attr( $next_run_date ); ?>" maxlength="10" pattern="\d{4}\-\d{2}\-\d{2}" required />
781
+ <input type="time" step="1" placeholder="HH:MM:SS" id="next_run_time" name="next_run_time" value="<?php echo esc_attr( $next_run_time ); ?>" maxlength="8" pattern="\d{2}:\d{2}:\d{2}" required />
782
+ <?php printf(
783
+ /* translators: %s Timezone name. */
784
+ esc_html__( 'Timezone: %s', 'wp-crontrol' ),
785
+ '<code>' . esc_html( $this->get_timezone_name() ) . '</code>'
786
+ ); ?>
787
+ <p class="description datetime-fallback hidden"><?php
788
+ /* translators: %s Date/time format for an input field. */
789
+ echo esc_html( sprintf(
790
+ __( 'Format: %s', 'wp-crontrol' ),
791
+ date( 'Y' ) . '-02-25 12:34:00'
792
+ ) );
793
+ ?></p>
794
  </td>
795
  </tr><tr>
796
+ <th valign="top" scope="row"><label for="schedule"><?php esc_html_e( 'Recurrence', 'wp-crontrol' ); ?></label></th>
797
  <td>
798
  <?php $this->schedules_dropdown( $existing['schedule'] ); ?>
799
  </td>
801
  </tbody></table>
802
  <p class="submit"><input type="submit" class="button-primary" value="<?php echo esc_attr( $button ); ?>" name="<?php echo esc_attr( $action ); ?>"/></p>
803
  </form>
804
+ <?php } else { ?>
805
+ <div class="error inline">
806
+ <p><?php esc_html_e( 'You cannot add or edit PHP cron events because your user account does not have the ability to edit files.', 'wp-crontrol' ); ?></p>
807
+ </div>
808
+ <?php } ?>
809
  </div>
810
  <?php
811
  }
849
  */
850
  public function admin_manage_page() {
851
  $messages = array(
852
+ /* translators: 1: The name of the cron event. */
853
+ '1' => __( 'Successfully executed the cron event %s.', 'wp-crontrol' ),
854
+ /* translators: 1: The name of the cron event. */
855
+ '4' => __( 'Successfully edited the cron event %s.', 'wp-crontrol' ),
856
+ /* translators: 1: The name of the cron event. */
857
+ '5' => __( 'Successfully created the cron event %s.', 'wp-crontrol' ),
858
+ /* translators: 1: The name of the cron event. */
859
+ '6' => __( 'Successfully deleted the cron event %s.', 'wp-crontrol' ),
860
+ /* translators: 1: The name of the cron event. */
861
+ '7' => __( 'Failed to the delete the cron event %s.', 'wp-crontrol' ),
862
+ /* translators: 1: The name of the cron event. */
863
+ '8' => __( 'Failed to the execute the cron event %s.', 'wp-crontrol' ),
864
  );
865
  if ( isset( $_GET['crontrol_name'] ) && isset( $_GET['crontrol_message'] ) && isset( $messages[ $_GET['crontrol_message'] ] ) ) {
866
  $hook = wp_unslash( $_GET['crontrol_name'] );
872
  $doing_edit = ( isset( $_GET['action'] ) && 'edit-cron' == $_GET['action'] ) ? wp_unslash( $_GET['id'] ) : false ;
873
  $time_format = 'Y-m-d H:i:s';
874
 
 
 
 
 
 
 
 
 
 
 
 
 
 
875
  $this->show_cron_status();
876
 
877
  ?>
880
  <table class="widefat striped">
881
  <thead>
882
  <tr>
883
+ <th scope="col"><?php esc_html_e( 'Action Name', 'wp-crontrol' ); ?></th>
884
+ <th scope="col"><?php esc_html_e( 'Arguments', 'wp-crontrol' ); ?></th>
885
+ <th scope="col"><?php esc_html_e( 'Next Run', 'wp-crontrol' ); ?></th>
886
+ <th scope="col"><?php esc_html_e( 'Recurrence', 'wp-crontrol' ); ?></th>
887
+ <th scope="col"><span class="screen-reader-text"><?php esc_html_e( 'Actions', 'wp-crontrol' ); ?></span></th>
888
  </tr>
889
  </thead>
890
  <tbody>
919
  echo '<tr id="cron-' . esc_attr( $id ) . '" class="">';
920
 
921
  if ( 'crontrol_cron_job' == $event->hook ) {
922
+ if ( ! empty( $event->args['name'] ) ) {
923
+ /* translators: 1: The name of the PHP cron event. */
924
+ echo '<td><em>' . esc_html( sprintf( __( 'PHP Cron (%s)', 'wp-crontrol' ), $event->args['name'] ) ) . '</em></td>';
925
+ } else {
926
+ echo '<td><em>' . esc_html__( 'PHP Cron', 'wp-crontrol' ) . '</em></td>';
927
+ }
928
  echo '<td><em>' . esc_html__( 'PHP Code', 'wp-crontrol' ) . '</em></td>';
929
  } else {
930
  echo '<td>' . esc_html( $event->hook ) . '</td>';
956
  'next_run' => urlencode( $event->time ),
957
  );
958
  $link = add_query_arg( $link, admin_url( 'tools.php' ) ) . '#crontrol_form';
959
+ echo '<td><span class="row-actions visible">';
960
+ echo "<a href='" . esc_url( $link ) . "'>" . esc_html__( 'Edit', 'wp-crontrol' ) . '</a> | ';
961
 
962
  $link = array(
963
  'page' => 'crontrol_admin_manage_page',
968
  );
969
  $link = add_query_arg( $link, admin_url( 'tools.php' ) );
970
  $link = wp_nonce_url( $link, "run-cron_{$event->hook}_{$event->sig}" );
971
+ echo "<a href='". esc_url( $link ) ."'>" . esc_html__( 'Run Now', 'wp-crontrol' ) . '</a> | ';
972
 
973
  $link = array(
974
  'page' => 'crontrol_admin_manage_page',
979
  );
980
  $link = add_query_arg( $link, admin_url( 'tools.php' ) );
981
  $link = wp_nonce_url( $link, "delete-cron_{$event->hook}_{$event->sig}_{$event->time}" );
982
+ echo "<span class='delete'><a href='".esc_url( $link )."'>" . esc_html__( 'Delete', 'wp-crontrol' ) . '</a></span>';
983
+ echo '</td>';
984
 
985
  echo '</tr>';
986
 
990
  </tbody>
991
  </table>
992
 
 
 
 
 
 
 
 
 
993
  </div>
994
  <?php
995
  if ( is_array( $doing_edit ) ) {
1002
  /**
1003
  * Pretty-prints the difference in two times.
1004
  *
1005
+ * @param int $older_date Unix timestamp.
1006
+ * @param int $newer_date Unix timestamp.
1007
  * @return string The pretty time_since value
1008
  * @link http://binarybonsai.com/code/timesince.txt
1009
  */
1011
  return $this->interval( $newer_date - $older_date );
1012
  }
1013
 
1014
+ /**
1015
+ * Converts a period of time in seconds into a human-readable format representing the interval.
1016
+ *
1017
+ * Example:
1018
+ *
1019
+ * echo self::interval( 90 );
1020
+ * // 1 minute 30 seconds
1021
+ *
1022
+ * @param int $since A period of time in seconds.
1023
+ * @return string An interval represented as a string.
1024
+ */
1025
  public function interval( $since ) {
1026
  // array of time period chunks
1027
  $chunks = array(
1028
+ /* translators: 1: The number of years in an interval of time. */
1029
  array( 60 * 60 * 24 * 365, _n_noop( '%s year', '%s years', 'wp-crontrol' ) ),
1030
+ /* translators: 1: The number of months in an interval of time. */
1031
  array( 60 * 60 * 24 * 30, _n_noop( '%s month', '%s months', 'wp-crontrol' ) ),
1032
+ /* translators: 1: The number of weeks in an interval of time. */
1033
  array( 60 * 60 * 24 * 7, _n_noop( '%s week', '%s weeks', 'wp-crontrol' ) ),
1034
+ /* translators: 1: The number of days in an interval of time. */
1035
  array( 60 * 60 * 24, _n_noop( '%s day', '%s days', 'wp-crontrol' ) ),
1036
+ /* translators: 1: The number of hours in an interval of time. */
1037
  array( 60 * 60, _n_noop( '%s hour', '%s hours', 'wp-crontrol' ) ),
1038
+ /* translators: 1: The number of minutes in an interval of time. */
1039
  array( 60, _n_noop( '%s minute', '%s minutes', 'wp-crontrol' ) ),
1040
+ /* translators: 1: The number of seconds in an interval of time. */
1041
  array( 1, _n_noop( '%s second', '%s seconds', 'wp-crontrol' ) ),
1042
  );
1043