udes/rest-api/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php' ), 'WC_REST_Product_Brands_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-brands-controller.php' ), 'WC_REST_Product_Brands_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-brands-v2-controller.php' ), 'WC_REST_Product_Categories_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-categories-controller.php' ), 'WC_REST_Product_Categories_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php' ), 'WC_REST_Product_Categories_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php' ), 'WC_REST_Product_Custom_Fields_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-custom-fields-controller.php' ), 'WC_REST_Product_Reviews_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php' ), 'WC_REST_Product_Reviews_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php' ), 'WC_REST_Product_Reviews_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php' ), 'WC_REST_Product_Shipping_Classes_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php' ), 'WC_REST_Product_Shipping_Classes_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php' ), 'WC_REST_Product_Shipping_Classes_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php' ), 'WC_REST_Product_Tags_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-tags-controller.php' ), 'WC_REST_Product_Tags_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php' ), 'WC_REST_Product_Tags_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php' ), 'WC_REST_Product_Variations_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php' ), 'WC_REST_Product_Variations_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php' ), 'WC_REST_Products_Catalog_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-products-catalog-controller.php' ), 'WC_REST_Products_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php' ), 'WC_REST_Products_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php' ), 'WC_REST_Products_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php' ), 'WC_REST_Refunds_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-refunds-controller.php' ), 'WC_REST_Report_Coupons_Totals_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php' ), 'WC_REST_Report_Customers_Totals_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php' ), 'WC_REST_Report_Orders_Totals_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php' ), 'WC_REST_Report_Products_Totals_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php' ), 'WC_REST_Report_Reviews_Totals_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php' ), 'WC_REST_Report_Sales_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-sales-controller.php' ), 'WC_REST_Report_Sales_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php' ), 'WC_REST_Report_Sales_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php' ), 'WC_REST_Report_Top_Sellers_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php' ), 'WC_REST_Report_Top_Sellers_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php' ), 'WC_REST_Report_Top_Sellers_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php' ), 'WC_REST_Reports_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-reports-controller.php' ), 'WC_REST_Reports_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php' ), 'WC_REST_Reports_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-reports-v2-controller.php' ), 'WC_REST_Setting_Options_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php' ), 'WC_REST_Setting_Options_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php' ), 'WC_REST_Settings_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php' ), 'WC_REST_Settings_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php' ), 'WC_REST_Settings_V4_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version4/class-wc-rest-settings-v4-controller.php' ), 'WC_REST_Shipping_Methods_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-methods-controller.php' ), 'WC_REST_Shipping_Methods_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php' ), 'WC_REST_Shipping_Zone_Locations_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php' ), 'WC_REST_Shipping_Zone_Locations_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php' ), 'WC_REST_Shipping_Zone_Methods_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php' ), 'WC_REST_Shipping_Zone_Methods_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php' ), 'WC_REST_Shipping_Zones_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller.php' ), 'WC_REST_Shipping_Zones_Controller_Base' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php' ), 'WC_REST_Shipping_Zones_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php' ), 'WC_REST_System_Status_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-system-status-controller.php' ), 'WC_REST_System_Status_Tools_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-system-status-tools-controller.php' ), 'WC_REST_System_Status_Tools_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php' ), 'WC_REST_System_Status_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php' ), 'WC_REST_Tax_Classes_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-tax-classes-controller.php' ), 'WC_REST_Tax_Classes_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php' ), 'WC_REST_Tax_Classes_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php' ), 'WC_REST_Taxes_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-taxes-controller.php' ), 'WC_REST_Taxes_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php' ), 'WC_REST_Taxes_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-taxes-v2-controller.php' ), 'WC_REST_Telemetry_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Telemetry/class-wc-rest-telemetry-controller.php' ), 'WC_REST_Terms_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php' ), 'WC_REST_V4_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version4/class-wc-rest-v4-controller.php' ), 'WC_REST_Variations_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-variations-controller.php' ), 'WC_REST_Webhook_Deliveries_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php' ), 'WC_REST_Webhook_Deliveries_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php' ), 'WC_REST_Webhooks_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-webhooks-controller.php' ), 'WC_REST_Webhooks_V1_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php' ), 'WC_REST_Webhooks_V2_Controller' => array( 'version' => '10.8.1.0', 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php' ), 'WP\\MCP\\Abilities\\DiscoverAbilitiesAbility' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Abilities/DiscoverAbilitiesAbility.php' ), 'WP\\MCP\\Abilities\\ExecuteAbilityAbility' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Abilities/ExecuteAbilityAbility.php' ), 'WP\\MCP\\Abilities\\GetAbilityInfoAbility' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Abilities/GetAbilityInfoAbility.php' ), 'WP\\MCP\\Abilities\\McpAbilityHelperTrait' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Abilities/McpAbilityHelperTrait.php' ), 'WP\\MCP\\Autoloader' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Autoloader.php' ), 'WP\\MCP\\Cli\\McpCommand' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Cli/McpCommand.php' ), 'WP\\MCP\\Cli\\StdioServerBridge' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Cli/StdioServerBridge.php' ), 'WP\\MCP\\Core\\McpAdapter' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Core/McpAdapter.php' ), 'WP\\MCP\\Core\\McpComponentRegistry' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Core/McpComponentRegistry.php' ), 'WP\\MCP\\Core\\McpServer' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Core/McpServer.php' ), 'WP\\MCP\\Core\\McpTransportFactory' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Core/McpTransportFactory.php' ), 'WP\\MCP\\Domain\\Prompts\\Contracts\\McpPromptBuilderInterface' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Prompts/Contracts/McpPromptBuilderInterface.php' ), 'WP\\MCP\\Domain\\Prompts\\McpPrompt' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Prompts/McpPrompt.php' ), 'WP\\MCP\\Domain\\Prompts\\McpPromptBuilder' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Prompts/McpPromptBuilder.php' ), 'WP\\MCP\\Domain\\Prompts\\McpPromptValidator' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Prompts/McpPromptValidator.php' ), 'WP\\MCP\\Domain\\Prompts\\RegisterAbilityAsMcpPrompt' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Prompts/RegisterAbilityAsMcpPrompt.php' ), 'WP\\MCP\\Domain\\Resources\\McpResource' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Resources/McpResource.php' ), 'WP\\MCP\\Domain\\Resources\\McpResourceValidator' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Resources/McpResourceValidator.php' ), 'WP\\MCP\\Domain\\Resources\\RegisterAbilityAsMcpResource' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Resources/RegisterAbilityAsMcpResource.php' ), 'WP\\MCP\\Domain\\Tools\\McpTool' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Tools/McpTool.php' ), 'WP\\MCP\\Domain\\Tools\\McpToolValidator' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Tools/McpToolValidator.php' ), 'WP\\MCP\\Domain\\Tools\\RegisterAbilityAsMcpTool' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Domain/Tools/RegisterAbilityAsMcpTool.php' ), 'WP\\MCP\\Handlers\\HandlerHelperTrait' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Handlers/HandlerHelperTrait.php' ), 'WP\\MCP\\Handlers\\Initialize\\InitializeHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Handlers/Initialize/InitializeHandler.php' ), 'WP\\MCP\\Handlers\\Prompts\\PromptsHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Handlers/Prompts/PromptsHandler.php' ), 'WP\\MCP\\Handlers\\Resources\\ResourcesHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Handlers/Resources/ResourcesHandler.php' ), 'WP\\MCP\\Handlers\\System\\SystemHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Handlers/System/SystemHandler.php' ), 'WP\\MCP\\Handlers\\Tools\\ToolsHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Handlers/Tools/ToolsHandler.php' ), 'WP\\MCP\\Infrastructure\\ErrorHandling\\Contracts\\McpErrorHandlerInterface' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Infrastructure/ErrorHandling/Contracts/McpErrorHandlerInterface.php' ), 'WP\\MCP\\Infrastructure\\ErrorHandling\\ErrorLogMcpErrorHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Infrastructure/ErrorHandling/ErrorLogMcpErrorHandler.php' ), 'WP\\MCP\\Infrastructure\\ErrorHandling\\McpErrorFactory' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Infrastructure/ErrorHandling/McpErrorFactory.php' ), 'WP\\MCP\\Infrastructure\\ErrorHandling\\NullMcpErrorHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Infrastructure/ErrorHandling/NullMcpErrorHandler.php' ), 'WP\\MCP\\Infrastructure\\Observability\\ConsoleObservabilityHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Infrastructure/Observability/ConsoleObservabilityHandler.php' ), 'WP\\MCP\\Infrastructure\\Observability\\Contracts\\McpObservabilityHandlerInterface' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Infrastructure/Observability/Contracts/McpObservabilityHandlerInterface.php' ), 'WP\\MCP\\Infrastructure\\Observability\\ErrorLogMcpObservabilityHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Infrastructure/Observability/ErrorLogMcpObservabilityHandler.php' ), 'WP\\MCP\\Infrastructure\\Observability\\McpObservabilityHelperTrait' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Infrastructure/Observability/McpObservabilityHelperTrait.php' ), 'WP\\MCP\\Infrastructure\\Observability\\NullMcpObservabilityHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Infrastructure/Observability/NullMcpObservabilityHandler.php' ), 'WP\\MCP\\Plugin' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Plugin.php' ), 'WP\\MCP\\Servers\\DefaultServerFactory' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Servers/DefaultServerFactory.php' ), 'WP\\MCP\\Transport\\Contracts\\McpRestTransportInterface' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/Contracts/McpRestTransportInterface.php' ), 'WP\\MCP\\Transport\\Contracts\\McpTransportInterface' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/Contracts/McpTransportInterface.php' ), 'WP\\MCP\\Transport\\HttpTransport' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/HttpTransport.php' ), 'WP\\MCP\\Transport\\Infrastructure\\HttpRequestContext' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/Infrastructure/HttpRequestContext.php' ), 'WP\\MCP\\Transport\\Infrastructure\\HttpRequestHandler' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/Infrastructure/HttpRequestHandler.php' ), 'WP\\MCP\\Transport\\Infrastructure\\HttpSessionValidator' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/Infrastructure/HttpSessionValidator.php' ), 'WP\\MCP\\Transport\\Infrastructure\\JsonRpcResponseBuilder' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/Infrastructure/JsonRpcResponseBuilder.php' ), 'WP\\MCP\\Transport\\Infrastructure\\McpTransportContext' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/Infrastructure/McpTransportContext.php' ), 'WP\\MCP\\Transport\\Infrastructure\\McpTransportHelperTrait' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/Infrastructure/McpTransportHelperTrait.php' ), 'WP\\MCP\\Transport\\Infrastructure\\RequestRouter' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/Infrastructure/RequestRouter.php' ), 'WP\\MCP\\Transport\\Infrastructure\\SessionManager' => array( 'version' => '0.3.0.0', 'path' => $vendorDir . '/wordpress/mcp-adapter/includes/Transport/Infrastructure/SessionManager.php' ), ); adds the settings related to the product attributes lookup table. * * @param array $settings Original settings configuration array. * @param string $section_id Settings section identifier. * @return array New settings configuration array. * * @internal For exclusive usage of WooCommerce core, backwards compatibility not guaranteed. */ public function add_product_attributes_lookup_table_settings( array $settings, string $section_id ): array { if ( 'advanced' === $section_id && $this->check_lookup_table_exists() ) { $title_item = array( 'title' => __( 'Product attributes lookup table', 'woocommerce' ), 'type' => 'title', ); $regeneration_is_in_progress = $this->regeneration_is_in_progress(); if ( $regeneration_is_in_progress ) { $title_item['desc'] = __( 'These settings are not available while the lookup table regeneration is in progress.', 'woocommerce' ); } $settings[] = $title_item; if ( ! $regeneration_is_in_progress ) { $regeneration_aborted_warning = $this->regeneration_was_aborted() ? sprintf( "

%s

%s

", __( 'WARNING: The product attributes lookup table regeneration process was aborted.', 'woocommerce' ), __( 'This means that the table is probably in an inconsistent state. It\'s recommended to run a new regeneration process or to resume the aborted process (Status - Tools - Regenerate the product attributes lookup table/Resume the product attributes lookup table regeneration) before enabling the table usage.', 'woocommerce' ) ) : null; $settings[] = array( 'title' => __( 'Enable table usage', 'woocommerce' ), 'desc' => __( 'Use the product attributes lookup table for catalog filtering.', 'woocommerce' ), 'desc_tip' => $regeneration_aborted_warning, 'id' => 'woocommerce_attribute_lookup_enabled', 'default' => 'no', 'type' => 'checkbox', 'checkboxgroup' => 'start', ); $settings[] = array( 'title' => __( 'Direct updates', 'woocommerce' ), 'desc' => __( 'Update the table directly upon product changes, instead of scheduling a deferred update.', 'woocommerce' ), 'id' => 'woocommerce_attribute_lookup_direct_updates', 'default' => 'no', 'type' => 'checkbox', 'checkboxgroup' => 'start', ); $settings[] = array( 'title' => __( 'Optimized updates', 'woocommerce' ), 'desc' => __( 'Uses much more performant queries to update the lookup table, but may not be compatible with some extensions.', 'woocommerce' ), 'desc_tip' => __( 'This setting only works when product data is stored in the posts table.', 'woocommerce' ), 'id' => 'woocommerce_attribute_lookup_optimized_updates', 'default' => 'no', 'type' => 'checkbox', 'checkboxgroup' => 'start', ); } $settings[] = array( 'type' => 'sectionend' ); } return $settings; } /** * Check if the optimized database access setting is enabled. * * @return bool True if the optimized database access setting is enabled. */ public function optimized_data_access_is_enabled() { return 'yes' === get_option( 'woocommerce_attribute_lookup_optimized_updates' ); } /** * Create the lookup table data for a product or variation using optimized database access. * For variable products entries are created for the main product and for all the variations. * * @param int $product_id Product or variation id. */ private function create_data_for_product_cpt( int $product_id ) { $this->last_create_operation_failed = false; try { $this->create_data_for_product_cpt_core( $product_id ); } catch ( \Exception $e ) { $data = array( 'source' => 'palt-updates', 'product_id' => $product_id, ); if ( $e instanceof \WC_Data_Exception ) { $data = array_merge( $data, $e->getErrorData() ); } else { $data['exception'] = $e; } WC()->call_function( 'wc_get_logger' ) ->error( "Lookup data creation (optimized) failed for product $product_id: " . $e->getMessage(), $data ); $this->last_create_operation_failed = true; } } /** * Core version of create_data_for_product_cpt (doesn't catch exceptions). * * @param int $product_id Product or variation id. * @return void * @throws \WC_Data_Exception Wrongly serialized attribute data found, or INSERT statement failed. */ private function create_data_for_product_cpt_core( int $product_id ) { global $wpdb; $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE product_or_parent_id = %d', $this->lookup_table_name, $product_id ) ); // * Obtain list of product variations, together with stock statuses; also get the product type. // For a variation this will return just one entry, with type 'variation'. // Output: $product_ids_with_stock_status = associative array where 'id' is the key and values are the stock status (1 for "in stock", 0 otherwise). // $variation_ids = raw list of variation ids. // $is_variable_product = true or false. // $is_variation = true or false. $sql = $wpdb->prepare( "(select p.ID as id, null parent, m.meta_value as stock_status, t.name as product_type from {$wpdb->posts} p left join {$wpdb->postmeta} m on p.id=m.post_id and m.meta_key='_stock_status' left join {$wpdb->term_relationships} tr on tr.object_id=p.id left join {$wpdb->term_taxonomy} tt on tt.term_taxonomy_id=tr.term_taxonomy_id left join {$wpdb->terms} t on t.term_id=tt.term_id where p.post_type = 'product' and p.post_status in ('publish', 'draft', 'pending', 'private') and tt.taxonomy='product_type' and t.name != 'exclude-from-search' and p.id=%d limit 1) union (select p.ID as id, p.post_parent as parent, m.meta_value as stock_status, 'variation' as product_type from {$wpdb->posts} p left join {$wpdb->postmeta} m on p.id=m.post_id and m.meta_key='_stock_status' where p.post_type = 'product_variation' and p.post_status in ('publish', 'draft', 'pending', 'private') and (p.ID=%d or p.post_parent=%d)); ", $product_id, $product_id, $product_id ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared $product_ids_with_stock_status = $wpdb->get_results( $sql, ARRAY_A ); $main_product_row = array_filter( $product_ids_with_stock_status, fn( $item ) => ProductType::VARIATION !== $item['product_type'] ); $is_variation = empty( $main_product_row ); $main_product_id = $is_variation ? current( $product_ids_with_stock_status )['parent'] : $product_id; $is_variable_product = ! $is_variation && ( ProductType::VARIABLE === current( $main_product_row )['product_type'] ); $product_ids_with_stock_status = ArrayUtil::group_by_column( $product_ids_with_stock_status, 'id', true ); $variation_ids = $is_variation ? array( $product_id ) : array_keys( array_diff_key( $product_ids_with_stock_status, array( $product_id => null ) ) ); $product_ids_with_stock_status = ArrayUtil::select( $product_ids_with_stock_status, 'stock_status' ); $product_ids_with_stock_status = array_map( fn( $item ) => ProductStockStatus::IN_STOCK === $item ? 1 : 0, $product_ids_with_stock_status ); // * Obtain the list of attributes used for variations and not. // Output: two lists of attribute slugs, all starting with 'pa_'. $sql = $wpdb->prepare( "select meta_value from {$wpdb->postmeta} where post_id=%d and meta_key=%s", $main_product_id, '_product_attributes' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared $temp = $wpdb->get_var( $sql ); if ( is_null( $temp ) ) { // The product has no attributes, thus there's no attributes lookup data to generate. return; } // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize $temp = unserialize( $temp ); if ( false === $temp ) { throw new \WC_Data_Exception( 0, 'The product attributes metadata row is not properly serialized' ); } $temp = array_filter( $temp, fn( $item, $slug ) => StringUtil::starts_with( $slug, 'pa_' ) && '' === $item['value'], ARRAY_FILTER_USE_BOTH ); $attributes_not_for_variations = $is_variation || $is_variable_product ? array_keys( array_filter( $temp, fn( $item ) => 0 === $item['is_variation'] ) ) : array_keys( $temp ); // * Obtain the terms used for each attribute. // Output: $terms_used_per_attribute = // [ // 'pa_...' => [ // [ // 'term_id' => , // 'attribute' => 'pa_...' // 'slug' => // ],... // ],... // ] $sql = $wpdb->prepare( "select tt.term_id, tt.taxonomy as attribute, t.slug from {$wpdb->prefix}term_relationships tr join {$wpdb->term_taxonomy} tt on tt.term_taxonomy_id = tr.term_taxonomy_id join {$wpdb->terms} t on t.term_id=tt.term_id where tr.object_id=%d and taxonomy like %s;", $main_product_id, 'pa_%' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared $terms_used_per_attribute = $wpdb->get_results( $sql, ARRAY_A ); foreach ( $terms_used_per_attribute as &$term ) { $term['attribute'] = strtolower( rawurlencode( $term['attribute'] ) ); } $terms_used_per_attribute = ArrayUtil::group_by_column( $terms_used_per_attribute, 'attribute' ); // * Obtain the actual variations defined (only if variations exist). // Output: $variations_defined = // [ // => [ // [ // 'variation_id' => , // 'attribute' => 'pa_...' // 'slug' => // ],... // ],... // ] // // Note that this does NOT include "any..." attributes! if ( ! $is_variation && ( ! $is_variable_product || empty( $variation_ids ) ) ) { $variations_defined = array(); } else { $sql = $wpdb->prepare( "select post_id as variation_id, substr(meta_key,11) as attribute, meta_value as slug from {$wpdb->postmeta} where post_id in (select ID from {$wpdb->posts} where (id=%d or post_parent=%d) and post_type = 'product_variation') and meta_key like %s and meta_value != ''", $product_id, $product_id, 'attribute_pa_%' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared $variations_defined = $wpdb->get_results( $sql, ARRAY_A ); $variations_defined = ArrayUtil::group_by_column( $variations_defined, 'variation_id' ); } // Now we'll fill an array with all the data rows to be inserted in the lookup table. $insert_data = array(); // * Insert data for the main product if ( ! $is_variation ) { foreach ( $attributes_not_for_variations as $attribute_name ) { foreach ( ( $terms_used_per_attribute[ $attribute_name ] ?? array() ) as $attribute_data ) { $insert_data[] = array( $product_id, $main_product_id, $attribute_name, $attribute_data['term_id'], 0, $product_ids_with_stock_status[ $product_id ] ); } } } // * Insert data for the variations defined // Remove the non-variation attributes data first. $terms_used_per_attribute = array_diff_key( $terms_used_per_attribute, array_flip( $attributes_not_for_variations ) ); $used_attributes_per_variation = array(); foreach ( $variations_defined as $variation_id => $variation_data ) { $used_attributes_per_variation[ $variation_id ] = array(); foreach ( $variation_data as $variation_attribute_data ) { $attribute_name = $variation_attribute_data['attribute']; $used_attributes_per_variation[ $variation_id ][] = $attribute_name; $term_id = current( array_filter( ( $terms_used_per_attribute[ $attribute_name ] ?? array() ), fn( $item ) => $item['slug'] === $variation_attribute_data['slug'] ) )['term_id'] ?? null; if ( is_null( $term_id ) ) { continue; } $insert_data[] = array( $variation_id, $main_product_id, $attribute_name, $term_id, 1, $product_ids_with_stock_status[ $variation_id ] ?? false ); } } // * Insert data for variations that have "any..." attributes and at least one defined attribute foreach ( $used_attributes_per_variation as $variation_id => $attributes_list ) { $any_attributes = array_diff_key( $terms_used_per_attribute, array_flip( $attributes_list ) ); foreach ( $any_attributes as $attributes_data ) { foreach ( $attributes_data as $attribute_data ) { $insert_data[] = array( $variation_id, $main_product_id, $attribute_data['attribute'], $attribute_data['term_id'], 1, $product_ids_with_stock_status[ $variation_id ] ?? false ); } } } // * Insert data for variations that have all their attributes defined as "any..." $variations_with_all_any = array_keys( array_diff_key( array_flip( $variation_ids ), $used_attributes_per_variation ) ); foreach ( $variations_with_all_any as $variation_id ) { foreach ( $terms_used_per_attribute as $attribute_name => $attribute_terms ) { foreach ( $attribute_terms as $attribute_term ) { $insert_data[] = array( $variation_id, $main_product_id, $attribute_name, $attribute_term['term_id'], 1, $product_ids_with_stock_status[ $variation_id ] ?? false ); } } } // * We have all the data to insert, let's go and insert it. $insert_data_chunks = array_chunk( $insert_data, 100 ); foreach ( $insert_data_chunks as $insert_data_chunk ) { $sql = 'INSERT INTO ' . $this->lookup_table_name . ' ( product_id, product_or_parent_id, taxonomy, term_id, is_variation_attribute, in_stock) VALUES ('; $values_strings = array(); foreach ( $insert_data_chunk as $dataset ) { $attribute_name = esc_sql( $dataset[2] ); $values_strings[] = "{$dataset[0]},{$dataset[1]},'{$attribute_name}',{$dataset[3]},{$dataset[4]},{$dataset[5]}"; } $sql .= implode( '),(', $values_strings ) . ')'; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared $result = $wpdb->query( $sql ); if ( false === $result ) { throw new \WC_Data_Exception( 0, 'INSERT statement failed', 0, array( 'db_error' => esc_html( $wpdb->last_error ), 'db_query' => esc_html( $wpdb->last_query ), ) ); } } } }