true, 'to_date' => $from_date, 'limit' => 1000, ); $deadline = microtime( true ) + 20; do { $deleted = Database::delete_counts( $args ); } while ( $deleted > 0 && microtime( true ) < $deadline ); // Prune visits log rows older than the retention period. $log_table = Database::get_log_table(); $deadline_log = microtime( true ) + 20; do { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared $deleted_log = $wpdb->query( $wpdb->prepare( "DELETE FROM {$log_table} WHERE visited_at < %s LIMIT 1000", $from_date_log ) ); } while ( $deleted_log > 0 && microtime( true ) < $deadline_log ); } /** * Function to enable run or actions. * * @since 3.0.0 * @param int $hour Hour. * @param int $min Minute. * @param string $recurrence Frequency. */ public static function enable_run( $hour, $min, $recurrence ) { // Invoke WordPress internal cron. if ( ! wp_next_scheduled( 'tptn_cron_hook' ) ) { wp_schedule_event( mktime( $hour, $min, 0 ), $recurrence, 'tptn_cron_hook' ); } else { wp_clear_scheduled_hook( 'tptn_cron_hook' ); wp_schedule_event( mktime( $hour, $min, 0 ), $recurrence, 'tptn_cron_hook' ); } } /** * Function to disable daily run or actions. * * @since 3.0.0 */ public static function disable_run() { if ( wp_next_scheduled( 'tptn_cron_hook' ) ) { wp_clear_scheduled_hook( 'tptn_cron_hook' ); } } /** * Drain the visits log into the count tables and prune orphaned log rows. * * @since 4.3.0 */ public function run_aggregation() { Database::aggregate_visit_log(); } /** * Schedule the aggregation cron to run at the configured interval. * * @since 4.3.0 */ public static function enable_aggregation_run() { /** * Override the aggregation cron schedule. Must be a registered WP-Cron recurrence * (e.g. 'one_minute', 'two_minutes', 'three_minutes', 'five_minutes'). * * @since 4.3.0 * * @param string $interval Schedule name. Default 'two_minutes'. */ $interval = (string) apply_filters( 'tptn_aggregation_cron_interval', 'two_minutes' ); if ( ! wp_next_scheduled( 'tptn_aggregation_cron_hook' ) ) { wp_schedule_event( time(), $interval, 'tptn_aggregation_cron_hook' ); } } /** * Remove the aggregation cron. * * @since 4.3.0 */ public static function disable_aggregation_run() { wp_clear_scheduled_hook( 'tptn_aggregation_cron_hook' ); } /** * Check that the aggregation cron is scheduled at the correct interval; reschedule if missing or changed. * * @since 4.3.0 */ public function check_aggregation_cron() { /** This filter is documented in includes/admin/class-cron.php */ $interval = (string) apply_filters( 'tptn_aggregation_cron_interval', 'two_minutes' ); $timestamp = wp_next_scheduled( 'tptn_aggregation_cron_hook' ); if ( ! $timestamp ) { self::enable_aggregation_run(); $this->aggregation_cron_was_missing = true; return; } $crons = _get_cron_array(); $args_key = md5( serialize( array() ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize $current = isset( $crons[ $timestamp ]['tptn_aggregation_cron_hook'][ $args_key ]['schedule'] ) ? $crons[ $timestamp ]['tptn_aggregation_cron_hook'][ $args_key ]['schedule'] : ''; if ( $current !== $interval ) { wp_clear_scheduled_hook( 'tptn_aggregation_cron_hook' ); self::enable_aggregation_run(); $this->aggregation_cron_interval_changed = true; } } /** * Show an admin notice when the aggregation cron was missing or rescheduled due to an interval change. * * @since 4.3.0 */ public function aggregation_cron_missing_notice() { if ( $this->aggregation_cron_interval_changed ) { ?>
' . esc_html( $hook ) . '', esc_html( $error['message'] ), esc_html( human_time_diff( $error['time'] ) ) ); ?>