slug => display name of active SEO/schema plugins */ public static function detect_seo_plugins() { $found = []; if ( defined( 'WPSEO_VERSION' ) ) $found['yoast'] = 'Yoast SEO'; if ( class_exists( 'RankMath' ) ) $found['rankmath'] = 'Rank Math'; if ( defined( 'AIOSEO_VERSION' ) || function_exists( 'aioseo' ) ) $found['aioseo'] = 'All in One SEO'; if ( defined( 'SEOPRESS_VERSION' ) ) $found['seopress'] = 'SEOPress'; if ( class_exists( 'The_SEO_Framework\\Load' ) || function_exists( 'the_seo_framework' ) ) $found['tsf'] = 'The SEO Framework'; if ( defined( 'SCHEMA_PRO_VERSION' ) || class_exists( 'Schema_Pro' ) ) $found['schemapro'] = 'Schema Pro'; return $found; } public static function seo_plugin_active() { return ! empty( self::detect_seo_plugins() ); } /** * Should we emit the WebPage + BreadcrumbList nodes? * In 'auto' mode we defer these to an active SEO plugin (which already emits them) * and only output our unique value (entity about[] + FAQPage). */ public static function should_emit_page_schema() { $mode = Semantic_Settings::schema_compat_mode(); // auto | full if ( $mode === 'full' ) return true; return ! self::seo_plugin_active(); } /** * Detect whether another plugin already serves /llms.txt, either as a * physical file or by a known AI/SEO plugin that registers the route. */ public static function llms_txt_owned_elsewhere() { // Physical file on disk takes precedence over any rewrite rule if ( file_exists( ABSPATH . 'llms.txt' ) ) return 'file'; // Known plugins that also output llms.txt if ( defined( 'RANKMATH_VERSION' ) && class_exists( 'RankMath\\Llms_Txt' ) ) return 'Rank Math'; return false; } }