client_registration = $client_registration; $this->logger = new NullLogger(); } /** * Returns the conditionals based on which this integration should be loaded. * * @return array The array of conditionals. */ public static function get_conditionals() { return [ MyYoast_Connection_Conditional::class ]; } /** * Registers hooks. * * @return void */ public function register_hooks() { \add_action( 'admin_init', [ $this, 'schedule_key_rotation' ] ); \add_action( self::CRON_HOOK, [ $this, 'handle_key_rotation' ] ); \add_action( 'wpseo_deactivate', [ $this, 'unschedule_key_rotation' ] ); // phpcs:ignore WordPress.WP.CronInterval -- The sniff doesn't understand the self::ROTATION_INTERVAL_IN_DAYS reference. \add_filter( 'cron_schedules', [ $this, 'add_cron_schedule' ] ); } /** * Adds a 90-day cron schedule. * * @param array> $schedules Existing cron schedules. * * @return array> Modified schedules. */ public function add_cron_schedule( $schedules ) { if ( ! \is_array( $schedules ) ) { $schedules = []; } $schedules[ self::ROTATION_INTERVAL ] = [ 'interval' => ( self::ROTATION_INTERVAL_IN_DAYS * \DAY_IN_SECONDS ), 'display' => \esc_html__( 'Every 90 days', 'wordpress-seo' ), ]; return $schedules; } /** * Schedules the key rotation cron job if not already scheduled. * * @return void */ public function schedule_key_rotation(): void { if ( ! \wp_next_scheduled( self::CRON_HOOK ) ) { \wp_schedule_event( ( \time() + ( self::ROTATION_INTERVAL_IN_DAYS * \DAY_IN_SECONDS ) ), self::ROTATION_INTERVAL, self::CRON_HOOK ); } } /** * Clears all scheduled key rotation events. * * @return void */ public function unschedule_key_rotation(): void { \wp_clear_scheduled_hook( self::CRON_HOOK ); } /** * Handles the key rotation cron event. * * @return void */ public function handle_key_rotation(): void { try { $this->client_registration->rotate_registration_keys(); } catch ( Exception $e ) { // Best-effort — log but don't crash cron. $this->logger->warning( 'Yoast MyYoast key rotation failed: {error}', [ 'error' => $e->getMessage() ] ); } } }