WordPress.org

Make WordPress Core

Ticket #20103: wp_theme.diff

File wp_theme.diff, 98.7 KB (added by nacin, 2 years ago)
  • wp-includes/class-wp-customize.php

     
    8181 
    8282                add_filter( 'template', array( $this, 'get_template' ) ); 
    8383                add_filter( 'stylesheet', array( $this, 'get_stylesheet' ) ); 
    84                 add_filter( 'pre_option_current_theme', array( $this, 'current_theme' ) ); 
    8584 
    8685                // @link: http://core.trac.wordpress.org/ticket/20027 
    8786                add_filter( 'pre_option_stylesheet', array( $this, 'get_stylesheet' ) ); 
     
    235234        } 
    236235 
    237236        /** 
    238          * Filter the current theme and return the name of the previewed theme. 
    239          * 
    240          * @since 3.4.0 
    241          * 
    242          * @return string Theme name. 
    243          */ 
    244         public function current_theme( $current_theme ) { 
    245                 $themes = get_themes(); 
    246  
    247                 if ( ! $themes ) 
    248                         return $current_theme; 
    249  
    250                 foreach ( $themes as $theme ) { 
    251                         if ( $theme['Stylesheet'] == $this->stylesheet && $theme['Template'] == $this->template ) 
    252                                 return $theme['Name']; 
    253                 } 
    254  
    255                 return $current_theme; 
    256         } 
    257  
    258         /** 
    259237         * Trigger save action and load customize controls. 
    260238         * 
    261239         * @since 3.4.0 
  • wp-includes/update.php

     
    235235        if ( defined( 'WP_INSTALLING' ) ) 
    236236                return false; 
    237237 
    238         if ( !function_exists( 'get_themes' ) ) 
    239                 require_once( ABSPATH . 'wp-includes/theme.php' ); 
    240  
    241         $installed_themes = get_themes( ); 
     238        $installed_themes = wp_get_themes(); 
    242239        $last_update = get_site_transient( 'update_themes' ); 
    243240        if ( ! is_object($last_update) ) 
    244241                $last_update = new stdClass; 
    245242 
    246243        $themes = array(); 
    247244        $checked = array(); 
    248         $exclude_fields = array('Template Files', 'Stylesheet Files', 'Status', 'Theme Root', 'Theme Root URI', 'Template Dir', 'Stylesheet Dir', 'Description', 'Tags', 'Screenshot'); 
    249245 
    250246        // Put slug of current theme into request. 
    251247        $themes['current_theme'] = get_option( 'stylesheet' ); 
    252248 
    253         foreach ( (array) $installed_themes as $theme_title => $theme ) { 
    254                 $themes[$theme['Stylesheet']] = array(); 
    255                 $checked[$theme['Stylesheet']] = $theme['Version']; 
     249        foreach ( $installed_themes as $theme ) { 
     250                $checked[ $theme->get_stylesheet() ] = $theme->get('Version'); 
    256251 
    257                 $themes[$theme['Stylesheet']]['Name'] = $theme['Name']; 
    258                 $themes[$theme['Stylesheet']]['Version'] = $theme['Version']; 
    259  
    260                 foreach ( (array) $theme as $key => $value ) { 
    261                         if ( !in_array($key, $exclude_fields) ) 
    262                                 $themes[$theme['Stylesheet']][$key] = $value; 
    263                 } 
     252                $themes[ $theme->get_stylesheet() ] = array( 
     253                        'Name'       => $theme->get('Name'), 
     254                        'Title'      => $theme->get('Name'), 
     255                        'Version'    => $theme->get('Version'), 
     256                        'Author'     => $theme->get('Author'), 
     257                        'Author URI'  => $theme->get('AuthorURI'), 
     258                        'Template'   => $theme->get_template(), 
     259                        'Stylesheet' => $theme->get_stylesheet(), 
     260                ); 
    264261        } 
    265262 
    266263        // Check for update on a different schedule, depending on the page. 
  • wp-includes/class-wp-theme.php

     
     1<?php 
     2/** 
     3 * WP_Theme Class 
     4 * 
     5 * @package WordPress 
     6 * @subpackage Theme 
     7 */ 
     8 
     9final class WP_Theme implements ArrayAccess { 
     10 
     11        /** 
     12         * Headers for style.css files. 
     13         * 
     14         * @static 
     15         * @access private 
     16         * @var array 
     17         */ 
     18        private static $file_headers = array( 
     19                'Name'        => 'Theme Name', 
     20                'ThemeURI'    => 'Theme URI', 
     21                'Description' => 'Description', 
     22                'Author'      => 'Author', 
     23                'AuthorURI'   => 'Author URI', 
     24                'Version'     => 'Version', 
     25                'Template'    => 'Template', 
     26                'Status'      => 'Status', 
     27                'Tags'        => 'Tags', 
     28                'TextDomain'  => 'Text Domain', 
     29                'DomainPath'  => 'Domain Path', 
     30        ); 
     31 
     32        /** 
     33         * Absolute path to the theme root, usually wp-content/themes 
     34         * 
     35         * @access private 
     36         * @var string 
     37         */ 
     38        private $theme_root; 
     39 
     40        /** 
     41         * Header data from the theme's style.css file. 
     42         * 
     43         * @access private 
     44         * @var array 
     45         */ 
     46        private $headers = array(); 
     47 
     48        /** 
     49         * Header data from the theme's style.css file after being sanitized. 
     50         * 
     51         * @access private 
     52         * @var array 
     53         */ 
     54        private $headers_sanitized; 
     55 
     56        /** 
     57         * Header name from the theme's style.css after being translated. 
     58         * 
     59         * Cached due to sorting functions running over the translated name. 
     60         */ 
     61        private $name_translated; 
     62 
     63        /** 
     64         * Errors encountered when initializing the theme. 
     65         * 
     66         * @access private 
     67         * @var WP_Error 
     68         */ 
     69        private $errors; 
     70 
     71        /** 
     72         * The directory name of the theme's files, inside the theme root. 
     73         * 
     74         * In the case of a child theme, this is directory name of the the child theme. 
     75         * Otherwise, 'stylesheet' is the same as 'template'. 
     76         * 
     77         * @access private 
     78         * @var string 
     79         */ 
     80        private $stylesheet; 
     81 
     82        /** 
     83         * The directory name of the theme's files, inside the theme root. 
     84         * 
     85         * In the case of a child theme, this is the directory name of the parent theme. 
     86         * Otherwise, 'template' is the same as 'stylesheet'. 
     87         * 
     88         * @access private 
     89         * @var string 
     90         */ 
     91        private $template; 
     92 
     93        /** 
     94         * A reference to the parent theme, in the case of a child theme. 
     95         * 
     96         * @access private 
     97         * @var WP_Theme 
     98         */ 
     99        private $parent; 
     100 
     101        /** 
     102         * Flag for whether the theme's textdomain is loaded. 
     103         * 
     104         * @access private 
     105         * @var bool 
     106         */ 
     107        private $textdomain_loaded; 
     108 
     109        /** 
     110         * Flag for whether the themes cache bucket should be persistently cached. 
     111         * 
     112         * Default is false. Can be set with the wp_cache_themes_persistent filter. 
     113         * 
     114         * @access private 
     115         * @var bool 
     116         */ 
     117        private static $persistently_cache; 
     118 
     119        /** 
     120         * Expiration time for the themes cache bucket. 
     121         * 
     122         * By default the bucket is not cached, so this value is useless. 
     123         * 
     124         * @access private 
     125         * @var bool 
     126         */ 
     127        private static $cache_expiration = 7200; 
     128 
     129        /** 
     130         * Constructor for WP_Theme. 
     131         * 
     132         * @param string $theme_dir Directory of the theme within the theme_root. 
     133         * @param string $theme_root Theme root. 
     134         * @param WP_Error|null $child If this theme is a parent theme, the child may be passed for validation purposes. 
     135         */ 
     136        public function __construct( $theme_dir, $theme_root, $child = null ) { 
     137                // Initialize caching on first run. 
     138                if ( ! isset( self::$persistently_cache ) ) { 
     139                        self::$persistently_cache = apply_filters( 'wp_cache_themes_persistently', false ); 
     140                        if ( is_int( self::$persistently_cache ) ) 
     141                                self::$cache_expiration = self::$persistently_cache; 
     142                        elseif ( ! self::$persistently_cache ) 
     143                                wp_cache_add_non_persistent_groups( 'themes' ); 
     144                } 
     145 
     146                $this->theme_root = $theme_root; 
     147                $this->stylesheet = $theme_dir; 
     148                $theme_file = $this->stylesheet . '/style.css'; 
     149 
     150                $cache = $this->cache_get( 'theme' ); 
     151 
     152                if ( is_array( $cache ) ) { 
     153                        foreach ( array( 'errors', 'headers', 'template', 'stylesheet' ) as $key ) { 
     154                                if ( isset( $cache[ $key ] ) ) 
     155                                        $this->$key = $cache[ $key ]; 
     156                        } 
     157                        if ( $this->errors ) 
     158                                return; 
     159                } elseif ( ! file_exists( $this->theme_root . '/' . $theme_file ) ) { 
     160                        $this->headers['Name'] = $this->stylesheet; 
     161                        $this->errors = new WP_Error( 'theme_no_stylesheet', __( 'Stylesheet is missing.' ) ); 
     162                        $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet ) ); 
     163                        if ( ! file_exists( $this->theme_root ) ) // Don't cache this one. 
     164                                $this->errors->add( 'theme_root_missing', __( 'ERROR: The themes directory is either empty or doesn&#8217;t exist. Please check your installation.' ) ); 
     165                        return; 
     166                } elseif ( ! is_readable( $this->theme_root . '/' . $theme_file ) ) { 
     167                        $this->headers['Name'] = $this->stylesheet; 
     168                        $this->errors = new WP_Error( 'theme_stylesheet_not_readable', __( 'Stylesheet is not readable.' ) ); 
     169                        $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet ) ); 
     170                        return; 
     171                } else { 
     172                        $this->headers = get_file_data( $this->theme_root . '/' . $theme_file, self::$file_headers, 'theme' ); 
     173                } 
     174 
     175                if ( ! $this->template = $this->get('Template') ) { 
     176                        if ( file_exists( $this->theme_root . '/' . $this->stylesheet . '/index.php' ) ) { 
     177                                $this->template = $this->stylesheet; 
     178                        } else { 
     179                                $this->errors = new WP_Error( 'theme_no_index', __( 'Template is missing.' ) ); 
     180                                $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet ) ); 
     181                                return; 
     182                        } 
     183                } 
     184 
     185                if ( $this->template != $this->stylesheet && ! file_exists( $this->theme_root . '/' . $this->template . '/index.php' ) ) { 
     186                        // If we're in a directory of themes inside /themes, look for the parent nearby. 
     187                        // wp-content/themes/directory-of-themes/* 
     188                        $parent_dir = dirname( $this->stylesheet ); 
     189                        if ( '.' != $parent_dir && file_exists( $this->theme_root . '/' . $parent_dir . '/' . $this->template . '/index.php' ) ) { 
     190                                $this->template = $parent_dir . '/' . $this->template; 
     191                        } elseif ( ( $directories = search_theme_directories() ) && isset( $directories[ $this->template ] ) ) { 
     192                                // Look for the template in the search_theme_directories() results, in case it is in another theme root. 
     193                                // We don't look into directories of themes, just the theme root. 
     194                                $theme_root_template = $directories[ $this->template ]['theme_root']; 
     195                        } else { 
     196                                // Parent theme is missing. 
     197                                $this->errors = new WP_Error( 'theme_no_parent', sprintf( __( 'The parent theme is missing. Please install the "%s" parent theme.' ), $this->template ) ); 
     198                                $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template ) ); 
     199                                return; 
     200                        } 
     201                } 
     202 
     203                // @TODO Check for theme name collision. But guess what? We don't care anymore! We only care about clashing matches found in search_theme_directories(). 
     204 
     205                // Set the parent, if we're a child theme. 
     206                if ( $this->template != $this->stylesheet ) { 
     207                        // If we are a parent, then there is a problem. Only two generations allowed! Cancel things out. 
     208                        if ( is_a( $child, 'WP_Theme' ) && $child->template == $this->stylesheet ) { 
     209                                $child->parent = null; 
     210                                $child->errors = new WP_Error( 'theme_parent_invalid', sprintf( __( 'The "%s" theme is not a valid parent theme.' ), $child->template ) ); 
     211                                $child->cache_add( 'theme', array( 'headers' => $child->headers, 'errors' => $child->errors, 'stylesheet' => $child->stylesheet, 'template' => $child->template ) ); 
     212                                // The two themes actually reference each other with the Template header. 
     213                                if ( $child->stylesheet == $this->template ) { 
     214                                        $this->errors = new WP_Error( 'theme_parent_invalid', sprintf( __( 'The "%s" theme is not a valid parent theme.' ), $this->template ) ); 
     215                                        $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template ) ); 
     216                                } 
     217                                return; 
     218                        } 
     219                        // Set the parent. Pass the current instance so we can do the crazy checks above and assess errors. 
     220                        $this->parent = new WP_Theme( $this->template, isset( $theme_root_template ) ? $theme_root_template : $this->theme_root, $this ); 
     221                } 
     222 
     223                // We're good. If we didn't retrieve from cache, set it. 
     224                if ( ! is_array( $cache ) ) 
     225                        $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template ) ); 
     226        } 
     227 
     228        /** 
     229         * __isset() magic method for properties formerly returned by current_theme_info() 
     230         */ 
     231        public function __isset( $offset ) { 
     232                static $properties = array( 
     233                        'name', 'title', 'version', 'parent_theme', 'template_dir', 'stylesheet_dir', 'template', 'stylesheet', 
     234                        'screenshot', 'description', 'author', 'tags', 'theme_root', 'theme_root_uri', 
     235                ); 
     236 
     237                return in_array( $offset, $properties ); 
     238        } 
     239 
     240        /** 
     241         * __get() magic method for properties formerly returned by current_theme_info() 
     242         */ 
     243        public function __get( $offset ) { 
     244                switch ( $offset ) { 
     245                        case 'name' : 
     246                        case 'title' : 
     247                                return $this->get('Name'); 
     248                        case 'version' : 
     249                                return $this->get('Version'); 
     250                        case 'parent_theme' : 
     251                                return $this->parent ? $this->parent->get('Name') : ''; 
     252                        case 'template_dir' : 
     253                                return $this->get_template_directory(); 
     254                        case 'stylesheet_dir' : 
     255                                return $this->get_stylesheet_directory(); 
     256                        case 'template' : 
     257                                return $this->get_template(); 
     258                        case 'stylesheet' : 
     259                                return $this->get_stylesheet(); 
     260                        case 'screenshot' : 
     261                                return $this->get_screenshot(); 
     262                        // 'author' and 'description' did not previously return translated data. 
     263                        case 'description' : 
     264                                return $this->display('Description'); 
     265                        case 'author' : 
     266                                return $this->display('Author'); 
     267                        case 'tags' : 
     268                                return $this->get( 'Tags' ); 
     269                        case 'theme_root' : 
     270                                return $this->get_theme_root(); 
     271                        case 'theme_root_uri' : 
     272                                return $this->get_theme_root_uri(); 
     273                } 
     274        } 
     275 
     276        /** 
     277         * Method to implement ArrayAccess for keys formerly returned by get_themes() 
     278         */ 
     279    public function offsetSet( $offset, $value ) {} 
     280 
     281        /** 
     282         * Method to implement ArrayAccess for keys formerly returned by get_themes() 
     283         */ 
     284    public function offsetUnset( $offset ) {} 
     285 
     286        /** 
     287         * Method to implement ArrayAccess for keys formerly returned by get_themes() 
     288         */ 
     289    public function offsetExists( $offset ) { 
     290        static $keys = array( 
     291                'Name', 'Version', 'Status', 'Title', 'Author', 'Author Name', 'Author URI', 'Description', 
     292                        'Template', 'Stylesheet', 'Template Files', 'Stylesheet Files', 'Template Dir', 'Stylesheet Dir', 
     293                         'Screenshot', 'Tags', 'Theme Root', 'Theme Root URI', 'Parent Theme', 
     294                ); 
     295 
     296        return in_array( $offset, $keys ); 
     297        } 
     298 
     299        /** 
     300         * Method to implement ArrayAccess for keys formerly returned by get_themes() 
     301         */ 
     302        public function offsetGet( $offset ) { 
     303        switch ( $offset ) { 
     304                        case 'Name' : 
     305                        case 'Version' : 
     306                        case 'Status' : 
     307                                return $this->get( $offset ); 
     308                        case 'Title' : 
     309                                return $this->get('Name'); 
     310                        // Author, Author Name, Author URI, and Description did not 
     311                        // previously return translated data. We are doing so now. 
     312                        // Title and Name could have been used as the key for get_themes(), 
     313                        // so both to remain untranslated for back compatibility. 
     314                        case 'Author' : 
     315                                return $this->display( 'Author'); 
     316                        case 'Author Name' : 
     317                                return $this->display( 'Author', false); 
     318                        case 'Author URI' : 
     319                                return $this->display('AuthorURI'); 
     320                        case 'Description' : 
     321                                return $this->display( 'Description'); 
     322                        case 'Template' : 
     323                                return $this->get_template(); 
     324                        case 'Stylesheet' : 
     325                                return $this->get_stylesheet(); 
     326                        case 'Template Files' : 
     327                                $files = $this->get_files('php'); 
     328                                foreach ( $files as &$file ) 
     329                                        $file = $this->theme_root . '/' . $file; 
     330                                return $files; 
     331                        case 'Stylesheet Files' : 
     332                                $files = $this->get_files('css'); 
     333                                foreach ( $files as &$file ) 
     334                                        $file = $this->theme_root . '/' . $file; 
     335                                return $files; 
     336                        case 'Template Dir' : 
     337                                return $this->get_template_directory(); 
     338                        case 'Stylesheet Dir' : 
     339                                return $this->get_stylesheet_directory(); 
     340                        case 'Screenshot' : 
     341                                return $this->get_screenshot(); 
     342                        case 'Tags' : 
     343                                return $this->get('Tags'); 
     344                        case 'Theme Root' : 
     345                                return $this->get_theme_root(); 
     346                        case 'Theme Root URI' : 
     347                                return $this->get_theme_root_uri(); 
     348                        case 'Parent Theme' : 
     349                                return $this->parent ? $this->parent->get('Name') : ''; 
     350                        default : 
     351                                return null; 
     352                } 
     353        } 
     354 
     355        /** 
     356         * Returns errors property. 
     357         * 
     358         * @since 3.4.0 
     359         * @access public 
     360         * 
     361         * @return WP_Error|bool WP_Error if there are errors, or false. 
     362         */ 
     363        public function errors() { 
     364                return is_wp_error( $this->errors ) ? $this->errors : false; 
     365        } 
     366 
     367        /** 
     368         * Returns reference to the parent theme. 
     369         * 
     370         * @since 3.4.0 
     371         * @access public 
     372         * 
     373         * @return WP_Theme|bool Parent theme, or false if the current theme is not a child theme. 
     374         */ 
     375        public function parent() { 
     376                return isset( $this->parent ) ? $this->parent : false; 
     377        } 
     378 
     379        /** 
     380         * Adds theme data to cache. 
     381         * 
     382         * Cache entries keyed by the theme and the type of data. 
     383         * 
     384         * @access private 
     385         * @since 3.4.0 
     386         * 
     387         * @param string $key Type of data to store (theme, screenshot, screenshot_count, files, headers) 
     388         * @param string $data Data to store 
     389         * @return bool Return value from wp_cache_add() 
     390         */ 
     391        private function cache_add( $key, $data ) { 
     392                return wp_cache_add( $key . '-' . $this->theme_root . '/' . $this->stylesheet, $data, 'themes', self::$cache_expiration ); 
     393        } 
     394 
     395        /** 
     396         * Gets theme data from cache. 
     397         * 
     398         * Cache entries are keyed by the theme and the type of data. 
     399         * 
     400         * @access private 
     401         * @since 3.4.0 
     402         * 
     403         * @param string $key Type of data to retrieve (theme, screenshot, screenshot_count, files, headers) 
     404         * @return mixed Retrieved data 
     405         */ 
     406        private function cache_get( $key ) { 
     407                return wp_cache_get( $key . '-' . $this->theme_root . '/' . $this->stylesheet, 'themes' ); 
     408        } 
     409 
     410        /** 
     411         * Clears the cache for the theme. 
     412         * 
     413         * @access public 
     414         * @since 3.4.0 
     415         */ 
     416        public function clear_cache() { 
     417                wp_cache_delete( 'theme-' . $this->cache_key, 'themes' ); 
     418                wp_cache_delete( 'screenshot-' . $this->cache_key, 'themes' ); 
     419                wp_cache_delete( 'screenshot_count-' . $this->cache_key, 'themes' ); 
     420                wp_cache_delete( 'files-' . $this->cache_key, 'themes' ); 
     421                wp_cache_delete( 'headers-' . $this->cache_key, 'themes' ); 
     422        } 
     423 
     424        /** 
     425         * Gets a theme header. 
     426         * 
     427         * The header is sanitized. 
     428         * 
     429         * @access public 
     430         * @since 3.4.0 
     431         * 
     432         * @param string $header Theme header. Name, Description, Author, Version, ThemeURI, AuthorURI, Status. 
     433         * @return string String on success, false on failure. 
     434         */ 
     435        public function get( $header ) { 
     436                if ( ! isset( $this->headers[ $header ] ) ) 
     437                        return false; 
     438 
     439                if ( ! isset( $this->headers_sanitized ) ) { 
     440                        $this->headers_sanitized = $this->cache_get( 'headers' ); 
     441                        if ( ! is_array( $this->headers_sanitized ) ) 
     442                                $headers = array(); 
     443                } 
     444 
     445                if ( isset( $this->headers_sanitized[ $header ] ) ) 
     446                        return $this->headers_sanitized[ $header ]; 
     447 
     448                // If an external object cache does not consider themes to be a persistent group, sanitize everything and cache it. 
     449                if ( self::$persistently_cache ) { 
     450                        foreach ( array_keys( $this->headers ) as $header ) 
     451                                $this->headers_sanitized[ $header ] = $this->sanitize_header( $header, $this->headers[ $header ] ); 
     452                        $this->cache_add( 'headers', $this->headers_sanitized ); 
     453                } else { 
     454                        $this->headers_sanitized[ $header ] = $this->sanitize_header( $header, $this->headers[ $header ] ); 
     455                } 
     456 
     457                return $this->headers_sanitized[ $header ]; 
     458        } 
     459 
     460        /** 
     461         * Gets a theme header ready for display (marked up, translated). 
     462         * 
     463         * @access public 
     464         * @since 3.4.0 
     465         * 
     466         * @param string $header Theme header. Name, Description, Author, Version, ThemeURI, AuthorURI, Status. 
     467         * @param bool $markup Optional. Whether to mark up the header. Defaults to true. 
     468         * @param bool $translate Optional. Whether to translate the header. Defaults to true. 
     469         * @return string Processed header, false on failure. 
     470         */ 
     471        public function display( $header, $markup = true, $translate = true ) { 
     472                $value = $this->get( $header ); 
     473                if ( false === $value || '' === $value ) 
     474                        return $value; 
     475 
     476                if ( ! $this->load_textdomain() ) 
     477                        $translate = false; 
     478 
     479                if ( $translate ) 
     480                        $value = $this->translate_header( $header, $value ); 
     481 
     482                if ( $markup ) 
     483                        $value = $this->markup_header( $header, $value, $translate ); 
     484 
     485                return $value; 
     486        } 
     487 
     488        /** 
     489         * Sanitize a theme header. 
     490         * 
     491         * @param string $header Theme header. Name, Description, Author, Version, ThemeURI, AuthorURI, Status. 
     492         * @param string $value Value to sanitize. 
     493         */ 
     494        private function sanitize_header( $header, $value ) { 
     495                switch ( $header ) { 
     496                        case 'Status' : 
     497                                if ( ! $value ) { 
     498                                        $value = 'public'; 
     499                                        break; 
     500                                } 
     501                                // Fall through otherwise. 
     502                        case 'Name' : 
     503                        case 'Author' : 
     504                                static $header_tags = array( 
     505                                        'abbr'    => array( 'title' => true ), 
     506                                        'acronym' => array( 'title' => true ), 
     507                                        'code'    => true, 
     508                                        'em'      => true, 
     509                                        'strong'  => true, 
     510                                ); 
     511                                $value = wp_kses( $value, $header_tags ); 
     512                                break; 
     513                        case 'Description' : 
     514                                static $header_tags_with_a = array( 
     515                                        'a'       => array( 'href' => true, 'title' => true ), 
     516                                        'abbr'    => array( 'title' => true ), 
     517                                        'acronym' => array( 'title' => true ), 
     518                                        'code'    => true, 
     519                                        'em'      => true, 
     520                                        'strong'  => true, 
     521                                ); 
     522                                $value = wp_kses( $value, $header_tags_with_a ); 
     523                                break; 
     524                        case 'ThemeURI' : 
     525                        case 'AuthorURI' : 
     526                                $value = esc_url( $value ); 
     527                                break; 
     528                        case 'Tags' : 
     529                                $value = array_filter( array_map( 'trim', explode( ',', strip_tags( $value ) ) ) ); 
     530                                break; 
     531                } 
     532 
     533                return $value; 
     534        } 
     535 
     536        /** 
     537         * Mark up a theme header. 
     538         * 
     539         * @access private 
     540         * @since 3.4.0 
     541         * 
     542         * @param string $header Theme header. Name, Description, Author, Version, ThemeURI, AuthorURI, Status. 
     543         * @param string $value Value to mark up. 
     544         * @param string $translate Whether the header has been translated. 
     545         * @return string Value, marked up. 
     546         */ 
     547        private function markup_header( $header, $value, $translate ) { 
     548                switch ( $header ) { 
     549                        case 'Description' : 
     550                                $value = wptexturize( $value ); 
     551                                break; 
     552                        case 'Author' : 
     553                                if ( $this->get('AuthorURI') ) { 
     554                                        static $attr = null; 
     555                                        if ( ! isset( $attr ) ) 
     556                                                $attr = esc_attr__( 'Visit author homepage' ); 
     557                                        $value = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $this->display( 'AuthorURI', true, $translate ), $attr, $value ); 
     558                                } elseif ( ! $value ) { 
     559                                        $value = __( 'Anonymous' ); 
     560                                } 
     561                                break; 
     562                        case 'Tags' : 
     563                                static $comma = null; 
     564                                if ( ! isset( $comma ) ) { 
     565                                        /* translators: used between list items, there is a space after the comma */ 
     566                                        $comma = __( ', ' ); 
     567                                } 
     568                                $value = implode( $comma, $value ); 
     569                                break; 
     570                } 
     571 
     572                return $value; 
     573        } 
     574 
     575        /** 
     576         * Translate a theme header. 
     577         * 
     578         * @access private 
     579         * @since 3.4.0 
     580         * 
     581         * @param string $header Theme header. Name, Description, Author, Version, ThemeURI, AuthorURI, Status. 
     582         * @param string $value Value to translate. 
     583         * @return string Translated value. 
     584         */ 
     585        private function translate_header( $header, $value ) { 
     586                switch ( $header ) { 
     587                        case 'Name' : 
     588                                // Cached for sorting reasons. 
     589                                if ( isset( $this->name_translated ) ) 
     590                                        return $this->name_translated; 
     591                                $this->name_translated = translate( $value, $this->get('TextDomain' ) ); 
     592                                return $this->name_translated; 
     593                        case 'Tags' : 
     594                                if ( empty( $value ) ) 
     595                                        return $value; 
     596 
     597                                static $tags_list; 
     598                                if ( ! isset( $tags_list ) ) { 
     599                                        $tags_list = array(); 
     600                                        $feature_list = get_theme_feature_list( false ); // No API 
     601                                        foreach ( $feature_list as $tags ) 
     602                                                $tags_list += $tags; 
     603                                } 
     604 
     605                                foreach ( $value as &$tag ) { 
     606                                        if ( isset( $tags_list[ $tag ] ) ) 
     607                                                $tag = $tags_list[ $tag ]; 
     608                                } 
     609 
     610                                return $value; 
     611                                break; 
     612                        default : 
     613                                $value = translate( $value, $this->get('TextDomain') ); 
     614                } 
     615                return $value; 
     616        } 
     617 
     618        /** 
     619         * The directory name of the theme's "stylesheet" files, inside the theme root. 
     620         * 
     621         * In the case of a child theme, this is directory name of the the child theme. 
     622         * Otherwise, get_stylesheet() is the same as get_template(). 
     623         * 
     624         * @since 3.4.0 
     625         * @access public 
     626         * 
     627         * @return string Stylesheet 
     628         */ 
     629        public function get_stylesheet() { 
     630                return $this->stylesheet; 
     631        } 
     632 
     633        /** 
     634         * The directory name of the theme's "template" files, inside the theme root. 
     635         * 
     636         * In the case of a child theme, this is the directory name of the parent theme. 
     637         * Otherwise, the get_template() is the same as get_stylesheet(). 
     638         * 
     639         * @since 3.4.0 
     640         * @access public 
     641         * 
     642         * @return string Template 
     643         */ 
     644        public function get_template() { 
     645                return $this->template; 
     646        } 
     647 
     648        /** 
     649         * Whether a theme is a child theme. 
     650         * 
     651         * @since 3.4.0 
     652         * @access public 
     653         * 
     654         * @return bool True if a theme is a child theme, false otherwise. 
     655         */ 
     656        public function is_child_theme() { 
     657                return $this->template !== $this->stylesheet; 
     658        } 
     659 
     660        /** 
     661         * Returns the absolute path to the directory of a theme's "stylesheet" files. 
     662         * 
     663         * In the case of a child theme, this is the absolute path to the directory 
     664         * of the child theme's files. 
     665         * 
     666         * @since 3.4.0 
     667         * @access public 
     668         * 
     669         * @return string Absolute path of the stylesheet directory. 
     670         */ 
     671        public function get_stylesheet_directory() { 
     672                if ( $this->errors && in_array( 'theme_root_missing', $this->errors->get_error_codes() ) ) 
     673                        return ''; 
     674 
     675                return $this->theme_root . '/' . $this->stylesheet; 
     676        } 
     677 
     678        /** 
     679         * Returns the absolute path to the directory of a theme's "template" files. 
     680         * 
     681         * In the case of a child theme, this is the absolute path to the directory 
     682         * of the parent theme's files. 
     683         * 
     684         * @since 3.4.0 
     685         * @access public 
     686         * 
     687         * @return string Absolute path of the template directory. 
     688         */ 
     689        public function get_template_directory() { 
     690                if ( $this->parent ) 
     691                        $theme_root = $this->parent->theme_root; 
     692                else 
     693                        $theme_root = $this->theme_root; 
     694 
     695                return $theme_root . '/' . $this->template; 
     696        } 
     697 
     698        /** 
     699         * Returns the URL to the directory of a theme's "stylesheet" files. 
     700         * 
     701         * In the case of a child theme, this is the URL to the directory of the 
     702         * child theme's files. 
     703         * 
     704         * @since 3.4.0 
     705         * @access public 
     706         * 
     707         * @return string URL to the stylesheet directory. 
     708         */ 
     709        public function get_stylesheet_directory_uri() { 
     710                return $this->theme_root_uri . '/' . $this->stylesheet; 
     711        } 
     712 
     713        /** 
     714         * Returns the URL to the directory of a theme's "template" files. 
     715         * 
     716         * In the case of a child theme, this is the URL to the directory of the 
     717         * parent theme's files. 
     718         * 
     719         * @since 3.4.0 
     720         * @access public 
     721         * 
     722         * @return string URL to the template directory. 
     723         */ 
     724        public function get_template_directory_uri() { 
     725                if ( $this->parent ) 
     726                        $theme_root_uri = $this->parent->theme_root_uri; 
     727                else 
     728                        $theme_root_uri = $this->theme_root; 
     729 
     730                return $theme_root . '/' . $this->template; 
     731        } 
     732 
     733        /** 
     734         * The absolute path to the directory of the theme root. 
     735         * 
     736         * This is typically the absolute path to wp-content/themes. 
     737         * 
     738         * @since 3.4.0 
     739         * @access public 
     740         * 
     741         * @return string Theme root. 
     742         */ 
     743        public function get_theme_root() { 
     744                return $this->theme_root; 
     745        } 
     746 
     747        /** 
     748         * Returns the URL to the directory of the theme root. 
     749         * 
     750         * This is typically the absolute path to wp-content/themes. 
     751         * 
     752         * @since 3.4.0 
     753         * @access public 
     754         * 
     755         * @return string Theme root URI. 
     756         */ 
     757        public function get_theme_root_uri() { 
     758                return str_replace( WP_CONTENT_DIR, content_url(), $this->theme_root ); 
     759        } 
     760 
     761        /** 
     762         * Returns the main screenshot file for the theme. 
     763         * 
     764         * The main screenshot is called screenshot.png. gif and jpg extensions are also allowed. 
     765         * 
     766         * Screenshots for a theme must be in the stylesheet directory. (In the case of a child 
     767         * theme, a parent theme's screenshots are inherited.) 
     768         * 
     769         * @since 3.4.0 
     770         * @access public 
     771         * 
     772         * @param string $uri Type of URL to include, either relative or absolute. Defaults to relative. 
     773         * @return mixed Screenshot file. False if the theme does not have a screenshot. 
     774         */ 
     775        public function get_screenshot( $uri = 'relative' ) { 
     776                $screenshot = $this->cache_get( 'screenshot' ); 
     777                if ( $screenshot ) { 
     778                        if ( 'absolute' == $uri ) 
     779                                return $this->get_stylesheet_directory_uri() . '/' . $screenshot; 
     780                        return $screenshot; 
     781                } elseif ( 0 === $screenshot ) { 
     782                        return false; 
     783                } 
     784 
     785                foreach ( array( 'png', 'gif', 'jpg', 'jpeg' ) as $ext ) { 
     786                        if ( file_exists( $this->get_stylesheet_directory() . "/screenshot.$ext" ) ) { 
     787                                $this->cache_add( 'screenshot', 'screenshot.' . $ext ); 
     788                                if ( 'absolute' == $uri ) 
     789                                        return $this->get_stylesheet_directory_uri() . '/' . 'screenshot.' . $ext; 
     790                                return 'screenshot.' . $ext; 
     791                        } 
     792                } 
     793 
     794                $this->cache_add( 'screenshot', 0 ); 
     795                $this->cache_add( 'screenshot_count', 0 ); 
     796                return false; 
     797        } 
     798 
     799        /** 
     800         * Returns the number of screenshots for a theme. 
     801         * 
     802         * The first screenshot may be called screenshot.png, .gif, or .jpg. Subsequent 
     803         * screenshots can be screenshot-2.png, screenshot-3.png, etc. The count must 
     804         * be consecutive for screenshots to be counted, and all screenshots beyond the 
     805         * initial one must be image/png files. 
     806         * 
     807         * @see WP_Theme::get_screenshot() 
     808         * @since 3.4.0 
     809         * @access public 
     810         * 
     811         * @return int Number of screenshots. Can be 0. 
     812         */ 
     813        public function get_screenshot_count() { 
     814                $screenshot_count = $this->cache_get( 'screenshot_count' ); 
     815                if ( is_numeric( $screenshot_count ) ) 
     816                        return $screenshot_count; 
     817 
     818                // This will set the screenshot cache. 
     819                // If there is no screenshot, the screenshot_count cache will also be set. 
     820                if ( ! $screenshot = $this->get_screenshot() ) 
     821                        return 0; 
     822 
     823                $prefix = $this->get_stylesheet() . '/screenshot-'; 
     824                $files = self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet(), 'png', 0 ); 
     825 
     826                $screenshot_count = 1; 
     827                while ( in_array( $prefix . ( $screenshot_count + 1 ) . '.png', $files['png'] ) ) 
     828                        $screenshot_count++; 
     829 
     830                $this->cache_add( 'screenshot_count', $screenshot_count ); 
     831                return $screenshot_count; 
     832        } 
     833 
     834        /** 
     835         * Returns an array of screenshot filenames. 
     836         * 
     837         * @see WP_Theme::get_screenshot() 
     838         * @see WP_Theme::get_screenshot_count() 
     839         * @since 3.4.0 
     840         * @access public 
     841         * 
     842         * @return array Screenshots. 
     843         */ 
     844        public function get_screenshots() { 
     845                if ( ! $count = $this->get_screenshot_count() ) 
     846                        return array(); 
     847 
     848                $screenshots = array( $this->get_screenshot() ); 
     849                for ( $i = 2; $i <= $count; $i++ ) 
     850                        $screenshots[] = 'screenshot-' . $i . '.png'; 
     851                return $screenshots; 
     852        } 
     853 
     854        /** 
     855         * Return files in the template and stylesheet directories. 
     856         * 
     857         * @since 3.4.0 
     858         * @access public 
     859         * 
     860         * @param string|null $type Optional. Type of files to return, either 'php' or 'css'. Defaults to null, for both. 
     861         * @return array If a specific $type is requested, returns an array of PHP files. If no $type is requested, 
     862         *      returns an array, with the keys being the file types, and the values being an array of files for those type. 
     863         */ 
     864        public function get_files( $type = null, $include_parent_files = false ) { 
     865                $files = $this->cache_get( 'files' ); 
     866                if ( ! is_array( $files ) ) { 
     867                        if ( $include_parent_files || ! $this->is_child_theme() ) 
     868                                // Template files can be one level down for the purposes of the theme editor, so this should be $depth = 1. 
     869                                // Todo: We ignore this for now, but this is why the branching is weird. 
     870                                $files = (array) self::scandir( $this->get_template_directory(), $this->get_template(), array( 'php', 'css' ) ); 
     871                        if ( $this->is_child_theme() ) 
     872                                $files = array_merge_recursive( $files, (array) self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet(), array( 'php', 'css' ) ) ); 
     873                        foreach ( $files as &$group ) 
     874                                sort( $group ); 
     875                        $this->cache_add( 'files', $files ); 
     876                } 
     877 
     878                if ( null === $type ) 
     879                        return $files; 
     880                elseif ( isset( $files[ $type ] ) ) 
     881                        return $files[ $type ]; 
     882 
     883                return array(); 
     884        } 
     885 
     886        public function get_page_templates() { 
     887                // If you screw up your current theme and we invalidate your parent, most things still work. Let it slide. 
     888                if ( $this->errors() && $this->errors()->get_error_codes() !== array( 'theme_parent_invalid' ) ) 
     889                        return array(); 
     890 
     891                $page_templates = $this->cache_get( 'page_templates' ); 
     892                if ( is_array( $page_templates ) ) 
     893                        return $page_templates; 
     894                $page_templates = array(); 
     895 
     896                $files = (array) self::scandir( $this->get_template_directory(), $this->get_template_directory(), 'php' ); 
     897                if ( $this->is_child_theme() ) 
     898                        $files = array_merge_recursive( $files, (array) self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet_directory(), 'php' ) ); 
     899 
     900                foreach ( $files['php'] as $file ) { 
     901                        $headers = get_file_data( $file, array( 'Name' => 'Template Name' ) ); 
     902                        if ( empty( $headers['Name'] ) ) 
     903                                continue; 
     904                        $page_templates[ $headers['Name'] ] = basename( $file ); 
     905                } 
     906 
     907                $this->cache_add( 'page_templates', $page_templates ); 
     908                return $page_templates; 
     909        } 
     910 
     911        /** 
     912         * Scans a directory for files of a certain extension. 
     913         * 
     914         * @since 3.4.0 
     915         * @access public 
     916         * 
     917         * @param string $path Absolute path to search. 
     918         * @param string $relative_path The basename of the absolute path. Used to control the returned path 
     919         *      for the found files, particularly when this function recurses to lower depths. 
     920         * @param array|string $extensions Array of extensions to find, or string of a single extension. 
     921         * @depth int How deep to search for files. Optional, defaults to a flat scan (0 depth). 
     922         */ 
     923        private static function scandir( $path, $relative_path, $extensions, $depth = 0 ) { 
     924                if ( is_array( $extensions ) ) 
     925                        $extensions = implode( '|', $extensions ); 
     926 
     927                if ( ! is_dir( $path ) ) 
     928                        return false; 
     929 
     930                $results = scandir( $path ); 
     931                $files = array(); 
     932 
     933                foreach ( $results as $result ) { 
     934                        if ( '.' == $result || '..' == $result ) 
     935                                continue; 
     936                        if ( is_dir( $path . '/' . $result ) ) { 
     937                                if ( ! $depth ) 
     938                                        continue; 
     939                                $found = self::scandir( $path . '/' . $result, $relative_path . '/' . $result, $extensions, $depth - 1 ); 
     940                                $files = array_merge_recursive( $files, $found ); 
     941                        } elseif ( preg_match( '~\.(' . $extensions . ')$~', $result, $match ) ) { 
     942                                if ( ! isset( $files[ $match[1] ] ) ) 
     943                                        $files[ $match[1] ] = array( $relative_path . '/'. $result ); 
     944                                else 
     945                                        $files[ $match[1] ][] = $relative_path . '/' . $result; 
     946                        } 
     947                } 
     948                return $files; 
     949        } 
     950 
     951        /** 
     952         * Loads the theme's textdomain. 
     953         * 
     954         * Translation files are not inherited from the parent theme. Todo: if this fails for the 
     955         * child theme, it should probably try to load the parent theme's translations. 
     956         * 
     957         * @since 3.4.0 
     958         * @access public 
     959         * 
     960         * @return True if the textdomain was successfully loaded or has already been loaded. False if 
     961         *      no textdomain was specified in the file headers, or if the domain could not be loaded. 
     962         */ 
     963        public function load_textdomain() { 
     964                if ( isset( $this->textdomain_loaded ) ) 
     965                        return $this->textdomain_loaded; 
     966 
     967                $textdomain = $this->get('TextDomain'); 
     968                if ( ! $textdomain ) { 
     969                        $this->textdomain_loaded = false; 
     970                        return false; 
     971                } 
     972 
     973                if ( is_textdomain_loaded( $textdomain ) ) { 
     974                        $this->textdomain_loaded = true; 
     975                        return true; 
     976                } 
     977 
     978                $path = $this->get_stylesheet_directory(); 
     979                if ( $domainpath = $this->get('DomainPath') ) 
     980                        $path .= $domainpath; 
     981 
     982                $this->textdomain_loaded = load_theme_textdomain( $textdomain, $path ); 
     983                return $this->textdomain_loaded; 
     984        } 
     985 
     986        /** 
     987         * Whether the theme is allowed (multisite only). 
     988         * 
     989         * @since 3.4.0 
     990         * @access public 
     991         * 
     992         * @param string $check Optional. Whether to check only the 'network'-wide settings, the 'site' 
     993         *      settings, or 'both'. Defaults to 'both'. 
     994         * @param int $blog_id Optional. Ignored if only network-wide settings are checked. Defaults to current blog. 
     995         * @return bool Whether the theme is allowed for the network. Returns true in single-site. 
     996         */ 
     997        public function is_allowed( $check = 'both', $blog_id = null ) { 
     998                if ( ! is_multisite() ) 
     999                        return true; 
     1000 
     1001                if ( 'both' == $check || 'network' == $check ) { 
     1002                        $allowed = self::get_allowed_on_network(); 
     1003                        if ( ! empty( $allowed[ $this->get_stylesheet() ] ) ) 
     1004                                return true; 
     1005                } 
     1006 
     1007                if ( 'both' == $check || 'site' == $check ) { 
     1008                        $allowed = self::get_allowed_on_site( $blog_id ); 
     1009                        if ( ! empty( $allowed[ $this->get_stylesheet() ] ) ) 
     1010                                return true; 
     1011                } 
     1012 
     1013                return false; 
     1014        } 
     1015 
     1016        /** 
     1017         * Returns array of stylesheet names of themes allowed on the site or network. 
     1018         * 
     1019         * @since 3.4.0 
     1020         * @access public 
     1021         * 
     1022         * @param int $blog_id Optional. Defaults to current blog. 
     1023         * @return array Array of stylesheet names. 
     1024         */ 
     1025        public static function get_allowed( $blog_id = null ) { 
     1026                return array_merge( self::get_allowed_on_network(), self::get_allowed_on_site( $blog_id ) ); 
     1027        } 
     1028 
     1029        /** 
     1030         * Returns array of stylesheet names of themes allowed on the network. 
     1031         * 
     1032         * @since 3.4.0 
     1033         * @access public 
     1034         * 
     1035         * @return array Array of stylesheet names. 
     1036         */ 
     1037        public static function get_allowed_on_network() { 
     1038                static $allowed_themes; 
     1039                if ( ! isset( $allowed_themes ) ) 
     1040                        $allowed_themes = (array) get_site_option( 'allowedthemes' ); 
     1041                return $allowed_themes; 
     1042        } 
     1043 
     1044        /** 
     1045         * Returns array of stylesheet names of themes allowed on the site. 
     1046         * 
     1047         * @since 3.4.0 
     1048         * @access public 
     1049         * 
     1050         * @param int $blog_id Optional. Defaults to current blog. 
     1051         * @return array Array of stylesheet names. 
     1052         */ 
     1053        public static function get_allowed_on_site( $blog_id = null ) { 
     1054                static $allowed_themes = array(); 
     1055                if ( ! $blog_id ) 
     1056                        $blog_id = get_current_blog_id(); 
     1057 
     1058                if ( ! isset( $allowed_themes[ $blog_id ] ) ) { 
     1059                        if ( $blog_id == get_current_blog_id() ) 
     1060                                $allowed_themes[ $blog_id ] = (array) get_option( 'allowedthemes' ); 
     1061                        else 
     1062                                $allowed_themes[ $blog_id ] = (array) get_blog_option( $blog_id, 'allowedthemes' ); 
     1063                } 
     1064 
     1065                return $allowed_themes[ $blog_id ]; 
     1066        } 
     1067 
     1068        /** 
     1069         * Sort themes by name. 
     1070         */ 
     1071        public static function sort_by_name( &$themes ) { 
     1072                if ( 0 === strpos( get_locale(), 'en_' ) ) { 
     1073                        uasort( $themes, array( 'WP_Theme', '_name_sort' ) ); 
     1074                } else { 
     1075                        uasort( $themes, array( 'WP_Theme', '_name_sort_i18n' ) ); 
     1076                } 
     1077        } 
     1078 
     1079        /** 
     1080         * Callback function for usort() to naturally sort themes by name. 
     1081         * 
     1082         * Accesses the Name header directly from the class for maximum speed. 
     1083         * Would choke on HTML but we don't care enough to slow it down with strip_tags(). 
     1084         * 
     1085         * @since 3.4.0 
     1086         * @access public 
     1087         */ 
     1088        private static function _name_sort( $a, $b ) { 
     1089                return strnatcasecmp( $a->headers['Name'], $b->headers['Name'] ); 
     1090        } 
     1091 
     1092        /** 
     1093         * Name sort (with translation). 
     1094         * 
     1095         * @since 3.4.0 
     1096         * @access public 
     1097         */ 
     1098        private static function _name_sort_i18n( $a, $b ) { 
     1099                // Don't mark up; Do translate. 
     1100                return strnatcasecmp( $a->display( 'Name', false, true ), $b->display( 'Name', false, true ) ); 
     1101        } 
     1102} 
     1103 
     1104/** 
     1105 * Returns an array of WP_Theme objects based on the arguments. 
     1106 * 
     1107 * Despite advances over get_themes(), this function is still quite expensive, and grows 
     1108 * linearly with additional themes. Stick to wp_get_theme() if possible. 
     1109 * 
     1110 * @since 3.4.0 
     1111 * 
     1112 * @param array $args Arguments. Currently 'errors' (defaults to false), 'allowed' 
     1113 *      (true, false; null for either; defaults to null; only applies to multisite), and 'blog_id' 
     1114 *      (defaults to current blog; used to find allowed themes; only applies to multisite). 
     1115 * @return Array of WP_Theme objects. 
     1116 */ 
     1117function wp_get_themes( $args = array() ) { 
     1118        $defaults = array( 'errors' => false, 'allowed' => null, 'blog_id' => 0 ); 
     1119        $args = wp_parse_args( $args, $defaults ); 
     1120 
     1121        static $_themes; 
     1122        if ( ! isset( $_themes ) ) { 
     1123                $theme_data = search_theme_directories(); 
     1124                // Make sure the current theme wins out, in case search_theme_directories() picks the wrong 
     1125                // one in the case of a conflict. (Normally, last registered theme root wins.) 
     1126                $current_theme = get_stylesheet(); 
     1127                $current_theme_root = WP_CONTENT_DIR . get_raw_theme_root( $current_theme ); 
     1128                foreach ( $theme_data as $theme_slug => $data ) { 
     1129                        if ( $current_theme == $theme_slug && $current_theme_root != $data['theme_root'] ) 
     1130                                $_themes[ $theme_slug ] = new WP_Theme( $theme_slug, $current_theme_root ); 
     1131                        else 
     1132                                $_themes[ $theme_slug ] = new WP_Theme( $theme_slug, $data['theme_root'] ); 
     1133                } 
     1134        } 
     1135 
     1136        $themes = $_themes; 
     1137 
     1138        if ( null !== $args['errors'] ) { 
     1139                foreach ( $themes as $theme_slug => $theme ) { 
     1140                        if ( $theme->errors() != $args['errors'] ) 
     1141                                unset( $themes[ $theme_slug ] ); 
     1142                } 
     1143        } 
     1144 
     1145        if ( is_multisite() && null !== $args['allowed'] ) { 
     1146                if ( $allowed = $args['allowed'] ) { 
     1147                        $allowed = 'network' == $allowed || 'site' == $allowed ? $allowed : 'both'; 
     1148                        $themes = array_intersect_key( $themes, WP_Theme::get_allowed( $allowed, $args['blog_id'] ) ); 
     1149                } else { 
     1150                        $themes = array_diff_key( $themes, WP_Theme::get_allowed( 'both', $args['blog_id'] ) ); 
     1151                } 
     1152        } 
     1153 
     1154        return $themes; 
     1155} 
     1156 
     1157/** 
     1158 * Gets a WP_Theme object for a theme. 
     1159 * 
     1160 * @since 3.4.0 
     1161 * 
     1162 * @param string $stylesheet Directory name for the theme. Optional. Defaults to current theme. 
     1163 * @param string $theme_root Theme root to look in. Optional. If not specified, get_raw_theme_root() 
     1164 *      is used for the $stylesheet provided (or current theme). 
     1165 * @return WP_Theme 
     1166 */ 
     1167function wp_get_theme( $stylesheet = null, $theme_root = null ) { 
     1168        if ( empty( $stylesheet ) ) 
     1169                $stylesheet = get_stylesheet(); 
     1170 
     1171        if ( empty( $theme_root ) ) 
     1172                $theme_root = WP_CONTENT_DIR . get_raw_theme_root( $stylesheet ); 
     1173 
     1174        return new WP_Theme( $stylesheet, $theme_root ); 
     1175} 
     1176 No newline at end of file 
  • wp-includes/theme.php

     
    247247} 
    248248 
    249249/** 
    250  * Retrieve list of themes with theme data in theme directory. 
    251  * 
    252  * The theme is broken, if it doesn't have a parent theme and is missing either 
    253  * style.css and, or index.php. If the theme has a parent theme then it is 
    254  * broken, if it is missing style.css; index.php is optional. The broken theme 
    255  * list is saved in the {@link $wp_broken_themes} global, which is displayed on 
    256  * the theme list in the administration panels. 
    257  * 
    258  * @since 1.5.0 
    259  * @global array $wp_broken_themes Stores the broken themes. 
    260  * @global array $wp_themes Stores the working themes. 
    261  * 
    262  * @return array Theme list with theme data. 
    263  */ 
    264 function get_themes() { 
    265         global $wp_themes, $wp_broken_themes; 
    266  
    267         if ( isset($wp_themes) ) 
    268                 return $wp_themes; 
    269  
    270         if ( !$theme_files = search_theme_directories() ) 
    271                 return false; 
    272  
    273         asort( $theme_files ); 
    274  
    275         $wp_themes = array(); 
    276  
    277         foreach ( (array) $theme_files as $theme_file ) { 
    278                 $theme_root = $theme_file['theme_root']; 
    279                 $theme_file = $theme_file['theme_file']; 
    280  
    281                 if ( !is_readable("$theme_root/$theme_file") ) { 
    282                         $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.')); 
    283                         continue; 
    284                 } 
    285  
    286                 $theme_data = get_theme_data("$theme_root/$theme_file"); 
    287  
    288                 $name        = $theme_data['Name']; 
    289                 $title       = $theme_data['Title']; 
    290                 $description = wptexturize($theme_data['Description']); 
    291                 $version     = $theme_data['Version']; 
    292                 $author      = $theme_data['Author']; 
    293                 $template    = $theme_data['Template']; 
    294                 $stylesheet  = dirname($theme_file); 
    295  
    296                 $screenshot = false; 
    297                 foreach ( array('png', 'gif', 'jpg', 'jpeg') as $ext ) { 
    298                         if (file_exists("$theme_root/$stylesheet/screenshot.$ext")) { 
    299                                 $screenshot = "screenshot.$ext"; 
    300                                 break; 
    301                         } 
    302                 } 
    303  
    304                 if ( empty($name) ) { 
    305                         $name = dirname($theme_file); 
    306                         $title = $name; 
    307                 } 
    308  
    309                 $parent_template = $template; 
    310  
    311                 if ( empty($template) ) { 
    312                         if ( file_exists("$theme_root/$stylesheet/index.php") ) 
    313                                 $template = $stylesheet; 
    314                         else 
    315                                 continue; 
    316                 } 
    317  
    318                 $template = trim( $template ); 
    319  
    320                 if ( !file_exists("$theme_root/$template/index.php") ) { 
    321                         $parent_dir = dirname(dirname($theme_file)); 
    322                         if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) { 
    323                                 $template = "$parent_dir/$template"; 
    324                                 $template_directory = "$theme_root/$template"; 
    325                         } else { 
    326                                 /** 
    327                                  * The parent theme doesn't exist in the current theme's folder or sub folder 
    328                                  * so lets use the theme root for the parent template. 
    329                                  */ 
    330                                 if ( isset($theme_files[$template]) && file_exists( $theme_files[$template]['theme_root'] . "/$template/index.php" ) ) { 
    331                                         $template_directory = $theme_files[$template]['theme_root'] . "/$template"; 
    332                                 } else { 
    333                                         if ( empty( $parent_template) ) 
    334                                                 $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'), 'error' => 'no_template'); 
    335                                         else 
    336                                                 $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 ); 
    337                                         continue; 
    338                                 } 
    339  
    340                         } 
    341                 } else { 
    342                         $template_directory = trim( $theme_root . '/' . $template ); 
    343                 } 
    344  
    345                 $stylesheet_files = array(); 
    346                 $template_files = array(); 
    347  
    348                 $stylesheet_dir = @ dir("$theme_root/$stylesheet"); 
    349                 if ( $stylesheet_dir ) { 
    350                         while ( ($file = $stylesheet_dir->read()) !== false ) { 
    351                                 if ( !preg_match('|^\.+$|', $file) ) { 
    352                                         if ( preg_match('|\.css$|', $file) ) 
    353                                                 $stylesheet_files[] = "$theme_root/$stylesheet/$file"; 
    354                                         elseif ( preg_match('|\.php$|', $file) ) 
    355                                                 $template_files[] = "$theme_root/$stylesheet/$file"; 
    356                                 } 
    357                         } 
    358                         @ $stylesheet_dir->close(); 
    359                 } 
    360  
    361                 $template_dir = @ dir("$template_directory"); 
    362                 if ( $template_dir ) { 
    363                         while ( ($file = $template_dir->read()) !== false ) { 
    364                                 if ( preg_match('|^\.+$|', $file) ) 
    365                                         continue; 
    366                                 if ( preg_match('|\.php$|', $file) ) { 
    367                                         $template_files[] = "$template_directory/$file"; 
    368                                 } elseif ( is_dir("$template_directory/$file") ) { 
    369                                         $template_subdir = @ dir("$template_directory/$file"); 
    370                                         if ( !$template_subdir ) 
    371                                                 continue; 
    372                                         while ( ($subfile = $template_subdir->read()) !== false ) { 
    373                                                 if ( preg_match('|^\.+$|', $subfile) ) 
    374                                                         continue; 
    375                                                 if ( preg_match('|\.php$|', $subfile) ) 
    376                                                         $template_files[] = "$template_directory/$file/$subfile"; 
    377                                         } 
    378                                         @ $template_subdir->close(); 
    379                                 } 
    380                         } 
    381                         @ $template_dir->close(); 
    382                 } 
    383  
    384                 //Make unique and remove duplicates when stylesheet and template are the same i.e. most themes 
    385                 $template_files = array_unique($template_files); 
    386                 $stylesheet_files = array_unique($stylesheet_files); 
    387  
    388                 $template_dir = $template_directory; 
    389                 $stylesheet_dir = $theme_root . '/' . $stylesheet; 
    390  
    391                 if ( empty($template_dir) ) 
    392                         $template_dir = '/'; 
    393                 if ( empty($stylesheet_dir) ) 
    394                         $stylesheet_dir = '/'; 
    395  
    396                 // Check for theme name collision. This occurs if a theme is copied to 
    397                 // a new theme directory and the theme header is not updated. Whichever 
    398                 // theme is first keeps the name. Subsequent themes get a suffix applied. 
    399                 // Default themes themes always trump their pretenders. 
    400                 if ( isset($wp_themes[$name]) ) { 
    401                         $trump_cards = array( 
    402                                 'classic'      => 'WordPress Classic', 
    403                                 'default'      => 'WordPress Default', 
    404                                 'twentyten'    => 'Twenty Ten', 
    405                                 'twentyeleven' => 'Twenty Eleven', 
    406                                 'twentytwelve' => 'Twenty Twelve', 
    407                         ); 
    408                         if ( isset( $trump_cards[ $stylesheet ] ) && $name == $trump_cards[ $stylesheet ] ) { 
    409                                 // If another theme has claimed to be one of our default themes, move 
    410                                 // them aside. 
    411                                 $suffix = $wp_themes[$name]['Stylesheet']; 
    412                                 $new_name = "$name/$suffix"; 
    413                                 $wp_themes[$new_name] = $wp_themes[$name]; 
    414                                 $wp_themes[$new_name]['Name'] = $new_name; 
    415                         } else { 
    416                                 $name = "$name/$stylesheet"; 
    417                         } 
    418                 } 
    419  
    420                 $theme_roots[$stylesheet] = str_replace( WP_CONTENT_DIR, '', $theme_root ); 
    421                 $wp_themes[$name] = array( 
    422                         'Name' => $name, 
    423                         'Title' => $title, 
    424                         'Description' => $description, 
    425                         'Author' => $author, 
    426                         'Author Name' => $theme_data['AuthorName'], 
    427                         'Author URI' => $theme_data['AuthorURI'], 
    428                         'Version' => $version, 
    429                         'Template' => $template, 
    430                         'Stylesheet' => $stylesheet, 
    431                         'Template Files' => $template_files, 
    432                         'Stylesheet Files' => $stylesheet_files, 
    433                         'Template Dir' => $template_dir, 
    434                         'Stylesheet Dir' => $stylesheet_dir, 
    435                         'Status' => $theme_data['Status'], 
    436                         'Screenshot' => $screenshot, 
    437                         'Tags' => $theme_data['Tags'], 
    438                         'Theme Root' => $theme_root, 
    439                         'Theme Root URI' => str_replace( WP_CONTENT_DIR, content_url(), $theme_root ), 
    440                 ); 
    441         } 
    442  
    443         unset($theme_files); 
    444  
    445         /* Store theme roots in the DB */ 
    446         if ( get_site_transient( 'theme_roots' ) != $theme_roots ) 
    447                 set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours 
    448         unset($theme_roots); 
    449  
    450         /* Resolve theme dependencies. */ 
    451         $theme_names = array_keys( $wp_themes ); 
    452         foreach ( (array) $theme_names as $theme_name ) { 
    453                 $wp_themes[$theme_name]['Parent Theme'] = ''; 
    454                 if ( $wp_themes[$theme_name]['Stylesheet'] != $wp_themes[$theme_name]['Template'] ) { 
    455                         foreach ( (array) $theme_names as $parent_theme_name ) { 
    456                                 if ( ($wp_themes[$parent_theme_name]['Stylesheet'] == $wp_themes[$parent_theme_name]['Template']) && ($wp_themes[$parent_theme_name]['Template'] == $wp_themes[$theme_name]['Template']) ) { 
    457                                         $wp_themes[$theme_name]['Parent Theme'] = $wp_themes[$parent_theme_name]['Name']; 
    458                                         break; 
    459                                 } 
    460                         } 
    461                 } 
    462         } 
    463  
    464         return $wp_themes; 
    465 } 
    466  
    467 /** 
    468250 * Retrieve theme roots. 
    469251 * 
    470252 * @since 2.9.0 
     
    479261 
    480262        $theme_roots = get_site_transient( 'theme_roots' ); 
    481263        if ( false === $theme_roots ) { 
    482                 get_themes(); 
    483                 $theme_roots = get_site_transient( 'theme_roots' ); // this is set in get_theme() 
     264                search_theme_directories(); // Regenerated the transient. 
     265                $theme_roots = get_site_transient( 'theme_roots' ); 
    484266        } 
    485267        return $theme_roots; 
    486268} 
    487269 
    488270/** 
    489  * Retrieve theme data. 
    490  * 
    491  * @since 1.5.0 
    492  * 
    493  * @param string $theme Theme name. 
    494  * @return array|null Null, if theme name does not exist. Theme data, if exists. 
    495  */ 
    496 function get_theme($theme) { 
    497         $themes = get_themes(); 
    498  
    499         if ( is_array( $themes ) && array_key_exists( $theme, $themes ) ) 
    500                 return $themes[$theme]; 
    501  
    502         return null; 
    503 } 
    504  
    505 /** 
    506271 * Retrieve current theme display name. 
    507272 * 
    508  * If the 'current_theme' option has already been set, then it will be returned 
    509  * instead. If it is not set, then each theme will be iterated over until both 
    510  * the current stylesheet and current template name. 
    511  * 
    512273 * @since 1.5.0 
    513274 * 
    514275 * @return string 
    515276 */ 
    516277function get_current_theme() { 
    517         if ( $theme = get_option('current_theme') ) 
    518                 return $theme; 
    519  
    520         $themes = get_themes(); 
    521         $current_theme = 'Twenty Eleven'; 
    522  
    523         if ( $themes ) { 
    524                 $theme_names = array_keys( $themes ); 
    525                 $current_template = get_option( 'template' ); 
    526                 $current_stylesheet = get_option( 'stylesheet' ); 
    527  
    528                 foreach ( (array) $theme_names as $theme_name ) { 
    529                         if ( $themes[$theme_name]['Stylesheet'] == $current_stylesheet && 
    530                                         $themes[$theme_name]['Template'] == $current_template ) { 
    531                                 $current_theme = $themes[$theme_name]['Name']; 
    532                                 break; 
    533                         } 
    534                 } 
    535         } 
    536  
    537         update_option('current_theme', $current_theme); 
    538  
    539         return $current_theme; 
     278        $theme = wp_get_theme(); 
     279        return $theme->get('Name'); 
    540280} 
    541281 
    542282/** 
     
    574314 * @return array Valid themes found 
    575315 */ 
    576316function search_theme_directories() { 
    577         global $wp_theme_directories, $wp_broken_themes; 
     317        global $wp_theme_directories; 
    578318        if ( empty( $wp_theme_directories ) ) 
    579319                return false; 
    580320 
    581         $theme_files = array(); 
    582         $wp_broken_themes = array(); 
     321        static $found_themes; 
     322        if ( isset( $found_themes ) ) 
     323                return $found_themes; 
     324        $found_themes = array(); 
    583325 
     326        if ( apply_filters( 'wp_cache_themes_persistently', false ) ) { 
     327                $cached_roots = get_site_transient( 'theme_roots' ); 
     328                if ( is_array( $cached_roots ) ) { 
     329                        foreach ( $cached_roots as $theme_dir => $theme_root ) { 
     330                                $found_themes[ $theme_dir ] = array( 
     331                                        'theme_file' => $theme_dir . '/style.css', 
     332                                        'theme_root' => $theme_root, 
     333                                ); 
     334                        } 
     335                        return $found_themes; 
     336                } 
     337        } 
     338 
    584339        /* Loop the registered theme directories and extract all themes */ 
    585340        foreach ( (array) $wp_theme_directories as $theme_root ) { 
    586341                $theme_loc = $theme_root; 
    587342 
    588343                /* We don't want to replace all forward slashes, see Trac #4541 */ 
    589344                if ( '/' != WP_CONTENT_DIR ) 
    590                         $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root); 
     345                        $theme_loc = str_replace( WP_CONTENT_DIR, '', $theme_root ); 
    591346 
    592347                /* Files in the root of the current theme directory and one subdir down */ 
    593                 $themes_dir = @ opendir($theme_root); 
    594  
    595                 if ( !$themes_dir ) 
     348                $dirs = @ scandir( $theme_root ); 
     349                if ( ! $dirs ) 
    596350                        return false; 
    597  
    598                 while ( ($theme_dir = readdir($themes_dir)) !== false ) { 
    599                         if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) { 
    600                                 if ( $theme_dir[0] == '.' || $theme_dir == 'CVS' ) 
    601                                         continue; 
    602  
    603                                 $stylish_dir = @opendir($theme_root . '/' . $theme_dir); 
    604                                 $found_stylesheet = false; 
    605  
    606                                 while ( ($theme_file = readdir($stylish_dir)) !== false ) { 
    607                                         if ( $theme_file == 'style.css' ) { 
    608                                                 $theme_files[$theme_dir] = array( 'theme_file' => $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root ); 
    609                                                 $found_stylesheet = true; 
    610                                                 break; 
    611                                         } 
     351                foreach ( $dirs as $dir ) { 
     352                        if ( ! is_dir( $theme_root . '/' . $dir ) || $dir[0] == '.' || $dir == 'CVS' ) 
     353                                continue; 
     354                        if ( file_exists( $theme_root . '/' . $dir . '/style.css' ) ) { 
     355                                // wp-content/themes/a-single-theme 
     356                                // wp-content/themes is $theme_root, a-single-theme is $dir 
     357                                $found_themes[ $dir ] = array( 
     358                                        'theme_file' => $dir . '/style.css', 
     359                                        'theme_root' => $theme_root, 
     360                                ); 
     361                        } else { 
     362                                $found_theme = false; 
     363                                // wp-content/themes/a-folder-of-themes/* 
     364                                // wp-content/themes is $theme_root, a-folder-of-themes is $dir, then themes are $sub_dirs 
     365                                $sub_dirs = @ scandir( $theme_root . '/' . $dir ); 
     366                                if ( ! $sub_dirs ) 
     367                                        return false; 
     368                                foreach ( $sub_dirs as $sub_dir ) { 
     369                                        if ( ! is_dir( $theme_root . '/' . $dir ) || $dir[0] == '.' || $dir == 'CVS' ) 
     370                                                continue; 
     371                                        if ( ! file_exists( $theme_root . '/' . $dir . '/' . $sub_dir . '/style.css' ) ) 
     372                                                continue; 
     373                                        $found_themes[ $dir . '/' . $sub_dir ] = array( 
     374                                                'theme_file' => $dir . '/' . $sub_dir . '/style.css', 
     375                                                'theme_root' => $theme_root, 
     376                                        ); 
     377                                        $found_theme = true; 
    612378                                } 
    613                                 @closedir($stylish_dir); 
     379                                // Never mind the above, it's just a theme missing a style.css. 
     380                                // Return it; WP_Theme will catch the error. 
     381                                if ( ! $found_theme ) 
     382                                        $found_themes[ $dir ] = array( 
     383                                                'theme_file' => $dir . '/style.css', 
     384                                                'theme_root' => $theme_root, 
     385                                        ); 
     386                        } 
     387                } 
     388        } 
    614389 
    615                                 if ( !$found_stylesheet ) { // look for themes in that dir 
    616                                         $subdir = "$theme_root/$theme_dir"; 
    617                                         $subdir_name = $theme_dir; 
    618                                         $theme_subdirs = @opendir( $subdir ); 
     390        asort( $found_themes ); 
    619391 
    620                                         $found_subdir_themes = false; 
    621                                         while ( ($theme_subdir = readdir($theme_subdirs)) !== false ) { 
    622                                                 if ( is_dir( $subdir . '/' . $theme_subdir) && is_readable($subdir . '/' . $theme_subdir) ) { 
    623                                                         if ( $theme_subdir[0] == '.' || $theme_subdir == 'CVS' ) 
    624                                                                 continue; 
     392        $theme_roots = array(); 
     393        foreach ( $found_themes as $theme_dir => $theme_data ) { 
     394                $theme_roots[ $theme_dir ] = $theme_data['theme_root']; 
     395        } 
    625396 
    626                                                         $stylish_dir = @opendir($subdir . '/' . $theme_subdir); 
    627                                                         $found_stylesheet = false; 
     397        if ( $theme_roots != get_site_transient( 'theme_roots' ) ) 
     398                set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours 
    628399 
    629                                                         while ( ($theme_file = readdir($stylish_dir)) !== false ) { 
    630                                                                 if ( $theme_file == 'style.css' ) { 
    631                                                                         $theme_files["$theme_dir/$theme_subdir"] = array( 'theme_file' => $subdir_name . '/' . $theme_subdir . '/' . $theme_file, 'theme_root' => $theme_root ); 
    632                                                                         $found_stylesheet = true; 
    633                                                                         $found_subdir_themes = true; 
    634                                                                         break; 
    635                                                                 } 
    636                                                         } 
    637                                                         @closedir($stylish_dir); 
    638                                                 } 
    639                                         } 
    640                                         @closedir($theme_subdirs); 
    641                                         if ( !$found_subdir_themes ) 
    642                                                 $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.')); 
    643                                 } 
    644                         } 
    645                 } 
    646                 @closedir( $themes_dir ); 
    647         } 
    648         return $theme_files; 
     400        return $found_themes; 
    649401} 
    650402 
    651403/** 
     
    725477                        $theme_root = $theme_roots[$stylesheet_or_template]; 
    726478        } 
    727479 
    728         return $theme_root; 
     480        return str_replace( WP_CONTENT_DIR, '', $theme_root ); 
    729481} 
    730482 
    731483/** 
  • wp-includes/deprecated.php

     
    29062906 */ 
    29072907function debug_fclose( $fp ) { 
    29082908        _deprecated_function( __FUNCTION__, 'error_log()' ); 
     2909} 
     2910 
     2911/** 
     2912 * Retrieve list of themes with theme data in theme directory. 
     2913 * 
     2914 * The theme is broken, if it doesn't have a parent theme and is missing either 
     2915 * style.css and, or index.php. If the theme has a parent theme then it is 
     2916 * broken, if it is missing style.css; index.php is optional. 
     2917 * 
     2918 * @since 1.5.0 
     2919 * @global array $wp_themes Stores the working themes. 
     2920 * 
     2921 * @return array Theme list with theme data. 
     2922 */ 
     2923function get_themes() { 
     2924        _deprecated_function( __FUNCTION__, '3.4', 'wp_get_themes()' ); 
     2925 
     2926        global $wp_themes; 
     2927        if ( isset( $wp_themes ) ) 
     2928                return $wp_themes; 
     2929 
     2930        $themes = wp_get_themes(); 
     2931        $wp_themes = array(); 
     2932 
     2933        foreach ( $themes as $theme ) { 
     2934                $wp_themes[ $theme->get('Name') ] = $theme; 
     2935        } 
     2936 
     2937        return $wp_themes; 
     2938} 
     2939 
     2940/** 
     2941 * Retrieve theme data. 
     2942 * 
     2943 * @since 1.5.0 
     2944 * 
     2945 * @param string $theme Theme name. 
     2946 * @return array|null Null, if theme name does not exist. Theme data, if exists. 
     2947 */ 
     2948function get_theme( $theme ) { 
     2949        _deprecated_function( __FUNCTION__, '3.4', 'wp_get_theme($stylesheet)' ); 
     2950 
     2951        $themes = get_themes(); 
     2952        if ( is_array( $themes ) && array_key_exists( $theme, $themes ) ) 
     2953                return $themes[$theme]; 
     2954        return null; 
    29092955} 
     2956 No newline at end of file 
  • wp-settings.php

     
    112112require( ABSPATH . WPINC . '/capabilities.php' ); 
    113113require( ABSPATH . WPINC . '/query.php' ); 
    114114require( ABSPATH . WPINC . '/theme.php' ); 
     115require( ABSPATH . WPINC . '/class-wp-theme.php' ); 
    115116require( ABSPATH . WPINC . '/user.php' ); 
    116117require( ABSPATH . WPINC . '/meta.php' ); 
    117118require( ABSPATH . WPINC . '/general-template.php' ); 
  • wp-admin/includes/ms-deprecated.php

     
    6464        _deprecated_function(__FUNCTION__, '3.0', 'is_network_only_plugin()' ); 
    6565        return is_network_only_plugin( $file ); 
    6666} 
     67 
     68function get_site_allowed_themes() { 
     69        _deprecated_function( __FUNCTION__, '3.4', 'WP_Theme::get_allowed_on_network()' ); 
     70        return array_map( 'intval', WP_Theme::get_allowed_on_network() ); 
     71} 
     72 
     73function wpmu_get_blog_allowedthemes( $blog_id = 0 ) { 
     74        _deprecated_function( __FUNCTION__, '3.4', 'WP_Theme::get_allowed_on_site()' ); 
     75        return array_map( 'intval', WP_Theme::get_allowed_on_site( $blog_id ) ); 
     76} 
     77 No newline at end of file 
  • wp-admin/includes/update.php

     
    217217} 
    218218 
    219219function get_theme_updates() { 
    220         $themes = get_themes(); 
     220        $themes = wp_get_themes(); 
    221221        $current = get_site_transient('update_themes'); 
    222222        $update_themes = array(); 
    223223 
    224         foreach ( $themes as $theme ) { 
    225                 $theme = (object) $theme; 
    226                 if ( isset($current->response[ $theme->Stylesheet ]) ) { 
    227                         $update_themes[$theme->Stylesheet] = $theme; 
    228                         $update_themes[$theme->Stylesheet]->update = $current->response[ $theme->Stylesheet ]; 
    229                 } 
     224        foreach ( $current->response as $stylesheet => $data ) { 
     225                $update_themes[ $stylesheet ] = wp_get_theme( $stylesheet ); 
     226                $update_themes[ $stylesheet ]->update = $data; 
    230227        } 
    231228 
    232229        return $update_themes; 
  • wp-admin/includes/upgrade.php

     
    11541154                $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('show_admin_bar_admin', 'plugins_last_view')" ); 
    11551155        } 
    11561156 
    1157         // 3.3-beta. Can remove before release. 
    1158         if ( $wp_current_db_version > 18715 && $wp_current_db_version < 19389 
    1159                 && is_main_site() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) 
    1160                         delete_metadata( 'user', 0, 'dismissed_wp_pointers', '', true ); 
    1161  
    11621157        if ( $wp_current_db_version >= 11548 ) 
    11631158                return; 
    11641159 
     
    12351230                $wpdb->query("ALTER TABLE $wpdb->comments DROP INDEX comment_approved"); 
    12361231                $wpdb->show_errors(); 
    12371232        } 
     1233 
     1234        if ( $wp_current_db_version < 20000 && is_main_site() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) { 
     1235                $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 'themes_last_view'" ); 
     1236        } 
    12381237} 
    12391238 
    12401239/** 
  • wp-admin/includes/class-wp-ms-themes-list-table.php

     
    1515        function __construct() { 
    1616                global $status, $page; 
    1717 
    18                 $default_status = get_user_option( 'themes_last_view' ); 
    19                 if ( empty( $default_status ) ) 
    20                         $default_status = 'all'; 
    21                 $status = isset( $_REQUEST['theme_status'] ) ? $_REQUEST['theme_status'] : $default_status; 
    22                 if ( !in_array( $status, array( 'all', 'enabled', 'disabled', 'upgrade', 'search' ) ) ) 
     18                $status = isset( $_REQUEST['theme_status'] ) ? $_REQUEST['theme_status'] : 'all'; 
     19                if ( ! in_array( $status, array( 'all', 'enabled', 'disabled', 'upgrade', 'search' ) ) ) 
    2320                        $status = 'all'; 
    24                 if ( $status != $default_status && 'search' != $status ) 
    25                         update_user_meta( get_current_user_id(), 'themes_last_view', $status ); 
    2621 
    2722                $page = $this->get_pagenum(); 
    2823 
     
    5550        } 
    5651 
    5752        function prepare_items() { 
    58                 global $status, $themes, $totals, $page, $orderby, $order, $s; 
     53                global $status, $totals, $page, $orderby, $order, $s; 
    5954 
    6055                wp_reset_vars( array( 'orderby', 'order', 's' ) ); 
    6156 
    6257                $themes = array( 
    63                         'all' => apply_filters( 'all_themes', get_themes() ), 
     58                        'all' => apply_filters( 'all_themes', wp_get_themes() ), 
    6459                        'search' => array(), 
    6560                        'enabled' => array(), 
    6661                        'disabled' => array(), 
    6762                        'upgrade' => array() 
    6863                ); 
    6964 
    70                 $site_allowed_themes = get_site_allowed_themes(); 
    71                 if ( !$this->is_site_themes ) { 
    72                         $allowed_themes = $site_allowed_themes; 
    73                         $themes_per_page = $this->get_items_per_page( 'themes_network_per_page' ); 
    74                 } else { 
    75                         $allowed_themes = wpmu_get_blog_allowedthemes( $this->site_id ); 
     65                if ( $this->is_site_themes ) { 
    7666                        $themes_per_page = $this->get_items_per_page( 'site_themes_network_per_page' ); 
     67                        $allowed_where = 'site'; 
     68                } else { 
     69                        $themes_per_page = $this->get_items_per_page( 'themes_network_per_page' ); 
     70                        $allowed_where = 'network'; 
    7771                } 
    7872 
    79                 $current = get_site_transient( 'update_themes' ); 
     73                $current = current_user_can( 'update_themes' ) && ! $this->is_site_themes && get_site_transient( 'update_themes' ); 
    8074 
    8175                foreach ( (array) $themes['all'] as $key => $theme ) { 
    82                         $theme_key = $theme['Stylesheet']; 
    83  
    84                         if ( isset( $allowed_themes [ $theme_key ] ) )  { 
    85                                 $themes['all'][$key]['enabled'] = true; 
    86                                 $themes['enabled'][$key] = $themes['all'][$key]; 
     76                        if ( $this->is_site_themes && $theme->is_allowed( 'network' ) ) { 
     77                                unset( $themes['all'][ $key ] ); 
     78                                continue; 
    8779                        } 
    88                         else { 
    89                                 $themes['all'][$key]['enabled'] = false; 
    90                                 $themes['disabled'][$key] = $themes['all'][$key]; 
    91                         } 
    92                         if ( isset( $current->response[ $theme['Template'] ] ) ) 
    93                                 $themes['upgrade'][$key] = $themes['all'][$key]; 
    9480 
    95                         if ( $this->is_site_themes && isset( $site_allowed_themes[$theme_key] ) ) { 
    96                                 unset( $themes['all'][$key] ); 
    97                                 unset( $themes['enabled'][$key] ); 
    98                                 unset( $themes['disabled'][$key] ); 
    99                         } 
     81                        $filter = $theme->is_allowed( $allowed_where, $this->site_id ) ? 'enabled' : 'disabled'; 
     82                        $themes[ $filter ][ $key ] = $themes['all'][ $key ]; 
     83 
     84                        if ( $current && isset( $current->response[ $key ] ) ) 
     85                                $themes['upgrade'][ $key ] = $themes['all'][ $key ]; 
    10086                } 
    10187 
    102                 if ( !current_user_can( 'update_themes' ) || $this->is_site_themes ) 
    103                         $themes['upgrade'] = array(); 
    104  
    10588                if ( $s ) { 
    10689                        $status = 'search'; 
    10790                        $themes['search'] = array_filter( $themes['all'], array( &$this, '_search_callback' ) ); 
     
    11598                        $status = 'all'; 
    11699 
    117100                $this->items = $themes[ $status ]; 
     101                WP_Theme::sort_by_name( $this->items ); 
     102 
     103                $this->has_items = ! empty( $themes['all'] ); 
    118104                $total_this_page = $totals[ $status ]; 
    119105 
    120106                if ( $orderby ) { 
    121107                        $orderby = ucfirst( $orderby ); 
    122108                        $order = strtoupper( $order ); 
    123109 
    124                         uasort( $this->items, array( &$this, '_order_callback' ) ); 
     110                        if ( $orderby == 'Name' ) { 
     111                                if ( 'ASC' == $order ) 
     112                                        $this->items = array_reverse( $this->items ); 
     113                        } else { 
     114                                uasort( $this->items, array( &$this, '_order_callback' ) ); 
     115                        } 
    125116                } 
    126117 
    127118                $start = ( $page - 1 ) * $themes_per_page; 
    128119 
    129120                if ( $total_this_page > $themes_per_page ) 
    130                         $this->items = array_slice( $this->items, $start, $themes_per_page ); 
     121                        $this->items = array_slice( $this->items, $start, $themes_per_page, true ); 
    131122 
    132123                $this->set_pagination_args( array( 
    133124                        'total_items' => $total_this_page, 
     
    140131                if ( is_null( $term ) ) 
    141132                        $term = stripslashes( $_REQUEST['s'] ); 
    142133 
    143                 $search_fields = array( 'Name', 'Title', 'Description', 'Author', 'Author Name', 'Author URI', 'Template', 'Stylesheet' ); 
    144                 foreach ( $search_fields as $field ) 
    145                         if ( stripos( $theme[ $field ], $term ) !== false ) 
     134                foreach ( array( 'Name', 'Description', 'Author', 'Author', 'AuthorURI' ) as $field ) { 
     135                        // Don't mark up; Do translate. 
     136                        if ( false !== stripos( $theme->display( $field, false, true ), $term ) ) 
    146137                                return true; 
     138                } 
    147139 
     140                if ( false !== stripos( $theme->get_stylesheet(), $term ) ) 
     141                        return true; 
     142 
     143                if ( false !== stripos( $theme->get_template(), $term ) ) 
     144                        return true; 
     145 
    148146                return false; 
    149147        } 
    150148 
     149        // Not used by any core columns. 
    151150        function _order_callback( $theme_a, $theme_b ) { 
    152151                global $orderby, $order; 
    153152 
    154                 $a = $theme_a[$orderby]; 
    155                 $b = $theme_b[$orderby]; 
     153                $a = $theme_a[ $orderby ]; 
     154                $b = $theme_b[ $orderby ]; 
    156155 
    157156                if ( $a == $b ) 
    158157                        return 0; 
     
    164163        } 
    165164 
    166165        function no_items() { 
    167                 global $themes; 
    168  
    169                 if ( !empty( $themes['all'] ) ) 
     166                if ( ! $$this->has_items ) 
    170167                        _e( 'No themes found.' ); 
    171168                else 
    172169                        _e( 'You do not appear to have any themes available at this time.' ); 
     
    264261 
    265262                $context = $status; 
    266263 
    267                 if ( $this->is_site_themes ) 
     264                if ( $this->is_site_themes ) { 
    268265                        $url = "site-themes.php?id={$this->site_id}&amp;"; 
    269                 else 
     266                        $allowed = $theme->is_allowed( 'site', $this->site_id ); 
     267                } else { 
    270268                        $url = 'themes.php?'; 
     269                        $allowed = $theme->is_allowed( 'network' ); 
     270                } 
    271271 
    272272                // preorder 
    273273                $actions = array( 
     
    277277                        'delete' => '' 
    278278                ); 
    279279 
    280                 $theme_key = $theme['Stylesheet']; 
     280                $theme_key = $theme->get_stylesheet(); 
    281281 
    282                 if ( empty( $theme['enabled'] ) ) 
     282                if ( ! $allowed ) 
    283283                        $actions['enable'] = '<a href="' . esc_url( wp_nonce_url($url . 'action=enable&amp;theme=' . $theme_key . '&amp;paged=' . $page . '&amp;s=' . $s, 'enable-theme_' . $theme_key) ) . '" title="' . esc_attr__('Enable this theme') . '" class="edit">' . ( $this->is_site_themes ? __( 'Enable' ) : __( 'Network Enable' ) ) . '</a>'; 
    284284                else 
    285285                        $actions['disable'] = '<a href="' . esc_url( wp_nonce_url($url . 'action=disable&amp;theme=' . $theme_key . '&amp;paged=' . $page . '&amp;s=' . $s, 'disable-theme_' . $theme_key) ) . '" title="' . esc_attr__('Disable this theme') . '">' . ( $this->is_site_themes ? __( 'Disable' ) : __( 'Network Disable' ) ) . '</a>'; 
    286286 
    287287                if ( current_user_can('edit_themes') ) 
    288                         $actions['edit'] = '<a href="' . esc_url('theme-editor.php?theme=' . urlencode( $theme['Name'] )) . '" title="' . esc_attr__('Open this theme in the Theme Editor') . '" class="edit">' . __('Edit') . '</a>'; 
     288                        $actions['edit'] = '<a href="' . esc_url('theme-editor.php?theme=' .  $theme_key ) . '" title="' . esc_attr__('Open this theme in the Theme Editor') . '" class="edit">' . __('Edit') . '</a>'; 
    289289 
    290                 if ( empty( $theme['enabled'] ) && current_user_can( 'delete_themes' ) && ! $this->is_site_themes && $theme_key != get_option( 'stylesheet' ) && $theme_key != get_option( 'template' ) ) 
     290                if ( ! $allowed && current_user_can( 'delete_themes' ) && ! $this->is_site_themes && $theme_key != get_option( 'stylesheet' ) && $theme_key != get_option( 'template' ) ) 
    291291                        $actions['delete'] = '<a href="' . esc_url( wp_nonce_url( 'themes.php?action=delete-selected&amp;checked[]=' . $theme_key . '&amp;theme_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'bulk-themes' ) ) . '" title="' . esc_attr__( 'Delete this theme' ) . '" class="delete">' . __( 'Delete' ) . '</a>'; 
    292292 
    293293                $actions = apply_filters( 'theme_action_links', array_filter( $actions ), $theme_key, $theme, $context ); 
    294294                $actions = apply_filters( "theme_action_links_$theme_key", $actions, $theme_key, $theme, $context ); 
    295295 
    296                 $class = empty( $theme['enabled'] ) ? 'inactive' : 'active'; 
    297                 $checkbox_id = "checkbox_" . md5($theme['Name']); 
    298                 $checkbox = "<input type='checkbox' name='checked[]' value='" . esc_attr( $theme_key ) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select') . " " . $theme['Name'] . "</label>"; 
     296                $class = ! $allowed ? 'inactive' : 'active'; 
     297                $checkbox_id = "checkbox_" . md5( $theme->get('Name') ); 
     298                $checkbox = "<input type='checkbox' name='checked[]' value='" . esc_attr( $theme_key ) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select') . " " . $theme->display('Name') . "</label>"; 
    299299 
    300                 $description = '<p>' . $theme['Description'] . '</p>'; 
    301                 $theme_name = $theme['Name']; 
     300                $description = '<p>' . $theme->display( 'Description' ) . '</p>'; 
    302301 
    303                 $id = sanitize_title( $theme_name ); 
     302                $id = sanitize_html_class( $theme->get_stylesheet() ); 
    304303 
    305304                echo "<tr id='$id' class='$class'>"; 
    306305 
     
    316315                                        echo "<th scope='row' class='check-column'>$checkbox</th>"; 
    317316                                        break; 
    318317                                case 'name': 
    319                                         echo "<td class='theme-title'$style><strong>$theme_name</strong>"; 
     318                                        echo "<td class='theme-title'$style><strong>" . $theme->display('Name') . "</strong>"; 
    320319                                        echo $this->row_actions( $actions, true ); 
    321320                                        echo "</td>"; 
    322321                                        break; 
    323322                                case 'description': 
    324323                                        echo "<td class='column-description desc'$style> 
    325                                                 <div class='theme-description'>$description</div> 
     324                                                <div class='theme-description'>" . $theme->display( 'Description' ) . "</div> 
    326325                                                <div class='$class second theme-version-author-uri'>"; 
    327326 
    328327                                        $theme_meta = array(); 
    329328 
    330                                         if ( !empty( $theme['Version'] ) ) 
    331                                                 $theme_meta[] = sprintf( __( 'Version %s' ), $theme['Version'] ); 
     329                                        if ( $theme->get('Version') ) 
     330                                                $theme_meta[] = sprintf( __( 'Version %s' ), $theme->display('Version') ); 
    332331 
    333                                         if ( !empty( $theme['Author'] ) ) 
    334                                                 $theme_meta[] = sprintf( __( 'By %s' ), $theme['Author'] ); 
     332                                        if ( $theme->get('Author') ) 
     333                                                $theme_meta[] = sprintf( __( 'By %s' ), $theme->display('Author') ); 
    335334 
    336                                         if ( !empty( $theme['Theme URI'] ) ) 
    337                                                 $theme_meta[] = '<a href="' . $theme['Theme URI'] . '" title="' . esc_attr__( 'Visit theme homepage' ) . '">' . __( 'Visit Theme Site' ) . '</a>'; 
     335                                        if ( $theme->get('ThemeURI') ) 
     336                                                $theme_meta[] = '<a href="' . $theme->display('ThemeURI') . '" title="' . esc_attr__( 'Visit theme homepage' ) . '">' . __( 'Visit Theme Site' ) . '</a>'; 
    338337 
    339338                                        $theme_meta = apply_filters( 'theme_row_meta', $theme_meta, $theme_key, $theme, $status ); 
    340339                                        echo implode( ' | ', $theme_meta ); 
  • wp-admin/includes/dashboard.php

     
    383383        echo "\n\t</table>\n\t</div>"; 
    384384 
    385385        echo "\n\t".'<div class="versions">'; 
    386         $ct = current_theme_info(); 
     386        $theme = wp_get_theme(); 
    387387 
    388388        echo "\n\t<p>"; 
    389389 
    390         if ( empty( $ct->stylesheet_dir ) ) { 
     390        if ( $theme->errors() ) { 
    391391                if ( ! is_multisite() || is_super_admin() ) 
    392392                        echo '<span class="error-message">' . __('ERROR: The themes directory is either empty or doesn&#8217;t exist. Please check your installation.') . '</span>'; 
    393393        } elseif ( ! empty($wp_registered_sidebars) ) { 
     
    401401                } 
    402402                $num = number_format_i18n( $num_widgets ); 
    403403 
    404                 $switch_themes = $ct->title; 
     404                $switch_themes = $theme->display('Name'); 
    405405                if ( current_user_can( 'switch_themes') ) 
    406406                        $switch_themes = '<a href="themes.php">' . $switch_themes . '</a>'; 
    407407                if ( current_user_can( 'edit_theme_options' ) ) { 
     
    411411                } 
    412412        } else { 
    413413                if ( current_user_can( 'switch_themes' ) ) 
    414                         printf( __('Theme <span class="b"><a href="themes.php">%1$s</a></span>'), $ct->title ); 
     414                        printf( __('Theme <span class="b"><a href="themes.php">%1$s</a></span>'), $theme->display('Name') ); 
    415415                else 
    416                         printf( __('Theme <span class="b">%1$s</span>'), $ct->title ); 
     416                        printf( __('Theme <span class="b">%1$s</span>'), $theme->display('Name') ); 
    417417        } 
    418418        echo '</p>'; 
    419419 
     
    13131313        <div class="welcome-panel-column welcome-panel-last"> 
    13141314                <h4><span class="icon16 icon-appearance"></span> <?php _e( 'Customize Your Site' ); ?></h4> 
    13151315                <?php 
    1316                 $ct = current_theme_info(); 
    1317                 if ( empty ( $ct->stylesheet_dir ) ) : 
     1316                $theme = wp_get_theme(); 
     1317                if ( $theme->errors() ) : 
    13181318                        echo '<p>'; 
    13191319                        printf( __( '<a href="%s">Install a theme</a> to get started customizing your site.' ), esc_url( admin_url( 'themes.php' ) ) ); 
    13201320                        echo '</p>'; 
    13211321                else: 
    13221322                        $customize_links = array(); 
    1323                         if ( 'twentyeleven' == $ct->stylesheet ) 
     1323                        if ( 'twentyeleven' == $theme->get_stylesheet() ) 
    13241324                                $customize_links[] = sprintf( __( '<a href="%s">Choose light or dark</a>' ), esc_url( admin_url( 'themes.php?page=theme_options' ) ) ); 
    13251325 
    13261326                        if ( current_theme_supports( 'custom-background' ) ) 
     
    13341334 
    13351335                        if ( ! empty( $customize_links ) ) { 
    13361336                                echo '<p>'; 
    1337                                 printf( __( 'Use the current theme &mdash; %1$s &mdash; or <a href="%2$s">choose a new one</a>. If you stick with %3$s, here are a few ways to make your site look unique.' ), $ct->title, esc_url( admin_url( 'themes.php' ) ), $ct->title ); 
     1337                                printf( __( 'Use the current theme &mdash; %1$s &mdash; or <a href="%2$s">choose a new one</a>. If you stick with %1$s, here are a few ways to make your site look unique.' ), $theme->display('Name'), esc_url( admin_url( 'themes.php' ) ) ); 
    13381338                                echo '</p>'; 
    13391339                        ?> 
    13401340                        <ul> 
     
    13451345                        <?php 
    13461346                        } else { 
    13471347                                echo '<p>'; 
    1348                                 printf( __( 'Use the current theme &mdash; %1$s &mdash; or <a href="%2$s">choose a new one</a>.' ), $ct->title, esc_url( admin_url( 'themes.php' ) ) ); 
     1348                                printf( __( 'Use the current theme &mdash; %1$s &mdash; or <a href="%2$s">choose a new one</a>.' ), $this->display('Name'), esc_url( admin_url( 'themes.php' ) ) ); 
    13491349                                echo '</p>'; 
    13501350                        } 
    13511351                endif; ?> 
  • wp-admin/includes/deprecated.php

     
    879879                $screen = convert_to_screen( $screen ); 
    880880 
    881881        WP_Screen::add_old_compat_help( $screen, $help ); 
     882} 
     883 
     884/** 
     885 * Get the allowed themes for the current blog. 
     886 * 
     887 * @since 3.0.0 
     888 * @deprecated 3.4.0 
     889 * @deprecated Use wp_get_themes() 
     890 * @see wp_get_themes() 
     891 * 
     892 * @return array $themes Array of allowed themes. 
     893 */ 
     894function get_allowed_themes() { 
     895        _deprecated_function( __FUNCTION__, '3.4', "wp_get_themes( array( 'allowed' => true ) )" ); 
     896 
     897        $themes = wp_get_themes( array( 'allowed' => true ) ); 
     898 
     899        $wp_themes = array(); 
     900        foreach ( $themes as $theme ) { 
     901                $wp_themes[ $theme->get('Name') ] = $theme; 
     902        } 
     903 
     904        return $wp_themes; 
     905} 
     906 
     907/** 
     908 * {@internal Missing Short Description}} 
     909 * 
     910 * @since 1.5.0 
     911 * 
     912 * @return unknown 
     913 */ 
     914function get_broken_themes() { 
     915        _deprecated_function( __FUNCTION__, '3.4', "wp_get_themes( array( 'errors' => true )" ); 
     916 
     917        $themes = wp_get_themes( array( 'errors' => true ) ); 
     918        $broken = array(); 
     919        foreach ( $themes as $theme ) { 
     920                $broken[ $theme->get('Name') ] = array( 
     921                        'Title' => $theme->get('Name'), 
     922                        'Description' => $theme->errors()->get_error_message(), 
     923                ); 
     924        } 
     925        return $broken; 
     926} 
     927 
     928/** 
     929 * {@internal Missing Short Description}} 
     930 * 
     931 * @since 2.0.0 
     932 * 
     933 * @return unknown 
     934 */ 
     935function current_theme_info() { 
     936        _deprecated_function( __FUNCTION__, '3.4', 'wp_get_theme()' ); 
     937 
     938        return wp_get_theme(); 
    882939} 
     940 No newline at end of file 
  • wp-admin/includes/schema.php

     
    343343 
    344344        $template = WP_DEFAULT_THEME; 
    345345        // If default theme is a child theme, we need to get its template 
    346         foreach ( (array) get_themes() as $theme ) { 
    347                 if ( WP_DEFAULT_THEME == $theme['Stylesheet'] ) { 
    348                         $template = $theme['Template']; 
    349                         break; 
    350                 } 
    351         } 
     346        $theme = wp_get_theme( $template ); 
     347        if ( ! $theme->errors() ) 
     348                $template = $theme->get_template(); 
    352349 
    353350        $timezone_string = ''; 
    354351        $gmt_offset = 0; 
  • wp-admin/includes/theme.php

     
    77 */ 
    88 
    99/** 
    10  * {@internal Missing Short Description}} 
    11  * 
    12  * @since 2.0.0 
    13  * 
    14  * @return unknown 
    15  */ 
    16 function current_theme_info() { 
    17         $themes = get_themes(); 
    18         $current_theme = get_current_theme(); 
    19  
    20         if ( ! $themes ) { 
    21                 $ct = new stdClass; 
    22                 $ct->name = $current_theme; 
    23                 return $ct; 
    24         } 
    25  
    26         if ( ! isset( $themes[$current_theme] ) ) { 
    27                 delete_option( 'current_theme' ); 
    28                 $current_theme = get_current_theme(); 
    29         } 
    30  
    31         $ct = new stdClass; 
    32         $ct->name = $current_theme; 
    33         $ct->title = $themes[$current_theme]['Title']; 
    34         $ct->version = $themes[$current_theme]['Version']; 
    35         $ct->parent_theme = $themes[$current_theme]['Parent Theme']; 
    36         $ct->template_dir = $themes[$current_theme]['Template Dir']; 
    37         $ct->stylesheet_dir = $themes[$current_theme]['Stylesheet Dir']; 
    38         $ct->template = $themes[$current_theme]['Template']; 
    39         $ct->stylesheet = $themes[$current_theme]['Stylesheet']; 
    40         $ct->screenshot = $themes[$current_theme]['Screenshot']; 
    41         $ct->description = $themes[$current_theme]['Description']; 
    42         $ct->author = $themes[$current_theme]['Author']; 
    43         $ct->tags = $themes[$current_theme]['Tags']; 
    44         $ct->theme_root = $themes[$current_theme]['Theme Root']; 
    45         $ct->theme_root_uri = $themes[$current_theme]['Theme Root URI']; 
    46         return $ct; 
    47 } 
    48  
    49 /** 
    5010 * Remove a theme 
    5111 * 
    5212 * @since 2.8.0 
     
    11474} 
    11575 
    11676/** 
    117  * {@internal Missing Short Description}} 
    118  * 
    119  * @since 1.5.0 
    120  * 
    121  * @return unknown 
    122  */ 
    123 function get_broken_themes() { 
    124         global $wp_broken_themes; 
    125  
    126         get_themes(); 
    127         return $wp_broken_themes; 
    128 } 
    129  
    130 /** 
    131  * Get the allowed themes for the current blog. 
    132  * 
    133  * @since 3.0.0 
    134  * 
    135  * @uses get_themes() 
    136  * @uses current_theme_info() 
    137  * @uses get_site_allowed_themes() 
    138  * @uses wpmu_get_blog_allowedthemes 
    139  * 
    140  * @return array $themes Array of allowed themes. 
    141  */ 
    142 function get_allowed_themes() { 
    143         if ( !is_multisite() ) 
    144                 return get_themes(); 
    145  
    146         $themes = get_themes(); 
    147         $ct = current_theme_info(); 
    148         $allowed_themes = apply_filters("allowed_themes", get_site_allowed_themes() ); 
    149         if ( $allowed_themes == false ) 
    150                 $allowed_themes = array(); 
    151  
    152         $blog_allowed_themes = wpmu_get_blog_allowedthemes(); 
    153         if ( is_array( $blog_allowed_themes ) ) 
    154                 $allowed_themes = array_merge( $allowed_themes, $blog_allowed_themes ); 
    155  
    156         if ( isset( $allowed_themes[ esc_html( $ct->stylesheet ) ] ) == false ) 
    157                 $allowed_themes[ esc_html( $ct->stylesheet ) ] = true; 
    158  
    159         reset( $themes ); 
    160         foreach ( $themes as $key => $theme ) { 
    161                 if ( isset( $allowed_themes[ esc_html( $theme[ 'Stylesheet' ] ) ] ) == false ) 
    162                         unset( $themes[ $key ] ); 
    163         } 
    164         reset( $themes ); 
    165  
    166         return $themes; 
    167 } 
    168  
    169 /** 
    17077 * Get the Page Templates available in this theme 
    17178 * 
    17279 * @since 1.5.0 
     
    17481 * @return array Key is the template name, value is the filename of the template 
    17582 */ 
    17683function get_page_templates() { 
    177         $themes = get_themes(); 
    178         $theme = get_current_theme(); 
    179         $templates = $themes[$theme]['Template Files']; 
    180         $page_templates = array(); 
    181  
    182         if ( is_array( $templates ) ) { 
    183                 $base = array( trailingslashit(get_template_directory()), trailingslashit(get_stylesheet_directory()) ); 
    184  
    185                 foreach ( $templates as $template ) { 
    186                         $basename = str_replace($base, '', $template); 
    187  
    188                         // don't allow template files in subdirectories 
    189                         if ( false !== strpos($basename, '/') ) 
    190                                 continue; 
    191  
    192                         if ( 'functions.php' == $basename ) 
    193                                 continue; 
    194  
    195                         $template_data = implode( '', file( $template )); 
    196  
    197                         $name = ''; 
    198                         if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name ) ) 
    199                                 $name = _cleanup_header_comment($name[1]); 
    200  
    201                         if ( !empty( $name ) ) { 
    202                                 $page_templates[trim( $name )] = $basename; 
    203                         } 
    204                 } 
    205         } 
    206  
    207         return $page_templates; 
     84        return wp_get_theme()->get_page_templates(); 
    20885} 
    20986 
    21087/** 
     
    240117        if ( !isset($themes_update) ) 
    241118                $themes_update = get_site_transient('update_themes'); 
    242119 
    243         if ( is_object($theme) && isset($theme->stylesheet) ) 
    244                 $stylesheet = $theme->stylesheet; 
    245         elseif ( is_array($theme) && isset($theme['Stylesheet']) ) 
    246                 $stylesheet = $theme['Stylesheet']; 
    247         else 
    248                 return false; //No valid info passed. 
     120        if ( ! is_a( $theme, 'WP_Theme' ) ) 
     121                return; 
    249122 
     123        $stylesheet = $theme->get_stylesheet(); 
     124 
    250125        if ( isset($themes_update->response[ $stylesheet ]) ) { 
    251126                $update = $themes_update->response[ $stylesheet ]; 
    252                 $theme_name = is_object($theme) ? $theme->name : (is_array($theme) ? $theme['Name'] : ''); 
     127                $theme_name = $theme->get('Name'); 
    253128                $details_url = add_query_arg(array('TB_iframe' => 'true', 'width' => 1024, 'height' => 800), $update['url']); //Theme browser inside WP? replace this, Also, theme preview JS will override this on the available list. 
    254129                $update_url = wp_nonce_url('update.php?action=upgrade-theme&amp;theme=' . urlencode($stylesheet), 'upgrade-theme_' . $stylesheet); 
    255130                $update_onclick = 'onclick="if ( confirm(\'' . esc_js( __("Updating this theme will lose any customizations you have made. 'Cancel' to stop, 'OK' to update.") ) . '\') ) {return true;}return false;"'; 
     
    270145 * 
    271146 * @since 3.1.0 
    272147 * 
     148 * @param bool $api Optional. Whether to hit the API for tags. Defaults to true. 
    273149 * @return array Array of features keyed by category with translations keyed by slug. 
    274150 */ 
    275 function get_theme_feature_list() { 
     151function get_theme_feature_list( $api = true ) { 
    276152        // Hard-coded list is used if api not accessible. 
    277153        $features = array( 
    278154                        __('Colors') => array( 
     
    290166                                'white'   => __( 'White' ), 
    291167                                'yellow'  => __( 'Yellow' ), 
    292168                                'dark'    => __( 'Dark' ), 
    293                                 'light'   => __( 'Light ') 
     169                                'light'   => __( 'Light' ) 
    294170                        ), 
    295171 
    296172                __('Columns') => array( 
     
    335211                ) 
    336212        ); 
    337213 
    338         if ( !current_user_can('install_themes') ) 
     214        if ( ! $api || !current_user_can('install_themes') ) 
    339215                return $features; 
    340216 
    341217        if ( !$feature_list = get_site_transient( 'wporg_theme_feature_list' ) ) 
  • wp-admin/includes/theme-install.php

     
    265265                } 
    266266        } 
    267267 
    268         $themes = get_themes(); 
    269         foreach ( (array) $themes as $this_theme ) { 
    270                 if ( is_array($this_theme) && $this_theme['Stylesheet'] == $api->slug ) { 
    271                         if ( version_compare( $this_theme['Version'], $api->version, '=' ) ) { 
     268        $theme = wp_get_theme( $api->slug ); 
     269        if ( is_a( $theme, 'WP_Theme' ) ) { 
     270                switch ( version_compare( $theme->get('Version'), $api->version ) ) { 
     271                        case 0; // equal 
    272272                                $type = 'latest_installed'; 
    273                         } elseif ( version_compare( $this_theme['Version'], $api->version, '>' ) ) { 
     273                        case 1: // installed theme > api version 
    274274                                $type = 'newer_installed'; 
    275                                 $newer_version = $this_theme['Version']; 
    276                         } 
    277                         break; 
     275                                $newer_version = $theme->get('Version'); 
    278276                } 
    279277        } 
    280278?> 
  • wp-admin/includes/class-wp-themes-list-table.php

     
    2424        } 
    2525 
    2626        function prepare_items() { 
    27                 global $ct; 
     27                $themes = wp_get_themes( array( 'allowed' => true ) ); 
    2828 
    29                 $ct = current_theme_info(); 
    30  
    31                 $themes = get_allowed_themes(); 
    32  
    3329                if ( ! empty( $_REQUEST['s'] ) ) { 
    3430                        $search = strtolower( stripslashes( $_REQUEST['s'] ) ); 
    3531                        $this->search = array_merge( $this->search, array_filter( array_map( 'trim', explode( ',', $search ) ) ) ); 
     
    4541 
    4642                if ( $this->search || $this->features ) { 
    4743                        foreach ( $themes as $key => $theme ) { 
    48                                 if ( !$this->search_theme( $theme ) ) 
     44                                if ( ! $this->search_theme( $theme ) ) 
    4945                                        unset( $themes[ $key ] ); 
    5046                        } 
    5147                } 
    5248 
    53                 unset( $themes[$ct->name] ); 
    54                 uksort( $themes, "strnatcasecmp" ); 
     49                unset( $themes[ get_option( 'stylesheet' ) ] ); 
     50                WP_Theme::sort_by_name( $themes ); 
    5551 
    5652                $per_page = 999; 
    5753                $page = $this->get_pagenum(); 
     
    125121 
    126122        function display_rows() { 
    127123                $themes = $this->items; 
    128                 $theme_names = array_keys( $themes ); 
    129                 natcasesort( $theme_names ); 
    130124 
    131         foreach ( $theme_names as $theme_name ) { 
    132                 $class = array( 'available-theme' ); 
    133         ?> 
    134         <div class="<?php echo join( ' ', $class ); ?>"> 
    135         <?php if ( !empty( $theme_name ) ) : 
    136         $template = $themes[$theme_name]['Template']; 
    137         $stylesheet = $themes[$theme_name]['Stylesheet']; 
    138         $title = $themes[$theme_name]['Title']; 
    139         $version = $themes[$theme_name]['Version']; 
    140         $description = $themes[$theme_name]['Description']; 
    141         $author = $themes[$theme_name]['Author']; 
    142         $screenshot = $themes[$theme_name]['Screenshot']; 
    143         $stylesheet_dir = $themes[$theme_name]['Stylesheet Dir']; 
    144         $template_dir = $themes[$theme_name]['Template Dir']; 
    145         $parent_theme = $themes[$theme_name]['Parent Theme']; 
    146         $theme_root = $themes[$theme_name]['Theme Root']; 
    147         $theme_root_uri = $themes[$theme_name]['Theme Root URI']; 
    148         $preview_link = esc_url( add_query_arg( array( 'preview' => 1, 'template' => $template, 'stylesheet' => $stylesheet, 'preview_iframe' => true, 'TB_iframe' => 'true' ), home_url( '/' ) ) ); 
    149         $preview_text = esc_attr( sprintf( __( 'Preview of &#8220;%s&#8221;' ), $title ) ); 
    150         $tags = $themes[$theme_name]['Tags']; 
    151         $thickbox_class = 'thickbox thickbox-preview'; 
    152         $activate_link = wp_nonce_url( "themes.php?action=activate&amp;template=" . urlencode( $template ) . "&amp;stylesheet=" . urlencode( $stylesheet ), 'switch-theme_' . $template ); 
    153         $activate_text = esc_attr( sprintf( __( 'Activate &#8220;%s&#8221;' ), $title ) ); 
    154         $actions = array(); 
    155         $actions[] = '<a href="' . $activate_link . '" class="activatelink" title="' . $activate_text . '">' . __( 'Activate' ) . '</a>'; 
    156         $actions[] = '<a href="' . $preview_link . '" class="thickbox thickbox-preview" title="' . esc_attr( sprintf( __( 'Preview &#8220;%s&#8221;' ), $theme_name ) ) . '">' . __( 'Preview' ) . '</a>'; 
    157         if ( ! is_multisite() && current_user_can( 'delete_themes' ) ) 
    158                 $actions[] = '<a class="submitdelete deletion" href="' . wp_nonce_url( "themes.php?action=delete&amp;template=$stylesheet", 'delete-theme_' . $stylesheet ) . '" onclick="' . "return confirm( '" . esc_js( sprintf( __( "You are about to delete this theme '%s'\n  'Cancel' to stop, 'OK' to delete." ), $theme_name ) ) . "' );" . '">' . __( 'Delete' ) . '</a>'; 
    159         $actions = apply_filters( 'theme_action_links', $actions, $themes[$theme_name] ); 
     125                foreach ( $themes as $theme ) { 
     126                        echo '<div class="available-theme">'; 
    160127 
    161         $actions = implode ( ' | ', $actions ); 
    162 ?> 
    163                 <a href="<?php echo $preview_link; ?>" class="<?php echo $thickbox_class; ?> screenshot"> 
    164 <?php if ( $screenshot ) : ?> 
    165                         <img src="<?php echo $theme_root_uri . '/' . $stylesheet . '/' . $screenshot; ?>" alt="" /> 
    166 <?php endif; ?> 
    167                 </a> 
    168 <h3><?php 
    169         /* translators: 1: theme title, 2: theme version, 3: theme author */ 
    170         printf( __( '%1$s %2$s by %3$s' ), $title, $version, $author ) ; ?></h3> 
     128                        $template = $theme->get_template(); 
     129                        $stylesheet = $theme->get_stylesheet(); 
    171130 
    172 <span class='action-links'><?php echo $actions ?></span> 
    173 <span class="separator hide-if-no-js">| </span><a href="#" class="theme-detail hide-if-no-js" tabindex='4'><?php _e('Details') ?></a> 
    174 <div class="themedetaildiv hide-if-js"> 
    175 <p><?php echo $description; ?></p> 
    176         <?php if ( current_user_can( 'edit_themes' ) && $parent_theme ) { 
    177         /* translators: 1: theme title, 2:  template dir, 3: stylesheet_dir, 4: theme title, 5: parent_theme */ ?> 
    178         <p><?php printf( __( 'The template files are located in <code>%2$s</code>. The stylesheet files are located in <code>%3$s</code>. <strong>%4$s</strong> uses templates from <strong>%5$s</strong>. Changes made to the templates will affect both themes.' ), $title, str_replace( WP_CONTENT_DIR, '', $template_dir ), str_replace( WP_CONTENT_DIR, '', $stylesheet_dir ), $title, $parent_theme ); ?></p> 
    179 <?php } else { ?> 
    180         <p><?php printf( __( 'All of this theme&#8217;s files are located in <code>%2$s</code>.' ), $title, str_replace( WP_CONTENT_DIR, '', $template_dir ), str_replace( WP_CONTENT_DIR, '', $stylesheet_dir ) ); ?></p> 
    181 <?php } ?> 
    182 <?php if ( $tags ) : ?> 
    183 <p><?php _e( 'Tags:' ); ?> <?php echo join( ', ', $tags ); ?></p> 
    184 <?php endif; ?> 
    185 <?php endif; // end if not empty theme_name ?> 
    186 </div> 
    187         <?php theme_update_available( $themes[$theme_name] ); ?> 
    188         </div> 
    189 <?php } // end foreach $theme_names 
     131                        $title = $theme->display('Name'); 
     132                        $version = $theme->display('Version'); 
     133                        $author = $theme->display('Author'); 
     134 
     135                        $activate_link = wp_nonce_url( "themes.php?action=activate&amp;template=" . urlencode( $template ) . "&amp;stylesheet=" . urlencode( $stylesheet ), 'switch-theme_' . $template ); 
     136                        $preview_link = esc_url( add_query_arg( 
     137                                array( 'preview' => 1, 'template' => $template, 'stylesheet' => $stylesheet, 'preview_iframe' => true, 'TB_iframe' => 'true' ), 
     138                                home_url( '/' ) ) ); 
     139 
     140                        $actions = array(); 
     141                        $actions[] = '<a href="' . $activate_link . '" class="activatelink" title="' 
     142                                . esc_attr( sprintf( __( 'Activate &#8220;%s&#8221;' ), $title ) ) . '">' . __( 'Activate' ) . '</a>'; 
     143                        $actions[] = '<a href="' . $preview_link . '" class="thickbox thickbox-preview" title="' 
     144                                . esc_attr( sprintf( __( 'Preview &#8220;%s&#8221;' ), $title ) ) . '">' . __( 'Preview' ) . '</a>'; 
     145                        if ( ! is_multisite() && current_user_can( 'delete_themes' ) ) 
     146                                $actions[] = '<a class="submitdelete deletion" href="' . wp_nonce_url( "themes.php?action=delete&amp;template=$stylesheet", 'delete-theme_' . $stylesheet ) 
     147                                        . '" onclick="' . "return confirm( '" . esc_js( sprintf( __( "You are about to delete this theme '%s'\n  'Cancel' to stop, 'OK' to delete." ), $title ) ) 
     148                                        . "' );" . '">' . __( 'Delete' ) . '</a>'; 
     149 
     150                        $actions = apply_filters( 'theme_action_links', $actions, $theme ); 
     151 
     152                        $actions = implode ( ' | ', $actions ); 
     153                        ?> 
     154                        <a href="<?php echo $preview_link; ?>" class="thickbox thickbox-preview screenshot"> 
     155                        <?php if ( $theme->get_screenshot() ) : ?> 
     156                                <img src="<?php echo esc_url( $theme->get_screenshot( 'absolute' ) ); ?>" alt="" /> 
     157                        <?php endif; ?> 
     158                        </a> 
     159                        <h3><?php 
     160                        /* translators: 1: theme title, 2: theme version, 3: theme author */ 
     161                        printf( __( '%1$s %2$s by %3$s' ), $title, $version, $author ) ; ?></h3> 
     162 
     163                        <span class='action-links'><?php echo $actions ?></span> 
     164                        <span class="separator hide-if-no-js">| </span><a href="#" class="theme-detail hide-if-no-js" tabindex='4'><?php _e('Details') ?></a> 
     165                        <div class="themedetaildiv hide-if-js"> 
     166                        <p><?php echo $theme->display('Description'); ?></p> 
     167                        <?php if ( current_user_can( 'edit_themes' ) && $theme->parent() ) : 
     168                                /* translators: 1: theme title, 2:  template dir, 3: stylesheet_dir, 4: theme title, 5: parent_theme */ ?> 
     169                                <p><?php printf( __( 'The template files are located in <code>%2$s</code>. The stylesheet files are located in <code>%3$s</code>. <strong>%4$s</strong> uses templates from <strong>%5$s</strong>. Changes made to the templates will affect both themes.' ), 
     170                                        $title, str_replace( WP_CONTENT_DIR, '', $theme->get_template_directory() ), str_replace( WP_CONTENT_DIR, '', $theme->get_stylesheet_directory() ), $title, $theme->parent()->display('Name') ); ?></p> 
     171                        <?php else : 
     172                                        /* translators: 1: theme title, 2:  template dir, 3: stylesheet_dir */ ?> 
     173                                <p><?php printf( __( 'All of this theme&#8217;s files are located in <code>%2$s</code>.' ), 
     174                                        $title, str_replace( WP_CONTENT_DIR, '', $theme->get_template_directory() ), str_replace( WP_CONTENT_DIR, '', $theme->get_stylesheet_directory() ) ); ?></p> 
     175                        <?php endif; ?> 
     176                        <?php 
     177                        if ( $theme->get('Tags') ) 
     178                                printf( '<p>' . __( 'Tags: %s.' ) . '</p>', $theme->display('Tags') ); 
     179                        ?> 
     180                        </div> 
     181                        <?php theme_update_available( $theme ); ?> 
     182                        </div> 
     183                <?php 
     184                } 
    190185        } 
    191186 
    192187        function search_theme( $theme ) { 
    193                 $matched = 0; 
     188                // Search the features 
     189                if ( $this->features ) { 
     190                        foreach ( $this->features as $word ) { 
     191                                if ( ! in_array( $word, $theme->get('Tags') ) ) 
     192                                        return false; 
     193                        } 
     194                } 
    194195 
    195196                // Match all phrases 
    196                 if ( count( $this->search ) > 0 ) { 
     197                if ( $this->search ) { 
    197198                        foreach ( $this->search as $word ) { 
    198                                 $matched = 0; 
     199                                if ( in_array( $word, $theme->get('Tags') ) ) 
     200                                        continue; 
    199201 
    200                                 // In a tag? 
    201                                 if ( in_array( $word, array_map( 'sanitize_title_with_dashes', $theme['Tags'] ) ) ) 
    202                                         $matched = 1; 
    203  
    204                                 // In one of the fields? 
    205                                 foreach ( array( 'Name', 'Title', 'Description', 'Author', 'Template', 'Stylesheet' ) AS $field ) { 
    206                                         if ( stripos( $theme[$field], $word ) !== false ) 
    207                                                 $matched++; 
     202                                foreach ( array( 'Name', 'Description', 'Author', 'AuthorURI' ) as $header ) { 
     203                                        // Don't mark up; Do translate. 
     204                                        if ( false !== stripos( $theme->display( $header, false, true ), $word ) ) 
     205                                                continue 2; 
    208206                                } 
    209207 
    210                                 if ( $matched == 0 ) 
    211                                         return false; 
    212                         } 
    213                 } 
     208                                if ( false !== stripos( $theme->get_stylesheet(), $word ) ) 
     209                                        continue; 
    214210 
    215                 // Now search the features 
    216                 if ( count( $this->features ) > 0 ) { 
    217                         foreach ( $this->features as $word ) { 
    218                                 // In a tag? 
    219                                 if ( !in_array( $word, array_map( 'sanitize_title_with_dashes', $theme['Tags'] ) ) ) 
    220                                         return false; 
     211                                if ( false !== stripos( $theme->get_template(), $word ) ) 
     212                                        continue; 
     213 
     214                                return false; 
    221215                        } 
    222216                } 
    223217 
    224                 // Only get here if each word exists in the tags or one of the fields 
    225218                return true; 
    226219        } 
    227220} 
  • wp-admin/includes/ms.php

     
    169169        return true; 
    170170} 
    171171 
    172 function wpmu_get_blog_allowedthemes( $blog_id = 0 ) { 
    173         $themes = get_themes(); 
    174  
    175         if ( $blog_id != 0 ) 
    176                 switch_to_blog( $blog_id ); 
    177  
    178         $blog_allowed_themes = get_option( 'allowedthemes' ); 
    179         if ( !is_array( $blog_allowed_themes ) || empty( $blog_allowed_themes ) ) { // convert old allowed_themes to new allowedthemes 
    180                 $blog_allowed_themes = get_option( 'allowed_themes' ); 
    181  
    182                 if ( is_array( $blog_allowed_themes ) ) { 
    183                         foreach( (array) $themes as $key => $theme ) { 
    184                                 $theme_key = esc_html( $theme['Stylesheet'] ); 
    185                                 if ( isset( $blog_allowed_themes[$key] ) == true ) { 
    186                                         $blog_allowedthemes[$theme_key] = 1; 
    187                                 } 
    188                         } 
    189                         $blog_allowed_themes = $blog_allowedthemes; 
    190                         add_option( 'allowedthemes', $blog_allowed_themes ); 
    191                         delete_option( 'allowed_themes' ); 
    192                 } 
    193         } 
    194  
    195         if ( $blog_id != 0 ) 
    196                 restore_current_blog(); 
    197  
    198         return $blog_allowed_themes; 
    199 } 
    200  
    201172function update_option_new_admin_email( $old_value, $value ) { 
    202173        $email = get_option( 'admin_email' ); 
    203174        if ( $value == get_option( 'admin_email' ) || !is_email( $value ) ) 
     
    296267} 
    297268add_action( 'admin_notices', 'new_user_email_admin_notice' ); 
    298269 
    299 function get_site_allowed_themes() { 
    300         $themes = get_themes(); 
    301         $allowed_themes = get_site_option( 'allowedthemes' ); 
    302         if ( !is_array( $allowed_themes ) || empty( $allowed_themes ) ) { 
    303                 $allowed_themes = get_site_option( 'allowed_themes' ); // convert old allowed_themes format 
    304                 if ( !is_array( $allowed_themes ) ) { 
    305                         $allowed_themes = array(); 
    306                 } else { 
    307                         foreach( (array) $themes as $key => $theme ) { 
    308                                 $theme_key = esc_html( $theme['Stylesheet'] ); 
    309                                 if ( isset( $allowed_themes[ $key ] ) == true ) { 
    310                                         $allowedthemes[ $theme_key ] = 1; 
    311                                 } 
    312                         } 
    313                         $allowed_themes = $allowedthemes; 
    314                 } 
    315         } 
    316         return $allowed_themes; 
    317 } 
    318  
    319270/** 
    320271 * Determines if there is any upload space left in the current blog's quota. 
    321272 * 
  • wp-admin/themes.php

     
    9696<h2><?php echo esc_html( $title ); ?> 
    9797<?php endif; ?> 
    9898</h2> 
    99  
    100 <h3><?php _e('Current Theme'); ?></h3> 
     99<?php $ct = wp_get_theme(); ?> 
     100<h3><?php _e( 'Current Theme' ); ?></h3> 
    101101<div id="current-theme"> 
    102 <?php if ( $ct->screenshot ) : ?> 
    103 <img src="<?php echo $ct->theme_root_uri . '/' . $ct->stylesheet . '/' . $ct->screenshot; ?>" alt="<?php esc_attr_e('Current theme preview'); ?>" /> 
     102<?php if ( $ct->get_screenshot() ) : ?> 
     103<img src="<?php echo $ct->get_screenshot( 'absolute' ); ?>" alt="<?php esc_attr_e( 'Current theme preview'); ?>" /> 
    104104<?php endif; ?> 
    105105<h4><?php 
    106106        /* translators: 1: theme title, 2: theme version, 3: theme author */ 
    107         printf(__('%1$s %2$s by %3$s'), $ct->title, $ct->version, $ct->author) ; ?></h4> 
    108 <p class="theme-description"><?php echo $ct->description; ?></p> 
     107        printf( __( '%1$s %2$s by %3$s' ), $ct->display('Name'), $ct->display('Version'), $ct->display('Author') ) ; ?></h4> 
     108<p class="theme-description"><?php echo $ct->display('Description'); ?></p> 
    109109<div class="theme-options"> 
    110110        <span><?php _e( 'Options:' )?></span> 
    111111        <?php 
     
    117117                        if ( 'themes.php' == $item[2] || 'theme-editor.php' == $item[2] ) 
    118118                                continue; 
    119119                        // 0 = name, 1 = capability, 2 = file 
    120                         if ( ( strcmp($self, $item[2]) == 0 && empty($parent_file)) || ($parent_file && ($item[2] == $parent_file)) ) $class = ' class="current"'; 
    121  
     120                        if ( ( strcmp($self, $item[2]) == 0 && empty($parent_file)) || ($parent_file && ($item[2] == $parent_file)) ) 
     121                                $class = ' class="current"'; 
    122122                        if ( !empty($submenu[$item[2]]) ) { 
    123123                                $submenu[$item[2]] = array_values($submenu[$item[2]]); // Re-index. 
    124124                                $menu_hook = get_plugin_page_hook($submenu[$item[2]][0][2], $item[2]); 
     
    137137        } 
    138138        echo implode ( ' | ', $options ); 
    139139 
    140         if ( $ct->tags ) : ?> 
    141         <p><?php _e('Tags:'); ?> <?php echo join(', ', $ct->tags); ?></p> 
     140        if ( $ct->get('Tags') ) : ?> 
     141        <p><?php _e('Tags:'); ?> <?php echo $ct->display('Tags'); ?></p> 
    142142        <?php endif; ?> 
    143143</div> 
    144144<?php theme_update_available($ct); ?> 
     
    218218 
    219219<?php 
    220220// List broken themes, if any. 
    221 $broken_themes = get_broken_themes(); 
    222 if ( current_user_can('edit_themes') && count( $broken_themes ) ) { 
     221if ( current_user_can('edit_themes') && $broken_themes = wp_get_themes( array( 'errors' => true ) ) ) { 
    223222?> 
    224223 
    225224<h3><?php _e('Broken Themes'); ?></h3> 
     
    231230                <th><?php _e('Description'); ?></th> 
    232231        </tr> 
    233232<?php 
    234         $theme = ''; 
    235  
    236         $theme_names = array_keys($broken_themes); 
    237         natcasesort($theme_names); 
    238  
    239         foreach ($theme_names as $theme_name) { 
    240                 $name = $broken_themes[$theme_name]['Title']; 
    241                 $description = $broken_themes[$theme_name]['Description']; 
    242  
    243                 $theme = ('class="alternate"' == $theme) ? '' : 'class="alternate"'; 
     233        $alt = ''; 
     234        foreach ( $broken_themes as $broken_theme ) { 
     235                $alt = ('class="alternate"' == $alt) ? '' : 'class="alternate"'; 
    244236                echo " 
    245                 <tr $theme> 
    246                          <td>$name</td> 
    247                          <td>$description</td> 
     237                <tr $alt> 
     238                         <td>" . $broken_theme->get('Name') ."</td> 
     239                         <td>" . $broken_theme->errors()->get_error_message() . "</td> 
    248240                </tr>"; 
    249241        } 
    250242?> 
     
    254246?> 
    255247</div> 
    256248 
    257 <?php require('./admin-footer.php'); ?> 
     249<?php require('./admin-footer.php'); ?> 
     250 No newline at end of file