Make WordPress Core


Ignore:
Timestamp:
10/20/2023 07:33:59 PM (14 months ago)
Author:
joemcgill
Message:

Themes: Make caches for block patterns clearable.

In [56765], theme block pattern files were cached to a transient as a performance enhancement. However, transients are not easily clearable when caches are flushed on environments not using a persistent cache, which can lead to errors if the theme files are renamed, edited, or moved.

This changes the caching mechanism to use wp_cache_set() instead, and caches these values to the global group so they are still persistent on environments using an object cache, and will be cleared by a cache flush.

In addition, the helper _wp_get_block_patterns has been moved WP_Theme::get_block_patterns for consistency with other block related theme methods and cache helpers for these values, WP_Theme::get_pattern_cache and WP_Theme::set_pattern_cache, have been made private.

Relevant unit tests updated.

Props afercia, flixos90, mukesh27, joemcgill.
Merges [56978] to the 6.4 branch.
Fixes #59633. See #59591, #59490.

Location:
branches/6.4
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/6.4

    • Property svn:mergeinfo changed
      /trunk (added)merged: 56978
  • branches/6.4/src/wp-includes/block-patterns.php

    r56931 r56979  
    342342
    343343    foreach ( $themes as $theme ) {
    344         $patterns    = _wp_get_block_patterns( $theme );
     344        $patterns    = $theme->get_block_patterns();
    345345        $dirpath     = $theme->get_stylesheet_directory() . '/patterns/';
    346346        $text_domain = $theme->get( 'TextDomain' );
     
    388388}
    389389add_action( 'init', '_register_theme_block_patterns' );
    390 
    391 /**
    392  * Gets block pattern data for a specified theme.
    393  * Each pattern is defined as a PHP file and defines
    394  *  its metadata using plugin-style headers. The minimum required definition is:
    395  *
    396  *      /**
    397  *       * Title: My Pattern
    398  *       * Slug: my-theme/my-pattern
    399  *       *
    400  *
    401  *  The output of the PHP source corresponds to the content of the pattern, e.g.:
    402  *
    403  *      <main><p><?php echo "Hello"; ?></p></main>
    404  *
    405  *  If applicable, this will collect from both parent and child theme.
    406  *
    407  *  Other settable fields include:
    408  *
    409  *    - Description
    410  *    - Viewport Width
    411  *    - Inserter         (yes/no)
    412  *    - Categories       (comma-separated values)
    413  *    - Keywords         (comma-separated values)
    414  *    - Block Types      (comma-separated values)
    415  *    - Post Types       (comma-separated values)
    416  *    - Template Types   (comma-separated values)
    417  *
    418  * @since 6.4.0
    419  * @access private
    420  *
    421  * @param WP_Theme $theme Theme object.
    422  * @return array Block pattern data.
    423  */
    424 function _wp_get_block_patterns( WP_Theme $theme ) {
    425     $can_use_cached = ! wp_is_development_mode( 'theme' );
    426 
    427     $pattern_data = $theme->get_pattern_cache();
    428     if ( is_array( $pattern_data ) ) {
    429         if ( $can_use_cached ) {
    430             return $pattern_data;
    431         }
    432         // If in development mode, clear pattern cache.
    433         $theme->delete_pattern_cache();
    434     }
    435 
    436     $dirpath      = $theme->get_stylesheet_directory() . '/patterns/';
    437     $pattern_data = array();
    438 
    439     if ( ! file_exists( $dirpath ) ) {
    440         if ( $can_use_cached ) {
    441             $theme->set_pattern_cache( $pattern_data );
    442         }
    443         return $pattern_data;
    444     }
    445     $files = glob( $dirpath . '*.php' );
    446     if ( ! $files ) {
    447         if ( $can_use_cached ) {
    448             $theme->set_pattern_cache( $pattern_data );
    449         }
    450         return $pattern_data;
    451     }
    452 
    453     $default_headers = array(
    454         'title'         => 'Title',
    455         'slug'          => 'Slug',
    456         'description'   => 'Description',
    457         'viewportWidth' => 'Viewport Width',
    458         'inserter'      => 'Inserter',
    459         'categories'    => 'Categories',
    460         'keywords'      => 'Keywords',
    461         'blockTypes'    => 'Block Types',
    462         'postTypes'     => 'Post Types',
    463         'templateTypes' => 'Template Types',
    464     );
    465 
    466     $properties_to_parse = array(
    467         'categories',
    468         'keywords',
    469         'blockTypes',
    470         'postTypes',
    471         'templateTypes',
    472     );
    473 
    474     foreach ( $files as $file ) {
    475         $pattern = get_file_data( $file, $default_headers );
    476 
    477         if ( empty( $pattern['slug'] ) ) {
    478             _doing_it_wrong(
    479                 __FUNCTION__,
    480                 sprintf(
    481                     /* translators: 1: file name. */
    482                     __( 'Could not register file "%s" as a block pattern ("Slug" field missing)' ),
    483                     $file
    484                 ),
    485                 '6.0.0'
    486             );
    487             continue;
    488         }
    489 
    490         if ( ! preg_match( '/^[A-z0-9\/_-]+$/', $pattern['slug'] ) ) {
    491             _doing_it_wrong(
    492                 __FUNCTION__,
    493                 sprintf(
    494                     /* translators: 1: file name; 2: slug value found. */
    495                     __( 'Could not register file "%1$s" as a block pattern (invalid slug "%2$s")' ),
    496                     $file,
    497                     $pattern['slug']
    498                 ),
    499                 '6.0.0'
    500             );
    501         }
    502 
    503         // Title is a required property.
    504         if ( ! $pattern['title'] ) {
    505             _doing_it_wrong(
    506                 __FUNCTION__,
    507                 sprintf(
    508                     /* translators: 1: file name. */
    509                     __( 'Could not register file "%s" as a block pattern ("Title" field missing)' ),
    510                     $file
    511                 ),
    512                 '6.0.0'
    513             );
    514             continue;
    515         }
    516 
    517         // For properties of type array, parse data as comma-separated.
    518         foreach ( $properties_to_parse as $property ) {
    519             if ( ! empty( $pattern[ $property ] ) ) {
    520                 $pattern[ $property ] = array_filter( wp_parse_list( (string) $pattern[ $property ] ) );
    521             } else {
    522                 unset( $pattern[ $property ] );
    523             }
    524         }
    525 
    526         // Parse properties of type int.
    527         $property = 'viewportWidth';
    528         if ( ! empty( $pattern[ $property ] ) ) {
    529             $pattern[ $property ] = (int) $pattern[ $property ];
    530         } else {
    531             unset( $pattern[ $property ] );
    532         }
    533 
    534         // Parse properties of type bool.
    535         $property = 'inserter';
    536         if ( ! empty( $pattern[ $property ] ) ) {
    537             $pattern[ $property ] = in_array(
    538                 strtolower( $pattern[ $property ] ),
    539                 array( 'yes', 'true' ),
    540                 true
    541             );
    542         } else {
    543             unset( $pattern[ $property ] );
    544         }
    545 
    546         $key = str_replace( $dirpath, '', $file );
    547 
    548         $pattern_data[ $key ] = $pattern;
    549     }
    550 
    551     if ( $can_use_cached ) {
    552         $theme->set_pattern_cache( $pattern_data );
    553     }
    554 
    555     return $pattern_data;
    556 }
Note: See TracChangeset for help on using the changeset viewer.