Commit 65b7e3b4cad for woocommerce

commit 65b7e3b4cad890d92ae6d109ff0e48c53c31853a
Author: Brandon Kraft <public@brandonkraft.com>
Date:   Wed Jul 29 14:59:22 2026 -0600

    Add compatibility stubs for two removed REST controllers to prevent 10.9.x to 11.0 upgrade fatals (#67136)

    * Add WC_REST_Layout_Templates_Controller compatibility stub

    PR 65500 removed the controller with the deprecated product block editor,
    but 10.9.4 still ships it and registers it unconditionally in Server.php.
    During an in-place update WordPress swaps the files while 10.9's code is
    still resident, the wc-admin settings preload boots the REST server on
    admin_print_footer_scripts, and register_rest_routes() instantiates a class
    whose file is already gone. The bundled autoloader hard-requires the missing
    path and the update screen dies.

    Nothing in 11.0 registers or uses this class. The stub exists only so a 10.9
    controller list surviving across the file swap has something to instantiate.
    Same approach as PR 66081 took for Admin\API\Settings.

    * Add WC_REST_Products_Catalog_Controller compatibility stub

    Same failure mode as the layout-templates stub. 10.9.4 ships this controller
    and registers it in get_v3_controllers() behind the products-catalog-api
    feature flag; 11.0 deletes the file.

    The flag is off by default, but it is flippable at runtime via WooCommerce
    Beta Tester or any plugin filtering woocommerce_admin_get_feature_config, and
    wc_admin_get_feature_config() is pinned in PHP's function table pre-swap, so
    trunk removing the flag does not close the path. Beta Tester users are also
    disproportionately the people who update to an RC over 10.9.x.

    * Fix phpcs and phpstan failures in the REST controller stubs

    ---------

    Co-authored-by: Jorge Torres <jorge.torres@automattic.com>

diff --git a/plugins/woocommerce/changelog/fix-layout-templates-upgrade-stub b/plugins/woocommerce/changelog/fix-layout-templates-upgrade-stub
new file mode 100644
index 00000000000..415699b2800
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-layout-templates-upgrade-stub
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Add no-op WC_REST_Layout_Templates_Controller and WC_REST_Products_Catalog_Controller stubs so an in-place update from 10.9.x does not fatal when the 10.9 controller list instantiates a class whose file has already been swapped away.
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-layout-templates-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-layout-templates-controller.php
new file mode 100644
index 00000000000..052e4c725c4
--- /dev/null
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-layout-templates-controller.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * REST API Layout Templates controller (compatibility stub).
+ *
+ * @package WooCommerce\RestApi
+ */
+
+declare(strict_types=1);
+
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * REST API Layout Templates controller class.
+ *
+ * The real controller was removed in 11.0 with the deprecated product block editor. This empty
+ * stub stays so an in-memory 10.9 controller list, still naming this class while the files are
+ * swapped to 11.0 during an update, can instantiate it instead of fataling on the deleted file.
+ * It registers nothing.
+ *
+ * @deprecated 11.0.0
+ */
+class WC_REST_Layout_Templates_Controller {
+
+	/**
+	 * Register routes. Intentionally a no-op.
+	 */
+	public function register_routes(): void {}
+}
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-catalog-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-catalog-controller.php
new file mode 100644
index 00000000000..e06418ef038
--- /dev/null
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-catalog-controller.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * REST API Products Catalog controller (compatibility stub).
+ *
+ * @package WooCommerce\RestApi
+ */
+
+declare(strict_types=1);
+
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * REST API Products Catalog controller class.
+ *
+ * The real controller was removed in 11.0. This empty stub stays so an in-memory 10.9 controller
+ * list, still naming this class while the files are swapped to 11.0 during an update, can
+ * instantiate it instead of fataling on the deleted file. It registers nothing.
+ *
+ * 10.9 only added this entry when the `products-catalog-api` feature was enabled, which is off by
+ * default — but the flag is flippable at runtime (WooCommerce Beta Tester, or any plugin filtering
+ * `woocommerce_admin_get_feature_config`), and the feature config is resolved from the pre-swap
+ * code, so trunk dropping the flag does not close the path.
+ *
+ * @deprecated 11.0.0
+ */
+class WC_REST_Products_Catalog_Controller {
+
+	/**
+	 * Register routes. Intentionally a no-op.
+	 */
+	public function register_routes(): void {}
+}