In wp_get_themes() under multisite, filter out allowed themes before creating WP_Theme objects, rather than after. search_theme_directories() provides us the stylesheet of each theme which is all we need to do the proper intersection. This results in major performance gains on sites that have large numbers of themes unavailable to them. see #20103.

git-svn-id: https://develop.svn.wordpress.org/trunk@20152 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Nacin 2012-03-08 07:46:39 +00:00
parent c7b3d21c18
commit 47dd0db830
1 changed files with 38 additions and 33 deletions

View File

@ -25,45 +25,50 @@ function wp_get_themes( $args = array() ) {
$defaults = array( 'errors' => false, 'allowed' => null, 'blog_id' => 0 );
$args = wp_parse_args( $args, $defaults );
static $_themes;
if ( ! isset( $_themes ) ) {
$_themes = array();
$theme_data = search_theme_directories();
static $_theme_directories, $_themes = array();
if ( ! isset( $_theme_directories ) ) {
$_theme_directories = search_theme_directories();
if ( count( $wp_theme_directories ) > 1 ) {
// Make sure the current theme wins out, in case search_theme_directories() picks the wrong
// one in the case of a conflict. (Normally, last registered theme root wins.)
$current_theme = get_stylesheet();
$current_theme_root = get_raw_theme_root( $current_theme );
if ( ! in_array( $current_theme_root, $wp_theme_directories ) )
$current_theme_root = WP_CONTENT_DIR . $current_theme_root;
foreach ( (array) $theme_data as $theme_slug => $data ) {
if ( $current_theme == $theme_slug && $current_theme_root != $data['theme_root'] )
$_themes[ $theme_slug ] = new WP_Theme( $theme_slug, $current_theme_root );
else
$_themes[ $theme_slug ] = new WP_Theme( $theme_slug, $data['theme_root'] );
$root_of_current_theme = get_raw_theme_root( $current_theme );
if ( ! in_array( $root_of_current_theme, $wp_theme_directories ) )
$root_of_current_theme = WP_CONTENT_DIR . $current_theme_root;
$_theme_directories[ $current_theme ]['theme_root'] = $root_of_current_theme;
}
}
$themes = $_themes;
if ( empty( $themes ) )
return $themes;
if ( empty( $_theme_directories ) )
return array();
if ( null !== $args['errors'] ) {
foreach ( $themes as $theme_slug => $theme ) {
if ( $theme->errors() != $args['errors'] )
unset( $themes[ $theme_slug ] );
}
}
$theme_directories = $_theme_directories;
if ( is_multisite() && null !== $args['allowed'] ) {
if ( $allowed = $args['allowed'] ) {
$allowed = $args['allowed'];
if ( 'network' === $allowed )
$themes = array_intersect_key( $themes, WP_Theme::get_allowed_on_network( $args['blog_id'] ) );
$theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed_on_network( $args['blog_id'] ) );
elseif ( 'site' === $allowed )
$themes = array_intersect_key( $themes, WP_Theme::get_allowed_on_site( $args['blog_id'] ) );
$theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed_on_site( $args['blog_id'] ) );
elseif ( $allowed )
$theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed( $args['blog_id'] ) );
else
$themes = array_intersect_key( $themes, WP_Theme::get_allowed( $args['blog_id'] ) );
} else {
$themes = array_diff_key( $themes, WP_Theme::get_allowed( $args['blog_id'] ) );
$theme_directories = array_diff_key( $theme_directories, WP_Theme::get_allowed( $args['blog_id'] ) );
}
$themes = array();
foreach ( $theme_directories as $theme => $theme_root ) {
if ( isset( $_themes[ $theme ] ) )
$themes[ $theme ] = $_themes[ $theme ];
else
$themes[ $theme ] = $_themes[ $theme ] = new WP_Theme( $theme, $theme_root['theme_root'] );
}
if ( null !== $args['errors'] ) {
foreach ( $themes as $theme => $wp_theme ) {
if ( $wp_theme->errors() != $args['errors'] )
unset( $themes[ $theme ] );
}
}