Delete Product Images on Product Deletion

Deletes the featured and gallery images associated with a WooCommerce product when the product is deleted, as long as the images are not used by other products.

PHP
/**
 * Snippet Name: Delete Product Images on Product Deletion
 * Snippet Author: coding-bunny.com
 * Description: Deletes the featured and gallery images associated with a WooCommerce product when the product is deleted.
 * Version: 1.1.0
 */

add_action( 'before_delete_post', 'cbdpi_delete_images', 10, 1 );

function cbdpi_delete_images( $post_id ) {
    if ( ! current_user_can( 'delete_products' ) ) return;
    if ( get_post_type( $post_id ) !== 'product' ) return;
    $product = wc_get_product( $post_id );
    if ( ! $product ) return;
    $featured = $product->get_image_id();
    $gallery  = $product->get_gallery_image_ids();
    $all_ids = array_filter( array_merge( array( $featured ), $gallery ) );
    if ( empty( $all_ids ) ) return;
    $used = cbdpi_get_used_ids( $all_ids, $post_id );
    foreach ( $all_ids as $img_id ) {
        if ( ! in_array( $img_id, $used ) ) {
            wp_delete_attachment( $img_id, true );
        }
    }
}

function cbdpi_get_used_ids( $img_ids, $current_id ) {
    global $wpdb;
    $ids_str = implode( ',', array_map( 'absint', $img_ids ) );
    $used = array();
    $prod_query = $wpdb->get_col( $wpdb->prepare(
        "SELECT DISTINCT meta_value FROM {$wpdb->postmeta}
        WHERE (
            ( meta_key = '_thumbnail_id' AND meta_value IN ($ids_str) )
            OR
            ( meta_key = '_product_image_gallery' AND meta_value != '' )
        )
        AND post_id != %d",
        $current_id
    ) );
    $used = array_merge( $used, array_intersect( $img_ids, array_map( 'intval', $prod_query ) ) );
    $gallery_query = $wpdb->get_results( $wpdb->prepare(
        "SELECT meta_value FROM {$wpdb->postmeta}
        WHERE meta_key = '_product_image_gallery'
        AND post_id != %d
        AND meta_value != ''",
        $current_id
    ) );
    foreach ( $gallery_query as $row ) {
        $g_ids = array_map( 'intval', explode( ',', $row->meta_value ) );
        foreach ( $img_ids as $id ) {
            if ( in_array( $id, $g_ids ) && ! in_array( $id, $used ) ) {
                $used[] = $id;
            }
        }
    }
    $posts_query = $wpdb->get_col(
        "SELECT meta_value FROM {$wpdb->postmeta}
        WHERE meta_key = '_thumbnail_id'
        AND meta_value IN ($ids_str)
        AND post_id != " . absint( $current_id )
    );
    $used = array_merge( $used, array_intersect( $img_ids, array_map( 'intval', $posts_query ) ) );
    return array_unique( $used );
}

How To Implement This Solution?

Leave a Reply