You've already forked wc-composable-product
v1.2.0 - Fix product selection, cart pricing, admin tabs + CI/CD
Fix three critical bugs that persisted through v1.1.11-v1.1.14: - Product selection always empty: meta_query checked _product_type in postmeta, but WooCommerce uses the product_type taxonomy. Replaced with correct tax_query using NOT IN operator. - Cart price always 0.00: composable_price_calculated flag persisted in session, preventing recalculation on page loads. Removed flag; static variable already handles per-request dedup. - Admin tabs both visible on load: JS now triggers WooCommerce native tab click instead of manually toggling panel visibility. Add Gitea CI/CD release workflow triggered on v* tags. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -200,7 +200,7 @@ class Cart_Handler {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use static flag to prevent multiple executions
|
||||
// Use static flag to prevent multiple executions within the same request
|
||||
static $already_calculated = false;
|
||||
if ($already_calculated) {
|
||||
return;
|
||||
@@ -208,13 +208,10 @@ class Cart_Handler {
|
||||
|
||||
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
|
||||
if (isset($cart_item['data']) && $cart_item['data']->get_type() === 'composable') {
|
||||
if (isset($cart_item['composable_products']) && !isset($cart_item['composable_price_calculated'])) {
|
||||
if (isset($cart_item['composable_products'])) {
|
||||
$product = $cart_item['data'];
|
||||
$price = $product->calculate_composed_price($cart_item['composable_products']);
|
||||
$cart_item['data']->set_price($price);
|
||||
|
||||
// Mark as calculated to prevent re-calculation by other plugins
|
||||
$cart->cart_contents[$cart_item_key]['composable_price_calculated'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,24 +110,20 @@ class Product_Type extends \WC_Product {
|
||||
'post_status' => 'publish',
|
||||
'orderby' => 'title',
|
||||
'order' => 'ASC',
|
||||
'tax_query' => [],
|
||||
];
|
||||
|
||||
// Exclude composable products from selection
|
||||
$args['meta_query'] = [
|
||||
// Exclude composable products using the product_type taxonomy
|
||||
// (WooCommerce stores product types as taxonomy terms, NOT as postmeta)
|
||||
$args['tax_query'] = [
|
||||
'relation' => 'AND',
|
||||
[
|
||||
'key' => '_product_type',
|
||||
'value' => 'composable',
|
||||
'compare' => '!=',
|
||||
'taxonomy' => 'product_type',
|
||||
'field' => 'slug',
|
||||
'terms' => ['composable'],
|
||||
'operator' => 'NOT IN',
|
||||
],
|
||||
];
|
||||
|
||||
// Debug logging
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('Composable Product Criteria: ' . print_r($criteria, true));
|
||||
}
|
||||
|
||||
switch ($criteria['type']) {
|
||||
case 'category':
|
||||
if (!empty($criteria['categories'])) {
|
||||
@@ -154,28 +150,20 @@ class Product_Type extends \WC_Product {
|
||||
case 'sku':
|
||||
if (!empty($criteria['skus'])) {
|
||||
$skus = array_map('trim', explode(',', $criteria['skus']));
|
||||
$args['meta_query'][] = [
|
||||
'key' => '_sku',
|
||||
'value' => $skus,
|
||||
'compare' => 'IN',
|
||||
$args['meta_query'] = [
|
||||
[
|
||||
'key' => '_sku',
|
||||
'value' => $skus,
|
||||
'compare' => 'IN',
|
||||
],
|
||||
];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Debug logging
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('Composable Product Query Args: ' . print_r($args, true));
|
||||
}
|
||||
|
||||
$query = new \WP_Query($args);
|
||||
$products = [];
|
||||
|
||||
// Debug logging
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('Composable Product Query Found: ' . $query->found_posts . ' posts');
|
||||
}
|
||||
|
||||
if ($query->have_posts()) {
|
||||
foreach ($query->posts as $post) {
|
||||
$product = wc_get_product($post->ID);
|
||||
@@ -186,36 +174,21 @@ class Product_Type extends \WC_Product {
|
||||
|
||||
// Handle variable products by including their variations
|
||||
if ($product->is_type('variable')) {
|
||||
// Get variation IDs directly from the product
|
||||
$variation_ids = $product->get_children();
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('Variable product ' . $product->get_id() . ' has ' . count($variation_ids) . ' variations');
|
||||
}
|
||||
foreach ($variation_ids as $variation_id) {
|
||||
$variation = wc_get_product($variation_id);
|
||||
if ($variation && $variation->is_purchasable()) {
|
||||
$products[] = $variation;
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('Added variation ' . $variation_id . ' - ' . $variation->get_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($product->is_purchasable()) {
|
||||
// Simple and other product types
|
||||
$products[] = $product;
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('Added simple product ' . $product->get_id() . ' - ' . $product->get_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_reset_postdata();
|
||||
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('Total products available: ' . count($products));
|
||||
}
|
||||
|
||||
return $products;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user