[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> class-wp-block-bindings-registry.php (source)

   1  <?php
   2  /**
   3   * Block Bindings API: WP_Block_Bindings_Registry class.
   4   *
   5   * Supports overriding content in blocks by connecting them to different sources.
   6   *
   7   * @package WordPress
   8   * @subpackage Block Bindings
   9   * @since 6.5.0
  10   */
  11  
  12  /**
  13   * Core class used for interacting with block bindings sources.
  14   *
  15   * @since 6.5.0
  16   */
  17  final class WP_Block_Bindings_Registry {
  18  
  19      /**
  20       * Holds the registered block bindings sources, keyed by source identifier.
  21       *
  22       * @since 6.5.0
  23       * @var WP_Block_Bindings_Source[]
  24       */
  25      private $sources = array();
  26  
  27      /**
  28       * Container for the main instance of the class.
  29       *
  30       * @since 6.5.0
  31       * @var WP_Block_Bindings_Registry|null
  32       */
  33      private static $instance = null;
  34  
  35      /**
  36       * Supported source properties that can be passed to the registered source.
  37       *
  38       * @since 6.5.0
  39       * @var string[]
  40       */
  41      private $allowed_source_properties = array(
  42          'label',
  43          'get_value_callback',
  44          'uses_context',
  45      );
  46  
  47      /**
  48       * Supported blocks that can use the block bindings API.
  49       *
  50       * @since 6.5.0
  51       * @var string[]
  52       */
  53      private $supported_blocks = array(
  54          'core/paragraph',
  55          'core/heading',
  56          'core/image',
  57          'core/button',
  58      );
  59  
  60      /**
  61       * Registers a new block bindings source.
  62       *
  63       * This is a low-level method. For most use cases, it is recommended to use
  64       * the `register_block_bindings_source()` function instead.
  65       *
  66       * @see register_block_bindings_source()
  67       *
  68       * Sources are used to override block's original attributes with a value
  69       * coming from the source. Once a source is registered, it can be used by a
  70       * block by setting its `metadata.bindings` attribute to a value that refers
  71       * to the source.
  72       *
  73       * @since 6.5.0
  74       *
  75       * @param string   $source_name       The name of the source. It must be a string containing a namespace prefix, i.e.
  76       *                                    `my-plugin/my-custom-source`. It must only contain lowercase alphanumeric
  77       *                                    characters, the forward slash `/` and dashes.
  78       * @param array    $source_properties {
  79       *     The array of arguments that are used to register a source.
  80       *
  81       *     @type string   $label                   The label of the source.
  82       *     @type callable $get_value_callback      A callback executed when the source is processed during block rendering.
  83       *                                             The callback should have the following signature:
  84       *
  85       *                                             `function ($source_args, $block_instance,$attribute_name): mixed`
  86       *                                                 - @param array    $source_args    Array containing source arguments
  87       *                                                                                   used to look up the override value,
  88       *                                                                                   i.e. {"key": "foo"}.
  89       *                                                 - @param WP_Block $block_instance The block instance.
  90       *                                                 - @param string   $attribute_name The name of the target attribute.
  91       *                                             The callback has a mixed return type; it may return a string to override
  92       *                                             the block's original value, null, false to remove an attribute, etc.
  93       *     @type string[] $uses_context (optional) Array of values to add to block `uses_context` needed by the source.
  94       * }
  95       * @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure.
  96       */
  97  	public function register( string $source_name, array $source_properties ) {
  98          if ( ! is_string( $source_name ) ) {
  99              _doing_it_wrong(
 100                  __METHOD__,
 101                  __( 'Block bindings source name must be a string.' ),
 102                  '6.5.0'
 103              );
 104              return false;
 105          }
 106  
 107          if ( preg_match( '/[A-Z]+/', $source_name ) ) {
 108              _doing_it_wrong(
 109                  __METHOD__,
 110                  __( 'Block bindings source names must not contain uppercase characters.' ),
 111                  '6.5.0'
 112              );
 113              return false;
 114          }
 115  
 116          $name_matcher = '/^[a-z0-9-]+\/[a-z0-9-]+$/';
 117          if ( ! preg_match( $name_matcher, $source_name ) ) {
 118              _doing_it_wrong(
 119                  __METHOD__,
 120                  __( 'Block bindings source names must contain a namespace prefix. Example: my-plugin/my-custom-source' ),
 121                  '6.5.0'
 122              );
 123              return false;
 124          }
 125  
 126          if ( $this->is_registered( $source_name ) ) {
 127              _doing_it_wrong(
 128                  __METHOD__,
 129                  /* translators: %s: Block bindings source name. */
 130                  sprintf( __( 'Block bindings source "%s" already registered.' ), $source_name ),
 131                  '6.5.0'
 132              );
 133              return false;
 134          }
 135  
 136          // Validates that the source properties contain the label.
 137          if ( ! isset( $source_properties['label'] ) ) {
 138              _doing_it_wrong(
 139                  __METHOD__,
 140                  __( 'The $source_properties must contain a "label".' ),
 141                  '6.5.0'
 142              );
 143              return false;
 144          }
 145  
 146          // Validates that the source properties contain the get_value_callback.
 147          if ( ! isset( $source_properties['get_value_callback'] ) ) {
 148              _doing_it_wrong(
 149                  __METHOD__,
 150                  __( 'The $source_properties must contain a "get_value_callback".' ),
 151                  '6.5.0'
 152              );
 153              return false;
 154          }
 155  
 156          // Validates that the get_value_callback is a valid callback.
 157          if ( ! is_callable( $source_properties['get_value_callback'] ) ) {
 158              _doing_it_wrong(
 159                  __METHOD__,
 160                  __( 'The "get_value_callback" parameter must be a valid callback.' ),
 161                  '6.5.0'
 162              );
 163              return false;
 164          }
 165  
 166          // Validates that the uses_context parameter is an array.
 167          if ( isset( $source_properties['uses_context'] ) && ! is_array( $source_properties['uses_context'] ) ) {
 168              _doing_it_wrong(
 169                  __METHOD__,
 170                  __( 'The "uses_context" parameter must be an array.' ),
 171                  '6.5.0'
 172              );
 173              return false;
 174          }
 175  
 176          if ( ! empty( array_diff( array_keys( $source_properties ), $this->allowed_source_properties ) ) ) {
 177              _doing_it_wrong(
 178                  __METHOD__,
 179                  __( 'The $source_properties array contains invalid properties.' ),
 180                  '6.5.0'
 181              );
 182              return false;
 183          }
 184  
 185          $source = new WP_Block_Bindings_Source(
 186              $source_name,
 187              $source_properties
 188          );
 189  
 190          $this->sources[ $source_name ] = $source;
 191  
 192          // Adds `uses_context` defined by block bindings sources.
 193          add_filter(
 194              'get_block_type_uses_context',
 195              function ( $uses_context, $block_type ) use ( $source ) {
 196                  if ( ! in_array( $block_type->name, $this->supported_blocks, true ) || empty( $source->uses_context ) ) {
 197                      return $uses_context;
 198                  }
 199                  // Use array_values to reset the array keys.
 200                  return array_values( array_unique( array_merge( $uses_context, $source->uses_context ) ) );
 201              },
 202              10,
 203              2
 204          );
 205  
 206          return $source;
 207      }
 208  
 209      /**
 210       * Unregisters a block bindings source.
 211       *
 212       * @since 6.5.0
 213       *
 214       * @param string $source_name Block bindings source name including namespace.
 215       * @return WP_Block_Bindings_Source|false The unregistered block bindings source on success and `false` otherwise.
 216       */
 217  	public function unregister( string $source_name ) {
 218          if ( ! $this->is_registered( $source_name ) ) {
 219              _doing_it_wrong(
 220                  __METHOD__,
 221                  /* translators: %s: Block bindings source name. */
 222                  sprintf( __( 'Block binding "%s" not found.' ), $source_name ),
 223                  '6.5.0'
 224              );
 225              return false;
 226          }
 227  
 228          $unregistered_source = $this->sources[ $source_name ];
 229          unset( $this->sources[ $source_name ] );
 230  
 231          return $unregistered_source;
 232      }
 233  
 234      /**
 235       * Retrieves the list of all registered block bindings sources.
 236       *
 237       * @since 6.5.0
 238       *
 239       * @return WP_Block_Bindings_Source[] The array of registered sources.
 240       */
 241  	public function get_all_registered() {
 242          return $this->sources;
 243      }
 244  
 245      /**
 246       * Retrieves a registered block bindings source.
 247       *
 248       * @since 6.5.0
 249       *
 250       * @param string $source_name The name of the source.
 251       * @return WP_Block_Bindings_Source|null The registered block bindings source, or `null` if it is not registered.
 252       */
 253  	public function get_registered( string $source_name ) {
 254          if ( ! $this->is_registered( $source_name ) ) {
 255              return null;
 256          }
 257  
 258          return $this->sources[ $source_name ];
 259      }
 260  
 261      /**
 262       * Checks if a block bindings source is registered.
 263       *
 264       * @since 6.5.0
 265       *
 266       * @param string $source_name The name of the source.
 267       * @return bool `true` if the block bindings source is registered, `false` otherwise.
 268       */
 269  	public function is_registered( $source_name ) {
 270          return isset( $this->sources[ $source_name ] );
 271      }
 272  
 273      /**
 274       * Wakeup magic method.
 275       *
 276       * @since 6.5.0
 277       */
 278  	public function __wakeup() {
 279          if ( ! $this->sources ) {
 280              return;
 281          }
 282          if ( ! is_array( $this->sources ) ) {
 283              throw new UnexpectedValueException();
 284          }
 285          foreach ( $this->sources as $value ) {
 286              if ( ! $value instanceof WP_Block_Bindings_Source ) {
 287                  throw new UnexpectedValueException();
 288              }
 289          }
 290      }
 291  
 292      /**
 293       * Utility method to retrieve the main instance of the class.
 294       *
 295       * The instance will be created if it does not exist yet.
 296       *
 297       * @since 6.5.0
 298       *
 299       * @return WP_Block_Bindings_Registry The main instance.
 300       */
 301  	public static function get_instance() {
 302          if ( null === self::$instance ) {
 303              self::$instance = new self();
 304          }
 305  
 306          return self::$instance;
 307      }
 308  }


Generated : Fri May 3 08:20:01 2024 Cross-referenced by PHPXref