Fix licenses not showing in admin order form for variable products (v0.5.13)

- Fix OrderLicenseController to use isLicensedProduct() for consistent product type detection
- Fixed expected licenses calculation for variable product orders
- Fixed manual license generation from admin order page for variable products
- Remove debug logging from all source files (PHP and JavaScript)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-27 15:45:32 +01:00
parent 142500cab0
commit d29697ac62
9 changed files with 191 additions and 34 deletions

View File

@@ -83,7 +83,7 @@ final class OrderLicenseController
$hasLicensedProduct = false;
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if ($product && $product->is_type('licensed')) {
if ($product && $this->licenseManager->isLicensedProduct($product)) {
$hasLicensedProduct = true;
break;
}
@@ -162,7 +162,7 @@ final class OrderLicenseController
// Legacy: one license per licensed product
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if ($product && $product->is_type('licensed')) {
if ($product && $this->licenseManager->isLicensedProduct($product)) {
$expectedLicenses++;
}
}
@@ -567,7 +567,7 @@ final class OrderLicenseController
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if (!$product || !$product->is_type('licensed')) {
if (!$product || !$this->licenseManager->isLicensedProduct($product)) {
continue;
}
@@ -615,7 +615,7 @@ final class OrderLicenseController
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if (!$product || !$product->is_type('licensed')) {
if (!$product || !$this->licenseManager->isLicensedProduct($product)) {
continue;
}

View File

@@ -112,10 +112,12 @@ final class CheckoutBlocksIntegration implements IntegrationInterface
public function get_script_data(): array
{
$isMultiDomain = SettingsController::isMultiDomainEnabled();
$licensedProducts = $this->getLicensedProductsFromCart();
$hasLicensedProducts = !empty($licensedProducts);
return [
'hasLicensedProducts' => $this->cartHasLicensedProducts(),
'licensedProducts' => $this->getLicensedProductsFromCart(),
'hasLicensedProducts' => $hasLicensedProducts,
'licensedProducts' => $licensedProducts,
'isMultiDomainEnabled' => $isMultiDomain,
'fieldPlaceholder' => __('example.com', 'wc-licensed-product'),
'fieldDescription' => $isMultiDomain
@@ -151,8 +153,11 @@ final class CheckoutBlocksIntegration implements IntegrationInterface
}
$licensedProducts = [];
foreach (WC()->cart->get_cart() as $cartItem) {
$cartContents = WC()->cart->get_cart();
foreach ($cartContents as $cartKey => $cartItem) {
$product = $cartItem['data'];
if (!$product) {
continue;
}
@@ -171,11 +176,12 @@ final class CheckoutBlocksIntegration implements IntegrationInterface
}
// Check for variations of licensed-variable products
if ($product->is_type('variation')) {
$parentId = $product->get_parent_id();
$parent = wc_get_product($parentId);
// Use WC_Product_Factory::get_product_type() for reliable parent type check
$parentId = $product->get_parent_id();
if ($parentId) {
$parentType = \WC_Product_Factory::get_product_type($parentId);
if ($parent && $parent->is_type('licensed-variable')) {
if ($parentType === 'licensed-variable') {
$variationId = $product->get_id();
// Get duration label if it's a LicensedProductVariation

View File

@@ -67,8 +67,9 @@ final class CheckoutController
}
$licensedProducts = [];
foreach (WC()->cart->get_cart() as $cartItem) {
foreach (WC()->cart->get_cart() as $cartItemKey => $cartItem) {
$product = $cartItem['data'];
if (!$product) {
continue;
}
@@ -87,11 +88,12 @@ final class CheckoutController
}
// Check for variations of licensed-variable products
if ($product->is_type('variation')) {
$parentId = $product->get_parent_id();
$parent = wc_get_product($parentId);
// Use WC_Product_Factory::get_product_type() for reliable parent type check
$parentId = $product->get_parent_id();
if ($parentId) {
$parentType = \WC_Product_Factory::get_product_type($parentId);
if ($parent && $parent->is_type('licensed-variable')) {
if ($parentType === 'licensed-variable') {
$variationId = $product->get_id();
// Use combination key to allow same product with different variations
$key = "{$parentId}_{$variationId}";
@@ -127,6 +129,7 @@ final class CheckoutController
public function addDomainField(): void
{
$licensedProducts = $this->getLicensedProductsFromCart();
if (empty($licensedProducts)) {
return;
}
@@ -401,6 +404,7 @@ final class CheckoutController
public function saveDomainField(int $orderId): void
{
$licensedProducts = $this->getLicensedProductsFromCart();
if (empty($licensedProducts)) {
return;
}

View File

@@ -37,10 +37,18 @@ class LicenseManager
return true;
}
// Check for our custom variation class
if ($product instanceof LicensedProductVariation) {
return true;
}
// Variation of a licensed-variable product
if ($product->is_type('variation') && $product->get_parent_id()) {
$parent = wc_get_product($product->get_parent_id());
if ($parent && $parent->is_type('licensed-variable')) {
// Use WC_Product_Factory::get_product_type() for reliable parent type check
// This queries the database directly and doesn't depend on product class loading
$parentId = $product->get_parent_id();
if ($parentId) {
$parentType = \WC_Product_Factory::get_product_type($parentId);
if ($parentType === 'licensed-variable') {
return true;
}
}
@@ -101,10 +109,10 @@ class LicenseManager
// For variations, load the variation; otherwise load the parent product
if ($variationId) {
$settingsProduct = wc_get_product($variationId);
$parentProduct = wc_get_product($productId);
// Verify parent is licensed-variable
if (!$parentProduct || !$parentProduct->is_type('licensed-variable')) {
// Verify parent is licensed-variable using DB-level type check
$parentType = \WC_Product_Factory::get_product_type($productId);
if ($parentType !== 'licensed-variable') {
return null;
}

View File

@@ -210,6 +210,7 @@ final class Plugin
// Try new multi-domain format first
$domainData = $order->get_meta('_licensed_product_domains');
if (!empty($domainData) && is_array($domainData)) {
$this->generateLicensesMultiDomain($order, $domainData);
return;
@@ -244,7 +245,12 @@ final class Plugin
// Generate licenses for each licensed product
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if (!$product || !$this->licenseManager->isLicensedProduct($product)) {
if (!$product) {
continue;
}
if (!$this->licenseManager->isLicensedProduct($product)) {
continue;
}
@@ -278,12 +284,14 @@ final class Plugin
private function generateLicensesSingleDomain(\WC_Order $order): void
{
$domain = $order->get_meta('_licensed_product_domain');
if (empty($domain)) {
return;
}
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if ($product && $this->licenseManager->isLicensedProduct($product)) {
// Get the parent product ID (for variations, this is the main product)
$productId = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();