Hey @everyone,
Just sharing another snippet with the community.
By default, when someone is making a booking and reaches the Checkout page, the product image shown in the order summary is blank.
Here’s how to fix that and have the Product image sync up with the original Listing image.
- Add the following snippet (via Code Snippets plugin for easy maintainence)
/**
* Sync WooCommerce product thumbnail from a HivePress listing's image(s)
* when listing image(s) are created or updated.
*/
add_action( 'hivepress/v1/models/listing/update_image', 'cb_hp_sync_wc_product_thumb_from_listing', 10, 2 );
add_action( 'hivepress/v1/models/listing/update_images', 'cb_hp_sync_wc_product_thumb_from_listing', 10, 2 );
add_action( 'hivepress/v1/models/listing/create', 'cb_hp_sync_wc_product_thumb_from_listing_event', 10, 2 );
add_action( 'hivepress/v1/models/listing/update', 'cb_hp_sync_wc_product_thumb_from_listing_event', 10, 2 );
function cb_hp_sync_wc_product_thumb_from_listing_event( $listing_id ) {
cb_hp_sync_wc_product_thumb_from_listing( $listing_id, null );
}
function cb_hp_sync_wc_product_thumb_from_listing( $listing_id, $new_value ) {
$listing_id = absint( $listing_id );
if ( ! $listing_id ) return;
$attachment_id = cb_hp_pick_image_id_from_value( $new_value );
// If the hook didn't give an ID, read from the Listing model.
if ( ! $attachment_id && class_exists( '\HivePress\Models\Listing' ) ) {
try {
$listing = \HivePress\Models\Listing::query()->get_by_id( $listing_id );
if ( $listing && method_exists( $listing, 'get_images__id' ) ) {
$ids = (array) $listing->get_images__id();
$attachment_id = $ids ? absint( reset( $ids ) ) : 0;
}
} catch ( \Throwable $e ) {}
}
if ( ! $attachment_id ) return;
// Find WooCommerce products linked to this listing.
$product_ids = get_posts( [
'post_type' => 'product',
'post_status' => 'any',
'numberposts' => -1,
'fields' => 'ids',
'post_parent' => $listing_id,
] );
if ( empty( $product_ids ) ) return;
foreach ( $product_ids as $pid ) {
$current = (int) get_post_thumbnail_id( $pid );
if ( $current === $attachment_id ) continue;
update_post_meta( $pid, '_thumbnail_id', $attachment_id );
if ( function_exists( 'wc_delete_product_transients' ) ) {
wc_delete_product_transients( $pid );
}
}
}
function cb_hp_pick_image_id_from_value( $value ) {
if ( is_numeric( $value ) ) {
return absint( $value );
}
if ( is_array( $value ) && ! empty( $value ) ) {
$first = reset( $value );
if ( is_numeric( $first ) ) {
return absint( $first );
}
if ( is_object( $first ) && method_exists( $first, 'get_id' ) ) {
return absint( $first->get_id() );
}
if ( is_array( $first ) && isset( $first['id'] ) ) {
return absint( $first['id'] );
}
}
return 0;
}
/**
* MANUAL BACKFILL — Run once to sync all existing listings to their WooCommerce product thumbs.
*
* 1. Visit: https://your-site.com/?hp_backfill_thumbs=1 while logged in as admin.
* 2. Wait for "Backfill complete" message.
* 3. Remove or comment out this function for security.
*/
add_action( 'init', function() {
if ( ! is_admin() && current_user_can( 'manage_options' ) && isset( $_GET['hp_backfill_thumbs'] ) ) {
$listings = get_posts( [
'post_type' => 'hp_listing',
'post_status' => 'any',
'numberposts' => -1,
'fields' => 'ids',
] );
foreach ( $listings as $lid ) {
cb_hp_sync_wc_product_thumb_from_listing( $lid, null );
}
wp_die( 'Backfill complete. All listing images synced to WooCommerce products.' );
}
} );
- Visit https://www.your-website-address.com
/?hp_backfill_thumbs=1
- The snippet makes the magic happen for any new listings, or when an existing listing is updated.
- The second step backfills all of your existing orders.
I hope the community finds this useful!
Cheers,
Chris ![]()