WordPress.org

Make WordPress Core

Ticket #20103: 20103.3.diff

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

     
    77 */ 
    88 
    99/** 
     10 * Returns an array of WP_Theme objects based on the arguments. 
     11 * 
     12 * Despite advances over get_themes(), this function is still quite expensive, and grows 
     13 * linearly with additional themes. Stick to wp_get_theme() if possible. 
     14 * 
     15 * @since 3.4.0 
     16 * 
     17 * @param array $args Arguments. Currently 'errors' (defaults to false), 'allowed' 
     18 *      (true, false; null for either; defaults to null; only applies to multisite), and 'blog_id' 
     19 *      (defaults to current blog; used to find allowed themes; only applies to multisite). 
     20 * @return Array of WP_Theme objects. 
     21 */ 
     22function wp_get_themes( $args = array() ) { 
     23        $defaults = array( 'errors' => false, 'allowed' => null, 'blog_id' => 0 ); 
     24        $args = wp_parse_args( $args, $defaults ); 
     25 
     26        static $_themes; 
     27        if ( ! isset( $_themes ) ) { 
     28                $theme_data = search_theme_directories(); 
     29                // Make sure the current theme wins out, in case search_theme_directories() picks the wrong 
     30                // one in the case of a conflict. (Normally, last registered theme root wins.) 
     31                $current_theme = get_stylesheet(); 
     32                $current_theme_root = get_raw_theme_root( $current_theme ); 
     33                foreach ( $theme_data as $theme_slug => $data ) { 
     34                        if ( $current_theme == $theme_slug && $current_theme_root != $data['theme_root'] ) 
     35                                $_themes[ $theme_slug ] = new WP_Theme( $theme_slug, $current_theme_root ); 
     36                        else 
     37                                $_themes[ $theme_slug ] = new WP_Theme( $theme_slug, $data['theme_root'] ); 
     38                } 
     39        } 
     40 
     41        $themes = $_themes; 
     42 
     43        if ( null !== $args['errors'] ) { 
     44                foreach ( $themes as $theme_slug => $theme ) { 
     45                        if ( $theme->errors() != $args['errors'] ) 
     46                                unset( $themes[ $theme_slug ] ); 
     47                } 
     48        } 
     49 
     50        if ( is_multisite() && null !== $args['allowed'] ) { 
     51                if ( $allowed = $args['allowed'] ) { 
     52                        $allowed = 'network' == $allowed || 'site' == $allowed ? $allowed : 'both'; 
     53                        $themes = array_intersect_key( $themes, WP_Theme::get_allowed( $allowed, $args['blog_id'] ) ); 
     54                } else { 
     55                        $themes = array_diff_key( $themes, WP_Theme::get_allowed( 'both', $args['blog_id'] ) ); 
     56                } 
     57        } 
     58 
     59        return $themes; 
     60} 
     61 
     62/** 
     63 * Gets a WP_Theme object for a theme. 
     64 * 
     65 * @since 3.4.0 
     66 * 
     67 * @param string $stylesheet Directory name for the theme. Optional. Defaults to current theme. 
     68 * @param string $theme_root Theme root to look in. Optional. If not specified, get_raw_theme_root() 
     69 *      is used for the $stylesheet provided (or current theme). 
     70 * @return WP_Theme 
     71 */ 
     72function wp_get_theme( $stylesheet = null, $theme_root = null ) { 
     73        if ( empty( $stylesheet ) ) 
     74                $stylesheet = get_stylesheet(); 
     75 
     76        if ( empty( $theme_root ) ) 
     77                $theme_root = get_raw_theme_root( $stylesheet ); 
     78 
     79        return new WP_Theme( $stylesheet, $theme_root ); 
     80} 
     81 
     82/** 
    1083 * Whether a child theme is in use. 
    1184 * 
    1285 * @since 3.0.0 
     
    247320} 
    248321 
    249322/** 
    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 /** 
    468323 * Retrieve theme roots. 
    469324 * 
    470325 * @since 2.9.0 
     
    479334 
    480335        $theme_roots = get_site_transient( 'theme_roots' ); 
    481336        if ( false === $theme_roots ) { 
    482                 get_themes(); 
    483                 $theme_roots = get_site_transient( 'theme_roots' ); // this is set in get_theme() 
     337                search_theme_directories(); // Regenerated the transient. 
     338                $theme_roots = get_site_transient( 'theme_roots' ); 
    484339        } 
    485340        return $theme_roots; 
    486341} 
    487342 
    488343/** 
    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 /** 
    506344 * Retrieve current theme display name. 
    507345 * 
    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  * 
    512346 * @since 1.5.0 
    513347 * 
    514348 * @return string 
    515349 */ 
    516350function 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; 
     351        $theme = wp_get_theme(); 
     352        return $theme->get('Name'); 
    540353} 
    541354 
    542355/** 
     
    571384 * @return array Valid themes found 
    572385 */ 
    573386function search_theme_directories() { 
    574         global $wp_theme_directories, $wp_broken_themes; 
     387        global $wp_theme_directories; 
    575388        if ( empty( $wp_theme_directories ) ) 
    576389                return false; 
    577390 
    578         $theme_files = array(); 
    579         $wp_broken_themes = array(); 
     391        static $found_themes; 
     392        if ( isset( $found_themes ) ) 
     393                return $found_themes; 
     394        $found_themes = array(); 
    580395 
     396        if ( apply_filters( 'wp_cache_themes_persistently', false ) ) { 
     397                $cached_roots = get_site_transient( 'theme_roots' ); 
     398                if ( is_array( $cached_roots ) ) { 
     399                        foreach ( $cached_roots as $theme_dir => $theme_root ) { 
     400                                $found_themes[ $theme_dir ] = array( 
     401                                        'theme_file' => $theme_dir . '/style.css', 
     402                                        'theme_root' => $theme_root, 
     403                                ); 
     404                        } 
     405                        return $found_themes; 
     406                } 
     407        } 
     408 
    581409        /* Loop the registered theme directories and extract all themes */ 
    582410        foreach ( (array) $wp_theme_directories as $theme_root ) { 
    583                 $theme_loc = $theme_root; 
    584411 
    585                 /* We don't want to replace all forward slashes, see Trac #4541 */ 
    586                 if ( '/' != WP_CONTENT_DIR ) 
    587                         $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root); 
    588  
    589                 /* Files in the root of the current theme directory and one subdir down */ 
    590                 $themes_dir = @ opendir($theme_root); 
    591  
    592                 if ( !$themes_dir ) 
     412                // Start with directories in the root of the current theme directory. 
     413                $dirs = @ scandir( $theme_root ); 
     414                if ( ! $dirs ) 
    593415                        return false; 
    594  
    595                 while ( ($theme_dir = readdir($themes_dir)) !== false ) { 
    596                         if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) { 
    597                                 if ( $theme_dir[0] == '.' || $theme_dir == 'CVS' ) 
    598                                         continue; 
    599  
    600                                 $stylish_dir = @opendir($theme_root . '/' . $theme_dir); 
    601                                 $found_stylesheet = false; 
    602  
    603                                 while ( ($theme_file = readdir($stylish_dir)) !== false ) { 
    604                                         if ( $theme_file == 'style.css' ) { 
    605                                                 $theme_files[$theme_dir] = array( 'theme_file' => $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root ); 
    606                                                 $found_stylesheet = true; 
    607                                                 break; 
    608                                         } 
     416                foreach ( $dirs as $dir ) { 
     417                        if ( ! is_dir( $theme_root . '/' . $dir ) || $dir[0] == '.' || $dir == 'CVS' ) 
     418                                continue; 
     419                        if ( file_exists( $theme_root . '/' . $dir . '/style.css' ) ) { 
     420                                // wp-content/themes/a-single-theme 
     421                                // wp-content/themes is $theme_root, a-single-theme is $dir 
     422                                $found_themes[ $dir ] = array( 
     423                                        'theme_file' => $dir . '/style.css', 
     424                                        'theme_root' => $theme_root, 
     425                                ); 
     426                        } else { 
     427                                $found_theme = false; 
     428                                // wp-content/themes/a-folder-of-themes/* 
     429                                // wp-content/themes is $theme_root, a-folder-of-themes is $dir, then themes are $sub_dirs 
     430                                $sub_dirs = @ scandir( $theme_root . '/' . $dir ); 
     431                                if ( ! $sub_dirs ) 
     432                                        return false; 
     433                                foreach ( $sub_dirs as $sub_dir ) { 
     434                                        if ( ! is_dir( $theme_root . '/' . $dir ) || $dir[0] == '.' || $dir == 'CVS' ) 
     435                                                continue; 
     436                                        if ( ! file_exists( $theme_root . '/' . $dir . '/' . $sub_dir . '/style.css' ) ) 
     437                                                continue; 
     438                                        $found_themes[ $dir . '/' . $sub_dir ] = array( 
     439                                                'theme_file' => $dir . '/' . $sub_dir . '/style.css', 
     440                                                'theme_root' => $theme_root, 
     441                                        ); 
     442                                        $found_theme = true; 
    609443                                } 
    610                                 @closedir($stylish_dir); 
     444                                // Never mind the above, it's just a theme missing a style.css. 
     445                                // Return it; WP_Theme will catch the error. 
     446                                if ( ! $found_theme ) 
     447                                        $found_themes[ $dir ] = array( 
     448                                                'theme_file' => $dir . '/style.css', 
     449                                                'theme_root' => $theme_root, 
     450                                        ); 
     451                        } 
     452                } 
     453        } 
    611454 
    612                                 if ( !$found_stylesheet ) { // look for themes in that dir 
    613                                         $subdir = "$theme_root/$theme_dir"; 
    614                                         $subdir_name = $theme_dir; 
    615                                         $theme_subdirs = @opendir( $subdir ); 
     455        asort( $found_themes ); 
    616456 
    617                                         $found_subdir_themes = false; 
    618                                         while ( ($theme_subdir = readdir($theme_subdirs)) !== false ) { 
    619                                                 if ( is_dir( $subdir . '/' . $theme_subdir) && is_readable($subdir . '/' . $theme_subdir) ) { 
    620                                                         if ( $theme_subdir[0] == '.' || $theme_subdir == 'CVS' ) 
    621                                                                 continue; 
     457        $theme_roots = array(); 
     458        foreach ( $found_themes as $theme_dir => $theme_data ) { 
     459                $theme_roots[ $theme_dir ] = $theme_data['theme_root']; 
     460        } 
    622461 
    623                                                         $stylish_dir = @opendir($subdir . '/' . $theme_subdir); 
    624                                                         $found_stylesheet = false; 
     462        if ( $theme_roots != get_site_transient( 'theme_roots' ) ) 
     463                set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours 
    625464 
    626                                                         while ( ($theme_file = readdir($stylish_dir)) !== false ) { 
    627                                                                 if ( $theme_file == 'style.css' ) { 
    628                                                                         $theme_files["$theme_dir/$theme_subdir"] = array( 'theme_file' => $subdir_name . '/' . $theme_subdir . '/' . $theme_file, 'theme_root' => $theme_root ); 
    629                                                                         $found_stylesheet = true; 
    630                                                                         $found_subdir_themes = true; 
    631                                                                         break; 
    632                                                                 } 
    633                                                         } 
    634                                                         @closedir($stylish_dir); 
    635                                                 } 
    636                                         } 
    637                                         @closedir($theme_subdirs); 
    638                                         if ( !$found_subdir_themes ) 
    639                                                 $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.')); 
    640                                 } 
    641                         } 
    642                 } 
    643                 @closedir( $themes_dir ); 
    644         } 
    645         return $theme_files; 
     465        return $found_themes; 
    646466} 
    647467 
    648468/** 
  • 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 . '/template.php' ); 
    116117require( ABSPATH . WPINC . '/user.php' ); 
    117118require( ABSPATH . WPINC . '/meta.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

     
    459459        if ( $wp_current_db_version < 19389 ) 
    460460                upgrade_330(); 
    461461 
    462         if ( $wp_current_db_version < 19799 ) 
     462        if ( $wp_current_db_version < 20002 ) 
    463463                upgrade_340(); 
    464464 
    465465        maybe_disable_automattic_widgets(); 
     
    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 < 20002 && 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