You've already forked wc-licensed-product
Fix stock indicator on licensed variable products (v0.5.12)
- Fixed stock indicator appearing in cart for licensed variable products - Override get_children() with direct SQL query to bypass WooCommerce type check - Override get_variation_attributes() for proper taxonomy attribute loading - Override get_variation_prices() to prevent null array errors - Override get_available_variations() with empty availability_html - Added is_type() override to pass variable type checks - Added multiple stock-related filters for comprehensive coverage - Improved isLicensedProductOrVariation() with DB-level parent type check Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
18
CHANGELOG.md
18
CHANGELOG.md
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.5.12] - 2026-01-27
|
||||
|
||||
### Fixed
|
||||
|
||||
- **CRITICAL:** Fixed stock indicator ("1 in stock") appearing in cart for licensed variable product variations
|
||||
- Override `get_children()` with direct SQL query to bypass WooCommerce's `is_type('variable')` check
|
||||
- Override `get_variation_attributes()` to properly load taxonomy attribute terms
|
||||
- Override `get_variation_prices()` to prevent fatal error with null `$this->prices_array`
|
||||
- Override `get_available_variations()` with empty `availability_html` for variations
|
||||
- Added `is_type()` override to return true for both 'licensed-variable' and 'variable' type checks
|
||||
- Added multiple stock-related filters: `woocommerce_get_availability_text`, `woocommerce_product_get_stock_quantity`, `woocommerce_product_variation_get_stock_quantity`
|
||||
- Improved `isLicensedProductOrVariation()` check using `WC_Product_Factory::get_product_type()` for reliable parent type detection
|
||||
|
||||
### Changed
|
||||
|
||||
- `LicensedProductVariation` now includes `get_availability()`, `managing_stock()`, and `is_purchasable()` overrides
|
||||
- Simplified `isVirtual()` to use shared `isLicensedProductOrVariation()` helper
|
||||
|
||||
## [0.5.11] - 2026-01-27
|
||||
|
||||
### Fixed
|
||||
|
||||
Binary file not shown.
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WC Licensed Product 0.5.0\n"
|
||||
"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n"
|
||||
"POT-Creation-Date: 2026-01-27 13:34+0100\n"
|
||||
"POT-Creation-Date: 2026-01-27 14:41+0100\n"
|
||||
"PO-Revision-Date: 2026-01-25T18:30:00+00:00\n"
|
||||
"Last-Translator: Marco Graetsch <magdev3.0@gmail.com>\n"
|
||||
"Language-Team: German (Switzerland) <de_CH@li.org>\n"
|
||||
@@ -311,10 +311,10 @@ msgstr "Speichern"
|
||||
#: src/Admin/DashboardWidgetController.php:136
|
||||
#: src/Admin/OrderLicenseController.php:260
|
||||
#: src/Admin/SettingsController.php:192
|
||||
#: src/Product/LicensedProductVariation.php:139
|
||||
#: src/Product/LicensedProductType.php:136
|
||||
#: src/Product/LicensedProductType.php:184
|
||||
#: src/Product/LicensedProductType.php:403
|
||||
#: src/Product/LicensedProductVariation.php:194
|
||||
#: src/Product/LicensedProductType.php:164
|
||||
#: src/Product/LicensedProductType.php:212
|
||||
#: src/Product/LicensedProductType.php:553
|
||||
#: src/Frontend/AccountController.php:286
|
||||
msgid "Lifetime"
|
||||
msgstr "Lebenslang"
|
||||
@@ -492,6 +492,7 @@ msgstr "Lizenz erfolgreich verlängert."
|
||||
msgid "License set to lifetime successfully."
|
||||
msgstr "Lizenz erfolgreich auf lebenslang gesetzt."
|
||||
|
||||
#. translators: %d: number of licenses
|
||||
#: src/Admin/AdminController.php:1106
|
||||
#, php-format
|
||||
msgid "%d license activated."
|
||||
@@ -499,6 +500,7 @@ msgid_plural "%d licenses activated."
|
||||
msgstr[0] "%d Lizenz aktiviert."
|
||||
msgstr[1] "%d Lizenzen aktiviert."
|
||||
|
||||
#. translators: %d: number of licenses
|
||||
#: src/Admin/AdminController.php:1114
|
||||
#, php-format
|
||||
msgid "%d license deactivated."
|
||||
@@ -506,6 +508,7 @@ msgid_plural "%d licenses deactivated."
|
||||
msgstr[0] "%d Lizenz deaktiviert."
|
||||
msgstr[1] "%d Lizenzen deaktiviert."
|
||||
|
||||
#. translators: %d: number of licenses
|
||||
#: src/Admin/AdminController.php:1122
|
||||
#, php-format
|
||||
msgid "%d license revoked."
|
||||
@@ -513,6 +516,7 @@ msgid_plural "%d licenses revoked."
|
||||
msgstr[0] "%d Lizenz widerrufen."
|
||||
msgstr[1] "%d Lizenzen widerrufen."
|
||||
|
||||
#. translators: %d: number of licenses
|
||||
#: src/Admin/AdminController.php:1130
|
||||
#, php-format
|
||||
msgid "%d license deleted."
|
||||
@@ -520,6 +524,7 @@ msgid_plural "%d licenses deleted."
|
||||
msgstr[0] "%d Lizenz gelöscht."
|
||||
msgstr[1] "%d Lizenzen gelöscht."
|
||||
|
||||
#. translators: %d: number of licenses
|
||||
#: src/Admin/AdminController.php:1138
|
||||
#, php-format
|
||||
msgid "%d license extended."
|
||||
@@ -541,6 +546,7 @@ msgstr ""
|
||||
msgid "No licenses to export."
|
||||
msgstr "Keine Lizenzen zum Exportieren."
|
||||
|
||||
#. translators: %d: number of licenses imported
|
||||
#: src/Admin/AdminController.php:1159
|
||||
#, php-format
|
||||
msgid "%d license imported."
|
||||
@@ -548,6 +554,7 @@ msgid_plural "%d licenses imported."
|
||||
msgstr[0] "%d Lizenz importiert."
|
||||
msgstr[1] "%d Lizenzen importiert."
|
||||
|
||||
#. translators: %d: number of licenses updated
|
||||
#: src/Admin/AdminController.php:1166
|
||||
#, php-format
|
||||
msgid "%d updated."
|
||||
@@ -555,6 +562,7 @@ msgid_plural "%d updated."
|
||||
msgstr[0] "%d aktualisiert."
|
||||
msgstr[1] "%d aktualisiert."
|
||||
|
||||
#. translators: %d: number of licenses skipped
|
||||
#: src/Admin/AdminController.php:1174
|
||||
#, php-format
|
||||
msgid "%d skipped."
|
||||
@@ -562,6 +570,7 @@ msgid_plural "%d skipped."
|
||||
msgstr[0] "%d übersprungen."
|
||||
msgstr[1] "%d übersprungen."
|
||||
|
||||
#. translators: %d: number of errors
|
||||
#: src/Admin/AdminController.php:1182
|
||||
#, php-format
|
||||
msgid "%d error."
|
||||
@@ -1020,6 +1029,7 @@ msgstr "Domain bearbeiten"
|
||||
msgid "View in Licenses"
|
||||
msgstr "In Lizenzen anzeigen"
|
||||
|
||||
#. translators: %s: Link to licenses page
|
||||
#: src/Admin/OrderLicenseController.php:280
|
||||
#, php-format
|
||||
msgid "For more actions (revoke, extend, delete), go to the %s page."
|
||||
@@ -1166,8 +1176,8 @@ msgstr ""
|
||||
"Diese Einstellungen dienen als Standard für neue lizensierte Produkte. "
|
||||
"Individuelle Produkteinstellungen überschreiben diese Standards."
|
||||
|
||||
#: src/Admin/SettingsController.php:176 src/Product/LicensedProductType.php:154
|
||||
#: src/Product/LicensedProductType.php:420
|
||||
#: src/Admin/SettingsController.php:176 src/Product/LicensedProductType.php:182
|
||||
#: src/Product/LicensedProductType.php:570
|
||||
msgid "Max Activations"
|
||||
msgstr "Max. Aktivierungen"
|
||||
|
||||
@@ -1175,7 +1185,7 @@ msgstr "Max. Aktivierungen"
|
||||
msgid "Default maximum number of domain activations per license."
|
||||
msgstr "Standard maximale Anzahl der Domain-Aktivierungen pro Lizenz."
|
||||
|
||||
#: src/Admin/SettingsController.php:187 src/Product/LicensedProductType.php:172
|
||||
#: src/Admin/SettingsController.php:187 src/Product/LicensedProductType.php:200
|
||||
msgid "License Validity (Days)"
|
||||
msgstr "Lizenz-Gültigkeit (Tage)"
|
||||
|
||||
@@ -1187,7 +1197,7 @@ msgstr ""
|
||||
"Standard Anzahl Tage, die eine Lizenz gültig ist. Leer lassen oder auf 0 "
|
||||
"setzen für lebenslange Lizenzen."
|
||||
|
||||
#: src/Admin/SettingsController.php:199 src/Product/LicensedProductType.php:190
|
||||
#: src/Admin/SettingsController.php:199 src/Product/LicensedProductType.php:218
|
||||
msgid "Bind to Major Version"
|
||||
msgstr "An Hauptversion binden"
|
||||
|
||||
@@ -1215,6 +1225,7 @@ msgstr ""
|
||||
msgid "Expiration Warning Schedule"
|
||||
msgstr "Ablaufwarnung Zeitplan"
|
||||
|
||||
#. translators: %s: URL to WooCommerce email settings
|
||||
#: src/Admin/SettingsController.php:230
|
||||
#, php-format
|
||||
msgid ""
|
||||
@@ -1346,6 +1357,7 @@ msgstr "Lizenz-Domains"
|
||||
msgid "Each license requires a unique domain."
|
||||
msgstr "Jede Lizenz erfordert eine eindeutige Domain."
|
||||
|
||||
#. translators: %d: license number
|
||||
#: src/Checkout/CheckoutBlocksIntegration.php:129
|
||||
#: src/Checkout/CheckoutController.php:224
|
||||
#, php-format
|
||||
@@ -1357,6 +1369,16 @@ msgstr "Lizenz %d:"
|
||||
msgid "required"
|
||||
msgstr "erforderlich"
|
||||
|
||||
#: src/Checkout/CheckoutController.php:215
|
||||
#, php-format
|
||||
msgid "licensed_domains[%s][%d]"
|
||||
msgstr "licensed_domains[%s][%d]"
|
||||
|
||||
#: src/Checkout/CheckoutController.php:216
|
||||
#, php-format
|
||||
msgid "licensed_domain_%s_%d"
|
||||
msgstr "licensed_domain_%s_%d"
|
||||
|
||||
#: src/Checkout/CheckoutController.php:323
|
||||
msgid "Please enter a domain for your license."
|
||||
msgstr "Bitte geben Sie eine Domain für Ihre Lizenz ein."
|
||||
@@ -1365,16 +1387,19 @@ msgstr "Bitte geben Sie eine Domain für Ihre Lizenz ein."
|
||||
msgid "Please enter a valid domain for your license."
|
||||
msgstr "Bitte geben Sie eine gültige Domain für Ihre Lizenz ein."
|
||||
|
||||
#. translators: 1: product name, 2: license number
|
||||
#: src/Checkout/CheckoutController.php:356
|
||||
#, php-format
|
||||
msgid "Please enter a domain for %1$s (License %2$d)."
|
||||
msgstr "Bitte geben Sie eine Domain für %1$s (Lizenz %2$d) ein."
|
||||
|
||||
#. translators: 1: product name, 2: license number
|
||||
#: src/Checkout/CheckoutController.php:371
|
||||
#, php-format
|
||||
msgid "Please enter a valid domain for %1$s (License %2$d)."
|
||||
msgstr "Bitte geben Sie eine gültige Domain für %1$s (Lizenz %2$d) ein."
|
||||
|
||||
#. translators: 1: domain name, 2: product name
|
||||
#: src/Checkout/CheckoutController.php:385
|
||||
#, php-format
|
||||
msgid ""
|
||||
@@ -1438,68 +1463,74 @@ msgstr "Diese Lizenz ist für diese Domain nicht gültig."
|
||||
msgid "Attachment file not found."
|
||||
msgstr "Anhangs-Datei nicht gefunden."
|
||||
|
||||
#. translators: 1: provided hash, 2: calculated hash
|
||||
#: src/Product/VersionManager.php:177
|
||||
#, php-format
|
||||
msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
|
||||
msgstr "Datei-Prüfsumme stimmt nicht überein. Erwartet: %1$s, Erhalten: %2$s"
|
||||
|
||||
#: src/Product/LicensedProductVariation.php:143
|
||||
#: src/Product/LicensedProductVariation.php:198
|
||||
msgid "Monthly"
|
||||
msgstr "Monatlich"
|
||||
|
||||
#: src/Product/LicensedProductVariation.php:147
|
||||
#: src/Product/LicensedProductVariation.php:202
|
||||
msgid "Quarterly"
|
||||
msgstr "Vierteljährlich"
|
||||
|
||||
#: src/Product/LicensedProductVariation.php:151
|
||||
#: src/Product/LicensedProductVariation.php:206
|
||||
msgid "Yearly"
|
||||
msgstr "Jährlich"
|
||||
|
||||
#: src/Product/LicensedProductVariation.php:156
|
||||
#. translators: %d: number of days
|
||||
#: src/Product/LicensedProductVariation.php:211
|
||||
#, php-format
|
||||
msgid "%d day"
|
||||
msgid_plural "%d days"
|
||||
msgstr[0] "%d Tag"
|
||||
msgstr[1] "%d Tage"
|
||||
|
||||
#: src/Product/LicensedProductType.php:72
|
||||
#: src/Product/LicensedProductType.php:82
|
||||
msgid "Licensed Product"
|
||||
msgstr "Lizensiertes Produkt"
|
||||
|
||||
#: src/Product/LicensedProductType.php:73
|
||||
#: src/Product/LicensedProductType.php:83
|
||||
msgid "Licensed Variable Product"
|
||||
msgstr "Lizensiertes variables Produkt"
|
||||
|
||||
#: src/Product/LicensedProductType.php:108
|
||||
#: src/Product/LicensedProductType.php:136
|
||||
msgid "License Settings"
|
||||
msgstr "Lizenz-Einstellungen"
|
||||
|
||||
#: src/Product/LicensedProductType.php:135
|
||||
#: src/Product/LicensedProductType.php:402
|
||||
#: src/Product/LicensedProductType.php:163
|
||||
#: src/Product/LicensedProductType.php:552
|
||||
#, php-format
|
||||
msgid "%d days"
|
||||
msgstr "%d Tage"
|
||||
|
||||
#: src/Product/LicensedProductType.php:145
|
||||
#. translators: %s: URL to settings page
|
||||
#: src/Product/LicensedProductType.php:173
|
||||
#, php-format
|
||||
msgid "Leave fields empty to use default settings from %s."
|
||||
msgstr "Felder leer lassen, um Standardeinstellungen von %s zu verwenden."
|
||||
|
||||
#: src/Product/LicensedProductType.php:147
|
||||
#: src/Product/LicensedProductType.php:175
|
||||
msgid "WooCommerce > Settings > Licensed Products"
|
||||
msgstr "WooCommerce > Einstellungen > Lizensierte Produkte"
|
||||
|
||||
#: src/Product/LicensedProductType.php:157
|
||||
#. translators: %d: default max activations value
|
||||
#: src/Product/LicensedProductType.php:185
|
||||
#, php-format
|
||||
msgid "Maximum number of domain activations per license. Default: %d"
|
||||
msgstr "Maximale Anzahl der Domain-Aktivierungen pro Lizenz. Standard: %d"
|
||||
|
||||
#: src/Product/LicensedProductType.php:175
|
||||
#. translators: %s: default validity value
|
||||
#: src/Product/LicensedProductType.php:203
|
||||
#, php-format
|
||||
msgid "Number of days the license is valid. Leave empty for default (%s)."
|
||||
msgstr "Anzahl Tage, die die Lizenz gültig ist. Leer lassen für Standard (%s)."
|
||||
|
||||
#: src/Product/LicensedProductType.php:193
|
||||
#. translators: %s: default bind to version value (Yes/No)
|
||||
#: src/Product/LicensedProductType.php:221
|
||||
#, php-format
|
||||
msgid ""
|
||||
"If enabled, licenses are bound to the major version at purchase time. "
|
||||
@@ -1508,35 +1539,35 @@ msgstr ""
|
||||
"Falls aktiviert, werden Lizenzen an die Hauptversion zum Kaufzeitpunkt "
|
||||
"gebunden. Standard: %s"
|
||||
|
||||
#: src/Product/LicensedProductType.php:194
|
||||
#: src/Product/LicensedProductType.php:222
|
||||
msgid "Yes"
|
||||
msgstr "Ja"
|
||||
|
||||
#: src/Product/LicensedProductType.php:194
|
||||
#: src/Product/LicensedProductType.php:222
|
||||
msgid "No"
|
||||
msgstr "Nein"
|
||||
|
||||
#: src/Product/LicensedProductType.php:329
|
||||
#: src/Product/LicensedProductType.php:447
|
||||
msgid "Version:"
|
||||
msgstr "Version:"
|
||||
|
||||
#: src/Product/LicensedProductType.php:373
|
||||
#: src/Product/LicensedProductType.php:523
|
||||
msgid "Licensed products are always virtual"
|
||||
msgstr "Lizenzierte Produkte sind immer virtuell"
|
||||
|
||||
#: src/Product/LicensedProductType.php:375
|
||||
#: src/Product/LicensedProductType.php:525
|
||||
msgid "Virtual"
|
||||
msgstr "Virtuell"
|
||||
|
||||
#: src/Product/LicensedProductType.php:408
|
||||
#: src/Product/LicensedProductType.php:558
|
||||
msgid "License Duration (Days)"
|
||||
msgstr "Lizenz-Gültigkeit (Tage)"
|
||||
|
||||
#: src/Product/LicensedProductType.php:417
|
||||
#: src/Product/LicensedProductType.php:567
|
||||
msgid "Leave empty for parent default. 0 = Lifetime."
|
||||
msgstr "Leer lassen für übergeordneten Standard. 0 = Lebenslang."
|
||||
|
||||
#: src/Product/LicensedProductType.php:429
|
||||
#: src/Product/LicensedProductType.php:579
|
||||
msgid "Leave empty for parent default."
|
||||
msgstr "Leer lassen für übergeordneten Standard."
|
||||
|
||||
@@ -1599,6 +1630,7 @@ msgstr "Bitte melden Sie sich an, um Ihre Lizenzen zu sehen."
|
||||
msgid "You have no licenses yet."
|
||||
msgstr "Sie haben noch keine Lizenzen."
|
||||
|
||||
#. translators: %s: order number
|
||||
#: src/Frontend/AccountController.php:245
|
||||
#, php-format
|
||||
msgid "Order #%s"
|
||||
@@ -1756,6 +1788,7 @@ msgstr ""
|
||||
"Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz vor "
|
||||
"dem Ablaufdatum."
|
||||
|
||||
#. translators: %s: list of placeholders
|
||||
#: src/Email/LicenseExpirationEmail.php:301
|
||||
#: src/Email/LicenseExpiredEmail.php:288
|
||||
#, php-format
|
||||
@@ -1894,6 +1927,7 @@ msgstr ""
|
||||
msgid "Configure License"
|
||||
msgstr "Lizenz konfigurieren"
|
||||
|
||||
#. translators: %s: WooCommerce plugin name
|
||||
#: wc-licensed-product.php:61
|
||||
#, php-format
|
||||
msgid "%s requires WooCommerce to be installed and active."
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WC Licensed Product 0.5.8\n"
|
||||
"Project-Id-Version: WC Licensed Product 0.5.12\n"
|
||||
"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n"
|
||||
"POT-Creation-Date: 2026-01-27 13:34+0100\n"
|
||||
"POT-Creation-Date: 2026-01-27 14:41+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -304,10 +304,10 @@ msgstr ""
|
||||
#: src/Admin/DashboardWidgetController.php:136
|
||||
#: src/Admin/OrderLicenseController.php:260
|
||||
#: src/Admin/SettingsController.php:192
|
||||
#: src/Product/LicensedProductVariation.php:139
|
||||
#: src/Product/LicensedProductType.php:136
|
||||
#: src/Product/LicensedProductType.php:184
|
||||
#: src/Product/LicensedProductType.php:403
|
||||
#: src/Product/LicensedProductVariation.php:194
|
||||
#: src/Product/LicensedProductType.php:164
|
||||
#: src/Product/LicensedProductType.php:212
|
||||
#: src/Product/LicensedProductType.php:553
|
||||
#: src/Frontend/AccountController.php:286
|
||||
msgid "Lifetime"
|
||||
msgstr ""
|
||||
@@ -485,6 +485,7 @@ msgstr ""
|
||||
msgid "License set to lifetime successfully."
|
||||
msgstr ""
|
||||
|
||||
#. translators: %d: number of licenses
|
||||
#: src/Admin/AdminController.php:1106
|
||||
#, php-format
|
||||
msgid "%d license activated."
|
||||
@@ -492,6 +493,7 @@ msgid_plural "%d licenses activated."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#. translators: %d: number of licenses
|
||||
#: src/Admin/AdminController.php:1114
|
||||
#, php-format
|
||||
msgid "%d license deactivated."
|
||||
@@ -499,6 +501,7 @@ msgid_plural "%d licenses deactivated."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#. translators: %d: number of licenses
|
||||
#: src/Admin/AdminController.php:1122
|
||||
#, php-format
|
||||
msgid "%d license revoked."
|
||||
@@ -506,6 +509,7 @@ msgid_plural "%d licenses revoked."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#. translators: %d: number of licenses
|
||||
#: src/Admin/AdminController.php:1130
|
||||
#, php-format
|
||||
msgid "%d license deleted."
|
||||
@@ -513,6 +517,7 @@ msgid_plural "%d licenses deleted."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#. translators: %d: number of licenses
|
||||
#: src/Admin/AdminController.php:1138
|
||||
#, php-format
|
||||
msgid "%d license extended."
|
||||
@@ -532,6 +537,7 @@ msgstr ""
|
||||
msgid "No licenses to export."
|
||||
msgstr ""
|
||||
|
||||
#. translators: %d: number of licenses imported
|
||||
#: src/Admin/AdminController.php:1159
|
||||
#, php-format
|
||||
msgid "%d license imported."
|
||||
@@ -539,6 +545,7 @@ msgid_plural "%d licenses imported."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#. translators: %d: number of licenses updated
|
||||
#: src/Admin/AdminController.php:1166
|
||||
#, php-format
|
||||
msgid "%d updated."
|
||||
@@ -546,6 +553,7 @@ msgid_plural "%d updated."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#. translators: %d: number of licenses skipped
|
||||
#: src/Admin/AdminController.php:1174
|
||||
#, php-format
|
||||
msgid "%d skipped."
|
||||
@@ -553,6 +561,7 @@ msgid_plural "%d skipped."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#. translators: %d: number of errors
|
||||
#: src/Admin/AdminController.php:1182
|
||||
#, php-format
|
||||
msgid "%d error."
|
||||
@@ -997,6 +1006,7 @@ msgstr ""
|
||||
msgid "View in Licenses"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s: Link to licenses page
|
||||
#: src/Admin/OrderLicenseController.php:280
|
||||
#, php-format
|
||||
msgid "For more actions (revoke, extend, delete), go to the %s page."
|
||||
@@ -1133,8 +1143,8 @@ msgid ""
|
||||
"product settings override these defaults."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/SettingsController.php:176 src/Product/LicensedProductType.php:154
|
||||
#: src/Product/LicensedProductType.php:420
|
||||
#: src/Admin/SettingsController.php:176 src/Product/LicensedProductType.php:182
|
||||
#: src/Product/LicensedProductType.php:570
|
||||
msgid "Max Activations"
|
||||
msgstr ""
|
||||
|
||||
@@ -1142,7 +1152,7 @@ msgstr ""
|
||||
msgid "Default maximum number of domain activations per license."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/SettingsController.php:187 src/Product/LicensedProductType.php:172
|
||||
#: src/Admin/SettingsController.php:187 src/Product/LicensedProductType.php:200
|
||||
msgid "License Validity (Days)"
|
||||
msgstr ""
|
||||
|
||||
@@ -1152,7 +1162,7 @@ msgid ""
|
||||
"lifetime licenses."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/SettingsController.php:199 src/Product/LicensedProductType.php:190
|
||||
#: src/Admin/SettingsController.php:199 src/Product/LicensedProductType.php:218
|
||||
msgid "Bind to Major Version"
|
||||
msgstr ""
|
||||
|
||||
@@ -1176,6 +1186,7 @@ msgstr ""
|
||||
msgid "Expiration Warning Schedule"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s: URL to WooCommerce email settings
|
||||
#: src/Admin/SettingsController.php:230
|
||||
#, php-format
|
||||
msgid ""
|
||||
@@ -1299,6 +1310,7 @@ msgstr ""
|
||||
msgid "Each license requires a unique domain."
|
||||
msgstr ""
|
||||
|
||||
#. translators: %d: license number
|
||||
#: src/Checkout/CheckoutBlocksIntegration.php:129
|
||||
#: src/Checkout/CheckoutController.php:224
|
||||
#, php-format
|
||||
@@ -1310,6 +1322,16 @@ msgstr ""
|
||||
msgid "required"
|
||||
msgstr ""
|
||||
|
||||
#: src/Checkout/CheckoutController.php:215
|
||||
#, php-format
|
||||
msgid "licensed_domains[%s][%d]"
|
||||
msgstr ""
|
||||
|
||||
#: src/Checkout/CheckoutController.php:216
|
||||
#, php-format
|
||||
msgid "licensed_domain_%s_%d"
|
||||
msgstr ""
|
||||
|
||||
#: src/Checkout/CheckoutController.php:323
|
||||
msgid "Please enter a domain for your license."
|
||||
msgstr ""
|
||||
@@ -1318,16 +1340,19 @@ msgstr ""
|
||||
msgid "Please enter a valid domain for your license."
|
||||
msgstr ""
|
||||
|
||||
#. translators: 1: product name, 2: license number
|
||||
#: src/Checkout/CheckoutController.php:356
|
||||
#, php-format
|
||||
msgid "Please enter a domain for %1$s (License %2$d)."
|
||||
msgstr ""
|
||||
|
||||
#. translators: 1: product name, 2: license number
|
||||
#: src/Checkout/CheckoutController.php:371
|
||||
#, php-format
|
||||
msgid "Please enter a valid domain for %1$s (License %2$d)."
|
||||
msgstr ""
|
||||
|
||||
#. translators: 1: domain name, 2: product name
|
||||
#: src/Checkout/CheckoutController.php:385
|
||||
#, php-format
|
||||
msgid ""
|
||||
@@ -1389,103 +1414,109 @@ msgstr ""
|
||||
msgid "Attachment file not found."
|
||||
msgstr ""
|
||||
|
||||
#. translators: 1: provided hash, 2: calculated hash
|
||||
#: src/Product/VersionManager.php:177
|
||||
#, php-format
|
||||
msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductVariation.php:143
|
||||
#: src/Product/LicensedProductVariation.php:198
|
||||
msgid "Monthly"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductVariation.php:147
|
||||
#: src/Product/LicensedProductVariation.php:202
|
||||
msgid "Quarterly"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductVariation.php:151
|
||||
#: src/Product/LicensedProductVariation.php:206
|
||||
msgid "Yearly"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductVariation.php:156
|
||||
#. translators: %d: number of days
|
||||
#: src/Product/LicensedProductVariation.php:211
|
||||
#, php-format
|
||||
msgid "%d day"
|
||||
msgid_plural "%d days"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:72
|
||||
#: src/Product/LicensedProductType.php:82
|
||||
msgid "Licensed Product"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:73
|
||||
#: src/Product/LicensedProductType.php:83
|
||||
msgid "Licensed Variable Product"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:108
|
||||
#: src/Product/LicensedProductType.php:136
|
||||
msgid "License Settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:135
|
||||
#: src/Product/LicensedProductType.php:402
|
||||
#: src/Product/LicensedProductType.php:163
|
||||
#: src/Product/LicensedProductType.php:552
|
||||
#, php-format
|
||||
msgid "%d days"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:145
|
||||
#. translators: %s: URL to settings page
|
||||
#: src/Product/LicensedProductType.php:173
|
||||
#, php-format
|
||||
msgid "Leave fields empty to use default settings from %s."
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:147
|
||||
#: src/Product/LicensedProductType.php:175
|
||||
msgid "WooCommerce > Settings > Licensed Products"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:157
|
||||
#. translators: %d: default max activations value
|
||||
#: src/Product/LicensedProductType.php:185
|
||||
#, php-format
|
||||
msgid "Maximum number of domain activations per license. Default: %d"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:175
|
||||
#. translators: %s: default validity value
|
||||
#: src/Product/LicensedProductType.php:203
|
||||
#, php-format
|
||||
msgid "Number of days the license is valid. Leave empty for default (%s)."
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:193
|
||||
#. translators: %s: default bind to version value (Yes/No)
|
||||
#: src/Product/LicensedProductType.php:221
|
||||
#, php-format
|
||||
msgid ""
|
||||
"If enabled, licenses are bound to the major version at purchase time. "
|
||||
"Default: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:194
|
||||
#: src/Product/LicensedProductType.php:222
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:194
|
||||
#: src/Product/LicensedProductType.php:222
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:329
|
||||
#: src/Product/LicensedProductType.php:447
|
||||
msgid "Version:"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:373
|
||||
#: src/Product/LicensedProductType.php:523
|
||||
msgid "Licensed products are always virtual"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:375
|
||||
#: src/Product/LicensedProductType.php:525
|
||||
msgid "Virtual"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:408
|
||||
#: src/Product/LicensedProductType.php:558
|
||||
msgid "License Duration (Days)"
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:417
|
||||
#: src/Product/LicensedProductType.php:567
|
||||
msgid "Leave empty for parent default. 0 = Lifetime."
|
||||
msgstr ""
|
||||
|
||||
#: src/Product/LicensedProductType.php:429
|
||||
#: src/Product/LicensedProductType.php:579
|
||||
msgid "Leave empty for parent default."
|
||||
msgstr ""
|
||||
|
||||
@@ -1548,6 +1579,7 @@ msgstr ""
|
||||
msgid "You have no licenses yet."
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s: order number
|
||||
#: src/Frontend/AccountController.php:245
|
||||
#, php-format
|
||||
msgid "Order #%s"
|
||||
@@ -1697,6 +1729,7 @@ msgid ""
|
||||
"expiration date."
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s: list of placeholders
|
||||
#: src/Email/LicenseExpirationEmail.php:301
|
||||
#: src/Email/LicenseExpiredEmail.php:288
|
||||
#, php-format
|
||||
@@ -1827,6 +1860,7 @@ msgstr ""
|
||||
msgid "Configure License"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s: WooCommerce plugin name
|
||||
#: wc-licensed-product.php:61
|
||||
#, php-format
|
||||
msgid "%s requires WooCommerce to be installed and active."
|
||||
|
||||
1
releases/wc-licensed-product-0.5.12.sha256
Normal file
1
releases/wc-licensed-product-0.5.12.sha256
Normal file
@@ -0,0 +1 @@
|
||||
20bb5cd453de9bca781864430ebd152c82f660b6f9fc3f09107ba03489a71d75 /home/magdev/workspaces/php/wordpress/wp-content/plugins/wc-licensed-product/releases/wc-licensed-product-0.5.12.zip
|
||||
BIN
releases/wc-licensed-product-0.5.12.zip
Normal file
BIN
releases/wc-licensed-product-0.5.12.zip
Normal file
Binary file not shown.
@@ -55,6 +55,14 @@ class LicensedProduct extends WC_Product
|
||||
return $this->exists() && $this->get_price() !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Licensed products are always in stock (virtual, no inventory)
|
||||
*/
|
||||
public function is_in_stock(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get max activations for this product
|
||||
* Falls back to default settings if not set on product
|
||||
|
||||
@@ -46,9 +46,19 @@ final class LicensedProductType
|
||||
add_action('woocommerce_licensed_add_to_cart', [$this, 'addToCartTemplate']);
|
||||
add_action('woocommerce_licensed-variable_add_to_cart', [$this, 'variableAddToCartTemplate']);
|
||||
|
||||
// Use variable product add-to-cart handler for licensed-variable products
|
||||
add_filter('woocommerce_add_to_cart_handler', [$this, 'addToCartHandler'], 10, 2);
|
||||
|
||||
// Make product virtual by default
|
||||
add_filter('woocommerce_product_is_virtual', [$this, 'isVirtual'], 10, 2);
|
||||
|
||||
// Hide stock HTML for licensed products
|
||||
add_filter('woocommerce_get_stock_html', [$this, 'hideStockHtml'], 10, 2);
|
||||
add_filter('woocommerce_get_availability', [$this, 'hideAvailability'], 10, 2);
|
||||
add_filter('woocommerce_get_availability_text', [$this, 'hideAvailabilityText'], 10, 2);
|
||||
add_filter('woocommerce_product_get_stock_quantity', [$this, 'hideStockQuantity'], 10, 2);
|
||||
add_filter('woocommerce_product_variation_get_stock_quantity', [$this, 'hideStockQuantity'], 10, 2);
|
||||
|
||||
// Display current version under product title on single product page
|
||||
add_action('woocommerce_single_product_summary', [$this, 'displayCurrentVersion'], 6);
|
||||
|
||||
@@ -80,9 +90,9 @@ final class LicensedProductType
|
||||
* @param string $className Default class name
|
||||
* @param string $productType Product type
|
||||
* @param string $postType Post type (usually 'product' or 'product_variation')
|
||||
* @param int $productId Product ID
|
||||
* @param mixed $productId Product ID (can be int or string)
|
||||
*/
|
||||
public function getProductClass(string $className, string $productType, string $postType = '', int $productId = 0): string
|
||||
public function getProductClass(string $className, string $productType, string $postType = '', $productId = 0): string
|
||||
{
|
||||
if ($productType === 'licensed') {
|
||||
return LicensedProduct::class;
|
||||
@@ -91,17 +101,19 @@ final class LicensedProductType
|
||||
return LicensedVariableProduct::class;
|
||||
}
|
||||
// Handle variations of licensed-variable products
|
||||
if ($productType === 'variation') {
|
||||
// Check both by product type and by post type for variations
|
||||
if ($productType === 'variation' || $postType === 'product_variation') {
|
||||
// Get parent ID from the product post
|
||||
$parentId = 0;
|
||||
if ($productId > 0) {
|
||||
$parentId = wp_get_post_parent_id($productId);
|
||||
$productIdInt = (int) $productId;
|
||||
if ($productIdInt > 0) {
|
||||
$parentId = wp_get_post_parent_id($productIdInt);
|
||||
}
|
||||
// Fallback to global $post if product ID not available
|
||||
if (!$parentId) {
|
||||
global $post;
|
||||
if ($post && $post->post_parent) {
|
||||
$parentId = $post->post_parent;
|
||||
$parentId = (int) $post->post_parent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,26 +293,111 @@ final class LicensedProductType
|
||||
wc_get_template('single-product/add-to-cart/simple.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the variable product add-to-cart handler for licensed-variable products
|
||||
* WooCommerce uses product type to determine which handler to use
|
||||
*/
|
||||
public function addToCartHandler(string $handler, \WC_Product $product): string
|
||||
{
|
||||
if ($product->is_type('licensed-variable')) {
|
||||
return 'variable';
|
||||
}
|
||||
return $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide stock HTML for licensed products (they're always virtual/in-stock)
|
||||
*/
|
||||
public function hideStockHtml(string $html, \WC_Product $product): string
|
||||
{
|
||||
if ($this->isLicensedProductOrVariation($product)) {
|
||||
return '';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide availability data for licensed products (they're always virtual/in-stock)
|
||||
*/
|
||||
public function hideAvailability(array $availability, \WC_Product $product): array
|
||||
{
|
||||
if ($this->isLicensedProductOrVariation($product)) {
|
||||
return [
|
||||
'availability' => '',
|
||||
'class' => '',
|
||||
];
|
||||
}
|
||||
return $availability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide availability text for licensed products
|
||||
*/
|
||||
public function hideAvailabilityText(string $availability, \WC_Product $product): string
|
||||
{
|
||||
if ($this->isLicensedProductOrVariation($product)) {
|
||||
return '';
|
||||
}
|
||||
return $availability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide stock quantity for licensed products (return null = no stock display)
|
||||
*
|
||||
* @param int|null $quantity
|
||||
* @param \WC_Product $product
|
||||
* @return int|null
|
||||
*/
|
||||
public function hideStockQuantity($quantity, \WC_Product $product)
|
||||
{
|
||||
if ($this->isLicensedProductOrVariation($product)) {
|
||||
return null;
|
||||
}
|
||||
return $quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if product is a licensed product or variation of one
|
||||
*/
|
||||
private function isLicensedProductOrVariation(\WC_Product $product): bool
|
||||
{
|
||||
// Direct licensed products
|
||||
if ($product->is_type('licensed') || $product->is_type('licensed-variable')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check by class name for our custom variation class
|
||||
if ($product instanceof LicensedProductVariation) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if this is a variation with a licensed-variable parent
|
||||
// Use WC_Product_Factory::get_product_type() to get parent type directly from DB
|
||||
// This is more reliable than loading the full product object
|
||||
$parentId = $product->get_parent_id();
|
||||
if ($parentId) {
|
||||
$parentType = \WC_Product_Factory::get_product_type($parentId);
|
||||
if ($parentType === 'licensed-variable') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make licensed products virtual by default
|
||||
*/
|
||||
public function isVirtual(bool $isVirtual, \WC_Product $product): bool
|
||||
{
|
||||
if ($product->is_type('licensed') || $product->is_type('licensed-variable')) {
|
||||
if ($this->isLicensedProductOrVariation($product)) {
|
||||
return true;
|
||||
}
|
||||
// Also handle variations of licensed-variable products
|
||||
if ($product->is_type('variation') && $product->get_parent_id()) {
|
||||
$parent = wc_get_product($product->get_parent_id());
|
||||
if ($parent && $parent->is_type('licensed-variable')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return $isVirtual;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue frontend styles for licensed products on single product pages
|
||||
* Enqueue frontend styles and scripts for licensed products on single product pages
|
||||
*/
|
||||
public function enqueueFrontendStyles(): void
|
||||
{
|
||||
@@ -320,6 +417,11 @@ final class LicensedProductType
|
||||
[],
|
||||
WC_LICENSED_PRODUCT_VERSION
|
||||
);
|
||||
|
||||
// For licensed-variable products, enqueue WooCommerce variation scripts
|
||||
if ($product->is_type('licensed-variable')) {
|
||||
wp_enqueue_script('wc-add-to-cart-variation');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -372,8 +474,13 @@ final class LicensedProductType
|
||||
return;
|
||||
}
|
||||
|
||||
// Update global $product to use the correctly loaded instance
|
||||
// This ensures the template has the right product type
|
||||
$product = $variableProduct;
|
||||
|
||||
// Get variations count to determine if we should load them via AJAX
|
||||
$getVariations = count($variableProduct->get_children()) <= apply_filters('woocommerce_ajax_variation_threshold', 30, $variableProduct);
|
||||
$children = $variableProduct->get_children();
|
||||
$getVariations = count($children) <= apply_filters('woocommerce_ajax_variation_threshold', 30, $variableProduct);
|
||||
|
||||
// Get template variables - WooCommerce expects these to be set
|
||||
$availableVariations = $getVariations ? $variableProduct->get_available_variations() : false;
|
||||
|
||||
@@ -35,6 +35,61 @@ class LicensedProductVariation extends WC_Product_Variation
|
||||
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
|
||||
|
||||
@@ -41,6 +41,19 @@ class LicensedVariableProduct extends WC_Product_Variable
|
||||
return 'licensed-variable';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if product is of a certain type
|
||||
* Override to return true for 'variable' as well, so WooCommerce internal
|
||||
* checks pass (many methods in WC_Product_Variable check is_type('variable'))
|
||||
*/
|
||||
public function is_type($type): bool
|
||||
{
|
||||
if (is_array($type)) {
|
||||
return in_array($this->get_type(), $type, true) || in_array('variable', $type, true);
|
||||
}
|
||||
return $this->get_type() === $type || 'variable' === $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Licensed products are always virtual
|
||||
*/
|
||||
@@ -60,6 +73,189 @@ class LicensedVariableProduct extends WC_Product_Variable
|
||||
return parent::is_purchasable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Licensed products are always in stock (virtual, no inventory)
|
||||
*/
|
||||
public function is_in_stock(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children (variations) for this product
|
||||
* Override because WC_Product_Variable::get_children() checks is_type('variable')
|
||||
* which fails for our 'licensed-variable' type
|
||||
*/
|
||||
public function get_children($context = 'view'): array
|
||||
{
|
||||
if (!$this->get_id()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Query variations directly from database since WooCommerce's data store
|
||||
// doesn't work properly with custom variable product types
|
||||
global $wpdb;
|
||||
$children = $wpdb->get_col($wpdb->prepare(
|
||||
"SELECT ID FROM {$wpdb->posts}
|
||||
WHERE post_parent = %d
|
||||
AND post_type = 'product_variation'
|
||||
AND post_status IN ('publish', 'private')
|
||||
ORDER BY menu_order ASC, ID ASC",
|
||||
$this->get_id()
|
||||
));
|
||||
|
||||
$children = array_map('intval', $children);
|
||||
|
||||
if ('view' === $context) {
|
||||
$children = apply_filters('woocommerce_get_children', $children, $this, false);
|
||||
}
|
||||
|
||||
return is_array($children) ? $children : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get variation attributes for this product
|
||||
* Override because WC_Product_Variable uses data_store which doesn't work
|
||||
* properly with custom variable product types
|
||||
*/
|
||||
public function get_variation_attributes(): array
|
||||
{
|
||||
$attributes = $this->get_attributes();
|
||||
|
||||
if (!$attributes || !is_array($attributes)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$variation_attributes = [];
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
// For WC_Product_Attribute objects
|
||||
if ($attribute instanceof \WC_Product_Attribute) {
|
||||
if ($attribute->get_variation()) {
|
||||
$attribute_name = $attribute->get_name();
|
||||
|
||||
// For taxonomy attributes, get term slugs
|
||||
if ($attribute->is_taxonomy()) {
|
||||
$attribute_terms = wc_get_product_terms(
|
||||
$this->get_id(),
|
||||
$attribute_name,
|
||||
['fields' => 'slugs']
|
||||
);
|
||||
$variation_attributes[$attribute_name] = $attribute_terms;
|
||||
} else {
|
||||
// For custom attributes, get options directly
|
||||
$variation_attributes[$attribute_name] = $attribute->get_options();
|
||||
}
|
||||
}
|
||||
}
|
||||
// For array-based attributes (older format)
|
||||
elseif (is_array($attribute) && !empty($attribute['is_variation'])) {
|
||||
$attribute_name = $attribute['name'];
|
||||
$values = isset($attribute['value']) ? explode('|', $attribute['value']) : [];
|
||||
$variation_attributes[$attribute_name] = array_map('trim', $values);
|
||||
}
|
||||
}
|
||||
|
||||
return $variation_attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get variation prices (regular, sale, and final prices)
|
||||
* Override because WC_Product_Variable uses data_store which doesn't work
|
||||
* properly with custom variable product types
|
||||
*/
|
||||
public function get_variation_prices($for_display = false): array
|
||||
{
|
||||
$children = $this->get_children();
|
||||
|
||||
if (empty($children)) {
|
||||
return [
|
||||
'price' => [],
|
||||
'regular_price' => [],
|
||||
'sale_price' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$prices = [
|
||||
'price' => [],
|
||||
'regular_price' => [],
|
||||
'sale_price' => [],
|
||||
];
|
||||
|
||||
foreach ($children as $child_id) {
|
||||
$variation = wc_get_product($child_id);
|
||||
if ($variation) {
|
||||
$price = $variation->get_price();
|
||||
$regular_price = $variation->get_regular_price();
|
||||
$sale_price = $variation->get_sale_price();
|
||||
|
||||
if ('' !== $price) {
|
||||
$prices['price'][$child_id] = $price;
|
||||
}
|
||||
if ('' !== $regular_price) {
|
||||
$prices['regular_price'][$child_id] = $regular_price;
|
||||
}
|
||||
if ('' !== $sale_price) {
|
||||
$prices['sale_price'][$child_id] = $sale_price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort prices
|
||||
asort($prices['price']);
|
||||
asort($prices['regular_price']);
|
||||
asort($prices['sale_price']);
|
||||
|
||||
$this->prices_array = $prices;
|
||||
|
||||
return $this->prices_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available variations for this product
|
||||
* Override because WC_Product_Variable uses data_store which doesn't work
|
||||
* properly with custom variable product types
|
||||
*/
|
||||
public function get_available_variations($return = 'array')
|
||||
{
|
||||
$children = $this->get_children();
|
||||
$available_variations = [];
|
||||
|
||||
foreach ($children as $child_id) {
|
||||
$variation = wc_get_product($child_id);
|
||||
|
||||
if (!$variation) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if variation should be available
|
||||
if (!$variation->exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if purchasable (has price)
|
||||
if (!$variation->is_purchasable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Build variation data
|
||||
if ($return === 'array') {
|
||||
$variationData = $this->get_available_variation($variation);
|
||||
// Override availability_html to be empty for licensed products
|
||||
$variationData['availability_html'] = '';
|
||||
$available_variations[] = $variationData;
|
||||
} else {
|
||||
$available_variations[] = $variation;
|
||||
}
|
||||
}
|
||||
|
||||
if ($return === 'array') {
|
||||
$available_variations = array_values(array_filter($available_variations));
|
||||
}
|
||||
|
||||
return $available_variations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get max activations for this product (parent default)
|
||||
* Falls back to default settings if not set on product
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Plugin Name: WooCommerce Licensed Product
|
||||
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-licensed-product
|
||||
* Description: WooCommerce plugin to sell software products using license keys with domain-based validation.
|
||||
* Version: 0.5.11
|
||||
* Version: 0.5.12
|
||||
* Author: Marco Graetsch
|
||||
* Author URI: https://src.bundespruefstelle.ch/magdev
|
||||
* License: GPL-2.0-or-later
|
||||
@@ -28,7 +28,7 @@ if (!defined('ABSPATH')) {
|
||||
}
|
||||
|
||||
// Plugin constants
|
||||
define('WC_LICENSED_PRODUCT_VERSION', '0.5.11');
|
||||
define('WC_LICENSED_PRODUCT_VERSION', '0.5.12');
|
||||
define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__);
|
||||
define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||
|
||||
Reference in New Issue
Block a user