licenseManager = $licenseManager; $this->registerHooks(); } /** * Register WordPress hooks */ private function registerHooks(): void { // Add domain field to checkout add_action('woocommerce_after_order_notes', [$this, 'addDomainField']); // Validate domain field add_action('woocommerce_checkout_process', [$this, 'validateDomainField']); // Save domain field to order meta add_action('woocommerce_checkout_update_order_meta', [$this, 'saveDomainField']); // Display domain in order details (admin) add_action('woocommerce_admin_order_data_after_billing_address', [$this, 'displayDomainInAdmin']); // Display domain in order email add_action('woocommerce_email_after_order_table', [$this, 'displayDomainInEmail'], 10, 3); } /** * Check if cart contains licensed products */ private function cartHasLicensedProducts(): bool { return !empty($this->getLicensedProductsFromCart()); } /** * Get licensed products from cart with quantities * * @return array */ private function getLicensedProductsFromCart(): array { if (!WC()->cart) { return []; } $licensedProducts = []; foreach (WC()->cart->get_cart() as $cartItem) { $product = $cartItem['data']; if ($product && $product->is_type('licensed')) { $productId = $product->get_id(); $licensedProducts[$productId] = [ 'product_id' => $productId, 'name' => $product->get_name(), 'quantity' => (int) $cartItem['quantity'], ]; } } return $licensedProducts; } /** * Add domain fields to checkout form * Shows multiple domain fields if multi-domain is enabled, otherwise single field */ public function addDomainField(): void { $licensedProducts = $this->getLicensedProductsFromCart(); if (empty($licensedProducts)) { return; } // Check if multi-domain licensing is enabled if (SettingsController::isMultiDomainEnabled()) { $this->renderMultiDomainFields($licensedProducts); } else { $this->renderSingleDomainField(); } } /** * Render single domain field (legacy mode) */ private function renderSingleDomainField(): void { $savedValue = ''; // Check POST data first (validation failure case) if (isset($_POST['licensed_product_domain'])) { $savedValue = sanitize_text_field($_POST['licensed_product_domain']); } elseif (WC()->session) { $savedValue = WC()->session->get('licensed_product_domain', ''); } ?>

$productData): ?>

1) { printf(' (×%d)', $productData['quantity']); } ?>

getSavedDomainValue($productId, $i); ?>

session) { $sessionDomains = WC()->session->get('licensed_product_domains', []); foreach ($sessionDomains as $item) { if (isset($item['product_id']) && (int) $item['product_id'] === $productId) { if (isset($item['domains'][$index])) { return $item['domains'][$index]; } } } } return ''; } /** * Validate domain fields during checkout */ public function validateDomainField(): void { $licensedProducts = $this->getLicensedProductsFromCart(); if (empty($licensedProducts)) { return; } // Check if multi-domain licensing is enabled if (SettingsController::isMultiDomainEnabled()) { $this->validateMultiDomainFields($licensedProducts); } else { $this->validateSingleDomainField(); } } /** * Validate single domain field */ private function validateSingleDomainField(): void { $domain = isset($_POST['licensed_product_domain']) ? sanitize_text_field($_POST['licensed_product_domain']) : ''; if (empty($domain)) { wc_add_notice(__('Please enter a domain for your license.', 'wc-licensed-product'), 'error'); return; } $normalizedDomain = $this->licenseManager->normalizeDomain($domain); if (!$this->isValidDomain($normalizedDomain)) { wc_add_notice(__('Please enter a valid domain for your license.', 'wc-licensed-product'), 'error'); } } /** * Validate multi-domain fields */ private function validateMultiDomainFields(array $licensedProducts): void { $licensedDomains = $_POST['licensed_domains'] ?? []; foreach ($licensedProducts as $productId => $productData) { $productDomains = $licensedDomains[$productId] ?? []; $normalizedDomains = []; for ($i = 0; $i < $productData['quantity']; $i++) { $domain = isset($productDomains[$i]) ? sanitize_text_field($productDomains[$i]) : ''; // Check if domain is empty if (empty($domain)) { wc_add_notice( sprintf( /* translators: 1: product name, 2: license number */ __('Please enter a domain for %1$s (License %2$d).', 'wc-licensed-product'), $productData['name'], $i + 1 ), 'error' ); continue; } // Validate domain format $normalizedDomain = $this->licenseManager->normalizeDomain($domain); if (!$this->isValidDomain($normalizedDomain)) { wc_add_notice( sprintf( /* translators: 1: product name, 2: license number */ __('Please enter a valid domain for %1$s (License %2$d).', 'wc-licensed-product'), $productData['name'], $i + 1 ), 'error' ); continue; } // Check for duplicate domains within same product if (in_array($normalizedDomain, $normalizedDomains, true)) { wc_add_notice( sprintf( /* translators: 1: domain name, 2: product name */ __('The domain "%1$s" is used multiple times for %2$s. Each license requires a unique domain.', 'wc-licensed-product'), $normalizedDomain, $productData['name'] ), 'error' ); } else { $normalizedDomains[] = $normalizedDomain; } } } } /** * Save domain fields to order meta */ public function saveDomainField(int $orderId): void { $licensedProducts = $this->getLicensedProductsFromCart(); if (empty($licensedProducts)) { return; } $order = wc_get_order($orderId); if (!$order) { return; } // Check if multi-domain licensing is enabled if (SettingsController::isMultiDomainEnabled()) { $this->saveMultiDomainFields($order, $licensedProducts); } else { $this->saveSingleDomainField($order); } } /** * Save single domain field to order meta (legacy format) */ private function saveSingleDomainField(\WC_Order $order): void { $domain = isset($_POST['licensed_product_domain']) ? sanitize_text_field($_POST['licensed_product_domain']) : ''; if (!empty($domain)) { $normalizedDomain = $this->licenseManager->normalizeDomain($domain); $order->update_meta_data('_licensed_product_domain', $normalizedDomain); $order->save(); } } /** * Save multi-domain fields to order meta */ private function saveMultiDomainFields(\WC_Order $order, array $licensedProducts): void { $licensedDomains = $_POST['licensed_domains'] ?? []; $domainData = []; foreach ($licensedProducts as $productId => $productData) { $productDomains = $licensedDomains[$productId] ?? []; $normalizedDomains = []; for ($i = 0; $i < $productData['quantity']; $i++) { $domain = isset($productDomains[$i]) ? sanitize_text_field($productDomains[$i]) : ''; if (!empty($domain)) { $normalizedDomains[] = $this->licenseManager->normalizeDomain($domain); } } if (!empty($normalizedDomains)) { $domainData[] = [ 'product_id' => $productId, 'domains' => $normalizedDomains, ]; } } if (!empty($domainData)) { $order->update_meta_data('_licensed_product_domains', $domainData); $order->save(); } } /** * Display domains in admin order view */ public function displayDomainInAdmin(\WC_Order $order): void { // Try new multi-domain format first $domainData = $order->get_meta('_licensed_product_domains'); if (!empty($domainData) && is_array($domainData)) { $this->displayMultiDomainsInAdmin($domainData); return; } // Fall back to legacy single domain $domain = $order->get_meta('_licensed_product_domain'); if (!$domain) { return; } ?>

get_name() : __('Unknown Product', 'wc-licensed-product'); ?>

:

get_meta('_licensed_product_domains'); if (!empty($domainData) && is_array($domainData)) { $this->displayMultiDomainsInEmail($domainData, $plainText); return; } // Fall back to legacy single domain $domain = $order->get_meta('_licensed_product_domain'); if (!$domain) { return; } if ($plainText) { echo "\n" . esc_html__('License Domain:', 'wc-licensed-product') . ' ' . esc_html($domain) . "\n"; } else { ?>

get_name() : __('Unknown Product', 'wc-licensed-product'); echo ' ' . esc_html($productName) . ': ' . esc_html(implode(', ', $item['domains'])) . "\n"; } } else { ?>
get_name() : __('Unknown Product', 'wc-licensed-product'); ?>

:

255) { return false; } // Check for valid domain pattern $pattern = '/^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/'; return (bool) preg_match($pattern, $domain); } }