hooks(); $this->register_adapters(); $this->register_cron(); Working_Dir::ensure(); // AJAX + download must register even when the request is admin-ajax / admin-post. ( new \BRVerify\Admin\Ajax() )->hooks(); ( new \BRVerify\Admin\Download() )->hooks(); // Phase K: opt-in pre-update backups. Hooks are always registered (auto-updates run in // cron/REST contexts); each entry point returns immediately while the setting is OFF. ( new \BRVerify\Updates\Pre_Update() )->hooks(); if ( is_admin() ) { ( new \BRVerify\Admin\Pre_Update_Notice() )->hooks(); ( new Admin() )->hooks(); ( new Settings_Page() )->hooks(); if ( class_exists( '\\BRVerify\\Admin\\Extras_Note' ) ) { ( new \BRVerify\Admin\Extras_Note() )->hooks(); } } /** * Fires after 007AJ Backup Restore Verifier free core has booted. * * extension modules may listen here at priority 20+. * * @param Plugin $plugin Plugin instance. */ do_action( 'brverify_booted', $this ); } /** * Register cron intervals + tick + scheduled backup handlers. */ private function register_cron(): void { add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) ); add_action( 'brverify_cron_tick', array( $this, 'cron_tick' ) ); $this->scheduler = new Scheduler(); $this->scheduler->hooks(); if ( ! wp_next_scheduled( 'brverify_cron_tick' ) ) { wp_schedule_event( time() + MINUTE_IN_SECONDS, 'brverify_five_minutes', 'brverify_cron_tick' ); } // Ensure backup schedule matches settings (idempotent). $interval = \BRVerify\Support\Settings::schedule_interval(); if ( \BRVerify\Support\Settings::INTERVAL_DISABLED !== $interval ) { if ( ! wp_next_scheduled( Scheduler::HOOK_SCHEDULED_BACKUP ) ) { $this->scheduler->reschedule(); } } } /** * Custom cron intervals. * * @param array> $schedules Schedules. * @return array> */ public function cron_schedules( array $schedules ): array { if ( ! isset( $schedules['brverify_five_minutes'] ) ) { $schedules['brverify_five_minutes'] = array( 'interval' => 5 * MINUTE_IN_SECONDS, 'display' => __( 'Every five minutes (007AJ Backup Restore Verifier)', '007aj-backup-restore-verifier' ), ); } if ( ! isset( $schedules['weekly'] ) ) { $schedules['weekly'] = array( 'interval' => WEEK_IN_SECONDS, 'display' => __( 'Once Weekly (007AJ Backup Restore Verifier)', '007aj-backup-restore-verifier' ), ); } return $schedules; } /** * Cron wakeup — resume claimable jobs. */ public function cron_tick(): void { ( new Job_Runner() )->cron_tick(); } /** * Scheduler accessor. */ public function scheduler(): Scheduler { if ( null === $this->scheduler ) { $this->scheduler = new Scheduler(); } return $this->scheduler; } /** * Seed free LocalAdapter; extended edition remotes register on plugins_loaded:25. * * Free boots at plugins_loaded:10; extended edition boots at :20 and hooks * `brverify_register_adapters`. Firing the action at :25 ensures * extended edition (and other add-ons) are subscribed before adapters are collected. * * Extension point for extended edition: * add_action( 'brverify_register_adapters', function( Adapter_Registry $r ) { … }, 20 ); */ private function register_adapters(): void { $this->adapters = new Adapter_Registry(); $this->adapters->register( new LocalAdapter() ); // Defer extension registration until after extended edition plugins_loaded:20 boot. if ( ! has_action( 'plugins_loaded', array( $this, 'fire_register_adapters' ) ) ) { add_action( 'plugins_loaded', array( $this, 'fire_register_adapters' ), 25 ); } } /** * Fire adapter registration hook (Local already seeded). */ public function fire_register_adapters(): void { if ( null === $this->adapters ) { $this->adapters = new Adapter_Registry(); $this->adapters->register( new LocalAdapter() ); } /** * Register storage adapters. * * Free ships LocalAdapter only. extended edition registers remote adapters here. * Do not add activation SDKs or feature gates in the free tree. * * @param Adapter_Registry $registry Adapter registry. */ do_action( 'brverify_register_adapters', $this->adapters ); } /** * Adapter registry accessor. */ public function adapters(): Adapter_Registry { if ( null === $this->adapters ) { $this->register_adapters(); } return $this->adapters; } /** * Map manage_brverify → manage_options on single-site. * * @param string[] $caps Primitive caps. * @param string $cap Meta cap. * @return string[] */ public function map_meta_cap( array $caps, string $cap ): array { if ( 'manage_brverify' === $cap && ! is_multisite() ) { return array( 'manage_options' ); } return $caps; } }