Commit 06e8f632a04 for woocommerce

commit 06e8f632a042a327328a9c6de12fb2f68abcce01
Author: Mike Jolley <mike.jolley@me.com>
Date:   Wed Jul 8 13:26:17 2026 +0100

    Hide Downloadable product permissions metabox by default on the order edit screen (#66119)

    * Hide Downloadable product permissions metabox by default on order edit screen

    Download permissions are granted automatically by WooCommerce, so the box
    rarely needs manual attention. Add it to the order screen's default hidden
    list via the existing WC_Admin_Post_Types::hidden_meta_boxes callback (already
    hooked to default_hidden_meta_boxes). The box stays registered, so merchants
    can re-enable it via Screen Options and that preference persists per user.
    Covers HPOS and legacy CPT order screens via wc_get_page_screen_id().

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    * Remove stale PHPStan baseline entry for resolved $screen->base access

    Typing hidden_meta_boxes()'s $screen param as WP_Screen resolves both the
    $screen->post_type and $screen->base accesses. The post_type baseline count
    was decremented; the base entry (count 1) is now fully resolved and must be
    removed. A stale local PHPStan result cache hid this; CI on a cold cache
    flagged the unmatched pattern.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    * Fix flaky downloads e2e by setting the meta-box preference via WP-CLI

    The "Downloadable product permissions" e2e suite drove the Screen Options UI
    in beforeEach to reveal the now-hidden-by-default box, but clicking
    #show-settings-link on the order screen timed out (the button resolves but
    isn't actionable). Replace that with a one-time WP-CLI write of the admin
    user's hidden-meta-boxes user option in beforeAll, which persists across the
    tests' own re-navigations, and clean it up in afterAll. Both screen ids are
    covered (woocommerce_page_wc-orders for HPOS, shop_order for the HPOS-disabled
    job, which also runs these @hpos tests). The CLI calls use --skip-plugins so
    WP-CLI bootstraps core only; loading the full @services plugin set exhausts
    the CLI memory limit (google-listings-and-ads fatals on boot). beforeEach is
    left identical to trunk.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---------

    Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

diff --git a/plugins/woocommerce/changelog/dsgwoo-1343-hide-downloads-metabox b/plugins/woocommerce/changelog/dsgwoo-1343-hide-downloads-metabox
new file mode 100644
index 00000000000..a61f533fed4
--- /dev/null
+++ b/plugins/woocommerce/changelog/dsgwoo-1343-hide-downloads-metabox
@@ -0,0 +1,4 @@
+Significance: patch
+Type: tweak
+
+Hide the Downloadable product permissions meta box by default on the order edit screen. Merchants can re-enable it via Screen Options.
diff --git a/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php b/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php
index 31d8ba95c94..712c7696851 100644
--- a/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php
+++ b/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php
@@ -726,8 +726,8 @@ class WC_Admin_Post_Types {
 	/**
 	 * Hidden default Meta-Boxes.
 	 *
-	 * @param  array  $hidden Hidden boxes.
-	 * @param  object $screen Current screen.
+	 * @param  array     $hidden Hidden boxes.
+	 * @param  WP_Screen $screen Current screen.
 	 * @return array
 	 */
 	public function hidden_meta_boxes( $hidden, $screen ) {
@@ -735,6 +735,11 @@ class WC_Admin_Post_Types {
 			$hidden = array_merge( $hidden, array( 'postcustom' ) );
 		}

+		// Download permissions are granted automatically, so hide the box by default on order screens (HPOS and legacy CPT). Merchants can re-enable it via Screen Options.
+		if ( wc_get_page_screen_id( 'shop-order' ) === $screen->id ) {
+			$hidden = array_merge( $hidden, array( 'woocommerce-order-downloads' ) );
+		}
+
 		return $hidden;
 	}

diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index fb11252b780..80278e498e7 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -2406,16 +2406,10 @@ parameters:
 			count: 1
 			path: includes/admin/class-wc-admin-pointers.php

-		-
-			message: '#^Access to an undefined property object\:\:\$base\.$#'
-			identifier: property.notFound
-			count: 1
-			path: includes/admin/class-wc-admin-post-types.php
-
 		-
 			message: '#^Access to an undefined property object\:\:\$post_type\.$#'
 			identifier: property.notFound
-			count: 2
+			count: 1
 			path: includes/admin/class-wc-admin-post-types.php

 		-
diff --git a/plugins/woocommerce/tests/e2e/tests/order/order-edit.spec.ts b/plugins/woocommerce/tests/e2e/tests/order/order-edit.spec.ts
index f3007bce2e5..9891dd2190d 100644
--- a/plugins/woocommerce/tests/e2e/tests/order/order-edit.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/order/order-edit.spec.ts
@@ -10,6 +10,7 @@ import { tags, expect, test } from '../../fixtures/fixtures';
 import { ADMIN_STATE_PATH } from '../../playwright.config';
 import { random } from '../../utils/helpers';
 import { getMediaBySlug } from '../../utils/media';
+import { wpCLI } from '../../utils/cli';

 test.use( { storageState: ADMIN_STATE_PATH } );

@@ -391,6 +392,15 @@ test.describe(
 			email: 'john.doe@example.com',
 		};

+		// The downloads box is hidden by default on the order edit screen. These tests run
+		// in both the HPOS (woocommerce_page_wc-orders) and HPOS-disabled (shop_order) jobs,
+		// so the admin user's hidden-meta-boxes preference is cleared for both screen ids to
+		// keep the box visible. Keys are blog-prefixed user meta (single-site wp-env prefix).
+		const orderScreenHiddenMetaKeys = [
+			'wp_metaboxhidden_woocommerce_page_wc-orders',
+			'wp_metaboxhidden_shop_order',
+		];
+
 		let orderId: number,
 			productId: number,
 			product2Id: number,
@@ -432,6 +442,28 @@ test.describe(
 			( { source_url: downloadFile } = await getMediaBySlug(
 				'image-01'
 			) );
+
+			// Persist a Screen Options preference (an empty hidden-meta-boxes list) for the
+			// admin user (ID 1) so the box stays visible while the tests navigate between
+			// orders. An empty list short-circuits the default_hidden_meta_boxes filter that
+			// would otherwise hide it. --skip-plugins/--skip-themes bootstraps core only:
+			// the meta write needs no plugins, and loading them all exhausts WP-CLI's memory
+			// limit in the @services environment (google-listings-and-ads fatals on boot).
+			for ( const key of orderScreenHiddenMetaKeys ) {
+				await wpCLI(
+					`wp user meta update 1 ${ key } '[]' --format=json --skip-plugins --skip-themes`
+				);
+			}
+		} );
+
+		test.afterAll( async () => {
+			// Restore the default-hidden behaviour so the visible state doesn't leak to
+			// other order-screen tests.
+			for ( const key of orderScreenHiddenMetaKeys ) {
+				await wpCLI(
+					`wp user meta delete 1 ${ key } --skip-plugins --skip-themes`
+				);
+			}
 		} );

 		test.beforeEach( async ( { restApi } ) => {
diff --git a/plugins/woocommerce/tests/unit-tests/admin/class-wc-tests-admin-post-types.php b/plugins/woocommerce/tests/unit-tests/admin/class-wc-tests-admin-post-types.php
index 72e31fdd38d..5a91306ec5a 100644
--- a/plugins/woocommerce/tests/unit-tests/admin/class-wc-tests-admin-post-types.php
+++ b/plugins/woocommerce/tests/unit-tests/admin/class-wc-tests-admin-post-types.php
@@ -151,4 +151,38 @@ class WC_Tests_Admin_Post_Types extends WC_Unit_Test_Case {
 		$actual  = $product->{"get_{$type_of_price}_price"}();
 		$this->assertEquals( $expected_new_price, $actual );
 	}
+
+	/**
+	 * @test
+	 * @testdox The downloadable product permissions meta box is hidden by default on the order edit screen.
+	 */
+	public function hidden_meta_boxes_hides_order_downloads_on_order_screen() {
+		$sut    = new WC_Admin_Post_Types();
+		$screen = (object) array(
+			'id'        => wc_get_page_screen_id( 'shop-order' ),
+			'post_type' => 'shop_order',
+			'base'      => 'post',
+		);
+
+		$hidden = $sut->hidden_meta_boxes( array(), $screen );
+
+		$this->assertContains( 'woocommerce-order-downloads', $hidden );
+	}
+
+	/**
+	 * @test
+	 * @testdox The order downloads hide-by-default rule does not leak to unrelated screens.
+	 */
+	public function hidden_meta_boxes_leaves_other_screens_untouched() {
+		$sut    = new WC_Admin_Post_Types();
+		$screen = (object) array(
+			'id'        => 'dashboard',
+			'post_type' => '',
+			'base'      => 'dashboard',
+		);
+
+		$hidden = $sut->hidden_meta_boxes( array(), $screen );
+
+		$this->assertNotContains( 'woocommerce-order-downloads', $hidden );
+	}
 }