WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 3 years ago

#20919 closed defect (bug) (fixed)

Live Preview post-installation fails with multiple theme directories

Reported by: duck_ Owned by: nacin
Milestone: 3.4 Priority: normal
Severity: normal Version: 3.4
Component: Themes Keywords: has-patch commit
Focuses: Cc:

Description

If another theme directory is registered with register_theme_directory() then clicking Live Preview on the post-installation screen results in a "Cheatin' uh?" message.

Tested with a checkout of wpcom-themes in the wp-content directory with a one line plugin:

register_theme_directory( '/srv/http/wp.dev/public/wp-content/wpcom-themes' );

The problem is that get_theme_roots() returns the array stored in the theme_roots transient. This doesn't contain a value for the newly installed theme yet, so get_raw_theme_root() returns false. Therefore, wp_get_theme( 'newly-installed-theme' ) uses WP_CONTENT_DIR as the value for $theme_root. So, the returned WP_Theme has a theme_not_found error.

So, the theme exists check in WP_Customize_Manager::setup_theme() fails and a "Cheatin' uh?" message is displayed.

A possible solution is the trash the theme_roots site transient post install so that the next get_theme_roots() calls search_theme_directories().

This is spun out of ocean90's comment on #20914.

Attachments (2)

20919.diff (532 bytes) - added by duck_ 3 years ago.
20919.2.diff (898 bytes) - added by nacin 3 years ago.

Download all attachments as: .zip

Change History (13)

comment:1 @duck_3 years ago

This code in wp_get_theme() is a little strange:

if ( false === $theme_root )
    $theme_root = WP_CONTENT_DIR . $theme_root;

concatenating false onto a string doesn't look right. Should this be defaulting to: WP_CONTENT_DIR . '/themes'?

Doing this would also stop the error message in the description if the theme is installed into the default directory.

comment:2 @nacin3 years ago

  • Milestone changed from Awaiting Review to 3.4

comment:3 follow-up: @nacin3 years ago

Making that $theme_root = WP_CONTENT_DIR . '/themes' should fix this, yes? That was a mistake in [20504] and is an easy adjustment.

comment:4 in reply to: ↑ 3 @duck_3 years ago

Replying to nacin:

Making that $theme_root = WP_CONTENT_DIR . '/themes' should fix this, yes? That was a mistake in [20504] and is an easy adjustment.

Yes.

@duck_3 years ago

comment:5 @nacin3 years ago

  • Keywords commit added

20919.diff looks good.

comment:6 @nacin3 years ago

  • Keywords has-patch added

comment:7 @nacin3 years ago

  • Owner set to nacin
  • Status changed from new to reviewing

@nacin3 years ago

comment:8 @nacin3 years ago

While the issue that 20919.diff is a bug, that block of code should not be hit here.

Rather, when a theme is installed or updated, we should be flushing the theme cache. We attempt to do this like so:

// Force refresh of theme update information
delete_site_transient('update_themes');
foreach ( wp_get_themes() as $theme )
	$theme->cache_delete();

While wp_get_themes() here has been called after the theme is installed, it was already called on the page thanks to wp_update_themes(). Thus, we're clearing the cache for individual themes, but not for the theme roots.

To allow for testing, we implemented a $force argument to search_theme_directories(), which means it skips its local cache. We also use this in get_theme_roots() to regenerate the transient if it does not exist. So, two options:

  1. Call delete_site_transient( 'theme_roots' ) and let core regenerate it on the next call to wp_get_themes().
  2. Forcibly update the theme root transient by calling search_theme_directories( true ).

They are functionally equivalent, but 2 seems like a better option, given our intention to force-clear all cache.

20919.2.diff implements this. Tested.


I stuck this at the top of wp_get_themes() for testing:

error_log( 'We have run wp_get_themes()' . "\n    " . remove_query_arg( null ) . "\n    Arguments: " . serialize( $args ) . "\n    Backtrace: " . wp_debug_backtrace_summary() );

comment:9 @nacin3 years ago

Both 20919.2.diff (nacin) and 20919.diff (duck_) should be committed.

comment:10 @ryan3 years ago

In [21063]:

Fallback to /themes when there is no theme root. Props duck_. see #20919

comment:11 @ryan3 years ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

In [21064]:

Force a theme directory scan after installing and upgrading themes. Props nacin. fixes #20919

Note: See TracTickets for help on using tickets.