Make WordPress Core

Opened 2 years ago

Closed 2 years ago

#56941 closed defect (bug) (worksforme)

Fatal error produced by block using closure as render_callback

Reported by: andrewleap's profile andrewleap Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Themes Keywords:
Focuses: Cc:

Description

The following code causes site to blow up on front and in post editor

register_block_type(
	__DIR__,
	array(
                                     // attempted to serialize closure      
		'render_callback' => function( $attributes, $content, $block ){}
	)
);


Fatal error: Uncaught Exception: Serialization of 'Closure' is not allowed in /app/wp-includes/block-supports/elements.php...

Change History (5)

#1 follow-up: @wildworks
2 years ago

I could not reproduce it in either WordPress 6.0 or 6.1-RC6. Did it work correctly in WordPress 6.0?

Here is my test procedure:

  • Run npx @wordpress/create-block test-block directly under the plugin directory
  • Update test-block.php as follows:
function create_block_test_block_block_init() {
	register_block_type(
		__DIR__ . '/build',
		array(
			'render_callback' => function( $attributes, $content, $block ) {
				return 'rendered';
			},
		)
	);
}
add_action( 'init', 'create_block_test_block_block_init' );
  • Insert the block into the editor and save it
  • Confirm that no errors occur in both the editor and the front end

#2 @audrasjb
2 years ago

@andrewleap thanks for the ticket!

Could you please provide more info about the WordPress version you used when you produced this issue? Thanks :)

#3 in reply to: ↑ 1 @andrewleap
2 years ago

Apologies, This was my mistake. I was panicking as the new version is being released imminently .

The culprit was actually this in my theme:

/**
 * Add a reference to block parent in render function.
 *
 * @param array $parsed_block Block data.
 */
function xd_append_parent_block_data( $parsed_block ) {
	$block = new WP_Block( $parsed_block );
	foreach ( $parsed_block['innerBlocks'] as &$inner_block ) {
		$inner_block['parent'] = array(
			'name'  => $block->name,
			'props' => $block->attributes,
			'block' => $block,
		);
	}
	return $parsed_block;
}

add_filter( 'render_block_data', 'xd_append_parent_block_data' );

We add a reference to the parent block in the block data as this allows us to contextually change the output in the render function. That parent block will also have a closure for its render callback function. Of Course, the block serialization that was recently added will not play nice when trying to serialize a callback.

<?php
function wp_get_elements_class_name( $block ) {
        return 'wp-elements-' . md5( serialize( $block ) );
}

We can fix this with update to our plugin. Thanks for taking the time to look at this.

#4 @audrasjb
2 years ago

  • Keywords reporter-feedback added
  • Milestone changed from Awaiting Review to 6.1

Moving to milestone 6.1 for better visibility, while we're waiting for reporter feedback.

Version 0, edited 2 years ago by audrasjb (next)

#5 @audrasjb
2 years ago

  • Keywords reporter-feedback removed
  • Milestone 6.1 deleted
  • Resolution set to worksforme
  • Severity changed from blocker to normal
  • Status changed from assigned to closed
  • Version 6.1 deleted

Closing as per comment 3 :)

Note: See TracTickets for help on using tickets.