Automattic\WooCommerce\Blocks\BlockTypes

ProductImage::render_image │ private │ WC 1.0

Render Image.

Method of the class: ProductImage{}

Returns

string.

Usage

// private - for code of main (parent) class only
$result = $this->render_image( $product, $attributes, $image_id );
$product(WC_Product) (required)
Product object.
$attributes(array) (required)
Parsed attributes.
$image_id(int|null)
Optional image ID from context.
Default: null

ProductImage::render_image() code WC 11.1.2

private function render_image( $product, $attributes, $image_id = null ) {
	$image_size  = 'large';
	$image_style = '';

	if ( ! empty( $attributes['height'] ) ) {
		$image_style .= sprintf( 'height:%s;', $attributes['height'] );
	}
	if ( ! empty( $attributes['width'] ) ) {
		$image_style .= sprintf( 'width:%s;', $attributes['width'] );
	}
	if ( ! empty( $attributes['scale'] ) ) {
		$image_style .= sprintf( 'object-fit:%s;', $attributes['scale'] );
	}

	$aspect_ratio = $this->resolve_aspect_ratio( $attributes );
	if ( $aspect_ratio ) {
		$image_style .= sprintf( 'aspect-ratio:%s;', $aspect_ratio );
	}

	if ( ! empty( $attributes['style']['dimensions']['minHeight'] ) ) {
		$image_style .= sprintf( 'min-height:%s;', $attributes['style']['dimensions']['minHeight'] );
	}

	$featured_image_id          = (int) $product->get_image_id();
	$provided_image_id_is_valid = false;

	if ( $image_id ) {
		$gallery_image_ids          = ProductGalleryUtils::get_all_image_ids( $product );
		$available_image_ids        = array_merge( [ $featured_image_id ], $gallery_image_ids );
		$provided_image_id_is_valid = in_array( $image_id, $available_image_ids, true );
	}

	$target_image_id = $provided_image_id_is_valid ? $image_id : $featured_image_id;

	if ( ! $target_image_id ) {
		return wc_placeholder_img(
			$image_size,
			array(
				'style'         => $image_style,
				'data-image-id' => 0,
			)
		);
	}

	$alt_text = get_post_meta( $target_image_id, '_wp_attachment_image_alt', true );

	/**
	 * Filters the loading attribute for product images.
	 *
	 * Allowed values are 'lazy', 'eager', and 'auto'. Any other value will result in default browser behavior.
	 *
	 * @since 10.6.0
	 *
	 * @param string $loading_attr The loading attribute. Default 'lazy'.
	 * @param int    $image_id     Target image ID.
	 */
	$loading_attr = apply_filters(
		'woocommerce_product_image_loading_attr',
		'lazy',
		$target_image_id,
	);

	$loading_attr    = is_string( $loading_attr ) ? strtolower( trim( $loading_attr ) ) : '';
	$allowed_loading = array( 'lazy', 'eager', 'auto' );

	if ( ! in_array( $loading_attr, $allowed_loading, true ) ) {
		$loading_attr = '';
	}

	$attr = array(
		'alt'           => empty( $alt_text ) ? $product->get_title() : $alt_text,
		'data-testid'   => 'product-image',
		'data-image-id' => $target_image_id,
		'style'         => $image_style,
	);

	if ( ! empty( $loading_attr ) ) {
		$attr['loading'] = $loading_attr;
	}

	$srcset_aspect_ratio = $aspect_ratio;
	if ( is_numeric( $srcset_aspect_ratio ) ) {
		$srcset_aspect_ratio = (string) $srcset_aspect_ratio . '/1';
	}

	$adjust_srcset = function ( $sources, $size_array, $image_src, $image_meta ) use ( $srcset_aspect_ratio ) {
		if (
			! is_string( $srcset_aspect_ratio ) ||
			! is_array( $sources ) ||
			! is_array( $image_meta ) ||
			! isset( $image_meta['width'], $image_meta['height'] ) ||
			! is_numeric( $image_meta['width'] ) ||
			! is_numeric( $image_meta['height'] ) ||
			$image_meta['width'] <= 0 ||
			$image_meta['height'] <= 0
		) {
			return $sources;
		}

		$aspect_ratio_parts = explode( '/', $srcset_aspect_ratio );

		if (
			count( $aspect_ratio_parts ) !== 2 ||
			! is_numeric( $aspect_ratio_parts[0] ) ||
			! is_numeric( $aspect_ratio_parts[1] ) ||
			$aspect_ratio_parts[0] <= 0 ||
			$aspect_ratio_parts[1] <= 0
		) {
			return $sources;
		}

		$block_aspect_ratio = $aspect_ratio_parts[0] / $aspect_ratio_parts[1];
		$image_aspect_ratio = $image_meta['width'] / $image_meta['height'];

		if ( $image_aspect_ratio > $block_aspect_ratio ) {
			$stretch_factor = $image_aspect_ratio / $block_aspect_ratio;

			foreach ( $sources as $key => $source ) {
				if ( ! is_array( $source ) || ! isset( $source['value'] ) || ! is_numeric( $source['value'] ) ) {
					continue;
				}
				$sources[ $key ]['value'] = max( 1, (int) round( $source['value'] / $stretch_factor ) );
			}
		}

		return $sources;
	};

	$maybe_adjust_srcset =
		'cover' === $attributes['scale'] &&
		is_string( $srcset_aspect_ratio ) &&
		false !== strpos( $srcset_aspect_ratio, '/' );

	if ( $maybe_adjust_srcset ) {
		add_filter( 'wp_calculate_image_srcset', $adjust_srcset, 10, 4 );
	}

	try {
		$image_html = $provided_image_id_is_valid ? wp_get_attachment_image( $image_id, $image_size, false, $attr ) : $product->get_image( $image_size, $attr );
	} finally {
		if ( $maybe_adjust_srcset ) {
			remove_filter( 'wp_calculate_image_srcset', $adjust_srcset, 10 );
		}
	}

	return $image_html;
}