WordPress.org

Make WordPress Core

Ticket #10467: register_theme_directory-005.diff

File register_theme_directory-005.diff, 18.7 KB (added by markjaquith, 11 years ago)
  • wp-includes/theme.php

     
    3434 */
    3535function get_stylesheet_directory() {
    3636        $stylesheet = get_stylesheet();
    37         $stylesheet_dir = get_theme_root() . "/$stylesheet";
    38         return apply_filters('stylesheet_directory', $stylesheet_dir, $stylesheet);
     37        $theme_root = get_theme_root( $stylesheet );
     38        $stylesheet_dir = "$theme_root/$stylesheet";
     39
     40        return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root );
    3941}
    4042
    4143/**
     
    4749 */
    4850function get_stylesheet_directory_uri() {
    4951        $stylesheet = get_stylesheet();
    50         $stylesheet_dir_uri = get_theme_root_uri() . "/$stylesheet";
    51         return apply_filters('stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet);
     52        $theme_root_uri = get_theme_root_uri( $stylesheet );
     53        $stylesheet_dir_uri = "$theme_root_uri/$stylesheet";
     54
     55        return apply_filters( 'stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet, $theme_root_uri );
    5256}
    5357
    5458/**
     
    123127 */
    124128function get_template_directory() {
    125129        $template = get_template();
    126         $template_dir = get_theme_root() . "/$template";
    127         return apply_filters('template_directory', $template_dir, $template);
     130        $theme_root = get_theme_root( $template );
     131        $template_dir = "$theme_root/$template";
     132               
     133        return apply_filters( 'template_directory', $template_dir, $template, $theme_root );
    128134}
    129135
    130136/**
     
    137143 */
    138144function get_template_directory_uri() {
    139145        $template = get_template();
    140         $template_dir_uri = get_theme_root_uri() . "/$template";
    141         return apply_filters('template_directory_uri', $template_dir_uri, $template);
     146        $theme_root_uri = get_theme_root_uri( $template );
     147        $template_dir_uri = "$theme_root_uri/$template";
     148       
     149        return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri );
    142150}
    143151
    144152/**
     
    253261        if ( isset($wp_themes) )
    254262                return $wp_themes;
    255263
    256         $themes = array();
    257         $wp_broken_themes = array();
    258         $theme_loc = $theme_root = get_theme_root();
    259         if ( '/' != WP_CONTENT_DIR ) // don't want to replace all forward slashes, see Trac #4541
    260                 $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root);
     264        /* Register wp-content/themes as a theme directory */
     265        register_theme_directory( 'themes' );
    261266
    262         // Files in wp-content/themes directory and one subdir down
    263         $themes_dir = @ opendir($theme_root);
    264         if ( !$themes_dir )
     267        if ( !$theme_files = search_theme_directories() )
    265268                return false;
     269       
     270        asort( $theme_files );
     271       
     272        foreach ( (array) $theme_files as $theme_file ) {
     273                $theme_root = $theme_file['theme_root'];
     274                $theme_file = $theme_file['theme_file'];
    266275
    267         while ( ($theme_dir = readdir($themes_dir)) !== false ) {
    268                 if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) {
    269                         if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
    270                                 continue;
    271                         $stylish_dir = @ opendir($theme_root . '/' . $theme_dir);
    272                         $found_stylesheet = false;
    273                         while ( ($theme_file = readdir($stylish_dir)) !== false ) {
    274                                 if ( $theme_file == 'style.css' ) {
    275                                         $theme_files[] = $theme_dir . '/' . $theme_file;
    276                                         $found_stylesheet = true;
    277                                         break;
    278                                 }
    279                         }
    280                         @closedir($stylish_dir);
    281                         if ( !$found_stylesheet ) { // look for themes in that dir
    282                                 $subdir = "$theme_root/$theme_dir";
    283                                 $subdir_name = $theme_dir;
    284                                 $theme_subdir = @ opendir( $subdir );
    285                                 while ( ($theme_dir = readdir($theme_subdir)) !== false ) {
    286                                         if ( is_dir( $subdir . '/' . $theme_dir) && is_readable($subdir . '/' . $theme_dir) ) {
    287                                                 if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
    288                                                         continue;
    289                                                 $stylish_dir = @ opendir($subdir . '/' . $theme_dir);
    290                                                 $found_stylesheet = false;
    291                                                 while ( ($theme_file = readdir($stylish_dir)) !== false ) {
    292                                                         if ( $theme_file == 'style.css' ) {
    293                                                                 $theme_files[] = $subdir_name . '/' . $theme_dir . '/' . $theme_file;
    294                                                                 $found_stylesheet = true;
    295                                                                 break;
    296                                                         }
    297                                                 }
    298                                                 @closedir($stylish_dir);
    299                                         }
    300                                 }
    301                                 @closedir($theme_subdir);
    302                                 $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.'));
    303                         }
    304                 }
    305         }
    306         if ( is_dir( $theme_dir ) )
    307                 @closedir( $theme_dir );
    308 
    309         if ( !$themes_dir || !$theme_files )
    310                 return $themes;
    311 
    312         sort($theme_files);
    313 
    314         foreach ( (array) $theme_files as $theme_file ) {
    315276                if ( !is_readable("$theme_root/$theme_file") ) {
    316277                        $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.'));
    317278                        continue;
     
    346307                        else
    347308                                continue;
    348309                }
     310               
     311                $template = trim( $template );
    349312
    350                 $template = trim($template);
    351 
    352313                if ( !file_exists("$theme_root/$template/index.php") ) {
    353314                        $parent_dir = dirname(dirname($theme_file));
    354315                        if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) {
    355                                 $template = "$parent_dir/$template";
     316                                $template = "$theme_root/$parent_dir/$template";
    356317                        } else {
    357                                 $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'));
    358                                 continue;
     318                                /** 
     319                                 * The parent theme doesn't exist in the current theme's folder or sub folder
     320                                 * so lets use the theme root for the parent template.
     321                                 */
     322                                $parent_theme_root = $theme_files[$template]['theme_root'];
     323                                if ( file_exists( "$parent_theme_root/$template/index.php" ) ) {
     324                                        $template = "$parent_theme_root/$template";
     325                                } else {
     326                                        $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'));
     327                                        continue;
     328                                }
     329                               
    359330                        }
     331                } else {
     332                        $template = trim( $theme_root . '/' . $template );
    360333                }
    361 
     334               
    362335                $stylesheet_files = array();
    363336                $template_files = array();
    364337
     
    367340                        while ( ($file = $stylesheet_dir->read()) !== false ) {
    368341                                if ( !preg_match('|^\.+$|', $file) ) {
    369342                                        if ( preg_match('|\.css$|', $file) )
    370                                                 $stylesheet_files[] = "$theme_loc/$stylesheet/$file";
     343                                                $stylesheet_files[] = "$theme_root/$stylesheet/$file";
    371344                                        elseif ( preg_match('|\.php$|', $file) )
    372                                                 $template_files[] = "$theme_loc/$stylesheet/$file";
     345                                                $template_files[] = "$theme_root/$stylesheet/$file";
    373346                                }
    374347                        }
    375348                        @ $stylesheet_dir->close();
    376349                }
    377350
    378                 $template_dir = @ dir("$theme_root/$template");
     351                $template_dir = @ dir("$template");
    379352                if ( $template_dir ) {
    380353                        while ( ($file = $template_dir->read()) !== false ) {
    381354                                if ( preg_match('|^\.+$|', $file) )
    382355                                        continue;
    383356                                if ( preg_match('|\.php$|', $file) ) {
    384                                         $template_files[] = "$theme_loc/$template/$file";
    385                                 } elseif ( is_dir("$theme_root/$template/$file") ) {
    386                                         $template_subdir = @ dir("$theme_root/$template/$file");
     357                                        $template_files[] = "$template/$file";
     358                                } elseif ( is_dir("$template/$file") ) {
     359                                        $template_subdir = @ dir("$template/$file");
    387360                                        while ( ($subfile = $template_subdir->read()) !== false ) {
    388361                                                if ( preg_match('|^\.+$|', $subfile) )
    389362                                                        continue;
    390363                                                if ( preg_match('|\.php$|', $subfile) )
    391                                                         $template_files[] = "$theme_loc/$template/$file/$subfile";
     364                                                        $template_files[] = "$template/$file/$subfile";
    392365                                        }
    393366                                        @ $template_subdir->close();
    394367                                }
     
    422395                        }
    423396                }
    424397
    425                 $themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Stylesheet' => $stylesheet, 'Template Files' => $template_files, 'Stylesheet Files' => $stylesheet_files, 'Template Dir' => $template_dir, 'Stylesheet Dir' => $stylesheet_dir, 'Status' => $theme_data['Status'], 'Screenshot' => $screenshot, 'Tags' => $theme_data['Tags']);
     398                $theme_roots[$stylesheet] = str_replace( WP_CONTENT_DIR, '', $theme_root );
     399                $themes[$name] = array( 'Name' => $name, 'Title' => $title, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => basename( $template ), 'Stylesheet' => $stylesheet, 'Template Files' => $template_files, 'Stylesheet Files' => $stylesheet_files, 'Template Dir' => $template_dir, 'Stylesheet Dir' => $stylesheet_dir, 'Status' => $theme_data['Status'], 'Screenshot' => $screenshot, 'Tags' => $theme_data['Tags'], 'Theme Root' => $theme_root, 'Theme Root URI' => str_replace( WP_CONTENT_DIR, content_url(), $theme_root ) );
    426400        }
    427401
    428         // Resolve theme dependencies.
    429         $theme_names = array_keys($themes);
     402        /* Resolve theme dependencies. */
     403        $theme_names = array_keys( $themes );
    430404
     405        /* Store theme roots in the DB */
     406        if ( get_transient( 'theme_roots' ) != $theme_roots )
     407                set_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours
     408
    431409        foreach ( (array) $theme_names as $theme_name ) {
    432410                $themes[$theme_name]['Parent Theme'] = '';
    433411                if ( $themes[$theme_name]['Stylesheet'] != $themes[$theme_name]['Template'] ) {
     
    441419        }
    442420
    443421        $wp_themes = $themes;
    444 
     422       
    445423        return $themes;
    446424}
    447425
    448426/**
     427 * Retrieve theme roots.
     428 *
     429 * @since 2.9.0
     430 *
     431 * @return array Theme roots
     432 */
     433function get_theme_roots() {
     434        $theme_roots = get_transient( 'theme_roots' );
     435        if ( false === $theme_roots ) {
     436                get_themes();
     437                $theme_roots = get_transient( 'theme_roots' ); // this is set in get_theme()
     438        }
     439        return $theme_roots;
     440}
     441
     442/**
    449443 * Retrieve theme data.
    450444 *
    451445 * @since 1.5.0
     
    499493}
    500494
    501495/**
     496 * Register a directory that contains themes relative to the content directory.
     497 *
     498 * @since 2.9.0
     499 *
     500 * @return bool
     501 */
     502function register_theme_directory( $directory ) {
     503        global $wp_theme_directories;
     504       
     505        /* The theme directory should be relative to the content directory */
     506        $registered_directory = WP_CONTENT_DIR . '/' . $directory;
     507       
     508        /* If this folder does not exist, return and do not register */
     509        if ( !file_exists( $registered_directory ) )
     510                return false;
     511       
     512        $wp_theme_directories[] = $registered_directory;
     513       
     514        return true;
     515}
     516
     517/**
     518 * Search all registered theme directories for complete and valid themes.
     519 *
     520 * @since 2.9.0
     521 *
     522 * @return array Valid themes found
     523 */
     524function search_theme_directories() {
     525        global $wp_theme_directories, $wp_broken_themes;
     526       
     527        if ( empty( $wp_theme_directories ) )
     528                return false;
     529
     530        $theme_files = array();
     531        $wp_broken_themes = array();
     532
     533        /* Loop the registered theme directories and extract all themes */
     534        foreach ( (array) $wp_theme_directories as $theme_root ) {
     535                $theme_loc = $theme_root;
     536               
     537                /* We don't want to replace all forward slashes, see Trac #4541 */
     538                if ( '/' != WP_CONTENT_DIR )
     539                        $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root);
     540
     541                /* Files in the root of the current theme directory and one subdir down */
     542                $themes_dir = @ opendir($theme_root);
     543
     544                if ( !$themes_dir )
     545                        return false;
     546
     547                while ( ($theme_dir = readdir($themes_dir)) !== false ) {
     548                        if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) {
     549                                if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
     550                                        continue;
     551
     552                                $stylish_dir = @ opendir($theme_root . '/' . $theme_dir);
     553                                $found_stylesheet = false;
     554                               
     555                                while ( ($theme_file = readdir($stylish_dir)) !== false ) {
     556                                        if ( $theme_file == 'style.css' ) {
     557                                                $theme_files[$theme_dir] = array( 'theme_file' => $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root );
     558                                                $found_stylesheet = true;
     559                                                break;
     560                                        }
     561                                }
     562                                @closedir($stylish_dir);
     563                               
     564                                if ( !$found_stylesheet ) { // look for themes in that dir
     565                                        $subdir = "$theme_root/$theme_dir";
     566                                        $subdir_name = $theme_dir;
     567                                        $theme_subdir = @ opendir( $subdir );
     568                                       
     569                                        while ( ($theme_dir = readdir($theme_subdir)) !== false ) {
     570                                                if ( is_dir( $subdir . '/' . $theme_dir) && is_readable($subdir . '/' . $theme_dir) ) {
     571                                                        if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
     572                                                                continue;
     573                                                               
     574                                                        $stylish_dir = @ opendir($subdir . '/' . $theme_dir);
     575                                                        $found_stylesheet = false;
     576                                                       
     577                                                        while ( ($theme_file = readdir($stylish_dir)) !== false ) {
     578                                                                if ( $theme_file == 'style.css' ) {
     579                                                                        $theme_files[$theme_dir] = array( 'theme_file' => $subdir_name . '/' . $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root );
     580                                                                        $found_stylesheet = true;
     581                                                                        break;
     582                                                                }
     583                                                        }
     584                                                        @closedir($stylish_dir);
     585                                                }
     586                                        }
     587                                        @closedir($theme_subdir);
     588                                       
     589                                        $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.'));
     590                                }
     591                        }
     592                }
     593                if ( is_dir( $theme_dir ) )
     594                        @closedir( $theme_dir );
     595        }
     596       
     597        return $theme_files;
     598}
     599
     600/**
    502601 * Retrieve path to themes directory.
    503602 *
    504603 * Does not have trailing slash.
    505604 *
    506605 * @since 1.5.0
     606 * @param $stylesheet_or_template The stylesheet or template name of the theme
    507607 * @uses apply_filters() Calls 'theme_root' filter on path.
    508608 *
    509609 * @return string Theme path.
    510610 */
    511 function get_theme_root() {
    512         return apply_filters('theme_root', WP_CONTENT_DIR . "/themes");
     611function get_theme_root( $stylesheet_or_template = false ) {
     612        $theme_roots = get_theme_roots();
     613       
     614        if ( $theme_roots[$stylesheet_or_template] )
     615                $theme_root = WP_CONTENT_DIR . '/' . $theme_roots[$stylesheet_or_template];
     616        else
     617                $theme_root = WP_CONTENT_DIR . '/themes';
     618
     619        return apply_filters( 'theme_root', $theme_root );
    513620}
    514621
    515622/**
     
    518625 * Does not have trailing slash.
    519626 *
    520627 * @since 1.5.0
     628 * @param $stylesheet_or_template The stylesheet or template name of the theme
    521629 *
    522630 * @return string Themes URI.
    523631 */
    524 function get_theme_root_uri() {
    525         return apply_filters('theme_root_uri', content_url('themes'), get_option('siteurl'));
     632function get_theme_root_uri( $stylesheet_or_template = false ) {
     633        $theme_roots = get_theme_roots();
     634       
     635        if ( $theme_roots[$stylesheet_or_template] )
     636                $theme_root_uri = content_url( $theme_roots[$stylesheet_or_template] );
     637        else
     638                $theme_root_uri = content_url( 'themes' );
     639
     640        return apply_filters( 'theme_root_uri', $theme_root_uri, get_option('siteurl'), $stylesheet_or_template );
    526641}
    527642
    528643/**
  • wp-admin/includes/theme.php

     
    2828        $ct->description = $themes[$current_theme]['Description'];
    2929        $ct->author = $themes[$current_theme]['Author'];
    3030        $ct->tags = $themes[$current_theme]['Tags'];
     31        $ct->theme_root = $themes[$current_theme]['Theme Root'];
     32        $ct->theme_root_uri = $themes[$current_theme]['Theme Root URI'];
    3133        return $ct;
    3234}
    3335
  • wp-admin/themes.php

     
    132132<h3><?php _e('Current Theme'); ?></h3>
    133133<div id="current-theme">
    134134<?php if ( $ct->screenshot ) : ?>
    135 <img src="<?php echo content_url($ct->stylesheet_dir . '/' . $ct->screenshot); ?>" alt="<?php _e('Current theme preview'); ?>" />
     135<img src="<?php echo $ct->theme_root_uri . '/' . $ct->stylesheet . '/' . $ct->screenshot; ?>" alt="<?php _e('Current theme preview'); ?>" />
    136136<?php endif; ?>
    137137<h4><?php
    138138        /* translators: 1: theme title, 2: theme version, 3: theme author */
    139139        printf(__('%1$s %2$s by %3$s'), $ct->title, $ct->version, $ct->author) ; ?></h4>
    140140<p class="theme-description"><?php echo $ct->description; ?></p>
    141141<?php if ($ct->parent_theme) { ?>
    142         <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.'), $ct->title, $ct->template_dir, $ct->stylesheet_dir, $ct->title, $ct->parent_theme); ?></p>
     142        <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.'), $ct->title, str_replace( WP_CONTENT_DIR, '', $ct->template_dir ), str_replace( WP_CONTENT_DIR, '', $ct->stylesheet_dir ), $ct->title, $ct->parent_theme); ?></p>
    143143<?php } else { ?>
    144         <p><?php printf(__('All of this theme&#8217;s files are located in <code>%2$s</code>.'), $ct->title, $ct->template_dir, $ct->stylesheet_dir); ?></p>
     144        <p><?php printf(__('All of this theme&#8217;s files are located in <code>%2$s</code>.'), $ct->title, str_replace( WP_CONTENT_DIR, '', $ct->template_dir ), str_replace( WP_CONTENT_DIR, '', $ct->stylesheet_dir ) ); ?></p>
    145145<?php } ?>
    146146<?php if ( $ct->tags ) : ?>
    147147<p><?php _e('Tags:'); ?> <?php echo join(', ', $ct->tags); ?></p>
     
    203203        $stylesheet_dir = $themes[$theme_name]['Stylesheet Dir'];
    204204        $template_dir = $themes[$theme_name]['Template Dir'];
    205205        $parent_theme = $themes[$theme_name]['Parent Theme'];
     206        $theme_root = $themes[$theme_name]['Theme Root'];
     207        $theme_root_uri = $themes[$theme_name]['Theme Root URI'];
    206208        $preview_link = esc_url(get_option('home') . '/');
    207209        if ( is_ssl() )
    208210                $preview_link = str_replace( 'http://', 'https://', $preview_link );
     
    223225?>
    224226                <a href="<?php echo $preview_link; ?>" class="<?php echo $thickbox_class; ?> screenshot">
    225227<?php if ( $screenshot ) : ?>
    226                         <img src="<?php echo content_url($stylesheet_dir . '/' . $screenshot); ?>" alt="" />
     228                        <img src="<?php echo $theme_root_uri . '/' . $stylesheet . '/' . $screenshot; ?>" alt="" />
    227229<?php endif; ?>
    228230                </a>
    229231<h3><?php
     
    233235<span class='action-links'><?php echo $actions ?></span>
    234236        <?php if ($parent_theme) {
    235237        /* translators: 1: theme title, 2:  template dir, 3: stylesheet_dir, 4: theme title, 5: parent_theme */ ?>
    236         <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, $template_dir, $stylesheet_dir, $title, $parent_theme); ?></p>
     238        <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>
    237239<?php } else { ?>
    238         <p><?php printf(__('All of this theme&#8217;s files are located in <code>%2$s</code>.'), $title, $template_dir, $stylesheet_dir); ?></p>
     240        <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>
    239241<?php } ?>
    240242<?php if ( $tags ) : ?>
    241243<p><?php _e('Tags:'); ?> <?php echo join(', ', $tags); ?></p>