Edit file File name : ProductGalleryUtils.php Content :<?php namespace Automattic\WooCommerce\Blocks\Utils; /** * Utility methods used for the Product Gallery block. * {@internal This class and its methods are not intended for public use.} */ class ProductGalleryUtils { const CROP_IMAGE_SIZE_NAME = '_woo_blocks_product_gallery_crop_full'; /** * When requesting a full-size image, this function may return an array with a single image. * However, when requesting a non-full-size image, it will always return an array with multiple images. * This distinction is based on the image size needed for rendering purposes: * - "Full" size is used for the main product featured image. * - Non-full sizes are used for rendering thumbnails. * * @param int $post_id Post ID. * @param string $size Image size. * @param array $attributes Attributes. * @param string $wrapper_class Wrapper class. * @param bool $crop_images Whether to crop images. * @return array */ public static function get_product_gallery_images( $post_id, $size = 'full', $attributes = array(), $wrapper_class = '', $crop_images = false ) { $product_gallery_images = array(); $product = wc_get_product( $post_id ); if ( $product ) { $all_product_gallery_image_ids = self::get_product_gallery_image_ids( $product ); if ( 'full' === $size || 'full' !== $size && count( $all_product_gallery_image_ids ) > 1 ) { $size = $crop_images ? self::CROP_IMAGE_SIZE_NAME : $size; foreach ( $all_product_gallery_image_ids as $product_gallery_image_id ) { if ( '0' !== $product_gallery_image_id ) { if ( $crop_images ) { self::maybe_generate_intermediate_image( $product_gallery_image_id, self::CROP_IMAGE_SIZE_NAME ); } $product_image_html = wp_get_attachment_image( $product_gallery_image_id, $size, false, $attributes ); } else { $product_image_html = self::get_product_image_placeholder_html( $size, $attributes, $crop_images ); } if ( $wrapper_class ) { $product_image_html = '<div class="' . $wrapper_class . '">' . $product_image_html . '</div>'; } $product_image_html_processor = new \WP_HTML_Tag_Processor( $product_image_html ); $product_image_html_processor->next_tag( 'img' ); $product_image_html_processor->set_attribute( 'data-wc-context', wp_json_encode( array( 'imageId' => $product_gallery_image_id, ) ) ); $product_gallery_images[] = $product_image_html_processor->get_updated_html(); } } } return $product_gallery_images; } /** * Get the product gallery image IDs. * * @param \WC_Product $product The product object to retrieve the gallery images for. * @param int $max_number_of_visible_images The maximum number of visible images to return. Defaults to 8. * @param bool $only_visible Whether to return only the visible images. Defaults to false. * @return array An array of unique image IDs for the product gallery. */ public static function get_product_gallery_image_ids( $product, $max_number_of_visible_images = 8, $only_visible = false ) { // Main product featured image. $featured_image_id = $product->get_image_id(); // All other product gallery images. $product_gallery_image_ids = $product->get_gallery_image_ids(); // If the Product image is not set, we need to set it to a placeholder image. if ( '' === $featured_image_id ) { $featured_image_id = '0'; } // We don't want to show the same image twice, so we have to remove the featured image from the gallery if it's there. $unique_image_ids = array_unique( array_merge( array( $featured_image_id ), $product_gallery_image_ids ) ); foreach ( $unique_image_ids as $key => $image_id ) { $unique_image_ids[ $key ] = strval( $image_id ); } if ( count( $unique_image_ids ) > $max_number_of_visible_images && $only_visible ) { $unique_image_ids = array_slice( $unique_image_ids, 0, $max_number_of_visible_images ); } // Reindex array. $unique_image_ids = array_values( $unique_image_ids ); return $unique_image_ids; } /** * Generates the intermediate image sizes only when needed. * * @param int $attachment_id Attachment ID. * @param string $size Image size. * @return void */ public static function maybe_generate_intermediate_image( $attachment_id, $size ) { $metadata = image_get_intermediate_size( $attachment_id, $size ); $upload_dir = wp_upload_dir(); $image_path = ''; if ( $metadata ) { $image_path = $upload_dir['basedir'] . '/' . $metadata['path']; } /* * We need to check both if the size metadata exists and if the file exists. * Sometimes we can have orphaned image file and no metadata or vice versa. */ if ( $metadata && file_exists( $image_path ) ) { return; } $image_path = wp_get_original_image_path( $attachment_id ); $image_metadata = wp_get_attachment_metadata( $attachment_id ); // If image sizes are not available. Bail. if ( ! isset( $image_metadata['width'], $image_metadata['height'] ) ) { return; } /* * We want to take the minimum dimension of the image and * use that size as the crop size for the new image. */ $min_size = min( $image_metadata['width'], $image_metadata['height'] ); $new_image_metadata = image_make_intermediate_size( $image_path, $min_size, $min_size, true ); $image_metadata['sizes'][ $size ] = $new_image_metadata; wp_update_attachment_metadata( $attachment_id, $image_metadata ); } /** * Get the product image placeholder HTML. * * @param string $size Image size. * @param array $attributes Attributes. * @param bool $crop_images Whether to crop images. * @return string */ public static function get_product_image_placeholder_html( $size, $attributes, $crop_images ) { $placeholder_image_id = get_option( 'woocommerce_placeholder_image', 0 ); if ( ! $placeholder_image_id ) { // Return default fallback WooCommerce placeholder image. return wc_placeholder_img( array( '', '' ), $attributes ); } if ( $crop_images ) { self::maybe_generate_intermediate_image( $placeholder_image_id, self::CROP_IMAGE_SIZE_NAME ); } return wp_get_attachment_image( $placeholder_image_id, $size, false, $attributes ); } } Save