From 882f56d049fceda3a4ec70441790d95348a3129c Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 25 Mar 2026 08:30:45 +0100 Subject: [PATCH 1/3] Require WP-CLI v2.13 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index de56882c..aba06a05 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } ], "require": { - "wp-cli/wp-cli": "^2.12" + "wp-cli/wp-cli": "^2.13" }, "require-dev": { "wp-cli/entity-command": "^1.3 || ^2", From be4b090b5511b8a0674b88d76df8771cb6319e6c Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 25 Mar 2026 10:34:15 +0100 Subject: [PATCH 2/3] PHPStan fix --- src/Cache_Command.php | 3 +-- src/Transient_Command.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Cache_Command.php b/src/Cache_Command.php index 29cb7367..ab5c8b56 100644 --- a/src/Cache_Command.php +++ b/src/Cache_Command.php @@ -168,7 +168,6 @@ public function delete( $args, $assoc_args ) { */ public function flush() { // TODO: Needs fixing in wp-cli/wp-cli - // @phpstan-ignore offsetAccess.nonOffsetAccessible if ( WP_CLI::has_config( 'url' ) && ! empty( WP_CLI::get_config()['url'] ) && is_multisite() ) { WP_CLI::warning( 'Flushing the cache may affect all sites in a multisite installation, depending on the implementation of the object cache.' ); } @@ -574,7 +573,7 @@ function ( $key ) { if ( ! empty( $stdin_value ) ) { $patch_value = WP_CLI::read_value( $stdin_value, $assoc_args ); } elseif ( count( $key_path ) > 1 ) { - $patch_value = WP_CLI::read_value( array_pop( $key_path ), $assoc_args ); + $patch_value = WP_CLI::read_value( (string) array_pop( $key_path ), $assoc_args ); } else { $patch_value = null; } diff --git a/src/Transient_Command.php b/src/Transient_Command.php index 658f8f78..e29b5dc1 100644 --- a/src/Transient_Command.php +++ b/src/Transient_Command.php @@ -557,7 +557,7 @@ function ( $key ) { if ( ! empty( $stdin_value ) ) { $patch_value = WP_CLI::read_value( $stdin_value, $assoc_args ); } elseif ( count( $key_path ) > 1 ) { - $patch_value = WP_CLI::read_value( array_pop( $key_path ), $assoc_args ); + $patch_value = WP_CLI::read_value( (string) array_pop( $key_path ), $assoc_args ); } else { $patch_value = null; } From 6776a13fecd0189ed8961178d930c2792475d94d Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 25 Mar 2026 12:36:03 +0100 Subject: [PATCH 3/3] Update tests involving object cache --- features/cache.feature | 12 +++++++++++ features/transient.feature | 44 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/features/cache.feature b/features/cache.feature index 8e21a820..21c23a66 100644 --- a/features/cache.feature +++ b/features/cache.feature @@ -1,5 +1,6 @@ Feature: Managed the WordPress object cache + @skip-object-cache Scenario: Default group is 'default' Given a WP install And a wp-content/mu-plugins/test-harness.php file: @@ -210,3 +211,14 @@ Feature: Managed the WordPress object cache When I run `wp cache supports set_multiple` Then the return code should be 0 + + @require-object-cache + Scenario: Object caches may return success when deleting non-existent objects + Given a WP install + + When I run `wp cache delete nonexistentkey` + Then STDOUT should be: + """ + Success: Object deleted. + """ + And the return code should be 0 diff --git a/features/transient.feature b/features/transient.feature index bba5f641..10111b0a 100644 --- a/features/transient.feature +++ b/features/transient.feature @@ -55,6 +55,7 @@ Feature: Manage WordPress transient cache Success: Transient deleted. """ + @skip-object-cache Scenario: Deleting all transients on single site Given a WP install # We set `WP_DEVELOPMENT_MODE` to stop WordPress from automatically creating @@ -125,6 +126,7 @@ Feature: Manage WordPress transient cache Warning: Transient with key "foo4" is not set. """ + @skip-object-cache Scenario: Deleting expired transients on single site Given a WP install And I run `wp transient set foo bar 600` @@ -196,6 +198,7 @@ Feature: Manage WordPress transient cache bar4 """ + @skip-object-cache Scenario: Deleting all transients on multisite Given a WP multisite install # We set `WP_DEVELOPMENT_MODE` to stop WordPress from automatically creating @@ -291,6 +294,7 @@ Feature: Manage WordPress transient cache Warning: Transient with key "foo6" is not set. """ + @skip-object-cache Scenario: Deleting expired transients on multisite Given a WP multisite install And I run `wp site create --slug=foo` @@ -391,6 +395,7 @@ Feature: Manage WordPress transient cache bar6 """ + @skip-object-cache Scenario: List transients on single site Given a WP install And I run `wp transient set foo bar` @@ -446,6 +451,7 @@ Feature: Manage WordPress transient cache foo6,bar6,1321009871 """ + @skip-object-cache Scenario: List transients on multisite Given a WP multisite install # We set `WP_DEVELOPMENT_MODE` to stop WordPress from automatically creating @@ -504,6 +510,7 @@ Feature: Manage WordPress transient cache foo6,bar6,1321009871 """ + @skip-object-cache Scenario: List transients with search and exclude pattern Given a WP install And I run `wp transient set foo bar` @@ -603,3 +610,40 @@ Feature: Manage WordPress transient cache name foo4 """ + + @require-object-cache + Scenario: Transient database operations warn when external object cache is active + Given a WP install + + When I try `wp transient list --format=count` + Then STDERR should be: + """ + Warning: Transients are stored in an external object cache, and this command only shows those stored in the database. + """ + And STDOUT should be: + """ + 0 + """ + And the return code should be 0 + + When I try `wp transient delete --all` + Then STDERR should be: + """ + Warning: Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients. + """ + And STDOUT should be: + """ + Success: No transients found. + """ + And the return code should be 0 + + When I try `wp transient delete --expired` + Then STDERR should be: + """ + Warning: Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients. + """ + And STDOUT should be: + """ + Success: No expired transients found. + """ + And the return code should be 0