[ 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       * Registers a new block bindings source.
  49       *
  50       * This is a low-level method. For most use cases, it is recommended to use
  51       * the `register_block_bindings_source()` function instead.
  52       *
  53       * @see register_block_bindings_source()
  54       *
  55       * Sources are used to override block's original attributes with a value
  56       * coming from the source. Once a source is registered, it can be used by a
  57       * block by setting its `metadata.bindings` attribute to a value that refers
  58       * to the source.
  59       *
  60       * @since 6.5.0
  61       *
  62       * @param string $source_name       The name of the source. It must be a string containing a namespace prefix, i.e.
  63       *                                  `my-plugin/my-custom-source`. It must only contain lowercase alphanumeric
  64       *                                  characters, the forward slash `/` and dashes.
  65       * @param array  $source_properties {
  66       *     The array of arguments that are used to register a source.
  67       *
  68       *     @type string   $label              The label of the source.
  69       *     @type callable $get_value_callback A callback executed when the source is processed during block rendering.
  70       *                                        The callback should have the following signature:
  71       *
  72       *                                        `function( $source_args, $block_instance, $attribute_name ): mixed`
  73       *                                            - @param array    $source_args    Array containing source arguments
  74       *                                                                              used to look up the override value,
  75       *                                                                              i.e. {"key": "foo"}.
  76       *                                            - @param WP_Block $block_instance The block instance.
  77       *                                            - @param string   $attribute_name The name of the target attribute.
  78       *                                        The callback has a mixed return type; it may return a string to override
  79       *                                        the block's original value, null, false to remove an attribute, etc.
  80       *     @type string[] $uses_context       Optional. Array of values to add to block `uses_context` needed by the source.
  81       * }
  82       * @return WP_Block_Bindings_Source|false Source when the registration was successful, or `false` on failure.
  83       */
  84  	public function register( string $source_name, array $source_properties ) {
  85          if ( ! is_string( $source_name ) ) {
  86              _doing_it_wrong(
  87                  __METHOD__,
  88                  __( 'Block bindings source name must be a string.' ),
  89                  '6.5.0'
  90              );
  91              return false;
  92          }
  93  
  94          if ( preg_match( '/[A-Z]+/', $source_name ) ) {
  95              _doing_it_wrong(
  96                  __METHOD__,
  97                  __( 'Block bindings source names must not contain uppercase characters.' ),
  98                  '6.5.0'
  99              );
 100              return false;
 101          }
 102  
 103          $name_matcher = '/^[a-z0-9-]+\/[a-z0-9-]+$/';
 104          if ( ! preg_match( $name_matcher, $source_name ) ) {
 105              _doing_it_wrong(
 106                  __METHOD__,
 107                  __( 'Block bindings source names must contain a namespace prefix. Example: my-plugin/my-custom-source' ),
 108                  '6.5.0'
 109              );
 110              return false;
 111          }
 112  
 113          if ( $this->is_registered( $source_name ) ) {
 114              _doing_it_wrong(
 115                  __METHOD__,
 116                  /* translators: %s: Block bindings source name. */
 117                  sprintf( __( 'Block bindings source "%s" already registered.' ), $source_name ),
 118                  '6.5.0'
 119              );
 120              return false;
 121          }
 122  
 123          // Validates that the source properties contain the label.
 124          if ( ! isset( $source_properties['label'] ) ) {
 125              _doing_it_wrong(
 126                  __METHOD__,
 127                  __( 'The $source_properties must contain a "label".' ),
 128                  '6.5.0'
 129              );
 130              return false;
 131          }
 132  
 133          // Validates that the source properties contain the get_value_callback.
 134          if ( ! isset( $source_properties['get_value_callback'] ) ) {
 135              _doing_it_wrong(
 136                  __METHOD__,
 137                  __( 'The $source_properties must contain a "get_value_callback".' ),
 138                  '6.5.0'
 139              );
 140              return false;
 141          }
 142  
 143          // Validates that the get_value_callback is a valid callback.
 144          if ( ! is_callable( $source_properties['get_value_callback'] ) ) {
 145              _doing_it_wrong(
 146                  __METHOD__,
 147                  __( 'The "get_value_callback" parameter must be a valid callback.' ),
 148                  '6.5.0'
 149              );
 150              return false;
 151          }
 152  
 153          // Validates that the uses_context parameter is an array.
 154          if ( isset( $source_properties['uses_context'] ) && ! is_array( $source_properties['uses_context'] ) ) {
 155              _doing_it_wrong(
 156                  __METHOD__,
 157                  __( 'The "uses_context" parameter must be an array.' ),
 158                  '6.5.0'
 159              );
 160              return false;
 161          }
 162  
 163          if ( ! empty( array_diff( array_keys( $source_properties ), $this->allowed_source_properties ) ) ) {
 164              _doing_it_wrong(
 165                  __METHOD__,
 166                  __( 'The $source_properties array contains invalid properties.' ),
 167                  '6.5.0'
 168              );
 169              return false;
 170          }
 171  
 172          $source = new WP_Block_Bindings_Source(
 173              $source_name,
 174              $source_properties
 175          );
 176  
 177          $this->sources[ $source_name ] = $source;
 178  
 179          return $source;
 180      }
 181  
 182      /**
 183       * Unregisters a block bindings source.
 184       *
 185       * @since 6.5.0
 186       *
 187       * @param string $source_name Block bindings source name including namespace.
 188       * @return WP_Block_Bindings_Source|false The unregistered block bindings source on success and `false` otherwise.
 189       */
 190  	public function unregister( string $source_name ) {
 191          if ( ! $this->is_registered( $source_name ) ) {
 192              _doing_it_wrong(
 193                  __METHOD__,
 194                  /* translators: %s: Block bindings source name. */
 195                  sprintf( __( 'Block binding "%s" not found.' ), $source_name ),
 196                  '6.5.0'
 197              );
 198              return false;
 199          }
 200  
 201          $unregistered_source = $this->sources[ $source_name ];
 202          unset( $this->sources[ $source_name ] );
 203  
 204          return $unregistered_source;
 205      }
 206  
 207      /**
 208       * Retrieves the list of all registered block bindings sources.
 209       *
 210       * @since 6.5.0
 211       *
 212       * @return WP_Block_Bindings_Source[] The array of registered sources.
 213       */
 214  	public function get_all_registered() {
 215          return $this->sources;
 216      }
 217  
 218      /**
 219       * Retrieves a registered block bindings source.
 220       *
 221       * @since 6.5.0
 222       *
 223       * @param string $source_name The name of the source.
 224       * @return WP_Block_Bindings_Source|null The registered block bindings source, or `null` if it is not registered.
 225       */
 226  	public function get_registered( string $source_name ) {
 227          if ( ! $this->is_registered( $source_name ) ) {
 228              return null;
 229          }
 230  
 231          return $this->sources[ $source_name ];
 232      }
 233  
 234      /**
 235       * Checks if a block bindings source is registered.
 236       *
 237       * @since 6.5.0
 238       *
 239       * @param string|null $source_name The name of the source.
 240       * @return bool `true` if the block bindings source is registered, `false` otherwise.
 241       */
 242  	public function is_registered( $source_name ) {
 243          return isset( $source_name, $this->sources[ $source_name ] );
 244      }
 245  
 246      /**
 247       * Wakeup magic method.
 248       *
 249       * @since 6.5.0
 250       */
 251  	public function __wakeup() {
 252          if ( ! $this->sources ) {
 253              return;
 254          }
 255          if ( ! is_array( $this->sources ) ) {
 256              throw new UnexpectedValueException();
 257          }
 258          foreach ( $this->sources as $value ) {
 259              if ( ! $value instanceof WP_Block_Bindings_Source ) {
 260                  throw new UnexpectedValueException();
 261              }
 262          }
 263      }
 264  
 265      /**
 266       * Utility method to retrieve the main instance of the class.
 267       *
 268       * The instance will be created if it does not exist yet.
 269       *
 270       * @since 6.5.0
 271       *
 272       * @return WP_Block_Bindings_Registry The main instance.
 273       */
 274  	public static function get_instance() {
 275          if ( null === self::$instance ) {
 276              self::$instance = new self();
 277          }
 278  
 279          return self::$instance;
 280      }
 281  }


Generated : Wed Jun 24 08:20:11 2026 Cross-referenced by PHPXref