bal post * instead of fetching the product through the `productId` attribute, so even if the * `productId` is passed to the inner block, it will still use the global post. * * @param array $block Block attributes. * @param array $context Block context. */ protected function replace_post_for_single_product_inner_block( $block, &$context ) { if ( $this->single_product_inner_blocks_names ) { // Find the block index in $this->single_product_inner_blocks_names // starting from the end. $block_index_reversed = array_search( $block['blockName'], array_reverse( $this->single_product_inner_blocks_names ), true ); if ( false !== $block_index_reversed ) { $block_index = count( $this->single_product_inner_blocks_names ) - (int) $block_index_reversed - 1; $block_name = $block['blockName']; // Remove all blocks after the current one. In some cases, like // in the Product Gallery block, inner blocks are rendered // directly by the parent block, so we need to skip them. $this->single_product_inner_blocks_names = array_slice( $this->single_product_inner_blocks_names, 0, $block_index ); /** * This is a temporary fix to ensure the Post Title and Excerpt blocks work as expected * until Gutenberg versions 15.2 and 15.6 are included in the core of WordPress. * * Important: the original post data is restored in the restore_global_post method. * * @see https://github.com/WordPress/gutenberg/pull/48001 * @see https://github.com/WordPress/gutenberg/pull/49495 */ if ( 'core/post-excerpt' === $block_name || 'core/post-title' === $block_name ) { global $post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited $post = get_post( $this->product_id ); if ( $post instanceof \WP_Post ) { setup_postdata( $post ); } } $context['postId'] = $this->product_id; $context['singleProduct'] = true; } } } /** * Render the Single Product block. * * @param array $attributes Block attributes. * @param string $content Block content. * @param WP_Block $block Block instance. * * @return string Rendered block type output. */ protected function render( $attributes, $content, $block ) { $product = wc_get_product( $block->context['postId'] ); if ( ! $product instanceof \WC_Product ) { return ''; } $interactivity_context = array( 'productId' => $product->get_id(), 'variationId' => null, ); $html = new \WP_HTML_Tag_Processor( $content ); if ( $html->next_tag( array( 'tag_name' => 'div' ) ) ) { $html->set_attribute( 'data-wp-interactive', $this->get_full_block_name() ); $html->set_attribute( 'data-wp-context', wp_json_encode( $interactivity_context, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ) ); } $updated_html = $html->get_updated_html(); return parent::render( $attributes, $updated_html, $block ); } /** * Get the frontend script handle for this block type. * * @param string $key Data to get, or default to everything. * * @return null This block has no frontend script. */ protected function get_block_type_script( $key = null ) { return null; } }
Fatal error: Uncaught Error: Class "Automattic\WooCommerce\Blocks\BlockTypes\SingleProduct" not found in /htdocs/wp-content/plugins/woocommerce/src/Blocks/BlockTypesController.php:118 Stack trace: #0 /htdocs/wp-includes/class-wp-hook.php(341): Automattic\WooCommerce\Blocks\BlockTypesController->register_blocks('') #1 /htdocs/wp-includes/class-wp-hook.php(365): WP_Hook->apply_filters(NULL, Array) #2 /htdocs/wp-includes/plugin.php(522): WP_Hook->do_action(Array) #3 /htdocs/wp-settings.php(742): do_action('init') #4 /htdocs/wp-config.php(98): require_once('/htdocs/wp-sett...') #5 /htdocs/wp-load.php(50): require_once('/htdocs/wp-conf...') #6 /htdocs/wp-blog-header.php(13): require_once('/htdocs/wp-load...') #7 /htdocs/index.php(17): require('/htdocs/wp-blog...') #8 {main} thrown in /htdocs/wp-content/plugins/woocommerce/src/Blocks/BlockTypesController.php on line 118