=' ) ); /** * Filters whether WooCommerce-dependent features should load. * * @param bool $active Whether a supported WooCommerce version is active. */ return (bool) apply_filters( 'aicommerce_has_woocommerce', $active ); } /** * Render a score badge HTML fragment. * * Shared helper used by Elementor, Divi, Bricks, and shortcode integrations. * * @param int $score The AI readiness score (0-100). * @param string $style Display style: 'badge', 'bar', or 'minimal'. * @param bool $show_label Whether to show the "AI Visibility Score" label. * @param string $color Primary color (hex). * @param string $font_size Font size with unit (e.g., '24px'). * * @return string HTML markup. */ function aicommerce_render_score_badge( int $score, string $style = 'badge', bool $show_label = true, string $color = '#00e58a', string $font_size = '24px' ): string { $html = '
'; if ( 'badge' === $style ) { $html .= '
'; $html .= '' . esc_html( (string) $score ) . ''; $html .= '
'; } elseif ( 'bar' === $style ) { $html .= '
'; $html .= '
'; $html .= '
'; $html .= '' . esc_html( (string) $score ) . '/100'; } else { $html .= '' . esc_html( (string) $score ) . ''; } if ( $show_label ) { $html .= '

' . esc_html__( 'AI Visibility Score', 'ai-discoverability-kit' ) . '

'; } $html .= '
'; return $html; } /** * Declare HPOS compatibility. */ add_action( 'before_woocommerce_init', static function (): void { if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); } } ); /** * Declare WooCommerce Blocks compatibility. */ add_action( 'before_woocommerce_init', static function (): void { if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true ); } } ); /** * Check PHP version compatibility before loading. */ if ( version_compare( PHP_VERSION, AICOMMERCE_MIN_PHP_VERSION, '<' ) ) { add_action( 'admin_notices', static function (): void { printf( '

%s

', esc_html( sprintf( /* translators: 1: Required PHP version 2: Current PHP version */ __( 'Tyralix AI Discoverability requires PHP %1$s or higher. You are running PHP %2$s. Please upgrade your PHP version.', 'ai-discoverability-kit' ), AICOMMERCE_MIN_PHP_VERSION, PHP_VERSION ) ) ); } ); return; } /** * PSR-4 autoloader for the plugin's own classes. * * The plugin has no third-party runtime dependencies, so it ships without a * Composer vendor directory and registers a lightweight autoloader that maps * the AICommerce\ namespace to the src/ directory. * * @param string $class_name Fully-qualified class name being loaded. * * @return void */ spl_autoload_register( static function ( string $class_name ): void { $prefix = 'AICommerce\\'; $length = strlen( $prefix ); if ( 0 !== strncmp( $prefix, $class_name, $length ) ) { return; } $relative = substr( $class_name, $length ); $file = AICOMMERCE_PLUGIN_DIR . 'src/' . str_replace( '\\', '/', $relative ) . '.php'; if ( is_readable( $file ) ) { require_once $file; } } ); /** * Boot the plugin after all plugins are loaded. * * WooCommerce is optional. When it is present, ecommerce features (product * schema, feeds, agentic commerce) load automatically; otherwise the plugin * runs its website/article/page schema, llms.txt, and crawler features. */ add_action( 'plugins_loaded', static function (): void { // Gentle warning only if WooCommerce is present but below the supported version. if ( class_exists( 'WooCommerce' ) && defined( 'WC_VERSION' ) && version_compare( WC_VERSION, AICOMMERCE_MIN_WC_VERSION, '<' ) ) { add_action( 'admin_notices', static function (): void { printf( '

%s

', esc_html( sprintf( /* translators: 1: Required WC version 2: Current WC version */ __( 'Tyralix AI Discoverability: WooCommerce %1$s or higher is recommended for ecommerce features. You are running WooCommerce %2$s.', 'ai-discoverability-kit' ), AICOMMERCE_MIN_WC_VERSION, WC_VERSION ) ) ); } ); } // Boot the plugin (with or without WooCommerce). $container = new \AICommerce\Core\ServiceContainer(); $plugin = new \AICommerce\Core\Plugin( $container ); $plugin->boot(); }, 0 ); /** * Run activation tasks for a single site. * * @return void */ function aicommerce_activate_site(): void { update_option( 'aicommerce_db_version', '0.0.0', false ); $defaults = array( 'aicommerce_schema_enabled' => array( 'value' => true, 'autoload' => true, ), 'aicommerce_site_schema_enabled' => array( 'value' => true, 'autoload' => true, ), 'aicommerce_conflict_suppress' => array( 'value' => true, 'autoload' => true, ), 'aicommerce_onboarding_complete' => array( 'value' => false, 'autoload' => false, ), ); foreach ( $defaults as $key => $meta ) { if ( false === get_option( $key ) ) { add_option( $key, $meta['value'], '', $meta['autoload'] ? 'yes' : 'no' ); } } flush_rewrite_rules(); } /** * Activation hook. */ register_activation_hook( __FILE__, static function ( bool $network_wide = false ): void { if ( version_compare( get_bloginfo( 'version' ), AICOMMERCE_MIN_WP_VERSION, '<' ) ) { wp_die( esc_html( sprintf( /* translators: %s: Required WP version */ __( 'Tyralix AI Discoverability requires WordPress %s or higher.', 'ai-discoverability-kit' ), AICOMMERCE_MIN_WP_VERSION ) ), esc_html__( 'Plugin Activation Error', 'ai-discoverability-kit' ), array( 'back_link' => true ) ); } if ( is_multisite() && $network_wide ) { $sites = get_sites( array( 'number' => 0, 'fields' => 'ids', ) ); foreach ( $sites as $site_id ) { switch_to_blog( $site_id ); aicommerce_activate_site(); restore_current_blog(); } } else { aicommerce_activate_site(); } } ); // Multisite: set up new blogs when they are created on the network. if ( is_multisite() ) { add_action( 'wp_initialize_site', static function ( $new_site ): void { if ( ! is_plugin_active_for_network( AICOMMERCE_PLUGIN_BASENAME ) ) { return; } switch_to_blog( $new_site->blog_id ); aicommerce_activate_site(); restore_current_blog(); }, 100 ); } /** * Deactivation hook. */ register_deactivation_hook( __FILE__, static function (): void { // Clear any scheduled Action Scheduler hooks. if ( function_exists( 'as_unschedule_all_actions' ) ) { as_unschedule_all_actions( 'aicommerce_generate_feed' ); as_unschedule_all_actions( 'aicommerce_crawl_monitor' ); } // Clear rewrite rules. flush_rewrite_rules(); } );