$image ) { $id = $image['id']; $src = $image['src']; $srcset = $image['srcset']; $sizes = $image['sizes']; $alt = $image['alt']; $loading = 0 === $index ? 'fetchpriority="high"' : 'loading="lazy"'; $images_html .= "{$alt}"; } ob_start(); ?> . $pos = strrpos( $gallery_html, '' ); if ( false !== $pos ) { // Inject the dialog_html at the correct position. $html = substr_replace( $gallery_html, $dialog_html, $pos, 0 ); return $html; } return $gallery_html; } /** * Include and render the block. * * @param array $attributes Block attributes. Default empty array. * @param string $content Block content. Default empty string. * @param WP_Block $block Block instance. * @return string Rendered block type output. */ protected function render( $attributes, $content, $block ) { $post_id = $block->context['postId'] ?? ''; $product = wc_get_product( $post_id ); if ( ! $product instanceof \WC_Product ) { return ''; } $image_ids = ProductGalleryUtils::get_all_image_ids( $product ); $number_of_images = count( $image_ids ); $classname = StyleAttributesUtils::get_classes_by_attributes( $attributes, array( 'extra_classes' ) ); $initial_image_id = $number_of_images > 0 ? $image_ids[0] : -1; $classname_single_image = $number_of_images < 2 ? 'is-single-product-gallery-image' : ''; $product_id = strval( $product->get_id() ); $fullsize_image_data = ProductGalleryUtils::get_image_src_data( $image_ids, 'full', $product->get_title() ); $gallery_with_dialog = $this->inject_dialog( $content, $this->render_dialog( $fullsize_image_data ) ); $p = new \WP_HTML_Tag_Processor( $gallery_with_dialog ); $html = $gallery_with_dialog; if ( $p->next_tag() ) { $p->set_attribute( 'data-wp-interactive', $this->get_full_block_name() ); $p->set_attribute( 'data-wp-context', wp_json_encode( array( 'imageData' => $image_ids, 'isDialogOpen' => false, 'isDragging' => false, 'touchStartX' => 0, 'touchCurrentX' => 0, 'productId' => $product_id, 'selectedImageId' => $initial_image_id, 'thumbnailsOverflow' => [ 'top' => false, 'bottom' => false, 'left' => false, 'right' => false, ], // Next/Previous Buttons block context. 'hideNextPreviousButtons' => $number_of_images <= 1, 'isDisabledPrevious' => true, 'isDisabledNext' => false, 'ariaLabelPrevious' => __( 'Previous image', 'woocommerce' ), 'ariaLabelNext' => __( 'Next image', 'woocommerce' ), ), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ) ); if ( $product->is_type( ProductType::VARIABLE ) ) { $variations_data = $product->get_available_variations( 'objects' ); $formatted_variations_data = array(); $has_variation_images = false; foreach ( $variations_data as $variation ) { $variation_image_id = (int) $variation->get_image_id(); if ( $variation_image_id ) { $has_variation_images = true; $formatted_variations_data[ $variation->get_id() ] = array( 'image_id' => $variation_image_id, ); } } if ( $has_variation_images ) { wp_interactivity_config( 'woocommerce', array( 'products' => array( $product->get_id() => array( 'image_id' => (int) $product->get_image_id(), 'variations' => $formatted_variations_data, ), ), ) ); // Support legacy Add to Cart with Options block. $p->set_attribute( 'data-wp-init--watch-changes-on-add-to-cart-form', 'callbacks.watchForChangesOnAddToCartForm' ); // Support blockified Add to Cart + Options block. $p->set_attribute( 'data-wp-watch', 'callbacks.listenToProductDataChanges' ); } } $p->add_class( $classname ); $p->add_class( $classname_single_image ); $html = $p->get_updated_html(); } return $html; } }