diff --git a/CHANGELOG.md b/CHANGELOG.md index 6902854..6e8503a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.5.11] - 2026-01-27 + +### Fixed + +- **CRITICAL:** Fixed "sold out" message on licensed variable products by correcting `is_purchasable()` method +- Variable products don't have a direct price - `is_purchasable()` now delegates to parent `WC_Product_Variable` class +- Fixed variation class detection by using product ID parameter instead of unreliable global `$post` +- Product class filter now properly accepts all 4 WooCommerce filter parameters for reliable variation detection + ## [0.5.10] - 2026-01-27 ### Fixed diff --git a/releases/wc-licensed-product-0.5.11.zip b/releases/wc-licensed-product-0.5.11.zip new file mode 100644 index 0000000..20325cb Binary files /dev/null and b/releases/wc-licensed-product-0.5.11.zip differ diff --git a/releases/wc-licensed-product-0.5.11.zip.sha256 b/releases/wc-licensed-product-0.5.11.zip.sha256 new file mode 100644 index 0000000..a1d7460 --- /dev/null +++ b/releases/wc-licensed-product-0.5.11.zip.sha256 @@ -0,0 +1 @@ +32571178bfa8f0d0a03ed05b498d5f9b3c860104393a96732e86a03b6de298d2 wc-licensed-product-0.5.11.zip diff --git a/src/Product/LicensedProductType.php b/src/Product/LicensedProductType.php index 7abb461..ff9fe12 100644 --- a/src/Product/LicensedProductType.php +++ b/src/Product/LicensedProductType.php @@ -32,7 +32,7 @@ final class LicensedProductType { // Register product types add_filter('product_type_selector', [$this, 'addProductType']); - add_filter('woocommerce_product_class', [$this, 'getProductClass'], 10, 2); + add_filter('woocommerce_product_class', [$this, 'getProductClass'], 10, 4); // Add product data tabs add_filter('woocommerce_product_data_tabs', [$this, 'addProductDataTab']); @@ -76,8 +76,13 @@ final class LicensedProductType /** * Get product class for licensed types + * + * @param string $className Default class name + * @param string $productType Product type + * @param string $postType Post type (usually 'product' or 'product_variation') + * @param int $productId Product ID */ - public function getProductClass(string $className, string $productType): string + public function getProductClass(string $className, string $productType, string $postType = '', int $productId = 0): string { if ($productType === 'licensed') { return LicensedProduct::class; @@ -87,10 +92,21 @@ final class LicensedProductType } // Handle variations of licensed-variable products if ($productType === 'variation') { - // Check if parent is licensed-variable - global $post; - if ($post && $post->post_parent) { - $parentType = \WC_Product_Factory::get_product_type($post->post_parent); + // Get parent ID from the product post + $parentId = 0; + if ($productId > 0) { + $parentId = wp_get_post_parent_id($productId); + } + // Fallback to global $post if product ID not available + if (!$parentId) { + global $post; + if ($post && $post->post_parent) { + $parentId = $post->post_parent; + } + } + + if ($parentId) { + $parentType = \WC_Product_Factory::get_product_type($parentId); if ($parentType === 'licensed-variable') { return LicensedProductVariation::class; } diff --git a/src/Product/LicensedVariableProduct.php b/src/Product/LicensedVariableProduct.php index 81fc864..d1eb233 100644 --- a/src/Product/LicensedVariableProduct.php +++ b/src/Product/LicensedVariableProduct.php @@ -50,11 +50,14 @@ class LicensedVariableProduct extends WC_Product_Variable } /** - * Licensed products are purchasable + * Licensed variable products are purchasable if the parent check passes + * Variable products don't have a direct price - their variations do */ public function is_purchasable(): bool { - return $this->exists() && $this->get_price() !== ''; + // Use the parent WC_Product_Variable logic + // which checks exists() and status, not price + return parent::is_purchasable(); } /** diff --git a/wc-licensed-product.php b/wc-licensed-product.php index bb4d435..2600266 100644 --- a/wc-licensed-product.php +++ b/wc-licensed-product.php @@ -3,7 +3,7 @@ * Plugin Name: WooCommerce Licensed Product * Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-licensed-product * Description: WooCommerce plugin to sell software products using license keys with domain-based validation. - * Version: 0.5.10 + * Version: 0.5.11 * Author: Marco Graetsch * Author URI: https://src.bundespruefstelle.ch/magdev * License: GPL-2.0-or-later @@ -28,7 +28,7 @@ if (!defined('ABSPATH')) { } // Plugin constants -define('WC_LICENSED_PRODUCT_VERSION', '0.5.10'); +define('WC_LICENSED_PRODUCT_VERSION', '0.5.11'); define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__); define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));