Opened 7 years ago
Closed 6 years ago
#43228 closed defect (bug) (wontfix)
register_theme_directory() needs to delete the `theme_roots` transient
Reported by: | johnbillion | Owned by: | johnbillion |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | |
Component: | Themes | Keywords: | has-unit-tests needs-patch |
Focuses: | Cc: |
Description
Calling register_theme_directory( '/path/to/themes' )
adds an element to the global $wp_theme_directories
array.
When WordPress attempts to load the active theme, it ultimately calls get_theme_roots()
which first checks for a cached value in the theme_roots
transient before looking at the $wp_theme_directories
global. This transient does not get deleted when register_theme_directory()
is called, therefore if get_theme_roots()
gets called before register_theme_directory()
then the theme directory registration will silently fail due to the use of a stale cache of registered theme directories.
get_theme_roots()
is ultimately called by several theme-related functions, such as wp_get_themes()
and wp_get_theme()
, so it's reasonable to expect that get_theme_roots()
might get called before register_theme_directory()
.
register_theme_directory()
should delete the theme_roots
cache in order to avoid this problem.
This bug has manifested itself in the WP-CLI theme test scaffolding command, which calls register_theme_directory()
on the muplugins_loaded
hook, which means the theme_roots
transient has already been populated with registered theme directories.
Attachments (2)
Change History (13)
#2
@
7 years ago
- Keywords has-unit-tests added; needs-unit-tests removed
Why not use wp_clean_themes_cache()
instead? It gives us the benefit of regenerating the cache and clearing the theme updates cache in case the newly added directory contains outdated themes.
Both versions make the tests pass. The test fails without @johnbillion's patch or the wp_clean_themes_cache()
version thereof.
#3
@
7 years ago
- Milestone changed from Awaiting Review to 5.0
- Owner set to johnbillion
- Status changed from new to reviewing
#5
@
7 years ago
The call to wp_clean_themes_cache()
shouldn't be done on installing I think, so need somthing like
if ( ! wp_installing() ) { wp_clean_themes_cache(); }
otherwise get WordPress database error notices from wpdb
, see https://travis-ci.org/wp-cli/wp-cli/jobs/349573438
#6
@
7 years ago
- Resolution fixed deleted
- Status changed from closed to reopened
Calling wp_clean_themes_cache()
this early in the load process renders the filter 'extra_themes_headers'
in get_file_data()
of wp-includes/functions.php useless as a call from any other source.
@johnbillion this breaks stuff. Try adding any additional theme headers using the above filter hook and you will see.
#8
@
7 years ago
register_theme_directory()
is intended to run on every page load AFAICT, so ultimately deleting the theme_roots
transient or update_themes
option isn't a viable option for calling within register_theme_directory()
.
I suspect that calling search_theme_directories( true )
within the branch that actually appends within register_theme_directory()
will be a bit better, but it'll still cause unexpected IO to happen when the theme roots hasn't actually changed from what's in the transient (ie. this directory was registered on the last page load too).
I think that search_theme_directories()
and get_theme_roots()
needs to hash $wp_theme_directories
and include that as part of it's transient name, which should solve both the reported issue and the issue of extra IO.
Either way, The patch as committed needs reverting.
Patch. Needs some tests.