You've already forked wc-licensed-product
Implement multi-domain licensing for v0.5.0
- Add multi-domain checkout support for WooCommerce Blocks - Fix domain field rendering using ExperimentalOrderMeta slot - Add DOM injection fallback for checkout field rendering - Update translations with new multi-domain strings (de_CH) - Update email templates for grouped license display - Refactor account page to group licenses by product/order Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ namespace Jeremias\WcLicensedProduct\Checkout;
|
||||
use Automattic\WooCommerce\StoreApi\Schemas\V1\CheckoutSchema;
|
||||
use Automattic\WooCommerce\StoreApi\StoreApi;
|
||||
use Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema;
|
||||
use Jeremias\WcLicensedProduct\Admin\SettingsController;
|
||||
use Jeremias\WcLicensedProduct\License\LicenseManager;
|
||||
|
||||
/**
|
||||
@@ -70,6 +71,12 @@ final class StoreApiExtension
|
||||
*/
|
||||
public function getExtensionData(): array
|
||||
{
|
||||
if (SettingsController::isMultiDomainEnabled()) {
|
||||
return [
|
||||
'licensed_product_domains' => WC()->session ? WC()->session->get('licensed_product_domains', []) : [],
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'licensed_product_domain' => WC()->session ? WC()->session->get('licensed_product_domain', '') : '',
|
||||
];
|
||||
@@ -80,6 +87,31 @@ final class StoreApiExtension
|
||||
*/
|
||||
public function getExtensionSchema(): array
|
||||
{
|
||||
if (SettingsController::isMultiDomainEnabled()) {
|
||||
return [
|
||||
'licensed_product_domains' => [
|
||||
'description' => __('Domains for license activation by product', 'wc-licensed-product'),
|
||||
'type' => 'array',
|
||||
'context' => ['view', 'edit'],
|
||||
'readonly' => false,
|
||||
'items' => [
|
||||
'type' => 'object',
|
||||
'properties' => [
|
||||
'product_id' => [
|
||||
'type' => 'integer',
|
||||
],
|
||||
'domains' => [
|
||||
'type' => 'array',
|
||||
'items' => [
|
||||
'type' => 'string',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'licensed_product_domain' => [
|
||||
'description' => __('Domain for license activation', 'wc-licensed-product'),
|
||||
@@ -95,30 +127,103 @@ final class StoreApiExtension
|
||||
*/
|
||||
public function handleExtensionUpdate(array $data): void
|
||||
{
|
||||
if (isset($data['licensed_product_domain'])) {
|
||||
$domain = sanitize_text_field($data['licensed_product_domain']);
|
||||
$normalizedDomain = $this->licenseManager->normalizeDomain($domain);
|
||||
if (SettingsController::isMultiDomainEnabled()) {
|
||||
// Multi-domain mode
|
||||
if (isset($data['licensed_product_domains']) && is_array($data['licensed_product_domains'])) {
|
||||
$normalizedData = $this->normalizeDomainsData($data['licensed_product_domains']);
|
||||
|
||||
if (WC()->session) {
|
||||
WC()->session->set('licensed_product_domain', $normalizedDomain);
|
||||
if (WC()->session) {
|
||||
WC()->session->set('licensed_product_domains', $normalizedData);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Single domain mode
|
||||
if (isset($data['licensed_product_domain'])) {
|
||||
$sanitized = sanitize_text_field($data['licensed_product_domain']);
|
||||
$normalized = $this->licenseManager->normalizeDomain($sanitized);
|
||||
|
||||
if (WC()->session) {
|
||||
WC()->session->set('licensed_product_domain', $normalized);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the checkout order - save domain to order meta
|
||||
* Normalize domains data from frontend
|
||||
*/
|
||||
private function normalizeDomainsData(array $domainsData): array
|
||||
{
|
||||
$normalized = [];
|
||||
|
||||
foreach ($domainsData as $item) {
|
||||
if (!isset($item['product_id']) || !isset($item['domains']) || !is_array($item['domains'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$productId = (int) $item['product_id'];
|
||||
$domains = [];
|
||||
|
||||
foreach ($item['domains'] as $domain) {
|
||||
$sanitized = sanitize_text_field($domain);
|
||||
if (!empty($sanitized)) {
|
||||
$domains[] = $this->licenseManager->normalizeDomain($sanitized);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($domains)) {
|
||||
$normalized[] = [
|
||||
'product_id' => $productId,
|
||||
'domains' => $domains,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the checkout order - save domains to order meta
|
||||
*/
|
||||
public function processCheckoutOrder(\WC_Order $order): void
|
||||
{
|
||||
$domain = WC()->session ? WC()->session->get('licensed_product_domain', '') : '';
|
||||
$requestData = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
// Also check in the request data for block checkout
|
||||
if (empty($domain)) {
|
||||
$requestData = json_decode(file_get_contents('php://input'), true);
|
||||
if (isset($requestData['extensions'][self::IDENTIFIER]['licensed_product_domain'])) {
|
||||
$domain = sanitize_text_field($requestData['extensions'][self::IDENTIFIER]['licensed_product_domain']);
|
||||
$domain = $this->licenseManager->normalizeDomain($domain);
|
||||
}
|
||||
if (SettingsController::isMultiDomainEnabled()) {
|
||||
$this->processMultiDomainOrder($order, $requestData);
|
||||
} else {
|
||||
$this->processSingleDomainOrder($order, $requestData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process order in single domain mode (legacy)
|
||||
*/
|
||||
private function processSingleDomainOrder(\WC_Order $order, ?array $requestData): void
|
||||
{
|
||||
$domain = '';
|
||||
|
||||
// Check session first
|
||||
if (WC()->session) {
|
||||
$domain = WC()->session->get('licensed_product_domain', '');
|
||||
}
|
||||
|
||||
// Check in the request data for block checkout (extension data)
|
||||
if (empty($domain) && isset($requestData['extensions'][self::IDENTIFIER]['licensed_product_domain'])) {
|
||||
$sanitized = sanitize_text_field($requestData['extensions'][self::IDENTIFIER]['licensed_product_domain']);
|
||||
$domain = $this->licenseManager->normalizeDomain($sanitized);
|
||||
}
|
||||
|
||||
// Check for wclp_license_domain (from our hidden input)
|
||||
if (empty($domain) && isset($requestData['wclp_license_domain'])) {
|
||||
$sanitized = sanitize_text_field($requestData['wclp_license_domain']);
|
||||
$domain = $this->licenseManager->normalizeDomain($sanitized);
|
||||
}
|
||||
|
||||
// Check for additional_fields (WC Blocks API)
|
||||
if (empty($domain) && isset($requestData['additional_fields']['wc-licensed-product/domain'])) {
|
||||
$sanitized = sanitize_text_field($requestData['additional_fields']['wc-licensed-product/domain']);
|
||||
$domain = $this->licenseManager->normalizeDomain($sanitized);
|
||||
}
|
||||
|
||||
if (!empty($domain)) {
|
||||
@@ -131,4 +236,65 @@ final class StoreApiExtension
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process order in multi-domain mode
|
||||
*/
|
||||
private function processMultiDomainOrder(\WC_Order $order, ?array $requestData): void
|
||||
{
|
||||
$domainData = [];
|
||||
|
||||
// Check session first
|
||||
if (WC()->session) {
|
||||
$domainData = WC()->session->get('licensed_product_domains', []);
|
||||
}
|
||||
|
||||
// Check in the request data for block checkout (extension data)
|
||||
if (empty($domainData) && isset($requestData['extensions'][self::IDENTIFIER]['licensed_product_domains'])) {
|
||||
$domainData = $this->normalizeDomainsData(
|
||||
$requestData['extensions'][self::IDENTIFIER]['licensed_product_domains']
|
||||
);
|
||||
}
|
||||
|
||||
// Check for wclp_license_domains (from our hidden input - JSON string)
|
||||
if (empty($domainData) && isset($requestData['wclp_license_domains'])) {
|
||||
$parsed = json_decode($requestData['wclp_license_domains'], true);
|
||||
if (is_array($parsed)) {
|
||||
$domainData = $this->normalizeDomainsData($parsed);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for licensed_domains in classic format (from DOM injection)
|
||||
if (empty($domainData) && isset($requestData['licensed_domains']) && is_array($requestData['licensed_domains'])) {
|
||||
$domainData = [];
|
||||
foreach ($requestData['licensed_domains'] as $productId => $domains) {
|
||||
if (!is_array($domains)) {
|
||||
continue;
|
||||
}
|
||||
$normalizedDomains = [];
|
||||
foreach ($domains as $domain) {
|
||||
$sanitized = sanitize_text_field($domain);
|
||||
if (!empty($sanitized)) {
|
||||
$normalizedDomains[] = $this->licenseManager->normalizeDomain($sanitized);
|
||||
}
|
||||
}
|
||||
if (!empty($normalizedDomains)) {
|
||||
$domainData[] = [
|
||||
'product_id' => (int) $productId,
|
||||
'domains' => $normalizedDomains,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($domainData)) {
|
||||
$order->update_meta_data('_licensed_product_domains', $domainData);
|
||||
$order->save();
|
||||
|
||||
// Clear session data
|
||||
if (WC()->session) {
|
||||
WC()->session->set('licensed_product_domains', []);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user