⚡ NEW: Changeset/ - Complete Album!

Changeset 59731


Ignore:
Timestamp:
01/29/2025 09:14:53 PM (11 months ago)
Author:
flixos90
Message:

Editor: Relax restrictions around registration of block metadata collections.

This changeset allows for block metadata collections to be registered for almost any source, such as MU plugins, themes, or custom directories with e.g. symlinked plugins or symlinked themes. Prior to the change, block metadata collections could only be registered for plugins and WordPress Core.

There are still safeguards in place to prevent registration of collections in locations that would cause conflicts. For example, it is not possible to register a collection for the entire wp-content/plugins directory or the entire wp-content/themes directory, since such a collection would conflict with any specific plugin's or theme's collection. In case developers would like to enable this safeguard for their own custom directories, they can use the new wp_allowed_block_metadata_collection_roots filter.

Reviewed by jorbin.
Merges [59730] to the 6.7 branch.

Props assassinateur, bowedk, desrosj, dougwollison, flixos90, glynnquelch, gziolo, jorbin, mreishus, swissspidy.
Fixes #62140.

Location:
branches/6.7
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/6.7

  • branches/6.7/src/wp-includes/class-wp-block-metadata-registry.php

    r59132 r59731  
    3939
    4040    /**
    41      * Stores the WordPress 'wp-includes' directory path.
    42      *
    43      * @since 6.7.0
    44      * @var string|null
    45      */
    46     private static $wpinc_dir = null;
    47 
    48     /**
    49      * Stores the normalized WordPress plugin directory path.
    50      *
    51      * @since 6.7.0
    52      * @var string|null
    53      */
    54     private static $plugin_dir = null;
     41     * Stores the default allowed collection root paths.
     42     *
     43     * @since 6.7.2
     44     * @var string[]|null
     45     */
     46    private static $default_collection_roots = null;
    5547
    5648    /**
     
    9385        $path = wp_normalize_path( rtrim( $path, '/' ) );
    9486
    95         $wpinc_dir  = self::get_wpinc_dir();
    96         $plugin_dir = self::get_plugin_dir();
     87        $collection_roots = self::get_default_collection_roots();
     88
     89        /**
     90         * Filters the root directory paths for block metadata collections.
     91         *
     92         * Any block metadata collection that is registered must not use any of these paths, or any parent directory
     93         * path of them. Most commonly, block metadata collections should reside within one of these paths, though in
     94         * some scenarios they may also reside in entirely different directories (e.g. in case of symlinked plugins).
     95         *
     96         * Example:
     97         * * It is allowed to register a collection with path `WP_PLUGIN_DIR . '/my-plugin'`.
     98         * * It is not allowed to register a collection with path `WP_PLUGIN_DIR`.
     99         * * It is not allowed to register a collection with path `dirname( WP_PLUGIN_DIR )`.
     100         *
     101         * The default list encompasses the `wp-includes` directory, as well as the root directories for plugins,
     102         * must-use plugins, and themes. This filter can be used to expand the list, e.g. to custom directories that
     103         * contain symlinked plugins, so that these root directories cannot be used themselves for a block metadata
     104         * collection either.
     105         *
     106         * @since 6.7.2
     107         *
     108         * @param string[] $collection_roots List of allowed metadata collection root paths.
     109         */
     110        $collection_roots = apply_filters( 'wp_allowed_block_metadata_collection_roots', $collection_roots );
     111
     112        $collection_roots = array_unique(
     113            array_map(
     114                static function ( $allowed_root ) {
     115                    return rtrim( $allowed_root, '/' );
     116                },
     117                $collection_roots
     118            )
     119        );
    97120
    98121        // Check if the path is valid:
    99         if ( str_starts_with( $path, $plugin_dir ) ) {
    100             // For plugins, ensure the path is within a specific plugin directory and not the base plugin directory.
    101             $relative_path = substr( $path, strlen( $plugin_dir ) + 1 );
    102             $plugin_name   = strtok( $relative_path, '/' );
    103 
    104             if ( empty( $plugin_name ) || $plugin_name === $relative_path ) {
    105                 _doing_it_wrong(
    106                     __METHOD__,
    107                     __( 'Block metadata collections can only be registered for a specific plugin. The provided path is neither a core path nor a valid plugin path.' ),
    108                     '6.7.0'
    109                 );
    110                 return false;