You've already forked wc-licensed-product
208 lines
6.0 KiB
PHP
208 lines
6.0 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* Checkout Controller
|
||
|
|
*
|
||
|
|
* @package Jeremias\WcLicensedProduct\Checkout
|
||
|
|
*/
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace Jeremias\WcLicensedProduct\Checkout;
|
||
|
|
|
||
|
|
use Jeremias\WcLicensedProduct\License\LicenseManager;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Handles checkout modifications for licensed products
|
||
|
|
*/
|
||
|
|
final class CheckoutController
|
||
|
|
{
|
||
|
|
private LicenseManager $licenseManager;
|
||
|
|
|
||
|
|
public function __construct(LicenseManager $licenseManager)
|
||
|
|
{
|
||
|
|
$this->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
|
||
|
|
{
|
||
|
|
if (!WC()->cart) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (WC()->cart->get_cart() as $cartItem) {
|
||
|
|
$product = $cartItem['data'];
|
||
|
|
if ($product && $product->is_type('licensed')) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add domain field to checkout form
|
||
|
|
*/
|
||
|
|
public function addDomainField(): void
|
||
|
|
{
|
||
|
|
if (!$this->cartHasLicensedProducts()) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
?>
|
||
|
|
<div id="licensed-product-domain-field">
|
||
|
|
<h3><?php esc_html_e('License Domain', 'wc-licensed-product'); ?></h3>
|
||
|
|
<p class="form-row form-row-wide">
|
||
|
|
<label for="licensed_product_domain">
|
||
|
|
<?php esc_html_e('Domain for License Activation', 'wc-licensed-product'); ?>
|
||
|
|
<abbr class="required" title="<?php esc_attr_e('required', 'wc-licensed-product'); ?>">*</abbr>
|
||
|
|
</label>
|
||
|
|
<input
|
||
|
|
type="text"
|
||
|
|
class="input-text"
|
||
|
|
name="licensed_product_domain"
|
||
|
|
id="licensed_product_domain"
|
||
|
|
placeholder="<?php esc_attr_e('example.com', 'wc-licensed-product'); ?>"
|
||
|
|
value="<?php echo esc_attr(WC()->checkout->get_value('licensed_product_domain')); ?>"
|
||
|
|
/>
|
||
|
|
<span class="description">
|
||
|
|
<?php esc_html_e('Enter the domain where you will use this license (without http:// or www).', 'wc-licensed-product'); ?>
|
||
|
|
</span>
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
<?php
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Validate domain field during checkout
|
||
|
|
*/
|
||
|
|
public function validateDomainField(): void
|
||
|
|
{
|
||
|
|
if (!$this->cartHasLicensedProducts()) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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 activation.', 'wc-licensed-product'),
|
||
|
|
'error'
|
||
|
|
);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate domain format
|
||
|
|
$normalizedDomain = $this->licenseManager->normalizeDomain($domain);
|
||
|
|
if (!$this->isValidDomain($normalizedDomain)) {
|
||
|
|
wc_add_notice(
|
||
|
|
__('Please enter a valid domain name.', 'wc-licensed-product'),
|
||
|
|
'error'
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Save domain field to order meta
|
||
|
|
*/
|
||
|
|
public function saveDomainField(int $orderId): void
|
||
|
|
{
|
||
|
|
if (!$this->cartHasLicensedProducts()) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isset($_POST['licensed_product_domain']) && !empty($_POST['licensed_product_domain'])) {
|
||
|
|
$domain = sanitize_text_field($_POST['licensed_product_domain']);
|
||
|
|
$normalizedDomain = $this->licenseManager->normalizeDomain($domain);
|
||
|
|
|
||
|
|
$order = wc_get_order($orderId);
|
||
|
|
if ($order) {
|
||
|
|
$order->update_meta_data('_licensed_product_domain', $normalizedDomain);
|
||
|
|
$order->save();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Display domain in admin order view
|
||
|
|
*/
|
||
|
|
public function displayDomainInAdmin(\WC_Order $order): void
|
||
|
|
{
|
||
|
|
$domain = $order->get_meta('_licensed_product_domain');
|
||
|
|
if (!$domain) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
?>
|
||
|
|
<p>
|
||
|
|
<strong><?php esc_html_e('License Domain:', 'wc-licensed-product'); ?></strong>
|
||
|
|
<?php echo esc_html($domain); ?>
|
||
|
|
</p>
|
||
|
|
<?php
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Display domain in order emails
|
||
|
|
*/
|
||
|
|
public function displayDomainInEmail(\WC_Order $order, bool $sentToAdmin, bool $plainText): void
|
||
|
|
{
|
||
|
|
$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 {
|
||
|
|
?>
|
||
|
|
<p>
|
||
|
|
<strong><?php esc_html_e('License Domain:', 'wc-licensed-product'); ?></strong>
|
||
|
|
<?php echo esc_html($domain); ?>
|
||
|
|
</p>
|
||
|
|
<?php
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Validate domain format
|
||
|
|
*/
|
||
|
|
private function isValidDomain(string $domain): bool
|
||
|
|
{
|
||
|
|
// Basic domain validation
|
||
|
|
if (strlen($domain) > 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);
|
||
|
|
}
|
||
|
|
}
|