Duplicated pic in thumbnail gallery in Woocommerce - php

I'm building a Woocommerce site.
In the Shop grid overview, I'm showing the Featured Image of each product (see link). This Featured image will be cropped to maintain the same image ratio in the Shop Grid.
In the Single Product page, I managed to hide the Featured Image, and make the first of the thumbnails appear in big (see link).
I did so with the following code:
<div class="images">
<?php
$imgid = $product->get_gallery_attachment_ids();
?>
<a href="<?php echo wp_get_attachment_url( $imgid[0] ); ?>"
class="woocommerce-main-image zoom first"
rel="lightbox[product-gallery]">
<img src="<?php echo wp_get_attachment_url( $imgid[0] ); ?>" alt="">
</a>
<?php do_action( 'woocommerce_product_thumbnails' ); ?>
</div>
<script>
jQuery('.thumbnails.columns-3 a:first-child').hide()
</script>
The first part will find the first image in the gallery array and show it in big size (class woocommerce-main-image zoom first) while linking to the lightbox.
Then I call the thumbnails, and I hide the first one using jQuery to avoid a duplicate (first big size image and first thumb are the same).
The problem now is that in the Lightbox, the first image will appear duplicated, as it exists two times in the array, the first one I call in big, and the one from the thumbs array.
Any tips on how to not show the image twice in the lightbox?
Someone mentioned that I should filter the following function, but as of now I don't know how to do that.
public function get_gallery_attachment_ids() {
return apply_filters( 'woocommerce_product_gallery_attachment_ids', array_filter( (array) explode( ',', $this->product_image_gallery ) ), $this );
}

I think that using Multiple Post Thumbnails is the easiest solution. It is exactly for displaying different featured images in different locations.
Option #1: Multiple Post Thumbnails
You would install the plugin and then add the following to your theme's functions.php. It isn't 100% tested so there may be a stray typo or something. Full documentation is here.
// register the new thumbnail
function so_31835142_register_extra_thumbnail() {
if (class_exists('MultiPostThumbnails')) {
new MultiPostThumbnails(
array(
'label' => __('Product Loop Image', 'your-theme'),
'id' => 'product-loop-image',
'post_type' => 'product'
)
);
}
}
add_action( 'after_setup_theme', 'so_31835142_register_extra_thumbnail' );
// remove the existing loop thumbnail
function so_31835142_swap_loop_product_thumbnail(){
if (class_exists('MultiPostThumbnails')) {
remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
add_action( 'woocommerce_before_shop_loop_item_title', 'so_31835142_loop_product_thumbnail', 10 );
}
}
add_action( 'woocommerce_before_shop_loop_item, 'so_31835142_swap_loop_product_thumbnail' );
// Display the Secondary Thumbnail
function so_31835142_loop_product_thumbnail(){
global $product;
$thumbnail = MultiPostThumbnails::get_post_thumbnail(
'product',
'product-loop-image',
$product->id,
'shop_catalog'
);
if ( $thumbnail ) {
return $thumbnail;
} elseif ( wc_placeholder_img_src() ) {
return wc_placeholder_img( $size );
}
}
Then to use it, you'd set "Product Loop Image" the same way you traditionally set the "featured image". And this new image would be used in the loop.
Option #2: Template Overrides
But as an alternative, if you insist, you can write a custom single-product/product-image.php template and put it in your theme's woocommerce templates folder.
In this alternative we will only show images from the image gallery on the single product page, $product->get_gallery_attachment_ids(), and we will use a basic PHP loop and counter system to display the images differently depending on where they are in the loop. IE. the first image will display as the post thumbnail used to display and the remaining items will display as thumbs.
This section I have tested, so it should (in theory) be good to go.
<?php
/**
* Single Product Image
*
* #author WooThemes
* #package WooCommerce/Templates
* #version 2.0.14
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
global $post, $woocommerce, $product;
?>
<div class="images">
<?php
$attachment_ids = $product->get_gallery_attachment_ids();
if ( $attachment_ids ) {
$loop = 0;
$columns = apply_filters( 'woocommerce_product_thumbnails_columns', 3 );
$attachment_count = count( $attachment_ids );
foreach ( $attachment_ids as $attachment_id ) {
// here's your first image
if( $loop === 0 ){
$image_title = esc_attr( get_the_title( $attachment_id ) );
$image_caption = get_post( $attachment_id )->post_excerpt;
$image_link = wp_get_attachment_url( $attachment_id );
$image = wp_get_attachment_image( $attachment_id, apply_filters( 'single_product_large_thumbnail_size', 'shop_single' ), null, array(
'title' => $image_title,
'alt' => $image_title
) );
if ( $attachment_count > 0 ) {
$gallery = '[product-gallery]';
} else {
$gallery = '';
}
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s', $image_link, $image_caption, $image ), $post->ID );
// resume the thumbnails for the rest
} else {
// open the thumbnails div
if( $loop === 1 ) { ?>
<div class="thumbnails <?php echo 'columns-' . $columns; ?>">
<?php }
$classes = array( 'zoom' );
if ( $loop == 0 || $loop % $columns == 0 )
$classes[] = 'first';
if ( ( $loop + 1 ) % $columns == 0 )
$classes[] = 'last';
$image_link = wp_get_attachment_url( $attachment_id );
if ( ! $image_link )
continue;
$image_title = esc_attr( get_the_title( $attachment_id ) );
$image_caption = esc_attr( get_post_field( 'post_excerpt', $attachment_id ) );
$image = wp_get_attachment_image( $attachment_id, apply_filters( 'single_product_small_thumbnail_size', 'shop_thumbnail' ), 0, $attr = array(
'title' => $image_title,
'alt' => $image_title
) );
$image_class = esc_attr( implode( ' ', $classes ) );
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', sprintf( '%s', $image_link, $image_class, $image_caption, $image ), $attachment_id, $post->ID, $image_class );
// close the thumbnails div
if( $loop === $attachment_count ) { ?>
</div>
<?php }
}
$loop++;
}
?>
<?php
} else {
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '<img src="%s" alt="%s" />', wc_placeholder_img_src(), __( 'Placeholder', 'woocommerce' ) ), $post->ID );
}
?>
</div>

Related

Add title underneath WooCommerce product gallery images

I want to get the 'title' of each image to display underneath each image in the Woocommerce product gallery. Not the main image, but the smaller clickable thumbnails.
All of my images currently have titles set.
I have looked in product-thumbnails.php and have found this code:
if ( $attachment_ids && has_post_thumbnail() ) {
foreach ( $attachment_ids as $attachment_id ) {
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', wc_get_gallery_image_html( $attachment_id ), $attachment_id );
}
}
I believe this is what I need to edit but I am not sure what to add.
I also found this post where a similar thing has been asked but for captions Show caption under product gallery in WooCommerce, however it doesn't work when I add it
Any ideas?
EDIT
So I have copied the function from wc-template-functions.php into my child themes functions.php file:
function wc_get_gallery_image_html( $attachment_id, $main_image = false ) {
$flexslider = (bool) apply_filters( 'woocommerce_single_product_flexslider_enabled', get_theme_support( 'wc-product-gallery-slider' ) );
$gallery_thumbnail = wc_get_image_size( 'gallery_thumbnail' );
$thumbnail_size = apply_filters( 'woocommerce_gallery_thumbnail_size', array( $gallery_thumbnail['width'], $gallery_thumbnail['height'] ) );
$image_size = apply_filters( 'woocommerce_gallery_image_size', $flexslider || $main_image ? 'woocommerce_single' : $thumbnail_size );
$full_size = apply_filters( 'woocommerce_gallery_full_size', apply_filters( 'woocommerce_product_thumbnails_large_size', 'full' ) );
$thumbnail_src = wp_get_attachment_image_src( $attachment_id, $thumbnail_size );
$full_src = wp_get_attachment_image_src( $attachment_id, $full_size );
$image = wp_get_attachment_image( $attachment_id, $image_size, false, array(
'title' => get_post_field( 'post_title', $attachment_id ),
'data-caption' => get_post_field( 'post_excerpt', $attachment_id ),
'data-src' => $full_src[0],
'data-large_image' => $full_src[0],
'data-large_image_width' => $full_src[1],
'data-large_image_height' => $full_src[2],
'class' => $main_image ? 'wp-post-image' : '',
) );
return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" class="woocommerce-product-gallery__image">' . $image . '</div>';
}
I also renamed the function wc_get_gallery_image_with_title_html as well as changing the return line to this:
return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" class="woocommerce-product-gallery__image">' . $image . $imageTitle . '</div>';
It doesn't seem to work. However, if i add in the word TEST in place of $imageTitle in the return line above to see if anything will appear, the word TEST does appear below every image.
The word test doesnt appear under each thumbnail though, it appears under the main gallery image.
What am I missing or doing wrong here?
EDIT
Now the title shows thanks to Zipkundan's help, but it shows under the main image and not under each thumbnail. How can I move it to show under each relevant thumbnail?
Here, "wc_get_gallery_image_html( $attachment_id )" (one of the argument in the filter) is what outputs the final html. This is a function defined in "wc-template-functions.php". Thus you can not alter this function. You can see the function code at following URL:
http://woocommerce.wp-a2z.org/oik_api/wc_get_gallery_image_html/
Well, here's some hint for you to workout your way.
Hope you are using child theme. Copy the function code (the function which is passed as argument in filter) in your child theme's "functions.php" file. Name the function something different, say "wc_get_gallery_image_with_title_html". Alter that code to append the image title in the 'return' statement. Something like:
return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" class="woocommerce-product-gallery__image">' . $image . $imageTitle . '</div>';
Where, $imageTitle will be the title of the image wrapped into some html tag like 'span' or 'p'.
Then copy the file "product-thumbnails.php" into you child theme and replace the original function argument with the new function you have created. So the code becomes like this:
if ( $attachment_ids && has_post_thumbnail() ) {
foreach ( $attachment_ids as $attachment_id ) {
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', wc_get_gallery_image_with_title_html( $attachment_id ), $attachment_id );
}}
Hope this helps.
Update (after your Edit)
Hi Kiki,
You were missing output of the image title in the function. Following is the updated function.
function wc_get_gallery_image_with_title_html( $attachment_id, $main_image = false ) {
$flexslider = (bool) apply_filters( 'woocommerce_single_product_flexslider_enabled', get_theme_support( 'wc-product-gallery-slider' ) );
$gallery_thumbnail = wc_get_image_size( 'gallery_thumbnail' );
$thumbnail_size = apply_filters( 'woocommerce_gallery_thumbnail_size', array( $gallery_thumbnail['width'], $gallery_thumbnail['height'] ) );
$image_size = apply_filters( 'woocommerce_gallery_image_size', $flexslider || $main_image ? 'woocommerce_single' : $thumbnail_size );
$full_size = apply_filters( 'woocommerce_gallery_full_size', apply_filters( 'woocommerce_product_thumbnails_large_size', 'full' ) );
$thumbnail_src = wp_get_attachment_image_src( $attachment_id, $thumbnail_size );
$full_src = wp_get_attachment_image_src( $attachment_id, $full_size );
$image = wp_get_attachment_image( $attachment_id, $image_size, false, array(
'title' => get_post_field( 'post_title', $attachment_id ),
'data-caption' => get_post_field( 'post_excerpt', $attachment_id ),
'data-src' => $full_src[0],
'data-large_image' => $full_src[0],
'data-large_image_width' => $full_src[1],
'data-large_image_height' => $full_src[2],
'class' => $main_image ? 'wp-post-image' : '',
) );
$imageTitle = '<span>' . esc_html( get_the_title($attachment_id) ) . '</span>';
return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" class="woocommerce-product-gallery__image">' . $image . $imageTitle . '</div>';
}
Note the line before 'return' statement.
Try using the above function and don't forget to change the argument function in "product-thumbnails.php".
Also, once you get the image title text displayed, you might need to add some css rules for the text to display properly.
Hope this works.
Since the gallery thumbnail images are dynamically generated and appended via javascript, it can be customized only via javascript.
Following javascript custom function will append the title of product image in the gallery to its respective thumbnail in gallery navigation.
jQuery(window).load(function(){
if( jQuery('body').hasClass('single-product') ){
var imgtitles = [];
jQuery('.woocommerce-product-gallery__wrapper').children('div').each(function(){
var imgTitle = jQuery(this).find('a').find('img.wp-post-image').attr('title');
console.log(imgTitle);
imgtitles.push(imgTitle);
});
if( jQuery('ol.flex-control-nav').length && jQuery('ol.flex-control-nav').children().length>1 ){
for(i=0; i<imgtitles.length; ++i){
jQuery('ol.flex-control-nav li:nth-child('+(i+1)+')').append('<span class="flexthum-title">'+imgtitles[i]+'</span>');
}
}
}});
You can see a working example here.
http://woocom.stuprohosting.in/product/vneck-tee/
If this gives you desired result, then I would recommend to discard changes you have made in "functions.php" and "product-thumbnails.php" which I suggested in previous answer.
I have used plugin "Header and Footer Scripts" to add this custom function in website footer. https://wordpress.org/plugins/header-and-footer-scripts/
jQuery(window).load(function(){
if( jQuery('body').hasClass('single-product') ){
var imgtitles = [];
jQuery('.woocommerce-product-gallery__wrapper').children('div').each(function(){
var imgTitle = jQuery(this).find('a').find('img').attr('data-caption');
console.log(imgTitle);
imgtitles.push(imgTitle);
});
if( jQuery('ol.flex-control-nav').length && jQuery('ol.flex-control-nav').children().length>1 ){
for(i=0; i<imgtitles.length; ++i){
jQuery('ol.flex-control-nav li:nth-child('+(i+1)+')').append('<span class="flexthum-title">'+imgtitles[i]+'</span>');
}
}
}});

Woocommerce full size img with large - product-image.php

I want to replace full size image with large image on woocommerce lighbox.
here is my code -
<?php
if ( has_post_thumbnail() ) {
$image = get_the_post_thumbnail( $post->ID, apply_filters( 'single_product_large_thumbnail_size', 'shop_single' ) );
$image_title = esc_attr( get_the_title( get_post_thumbnail_id() ) );
$image_link = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID) );
$attachment_count = count( $product->get_gallery_attachment_ids() );
if ( $attachment_count > 0 ) {
$gallery = '[product-gallery]';
} else {
$gallery = '';
}
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s', $image_link, $image_title, $image ), $post->ID );
} else {
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '<img src="%s" alt="Placeholder" class="bigbox" />', woocommerce_placeholder_img_src() ), $post->ID );
}
?>
<?php do_action( 'woocommerce_product_thumbnails' ); ?>
I've tried to change $image_link to
$image_link = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'large' );
with no luck.
The $image_link comes as array. to echo the image link, try,
<?php echo $image_link[0]; ?>
So your full code should be like this
WooCommerce has the filter 'woocommerce_single_product_image_html' , you don't repeat the code in your theme for this.
You would add the following in your functions.php or your functions plugin.
Note: this works in 2.6x and will not work with 2.7 since they changed the single image display a lot.
function yourprefix_woocommerce_single_product_image_html( $html, $post_id ) {
if ( ! class_exists( 'WooCommerce' ) ) return;
//bail if WooCommerce is not installed and active since we are using the WC_VERSION constant
if ( version_compare( WC_VERSION, '2.7', '<' ) ) {
$image_title = esc_attr( get_the_title( get_post_thumbnail_id() ) );
$image_link = wp_get_attachment_image_src( get_post_thumbnail_id(), 'large' ); //this is where and use the [0] on this variable in the sprintf
$image = get_the_post_thumbnail( $post_id, 'shop_single', array( 'title' => $image_title ) );
$html = sprintf('%s', $image_link[0], $image_title, $image );
} //end version compare still return the html so we don't get an error
return $html;
}
add_filter( 'woocommerce_single_product_image_html', 'yourprefix_woocommerce_single_product_image_html', 10, 2 );
Note: wp_get_attachment_image_src() is not what is used in the default code, it's wp_get_attachment_image_url() which gets the image uploaded, not a sized image. If you want the generated image use $variable = wp_get_attachment_image_src( ... ); and then $variable[0] for the url, $variable[1] width, $variable[2] height. There are plenty of tuts on this, so I won't repeat

WooCommerce get first gallery image as fallback, if post thumbnail is missing and at least the placeholder image

I have a problem to receive the first image of the woocommerce gallery, if the post thumbnail is missing. I want to show the post thumbnail, if this is missing, the first image of the WooCommerce gallery and at least the placeholder image, if all is missing.
I found this function in the WooCommerce Codex, but I donĀ“t come on an satisfying solution. Maybe someone can help me to receive an good solution
function woocommerce_get_product_thumbnail( $size = 'shop_catalog', $deprecated1 = 0, $deprecated2 = 0 ) {
global $post;
$image_size = apply_filters( 'single_product_archive_thumbnail_size', $size );
if ( has_post_thumbnail() ) {
$props = wc_get_product_attachment_props( get_post_thumbnail_id(), $post );
return get_the_post_thumbnail( $post->ID, $image_size, array(
'title' => $props['title'],
'alt' => $props['alt'],
) );
} elseif ( wc_placeholder_img_src() ) {
return wc_placeholder_img( $image_size );
}
}
}
So, I found myself an soultion. Is not as perfect as I wished, but it works. I post this this answer, if someone is searching for an similar solution. So, this could be an way:
/* GET PRODUCT IMAGE WITH GALLERY FALLBACK
================================================== */
if ( ! function_exists( 'zet_get_prod_image_fallback_gallery' ) ) {
function zet_get_prod_image_fallback_gallery() {
global $post, $woocommerce, $product;
$image_size = apply_filters( 'single_product_archive_thumbnail_size', $size );
$thumb_gallery_ids = $product->get_gallery_attachment_ids();
if ( has_post_thumbnail() || $thumb_gallery_ids ) {
if ( has_post_thumbnail() ) {
$image_id = get_post_thumbnail_id();
} else {
$image_id = $thumb_gallery_ids[0];
}
$thumb_image = wp_get_attachment_url( $image_id, apply_filters( 'single_product_small_thumbnail_size', 'shop_thumbnail' ) );
$image_html = '<img src="'.$thumb_image.'" />';
echo $image_html;
// Get the Placeholder image
} elseif ( wc_placeholder_img_src() ) {
echo wc_placeholder_img( $image_size );
}
}
}
For users who are not so familiar with wordpress: add this snippet to your functions.php
If you want to use this fallback for your whole shop -> change the function woocommerce_template_loop_product_thumbnail() in woocommerce/content-product.php to zet_get_prod_image_fallback_gallery(). Hope it helps!

Product image disappears when filtering WooCommerce function for Sale Flash Badge in ROEN theme

I am trying to display how many percent the user saves on the sales badge in WooCommerce. To make this work without this overwriting the "Featured" sales badge, I had to add some filters to my functions.php. Everything works fine now, exept that the product image on the product page disappears and I can't for the life of me understand why. The "onsale featured" code in the theme file product-image.php is almost the same as the "onsale" code, and I can't understand why the image would disappear when a product is on sale, but not when it is featured?
My code in functions.php
add_filter('woocommerce_sale_flash', 'my_custom_sale_flash' );
function my_custom_sale_flash($text) {
global $product;
if($product->is_on_sale()){
$percentage = round( ( ( $product->regular_price - $product->sale_price ) / $product->regular_price ) * 100 );
return '<span class="onsale">SPAR '.$percentage.' %</span>';
}elseif($product->is_featured()){
return '<span class="onsale featured">Utvalgt</span>';
}else if(!$product->is_in_stock()){
return '<span class="onsale">Utsolgt</span>';
}else if(!$product->get_price()){
return '<span class="onsale">GRATIS</span>';
}
}
The code in product-image.php in the ROEN theme
<?php
/**
* Single Product Image
*
* #author WooThemes
* #package WooCommerce/Templates
* #version 2.0.14
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
global $post, $woocommerce, $product;
?>
<div class="images">
<?php
if ( has_post_thumbnail() ) {
$image_title = "";
$image_link = wp_get_attachment_url( get_post_thumbnail_id() );
$image = get_the_post_thumbnail( $post->ID, apply_filters( 'single_product_large_thumbnail_size', 'shop_single' ), array('title' => $image_title) );
$attachment_count = count( $product->get_gallery_attachment_ids() );
if ( $attachment_count > 0 ) {
$gallery = '[product-gallery]';
$zoom = "";
} else {
$gallery = '';
$zoom = 'zoom';
}
$html = '';
if($product->is_featured()){
$html = apply_filters('woocommerce_sale_flash', '<span class="featured onsale">'.__('Featured','ROEN').'</span>', $post, $product);
}else if($product->is_on_sale()){
$html = apply_filters('woocommerce_sale_flash', '<span class="onsale">'.__( 'Sale!', 'woocommerce' ).'</span>', $post, $product);
}else if(!$product->is_in_stock()){
$html = '<span class="outofstock">'.__('Out of Stock','ROEN').'</span>';
}else if(!$product->get_price()){
$html = '<span class="free onsale">'.__('Free','ROEN').'</span>';
}
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s'.$html.'', $image_link, $image_title, $image_link , $image ), $post->ID );
} else {
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '<img src="%s" alt="Placeholder" />', woocommerce_placeholder_img_src() ), $post->ID );
}
?>
<?php do_action( 'woocommerce_product_thumbnails' ); ?>
</div>
I can't see why the problem arises? Featured products that are not on sale displays correctly both when viewed from a category and on the product page. Products that are on sale displays correctly when viewed from a category, but the image disappears on the product page.
Thank you for your time.
I got this fixed by changing
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s'.$html.'', $image_link, $image_title, $image_link , $image ), $post->ID );
To
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s%s', $image_link, $image_title, $image_link , $image, $html ), $post->ID );
Turns out Wordpress did not like the percentage sign in my span that was going to show in the sales badge, because of the way the ROEN theme is coded.
I tell you man, lot's of weird code in that theme.

Overriding template with hooks

I am having a little trouble editing a Woocommerce template with hooks. Essentially I would just like to change the product-image template so instead of linking to the uploaded product image, it links to the product post.
The current product-image.php woocommerce template has
global $post, $woocommerce, $product;
?>
<div class="images">
<?php
if ( has_post_thumbnail() ) {
$image_title = esc_attr( get_the_title( get_post_thumbnail_id() ) );
$image_link = wp_get_attachment_url( get_post_thumbnail_id() );
$image = get_the_post_thumbnail( $post->ID, apply_filters( 'single_product_large_thumbnail_size', 'shop_single' ), array(
'title' => $image_title
) );
$attachment_count = count( $product->get_gallery_attachment_ids() );
if ( $attachment_count > 0 ) {
$gallery = '[product-gallery]';
} else {
$gallery = '';
}
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s', $image_link, $image_title, $image ), $post->ID );
} else {
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '<img src="%s" alt="Placeholder" />', woocommerce_placeholder_img_src() ), $post->ID );
}
?>
<?php do_action( 'woocommerce_product_thumbnails' ); ?>
</div>
I am unsure of how to adapt the echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s', $image_link, $image_title, $image ), $post->ID ); to change the %s to a link to the post.
The hook I am using is:
add_action('woocommerce_product_thumbnails', 'custom_links');
function custom_links() {
//code
}
Could someone help me gain some direction with this?
You are calling action not filter. Also you are calling the wrong one.
Change this:
add_action('woocommerce_product_thumbnails', 'custom_links');
to this:
add_filter('woocommerce_single_product_image_html', 'custom_links', 10, 2);
The 2 represents the argument count for the function and your custom_links() should be something like:
function custom_links($link, $post_id) {
$pattern = '/(?<=href=")([^"]*)/';
$replacement = get_permalink($post->ID);
return preg_replace($pattern, $replacement, $link);
}
Process the $link variable as needed and then return it.

Categories