-/**
- * Retrieve theme data from parsed theme file.
- *
- * The description will have the tags filtered with the following HTML elements
- * whitelisted. The <b>'a'</b> element with the <em>href</em> and <em>title</em>
- * attributes. The <b>abbr</b> element with the <em>title</em> attribute. The
- * <b>acronym</b> element with the <em>title</em> attribute allowed. The
- * <b>code</b>, <b>em</b>, and <b>strong</b> elements also allowed.
- *
- * The style.css file must contain theme name, theme URI, and description. The
- * data can also contain author URI, author, template (parent template),
- * version, status, and finally tags. Some of these are not used by WordPress
- * administration panels, but are used by theme directory web sites which list
- * the theme.
- *
- * @since 1.5.0
- *
- * @param string $theme_file Theme file path.
- * @return array Theme data.
- */
-function get_theme_data( $theme_file ) {
- $default_headers = array(
- 'Name' => 'Theme Name',
- 'URI' => 'Theme URI',
- 'Description' => 'Description',
- 'Author' => 'Author',
- 'AuthorURI' => 'Author URI',
- 'Version' => 'Version',
- 'Template' => 'Template',
- 'Status' => 'Status',
- 'Tags' => 'Tags'
- );
-
- $themes_allowed_tags = array(
- 'a' => array(
- 'href' => array(),'title' => array()
- ),
- 'abbr' => array(
- 'title' => array()
- ),
- 'acronym' => array(
- 'title' => array()
- ),
- 'code' => array(),
- 'em' => array(),
- 'strong' => array()
- );
-
- $theme_data = get_file_data( $theme_file, $default_headers, 'theme' );
-
- $theme_data['Name'] = $theme_data['Title'] = wp_kses( $theme_data['Name'], $themes_allowed_tags );
-
- $theme_data['URI'] = esc_url( $theme_data['URI'] );
-
- $theme_data['Description'] = wptexturize( wp_kses( $theme_data['Description'], $themes_allowed_tags ) );
-
- $theme_data['AuthorURI'] = esc_url( $theme_data['AuthorURI'] );
-
- $theme_data['Template'] = wp_kses( $theme_data['Template'], $themes_allowed_tags );
-
- $theme_data['Version'] = wp_kses( $theme_data['Version'], $themes_allowed_tags );
-
- if ( $theme_data['Status'] == '' )
- $theme_data['Status'] = 'publish';
- else
- $theme_data['Status'] = wp_kses( $theme_data['Status'], $themes_allowed_tags );
-
- if ( $theme_data['Tags'] == '' )
- $theme_data['Tags'] = array();
- else
- $theme_data['Tags'] = array_map( 'trim', explode( ',', wp_kses( $theme_data['Tags'], array() ) ) );
-
- if ( $theme_data['Author'] == '' ) {
- $theme_data['Author'] = $theme_data['AuthorName'] = __('Anonymous');
- } else {
- $theme_data['AuthorName'] = wp_kses( $theme_data['Author'], $themes_allowed_tags );
- if ( empty( $theme_data['AuthorURI'] ) ) {
- $theme_data['Author'] = $theme_data['AuthorName'];
- } else {
- $theme_data['Author'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $theme_data['AuthorURI'], esc_attr__( 'Visit author homepage' ), $theme_data['AuthorName'] );
- }
- }
-
- return $theme_data;
-}
-
-/**
- * Retrieve list of themes with theme data in theme directory.
- *
- * The theme is broken, if it doesn't have a parent theme and is missing either
- * style.css and, or index.php. If the theme has a parent theme then it is
- * broken, if it is missing style.css; index.php is optional. The broken theme
- * list is saved in the {@link $wp_broken_themes} global, which is displayed on
- * the theme list in the administration panels.
- *
- * @since 1.5.0
- * @global array $wp_broken_themes Stores the broken themes.
- * @global array $wp_themes Stores the working themes.
- *
- * @return array Theme list with theme data.
- */
-function get_themes() {
- global $wp_themes, $wp_broken_themes;
-
- if ( isset($wp_themes) )
- return $wp_themes;
-
- if ( !$theme_files = search_theme_directories() )
- return false;
-
- asort( $theme_files );
-
- $wp_themes = array();
-
- foreach ( (array) $theme_files as $theme_file ) {
- $theme_root = $theme_file['theme_root'];
- $theme_file = $theme_file['theme_file'];
-
- if ( !is_readable("$theme_root/$theme_file") ) {
- $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.'));
- continue;
- }
-
- $theme_data = get_theme_data("$theme_root/$theme_file");
-
- $name = $theme_data['Name'];
- $title = $theme_data['Title'];
- $description = wptexturize($theme_data['Description']);
- $version = $theme_data['Version'];
- $author = $theme_data['Author'];
- $template = $theme_data['Template'];
- $stylesheet = dirname($theme_file);
-
- $screenshot = false;
- foreach ( array('png', 'gif', 'jpg', 'jpeg') as $ext ) {
- if (file_exists("$theme_root/$stylesheet/screenshot.$ext")) {
- $screenshot = "screenshot.$ext";
- break;
- }
- }
-
- if ( empty($name) ) {
- $name = dirname($theme_file);
- $title = $name;
- }
-
- $parent_template = $template;
-
- if ( empty($template) ) {
- if ( file_exists("$theme_root/$stylesheet/index.php") )
- $template = $stylesheet;
- else
- continue;
- }
-
- $template = trim( $template );
-
- if ( !file_exists("$theme_root/$template/index.php") ) {
- $parent_dir = dirname(dirname($theme_file));
- if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) {
- $template = "$parent_dir/$template";
- $template_directory = "$theme_root/$template";
- } else {
- /**
- * The parent theme doesn't exist in the current theme's folder or sub folder
- * so lets use the theme root for the parent template.
- */
- if ( isset($theme_files[$template]) && file_exists( $theme_files[$template]['theme_root'] . "/$template/index.php" ) ) {
- $template_directory = $theme_files[$template]['theme_root'] . "/$template";
- } else {
- if ( empty( $parent_template) )
- $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'), 'error' => 'no_template');
- else
- $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => sprintf( __('The parent theme is missing. Please install the "%s" parent theme.'), $parent_template ), 'error' => 'no_parent', 'parent' => $parent_template );
- continue;
- }
-
- }
- } else {
- $template_directory = trim( $theme_root . '/' . $template );
- }
-
- $stylesheet_files = array();
- $template_files = array();
-
- $stylesheet_dir = @ dir("$theme_root/$stylesheet");
- if ( $stylesheet_dir ) {
- while ( ($file = $stylesheet_dir->read()) !== false ) {
- if ( !preg_match('|^\.+$|', $file) ) {
- if ( preg_match('|\.css$|', $file) )
- $stylesheet_files[] = "$theme_root/$stylesheet/$file";
- elseif ( preg_match('|\.php$|', $file) )
- $template_files[] = "$theme_root/$stylesheet/$file";
- }
- }
- @ $stylesheet_dir->close();
- }
-
- $template_dir = @ dir("$template_directory");
- if ( $template_dir ) {
- while ( ($file = $template_dir->read()) !== false ) {
- if ( preg_match('|^\.+$|', $file) )
- continue;
- if ( preg_match('|\.php$|', $file) ) {
- $template_files[] = "$template_directory/$file";
- } elseif ( is_dir("$template_directory/$file") ) {
- $template_subdir = @ dir("$template_directory/$file");
- if ( !$template_subdir )
- continue;
- while ( ($subfile = $template_subdir->read()) !== false ) {
- if ( preg_match('|^\.+$|', $subfile) )
- continue;
- if ( preg_match('|\.php$|', $subfile) )
- $template_files[] = "$template_directory/$file/$subfile";
- }
- @ $template_subdir->close();
- }
- }
- @ $template_dir->close();
- }
-
- //Make unique and remove duplicates when stylesheet and template are the same i.e. most themes
- $template_files = array_unique($template_files);
- $stylesheet_files = array_unique($stylesheet_files);
-
- $template_dir = $template_directory;
- $stylesheet_dir = $theme_root . '/' . $stylesheet;
-
- if ( empty($template_dir) )
- $template_dir = '/';
- if ( empty($stylesheet_dir) )
- $stylesheet_dir = '/';
-
- // Check for theme name collision. This occurs if a theme is copied to
- // a new theme directory and the theme header is not updated. Whichever
- // theme is first keeps the name. Subsequent themes get a suffix applied.
- // The Twenty Ten, Default and Classic themes always trump their pretenders.
- if ( isset($wp_themes[$name]) ) {
- $trump_cards = array(
- 'classic' => 'WordPress Classic',
- 'default' => 'WordPress Default',
- 'twentyten' => 'Twenty Ten',
- );
- if ( isset( $trump_cards[ $stylesheet ] ) && $name == $trump_cards[ $stylesheet ] ) {
- // If another theme has claimed to be one of our default themes, move
- // them aside.
- $suffix = $wp_themes[$name]['Stylesheet'];
- $new_name = "$name/$suffix";
- $wp_themes[$new_name] = $wp_themes[$name];
- $wp_themes[$new_name]['Name'] = $new_name;
- } else {
- $name = "$name/$stylesheet";
- }
- }
-
- $theme_roots[$stylesheet] = str_replace( WP_CONTENT_DIR, '', $theme_root );
- $wp_themes[$name] = array(
- 'Name' => $name,
- 'Title' => $title,
- 'Description' => $description,
- 'Author' => $author,
- 'Author Name' => $theme_data['AuthorName'],
- 'Author URI' => $theme_data['AuthorURI'],
- 'Version' => $version,
- 'Template' => $template,
- 'Stylesheet' => $stylesheet,
- 'Template Files' => $template_files,
- 'Stylesheet Files' => $stylesheet_files,
- 'Template Dir' => $template_dir,
- 'Stylesheet Dir' => $stylesheet_dir,
- 'Status' => $theme_data['Status'],
- 'Screenshot' => $screenshot,
- 'Tags' => $theme_data['Tags'],
- 'Theme Root' => $theme_root,
- 'Theme Root URI' => str_replace( WP_CONTENT_DIR, content_url(), $theme_root ),
- );
- }
-
- unset($theme_files);
-
- /* Store theme roots in the DB */
- if ( get_site_transient( 'theme_roots' ) != $theme_roots )
- set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours
- unset($theme_roots);
-
- /* Resolve theme dependencies. */
- $theme_names = array_keys( $wp_themes );
- foreach ( (array) $theme_names as $theme_name ) {
- $wp_themes[$theme_name]['Parent Theme'] = '';
- if ( $wp_themes[$theme_name]['Stylesheet'] != $wp_themes[$theme_name]['Template'] ) {
- foreach ( (array) $theme_names as $parent_theme_name ) {
- if ( ($wp_themes[$parent_theme_name]['Stylesheet'] == $wp_themes[$parent_theme_name]['Template']) && ($wp_themes[$parent_theme_name]['Template'] == $wp_themes[$theme_name]['Template']) ) {
- $wp_themes[$theme_name]['Parent Theme'] = $wp_themes[$parent_theme_name]['Name'];
- break;
- }
- }
- }
- }
-
- return $wp_themes;
-}
-