=' ) );
/**
* 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(
'',
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(
'',
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();
}
);