diff --git a/composer.json b/composer.json index 62a605a1..898b5c03 100644 --- a/composer.json +++ b/composer.json @@ -61,6 +61,9 @@ "plugin update", "theme", "theme activate", + "theme cache", + "theme cache clear", + "theme cache flush", "theme delete", "theme disable", "theme enable", diff --git a/extension-command.php b/extension-command.php index 18b87efd..a80b2167 100644 --- a/extension-command.php +++ b/extension-command.php @@ -22,3 +22,4 @@ WP_CLI::add_command( 'theme', 'Theme_Command' ); WP_CLI::add_command( 'theme auto-updates', 'Theme_AutoUpdates_Command', $wpcli_extension_requires_wp_5_5 ); WP_CLI::add_command( 'theme mod', 'Theme_Mod_Command' ); +WP_CLI::add_command( 'theme cache', 'Theme_Cache_Command' ); diff --git a/features/theme-cache.feature b/features/theme-cache.feature new file mode 100644 index 00000000..fa6337da --- /dev/null +++ b/features/theme-cache.feature @@ -0,0 +1,76 @@ +Feature: Manage theme cache + + Background: + Given a WP installation + + Scenario: Clear cache for a single theme + When I run `wp theme install twentytwenty --force --activate` + Then STDOUT should contain: + """ + Success: + """ + + When I run `wp theme cache clear twentytwenty` + Then STDOUT should be: + """ + Success: Cleared cache for 'twentytwenty' theme. + """ + + Scenario: Clear cache for multiple themes + When I run `wp theme install twentytwentyone --force` + Then STDOUT should contain: + """ + Success: + """ + + When I run `wp theme install twentytwenty --force ` + Then STDOUT should contain: + """ + Success: + """ + + When I run `wp theme cache clear twentytwentyone twentytwenty` + Then STDOUT should be: + """ + Success: Cleared cache for 2 themes. + """ + + Scenario: Clear cache for all themes + When I run `wp theme install twentytwentyone --force` + Then STDOUT should contain: + """ + Success: + """ + + When I run `wp theme cache clear --all` + Then STDOUT should contain: + """ + Success: Cleared cache for + """ + And STDOUT should contain: + """ + themes. + """ + + Scenario: Clear cache for non-existent theme + When I try `wp theme cache clear nonexistent` + Then STDERR should contain: + """ + Warning: Theme 'nonexistent' not found. + """ + And the return code should be 1 + + Scenario: Clear cache with no arguments + When I try `wp theme cache clear` + Then STDERR should be: + """ + Error: Please specify one or more themes, or use --all. + """ + And the return code should be 1 + + Scenario: Flush the entire theme cache group + When I run `wp theme cache flush` + Then STDOUT should be: + """ + Success: The theme cache was flushed. + """ diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 96cef65a..7ed969bb 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -53,7 +53,7 @@ - */src/(Plugin_(AutoUpdates_)?|Theme_(Mod_|AutoUpdates_)?)Command\.php$ + */src/(Plugin_(AutoUpdates_)?|Theme_(Mod_|AutoUpdates_|Cache_)?)Command\.php$ diff --git a/src/Theme_Cache_Command.php b/src/Theme_Cache_Command.php new file mode 100644 index 00000000..f145e83b --- /dev/null +++ b/src/Theme_Cache_Command.php @@ -0,0 +1,117 @@ +...] + * : One or more themes to clear the cache for. + * + * [--all] + * : If set, clear cache for all installed themes. + * + * ## EXAMPLES + * + * # Clear cache for a single theme + * $ wp theme cache clear twentytwentyfour + * Success: Cleared cache for 'twentytwentyfour' theme. + * + * # Clear cache for multiple themes + * $ wp theme cache clear twentytwentythree twentytwentyfour + * Success: Cleared cache for 2 themes. + * + * # Clear cache for all themes + * $ wp theme cache clear --all + * Success: Cleared cache for all themes. + * + * @param string[] $args Positional arguments. + * @param array{all?: bool} $assoc_args Associative arguments. + */ + public function clear( $args, $assoc_args ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) { + WP_CLI::error( 'Please specify one or more themes, or use --all.' ); + } + + $themes = []; + + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + $all_themes = wp_get_themes(); + foreach ( $all_themes as $theme ) { + $themes[] = $theme; + } + } else { + foreach ( $args as $theme_slug ) { + $theme = wp_get_theme( $theme_slug ); + if ( ! $theme->exists() ) { + WP_CLI::warning( "Theme '{$theme_slug}' not found." ); + continue; + } + $themes[] = $theme; + } + } + + if ( empty( $themes ) ) { + WP_CLI::error( 'No valid themes to clear cache for.' ); + } + + $cleared = 0; + foreach ( $themes as $theme ) { + $theme->cache_delete(); + ++$cleared; + } + + if ( 1 === $cleared ) { + WP_CLI::success( "Cleared cache for '{$themes[0]->get_stylesheet()}' theme." ); + } else { + WP_CLI::success( "Cleared cache for {$cleared} themes." ); + } + } + + /** + * Flushes the entire theme cache group. + * + * ## EXAMPLES + * + * # Flush the entire theme cache group + * $ wp theme cache flush + * Success: The theme cache was flushed. + * + * @param string[] $args Positional arguments. Unused. + * @param array $assoc_args Associative arguments. Unused. + */ + public function flush( $args, $assoc_args ) { + // Only added in WordPress 6.1. + if ( function_exists( 'wp_cache_flush_group' ) ) { + wp_cache_flush_group( 'themes' ); + WP_CLI::success( 'The theme cache was flushed.' ); + return; + } + + // Fallback for WordPress versions prior to 6.1: clear cache for all themes. + if ( function_exists( 'wp_get_themes' ) ) { + $all_themes = wp_get_themes(); + foreach ( $all_themes as $theme ) { + $theme->cache_delete(); + } + WP_CLI::success( 'The theme cache was flushed.' ); + } else { + WP_CLI::warning( 'Your WordPress version does not support flushing the theme cache group.' ); + } + } +}