Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
"plugin update",
"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,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' );
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 twentytwentythree --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 twentytwentythree twentytwenty`
Then STDOUT should be:
"""
Success: Cleared cache for 2 themes.
"""

Scenario: Clear cache for all themes
When I run `wp theme install twentytwentythree --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
131 changes: 131 additions & 0 deletions src/Theme_Cache_Command.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?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 ) {
$this->clear_theme_cache( $theme );
++$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 ) {
$this->clear_theme_cache( $theme );
}
WP_CLI::success( 'The theme cache was flushed.' );
} else {
WP_CLI::warning( 'Your WordPress version does not support flushing the theme cache group.' );
}
}

/**
* Clear cache for a specific theme.
*
* @param \WP_Theme $theme Theme object.
*/
private function clear_theme_cache( $theme ) {
$cache_hash = md5( $theme->get_theme_root() . '/' . $theme->get_stylesheet() );
$cache_keys = [ 'theme', 'screenshot', 'headers', 'page_templates' ];

foreach ( $cache_keys as $key ) {
wp_cache_delete( $key . '-' . $cache_hash, 'themes' );
}
}
}
Loading