Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions src/wp-includes/block-bindings/post-data.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,29 @@ function _block_bindings_post_data_get_value( array $source_args, $block_instanc
return null;
}

if ( empty( $block_instance->context['postId'] ) ) {
/*
* BACKWARDS COMPATIBILITY: Hardcoded exception for navigation blocks.
* Required for WordPress 6.9+ navigation blocks. DO NOT REMOVE.
*/
$block_name = $block_instance->name ?? '';
$is_navigation_block = in_array(
$block_name,
array( 'core/navigation-link', 'core/navigation-submenu' ),
true
);

if ( $is_navigation_block ) {
// Navigation blocks: read from block attributes.
$post_id = $block_instance->attributes['id'] ?? null;
} else {
// All other blocks: use context.
$post_id = $block_instance->context['postId'] ?? null;
}

// If we don't have an entity ID, bail early.
if ( empty( $post_id ) ) {
return null;
}
$post_id = $block_instance->context['postId'];

// If a post isn't public, we need to prevent unauthorized users from accessing the post data.
$post = get_post( $post_id );
Expand All @@ -46,6 +65,11 @@ function _block_bindings_post_data_get_value( array $source_args, $block_instanc
return '';
}
}

if ( 'link' === $source_args['key'] ) {
$permalink = get_permalink( $post_id );
return false === $permalink ? null : esc_url( $permalink );
}
}

/**
Expand Down
119 changes: 119 additions & 0 deletions src/wp-includes/block-bindings/term-data.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php
/**
* Term Data source for Block Bindings.
*
* @since 6.9.0
* @package WordPress
* @subpackage Block Bindings
*/

/**
* Gets value for Term Data source.
*
* @since 6.9.0
* @access private
*
* @param array $source_args Array containing source arguments used to look up the override value.
* Example: array( "key" => "name" ).
* @param WP_Block $block_instance The block instance.
* @return mixed The value computed for the source.
*/
function _block_bindings_term_data_get_value( array $source_args, $block_instance ) {
if ( empty( $source_args['key'] ) ) {
return null;
}

/*
* BACKWARDS COMPATIBILITY: Hardcoded exception for navigation blocks.
* Required for WordPress 6.9+ navigation blocks. DO NOT REMOVE.
*/
$block_name = $block_instance->name ?? '';
$is_navigation_block = in_array(
$block_name,
array( 'core/navigation-link', 'core/navigation-submenu' ),
true
);

if ( $is_navigation_block ) {
// Navigation blocks: read from block attributes.
$term_id = $block_instance->attributes['id'] ?? null;
$type = $block_instance->attributes['type'] ?? '';
// Map UI shorthand to taxonomy slug when using attributes.
$taxonomy = ( 'tag' === $type ) ? 'post_tag' : $type;
} else {
// All other blocks: use context
$term_id = $block_instance->context['termId'] ?? null;
$taxonomy = $block_instance->context['taxonomy'] ?? '';
}

// If we don't have required identifiers, bail early.
if ( empty( $term_id ) || empty( $taxonomy ) ) {
return null;
}

// Get the term data.
$term = get_term( $term_id, $taxonomy );
if ( is_wp_error( $term ) || ! $term ) {
return null;
}

// Check if taxonomy exists and is publicly queryable.
$taxonomy_object = get_taxonomy( $taxonomy );
if ( ! $taxonomy_object || ! $taxonomy_object->publicly_queryable ) {
if ( ! current_user_can( 'read' ) ) {
return null;
}
}

switch ( $source_args['key'] ) {
case 'id':
return esc_html( (string) $term_id );

case 'name':
return esc_html( $term->name );

case 'link':
// Only taxonomy entities are supported by Term Data.
$term_link = get_term_link( $term );
return is_wp_error( $term_link ) ? null : esc_url( $term_link );

case 'slug':
return esc_html( $term->slug );

case 'description':
return wp_kses_post( $term->description );

case 'parent':
return esc_html( (string) $term->parent );

case 'count':
return esc_html( (string) $term->count );

default:
return null;
}
}

/**
* Registers Term Data source in the block bindings registry.
*
* @since 6.9.0
* @access private
*/
function _register_block_bindings_term_data_source() {
if ( get_block_bindings_source( 'core/term-data' ) ) {
// The source is already registered.
return;
}

register_block_bindings_source(
'core/term-data',
array(
'label' => _x( 'Term Data', 'block bindings source' ),
'get_value_callback' => '_block_bindings_term_data_get_value',
'uses_context' => array( 'termId', 'taxonomy' ),
)
);
}

add_action( 'init', '_register_block_bindings_term_data_source' );
1 change: 1 addition & 0 deletions src/wp-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@
require ABSPATH . WPINC . '/block-bindings/pattern-overrides.php';
require ABSPATH . WPINC . '/block-bindings/post-data.php';
require ABSPATH . WPINC . '/block-bindings/post-meta.php';
require ABSPATH . WPINC . '/block-bindings/term-data.php';
require ABSPATH . WPINC . '/blocks.php';
require ABSPATH . WPINC . '/blocks/index.php';
require ABSPATH . WPINC . '/block-editor.php';
Expand Down
1 change: 1 addition & 0 deletions tests/phpunit/includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ function _unhook_block_registration() {
remove_action( 'init', '_register_block_bindings_pattern_overrides_source' );
remove_action( 'init', '_register_block_bindings_post_data_source' );
remove_action( 'init', '_register_block_bindings_post_meta_source' );
remove_action( 'init', '_register_block_bindings_term_data_source' );
}
tests_add_filter( 'init', '_unhook_block_registration', 1000 );

Expand Down
1 change: 1 addition & 0 deletions tests/phpunit/tests/block-bindings/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public function test_get_all_registered() {
'core/post-data' => get_block_bindings_source( 'core/post-data' ),
'core/post-meta' => get_block_bindings_source( 'core/post-meta' ),
'core/pattern-overrides' => get_block_bindings_source( 'core/pattern-overrides' ),
'core/term-data' => get_block_bindings_source( 'core/term-data' ),
);

$registered = get_all_registered_block_bindings_sources();
Expand Down
Loading