Fix licensed variable products showing as sold out (v0.5.11)

- Fixed is_purchasable() method in LicensedVariableProduct to delegate to
  parent WC_Product_Variable instead of checking for price (variable products
  don't have direct prices, only their variations do)
- Fixed getProductClass() filter to accept all 4 WooCommerce parameters
  and use product_id for reliable variation parent detection
- Fallback to global $post when product_id not available for backwards compat

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-27 13:58:07 +01:00
parent db4966caf2
commit 953aa6c8e8
6 changed files with 39 additions and 10 deletions

View File

@@ -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;
}

View File

@@ -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();
}
/**