Automattic\WooCommerce\Internal\Features

FeaturesController::init_feature_definitions │ private │ WC 1.0

Initialize the hardcoded feature definitions array. This doesn't include:

  • Features that get initialized via the (deprecated) woocommerce_register_feature_definitions.
  • Features whose definition comes from another class. These are initialized directly in get_feature_definitions to avoid circular calls in the dependency injection container.

Method of the class: FeaturesController{}

No Hooks.

Returns

null. Nothing (null).

Usage

// private - for code of main (parent) class only
$result = $this->init_feature_definitions(): void;

FeaturesController::init_feature_definitions() code WC 11.2.1

private function init_feature_definitions(): void {
	$alpha_feature_testing_is_enabled = Constants::is_true( 'WOOCOMMERCE_ENABLE_ALPHA_FEATURE_TESTING' );
	$tracking_enabled                 = WC_Site_Tracking::is_tracking_enabled();

	$legacy_features = array(
		'analytics'                            => array(
			'name'                         => __( 'WooCommerce Analytics', 'woocommerce' ),
			'description'                  => __( 'Enable WooCommerce Analytics to track your store\'s key metrics and view them in a detailed dashboard. All data stays within your store.', 'woocommerce' ),
			'option_key'                   => Analytics::TOGGLE_OPTION_NAME,
			'is_experimental'              => false,
			'enabled_by_default'           => true,
			'disable_ui'                   => false,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		ProductMediaGallery::FEATURE_ID        => array(
			'name'                         => __( 'Product gallery videos', 'woocommerce' ),
			'description'                  => __( 'Enable videos in product galleries.', 'woocommerce' ),
			'option_key'                   => ProductMediaGallery::ENABLE_OPTION_NAME,
			'is_experimental'              => true,
			'enabled_by_default'           => false,
			'disable_ui'                   => false,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		'cart_checkout_blocks'                 => array(
			'name'                         => __( 'Cart & Checkout Blocks', 'woocommerce' ),
			'description'                  => __( 'Optimize for faster checkout', 'woocommerce' ),
			'is_experimental'              => false,
			'disable_ui'                   => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		'rate_limit_checkout'                  => array(
			'name'                         => __( 'Rate limit Checkout', 'woocommerce' ),
			'description'                  => sprintf(
				// translators: %s is the URL to the rate limiting documentation.
				__( 'Enables rate limiting for Checkout place order and Store API /checkout endpoint. To further control this, refer to <a href="%s" target="_blank">rate limiting documentation</a>.', 'woocommerce' ),
				'https://developer.woocommerce.com/docs/apis/store-api/rate-limiting/'
			),
			'is_experimental'              => false,
			'disable_ui'                   => false,
			'enabled_by_default'           => false,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		'marketplace'                          => array(
			'name'                         => __( 'Marketplace', 'woocommerce' ),
			'description'                  => __(
				'New, faster way to find extensions and themes for your WooCommerce store',
				'woocommerce'
			),
			'is_experimental'              => false,
			'enabled_by_default'           => true,
			'disable_ui'                   => true,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'deprecated_since'             => '10.5.0',
			'deprecated_value'             => true,
		),
		'order_withdrawal'                     => array(
			'name'                         => __( 'Order withdrawal', 'woocommerce' ),
			'description'                  => __( 'Enable the public order withdrawal feature for customer requests.', 'woocommerce' ),
			'learn_more_url'               => 'https://woocommerce.com/document/customer-order-withdrawal/',
			'enabled_by_default'           => false,
			'disable_ui'                   => false,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'is_experimental'              => false,
		),
		// Marked as a legacy feature to avoid compatibility checks, which aren't really relevant to this feature.
		// https://github.com/woocommerce/woocommerce/pull/39701#discussion_r1376976959.
		'order_attribution'                    => array(
			'name'                         => __( 'Order Attribution', 'woocommerce' ),
			'description'                  => __(
				'Enable this feature to track and credit channels and campaigns that contribute to orders on your site',
				'woocommerce'
			),
			'enabled_by_default'           => true,
			'disable_ui'                   => false,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'is_experimental'              => false,
		),
		'site_visibility_badge'                => array(
			'name'                         => __( 'Site visibility badge', 'woocommerce' ),
			'description'                  => __(
				'Enable the site visibility badge in the WordPress admin bar',
				'woocommerce'
			),
			'enabled_by_default'           => true,
			'disable_ui'                   => true,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'is_experimental'              => false,
			'disabled'                     => false,
		),
		'hpos_fts_indexes'                     => array(
			'name'                         => __( 'HPOS Full text search indexes', 'woocommerce' ),
			'description'                  => __(
				'Create and use full text search indexes for orders. This feature only works with high-performance order storage.',
				'woocommerce'
			),
			'is_experimental'              => true,
			'enabled_by_default'           => false,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'option_key'                   => CustomOrdersTableController::HPOS_FTS_INDEX_OPTION,
		),
		'hpos_datastore_caching'               => array(
			'name'                         => __( 'HPOS Data Caching', 'woocommerce' ),
			'description'                  => __(
				'Enable order data caching in the datastore. This feature only works with high-performance order storage and is recommended for stores using object caching.',
				'woocommerce'
			),
			'is_experimental'              => false,
			'enabled_by_default'           => false,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'disable_ui'                   => false,
			'option_key'                   => CustomOrdersTableController::HPOS_DATASTORE_CACHING_ENABLED_OPTION,
		),
		'remote_logging'                       => array(
			'name'                         => __( 'Remote Logging', 'woocommerce' ),
			'description'                  => sprintf(
				/* translators: %1$s: opening link tag, %2$s: closing link tag */
				__( 'Allow WooCommerce to send error logs and non-sensitive diagnostic data to help improve WooCommerce. This feature requires %1$susage tracking%2$s to be enabled.', 'woocommerce' ),
				'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=advanced&section=woocommerce_com' ) . '">',
				'</a>'
			),
			'enabled_by_default'           => true,
			'disable_ui'                   => false,

			/*
			 * This is not truly a legacy feature (it is not a feature that pre-dates the FeaturesController),
			 * but we wish to handle compatibility checking in a similar fashion to legacy features. The
			 * rational for setting legacy to true is therefore similar to that of the 'order_attribution'
			 * feature.
			 *
			 * @see https://github.com/woocommerce/woocommerce/pull/39701#discussion_r1376976959
			 */
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'is_experimental'              => false,
			'setting'                      => array(
				'disabled' => function () use ( $tracking_enabled ) {
					return ! $tracking_enabled;
				},
				'desc_tip' => function () use ( $tracking_enabled ) {
					if ( ! $tracking_enabled ) {
						return __( '⚠ Usage tracking must be enabled to use remote logging.', 'woocommerce' );
					}

					return '';
				},
			),
		),
		'deferred_transactional_emails'        => array(
			'name'                         => __( 'Deferred emails', 'woocommerce' ),
			'description'                  => __(
				'Send transactional emails asynchronously via Action Scheduler instead of during the current request.',
				'woocommerce'
			),
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'enabled_by_default'           => false,
			'is_experimental'              => false,
		),
		'customer_review_request'              => array(
			'name'                         => __( 'Customer review request (beta)', 'woocommerce' ),
			'description'                  => __(
				'Send customers a transactional email after order completion inviting them to review the products they bought, and host the per-order Review Order landing page.',
				'woocommerce'
			),
			// Skip compatibility checks like the other opt-in transactional-email features.
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'enabled_by_default'           => false,
			'is_experimental'              => false,
		),
		'email_improvements'                   => array(
			'name'                         => __( 'Email improvements', 'woocommerce' ),
			'description'                  => __(
				'Enable modern email design for transactional emails',
				'woocommerce'
			),

			/*
			 * This is not truly a legacy feature (it is not a feature that pre-dates the FeaturesController),
			 * but as this feature doesn't affect all extensions, and the rollout is fairly short,
			 * we'll skip the compatibility check by marking this as legacy. This is a workaround until
			 * we can implement a more sophisticated compatibility checking system.
			 *
			 * @see https://github.com/woocommerce/woocommerce/issues/39147
			 * @see https://github.com/woocommerce/woocommerce/issues/55540
			 */
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'is_experimental'              => false,
		),
		'blueprint'                            => array(
			'name'                         => __( 'Blueprint (beta)', 'woocommerce' ),
			'description'                  => __(
				'Enable blueprint to import and export settings in bulk',
				'woocommerce'
			),
			'enabled_by_default'           => true,
			'disable_ui'                   => false,

			/*
			* This is not truly a legacy feature (it is not a feature that pre-dates the FeaturesController),
			* but we wish to handle compatibility checking in a similar fashion to legacy features. The
			* rational for setting legacy to true is therefore similar to that of the 'order_attribution'
			* feature.
			*
			* @see https://github.com/woocommerce/woocommerce/pull/39701#discussion_r1376976959
			*/
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'is_experimental'              => false,
		),
		'block_email_editor'                   => array(
			'name'                         => __( 'Block Email Editor (alpha)', 'woocommerce' ),
			'description'                  => __(
				'Enable the block-based email editor for transactional emails.',
				'woocommerce'
			),
			'learn_more_url'               => 'https://github.com/woocommerce/woocommerce/discussions/52897#discussioncomment-11630256',

			/*
			* This is not truly a legacy feature (it is not a feature that pre-dates the FeaturesController),
			* but we wish to handle compatibility checking in a similar fashion to legacy features. The
			* rational for setting legacy to true is therefore similar to that of the 'order_attribution'
			* feature.
			*
			* @see https://github.com/woocommerce/woocommerce/pull/39701#discussion_r1376976959
			*/
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'enabled_by_default'           => false,
		),
		\Automattic\WooCommerce\Internal\VariationGallery\Package::FEATURE_ID => array(
			'name'                         => __( 'Variation gallery', 'woocommerce' ),
			'description'                  => __( 'Add multiple images per product variation.', 'woocommerce' ),
			'is_experimental'              => false,
			'enabled_by_default'           => true,
			'disable_ui'                   => true,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'deprecated_since'             => '11.1.0',
			'deprecated_value'             => true,
		),
		'wc-visual-attribute'                  => array(
			'name'                         => __( 'Color swatches for attributes', 'woocommerce' ),
			'description'                  => __(
				'Add color swatches to product attribute values.',
				'woocommerce'
			),
			'option_key'                   => 'woocommerce_feature_wc_visual_attribute_enabled',
			'is_experimental'              => true,
			'enabled_by_default'           => false,
			'disable_ui'                   => false,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		'point_of_sale'                        => array(
			'name'                         => __( 'Point of Sale', 'woocommerce' ),
			'description'                  => __(
				'Enable Point of Sale functionality in the WooCommerce mobile apps.',
				'woocommerce'
			),
			'is_experimental'              => false,
			'enabled_by_default'           => true,
			'disable_ui'                   => true,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'deprecated_since'             => '11.0.0',
			'deprecated_value'             => true,
		),
		'point_of_sale_staff'                  => array(
			'name'                         => __( 'POS staff', 'woocommerce' ),
			'description'                  => __(
				'Experimental: POS staff management, roles, and order attribution.',
				'woocommerce'
			),
			'enabled_by_default'           => false,
			// Hidden while incomplete so it can't ship merchant-toggleable; flip to
			// false when it's ready for an experimental preview.
			'disable_ui'                   => true,
			'is_experimental'              => true,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		'fulfillments'                         => array(
			'name'                         => __( 'Order Fulfillments', 'woocommerce' ),
			'description'                  => __(
				'Enable the Order Fulfillments feature to manage order fulfillment and shipping.',
				'woocommerce'
			),
			'enabled_by_default'           => false,
			'disable_ui'                   => true,
			'is_experimental'              => false,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		'mcp_integration'                      => array(
			'name'                         => __( 'WooCommerce MCP', 'woocommerce' ),
			'description'                  => $this->get_mcp_integration_description(),
			'enabled_by_default'           => false,
			'disable_ui'                   => false,
			'is_experimental'              => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'is_legacy'                    => false,
		),
		'destroy-empty-sessions'               => array(
			'name'                         => __( 'Clear Customer Sessions When Empty', 'woocommerce' ),
			'description'                  => __(
				'[Performance] Removes session cookies for non-logged in customers when session data is empty, improving page caching performance. May cause compatibility issues with extensions that depend on the session cookie without using session data.',
				'woocommerce'
			),
			'enabled_by_default'           => false,
			'is_experimental'              => true,
			'disable_ui'                   => false,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		PushNotifications::FEATURE_NAME        => array(
			'name'                         => __( 'Push Notifications', 'woocommerce' ),
			'description'                  => __(
				'Enable push notifications for the WooCommerce mobile apps to receive order notifications and store updates.',
				'woocommerce'
			),
			'is_experimental'              => false,
			'enabled_by_default'           => true,
			'disable_ui'                   => true,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'deprecated_since'             => '10.9.2',
			'deprecated_value'             => true,
		),
		'rest_api_caching'                     => array(
			'name'                         => __( 'REST API Caching', 'woocommerce' ),
			'description'                  => sprintf(
				/* translators: %1$s and %2$s are opening and closing <a> tags */
				__( 'Enable backend caching and cache control headers for REST API responses via the <code>RestApiCache</code> trait. ⚙️ %1$sConfiguration%2$s', 'woocommerce' ),
				'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=advanced&section=rest_api_caching' ) . '">',
				'</a>'
			),
			'enabled_by_default'           => false,
			'is_experimental'              => true,
			'disable_ui'                   => false,
			'skip_compatibility_checks'    => true,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		'cart_save_for_later'                  => array(
			'name'                         => __( 'Save for Later in Cart', 'woocommerce' ),
			'description'                  => __(
				'Let shoppers save cart items to a list to purchase later.',
				'woocommerce'
			),
			'is_experimental'              => true,
			'enabled_by_default'           => false,
			// Custom option_key as we expect this setting to move out of features to
			// a cart/checkout settings section.
			'option_key'                   => 'woocommerce_cart_save_for_later_enabled',
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		'product_wishlist'                     => array(
			'name'                         => __( 'Wishlists', 'woocommerce' ),
			'description'                  => __(
				'Let shoppers save products to a wishlist from product pages. Requires the Add to Cart + Options block on the single-product template.',
				'woocommerce'
			),
			'is_experimental'              => true,
			'enabled_by_default'           => false,
			'option_key'                   => 'woocommerce_product_wishlist_enabled',
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		ProductCacheController::FEATURE_NAME   => array(
			'name'                         => __( 'Cache Product Objects', 'woocommerce' ),
			'description'                  => __(
				'[Performance] Speeds up your store by caching product objects during each request, preventing duplicate product loads. Can improve page load times on product-heavy pages.',
				'woocommerce'
			),
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'enabled_by_default'           => false,
			'is_experimental'              => true,
			'disable_ui'                   => false,
		),
		StockNotifications::FEATURE_NAME       => array(
			'name'                         => __( 'Back in Stock Notifications', 'woocommerce' ),
			'description'                  => __(
				'Allow customers to sign up to receive an email when an out-of-stock product is back in stock.',
				'woocommerce'
			),
			'option_key'                   => StockNotifications::ENABLE_OPTION_NAME,
			'enabled_by_default'           => false,
			'is_experimental'              => true,
			'disable_ui'                   => false,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
		),
		BlockEditorUnifiedAssets::FEATURE_NAME => array(
			'name'                         => __( 'Unified block editor assets', 'woocommerce' ),
			'description'                  => __( 'Load WooCommerce block editor scripts and styles from shared bundles to improve editor performance.', 'woocommerce' ),
			'option_key'                   => BlockEditorUnifiedAssets::OPTION_NAME,
			'default_plugin_compatibility' => FeaturePluginCompatibility::COMPATIBLE,
			'enabled_by_default'           => false,
			'is_experimental'              => true,
			'disable_ui'                   => false,
		),
	);

	if ( ! $tracking_enabled ) {
		// Uncheck the remote logging feature when usage tracking is disabled.
		$legacy_features['remote_logging']['setting']['value'] = 'no';
	}

	foreach ( $legacy_features as $slug => $definition ) {
		$this->add_feature_definition( $slug, $definition['name'], $definition );
	}

	// Preload option caches to minimize future queries for options that do not yet exist or are not set to autoload.
	wp_prime_option_caches(
		array_map(
			static fn( $slug, $definition ) => $definition['option_key'] ?? sprintf( 'woocommerce_feature_%s_enabled', $slug ),
			array_keys( $this->features ),
			$this->features
		)
	);

	$this->init_compatibility_info_by_feature();
}