Changeset 59662
- Timestamp:
- 01/17/2025 09:35:50 PM (6 months ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-block.php
r59361 r59662 57 57 * @access protected 58 58 */ 59 protected $available_context ;59 protected $available_context = array(); 60 60 61 61 /** … … 141 141 $this->available_context = $available_context; 142 142 143 $this->refresh_context_dependents(); 144 } 145 146 /** 147 * Updates the context for the current block and its inner blocks. 148 * 149 * The method updates the context of inner blocks, if any, by passing down 150 * any context values the block provides (`provides_context`). 151 * 152 * If the block has inner blocks, the method recursively processes them by creating new instances of `WP_Block` 153 * for each inner block and updating their context based on the block's `provides_context` property. 154 * 155 * @since 6.8.0 156 */ 157 public function refresh_context_dependents() { 158 /* 159 * Merging the `$context` property here is not ideal, but for now needs to happen because of backward compatibility. 160 * Ideally, the `$context` property itself would not be filterable directly and only the `$available_context` would be filterable. 161 * However, this needs to be separately explored whether it's possible without breakage. 162 */ 163 $this->available_context = array_merge( $this->available_context, $this->context ); 164 143 165 if ( ! empty( $this->block_type->uses_context ) ) { 144 166 foreach ( $this->block_type->uses_context as $context_name ) { … … 149 171 } 150 172 151 if ( ! empty( $block['innerBlocks'] ) ) { 173 $this->refresh_parsed_block_dependents(); 174 } 175 176 /** 177 * Updates the parsed block content for the current block and its inner blocks. 178 * 179 * This method sets the `inner_html` and `inner_content` properties of the block based on the parsed 180 * block content provided during initialization. It ensures that the block instance reflects the 181 * most up-to-date content for both the inner HTML and any string fragments around inner blocks. 182 * 183 * If the block has inner blocks, this method initializes a new `WP_Block_List` for them, ensuring the 184 * correct content and context are updated for each nested block. 185 * 186 * @since 6.8.0 187 */ 188 public function refresh_parsed_block_dependents() { 189 if ( ! empty( $this->parsed_block['innerBlocks'] ) ) { 152 190 $child_context = $this->available_context; 153 191 … … 160 198 } 161 199 162 $this->inner_blocks = new WP_Block_List( $ block['innerBlocks'], $child_context, $registry );163 } 164 165 if ( ! empty( $ block['innerHTML'] ) ) {166 $this->inner_html = $ block['innerHTML'];167 } 168 169 if ( ! empty( $ block['innerContent'] ) ) {170 $this->inner_content = $ block['innerContent'];200 $this->inner_blocks = new WP_Block_List( $this->parsed_block['innerBlocks'], $child_context, $this->registry ); 201 } 202 203 if ( ! empty( $this->parsed_block['innerHTML'] ) ) { 204 $this->inner_html = $this->parsed_block['innerHTML']; 205 } 206 207 if ( ! empty( $this->parsed_block['innerContent'] ) ) { 208 $this->inner_content = $this->parsed_block['innerContent']; 171 209 } 172 210 } … … 507 545 $block_content .= $pre_render; 508 546 } else { 509 $source_block = $inner_block->parsed_block; 547 $source_block = $inner_block->parsed_block; 548 $inner_block_context = $inner_block->context; 510 549 511 550 /** This filter is documented in wp-includes/blocks.php */ … … 514 553 /** This filter is documented in wp-includes/blocks.php */ 515 554 $inner_block->context = apply_filters( 'render_block_context', $inner_block->context, $inner_block->parsed_block, $parent_block ); 555 556 /* 557 * The `refresh_context_dependents()` method already calls `refresh_parsed_block_dependents()`. 558 * Therefore the second condition is irrelevant if the first one is satisfied. 559 */ 560 if ( $inner_block->context !== $inner_block_context ) { 561 $inner_block->refresh_context_dependents(); 562 } elseif ( $inner_block->parsed_block !== $source_block ) { 563 $inner_block->refresh_parsed_block_dependents(); 564 } 516 565 517 566 $block_content .= $inner_block->render(); -
trunk/tests/phpunit/tests/blocks/renderBlock.php
r56761 r59662 193 193 $this->assertSame( array( 'example' => 'ok' ), $provided_context[0] ); 194 194 } 195 196 /** 197 * Tests the behavior of the 'render_block_context' filter based on the location of the filtered block. 198 * 199 * @ticket 62046 200 */ 201 public function test_render_block_context_inner_blocks() { 202 $provided_context = array(); 203 204 register_block_type( 205 'tests/context-provider', 206 array( 207 'provides_context' => array( 'example' ), 208 ) 209 ); 210 211 register_block_type( 212 'tests/context-consumer', 213 array( 214 'uses_context' => array( 'example' ), 215 'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) { 216 $provided_context = $block->context; 217 218 return ''; 219 }, 220 ) 221 ); 222 223 // Filter the context provided by the test block. 224 add_filter( 225 'render_block_context', 226 function ( $context, $parsed_block ) { 227 if ( isset( $parsed_block['blockName'] ) && 'tests/context-provider' === $parsed_block['blockName'] ) { 228 $context['example'] = 'ok'; 229 } 230 231 return $context; 232 }, 233 10, 234 2 235 ); 236 237 // Test inner block context when the provider block is a top-level block. 238 do_blocks( 239 <<<HTML 240 <!-- wp:tests/context-provider --> 241 <!-- wp:tests/context-consumer /--> 242 <!-- /wp:tests/context-provider --> 243 HTML 244 ); 245 $this->assertArrayHasKey( 'example', $provided_context, 'Test block is top-level block: Context should include "example"' ); 246 $this->assertSame( 'ok', $provided_context['example'], 'Test block is top-level block: "example" in context should be "ok"' ); 247 248 // Test inner block context when the provider block is an inner block. 249 do_blocks( 250 <<<HTML 251 <!-- wp:group {"layout":{"type":"constrained"}} --> 252 <!-- wp:tests/context-provider --> 253 <!-- wp:tests/context-consumer /--> 254 <!-- /wp:tests/context-provider --> 255 <!-- /wp:group --> 256 HTML 257 ); 258 $this->assertArrayHasKey( 'example', $provided_context, 'Test block is inner block: Block context should include "example"' ); 259 $this->assertSame( 'ok', $provided_context['example'], 'Test block is inner block: "example" in context should be "ok"' ); 260 } 261 262 /** 263 * Tests that the 'render_block_context' filter arbitrary context. 264 * 265 * @ticket 62046 266 */ 267 public function test_render_block_context_allowed_context() { 268 $provided_context = array(); 269 270 register_block_type( 271 'tests/context-consumer', 272 array( 273 'uses_context' => array( 'example' ), 274 'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) { 275 $provided_context = $block->context; 276 277 return ''; 278 }, 279 ) 280 ); 281 282 // Filter the context provided to the test block. 283 add_filter( 284 'render_block_context', 285 function ( $context, $parsed_block ) { 286 if ( isset( $parsed_block['blockName'] ) && 'tests/context-consumer' === $parsed_block['blockName'] ) { 287 $context['arbitrary'] = 'ok'; 288 } 289 290 return $context; 291 }, 292 10, 293 2 294 ); 295 296 do_blocks( 297 <<<HTML 298 <!-- wp:tests/context-consumer /--> 299 HTML 300 ); 301 $this->assertArrayNotHasKey( 'arbitrary', $provided_context, 'Test block is top-level block: Block context should not include "arbitrary"' ); 302 303 do_blocks( 304 <<<HTML 305 <!-- wp:group {"layout":{"type":"constrained"}} --> 306 <!-- wp:tests/context-consumer /--> 307 <!-- /wp:group --> 308 HTML 309 ); 310 311 /* 312 * These assertions assert something that ideally should not be the case: Inner blocks should respect the 313 * `uses_context` value just like top-level blocks do. However, due to logic in `WP_Block::render()`, the 314 * `context` property value itself is filterable when it should rather only apply to the `available_context` 315 * property. 316 * However, changing this behavior now would be a backward compatibility break, hence the assertion here. 317 * Potentially it can be reconsidered in the future, so that these two assertions could be replaced with an 318 * `assertArrayNotHasKey( 'arbitrary', $provided_context )`. 319 */ 320 $this->assertArrayHasKey( 'arbitrary', $provided_context, 'Test block is inner block: Block context should include "arbitrary"' ); 321 $this->assertSame( 'ok', $provided_context['arbitrary'], 'Test block is inner block: "arbitrary" in context should be "ok"' ); 322 } 195 323 }
Note: See TracChangeset
for help on using the changeset viewer.