PluginProbe
WebberZone Top 10 — Popular Posts / 4.3.3
WebberZone Top 10 — Popular Posts v4.3.3
4.5.2 4.5.1 4.5.0 4.4.3 4.4.2 4.4.1 4.4.0 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.4.1 1.5 1.5.1 1.5.2 1.5.3 1.6 All 118 releases
top-10 / includes / admin / class-cron.php

class-cron.php in WebberZone Top 10 — Popular Posts 4.3.3, at includes/admin/class-cron.php

225 lines 6.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Cron class.
4 *
5 * @package WebberZone\Top_Ten\Admin
6 */
7
8 namespace WebberZone\Top_Ten\Admin;
9
10 use WebberZone\Top_Ten\Database;
11 use WebberZone\Top_Ten\Util\Hook_Registry;
12
13 if ( ! defined( 'WPINC' ) ) {
14 die;
15 }
16
17 /**
18 * Class Cron
19 */
20 class Cron {
21 /**
22 * Whether the aggregation cron was missing and had to be rescheduled.
23 *
24 * @var bool
25 */
26 private bool $aggregation_cron_was_missing = false;
27
28 /**
29 * Whether the aggregation cron interval changed and had to be rescheduled.
30 *
31 * @var bool
32 */
33 private bool $aggregation_cron_interval_changed = false;
34
35 /**
36 * Initialize the class.
37 */
38 public function __construct() {
39 Hook_Registry::add_action( 'tptn_cron_hook', array( $this, 'run_cron' ) );
40 Hook_Registry::add_action( 'tptn_aggregation_cron_hook', array( $this, 'run_aggregation' ) );
41 Hook_Registry::add_action( 'admin_init', array( $this, 'check_aggregation_cron' ) );
42 Hook_Registry::add_action( 'admin_notices', array( $this, 'aggregation_cron_missing_notice' ) );
43 }
44
45 /**
46 * Function to truncate daily run.
47 *
48 * @since 3.0.0
49 */
50 public function run_cron() {
51 global $wpdb;
52
53 $delete_from = TOP_TEN_STORE_DATA;
54
55 /**
56 * Override maintenance day range.
57 *
58 * @since 2.5.0
59 *
60 * @param int $delete_from Number of days before which post data is deleted from daily tables.
61 */
62 $delete_from = apply_filters( 'tptn_maintenance_days', $delete_from );
63
64 $log_retention = TOP_TEN_LOG_STORE_DATA;
65
66 /**
67 * Override retention period for the visits log table.
68 *
69 * @since 4.3.0
70 *
71 * @param int $log_retention Number of days to retain raw visit log rows.
72 */
73 $log_retention = apply_filters( 'tptn_log_retention_days', $log_retention );
74
75 $current_time = strtotime( current_time( 'mysql' ) );
76 $cutoff = strtotime( "-{$delete_from} DAY", $current_time );
77 $cutoff_log = strtotime( "-{$log_retention} DAY", $current_time );
78 $from_date = gmdate( 'Y-m-d H', $cutoff );
79 $from_date_log = gmdate( 'Y-m-d H:i:s', $cutoff_log );
80
81 // Delete old daily entries.
82 $args = array(
83 'daily' => true,
84 'to_date' => $from_date,
85 'limit' => 1000,
86 );
87
88 $deadline = microtime( true ) + 20;
89 do {
90 $deleted = Database::delete_counts( $args );
91 } while ( $deleted > 0 && microtime( true ) < $deadline );
92
93 // Prune visits log rows older than the retention period.
94 $log_table = Database::get_log_table();
95 $deadline_log = microtime( true ) + 20;
96 do {
97 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
98 $deleted_log = $wpdb->query( $wpdb->prepare( "DELETE FROM {$log_table} WHERE visited_at < %s LIMIT 1000", $from_date_log ) );
99 } while ( $deleted_log > 0 && microtime( true ) < $deadline_log );
100 }
101
102 /**
103 * Function to enable run or actions.
104 *
105 * @since 3.0.0
106 * @param int $hour Hour.
107 * @param int $min Minute.
108 * @param string $recurrence Frequency.
109 */
110 public static function enable_run( $hour, $min, $recurrence ) {
111 // Invoke WordPress internal cron.
112 if ( ! wp_next_scheduled( 'tptn_cron_hook' ) ) {
113 wp_schedule_event( mktime( $hour, $min, 0 ), $recurrence, 'tptn_cron_hook' );
114 } else {
115 wp_clear_scheduled_hook( 'tptn_cron_hook' );
116 wp_schedule_event( mktime( $hour, $min, 0 ), $recurrence, 'tptn_cron_hook' );
117 }
118 }
119
120 /**
121 * Function to disable daily run or actions.
122 *
123 * @since 3.0.0
124 */
125 public static function disable_run() {
126 if ( wp_next_scheduled( 'tptn_cron_hook' ) ) {
127 wp_clear_scheduled_hook( 'tptn_cron_hook' );
128 }
129 }
130
131 /**
132 * Drain the visits log into the count tables and prune orphaned log rows.
133 *
134 * @since 4.3.0
135 */
136 public function run_aggregation() {
137 Database::aggregate_visit_log();
138 }
139
140 /**
141 * Schedule the aggregation cron to run at the configured interval.
142 *
143 * @since 4.3.0
144 */
145 public static function enable_aggregation_run() {
146 /**
147 * Override the aggregation cron schedule. Must be a registered WP-Cron recurrence
148 * (e.g. 'one_minute', 'two_minutes', 'three_minutes', 'five_minutes').
149 *
150 * @since 4.3.0
151 *
152 * @param string $interval Schedule name. Default 'two_minutes'.
153 */
154 $interval = (string) apply_filters( 'tptn_aggregation_cron_interval', 'two_minutes' );
155
156 if ( ! wp_next_scheduled( 'tptn_aggregation_cron_hook' ) ) {
157 wp_schedule_event( time(), $interval, 'tptn_aggregation_cron_hook' );
158 }
159 }
160
161 /**
162 * Remove the aggregation cron.
163 *
164 * @since 4.3.0
165 */
166 public static function disable_aggregation_run() {
167 wp_clear_scheduled_hook( 'tptn_aggregation_cron_hook' );
168 }
169
170 /**
171 * Check that the aggregation cron is scheduled at the correct interval; reschedule if missing or changed.
172 *
173 * @since 4.3.0
174 */
175 public function check_aggregation_cron() {
176 /** This filter is documented in includes/admin/class-cron.php */
177 $interval = (string) apply_filters( 'tptn_aggregation_cron_interval', 'two_minutes' );
178
179 $timestamp = wp_next_scheduled( 'tptn_aggregation_cron_hook' );
180
181 if ( ! $timestamp ) {
182 self::enable_aggregation_run();
183 $this->aggregation_cron_was_missing = true;
184 return;
185 }
186
187 $crons = _get_cron_array();
188 $args_key = md5( serialize( array() ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
189 $current = isset( $crons[ $timestamp ]['tptn_aggregation_cron_hook'][ $args_key ]['schedule'] )
190 ? $crons[ $timestamp ]['tptn_aggregation_cron_hook'][ $args_key ]['schedule']
191 : '';
192
193 if ( $current !== $interval ) {
194 wp_clear_scheduled_hook( 'tptn_aggregation_cron_hook' );
195 self::enable_aggregation_run();
196 $this->aggregation_cron_interval_changed = true;
197 }
198 }
199
200 /**
201 * Show an admin notice when the aggregation cron was missing or rescheduled due to an interval change.
202 *
203 * @since 4.3.0
204 */
205 public function aggregation_cron_missing_notice() {
206 if ( $this->aggregation_cron_interval_changed ) {
207 ?>
208 <div class="notice notice-info is-dismissible">
209 <p>
210 <?php esc_html_e( 'Top 10: The visit aggregation cron job (tptn_aggregation_cron_hook) has been rescheduled to match the updated interval.', 'top-10' ); ?>
211 </p>
212 </div>
213 <?php
214 } elseif ( $this->aggregation_cron_was_missing ) {
215 ?>
216 <div class="notice notice-warning is-dismissible">
217 <p>
218 <?php esc_html_e( 'Top 10: The visit aggregation cron job (tptn_aggregation_cron_hook) was missing and has been rescheduled automatically.', 'top-10' ); ?>
219 </p>
220 </div>
221 <?php
222 }
223 }
224 }
225