Code thêm nhanh hàng loạt ảnh cho biến thể sản phẩm trong WooCommerce

Cập nhật lần cuối 27/11/2025 by trong WordPress vào 27/11/2025 có 4 Views

Nhiều website dùng biến thể theo màu, size, chất liệu… và mọi thứ vẫn ổn cho đến khi đến đoạn thêm ảnh cho từng biến thể. Nếu sản phẩm chỉ có vài lựa chọn thì không sao, nhưng khi bạn có hàng chục – thậm chí hàng trăm biến thể, việc phải mở từng biến thể rồi chọn ảnh giống như “tự phạt mình” bằng một chuỗi thao tác lặp vô tận.

Và đoạn code dưới đây giúp bạn thêm nhanh hàng loạt ảnh cho đúng biến thể mong muốn — gọn, chính xác và không còn cảnh ngồi bấm thủ công nữa.

Video giới thiệu về chức năng này

Code thêm nhanh hàng loạt ảnh cho biến thể sản phẩm

Bạn chỉ cần thêm code dưới đây vào wp-content/themes/{your-theme}/functions.php và thưởng thức thành quả

Để duy trì blog nên mình có làm aff cho 1 số bên hosting. Nhưng dù aff mình cũng chọn 1 số nhà cung cấp uy tín về chất lượng và support nên các bạn cứ yên tâm nhé.

Nếu có mua hosting mà có trong list dưới đây các bạn click vào link trước khi mua để ủng hộ mình nhé. Mình cảm ơn nhiều

<?php
/*
Thêm ảnh hàng loạt cho biến thể sản phẩm
Author: Levantoan.com
*/

add_action('wp_ajax_bulk_set_variation_image', 'handle_bulk_set_variation_image');

function handle_bulk_set_variation_image() {
    
    if (!wp_verify_nonce($_POST['security'], 'bulk-edit-variations')) {
        wp_die(-1);
    }
        
    if (!current_user_can('edit_products') || empty($_POST['product_id']) || empty($_POST['image_id'])) {
        wp_die(-1);
    }
    
    $product_id = absint($_POST['product_id']);
    $image_id = absint($_POST['image_id']);
    $filters = !empty($_POST['filters']) ? wc_clean(wp_unslash($_POST['filters'])) : array();
        
    $variations = get_posts(array(
        'post_parent'    => $product_id,
        'posts_per_page' => -1,
        'post_type'      => 'product_variation',
        'fields'         => 'ids',
        'post_status'    => array('publish', 'private'),
    ));
    
    $updated_count = 0;
    
    foreach ($variations as $variation_id) {
        $variation = wc_get_product($variation_id);
        if (!$variation) continue;
        
        $should_update = true;
        if (!empty($filters)) {
            foreach ($filters as $attribute => $value) {
                $meta_key = 'attribute_' . $attribute;
                $variation_attribute = get_post_meta($variation_id, $meta_key, true);
                
                if ($variation_attribute !== $value) {
                    $should_update = false;
                    break;
                }
            }
        }
        
        if ($should_update) {
            update_post_meta($variation_id, '_thumbnail_id', $image_id);
            $updated_count++;
        }
    }
    
    WC_Product_Variable::sync($product_id);
    wc_delete_product_transients($product_id);
    
    wp_send_json_success(array(
        'message' => sprintf('Đã cập nhật ảnh cho %d biến thể!', $updated_count),
        'count' => $updated_count
    ));
}

add_action('wp_ajax_bulk_remove_variation_image', 'handle_bulk_remove_variation_image');

function handle_bulk_remove_variation_image() {

    if (!wp_verify_nonce($_POST['security'], 'bulk-edit-variations')) {
        wp_die(-1);
    }
    
    if (!current_user_can('edit_products') || empty($_POST['product_id'])) {
        wp_die(-1);
    }
    
    $product_id = absint($_POST['product_id']);
    $filters = !empty($_POST['filters']) ? wc_clean(wp_unslash($_POST['filters'])) : array();
    
    $variations = get_posts(array(
        'post_parent'    => $product_id,
        'posts_per_page' => -1,
        'post_type'      => 'product_variation',
        'fields'         => 'ids',
        'post_status'    => array('publish', 'private'),
    ));
    
    $updated_count = 0;
    
    foreach ($variations as $variation_id) {
        $variation = wc_get_product($variation_id);
        if (!$variation) continue;
        
        $should_update = true;
        if (!empty($filters)) {
            foreach ($filters as $attribute => $value) {
                $meta_key = 'attribute_' . $attribute;
                $variation_attribute = get_post_meta($variation_id, $meta_key, true);
                                
                if ($variation_attribute !== $value) {
                    $should_update = false;
                    break;
                }
            }
        }
        
        if ($should_update) {
            delete_post_meta($variation_id, '_thumbnail_id');
            $updated_count++;
        }
    }
    
    WC_Product_Variable::sync($product_id);
    wc_delete_product_transients($product_id);
    
    wp_send_json_success(array(
        'message' => sprintf('Đã bỏ ảnh của %d biến thể!', $updated_count),
        'count' => $updated_count
    ));
}

add_action('admin_footer', function () {
    global $pagenow, $post;
    if ($pagenow !== 'post.php' || get_post_type($post) !== 'product') return;

    $product = wc_get_product($post->ID);
    if (!$product || !$product->is_type('variable')) return;
    ?>
    <script>
        jQuery(function($){

            let toolbar = $("#variable_product_options .toolbar.toolbar-top");
            
            function showMessage(text, type = 'info') {
                let $message = $('#variation-tools-message');
                let bgColor = type === 'success' ? '#d4edda' : type === 'error' ? '#f8d7da' : '#e2e3e5';
                let borderColor = type === 'success' ? '#c3e6cb' : type === 'error' ? '#f5c6cb' : '#d6d8db';
                let textColor = type === 'success' ? '#155724' : type === 'error' ? '#721c24' : '#383d41';
                
                $message.html(text)
                    .css({
                        'background-color': bgColor,
                        'border-color': borderColor,
                        'color': textColor,
                        'display': 'block'
                    })
                    .fadeIn(200);
                
                setTimeout(function() {
                    $message.fadeOut(300, function() {
                        $(this).css('display', 'none');
                    });
                }, 2000);
            }

            function createToolbar() {
                let toolbar = $("#variable_product_options .toolbar.toolbar-top");
                
                if (toolbar.length && $("#my-variation-tools").length === 0){
                    let filtersHtml = '';
                    $('.toolbar-variations-defaults select[name^="default_attribute_"]').each(function() {
                        let $defaultSelect = $(this);
                        let attributeName = $defaultSelect.attr('name').replace('default_attribute_', '');
                        
                        let firstOptionText = $defaultSelect.find('option:first').text();
                        let label = firstOptionText
                            .replace('No default ', '')
                            .replace('Không mặc định ', '')
                            .replace('…', '')
                            .replace('&hellip;', '')
                            .replace('&amp;hellip;', '')
                            .trim();
                        
                        label = label.charAt(0).toUpperCase() + label.slice(1);
                        
                        filtersHtml += `<label><b>${label}:</b></label>`;
                        filtersHtml += `<select class="filter-attr" data-attr="${attributeName}" style="margin-right:8px;">`;
                        filtersHtml += '<option value="">-- Không lọc --</option>';
                        
                        $defaultSelect.find('option:not(:first)').each(function() {
                            let value = $(this).val();
                            let text = $(this).text();
                            filtersHtml += `<option value="${value}">${text}</option>`;
                        });
                        
                        filtersHtml += '</select>';
                    });
                    
                    let html = `<div id="my-variation-tools"
                            style="margin-top:10px; padding:10px; background:#fafafa; border:1px solid #ddd; position:relative;">
                <h3 style="margin-top:0;">🎯 Công cụ biến thể</h3>
                <div id="variation-tools-message" style="position: fixed;right: 10px;background: rgb(212, 237, 218);border: 1px solid rgb(195, 230, 203);border-radius: 4px;padding: 8px 12px;font-size: 13px;color: rgb(21, 87, 36);box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 5px;display: none;z-index: 99999;max-width: 300px;top: 50%;left: 50%;transform: translate3d(-50%, -50%, 0);"></div>

                ${filtersHtml}
                <br>
                <h4 style="margin: 10px 0;">🚀 Bulk Actions (Tất cả biến thể)</h4>
                <p style="font-size: 12px; color: #666; margin: 5px 0;">
                    <strong>Lưu ý:</strong> Các nút bên dưới sẽ áp dụng cho <strong>TẤT CẢ</strong> biến thể của sản phẩm (kể cả ở các trang khác) theo điều kiện đã chọn, 
                    không chỉ những biến thể hiện tại trên trang này.
                </p>
                <button class="button button-primary" id="btn-bulk-set-image">📷 Set ảnh cho TẤT CẢ biến thể theo điều kiện</button>
                <button class="button" id="btn-bulk-remove-image">🗑️ Bỏ ảnh TẤT CẢ biến thể theo điều kiện</button>
            </div>`;

                    toolbar.after(html);
                }
            }

            createToolbar();
            
            $('#woocommerce-product-data').on('woocommerce_variations_loaded', function() {
                createToolbar();
            });

            
            $(document).on("click", "#btn-bulk-set-image", function(e){
                e.preventDefault();
                e.stopPropagation();

                let filters = {};
                $(".filter-attr").each(function(){
                    let tax = $(this).data("attr");
                    let v   = $(this).val();
                    if (v) filters[tax] = v;
                });

                let frame = wp.media({
                    title: "Chọn ảnh cho tất cả biến thể",
                    multiple: false,
                    library:{type:"image"},
                    button:{text:"Dùng ảnh này"}
                });

                frame.on("select", function(){
                    let image = frame.state().get("selection").first().toJSON();
                    
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: {
                            action: 'bulk_set_variation_image',
                            security: '<?php echo wp_create_nonce("bulk-edit-variations"); ?>',
                            product_id: <?php echo $post->ID; ?>,
                            image_id: image.id,
                            filters: filters
                        },
                        beforeSend: function() {
                            let filterText = $.isEmptyObject(filters) ? "tất cả biến thể" : "các biến thể theo điều kiện";
                            showMessage("⏳ Đang cập nhật ảnh cho " + filterText + "...", 'info');
                        },
                        success: function(response) {
                            if (response.success) {
                                showMessage("✅ " + response.data.message, 'success');
                                
                                let currentPage = parseInt($('#variable_product_options .woocommerce_variations').attr('data-page')) || 1;
                                $('.variations-pagenav .page-selector').val(currentPage).trigger('change');
                            } else {
                                showMessage("❌ Có lỗi xảy ra!", 'error');
                            }
                        },
                        error: function() {
                            showMessage("❌ Có lỗi xảy ra khi gửi yêu cầu!", 'error');
                        }
                    });
                });

                frame.open();
                return false;
            });

            $(document).on("click", "#btn-bulk-remove-image", function(e){
                e.preventDefault();
                e.stopPropagation();

                let filters = {};
                $(".filter-attr").each(function(){
                    let tax = $(this).data("attr");
                    let v   = $(this).val();
                    if (v) filters[tax] = v;
                });

                let filterText = $.isEmptyObject(filters) ? "tất cả biến thể" : "các biến thể theo điều kiện đã chọn";
                
                if (!confirm("🗑️ Bạn có chắc muốn bỏ ảnh của " + filterText + "?")) {
                    return false;
                }

                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'bulk_remove_variation_image',
                        security: '<?php echo wp_create_nonce("bulk-edit-variations"); ?>',
                        product_id: <?php echo $post->ID; ?>,
                        filters: filters
                    },
                    beforeSend: function() {
                        let filterText = $.isEmptyObject(filters) ? "tất cả biến thể" : "các biến thể theo điều kiện";
                        showMessage("⏳ Đang bỏ ảnh cho " + filterText + "...", 'info');
                    },
                    success: function(response) {
                        if (response.success) {
                            showMessage("✅ " + response.data.message, 'success');
                            
                            let currentPage = parseInt($('#variable_product_options .woocommerce_variations').attr('data-page')) || 1;
                            $('.variations-pagenav .page-selector').val(currentPage).trigger('change');
                        } else {
                            showMessage("❌ Có lỗi xảy ra!", 'error');
                        }
                    },
                    error: function() {
                        showMessage("❌ Có lỗi xảy ra khi gửi yêu cầu!", 'error');
                    }
                });

                return false;
            });

        });
    </script>
<?php });

Chúc bạn thành công! nếu không làm được hay có lỗi gì hãy để lại comment nhé.

5/5 - (1 vote)
  • Bình luận
Sản phẩm nổi bật của Toản
x