WP_Theme::__construct( string $theme_dir, string $theme_root, WP_Theme|null $_child = null )

In this article

Constructor for WP_Theme.

Parameters

$theme_dirstringrequired
Directory of the theme within the theme_root.
$theme_rootstringrequired
Theme root.
$_childWP_Theme|nulloptional
If this theme is a parent theme, the child may be passed for validation purposes.

Default:null

Source

public function __construct( $theme_dir, $theme_root, $_child = null ) {	global $wp_theme_directories;	// Initialize caching on first run.	if ( ! isset( self::$persistently_cache ) ) {	/** This action is documented in wp-includes/theme.php */	self::$persistently_cache = apply_filters( 'wp_cache_themes_persistently', false, 'WP_Theme' );	if ( self::$persistently_cache ) {	wp_cache_add_global_groups( 'themes' );	if ( is_int( self::$persistently_cache ) ) {	self::$cache_expiration = self::$persistently_cache;	}	} else {	wp_cache_add_non_persistent_groups( 'themes' );	}	}	// Handle a numeric theme directory as a string.	$theme_dir = (string) $theme_dir;	$this->theme_root = $theme_root;	$this->stylesheet = $theme_dir;	// Correct a situation where the theme is 'some-directory/some-theme' but 'some-directory' was passed in as part of the theme root instead.	if ( ! in_array( $theme_root, (array) $wp_theme_directories, true )	&& in_array( dirname( $theme_root ), (array) $wp_theme_directories, true )	) {	$this->stylesheet = basename( $this->theme_root ) . '/' . $this->stylesheet;	$this->theme_root = dirname( $theme_root );	}	$this->cache_hash = md5( $this->theme_root . '/' . $this->stylesheet );	$theme_file = $this->stylesheet . '/style.css';	$cache = $this->cache_get( 'theme' );	if ( is_array( $cache ) ) {	foreach ( array( 'block_template_folders', 'block_theme', 'errors', 'headers', 'template' ) as $key ) {	if ( isset( $cache[ $key ] ) ) {	$this->$key = $cache[ $key ];	}	}	if ( $this->errors ) {	return;	}	if ( isset( $cache['theme_root_template'] ) ) {	$theme_root_template = $cache['theme_root_template'];	}	} elseif ( ! file_exists( $this->theme_root . '/' . $theme_file ) ) {	$this->headers['Name'] = $this->stylesheet;	if ( ! file_exists( $this->theme_root . '/' . $this->stylesheet ) ) {	$this->errors = new WP_Error(	'theme_not_found',	sprintf(	/* translators: %s: Theme directory name. */	__( 'The theme directory "%s" does not exist.' ),	esc_html( $this->stylesheet )	)	);	} else {	$this->errors = new WP_Error( 'theme_no_stylesheet', __( 'Stylesheet is missing.' ) );	}	$this->template = $this->stylesheet;	$this->block_theme = false;	$this->block_template_folders = $this->default_template_folders;	$this->cache_add(	'theme',	array(	'block_template_folders' => $this->block_template_folders,	'block_theme' => $this->block_theme,	'headers' => $this->headers,	'errors' => $this->errors,	'stylesheet' => $this->stylesheet,	'template' => $this->template,	)	);	if ( ! file_exists( $this->theme_root ) ) { // Don't cache this one.	$this->errors->add( 'theme_root_missing', __( '<strong>Error:</strong> The themes directory is either empty or does not exist. Please check your installation.' ) );	}	return;	} elseif ( ! is_readable( $this->theme_root . '/' . $theme_file ) ) {	$this->headers['Name'] = $this->stylesheet;	$this->errors = new WP_Error( 'theme_stylesheet_not_readable', __( 'Stylesheet is not readable.' ) );	$this->template = $this->stylesheet;	$this->block_theme = false;	$this->block_template_folders = $this->default_template_folders;	$this->cache_add(	'theme',	array(	'block_template_folders' => $this->block_template_folders,	'block_theme' => $this->block_theme,	'headers' => $this->headers,	'errors' => $this->errors,	'stylesheet' => $this->stylesheet,	'template' => $this->template,	)	);	return;	} else {	$this->headers = get_file_data( $this->theme_root . '/' . $theme_file, self::$file_headers, 'theme' );	/* * Default themes always trump their pretenders. * Properly identify default themes that are inside a directory within wp-content/themes. */	$default_theme_slug = array_search( $this->headers['Name'], self::$default_themes, true );	if ( $default_theme_slug ) {	if ( basename( $this->stylesheet ) !== $default_theme_slug ) {	$this->headers['Name'] .= '/' . $this->stylesheet;	}	}	}	if ( ! $this->template && $this->stylesheet === $this->headers['Template'] ) {	$this->errors = new WP_Error(	'theme_child_invalid',	sprintf(	/* translators: %s: Template. */	__( 'The theme defines itself as its parent theme. Please check the %s header.' ),	'<code>Template</code>'	)	);	$this->cache_add(	'theme',	array(	'block_template_folders' => $this->get_block_template_folders(),	'block_theme' => $this->is_block_theme(),	'headers' => $this->headers,	'errors' => $this->errors,	'stylesheet' => $this->stylesheet,	)	);	return;	}	// (If template is set from cache [and there are no errors], we know it's good.)	if ( ! $this->template ) {	$this->template = $this->headers['Template'];	}	if ( ! $this->template ) {	$this->template = $this->stylesheet;	$theme_path = $this->theme_root . '/' . $this->stylesheet;	if ( ! $this->is_block_theme() && ! file_exists( $theme_path . '/index.php' ) ) {	$error_message = sprintf(	/* translators: 1: templates/index.html, 2: index.php, 3: Documentation URL, 4: Template, 5: style.css */	__( 'Template is missing. Standalone themes need to have a %1$s or %2$s template file. <a href="%3$s">Child themes</a> need to have a %4$s header in the %5$s stylesheet.' ),	'<code>templates/index.html</code>',	'<code>index.php</code>',	__( 'https://developer.wordpress.org/themes/advanced-topics/child-themes/' ),	'<code>Template</code>',	'<code>style.css</code>'	);	$this->errors = new WP_Error( 'theme_no_index', $error_message );	$this->cache_add(	'theme',	array(	'block_template_folders' => $this->get_block_template_folders(),	'block_theme' => $this->block_theme,	'headers' => $this->headers,	'errors' => $this->errors,	'stylesheet' => $this->stylesheet,	'template' => $this->template,	)	);	return;	}	}	// If we got our data from cache, we can assume that 'template' is pointing to the right place.	if ( ! is_array( $cache )	&& $this->template !== $this->stylesheet	&& ! file_exists( $this->theme_root . '/' . $this->template . '/index.php' )	) {	/* * If we're in a directory of themes inside /themes, look for the parent nearby. * wp-content/themes/directory-of-themes/* */	$parent_dir = dirname( $this->stylesheet );	$directories = search_theme_directories();	if ( '.' !== $parent_dir	&& file_exists( $this->theme_root . '/' . $parent_dir . '/' . $this->template . '/index.php' )	) {	$this->template = $parent_dir . '/' . $this->template;	} elseif ( $directories && isset( $directories[ $this->template ] ) ) {	/* * Look for the template in the search_theme_directories() results, in case it is in another theme root. * We don't look into directories of themes, just the theme root. */	$theme_root_template = $directories[ $this->template ]['theme_root'];	} else {	// Parent theme is missing.	$this->errors = new WP_Error(	'theme_no_parent',	sprintf(	/* translators: %s: Theme directory name. */	__( 'The parent theme is missing. Please install the "%s" parent theme.' ),	esc_html( $this->template )	)	);	$this->cache_add(	'theme',	array(	'block_template_folders' => $this->get_block_template_folders(),	'block_theme' => $this->is_block_theme(),	'headers' => $this->headers,	'errors' => $this->errors,	'stylesheet' => $this->stylesheet,	'template' => $this->template,	)	);	$this->parent = new WP_Theme( $this->template, $this->theme_root, $this );	return;	}	}	// Set the parent, if we're a child theme.	if ( $this->template !== $this->stylesheet ) {	// If we are a parent, then there is a problem. Only two generations allowed! Cancel things out.	if ( $_child instanceof WP_Theme && $_child->template === $this->stylesheet ) {	$_child->parent = null;	$_child->errors = new WP_Error(	'theme_parent_invalid',	sprintf(	/* translators: %s: Theme directory name. */	__( 'The "%s" theme is not a valid parent theme.' ),	esc_html( $_child->template )	)	);	$_child->cache_add(	'theme',	array(	'block_template_folders' => $_child->get_block_template_folders(),	'block_theme' => $_child->is_block_theme(),	'headers' => $_child->headers,	'errors' => $_child->errors,	'stylesheet' => $_child->stylesheet,	'template' => $_child->template,	)	);	// The two themes actually reference each other with the Template header.	if ( $_child->stylesheet === $this->template ) {	$this->errors = new WP_Error(	'theme_parent_invalid',	sprintf(	/* translators: %s: Theme directory name. */	__( 'The "%s" theme is not a valid parent theme.' ),	esc_html( $this->template )	)	);	$this->cache_add(	'theme',	array(	'block_template_folders' => $this->get_block_template_folders(),	'block_theme' => $this->is_block_theme(),	'headers' => $this->headers,	'errors' => $this->errors,	'stylesheet' => $this->stylesheet,	'template' => $this->template,	)	);	}	return;	}	// Set the parent. Pass the current instance so we can do the checks above and assess errors.	$this->parent = new WP_Theme( $this->template, isset( $theme_root_template ) ? $theme_root_template : $this->theme_root, $this );	}	if ( wp_paused_themes()->get( $this->stylesheet ) && ( ! is_wp_error( $this->errors ) || ! isset( $this->errors->errors['theme_paused'] ) ) ) {	$this->errors = new WP_Error( 'theme_paused', __( 'This theme failed to load properly and was paused within the admin backend.' ) );	}	// We're good. If we didn't retrieve from cache, set it.	if ( ! is_array( $cache ) ) {	$cache = array(	'block_theme' => $this->is_block_theme(),	'block_template_folders' => $this->get_block_template_folders(),	'headers' => $this->headers,	'errors' => $this->errors,	'stylesheet' => $this->stylesheet,	'template' => $this->template,	);	// If the parent theme is in another root, we'll want to cache this. Avoids an entire branch of filesystem calls above.	if ( isset( $theme_root_template ) ) {	$cache['theme_root_template'] = $theme_root_template;	}	$this->cache_add( 'theme', $cache );	} } 

Hooks

apply_filters( ‘wp_cache_themes_persistently’, bool $cache_expiration, string $context )

Filters whether to get the cache of the registered theme directories.

Changelog

VersionDescription
3.4.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.