[ 'name' => 'Yoast SEO', 'class' => 'WPSEO', 'function' => 'wpseo_init', 'file' => 'wordpress-seo/wp-seo.php', ], 'rankmath' => [ 'name' => 'Rank Math', 'class' => 'RankMath', 'function' => 'rank_math', 'file' => 'seo-by-rank-math/rank-math.php', ], 'seopress' => [ 'name' => 'SEOPress', 'class' => 'SEOPress', 'function' => 'seopress_init', 'file' => 'wp-seopress/seopress.php', ], 'aioseo' => [ 'name' => 'All in One SEO', 'class' => 'AIOSEO', 'function' => 'aioseo', 'file' => 'all-in-one-seo-pack/all_in_one_seo_pack.php', ], 'theseoframework' => [ 'name' => 'The SEO Framework', 'class' => 'The_SEO_Framework\\Load', 'function' => 'the_seo_framework', 'file' => 'autodescription/autodescription.php', ], ]; /** * Detected plugins cache * * @var array|null */ private static ?array $detected_plugins = null; /** * Detect active SEO plugins * * @return array Detected plugins */ public static function detect_plugins(): array { if (self::$detected_plugins !== null) { return self::$detected_plugins; } self::$detected_plugins = []; foreach (self::KNOWN_PLUGINS as $slug => $plugin) { if (self::is_plugin_active($plugin)) { self::$detected_plugins[$slug] = $plugin; } } return self::$detected_plugins; } /** * Check if any SEO plugins are active * * @return bool True if SEO plugins detected */ public static function has_seo_plugins(): bool { return !empty(self::detect_plugins()); } /** * Get detected plugin names * * @return array Plugin names */ public static function get_plugin_names(): array { $detected = self::detect_plugins(); return array_column($detected, 'name'); } /** * Check if a specific plugin is active * * @param string $slug Plugin slug * @return bool True if plugin is active */ public static function is_plugin_detected(string $slug): bool { $detected = self::detect_plugins(); return isset($detected[$slug]); } /** * Check if a plugin is active * * @param array $plugin Plugin configuration * @return bool True if plugin is active */ private static function is_plugin_active(array $plugin): bool { // Check by class if (!empty($plugin['class']) && class_exists($plugin['class'])) { return true; } // Check by function if (!empty($plugin['function']) && function_exists($plugin['function'])) { return true; } // Check by plugin file if (!empty($plugin['file']) && function_exists('is_plugin_active') && is_plugin_active($plugin['file'])) { return true; } return false; } /** * Get admin notice message * * @return string Notice message */ public static function get_notice_message(): string { $plugin_names = self::get_plugin_names(); if (empty($plugin_names)) { return ''; } $plugin_list = implode(', ', $plugin_names); return sprintf( /* translators: %s: comma-separated list of detected SEO plugin names */ __('⚠️ SEO Plugin Detected: %s. ThinkRank will take priority for posts where you generate AI metadata. Consider disabling other SEO plugins for best results.', 'thinkrank'), $plugin_list ); } /** * Should show admin notice * * @return bool True if should show notice */ public static function should_show_notice(): bool { // Only show if SEO plugins detected if (!self::has_seo_plugins()) { return false; } // Show on admin pages (not just ThinkRank pages) if (!is_admin()) { return false; } // Check if user dismissed the notice $dismissed = get_user_meta(get_current_user_id(), 'thinkrank_seo_notice_dismissed', true); if ($dismissed) { return false; } return true; } /** * Dismiss notice for current user * * @return void */ public static function dismiss_notice(): void { update_user_meta(get_current_user_id(), 'thinkrank_seo_notice_dismissed', true); } /** * Reset notice dismissal (for testing) * * @return void */ public static function reset_notice(): void { delete_user_meta(get_current_user_id(), 'thinkrank_seo_notice_dismissed'); } }