From 9e104f54c091c97654108ff704de59e38465bba1 Mon Sep 17 00:00:00 2001 From: Rashed Hossain Date: Tue, 13 Oct 2026 15:59:30 +0600 Subject: [PATCH 1/2] Support --all and multiple post IDs for embed cache clear (#67) --- features/cache.feature | 95 ++++++++++++++++++++++++++++++++++++++++++ src/Cache_Command.php | 88 +++++++++++++++++++++++++++++--------- 2 files changed, 164 insertions(+), 19 deletions(-) diff --git a/features/cache.feature b/features/cache.feature index 4169f05..ff40ead 100644 --- a/features/cache.feature +++ b/features/cache.feature @@ -47,6 +47,101 @@ Feature: Manage oEmbed cache. Success: Cleared oEmbed cache. """ + Scenario: Clear oEmbed cache with missing arguments + When I try `wp embed cache clear` + Then STDERR should be: + """ + Error: Please specify one or more post IDs, or use --all. + """ + And the return code should be 1 + + Scenario: Clear oEmbed cache for multiple posts + When I run `wp post create --post_title="Post 1" --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID_1} + + When I run `wp post create --post_title="Post 2" --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID_2} + + When I run `wp post meta add {POST_ID_1} _oembed_foo 'bar'` + Then STDOUT should not be empty + + When I run `wp post meta add {POST_ID_2} _oembed_baz 'qux'` + Then STDOUT should not be empty + + When I run `wp embed cache clear {POST_ID_1} {POST_ID_2}` + Then STDOUT should be: + """ + Success: Cleared oEmbed cache for post {POST_ID_1}. + Success: Cleared oEmbed cache for post {POST_ID_2}. + """ + And the return code should be 0 + + When I try `wp post meta get {POST_ID_1} _oembed_foo` + Then the return code should be 1 + + When I try `wp post meta get {POST_ID_2} _oembed_baz` + Then the return code should be 1 + + Scenario: Clear oEmbed cache for multiple posts with some empty + When I run `wp post create --post_title="Post 1" --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID_1} + + When I run `wp post create --post_title="Post 2" --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID_2} + + When I run `wp post meta add {POST_ID_1} _oembed_foo 'bar'` + Then STDOUT should not be empty + + When I try `wp embed cache clear {POST_ID_1} {POST_ID_2}` + Then STDOUT should be: + """ + Success: Cleared oEmbed cache for post {POST_ID_1}. + """ + And STDERR should be: + """ + Warning: No cache to clear for post {POST_ID_2}! + """ + And the return code should be 1 + + Scenario: Clear all oEmbed caches + When I run `wp post create --post_title="Post 1" --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID_1} + + When I run `wp post create --post_title="Post 2" --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID_2} + + When I run `wp post meta add {POST_ID_1} _oembed_foo 'bar'` + Then STDOUT should not be empty + + When I run `wp post meta add {POST_ID_2} _oembed_baz 'qux'` + Then STDOUT should not be empty + + When I run `wp post create --post_title=EmbedCache --post_type=oembed_cache --post_status=publish --porcelain` + Then STDOUT should be a number + And save STDOUT as {OEMBED_POST_ID} + + When I run `wp embed cache clear --all` + Then STDOUT should be: + """ + Success: Cleared all oEmbed caches. + """ + And the return code should be 0 + + When I try `wp post meta get {POST_ID_1} _oembed_foo` + Then the return code should be 1 + + When I try `wp post meta get {POST_ID_2} _oembed_baz` + Then the return code should be 1 + + When I try `wp post get {OEMBED_POST_ID}` + Then the return code should be 1 + Scenario: Trigger oEmbed cache for a non-existent post When I try `wp embed cache trigger 123456` Then STDERR should contain: diff --git a/src/Cache_Command.php b/src/Cache_Command.php index 9c76def..99ac904 100644 --- a/src/Cache_Command.php +++ b/src/Cache_Command.php @@ -28,45 +28,95 @@ class Cache_Command extends WP_CLI_Command { /** - * Deletes all oEmbed caches for a given post. + * Deletes all oEmbed caches for a given post or all posts. * * oEmbed caches for a post are stored in the post's metadata. + * Starting with WordPress 4.9, embeds that aren't associated with a specific post will be cached in + * a new oembed_cache post type. * * ## OPTIONS * - * - * : ID of the post to clear the cache for. + * [...] + * : One or more IDs of the posts to clear the cache for. + * + * [--all] + * : Clear all oEmbed caches. * * ## EXAMPLES * - * # Clear cache for a post + * # Clear cache for a post. * $ wp embed cache clear 123 * Success: Cleared oEmbed cache. + * + * # Clear cache for multiple posts. + * $ wp embed cache clear 123 456 789 + * Success: Cleared oEmbed cache for post 123. + * Success: Cleared oEmbed cache for post 456. + * Success: Cleared oEmbed cache for post 789. + * + * # Clear all oEmbed caches. + * $ wp embed cache clear --all + * Success: Cleared all oEmbed caches. */ public function clear( $args, $assoc_args ) { + $all = Utils\get_flag_value( $assoc_args, 'all', false ); + + if ( empty( $args ) && ! $all ) { + WP_CLI::error( 'Please specify one or more post IDs, or use --all.' ); + } + + if ( $all ) { + /** @var \wpdb $wpdb */ + global $wpdb; + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching + $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key LIKE '_oembed_%'" ); + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching + $wpdb->query( "DELETE FROM {$wpdb->posts} WHERE post_type = 'oembed_cache'" ); + + WP_CLI::success( 'Cleared all oEmbed caches.' ); + return; + } + /** @var \WP_Embed $wp_embed */ global $wp_embed; - $post_id = $args[0]; - - $post_metas = get_post_custom_keys( $post_id ); + $errors = 0; + foreach ( $args as $post_id ) { + $post_metas = get_post_custom_keys( $post_id ); + + if ( $post_metas ) { + $post_metas = array_filter( + $post_metas, + function ( $v ) { + return '_oembed_' === substr( $v, 0, 8 ); + } + ); + } - if ( $post_metas ) { - $post_metas = array_filter( - $post_metas, - function ( $v ) { - return '_oembed_' === substr( $v, 0, 8 ); + if ( empty( $post_metas ) ) { + if ( 1 === count( $args ) ) { + WP_CLI::error( 'No cache to clear!' ); + } else { + WP_CLI::warning( "No cache to clear for post {$post_id}!" ); + ++$errors; + continue; } - ); - } + } - if ( empty( $post_metas ) ) { - WP_CLI::error( 'No cache to clear!' ); - } + $wp_embed->delete_oembed_caches( $post_id ); - $wp_embed->delete_oembed_caches( $post_id ); + if ( count( $args ) > 1 ) { + WP_CLI::success( "Cleared oEmbed cache for post {$post_id}." ); + } + } - WP_CLI::success( 'Cleared oEmbed cache.' ); + if ( 1 === count( $args ) ) { + WP_CLI::success( 'Cleared oEmbed cache.' ); + } elseif ( $errors > 0 ) { + WP_CLI::halt( 1 ); + } } /** From 79b6845f71bfea5d802ebf1b719185e2731e9b72 Mon Sep 17 00:00:00 2001 From: Rashed Hossain Date: Tue, 13 Oct 2026 16:08:47 +0600 Subject: [PATCH 2/2] Flush object cache after deleting all oEmbed caches --- src/Cache_Command.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Cache_Command.php b/src/Cache_Command.php index 99ac904..61a326a 100644 --- a/src/Cache_Command.php +++ b/src/Cache_Command.php @@ -75,6 +75,10 @@ public function clear( $args, $assoc_args ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->query( "DELETE FROM {$wpdb->posts} WHERE post_type = 'oembed_cache'" ); + if ( function_exists( 'wp_cache_flush' ) ) { + wp_cache_flush(); + } + WP_CLI::success( 'Cleared all oEmbed caches.' ); return; }