WP Crontrol - Version 1.5

Version Description

Download this release

Release Info

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

Code changes from version 1.4 to 1.5

Files changed (2) hide show
  1. readme.txt +4 -20
  2. wp-crontrol.php +128 -28
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.4
7
 
8
  WP Crontrol lets you view and control what's happening in the WP-Cron system.
9
 
@@ -11,7 +11,7 @@ WP Crontrol lets you view and control what's happening in the WP-Cron system.
11
 
12
  WP Crontrol lets you view and control what's happening in the WP-Cron system. From the admin screens you can:
13
 
14
- * View all cron events along with their arguments, recurrence, and when they are next due.
15
  * Edit, delete, and immediately run any cron events.
16
  * Add new cron events.
17
  * Add, edit, and remove custom cron schedules.
@@ -20,24 +20,8 @@ The admin screen will show you a warning message if your cron system doesn't app
20
 
21
  = Usage =
22
 
23
- 1. Go to the Tools -> Cron Events menu to manage cron events.
24
- 2. Go to the Settings -> Cron Schedules menu to manage cron schedules.
25
-
26
- == Installation ==
27
-
28
- You can install this plugin directly from your WordPress dashboard:
29
-
30
- 1. Go to the *Plugins* menu and click *Add New*.
31
- 2. Search for *WP Crontrol*.
32
- 3. Click *Install Now* next to the *WP Crontrol* plugin.
33
- 4. Activate the plugin.
34
-
35
- Alternatively, see the guide to [Manually Installing Plugins](http://codex.wordpress.org/Managing_Plugins#Manual_Plugin_Installation).
36
-
37
- = Usage =
38
-
39
- 1. Go to the Tools -> Cron Events menu to manage cron events.
40
- 2. Go to the Settings -> Cron Schedules menu to manage cron schedules.
41
 
42
  == Frequently Asked Questions ==
43
 
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.5
7
 
8
  WP Crontrol lets you view and control what's happening in the WP-Cron system.
9
 
11
 
12
  WP Crontrol lets you view and control what's happening in the WP-Cron system. From the admin screens you can:
13
 
14
+ * View all cron events along with their arguments, recurrence, callback functions, and when they are next due.
15
  * Edit, delete, and immediately run any cron events.
16
  * Add new cron events.
17
  * Add, edit, and remove custom cron schedules.
20
 
21
  = Usage =
22
 
23
+ 1. Go to the `Tools -> Cron Events` menu to manage cron events.
24
+ 2. Go to the `Settings -> Cron Schedules` menu to manage cron schedules.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  == Frequently Asked Questions ==
27
 
wp-crontrol.php CHANGED
@@ -3,8 +3,9 @@
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="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
@@ -32,7 +33,7 @@
32
  *
33
  * @package WP Crontrol
34
  * @author Edward Dale <scompt@scompt.com> & John Blackbourn <john@johnblackbourn.com>
35
- * @copyright Copyright 2013 Edward Dale & John Blackbourn
36
  * @license http://www.gnu.org/licenses/gpl.txt GPL 2.0
37
  * @link https://wordpress.org/plugins/wp-crontrol/
38
  * @since 0.2
@@ -71,7 +72,7 @@ class Crontrol {
71
  * Run using the 'init' action.
72
  */
73
  public function action_init() {
74
- load_plugin_textdomain( 'wp-crontrol', false, dirname( plugin_basename( __FILE__ ) ) . '/gettext' );
75
  }
76
 
77
  /**
@@ -107,10 +108,11 @@ class Crontrol {
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',
113
- 'crontrol_name' => urlencode( $in_hookname ),
114
  );
115
  wp_redirect( add_query_arg( $redirect, admin_url( 'tools.php' ) ) );
116
  exit;
@@ -150,10 +152,11 @@ class Crontrol {
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',
156
- 'crontrol_name' => urlencode( $in_hookname ),
157
  );
158
  wp_redirect( add_query_arg( $redirect, admin_url( 'tools.php' ) ) );
159
  exit;
@@ -741,7 +744,7 @@ class Crontrol {
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>
@@ -872,6 +875,15 @@ class Crontrol {
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,8 +892,9 @@ class Crontrol {
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>
@@ -891,7 +904,7 @@ class Crontrol {
891
  <?php
892
  if ( is_wp_error( $events ) ) {
893
  ?>
894
- <tr><td colspan="7"><?php echo esc_html( $events->get_error_message() ); ?></td></tr>
895
  <?php
896
  } else {
897
  foreach ( $events as $id => $event ) {
@@ -907,12 +920,12 @@ class Crontrol {
907
  }
908
 
909
  if ( empty( $event->args ) ) {
910
- $args = __( 'None', 'wp-crontrol' );
911
  } else {
912
  if ( defined( 'JSON_UNESCAPED_SLASHES' ) ) {
913
- $args = wp_json_encode( $event->args, JSON_UNESCAPED_SLASHES );
914
  } else {
915
- $args = stripslashes( wp_json_encode( $event->args ) );
916
  }
917
  }
918
 
@@ -926,9 +939,17 @@ class Crontrol {
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>';
931
- echo '<td>' . esc_html( $args ) . '</td>';
 
 
 
 
 
 
 
932
  }
933
 
934
  echo '<td>';
@@ -948,6 +969,10 @@ class Crontrol {
948
  echo '</td>';
949
  }
950
 
 
 
 
 
951
  $link = array(
952
  'page' => 'crontrol_admin_manage_page',
953
  'action' => 'edit-cron',
@@ -956,8 +981,7 @@ class Crontrol {
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,20 +992,23 @@ class Crontrol {
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',
975
- 'action' => 'delete-cron',
976
- 'id' => urlencode( $event->hook ),
977
- 'sig' => urlencode( $event->sig ),
978
- 'next_run' => urlencode( $event->time ),
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
 
987
  }
@@ -999,6 +1026,79 @@ class Crontrol {
999
  }
1000
  }
1001
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1002
  /**
1003
  * Pretty-prints the difference in two times.
1004
  *
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: John Blackbourn & contributors
7
+ * Author URI: https://github.com/johnbillion/wp-crontrol/graphs/contributors
8
+ * Version: 1.5
9
  * Text Domain: wp-crontrol
10
  * Domain Path: /languages/
11
  * License: GPL v2 or later
33
  *
34
  * @package WP Crontrol
35
  * @author Edward Dale <scompt@scompt.com> & John Blackbourn <john@johnblackbourn.com>
36
+ * @copyright Copyright 2008 Edward Dale, 2012-2017 John Blackbourn
37
  * @license http://www.gnu.org/licenses/gpl.txt GPL 2.0
38
  * @link https://wordpress.org/plugins/wp-crontrol/
39
  * @since 0.2
72
  * Run using the 'init' action.
73
  */
74
  public function action_init() {
75
+ load_plugin_textdomain( 'wp-crontrol', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
76
  }
77
 
78
  /**
108
  );
109
  $next_run = $in_next_run_date . ' ' . $in_next_run_time;
110
  $this->add_cron( $next_run, $in_schedule, 'crontrol_cron_job', $args );
111
+ $hookname = ( ! empty( $in_eventname ) ) ? $in_eventname : __( 'PHP Cron', 'wp-crontrol' );
112
  $redirect = array(
113
  'page' => 'crontrol_admin_manage_page',
114
  'crontrol_message' => '5',
115
+ 'crontrol_name' => urlencode( $hookname ),
116
  );
117
  wp_redirect( add_query_arg( $redirect, admin_url( 'tools.php' ) ) );
118
  exit;
152
  $i = $this->delete_cron( $in_original_hookname, $in_original_sig, $in_original_next_run );
153
  $next_run = $in_next_run_date . ' ' . $in_next_run_time;
154
  $i = $this->add_cron( $next_run, $in_schedule, 'crontrol_cron_job', $args );
155
+ $hookname = ( ! empty( $in_eventname ) ) ? $in_eventname : __( 'PHP Cron', 'wp-crontrol' );
156
  $redirect = array(
157
  'page' => 'crontrol_admin_manage_page',
158
  'crontrol_message' => '4',
159
+ 'crontrol_name' => urlencode( $hookname ),
160
  );
161
  wp_redirect( add_query_arg( $redirect, admin_url( 'tools.php' ) ) );
162
  exit;
744
  </tr>
745
  <?php else : ?>
746
  <tr>
747
+ <th valign="top" scope="row"><label for="hookname"><?php esc_html_e( 'Hook Name', 'wp-crontrol' ); ?></label></th>
748
  <td><input type="text" class="regular-text" id="hookname" name="hookname" value="<?php echo esc_attr( $existing['hookname'] ); ?>" required /></td>
749
  </tr>
750
  <tr>
875
  $doing_edit = ( isset( $_GET['action'] ) && 'edit-cron' == $_GET['action'] ) ? wp_unslash( $_GET['id'] ) : false ;
876
  $time_format = 'Y-m-d H:i:s';
877
 
878
+ $core_hooks = array(
879
+ 'wp_version_check',
880
+ 'wp_update_plugins',
881
+ 'wp_update_themes',
882
+ 'wp_scheduled_delete',
883
+ 'wp_scheduled_auto_draft_delete',
884
+ 'update_network_counts',
885
+ );
886
+
887
  $this->show_cron_status();
888
 
889
  ?>
892
  <table class="widefat striped">
893
  <thead>
894
  <tr>
895
+ <th scope="col"><?php esc_html_e( 'Hook Name', 'wp-crontrol' ); ?></th>
896
  <th scope="col"><?php esc_html_e( 'Arguments', 'wp-crontrol' ); ?></th>
897
+ <th scope="col"><?php esc_html_e( 'Actions', 'wp-crontrol' ); ?></th>
898
  <th scope="col"><?php esc_html_e( 'Next Run', 'wp-crontrol' ); ?></th>
899
  <th scope="col"><?php esc_html_e( 'Recurrence', 'wp-crontrol' ); ?></th>
900
  <th scope="col"><span class="screen-reader-text"><?php esc_html_e( 'Actions', 'wp-crontrol' ); ?></span></th>
904
  <?php
905
  if ( is_wp_error( $events ) ) {
906
  ?>
907
+ <tr><td colspan="6"><?php echo esc_html( $events->get_error_message() ); ?></td></tr>
908
  <?php
909
  } else {
910
  foreach ( $events as $id => $event ) {
920
  }
921
 
922
  if ( empty( $event->args ) ) {
923
+ $args = '<em>' . esc_html__( 'None', 'wp-crontrol' ) . '</em>';
924
  } else {
925
  if ( defined( 'JSON_UNESCAPED_SLASHES' ) ) {
926
+ $args = '<code>' . wp_json_encode( $event->args, JSON_UNESCAPED_SLASHES ) . '</code>';
927
  } else {
928
+ $args = '<code>' . stripslashes( wp_json_encode( $event->args ) ) . '</code>';
929
  }
930
  }
931
 
939
  echo '<td><em>' . esc_html__( 'PHP Cron', 'wp-crontrol' ) . '</em></td>';
940
  }
941
  echo '<td><em>' . esc_html__( 'PHP Code', 'wp-crontrol' ) . '</em></td>';
942
+ echo '<td><em>' . esc_html__( 'WP Crontrol', 'wp-crontrol' ) . '</em></td>';
943
  } else {
944
  echo '<td>' . esc_html( $event->hook ) . '</td>';
945
+ echo '<td>' . $args . '</td>'; // WPCS:: XSS ok.
946
+ echo '<td>';
947
+ $callbacks = array();
948
+ foreach ( $this->get_action_callbacks( $event->hook ) as $callback ) {
949
+ $callbacks[] = '<code>' . esc_html( $callback['callback']['name'] ) . '</code>';
950
+ }
951
+ echo implode( '<br>', $callbacks ); // WPCS:: XSS ok.
952
+ echo '</td>';
953
  }
954
 
955
  echo '<td>';
969
  echo '</td>';
970
  }
971
 
972
+ $links = array();
973
+
974
+ echo '<td><span class="row-actions visible">';
975
+
976
  $link = array(
977
  'page' => 'crontrol_admin_manage_page',
978
  'action' => 'edit-cron',
981
  'next_run' => urlencode( $event->time ),
982
  );
983
  $link = add_query_arg( $link, admin_url( 'tools.php' ) ) . '#crontrol_form';
984
+ $links[] = "<a href='" . esc_url( $link ) . "'>" . esc_html__( 'Edit', 'wp-crontrol' ) . '</a>';
 
985
 
986
  $link = array(
987
  'page' => 'crontrol_admin_manage_page',
992
  );
993
  $link = add_query_arg( $link, admin_url( 'tools.php' ) );
994
  $link = wp_nonce_url( $link, "run-cron_{$event->hook}_{$event->sig}" );
995
+ $links[] = "<a href='" . esc_url( $link ) . "'>" . esc_html__( 'Run Now', 'wp-crontrol' ) . '</a>';
996
+
997
+ if ( ! in_array( $event->hook, $core_hooks, true ) ) {
998
+ $link = array(
999
+ 'page' => 'crontrol_admin_manage_page',
1000
+ 'action' => 'delete-cron',
1001
+ 'id' => urlencode( $event->hook ),
1002
+ 'sig' => urlencode( $event->sig ),
1003
+ 'next_run' => urlencode( $event->time ),
1004
+ );
1005
+ $link = add_query_arg( $link, admin_url( 'tools.php' ) );
1006
+ $link = wp_nonce_url( $link, "delete-cron_{$event->hook}_{$event->sig}_{$event->time}" );
1007
+ $links[] = "<span class='delete'><a href='" . esc_url( $link ) . "'>" . esc_html__( 'Delete', 'wp-crontrol' ) . '</a></span>';
1008
+ }
1009
 
1010
+ echo implode( ' | ', $links ); // WPCS:: XSS ok.
1011
+ echo '</span></td>';
1012
  echo '</tr>';
1013
 
1014
  }
1026
  }
1027
  }
1028
 
1029
+ protected function get_action_callbacks( $name ) {
1030
+ global $wp_filter;
1031
+
1032
+ $actions = array();
1033
+
1034
+ if ( isset( $wp_filter[$name] ) ) {
1035
+
1036
+ # http://core.trac.wordpress.org/ticket/17817
1037
+ $action = $wp_filter[$name];
1038
+
1039
+ foreach ( $action as $priority => $callbacks ) {
1040
+
1041
+ foreach ( $callbacks as $callback ) {
1042
+
1043
+ $callback = self::populate_callback( $callback );
1044
+
1045
+ $actions[] = array(
1046
+ 'priority' => $priority,
1047
+ 'callback' => $callback,
1048
+ );
1049
+
1050
+ }
1051
+
1052
+ }
1053
+
1054
+ }
1055
+
1056
+ return $actions;
1057
+
1058
+ }
1059
+
1060
+ public static function populate_callback( array $callback ) {
1061
+
1062
+ // If Query Monitor is installed, use its rich callback analysis:
1063
+ if ( method_exists( 'QM_Util', 'populate_callback' ) ) {
1064
+ return QM_Util::populate_callback( $callback );
1065
+ }
1066
+
1067
+ if ( is_string( $callback['function'] ) && ( false !== strpos( $callback['function'], '::' ) ) ) {
1068
+ $callback['function'] = explode( '::', $callback['function'] );
1069
+ }
1070
+
1071
+ if ( is_array( $callback['function'] ) ) {
1072
+
1073
+ if ( is_object( $callback['function'][0] ) ) {
1074
+ $class = get_class( $callback['function'][0] );
1075
+ $access = '->';
1076
+ } else {
1077
+ $class = $callback['function'][0];
1078
+ $access = '::';
1079
+ }
1080
+
1081
+ $callback['name'] = $class . $access . $callback['function'][1] . '()';
1082
+
1083
+ } elseif ( is_object( $callback['function'] ) ) {
1084
+
1085
+ if ( is_a( $callback['function'], 'Closure' ) ) {
1086
+ $callback['name'] = 'Closure';
1087
+ } else {
1088
+ $class = get_class( $callback['function'] );
1089
+ $callback['name'] = $class . '->__invoke()';
1090
+ }
1091
+
1092
+ } else {
1093
+
1094
+ $callback['name'] = $callback['function'] . '()';
1095
+
1096
+ }
1097
+
1098
+ return $callback;
1099
+
1100
+ }
1101
+
1102
  /**
1103
  * Pretty-prints the difference in two times.
1104
  *