Make WordPress Core


Ignore:
Timestamp:
03/29/2012 02:59:48 AM (13 years ago)
Author:
nacin
Message:

Introduce WP_Theme->exists() to check if the queried theme actually exists. WP_Theme->exists() is a subset of errors() -- a theme with errors may still exist, but a theme that does not exist has an error of theme_not_found. wp_get_theme() now returns false if the theme does not exist. Improve scandir() and get_files() logic. see #20103.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/class-wp-theme.php

    r20233 r20312  
    196196        } elseif ( ! file_exists( $this->theme_root . '/' . $theme_file ) ) {
    197197            $this->headers['Name'] = $this->stylesheet;
    198             $this->errors = new WP_Error( 'theme_no_stylesheet', __( 'Stylesheet is missing.' ) );
     198            if ( ! file_exists( $this->theme_root . '/' . $this->stylesheet ) )
     199                $this->errors = new WP_Error( 'theme_not_found', __( 'The theme directory does not exist.' ) );
     200            else
     201                $this->errors = new WP_Error( 'theme_no_stylesheet', __( 'Stylesheet is missing.' ) );
    199202            $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet ) );
    200203            if ( ! file_exists( $this->theme_root ) ) // Don't cache this one.
     
    385388                return $this->get_stylesheet();
    386389            case 'Template Files' :
    387                 $files = $this->get_files('php', true);
    388                 foreach ( $files as &$file )
    389                     $file = $this->theme_root . '/' . $file;
     390                $files = $this->get_files( 'php', 1 );
     391                if ( $this->parent() )
     392                    $files = array_merge( $files, $this->parent()->get_files( 'php', 1 ) );
    390393                return $files;
    391394            case 'Stylesheet Files' :
    392                 $files = $this->get_files('css', true);
    393                 foreach ( $files as &$file )
    394                     $file = $this->theme_root . '/' . $file;
     395                $files = $this->get_files( 'css' );
     396                if ( $this->parent() )
     397                    $files = array_merge( $files, $this->parent()->get_files( 'css' ) );
    395398                return $files;
    396399            case 'Template Dir' :
     
    426429
    427430    /**
     431     * Whether the theme exists.
     432     *
     433     * A theme with errors exists. A theme with the error of 'theme_not_found',
     434     * meaning that the theme directory was not found, does not exist.
     435     *
     436     * @since 3.4.0
     437     * @access public
     438     *
     439     * @return bool Whether the theme exists.
     440     */
     441    public function exists() {
     442        return ! ( is_wp_error( $this->errors ) && in_array( 'theme_not_found', $this->errors->get_error_codes() ) );
     443    }
     444
     445    /**
    428446     * Returns reference to the parent theme.
    429447     *
     
    475493     */
    476494    public function cache_delete() {
    477         foreach ( array( 'theme', 'screenshot', 'screenshot_count', 'files', 'headers' ) as $key )
     495        foreach ( array( 'theme', 'screenshot', 'screenshot_count', 'files', 'headers', 'page_templates' ) as $key )
    478496            wp_cache_delete( $key . '-' . $this->cache_hash, 'themes' );
    479497    }
     
    892910
    893911        $prefix = $this->get_stylesheet() . '/screenshot-';
    894         $files = self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet(), 'png', 0 );
     912        $files = self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet(), 'png' );
    895913
    896914        $screenshot_count = 1;
     
    926944
    927945    /**
    928      * Return files in the template and stylesheet directories.
     946     * Return files in the theme's directory. Does not return files found in the parent theme.
    929947     *
    930948     * @since 3.4.0
     
    935953     *  returns an array, with the keys being the file types, and the values being an array of files for those type.
    936954     */
    937     public function get_files( $type = null, $include_parent_files = false ) {
     955    public function get_files( $type = null, $depth = 0 ) {
    938956        $files = $this->cache_get( 'files' );
    939957        if ( ! is_array( $files ) ) {
    940             if ( $include_parent_files || ! $this->is_child_theme() )
    941                 // Template files can be one level down for the purposes of the theme editor, so this should be $depth = 1.
    942                 // Todo: We ignore this for now, but this is why the branching is weird.
    943                 $files = self::scandir( $this->get_template_directory(), $this->get_template(), array( 'php', 'css' ) );
    944             else
    945                 $files = array();
    946             if ( $this->is_child_theme() )
    947                 $files = array_merge_recursive( $files, (array) self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet(), array( 'php', 'css' ) ) );
     958            $files = (array) self::scandir( $this->get_stylesheet_directory(), array( 'php', 'css' ), $depth );
    948959            foreach ( $files as &$group )
    949                 sort( $group );
     960                ksort( $group );
     961            unset( $group );
    950962            $this->cache_add( 'files', $files );
    951963        }
     
    959971    }
    960972
     973    /**
     974     * Returns the theme's page templates.
     975     *
     976     * @since 3.4.0
     977     * @access public
     978     *
     979     * @return array Array of page templates, keyed by filename, with the value of the translated header name.
     980     */
    961981    public function get_page_templates() {
    962982        // If you screw up your current theme and we invalidate your parent, most things still work. Let it slide.
     
    969989        $page_templates = array();
    970990
    971         $files = (array) self::scandir( $this->get_template_directory(), $this->get_template_directory(), 'php' );
     991        $files = (array) self::scandir( $this->get_template_directory(), 'php' );
    972992        if ( $this->is_child_theme() )
    973             $files = array_merge_recursive( $files, (array) self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet_directory(), 'php' ) );
     993            $files = array_merge_recursive( $files, (array) self::scandir( $this->get_stylesheet_directory(), 'php' ) );
    974994
    975995        foreach ( $files['php'] as $file ) {
     
    9911011     *
    9921012     * @param string $path Absolute path to search.
     1013     * @param array|string $extensions Array of extensions to find, or string of a single extension
     1014     * @param int $depth How deep to search for files. Optional, defaults to a flat scan (0 depth). -1 depth is infinite.
    9931015     * @param string $relative_path The basename of the absolute path. Used to control the returned path
    9941016     *  for the found files, particularly when this function recurses to lower depths.
    995      * @param array|string $extensions Array of extensions to find, or string of a single extension.
    996      * @depth int How deep to search for files. Optional, defaults to a flat scan (0 depth).
    997      */
    998     private static function scandir( $path, $relative_path, $extensions, $depth = 0 ) {
     1017     */
     1018    private static function scandir( $path, $extensions, $depth = 1, $relative_path = '' ) {
    9991019        if ( ! is_dir( $path ) )
    10001020            return false;
     
    10041024        $extensions = (array) $extensions;
    10051025        $files = array_fill_keys( $extensions, array() );
    1006         $extensions = implode( '|', $extensions );
     1026        $_extensions = implode( '|', $extensions );
     1027
     1028        $relative_path = trailingslashit( $relative_path );
     1029        if ( '/' == $relative_path )
     1030            $relative_path = '';
    10071031
    10081032        foreach ( $results as $result ) {
    1009             if ( '.' == $result || '..' == $result )
     1033            if ( '.' == $result[0] )
    10101034                continue;
    10111035            if ( is_dir( $path . '/' . $result ) ) {
    1012                 if ( ! $depth )
     1036                if ( ! $depth || 'CVS' == $result )
    10131037                    continue;
    1014                 $found = self::scandir( $path . '/' . $result, $relative_path . '/' . $result, $extensions, $depth - 1 );
     1038                $found = self::scandir( $path . '/' . $result, $extensions, $depth - 1 , $relative_path . $result );
    10151039                $files = array_merge_recursive( $files, $found );
    1016             } elseif ( preg_match( '~\.(' . $extensions . ')$~', $result, $match ) ) {
    1017                 $files[ $match[1] ][] = $relative_path . '/' . $result;
     1040            } elseif ( preg_match( '~\.(' . $_extensions . ')$~', $result, $match ) ) {
     1041                $files[ $match[1] ][ $relative_path . $result ] = $path . '/' . $result;
    10181042            }
    10191043        }
     1044
    10201045        return $files;
    10211046    }
Note: See TracChangeset for help on using the changeset viewer.