Updates to WP_Theme, wp_get_themes(), and related deprecated functions, after [UT570] [UT578] [UT579]. see #20103.
* ['Template Files'] and ['Stylesheet Files'] need to return files from the parent theme as well. * Don't strip links from the Author header. Some themes rely on the previous behavior, such as to link multiple authors (Sandbox, for example.) Don't restore links to the Name, that's just a bad idea. * Ensure we are always passing around arrays in get_files/scandir. * Better inline doc for wp_get_themes() arguments. * Introduce a 'force' flag for search_theme_directories() to re-scan, rather than return the cache. We will use this to re-build the theme_roots transient in get_theme_roots(), but it is more helpful for unit tests. Since search_theme_directories() is cached, don't cache again in wp_get_themes(). (Again benefits testing.) * Handle duplicate theme names in the old get_themes() when two themes match (and neither are a default theme, which is already handled). wp_get_themes() will consider both names to be the same; this is just for back compat since get_themes() is keyed by name. * Include an old array key in wp_broken_themes(). git-svn-id: http://svn.automattic.com/wordpress/trunk@20193 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
af84dbcf93
commit
962fae26f4
|
@ -917,8 +917,10 @@ function get_broken_themes() {
|
||||||
$themes = wp_get_themes( array( 'errors' => true ) );
|
$themes = wp_get_themes( array( 'errors' => true ) );
|
||||||
$broken = array();
|
$broken = array();
|
||||||
foreach ( $themes as $theme ) {
|
foreach ( $themes as $theme ) {
|
||||||
$broken[ $theme->get('Name') ] = array(
|
$name = $theme->get('Name');
|
||||||
'Title' => $theme->get('Name'),
|
$broken[ $name ] = array(
|
||||||
|
'Name' => $name,
|
||||||
|
'Title' => $name,
|
||||||
'Description' => $theme->errors()->get_error_message(),
|
'Description' => $theme->errors()->get_error_message(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,12 +384,12 @@ final class WP_Theme implements ArrayAccess {
|
||||||
case 'Stylesheet' :
|
case 'Stylesheet' :
|
||||||
return $this->get_stylesheet();
|
return $this->get_stylesheet();
|
||||||
case 'Template Files' :
|
case 'Template Files' :
|
||||||
$files = $this->get_files('php');
|
$files = $this->get_files('php', true);
|
||||||
foreach ( $files as &$file )
|
foreach ( $files as &$file )
|
||||||
$file = $this->theme_root . '/' . $file;
|
$file = $this->theme_root . '/' . $file;
|
||||||
return $files;
|
return $files;
|
||||||
case 'Stylesheet Files' :
|
case 'Stylesheet Files' :
|
||||||
$files = $this->get_files('css');
|
$files = $this->get_files('css', true);
|
||||||
foreach ( $files as &$file )
|
foreach ( $files as &$file )
|
||||||
$file = $this->theme_root . '/' . $file;
|
$file = $this->theme_root . '/' . $file;
|
||||||
return $files;
|
return $files;
|
||||||
|
@ -555,7 +555,6 @@ final class WP_Theme implements ArrayAccess {
|
||||||
}
|
}
|
||||||
// Fall through otherwise.
|
// Fall through otherwise.
|
||||||
case 'Name' :
|
case 'Name' :
|
||||||
case 'Author' :
|
|
||||||
static $header_tags = array(
|
static $header_tags = array(
|
||||||
'abbr' => array( 'title' => true ),
|
'abbr' => array( 'title' => true ),
|
||||||
'acronym' => array( 'title' => true ),
|
'acronym' => array( 'title' => true ),
|
||||||
|
@ -565,6 +564,8 @@ final class WP_Theme implements ArrayAccess {
|
||||||
);
|
);
|
||||||
$value = wp_kses( $value, $header_tags );
|
$value = wp_kses( $value, $header_tags );
|
||||||
break;
|
break;
|
||||||
|
case 'Author' :
|
||||||
|
// There shouldn't be anchor tags in Author, but some themes like to be challenging.
|
||||||
case 'Description' :
|
case 'Description' :
|
||||||
static $header_tags_with_a = array(
|
static $header_tags_with_a = array(
|
||||||
'a' => array( 'href' => true, 'title' => true ),
|
'a' => array( 'href' => true, 'title' => true ),
|
||||||
|
@ -935,7 +936,9 @@ final class WP_Theme implements ArrayAccess {
|
||||||
if ( $include_parent_files || ! $this->is_child_theme() )
|
if ( $include_parent_files || ! $this->is_child_theme() )
|
||||||
// Template files can be one level down for the purposes of the theme editor, so this should be $depth = 1.
|
// Template files can be one level down for the purposes of the theme editor, so this should be $depth = 1.
|
||||||
// Todo: We ignore this for now, but this is why the branching is weird.
|
// Todo: We ignore this for now, but this is why the branching is weird.
|
||||||
$files = (array) self::scandir( $this->get_template_directory(), $this->get_template(), array( 'php', 'css' ) );
|
$files = self::scandir( $this->get_template_directory(), $this->get_template(), array( 'php', 'css' ) );
|
||||||
|
else
|
||||||
|
$files = array();
|
||||||
if ( $this->is_child_theme() )
|
if ( $this->is_child_theme() )
|
||||||
$files = array_merge_recursive( $files, (array) self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet(), array( 'php', 'css' ) ) );
|
$files = array_merge_recursive( $files, (array) self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet(), array( 'php', 'css' ) ) );
|
||||||
foreach ( $files as &$group )
|
foreach ( $files as &$group )
|
||||||
|
@ -989,14 +992,14 @@ final class WP_Theme implements ArrayAccess {
|
||||||
* @depth int How deep to search for files. Optional, defaults to a flat scan (0 depth).
|
* @depth int How deep to search for files. Optional, defaults to a flat scan (0 depth).
|
||||||
*/
|
*/
|
||||||
private static function scandir( $path, $relative_path, $extensions, $depth = 0 ) {
|
private static function scandir( $path, $relative_path, $extensions, $depth = 0 ) {
|
||||||
if ( is_array( $extensions ) )
|
|
||||||
$extensions = implode( '|', $extensions );
|
|
||||||
|
|
||||||
if ( ! is_dir( $path ) )
|
if ( ! is_dir( $path ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
$results = scandir( $path );
|
$results = scandir( $path );
|
||||||
$files = array();
|
|
||||||
|
$extensions = (array) $extensions;
|
||||||
|
$files = array_fill_keys( $extensions, array() );
|
||||||
|
$extensions = implode( '|', $extensions );
|
||||||
|
|
||||||
foreach ( $results as $result ) {
|
foreach ( $results as $result ) {
|
||||||
if ( '.' == $result || '..' == $result )
|
if ( '.' == $result || '..' == $result )
|
||||||
|
@ -1007,9 +1010,6 @@ final class WP_Theme implements ArrayAccess {
|
||||||
$found = self::scandir( $path . '/' . $result, $relative_path . '/' . $result, $extensions, $depth - 1 );
|
$found = self::scandir( $path . '/' . $result, $relative_path . '/' . $result, $extensions, $depth - 1 );
|
||||||
$files = array_merge_recursive( $files, $found );
|
$files = array_merge_recursive( $files, $found );
|
||||||
} elseif ( preg_match( '~\.(' . $extensions . ')$~', $result, $match ) ) {
|
} elseif ( preg_match( '~\.(' . $extensions . ')$~', $result, $match ) ) {
|
||||||
if ( ! isset( $files[ $match[1] ] ) )
|
|
||||||
$files[ $match[1] ] = array( $relative_path . '/'. $result );
|
|
||||||
else
|
|
||||||
$files[ $match[1] ][] = $relative_path . '/' . $result;
|
$files[ $match[1] ][] = $relative_path . '/' . $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2933,7 +2933,11 @@ function get_themes() {
|
||||||
$wp_themes = array();
|
$wp_themes = array();
|
||||||
|
|
||||||
foreach ( $themes as $theme ) {
|
foreach ( $themes as $theme ) {
|
||||||
$wp_themes[ $theme->get('Name') ] = $theme;
|
$name = $theme->get('Name');
|
||||||
|
if ( isset( $wp_themes[ $name ] ) )
|
||||||
|
$wp_themes[ $name . '/' . $theme->get_stylesheet() ] = $theme;
|
||||||
|
else
|
||||||
|
$wp_themes[ $name ] = $theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $wp_themes;
|
return $wp_themes;
|
||||||
|
|
|
@ -9,14 +9,19 @@
|
||||||
/**
|
/**
|
||||||
* Returns an array of WP_Theme objects based on the arguments.
|
* Returns an array of WP_Theme objects based on the arguments.
|
||||||
*
|
*
|
||||||
* Despite advances over get_themes(), this function is still quite expensive, and grows
|
* Despite advances over get_themes(), this function is quite expensive, and grows
|
||||||
* linearly with additional themes. Stick to wp_get_theme() if possible.
|
* linearly with additional themes. Stick to wp_get_theme() if possible.
|
||||||
*
|
*
|
||||||
* @since 3.4.0
|
* @since 3.4.0
|
||||||
*
|
*
|
||||||
* @param array $args Arguments. Currently 'errors' (defaults to false), 'allowed'
|
* @param array $args The search arguments. Optional.
|
||||||
* (true, false; null for either; defaults to null; only applies to multisite), and 'blog_id'
|
* - errors mixed True to return themes with errors, false to return themes without errors, null
|
||||||
* (defaults to current blog; used to find allowed themes; only applies to multisite).
|
* to return all themes. Defaults to false.
|
||||||
|
* - allowed mixed (Multisite) True to return only allowed themes for a site. False to return only
|
||||||
|
* disallowed themes for a site. 'site' to return only site-allowed themes. 'network'
|
||||||
|
* to return only network-allowed themes. Null to return all themes. Defaults to null.
|
||||||
|
* - blog_id int (Multisite) The blog ID used to calculate which themes are allowed. Defaults to 0,
|
||||||
|
* synonymous for the current blog.
|
||||||
* @return Array of WP_Theme objects.
|
* @return Array of WP_Theme objects.
|
||||||
*/
|
*/
|
||||||
function wp_get_themes( $args = array() ) {
|
function wp_get_themes( $args = array() ) {
|
||||||
|
@ -25,25 +30,23 @@ function wp_get_themes( $args = array() ) {
|
||||||
$defaults = array( 'errors' => false, 'allowed' => null, 'blog_id' => 0 );
|
$defaults = array( 'errors' => false, 'allowed' => null, 'blog_id' => 0 );
|
||||||
$args = wp_parse_args( $args, $defaults );
|
$args = wp_parse_args( $args, $defaults );
|
||||||
|
|
||||||
static $_theme_directories, $_themes = array();
|
$theme_directories = search_theme_directories();
|
||||||
if ( ! isset( $_theme_directories ) ) {
|
|
||||||
$_theme_directories = search_theme_directories();
|
|
||||||
if ( count( $wp_theme_directories ) > 1 ) {
|
if ( count( $wp_theme_directories ) > 1 ) {
|
||||||
// Make sure the current theme wins out, in case search_theme_directories() picks the wrong
|
// 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.)
|
// one in the case of a conflict. (Normally, last registered theme root wins.)
|
||||||
$current_theme = get_stylesheet();
|
$current_theme = get_stylesheet();
|
||||||
|
if ( isset( $theme_directories[ $current_theme ] ) ) {
|
||||||
$root_of_current_theme = get_raw_theme_root( $current_theme );
|
$root_of_current_theme = get_raw_theme_root( $current_theme );
|
||||||
if ( ! in_array( $root_of_current_theme, $wp_theme_directories ) )
|
if ( ! in_array( $root_of_current_theme, $wp_theme_directories ) )
|
||||||
$root_of_current_theme = WP_CONTENT_DIR . $root_of_current_theme;
|
$root_of_current_theme = WP_CONTENT_DIR . $root_of_current_theme;
|
||||||
$_theme_directories[ $current_theme ]['theme_root'] = $root_of_current_theme;
|
$theme_directories[ $current_theme ]['theme_root'] = $root_of_current_theme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( empty( $_theme_directories ) )
|
if ( empty( $theme_directories ) )
|
||||||
return array();
|
return array();
|
||||||
|
|
||||||
$theme_directories = $_theme_directories;
|
|
||||||
|
|
||||||
if ( is_multisite() && null !== $args['allowed'] ) {
|
if ( is_multisite() && null !== $args['allowed'] ) {
|
||||||
$allowed = $args['allowed'];
|
$allowed = $args['allowed'];
|
||||||
if ( 'network' === $allowed )
|
if ( 'network' === $allowed )
|
||||||
|
@ -355,7 +358,7 @@ function get_theme_roots() {
|
||||||
|
|
||||||
$theme_roots = get_site_transient( 'theme_roots' );
|
$theme_roots = get_site_transient( 'theme_roots' );
|
||||||
if ( false === $theme_roots ) {
|
if ( false === $theme_roots ) {
|
||||||
search_theme_directories(); // Regenerate the transient.
|
search_theme_directories( true ); // Regenerate the transient.
|
||||||
$theme_roots = get_site_transient( 'theme_roots' );
|
$theme_roots = get_site_transient( 'theme_roots' );
|
||||||
}
|
}
|
||||||
return $theme_roots;
|
return $theme_roots;
|
||||||
|
@ -390,15 +393,16 @@ function register_theme_directory( $directory ) {
|
||||||
*
|
*
|
||||||
* @since 2.9.0
|
* @since 2.9.0
|
||||||
*
|
*
|
||||||
|
* @param bool $force Optional. Whether to force a new directory scan. Defaults to false.
|
||||||
* @return array Valid themes found
|
* @return array Valid themes found
|
||||||
*/
|
*/
|
||||||
function search_theme_directories() {
|
function search_theme_directories( $force = false ) {
|
||||||
global $wp_theme_directories;
|
global $wp_theme_directories;
|
||||||
if ( empty( $wp_theme_directories ) )
|
if ( empty( $wp_theme_directories ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
static $found_themes;
|
static $found_themes;
|
||||||
if ( isset( $found_themes ) )
|
if ( ! $force && isset( $found_themes ) )
|
||||||
return $found_themes;
|
return $found_themes;
|
||||||
|
|
||||||
$found_themes = array();
|
$found_themes = array();
|
||||||
|
|
Loading…
Reference in New Issue