Commit 0ae03265de6 for woocommerce
commit 0ae03265de64db2e1402ad11250a8f55ac92d6b7
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date: Thu Jul 23 11:54:37 2026 +0300
Pass placeholder image attributes to filter (#66691)
fix: pass placeholder image attributes to filter
The wc_placeholder_img() helper accepts and applies custom image attributes, but the woocommerce_placeholder_img filter only received the rendered HTML, size, and dimensions.
Append the parsed attribute array as the fourth filter argument so extensions can replace or inspect placeholder image HTML without parsing the markup. Existing callbacks keep the same argument order and continue to work with their current accepted_args values.
Refs #55501
diff --git a/plugins/woocommerce/changelog/fix-55501-placeholder-image-filter-attr b/plugins/woocommerce/changelog/fix-55501-placeholder-image-filter-attr
new file mode 100644
index 00000000000..d1f8ad91572
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-55501-placeholder-image-filter-attr
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Pass placeholder image attributes to the placeholder image filter.
diff --git a/plugins/woocommerce/includes/wc-product-functions.php b/plugins/woocommerce/includes/wc-product-functions.php
index 56a7c3dab08..393a980227e 100644
--- a/plugins/woocommerce/includes/wc-product-functions.php
+++ b/plugins/woocommerce/includes/wc-product-functions.php
@@ -481,7 +481,18 @@ function wc_placeholder_img( $size = 'woocommerce_thumbnail', $attr = '' ) {
$image_html = '<img src="' . esc_url( $image ) . '" ' . $hwstring . implode( ' ', $attributes ) . '/>';
}
- return apply_filters( 'woocommerce_placeholder_img', $image_html, $size, $dimensions );
+ /**
+ * Filters the placeholder image HTML.
+ *
+ * @param string $image_html The placeholder image HTML.
+ * @param string $size Image size.
+ * @param array $dimensions Image width and height.
+ * @param array $attr Attributes for the image markup.
+ *
+ * @since 2.0.0
+ * @since 11.1.0 Added the `$attr` parameter.
+ */
+ return apply_filters( 'woocommerce_placeholder_img', $image_html, $size, $dimensions, $attr );
}
/**
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/product/functions.php b/plugins/woocommerce/tests/legacy/unit-tests/product/functions.php
index ac1cbbfb5d5..f4b29bef240 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/product/functions.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/product/functions.php
@@ -1015,6 +1015,31 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
$this->assertStringContainsString( 'class="custom-class"', wc_placeholder_img( 'woocommerce_thumbnail', $attr ) );
}
+ /**
+ * @testdox Should pass image attributes to the placeholder image filter.
+ */
+ public function test_wc_placeholder_img_filter_receives_attributes() {
+ $captured_attr = null;
+ $attr = array(
+ 'class' => 'custom-class',
+ 'alt' => 'Custom alt',
+ );
+ $filter = function ( $image_html, $size, $dimensions, $filter_attr = null ) use ( &$captured_attr ) {
+ $captured_attr = $filter_attr;
+
+ return $image_html;
+ };
+
+ add_filter( 'woocommerce_placeholder_img', $filter, 10, 4 );
+ try {
+ wc_placeholder_img( 'woocommerce_thumbnail', $attr );
+ } finally {
+ remove_filter( 'woocommerce_placeholder_img', $filter, 10 );
+ }
+
+ $this->assertSame( $attr, $captured_attr );
+ }
+
/**
* @testdox Should use the filtered placeholder source for an attachment placeholder.
*/