$check ) { wp_schedule_single_event( time() + ( $i * 5 ), MIINTG_CRON_HOOK, array( $run_id, $check ) ); } // Nudges WP-Cron to fire on this request too, for sites with little // traffic between events. Harmless if it's already running. if ( ! defined( 'DOING_CRON' ) ) { spawn_cron(); } return $run_id; } /** * WP-Cron callback: runs exactly one check and records it. Never lets * an exception escape (a bad plugin manifest fetch, a filesystem error) * without marking that check's row 'error' — otherwise a run could sit * "running" forever with the admin UI showing perpetual progress. * * @param int $run_id Run id. * @param string $check Check name. */ function miintg_cron_run_check( $run_id, $check ) { try { $result = miintg_run_single_check( $check ); if ( null === $result ) { miintg_db_record_check( $run_id, $check, null, 'error' ); return; } $status = empty( $result['ok'] ) ? 'error' : 'complete'; miintg_db_record_check( $run_id, $check, $result, $status ); } catch ( Throwable $e ) { miintg_db_record_check( $run_id, $check, array( 'ok' => false, 'error' => $e->getMessage() ), 'error' ); } } /** * Clears any scan-related cron events on deactivation so a stale event * doesn't fire after the plugin is off. */ function miintg_scanner_deactivate() { $timestamp = wp_next_scheduled( MIINTG_CRON_HOOK ); while ( $timestamp ) { wp_unschedule_event( $timestamp, MIINTG_CRON_HOOK ); $timestamp = wp_next_scheduled( MIINTG_CRON_HOOK ); } }