You've already forked wc-licensed-product
Add licensed variable product support for duration-based licenses (v0.5.3)
Customers can now purchase licenses with different durations (monthly, yearly, lifetime) through WooCommerce product variations. Each variation can have its own license validity settings. New features: - LicensedVariableProduct class for variable licensed products - LicensedProductVariation class for individual variations - Per-variation license duration and max activations settings - Duration labels in checkout (Monthly, Quarterly, Yearly, etc.) - Full support for WooCommerce Blocks checkout with variations - Updated translations for German (de_CH) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
196
src/Product/LicensedProductVariation.php
Normal file
196
src/Product/LicensedProductVariation.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* Licensed Product Variation Class
|
||||
*
|
||||
* @package Jeremias\WcLicensedProduct\Product
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jeremias\WcLicensedProduct\Product;
|
||||
|
||||
use Jeremias\WcLicensedProduct\Admin\SettingsController;
|
||||
use WC_Product_Variation;
|
||||
|
||||
/**
|
||||
* Licensed Product Variation type extending WooCommerce Product Variation
|
||||
*
|
||||
* Each variation can have its own license duration settings.
|
||||
*/
|
||||
class LicensedProductVariation extends WC_Product_Variation
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($product = 0)
|
||||
{
|
||||
parent::__construct($product);
|
||||
}
|
||||
|
||||
/**
|
||||
* Licensed products are always virtual
|
||||
*/
|
||||
public function is_virtual(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get max activations for this variation
|
||||
* Falls back to parent product, then to default settings
|
||||
*/
|
||||
public function get_max_activations(): int
|
||||
{
|
||||
// Check variation-specific setting first
|
||||
$value = $this->get_meta('_licensed_max_activations', true);
|
||||
if ($value !== '' && $value !== null) {
|
||||
return max(1, (int) $value);
|
||||
}
|
||||
|
||||
// Fall back to parent product
|
||||
$parent = wc_get_product($this->get_parent_id());
|
||||
if ($parent && method_exists($parent, 'get_max_activations')) {
|
||||
return $parent->get_max_activations();
|
||||
}
|
||||
|
||||
return SettingsController::getDefaultMaxActivations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if variation has custom max activations set
|
||||
*/
|
||||
public function has_custom_max_activations(): bool
|
||||
{
|
||||
$value = $this->get_meta('_licensed_max_activations', true);
|
||||
return $value !== '' && $value !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get validity days for this variation
|
||||
* This is the primary license setting that varies per variation
|
||||
* Falls back to parent product, then to default settings
|
||||
*/
|
||||
public function get_validity_days(): ?int
|
||||
{
|
||||
// Check variation-specific setting first
|
||||
$value = $this->get_meta('_licensed_validity_days', true);
|
||||
if ($value !== '' && $value !== null) {
|
||||
$days = (int) $value;
|
||||
// 0 means lifetime
|
||||
return $days > 0 ? $days : null;
|
||||
}
|
||||
|
||||
// Fall back to parent product
|
||||
$parent = wc_get_product($this->get_parent_id());
|
||||
if ($parent && method_exists($parent, 'get_validity_days')) {
|
||||
return $parent->get_validity_days();
|
||||
}
|
||||
|
||||
return SettingsController::getDefaultValidityDays();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if variation has custom validity days set
|
||||
*/
|
||||
public function has_custom_validity_days(): bool
|
||||
{
|
||||
$value = $this->get_meta('_licensed_validity_days', true);
|
||||
return $value !== '' && $value !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if license should be bound to major version
|
||||
* Falls back to parent product, then to default settings
|
||||
*/
|
||||
public function is_bound_to_version(): bool
|
||||
{
|
||||
// Check variation-specific setting first
|
||||
$value = $this->get_meta('_licensed_bind_to_version', true);
|
||||
if ($value !== '' && $value !== null) {
|
||||
return $value === 'yes';
|
||||
}
|
||||
|
||||
// Fall back to parent product
|
||||
$parent = wc_get_product($this->get_parent_id());
|
||||
if ($parent && method_exists($parent, 'is_bound_to_version')) {
|
||||
return $parent->is_bound_to_version();
|
||||
}
|
||||
|
||||
return SettingsController::getDefaultBindToVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if variation has custom bind to version setting
|
||||
*/
|
||||
public function has_custom_bind_to_version(): bool
|
||||
{
|
||||
$value = $this->get_meta('_licensed_bind_to_version', true);
|
||||
return $value !== '' && $value !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the license duration label for display
|
||||
*/
|
||||
public function get_license_duration_label(): string
|
||||
{
|
||||
$days = $this->get_validity_days();
|
||||
|
||||
if ($days === null) {
|
||||
return __('Lifetime', 'wc-licensed-product');
|
||||
}
|
||||
|
||||
if ($days === 30) {
|
||||
return __('Monthly', 'wc-licensed-product');
|
||||
}
|
||||
|
||||
if ($days === 90) {
|
||||
return __('Quarterly', 'wc-licensed-product');
|
||||
}
|
||||
|
||||
if ($days === 365) {
|
||||
return __('Yearly', 'wc-licensed-product');
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
/* translators: %d: number of days */
|
||||
_n('%d day', '%d days', $days, 'wc-licensed-product'),
|
||||
$days
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current software version from parent product
|
||||
*/
|
||||
public function get_current_version(): string
|
||||
{
|
||||
$parent = wc_get_product($this->get_parent_id());
|
||||
if ($parent && method_exists($parent, 'get_current_version')) {
|
||||
return $parent->get_current_version();
|
||||
}
|
||||
|
||||
$versionManager = new VersionManager();
|
||||
$latestVersion = $versionManager->getLatestVersion($this->get_parent_id());
|
||||
|
||||
return $latestVersion ? $latestVersion->getVersion() : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get major version number from parent product
|
||||
*/
|
||||
public function get_major_version(): int
|
||||
{
|
||||
$parent = wc_get_product($this->get_parent_id());
|
||||
if ($parent && method_exists($parent, 'get_major_version')) {
|
||||
return $parent->get_major_version();
|
||||
}
|
||||
|
||||
$versionManager = new VersionManager();
|
||||
$latestVersion = $versionManager->getLatestVersion($this->get_parent_id());
|
||||
|
||||
if ($latestVersion) {
|
||||
return $latestVersion->getMajorVersion();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user