SOLVED: PHP warning in wc-template-function.php if image in product gallery not exists in media library

I’m building a new site and checking the logs I see hundreds of PHP warning like this:
PHP Warning: Trying to access array offset on value of type bool in …/wp-content/plugins/woocommerce/includes/wc-template-functions.php on line 1608

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 );
	$alt_text          = trim( wp_strip_all_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) );
	$image             = wp_get_attachment_image(
		$attachment_id,
		$image_size,
		false,
		apply_filters(
			'woocommerce_gallery_image_html_attachment_image_params',
			array(
				'title'                   => _wp_specialchars( get_post_field( 'post_title', $attachment_id ), ENT_QUOTES, 'UTF-8', true ),
				'data-caption'            => _wp_specialchars( get_post_field( 'post_excerpt', $attachment_id ), ENT_QUOTES, 'UTF-8', true ),
				'data-src'                => esc_url( $full_src[0] ),
				'data-large_image'        => esc_url( $full_src[0] ),
				'data-large_image_width'  => esc_attr( $full_src[1] ),
				'data-large_image_height' => esc_attr( $full_src[2] ),
				'class'                   => esc_attr( $main_image ? 'wp-post-image' : '' ),
			),
			$attachment_id,
			$image_size,
			$main_image
		)
	);

	return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" data-thumb-alt="' . esc_attr( $alt_text ) . '" class="woocommerce-product-gallery__image"><a href="' . esc_url( $full_src[0] ) . '">' . $image . '</a></div>';
}

Looking at the wc-template-functions.php on line 1608

'data-large_image_height' => esc_attr( $full_src[2] ),

it looks like it’s something to do with images sizes.
Anybody knows what this is about or how to get rid of the warning?

Hi @christian ,

Unfortunately, I am not able to replicate this warning in debug log.
Can you check any custom element using on your single product page.
Do you have any plugin that’s changing the WooCommerce product gallery output?

Try identify which page generating the error, and deactivate plugins/custom code to see if able to track which causing the error messages.

Or maybe your image do not have height attribute? SVG? You could switch to WP default theme to compare as well.

Regards,
Jenn

hi @itchycode

I did some further testing. The PHP warnings comes from the Single Product template. Every time it’s opened.

I deactivated all plugins except Woocommerce and removed all templates except the Single Product template. Started from scratch… Inserted a Section, a Container and the Product Gallery with default settings. Nothing else.

Every time I open the Single Product Template I now get 6 PHP warnings of the same type (before I got maybe 30 every time).

PHP Warning: Trying to access array offset on value of type bool in .../wp-content/plugins/woocommerce/includes/wc-template-functions.php on line 1605
PHP Warning: Trying to access array offset on value of type bool in .../wp-content/plugins/woocommerce/includes/wc-template-functions.php on line 1606
PHP Warning: Trying to access array offset on value of type bool in .../wp-content/plugins/woocommerce/includes/wc-template-functions.php on line 1607
PHP Warning: Trying to access array offset on value of type bool in .../wp-content/plugins/woocommerce/includes/wc-template-functions.php on line 1608
PHP Warning: Trying to access array offset on value of type bool in .../wp-content/plugins/woocommerce/includes/wc-template-functions.php on line 1617
PHP Warning: Trying to access array offset on value of type bool in .../wp-content/plugins/woocommerce/includes/wc-template-functions.php on line 1617

Hi @christian ,

May I know which product you are using for populate content? Can you try another product?
Can you check if the error also occurs when visiting the actual frontend?
Please send temp admin access to help@bricksbuilder.io and include this forum thread URL as a reference if unable to find the root cause.

Regards,
Jenn

Can I ask what the solution was, as I am encountering the exact same problem.
A massive amount of PHP errors, on both the front and back-end saying “Trying to access array offset on value of type bool” referring to the exact same wc-template-functions.php lines and occurring only on my single product template.

Hi @Rafael_Costeau,

There is no update after the last conversation.
Please send temp admin access to help@bricksbuilder.io and include this forum thread URL as a reference if unable to find the root cause.

Regards,
Jenn

Thank you for the quick reply.
I’ve gone down the rabbit hole and seem to have identified and fixed the problem.
Also, it turned out it wasn’t specifically bricks related, but it is a problem that (anecdotally) seems pops up more frequently for people using various page builders.

For anyone who (like me) was encountering this problem and found this post via google and are looking for a solution, here is what I found:

The problem is most likely caused products having image ID’s linked in the product gallery which do not exist in the Media Library, in my case, this was likely caused by importing / exporting products.
For reference see this page or this page for more discussion regarding this error.

The way I solved this was to Query the SQL database for products missing taxonomy data: (tt.taxonomy IS NULL or t.name IS NULL )
It returned a list of products, showing both the ID and post_title, showing you which products have this problem.

I checked a few of these specific products and found that they had images in the image gallery which were “broken” or otherwise not displaying. When removing these “broken links” the errors stopped showing up in the Query Manager when visiting that page.

So I took the list of all ID and ran them through a custom PHP script that checks if the product_gallery_id is present in the media library and if it is not, removes it from the product.

This seems to have solved the problem as the error has not re-appeared in the server error log for the past hour, where previously it would appear dozens or hundreds of times in this timeframe.

1 Like

Thank you so much @Rafael_Costeau ,

I can replicate this issue now.
Recorded this in the bug tracker.
We will add some checking before using the broken or removed attachment ID inside the Product gallery element.

Regards,
Jenn

Hi guys,

We’ve fixed this issue in Bricks 1.9.8 beta, now available as a manual download in your account (see changelog).

Please let us know if you are still experiencing issues.

As with any beta release, please do not use it on a production or live website. It is only meant for testing in a local or staging environment.

The way I solved this was to Query the SQL database for products missing taxonomy data: (tt.taxonomy IS NULL or t.name IS NULL )
It returned a list of products, showing both the ID and post_title, showing you which products have this problem.

Hey, there. I’m into this issue for two weeks now. The issue started once products were imported. It seems no images are missing, but the ids maybe wrong nevertheless. Since the 1.9.8 is beta it won’t be pushed to the live page.
I found that thread on github last week and modified the WC template like described in Github with no success with those errors:

Can you share the full SQL query you used to find the affected productes?

1 Like

Hi,

I’m not 100% sure as I had to check my many notes from a few weeks ago which mainly contained throwing lots of shit at the wall and hoping something sticked.

If I remember correctly, after the post I made I had repeat the process a few times because I found I had either deleted too many terms (always be sure to backup!), not enough terms or unrelated reasons for restoring a backup. I think I ended up using:

SELECT p.ID, p.post_title
FROM wp_posts p
LEFT JOIN wp_term_relationships tr ON p.ID = tr.object_id
LEFT JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN wp_terms t ON tt.term_id = t.term_id
WHERE p.post_type = ‘product’
AND p.post_status = ‘publish’
AND (tt.taxonomy IS NULL OR t.name IS NULL)
GROUP BY p.ID;

But in the end, after applying the solution a few more times I found that the easiest way was to use a custom .php file which I uploaded to the main wordpress folder on the server, so that when I visited the URL showed all the “orphaned” ID’s and the products they were linked to.

After checking enough of them to make me confident enough that they were indeed all missing (the image link in the gallery will be broken when viewed on the backed), I adjusted the script to delete these items when run. Below is the code I used to find them without the “deleting” part, but please be warned that this is a) some random code you found on the internet and therefore shouldn’t be blindly trusted and b) I don’t know what the hell I’m doing either most of the time. So be super duper extra sure to proceed with caution and always make sure you have a backup!

<?php
// Simple security measure
if ($_GET['token'] !== 'YOUR_SECRET_TOKEN') {
    die('Unauthorized access.');
}

// Include the WordPress core
require_once('wp-load.php');

global $wpdb;

// Fetch all gallery images from products
$results = $wpdb->get_results("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_product_image_gallery'", OBJECT);

$orphaned_ids = [];
$products_info = [];

foreach ($results as $result) {
    $gallery_ids = explode(',', $result->meta_value);

    foreach ($gallery_ids as $image_id) {
        // Check if each image ID exists in the media library
        $exists = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->posts} WHERE ID = %d AND post_type = 'attachment'", $image_id));

        if ($exists == 0 && !empty($image_id)) {
            // This ID does not exist in the media library
            $orphaned_ids[$image_id][] = $result->post_id;
        }
    }
}

foreach ($orphaned_ids as $image_id => $post_ids) {
    foreach ($post_ids as $post_id) {
        $product = wc_get_product($post_id);
        if ($product) {
            $products_info[] = [
                'product_id' => $product->get_id(),
                'product_name' => $product->get_name(),
                'product_url' => get_permalink($product->get_id()),
                'orphaned_image_id' => $image_id,
            ];
        }
    }
}

// Output results as a table
echo "<table border='1'>";
echo "<tr><th>Product ID</th><th>Product Name</th><th>Product URL</th><th>Orphaned Image ID</th></tr>";
foreach ($products_info as $info) {
    echo "<tr>";
    echo "<td>{$info['product_id']}</td>";
    echo "<td>{$info['product_name']}</td>";
    echo "<td><a href='{$info['product_url']}'>Link</a></td>";
    echo "<td>{$info['orphaned_image_id']}</td>";
    echo "</tr>";
}
echo "</table>";
?>

This script uses a “secret token” as a simple security measure.
Replace “YOUR SECRET TOKEN” with a password of your choosing and visit:
http://yourwebsite.com/nameyougavethescript.php?token=YOURPASSWORD

I wish you the best of luck.

1 Like

Thanks for sharing! I went a quite similar SQL query route to find the products and deleted the product gallery IDs. So far no new warnings. But I’m not sure if this really solved the issue.