Files
wc-licensed-product/src/Product/LicensedProductVariation.php

252 lines
6.7 KiB
PHP
Raw Normal View History

<?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;
}
/**
* Licensed products are always in stock (virtual, no inventory)
*/
public function is_in_stock(): bool
{
return true;
}
/**
* Get availability - empty for licensed products (no stock indicator)
*/
public function get_availability(): array
{
return [
'availability' => '',
'class' => '',
];
}
/**
* Don't manage stock for licensed products
*/
public function managing_stock(): bool
{
return false;
}
/**
* Check if variation is purchasable
* Override to handle custom parent product type
*/
public function is_purchasable(): bool
{
// Check if variation exists
if (!$this->exists()) {
return false;
}
// Check parent product status
$parentId = $this->get_parent_id();
$parentStatus = get_post_status($parentId);
if ($parentStatus !== 'publish' && !current_user_can('edit_post', $parentId)) {
return false;
}
// Check if variation has a price
$price = $this->get_price();
if ($price === '' || $price === null) {
return false;
}
return apply_filters('woocommerce_variation_is_purchasable', true, $this);
}
/**
* 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;
}
}