Commit 50dce6441b2 for woocommerce

commit 50dce6441b205fa12ad269305ce8986f6e5208ab
Author: Alba Rincón <albarin@users.noreply.github.com>
Date:   Thu Apr 30 13:41:26 2026 +0200

    Add configurable APQ caching toggle to GraphQL settings (#64448)

    Co-authored-by: Nestor Soriano <konamiman@konamiman.com>

diff --git a/plugins/woocommerce/changelog/64448-64298-graphql-settings-apq b/plugins/woocommerce/changelog/64448-64298-graphql-settings-apq
new file mode 100644
index 00000000000..cddca349e54
--- /dev/null
+++ b/plugins/woocommerce/changelog/64448-64298-graphql-settings-apq
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add a setting to toggle Apollo Automatic Persisted Queries (APQ) caching on the GraphQL settings page.
\ No newline at end of file
diff --git a/plugins/woocommerce/src/Internal/Api/Main.php b/plugins/woocommerce/src/Internal/Api/Main.php
index 7ef7a9d76f3..ed369553577 100644
--- a/plugins/woocommerce/src/Internal/Api/Main.php
+++ b/plugins/woocommerce/src/Internal/Api/Main.php
@@ -27,6 +27,14 @@ class Main {
 	 */
 	public const OPTION_GET_ENDPOINT_ENABLED = 'woocommerce_graphql_get_endpoint_enabled';

+	/**
+	 * Option name for the "Enable APQ caching" setting.
+	 *
+	 * When disabled, the persistedQuery extension is ignored and requests are
+	 * treated as standard queries.
+	 */
+	public const OPTION_APQ_ENABLED = 'woocommerce_graphql_apq_enabled';
+
 	/**
 	 * Option name for the "Endpoint URL" setting.
 	 *
@@ -77,6 +85,16 @@ class Main {
 		return wc_string_to_bool( get_option( self::OPTION_GET_ENDPOINT_ENABLED, 'yes' ) );
 	}

+	/**
+	 * Whether the Apollo Automatic Persisted Queries (APQ) protocol is enabled.
+	 *
+	 * Defaults to true. When disabled, the `persistedQuery` request extension
+	 * is ignored and requests are processed as standard (non-persisted) queries.
+	 */
+	public static function is_apq_enabled(): bool {
+		return wc_string_to_bool( get_option( self::OPTION_APQ_ENABLED, 'yes' ) );
+	}
+
 	/**
 	 * Whether the ObjectCache-backed query cache is enabled.
 	 *
diff --git a/plugins/woocommerce/src/Internal/Api/QueryCache.php b/plugins/woocommerce/src/Internal/Api/QueryCache.php
index 5925afa17ad..99bac689c7c 100644
--- a/plugins/woocommerce/src/Internal/Api/QueryCache.php
+++ b/plugins/woocommerce/src/Internal/Api/QueryCache.php
@@ -50,10 +50,15 @@ class QueryCache {
 	 * @return DocumentNode|array
 	 */
 	public function resolve( ?string $query, array $extensions ) {
-		$apq = $extensions['persistedQuery'] ?? null;
-
-		if ( is_array( $apq ) && 1 === ( $apq['version'] ?? null ) && ! empty( $apq['sha256Hash'] ) ) {
-			return $this->resolve_apq( $query, $apq['sha256Hash'] );
+		$apq      = $extensions['persistedQuery'] ?? null;
+		$apq_hash = is_array( $apq ) ? ( $apq['sha256Hash'] ?? null ) : null;
+
+		if ( Main::is_apq_enabled()
+			&& is_array( $apq )
+			&& 1 === ( $apq['version'] ?? null )
+			&& is_string( $apq_hash )
+			&& '' !== $apq_hash ) {
+			return $this->resolve_apq( $query, $apq_hash );
 		}

 		// Standard query — no APQ.
diff --git a/plugins/woocommerce/src/Internal/Api/Settings.php b/plugins/woocommerce/src/Internal/Api/Settings.php
index c642a9d519f..42dae14bfc8 100644
--- a/plugins/woocommerce/src/Internal/Api/Settings.php
+++ b/plugins/woocommerce/src/Internal/Api/Settings.php
@@ -70,6 +70,13 @@ class Settings {
 				'default' => 'yes',
 				'type'    => 'checkbox',
 			),
+			array(
+				'title'   => __( 'Enable APQ caching', 'woocommerce' ),
+				'desc'    => __( 'Cache parsed queries using the Apollo Automatic Persisted Queries protocol', 'woocommerce' ),
+				'id'      => Main::OPTION_APQ_ENABLED,
+				'default' => 'yes',
+				'type'    => 'checkbox',
+			),
 			array(
 				'title'             => __( 'Maximum query depth', 'woocommerce' ),
 				'desc'              => __( 'Reject queries whose selection nesting exceeds this depth.', 'woocommerce' ),
diff --git a/plugins/woocommerce/tests/php/src/Internal/Api/SettingsTest.php b/plugins/woocommerce/tests/php/src/Internal/Api/SettingsTest.php
index 5968c021f40..7cc7540d516 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Api/SettingsTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Api/SettingsTest.php
@@ -95,6 +95,22 @@ class SettingsTest extends WC_Unit_Test_Case {
 		$this->assertSame( 'yes', $by_id[ Main::OPTION_GET_ENDPOINT_ENABLED ]['default'] );
 	}

+	/**
+	 * @testdox add_settings defines the APQ checkbox with a 'yes' default (PHP 8.1+).
+	 */
+	public function test_add_settings_defines_apq_checkbox(): void {
+		if ( PHP_VERSION_ID < 80100 ) {
+			$this->markTestSkipped( 'GraphQL settings require PHP 8.1+.' );
+		}
+
+		$fields = $this->sut->add_settings( array(), Settings::SECTION_ID );
+		$by_id  = array_column( $fields, null, 'id' );
+
+		$this->assertArrayHasKey( Main::OPTION_APQ_ENABLED, $by_id );
+		$this->assertSame( 'checkbox', $by_id[ Main::OPTION_APQ_ENABLED ]['type'] );
+		$this->assertSame( 'yes', $by_id[ Main::OPTION_APQ_ENABLED ]['default'] );
+	}
+
 	/**
 	 * @testdox add_settings defines the endpoint URL text field with the default constant as default.
 	 */