Skip to content
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
"plugin auto-updates status",
"theme",
"theme activate",
"theme cache",
"theme cache clear",
"theme cache flush",
"theme delete",
"theme disable",
"theme enable",
Expand Down
1 change: 1 addition & 0 deletions extension-command.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
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' );

// In admin context, WordPress hooks wp_update_plugins/wp_update_themes to
// various actions, causing update checks to run even when --skip-update-check is passed.
Expand Down
76 changes: 76 additions & 0 deletions features/theme-cache.feature
Original file line number Diff line number Diff line change
@@ -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.
"""
2 changes: 1 addition & 1 deletion phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

<!-- Exclude existing classes from the prefix rule as it would break BC to prefix them now. -->
<rule ref="WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound">
<exclude-pattern>*/src/(Plugin_(AutoUpdates_)?|Theme_(Mod_|AutoUpdates_)?)Command\.php$</exclude-pattern>
<exclude-pattern>*/src/(Plugin_(AutoUpdates_)?|Theme_(Mod_|AutoUpdates_|Cache_)?)Command\.php$</exclude-pattern>
</rule>

<rule ref="WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedNamespaceFound">
Expand Down
117 changes: 117 additions & 0 deletions src/Theme_Cache_Command.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php

/**
* Manages theme cache.
*
* ## EXAMPLES
*
* # Clear cache for a specific theme
* $ wp theme cache clear twentytwentyfour
* Success: Cleared cache for 'twentytwentyfour' theme.
*
* # Flush the entire theme cache group
* $ wp theme cache flush
* Success: The theme cache was flushed.
*/
class Theme_Cache_Command extends WP_CLI_Command {

/**
* Clears the cache for one or more themes.
*
* ## OPTIONS
*
* [<theme>...]
* : 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.' );
}
}
}