Optimize WooCommerce Variations
March 12, 2025 · AI Conversations
$variation = wc_get_product( $variation_id );
$product_variation = new WC_Product_Variation( $variation_id );
$image_tag = $product_variation->get_image();
$image_id = $variation->get_image_id();
?>
Width: |
BMT: |
Depth:
### Possible Causes of Hanging:
1. **Repeatedly Reassigning Arrays Inside the Loop:**
– In every iteration of the loop, you are reassigning `$p_width`, `$p_depth`, `$p_bmt`, and `$p_sku` after applying `array_unique()` and `array_filter()`. This causes unnecessary performance overhead.
– Since the `foreach` loop is iterating over potentially many variations, this can lead to excessive memory usage and slow execution.
2. **Fetching Metadata Repeatedly in Each Iteration:**
– `get_post_meta()` is being called multiple times per iteration.
– If the product has many variations, this can result in **hundreds or thousands of database queries**, causing the system to hang.
3. **Using `new WC_Product_Variation( $variation_id )` Unnecessarily:**
– `wc_get_product( $variation_id )` already returns a product object. Instantiating `WC_Product_Variation` separately is redundant and adds overhead.
### Optimized Code:
Instead of reassigning arrays inside the loop, collect the values first, then apply `array_unique()` and `array_filter()` **after the loop**.
$p_width = [];
$p_depth = [];
$p_bmt = [];
$p_sku = [];
foreach ($product->get_visible_children() as $variation_id) {
$variation = wc_get_product($variation_id);
if (!$variation) {
continue; // Skip if variation is invalid
}
$image_id = $variation->get_image_id();
?>
<div class="varfull col-sm-12" style="display:none; margin-bottom:20px;">
<div class="col-sm-12">
<h5 style="margin-bottom: 0px;"><?php echo esc_html($variation->get_sku()); ?></h5>
<div class="variationdesc">
<p style="margin-bottom: 5px;"><?php echo esc_html(get_post_meta($variation_id, '_variation_description', true)); ?></p>
<strong>Width:</strong> <?php echo esc_html(get_post_meta($variation_id, '_width_field', true)); ?> |
<strong>BMT:</strong> <?php echo esc_html(get_post_meta($variation_id, '_bmt_field', true)); ?> |
<strong>Depth:</strong> <?php echo esc_html(get_post_meta($variation_id, '_depth_field', true)); ?>
</div>
<div class="variationbutton">
<a id="button_enanle_disable_<?php echo $variation_id ?>" onclick="storeDataInLocalStorage(<?php echo $variation_id ?>)" style="cursor: pointer;">Add to project</a>
<a href="<?php echo esc_url(get_post_meta($variation_id, '_dtp_field', true)); ?>" download>Preview PDF</a>
</div>
</div>
</div>
<?php
// Collect values
$p_width[] = get_post_meta($variation_id, '_width_field', true);
$p_depth[] = get_post_meta($variation_id, '_depth_field', true);
$p_bmt[] = get_post_meta($variation_id, '_bmt_field', true);
$p_sku[] = $variation->get_sku();
}
// Apply array_unique() and array_filter() **only once** after the loop
$p_width = array_values(array_filter(array_unique($p_width), 'strlen'));
$p_depth = array_values(array_filter(array_unique($p_depth), 'strlen'));
$p_bmt = array_values(array_filter(array_unique($p_bmt), 'strlen'));
$p_sku = array_values(array_filter(array_unique($p_sku), 'strlen'));
### Key Optimizations:
✅ **Minimized Database Queries** – `get_post_meta()` is called only when necessary.
✅ **Avoids Repeated `array_unique()` Calls** – It runs **only once** after the loop instead of every iteration.
✅ **Removes Redundant `WC_Product_Variation` Instantiation** – Using only `wc_get_product()`.
✅ **Ensures Valid HTML** – Removed the unnecessary double `class="varfull col-sm-12"`.
✅ **Sanitization for Security** – Used `esc_html()` and `esc_url()` for escaping output.
This optimized version should prevent the system from hanging while maintaining the required functionality. 🚀
$product_variation = new WC_Product_Variation( $variation_id );
$product_variation = new WC_Product_Variation( $variation_id );
could be causing the issue.
### Why is this a Problem?
1. **Unnecessary Object Instantiation** – You are already retrieving the product object using:
$variation = wc_get_product($variation_id);
Instantiating `WC_Product_Variation` separately is redundant.
2. **Performance Overhead** – If the product has a large number of variations, creating a new `WC_Product_Variation` object for each one can cause memory overload and slow down execution.
3. **Potential Loop or Memory Leak** – If there is an issue in `WC_Product_Variation`, such as an infinite loop or excessive database queries, it can cause PHP to hang or time out.
—
### **Solution: Remove This Line**
Instead of:
$product_variation = new WC_Product_Variation( $variation_id );
$image_tag = $product_variation->get_image();
Just use:
$image_tag = $variation->get_image();
Since `$variation` is already a `WC_Product_Variation` instance when retrieved via `wc_get_product($variation_id)`, you **don’t** need to manually instantiate it.
—
### **Fixed Code**
$p_width = [];
$p_depth = [];
$p_bmt = [];
$p_sku = [];
foreach ($product->get_visible_children() as $variation_id) {
$variation = wc_get_product($variation_id);
if (!$variation) {
continue; // Skip if variation is invalid
}
$image_id = $variation->get_image_id();
$image_tag = $variation->get_image(); // Fetch image directly
?>
<div class="varfull col-sm-12" style="display:none; margin-bottom:20px;">
<div class="col-sm-12">
<h5 style="margin-bottom: 0px;"><?php echo esc_html($variation->get_sku()); ?></h5>
<div class="variationdesc">
<p style="margin-bottom: 5px;"><?php echo esc_html(get_post_meta($variation_id, '_variation_description', true)); ?></p>
<strong>Width:</strong> <?php echo esc_html(get_post_meta($variation_id, '_width_field', true)); ?> |
<strong>BMT:</strong> <?php echo esc_html(get_post_meta($variation_id, '_bmt_field', true)); ?> |
<strong>Depth:</strong> <?php echo esc_html(get_post_meta($variation_id, '_depth_field', true)); ?>
</div>
<div class="variationbutton">
<a id="button_enanle_disable_<?php echo $variation_id ?>" onclick="storeDataInLocalStorage(<?php echo $variation_id ?>)" style="cursor: pointer;">Add to project</a>
<a href="<?php echo esc_url(get_post_meta($variation_id, '_dtp_field', true)); ?>" download>Preview PDF</a>
</div>
</div>
</div>
<?php
// Collect values
$p_width[] = get_post_meta($variation_id, '_width_field', true);
$p_depth[] = get_post_meta($variation_id, '_depth_field', true);
$p_bmt[] = get_post_meta($variation_id, '_bmt_field', true);
$p_sku[] = $variation->get_sku();
}
// Apply array_unique() and array_filter() **only once** after the loop
$p_width = array_values(array_filter(array_unique($p_width), 'strlen'));
$p_depth = array_values(array_filter(array_unique($p_depth), 'strlen'));
$p_bmt = array_values(array_filter(array_unique($p_bmt), 'strlen'));
$p_sku = array_values(array_filter(array_unique($p_sku), 'strlen'));
—
### **Expected Improvement**
✅ **Fixes System Hanging** – Prevents unnecessary object creation in a loop.
✅ **Improves Performance** – Reduces memory usage and unnecessary computations.
✅ **Maintains Functionality** – The image retrieval still works without manually instantiating `WC_Product_Variation`.
Your script should now run significantly faster without hanging. 🚀