Merged in feature/81-dev-dev01 (pull request #5)
auto-patch 81-dev-dev01-2023-12-05T22_45_26 * auto-patch 81-dev-dev01-2023-12-05T22_45_26
This commit is contained in:
@@ -59,6 +59,7 @@ final class WP_Theme implements ArrayAccess {
|
||||
* @since 5.6.0 Added the Twenty Twenty-One theme.
|
||||
* @since 5.9.0 Added the Twenty Twenty-Two theme.
|
||||
* @since 6.1.0 Added the Twenty Twenty-Three theme.
|
||||
* @since 6.4.0 Added the Twenty Twenty-Four theme.
|
||||
* @var string[]
|
||||
*/
|
||||
private static $default_themes = array(
|
||||
@@ -77,6 +78,7 @@ final class WP_Theme implements ArrayAccess {
|
||||
'twentytwentyone' => 'Twenty Twenty-One',
|
||||
'twentytwentytwo' => 'Twenty Twenty-Two',
|
||||
'twentytwentythree' => 'Twenty Twenty-Three',
|
||||
'twentytwentyfour' => 'Twenty Twenty-Four',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -194,6 +196,25 @@ final class WP_Theme implements ArrayAccess {
|
||||
*/
|
||||
private $cache_hash;
|
||||
|
||||
/**
|
||||
* Block template folders.
|
||||
*
|
||||
* @since 6.4.0
|
||||
* @var string[]
|
||||
*/
|
||||
private $block_template_folders;
|
||||
|
||||
/**
|
||||
* Default values for template folders.
|
||||
*
|
||||
* @since 6.4.0
|
||||
* @var string[]
|
||||
*/
|
||||
private $default_template_folders = array(
|
||||
'wp_template' => 'templates',
|
||||
'wp_template_part' => 'parts',
|
||||
);
|
||||
|
||||
/**
|
||||
* Flag for whether the themes cache bucket should be persistently cached.
|
||||
*
|
||||
@@ -262,7 +283,7 @@ final class WP_Theme implements ArrayAccess {
|
||||
$cache = $this->cache_get( 'theme' );
|
||||
|
||||
if ( is_array( $cache ) ) {
|
||||
foreach ( array( 'block_theme', 'errors', 'headers', 'template' ) as $key ) {
|
||||
foreach ( array( 'block_template_folders', 'block_theme', 'errors', 'headers', 'template' ) as $key ) {
|
||||
if ( isset( $cache[ $key ] ) ) {
|
||||
$this->$key = $cache[ $key ];
|
||||
}
|
||||
@@ -287,16 +308,18 @@ final class WP_Theme implements ArrayAccess {
|
||||
} else {
|
||||
$this->errors = new WP_Error( 'theme_no_stylesheet', __( 'Stylesheet is missing.' ) );
|
||||
}
|
||||
$this->template = $this->stylesheet;
|
||||
$this->block_theme = false;
|
||||
$this->template = $this->stylesheet;
|
||||
$this->block_theme = false;
|
||||
$this->block_template_folders = $this->default_template_folders;
|
||||
$this->cache_add(
|
||||
'theme',
|
||||
array(
|
||||
'block_theme' => $this->block_theme,
|
||||
'headers' => $this->headers,
|
||||
'errors' => $this->errors,
|
||||
'stylesheet' => $this->stylesheet,
|
||||
'template' => $this->template,
|
||||
'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.
|
||||
@@ -304,18 +327,20 @@ final class WP_Theme implements ArrayAccess {
|
||||
}
|
||||
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->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_theme' => $this->block_theme,
|
||||
'headers' => $this->headers,
|
||||
'errors' => $this->errors,
|
||||
'stylesheet' => $this->stylesheet,
|
||||
'template' => $this->template,
|
||||
'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;
|
||||
@@ -345,10 +370,11 @@ final class WP_Theme implements ArrayAccess {
|
||||
$this->cache_add(
|
||||
'theme',
|
||||
array(
|
||||
'block_theme' => $this->is_block_theme(),
|
||||
'headers' => $this->headers,
|
||||
'errors' => $this->errors,
|
||||
'stylesheet' => $this->stylesheet,
|
||||
'block_template_folders' => $this->get_block_template_folders(),
|
||||
'block_theme' => $this->is_block_theme(),
|
||||
'headers' => $this->headers,
|
||||
'errors' => $this->errors,
|
||||
'stylesheet' => $this->stylesheet,
|
||||
)
|
||||
);
|
||||
|
||||
@@ -378,11 +404,12 @@ final class WP_Theme implements ArrayAccess {
|
||||
$this->cache_add(
|
||||
'theme',
|
||||
array(
|
||||
'block_theme' => $this->block_theme,
|
||||
'headers' => $this->headers,
|
||||
'errors' => $this->errors,
|
||||
'stylesheet' => $this->stylesheet,
|
||||
'template' => $this->template,
|
||||
'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;
|
||||
@@ -419,11 +446,12 @@ final class WP_Theme implements ArrayAccess {
|
||||
$this->cache_add(
|
||||
'theme',
|
||||
array(
|
||||
'block_theme' => $this->is_block_theme(),
|
||||
'headers' => $this->headers,
|
||||
'errors' => $this->errors,
|
||||
'stylesheet' => $this->stylesheet,
|
||||
'template' => $this->template,
|
||||
'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 );
|
||||
@@ -447,11 +475,12 @@ final class WP_Theme implements ArrayAccess {
|
||||
$_child->cache_add(
|
||||
'theme',
|
||||
array(
|
||||
'block_theme' => $_child->is_block_theme(),
|
||||
'headers' => $_child->headers,
|
||||
'errors' => $_child->errors,
|
||||
'stylesheet' => $_child->stylesheet,
|
||||
'template' => $_child->template,
|
||||
'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.
|
||||
@@ -467,11 +496,12 @@ final class WP_Theme implements ArrayAccess {
|
||||
$this->cache_add(
|
||||
'theme',
|
||||
array(
|
||||
'block_theme' => $this->is_block_theme(),
|
||||
'headers' => $this->headers,
|
||||
'errors' => $this->errors,
|
||||
'stylesheet' => $this->stylesheet,
|
||||
'template' => $this->template,
|
||||
'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,
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -488,11 +518,12 @@ final class WP_Theme implements ArrayAccess {
|
||||
// We're good. If we didn't retrieve from cache, set it.
|
||||
if ( ! is_array( $cache ) ) {
|
||||
$cache = array(
|
||||
'block_theme' => $this->is_block_theme(),
|
||||
'headers' => $this->headers,
|
||||
'errors' => $this->errors,
|
||||
'stylesheet' => $this->stylesheet,
|
||||
'template' => $this->template,
|
||||
'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 ) ) {
|
||||
@@ -741,6 +772,26 @@ final class WP_Theme implements ArrayAccess {
|
||||
return isset( $this->parent ) ? $this->parent : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform reinitialization tasks.
|
||||
*
|
||||
* Prevents a callback from being injected during unserialization of an object.
|
||||
*/
|
||||
public function __wakeup() {
|
||||
if ( $this->parent && ! $this->parent instanceof self ) {
|
||||
throw new UnexpectedValueException();
|
||||
}
|
||||
if ( $this->headers && ! is_array( $this->headers ) ) {
|
||||
throw new UnexpectedValueException();
|
||||
}
|
||||
foreach ( $this->headers as $value ) {
|
||||
if ( ! is_string( $value ) ) {
|
||||
throw new UnexpectedValueException();
|
||||
}
|
||||
}
|
||||
$this->headers_sanitized = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds theme data to cache.
|
||||
*
|
||||
@@ -779,16 +830,18 @@ final class WP_Theme implements ArrayAccess {
|
||||
foreach ( array( 'theme', 'screenshot', 'headers', 'post_templates' ) as $key ) {
|
||||
wp_cache_delete( $key . '-' . $this->cache_hash, 'themes' );
|
||||
}
|
||||
$this->template = null;
|
||||
$this->textdomain_loaded = null;
|
||||
$this->theme_root_uri = null;
|
||||
$this->parent = null;
|
||||
$this->errors = null;
|
||||
$this->headers_sanitized = null;
|
||||
$this->name_translated = null;
|
||||
$this->block_theme = null;
|
||||
$this->headers = array();
|
||||
$this->template = null;
|
||||
$this->textdomain_loaded = null;
|
||||
$this->theme_root_uri = null;
|
||||
$this->parent = null;
|
||||
$this->errors = null;
|
||||
$this->headers_sanitized = null;
|
||||
$this->name_translated = null;
|
||||
$this->block_theme = null;
|
||||
$this->block_template_folders = null;
|
||||
$this->headers = array();
|
||||
$this->__construct( $this->stylesheet, $this->theme_root );
|
||||
$this->delete_pattern_cache();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1556,7 +1609,7 @@ final class WP_Theme implements ArrayAccess {
|
||||
|
||||
if ( empty( $file ) ) {
|
||||
$path = $stylesheet_directory;
|
||||
} elseif ( file_exists( $stylesheet_directory . '/' . $file ) ) {
|
||||
} elseif ( $stylesheet_directory !== $template_directory && file_exists( $stylesheet_directory . '/' . $file ) ) {
|
||||
$path = $stylesheet_directory . '/' . $file;
|
||||
} else {
|
||||
$path = $template_directory . '/' . $file;
|
||||
@@ -1714,6 +1767,244 @@ final class WP_Theme implements ArrayAccess {
|
||||
return (array) apply_filters( 'site_allowed_themes', $allowed_themes[ $blog_id ], $blog_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the folder names of the block template directories.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @return string[] {
|
||||
* Folder names used by block themes.
|
||||
*
|
||||
* @type string $wp_template Theme-relative directory name for block templates.
|
||||
* @type string $wp_template_part Theme-relative directory name for block template parts.
|
||||
* }
|
||||
*/
|
||||
public function get_block_template_folders() {
|
||||
// Return set/cached value if available.
|
||||
if ( isset( $this->block_template_folders ) ) {
|
||||
return $this->block_template_folders;
|
||||
}
|
||||
|
||||
$this->block_template_folders = $this->default_template_folders;
|
||||
|
||||
$stylesheet_directory = $this->get_stylesheet_directory();
|
||||
// If the theme uses deprecated block template folders.
|
||||
if ( file_exists( $stylesheet_directory . '/block-templates' ) || file_exists( $stylesheet_directory . '/block-template-parts' ) ) {
|
||||
$this->block_template_folders = array(
|
||||
'wp_template' => 'block-templates',
|
||||
'wp_template_part' => 'block-template-parts',
|
||||
);
|
||||
}
|
||||
return $this->block_template_folders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets block pattern data for a specified theme.
|
||||
* Each pattern is defined as a PHP file and defines
|
||||
* its metadata using plugin-style headers. The minimum required definition is:
|
||||
*
|
||||
* /**
|
||||
* * Title: My Pattern
|
||||
* * Slug: my-theme/my-pattern
|
||||
* *
|
||||
*
|
||||
* The output of the PHP source corresponds to the content of the pattern, e.g.:
|
||||
*
|
||||
* <main><p><?php echo "Hello"; ?></p></main>
|
||||
*
|
||||
* If applicable, this will collect from both parent and child theme.
|
||||
*
|
||||
* Other settable fields include:
|
||||
*
|
||||
* - Description
|
||||
* - Viewport Width
|
||||
* - Inserter (yes/no)
|
||||
* - Categories (comma-separated values)
|
||||
* - Keywords (comma-separated values)
|
||||
* - Block Types (comma-separated values)
|
||||
* - Post Types (comma-separated values)
|
||||
* - Template Types (comma-separated values)
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @return array Block pattern data.
|
||||
*/
|
||||
public function get_block_patterns() {
|
||||
$can_use_cached = ! wp_is_development_mode( 'theme' );
|
||||
|
||||
$pattern_data = $this->get_pattern_cache();
|
||||
if ( is_array( $pattern_data ) ) {
|
||||
if ( $can_use_cached ) {
|
||||
return $pattern_data;
|
||||
}
|
||||
// If in development mode, clear pattern cache.
|
||||
$this->delete_pattern_cache();
|
||||
}
|
||||
|
||||
$dirpath = $this->get_stylesheet_directory() . '/patterns/';
|
||||
$pattern_data = array();
|
||||
|
||||
if ( ! file_exists( $dirpath ) ) {
|
||||
if ( $can_use_cached ) {
|
||||
$this->set_pattern_cache( $pattern_data );
|
||||
}
|
||||
return $pattern_data;
|
||||
}
|
||||
$files = glob( $dirpath . '*.php' );
|
||||
if ( ! $files ) {
|
||||
if ( $can_use_cached ) {
|
||||
$this->set_pattern_cache( $pattern_data );
|
||||
}
|
||||
return $pattern_data;
|
||||
}
|
||||
|
||||
$default_headers = array(
|
||||
'title' => 'Title',
|
||||
'slug' => 'Slug',
|
||||
'description' => 'Description',
|
||||
'viewportWidth' => 'Viewport Width',
|
||||
'inserter' => 'Inserter',
|
||||
'categories' => 'Categories',
|
||||
'keywords' => 'Keywords',
|
||||
'blockTypes' => 'Block Types',
|
||||
'postTypes' => 'Post Types',
|
||||
'templateTypes' => 'Template Types',
|
||||
);
|
||||
|
||||
$properties_to_parse = array(
|
||||
'categories',
|
||||
'keywords',
|
||||
'blockTypes',
|
||||
'postTypes',
|
||||
'templateTypes',
|
||||
);
|
||||
|
||||
foreach ( $files as $file ) {
|
||||
$pattern = get_file_data( $file, $default_headers );
|
||||
|
||||
if ( empty( $pattern['slug'] ) ) {
|
||||
_doing_it_wrong(
|
||||
__FUNCTION__,
|
||||
sprintf(
|
||||
/* translators: 1: file name. */
|
||||
__( 'Could not register file "%s" as a block pattern ("Slug" field missing)' ),
|
||||
$file
|
||||
),
|
||||
'6.0.0'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! preg_match( '/^[A-z0-9\/_-]+$/', $pattern['slug'] ) ) {
|
||||
_doing_it_wrong(
|
||||
__FUNCTION__,
|
||||
sprintf(
|
||||
/* translators: 1: file name; 2: slug value found. */
|
||||
__( 'Could not register file "%1$s" as a block pattern (invalid slug "%2$s")' ),
|
||||
$file,
|
||||
$pattern['slug']
|
||||
),
|
||||
'6.0.0'
|
||||
);
|
||||
}
|
||||
|
||||
// Title is a required property.
|
||||
if ( ! $pattern['title'] ) {
|
||||
_doing_it_wrong(
|
||||
__FUNCTION__,
|
||||
sprintf(
|
||||
/* translators: 1: file name. */
|
||||
__( 'Could not register file "%s" as a block pattern ("Title" field missing)' ),
|
||||
$file
|
||||
),
|
||||
'6.0.0'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// For properties of type array, parse data as comma-separated.
|
||||
foreach ( $properties_to_parse as $property ) {
|
||||
if ( ! empty( $pattern[ $property ] ) ) {
|
||||
$pattern[ $property ] = array_filter( wp_parse_list( (string) $pattern[ $property ] ) );
|
||||
} else {
|
||||
unset( $pattern[ $property ] );
|
||||
}
|
||||
}
|
||||
|
||||
// Parse properties of type int.
|
||||
$property = 'viewportWidth';
|
||||
if ( ! empty( $pattern[ $property ] ) ) {
|
||||
$pattern[ $property ] = (int) $pattern[ $property ];
|
||||
} else {
|
||||
unset( $pattern[ $property ] );
|
||||
}
|
||||
|
||||
// Parse properties of type bool.
|
||||
$property = 'inserter';
|
||||
if ( ! empty( $pattern[ $property ] ) ) {
|
||||
$pattern[ $property ] = in_array(
|
||||
strtolower( $pattern[ $property ] ),
|
||||
array( 'yes', 'true' ),
|
||||
true
|
||||
);
|
||||
} else {
|
||||
unset( $pattern[ $property ] );
|
||||
}
|
||||
|
||||
$key = str_replace( $dirpath, '', $file );
|
||||
|
||||
$pattern_data[ $key ] = $pattern;
|
||||
}
|
||||
|
||||
if ( $can_use_cached ) {
|
||||
$this->set_pattern_cache( $pattern_data );
|
||||
}
|
||||
|
||||
return $pattern_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets block pattern cache.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @return array|false Returns an array of patterns if cache is found, otherwise false.
|
||||
*/
|
||||
private function get_pattern_cache() {
|
||||
if ( ! $this->exists() ) {
|
||||
return false;
|
||||
}
|
||||
$pattern_data = wp_cache_get( 'wp_theme_patterns_' . $this->stylesheet );
|
||||
if ( is_array( $pattern_data ) && $pattern_data['version'] === $this->get( 'Version' ) ) {
|
||||
return $pattern_data['patterns'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets block pattern cache.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param array $patterns Block patterns data to set in cache.
|
||||
*/
|
||||
private function set_pattern_cache( array $patterns ) {
|
||||
$pattern_data = array(
|
||||
'version' => $this->get( 'Version' ),
|
||||
'patterns' => $patterns,
|
||||
);
|
||||
wp_cache_set( 'wp_theme_patterns_' . $this->stylesheet, $pattern_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears block pattern cache.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*/
|
||||
public function delete_pattern_cache() {
|
||||
wp_cache_delete( 'wp_theme_patterns_' . $this->stylesheet );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables a theme for all sites on the current network.
|
||||
*
|
||||
@@ -1812,4 +2103,16 @@ final class WP_Theme implements ArrayAccess {
|
||||
private static function _name_sort_i18n( $a, $b ) {
|
||||
return strnatcasecmp( $a->name_translated, $b->name_translated );
|
||||
}
|
||||
|
||||
private static function _check_headers_property_has_correct_type( $headers ) {
|
||||
if ( ! is_array( $headers ) ) {
|
||||
return false;
|
||||
}
|
||||
foreach ( $headers as $key => $value ) {
|
||||
if ( ! is_string( $key ) || ! is_string( $value ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user