register(); } private static function registerFrontendHooks(): void { // --- Sprint 4: Schema Injection + Conflict Detection --- // Three-tier strategy: Audit (always) → Advisory (conflicts) → Inject (no conflicts) $conflictDetector = self::$conflictDetector; // Frontend: Schema injection if (!is_admin()) { $apiKey = LicenseStorage::getApiKey(); if ($apiKey) { $client = new Client($apiKey); $injector = new Injector($client, $conflictDetector, new SchemaCollector()); $injector->register(); // Clear all Schema cache after scan completes (ADR-012 trigger 3) add_action('geolens_scan_completed', static function () use ($injector): void { $injector->clearAllCache(); }); } } // Expose ConflictDetector status to Admin Dashboard (Sprint 5) add_filter('geolens_conflict_status', static function () use ($conflictDetector): array { return $conflictDetector->getStatusSummary(); }); } private static function registerAdminHooks(): void { // --- Sprint 5: Admin UI --- $apiKey = LicenseStorage::getApiKey(); // Admin Pages $dashboardPage = new DashboardPage(); $pricingPage = new PricingPage(); $settingsPage = new SettingsPage(); $visibilityPage = new \GeoLens\Admin\Pages\VisibilityPage(); // AdminLoader (menu + asset enqueue) $adminLoader = new AdminLoader($dashboardPage, $pricingPage, $settingsPage, $visibilityPage); $adminLoader->register(); // AjaxHandler (unified AJAX entry point) // // 未授權時沒有金鑰、無法建立 Client(Client 拒絕空字串),故傳 null; // AjaxHandler::register() 只會註冊「取得金鑰」用的兩個 hook // (register_free / activate_license),其餘需授權的操作不註冊。 $client = $apiKey ? new Client($apiKey) : null; $licenseManager = $client ? new LicenseManager($client) : null; $ajaxHandler = new AjaxHandler( $client, $licenseManager, self::$conflictDetector, new LicenseManagerFactory() ); $ajaxHandler->register(); } public static function handleDailyLicenseCheck(): void { $apiKey = LicenseStorage::getApiKey(); if (! $apiKey) { return; } $client = new Client($apiKey); $licenseManager = new LicenseManager($client); $result = $licenseManager->verify(forceRefresh: true); if (is_wp_error($result)) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log error_log('[GeoLens] Daily license check failed: ' . $result->get_error_message()); } } /** * Reset state for testing purposes. * * @internal */ public static function reset(): void { self::$initialized = false; self::$conflictDetector = null; } }