9 Commits

Author SHA1 Message Date
4a90e6b18b Bump version to 0.3.9
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 16:08:41 +01:00
502a8c7cd7 Update translation template with current line references
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 16:07:46 +01:00
6b83fce8b2 Fix admin order license generation bug
- Add 'Generate Licenses' button to order meta box for admin-created orders
- Add AJAX handler for manual license generation
- Show warning when domain is not set or order is not paid
- Handle partial license generation (when some products already have licenses)
- Update German translations for new strings (365 translated)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 16:06:13 +01:00
8c33eaff29 Clean up known bugs section after v0.3.8 fix
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:38:19 +01:00
98002ae3d7 Update CLAUDE.md with v0.3.8 session history
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:37:14 +01:00
a93381dce6 Bump version to 0.3.8
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:34:38 +01:00
a522455a0a Fix duplicate translation string causing sprintf error
Removed duplicated German translation text that had two %s placeholders
causing ArgumentCountError in settings page. Updated composer.lock with
latest client library (64d215c).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:34:06 +01:00
2de6abe133 Update CLAUDE.md with v0.3.7 session history
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 10:21:49 +01:00
8d60758f23 Add release package v0.3.7
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 10:19:53 +01:00
11 changed files with 701 additions and 407 deletions

View File

@@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.3.9] - 2026-01-24
### Added
- "Generate Licenses" button in order meta box for admin-created orders
- "Generate Missing Licenses" button when some products in an order are missing licenses
- AJAX handler `ajaxGenerateOrderLicenses()` for manual license generation from admin
- Warning message when order domain is not set before generating licenses
### Fixed
- **Critical:** Licenses are now generated for orders created manually in admin area
- Previously, licenses were only generated via checkout hooks, leaving admin-created orders without licenses
### Technical Details
- Added `wclp_generate_order_licenses` AJAX action to `OrderLicenseController`
- Updated `order-licenses.js` with generate button handler and page reload on success
- Added CSS styles for generate status messages
- Updated translations (365 strings)
## [0.3.8] - 2026-01-24
### Fixed
- Fixed duplicate German translation string causing `ArgumentCountError` in settings page
- The notification settings description had duplicated text with two `%s` placeholders
### Changed
- Updated `magdev/wc-licensed-product-client` to latest version (64d215c)
## [0.3.7] - 2026-01-24 ## [0.3.7] - 2026-01-24
### Added ### Added

102
CLAUDE.md
View File

@@ -36,14 +36,9 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
No known bugs at the moment. No known bugs at the moment.
### Version 0.3.7 ### Version 0.3.9
- Fixed: Dashboard widget "View All Licenses" link used wrong page slug No changes at the moment.
- Fixed: Download links in customer account resulted in 404 errors (missing query var registration)
- Removed: Redundant "Status Breakdown" section from dashboard widget (info already in stat cards)
- Changed: License Types section now uses card style matching the stats row above
- Added: Download counter for licensed product versions (tracked per version)
- Added: Download Statistics admin dashboard widget showing total downloads, top products, and top versions
### Version 0.4.0 ### Version 0.4.0
@@ -1037,3 +1032,96 @@ define('WC_LICENSE_TRUSTED_PROXIES', '10.0.0.1,192.168.1.0/24');
- Created release package: `releases/wc-licensed-product-0.3.6.zip` (818 KB) - Created release package: `releases/wc-licensed-product-0.3.6.zip` (818 KB)
- SHA256: `b0063f0312759f090e12faba83de730baf4114139d763e46fad2b781d4b38270` - SHA256: `b0063f0312759f090e12faba83de730baf4114139d763e46fad2b781d4b38270`
- Tagged as `v0.3.6` and pushed to `main` branch - Tagged as `v0.3.6` and pushed to `main` branch
### 2026-01-24 - Version 0.3.7 - Dashboard Improvements & Download Counter
**Overview:**
Fixed dashboard widget bugs, improved UI consistency, and added download tracking functionality with a new statistics widget.
**Bug Fixes:**
- Fixed: Dashboard widget "View All Licenses" link used wrong page slug (`wc-licensed-product-licenses` instead of `wc-licenses`)
- Fixed: Download links in customer account resulted in 404 errors due to missing query var registration
- Added `license-download` endpoint registration during plugin activation in `Installer::activate()`
- Added `addDownloadQueryVar()` method to `DownloadController` for proper WordPress endpoint recognition
**UI Improvements:**
- Removed redundant "Status Breakdown" section from license statistics widget (info already shown in stat cards above)
- Changed License Types section to use card-style layout matching the stats row above
- Cleaned up unused CSS for status badges
**New Features:**
- Download counter for licensed product versions (tracked per version in database)
- New Download Statistics admin dashboard widget showing:
- Total downloads count
- Top 5 products by downloads
- Top 5 versions by downloads
**New files:**
- `src/Admin/DownloadWidgetController.php` - Dashboard widget for download statistics
**New methods in VersionManager:**
- `incrementDownloadCount()` - Atomically increment download count for a version
- `getTotalDownloadCount()` - Get total downloads across all versions
- `getDownloadStatistics()` - Get download stats grouped by product and version
**Modified files:**
- `src/Installer.php` - Added `download_count` column to versions table, added `license-download` endpoint registration
- `src/Product/ProductVersion.php` - Added `downloadCount` property and `getDownloadCount()` method
- `src/Product/VersionManager.php` - Added download counting methods
- `src/Frontend/DownloadController.php` - Added query var registration, increment download count on file serve
- `src/Admin/DashboardWidgetController.php` - Fixed URL, removed Status Breakdown, changed License Types to cards
- `src/Plugin.php` - Added DownloadWidgetController instantiation
**Technical notes:**
- Download count is incremented atomically using SQL `download_count = download_count + 1`
- Statistics queries use SQL aggregation with product name enrichment via `wc_get_product()`
- WordPress endpoints require both `add_rewrite_endpoint()` AND `query_vars` filter registration
- Existing installations need to flush rewrite rules (Settings > Permalinks > Save) or reactivate plugin
**Release v0.3.7:**
- Created release package: `releases/wc-licensed-product-0.3.7.zip` (827 KB)
- SHA256: `e93b2ab06f6d43c2179167090e07eda5db6809df6e391baece4ceba321cf33f6`
- Tagged as `v0.3.7` and pushed to `main` branch
### 2026-01-24 - Version 0.3.8 - Translation Bug Fix
**Overview:**
Fixed a critical translation bug that caused the settings page to crash with an `ArgumentCountError`.
**Bug Fix:**
- Fixed: Duplicate German translation string in `wc-licensed-product-de_CH.po` causing `ArgumentCountError` in settings page
- Root cause: The notification settings description was duplicated in the translation, resulting in two `%s` placeholders when only one argument was passed to `sprintf()`
- Location: [wc-licensed-product-de_CH.po:322-328](languages/wc-licensed-product-de_CH.po#L322-L328)
**Modified files:**
- `languages/wc-licensed-product-de_CH.po` - Removed duplicated translation string
- `languages/wc-licensed-product-de_CH.mo` - Recompiled binary translation
**Technical notes:**
- Error was logged to `tmp/fatal-errors-2026-01-24.log`
- The German `msgstr` contained the same text twice, each with a `%s` placeholder
- `sprintf()` at `SettingsController.php:221` only provided one argument for the single `%s` in the English source
- Translation strings with `%s` placeholders must have exactly matching placeholder counts between source and translation
**Dependency Updates:**
- Updated `magdev/wc-licensed-product-client` from `9f513a8` to `64d215c`
**Release v0.3.8:**
- Created release package: `releases/wc-licensed-product-0.3.8.zip` (829 KB)
- SHA256: `50ad6966c5ab8db2257572084d2d8a820448df62615678e1576696f2c0cb383d`
- Tagged as `v0.3.8` and pushed to `main` branch

View File

@@ -16,6 +16,9 @@
// Order domain save // Order domain save
$('#wclp-save-order-domain').on('click', this.saveOrderDomain.bind(this)); $('#wclp-save-order-domain').on('click', this.saveOrderDomain.bind(this));
// Generate licenses button
$(document).on('click', '#wclp-generate-licenses', this.generateLicenses.bind(this));
// License domain edit/save/cancel // License domain edit/save/cancel
$(document).on('click', '.wclp-edit-domain-btn', this.startEditDomain); $(document).on('click', '.wclp-edit-domain-btn', this.startEditDomain);
$(document).on('click', '.wclp-save-domain-btn', this.saveLicenseDomain.bind(this)); $(document).on('click', '.wclp-save-domain-btn', this.saveLicenseDomain.bind(this));
@@ -135,6 +138,54 @@
$editBtn.show(); $editBtn.show();
}, },
/**
* Generate licenses for order
*/
generateLicenses: function(e) {
e.preventDefault();
var $btn = $(e.currentTarget);
var $spinner = $btn.siblings('.spinner');
var $status = $btn.siblings('.wclp-generate-status');
var orderId = $btn.data('order-id');
$btn.prop('disabled', true);
$spinner.addClass('is-active');
$status.text('').removeClass('success error');
$.ajax({
url: wclpOrderLicenses.ajaxUrl,
type: 'POST',
data: {
action: 'wclp_generate_order_licenses',
nonce: wclpOrderLicenses.nonce,
order_id: orderId
},
success: function(response) {
if (response.success) {
$status.text(response.data.message).addClass('success');
if (response.data.reload) {
// Reload the page after a short delay to show the new licenses
setTimeout(function() {
window.location.reload();
}, 1500);
}
} else {
$status.text(response.data.message || wclpOrderLicenses.strings.error).addClass('error');
$btn.prop('disabled', false);
}
},
error: function() {
$status.text(wclpOrderLicenses.strings.error).addClass('error');
$btn.prop('disabled', false);
},
complete: function() {
$spinner.removeClass('is-active');
}
});
},
/** /**
* Save license domain * Save license domain
*/ */

16
composer.lock generated
View File

@@ -12,7 +12,7 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client.git", "url": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client.git",
"reference": "9f513a819e8218a0e8e16f0be8f7edbf0f30245e" "reference": "64d215cb265a64ff318cfbb954dd128b0076dc1d"
}, },
"require": { "require": {
"php": "^8.3", "php": "^8.3",
@@ -52,7 +52,7 @@
"issues": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client/issues", "issues": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client/issues",
"source": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client" "source": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client"
}, },
"time": "2026-01-23T15:45:59+00:00" "time": "2026-01-24T13:32:11+00:00"
}, },
{ {
"name": "psr/cache", "name": "psr/cache",
@@ -894,16 +894,16 @@
}, },
{ {
"name": "twig/twig", "name": "twig/twig",
"version": "v3.22.2", "version": "v3.23.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/twigphp/Twig.git", "url": "https://github.com/twigphp/Twig.git",
"reference": "946ddeafa3c9f4ce279d1f34051af041db0e16f2" "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/946ddeafa3c9f4ce279d1f34051af041db0e16f2", "url": "https://api.github.com/repos/twigphp/Twig/zipball/a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9",
"reference": "946ddeafa3c9f4ce279d1f34051af041db0e16f2", "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -957,7 +957,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/twigphp/Twig/issues", "issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.22.2" "source": "https://github.com/twigphp/Twig/tree/v3.23.0"
}, },
"funding": [ "funding": [
{ {
@@ -969,7 +969,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-12-14T11:28:47+00:00" "time": "2026-01-23T21:00:41+00:00"
} }
], ],
"packages-dev": [], "packages-dev": [],

View File

@@ -4,8 +4,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: WC Licensed Product 0.3.1\n" "Project-Id-Version: WC Licensed Product 0.3.1\n"
"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-01-24 10:11+0100\n" "POT-Creation-Date: 2026-01-24 16:03+0100\n"
"PO-Revision-Date: 2026-01-22T17:15:00+00:00\n" "PO-Revision-Date: 2026-01-22T17:15:00+00:00\n"
"Last-Translator: Marco Graetsch <magdev3.0@gmail.com>\n" "Last-Translator: Marco Graetsch <magdev3.0@gmail.com>\n"
"Language-Team: German (Switzerland) <de_CH@li.org>\n" "Language-Team: German (Switzerland) <de_CH@li.org>\n"
@@ -15,24 +15,25 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/Admin/OrderLicenseController.php:56 #: src/Admin/OrderLicenseController.php:57
msgid "Product Licenses" msgid "Product Licenses"
msgstr "Produktlizenzen" msgstr "Produktlizenzen"
#: src/Admin/OrderLicenseController.php:77 #: src/Admin/OrderLicenseController.php:78
#: src/Admin/OrderLicenseController.php:313 #: src/Admin/OrderLicenseController.php:367
#: src/Admin/OrderLicenseController.php:469
msgid "Order not found." msgid "Order not found."
msgstr "Bestellung nicht gefunden." msgstr "Bestellung nicht gefunden."
#: src/Admin/OrderLicenseController.php:92 #: src/Admin/OrderLicenseController.php:93
msgid "This order does not contain licensed products." msgid "This order does not contain licensed products."
msgstr "Diese Bestellung enthält keine lizensierten Produkte." msgstr "Diese Bestellung enthält keine lizensierten Produkte."
#: src/Admin/OrderLicenseController.php:106 #: src/Admin/OrderLicenseController.php:107
msgid "Order Domain" msgid "Order Domain"
msgstr "Bestellungs-Domain" msgstr "Bestellungs-Domain"
#: src/Admin/OrderLicenseController.php:108 #: src/Admin/OrderLicenseController.php:109
msgid "" msgid ""
"The domain specified during checkout. Changing this will not automatically " "The domain specified during checkout. Changing this will not automatically "
"update existing license domains." "update existing license domains."
@@ -40,31 +41,31 @@ msgstr ""
"Die bei der Bestellung angegebene Domain. Eine Änderung aktualisiert nicht " "Die bei der Bestellung angegebene Domain. Eine Änderung aktualisiert nicht "
"automatisch bestehende Lizenz-Domains." "automatisch bestehende Lizenz-Domains."
#: src/Admin/OrderLicenseController.php:116 #: src/Admin/OrderLicenseController.php:117
#: src/Checkout/CheckoutController.php:89 #: src/Checkout/CheckoutController.php:89
#: src/Checkout/CheckoutBlocksIntegration.php:102 #: src/Checkout/CheckoutBlocksIntegration.php:102
msgid "example.com" msgid "example.com"
msgstr "beispiel.ch" msgstr "beispiel.ch"
#: src/Admin/OrderLicenseController.php:118 #: src/Admin/OrderLicenseController.php:119
#: src/Admin/OrderLicenseController.php:182 src/Admin/AdminController.php:150 #: src/Admin/OrderLicenseController.php:209 src/Admin/AdminController.php:150
#: src/Admin/AdminController.php:1340 src/Admin/AdminController.php:1360 #: src/Admin/AdminController.php:1340 src/Admin/AdminController.php:1360
#: src/Admin/AdminController.php:1381 #: src/Admin/AdminController.php:1381
msgid "Save" msgid "Save"
msgstr "Speichern" msgstr "Speichern"
#: src/Admin/OrderLicenseController.php:127 #: src/Admin/OrderLicenseController.php:128
#: src/Admin/OrderLicenseController.php:222 src/Admin/AdminController.php:76 #: src/Admin/OrderLicenseController.php:249 src/Admin/AdminController.php:76
#: src/Admin/AdminController.php:77 src/Admin/AdminController.php:90 #: src/Admin/AdminController.php:77 src/Admin/AdminController.php:90
#: src/Admin/AdminController.php:1200 src/Frontend/AccountController.php:90 #: src/Admin/AdminController.php:1200 src/Frontend/AccountController.php:90
msgid "Licenses" msgid "Licenses"
msgstr "Lizenzen" msgstr "Lizenzen"
#: src/Admin/OrderLicenseController.php:131 #: src/Admin/OrderLicenseController.php:144
msgid "No licenses have been generated for this order yet." msgid "No licenses have been generated for this order yet."
msgstr "Für diese Bestellung wurden noch keine Lizenzen generiert." msgstr "Für diese Bestellung wurden noch keine Lizenzen generiert."
#: src/Admin/OrderLicenseController.php:134 #: src/Admin/OrderLicenseController.php:147
msgid "" msgid ""
"Licenses should be generated automatically when an order is paid. If " "Licenses should be generated automatically when an order is paid. If "
"missing, check that a domain was specified during checkout." "missing, check that a domain was specified during checkout."
@@ -73,105 +74,127 @@ msgstr ""
"wird. Falls fehlend, prüfen Sie, ob bei der Bestellung eine Domain angegeben " "wird. Falls fehlend, prüfen Sie, ob bei der Bestellung eine Domain angegeben "
"wurde." "wurde."
#: src/Admin/OrderLicenseController.php:137 #: src/Admin/OrderLicenseController.php:150
msgid "Licenses will be generated when the order is marked as paid/completed." msgid "Licenses will be generated when the order is marked as paid/completed."
msgstr "" msgstr "Lizenzen werden generiert, sobald die Bestellung als bezahlt/abgeschlossen markiert wird."
"Lizenzen werden generiert, sobald die Bestellung als bezahlt/abgeschlossen "
"markiert wird."
#: src/Admin/OrderLicenseController.php:144 #: src/Admin/OrderLicenseController.php:156
msgid "Generate Licenses"
msgstr "Lizenzen generieren"
#: src/Admin/OrderLicenseController.php:164
msgid "Please set the order domain above before generating licenses."
msgstr "Bitte legen Sie zuerst die Bestellungs-Domain oben fest, bevor Sie Lizenzen generieren."
#: src/Admin/OrderLicenseController.php:171
#: src/Admin/SettingsController.php:142 src/Admin/AdminController.php:1291 #: src/Admin/SettingsController.php:142 src/Admin/AdminController.php:1291
#: src/Admin/AdminController.php:1442 src/Admin/AdminController.php:1491 #: src/Admin/AdminController.php:1442 src/Admin/AdminController.php:1491
#: src/Email/LicenseEmailController.php:269 #: src/Email/LicenseEmailController.php:269
msgid "License Key" msgid "License Key"
msgstr "Lizenzschlüssel" msgstr "Lizenzschlüssel"
#: src/Admin/OrderLicenseController.php:145 src/Admin/AdminController.php:1292 #: src/Admin/OrderLicenseController.php:172 src/Admin/AdminController.php:1292
#: src/Admin/AdminController.php:1443 src/Admin/AdminController.php:1608 #: src/Admin/AdminController.php:1443 src/Admin/AdminController.php:1608
#: src/Email/LicenseEmailController.php:268 #: src/Email/LicenseEmailController.php:268
msgid "Product" msgid "Product"
msgstr "Produkt" msgstr "Produkt"
#: src/Admin/OrderLicenseController.php:146 src/Admin/AdminController.php:1294 #: src/Admin/OrderLicenseController.php:173 src/Admin/AdminController.php:1294
#: src/Admin/AdminController.php:1445 src/Admin/AdminController.php:1495 #: src/Admin/AdminController.php:1445 src/Admin/AdminController.php:1495
msgid "Domain" msgid "Domain"
msgstr "Domain" msgstr "Domain"
#: src/Admin/OrderLicenseController.php:147 #: src/Admin/OrderLicenseController.php:174
#: src/Admin/VersionAdminController.php:140 src/Admin/AdminController.php:1295 #: src/Admin/VersionAdminController.php:140 src/Admin/AdminController.php:1295
#: src/Admin/AdminController.php:1446 #: src/Admin/AdminController.php:1446
msgid "Status" msgid "Status"
msgstr "Status" msgstr "Status"
#: src/Admin/OrderLicenseController.php:148 src/Admin/AdminController.php:1297 #: src/Admin/OrderLicenseController.php:175 src/Admin/AdminController.php:1297
#: src/Admin/AdminController.php:1448 src/Admin/AdminController.php:1611 #: src/Admin/AdminController.php:1448 src/Admin/AdminController.php:1611
#: src/Admin/AdminController.php:1613 src/Email/LicenseEmailController.php:270 #: src/Admin/AdminController.php:1613 src/Email/LicenseEmailController.php:270
msgid "Expires" msgid "Expires"
msgstr "Läuft ab" msgstr "Läuft ab"
#: src/Admin/OrderLicenseController.php:149 #: src/Admin/OrderLicenseController.php:176
#: src/Admin/VersionAdminController.php:142 src/Admin/AdminController.php:1298 #: src/Admin/VersionAdminController.php:142 src/Admin/AdminController.php:1298
#: src/Admin/AdminController.php:1449 #: src/Admin/AdminController.php:1449
msgid "Actions" msgid "Actions"
msgstr "Aktionen" msgstr "Aktionen"
#: src/Admin/OrderLicenseController.php:168 src/Admin/AdminController.php:195 #: src/Admin/OrderLicenseController.php:195 src/Admin/AdminController.php:195
#: src/Admin/AdminController.php:1019 #: src/Admin/AdminController.php:1019
msgid "Unknown" msgid "Unknown"
msgstr "Unbekannt" msgstr "Unbekannt"
#: src/Admin/OrderLicenseController.php:178 #: src/Admin/OrderLicenseController.php:205
msgid "Edit domain" msgid "Edit domain"
msgstr "Domain bearbeiten" msgstr "Domain bearbeiten"
#: src/Admin/OrderLicenseController.php:185 src/Admin/AdminController.php:149 #: src/Admin/OrderLicenseController.php:212 src/Admin/AdminController.php:149
#: src/Admin/AdminController.php:1341 src/Admin/AdminController.php:1361 #: src/Admin/AdminController.php:1341 src/Admin/AdminController.php:1361
#: src/Admin/AdminController.php:1382 src/Admin/AdminController.php:1537 #: src/Admin/AdminController.php:1382 src/Admin/AdminController.php:1537
#: src/Frontend/AccountController.php:271 #: src/Frontend/AccountController.php:271
msgid "Cancel" msgid "Cancel"
msgstr "Abbrechen" msgstr "Abbrechen"
#: src/Admin/OrderLicenseController.php:201 #: src/Admin/OrderLicenseController.php:228
#: src/Admin/SettingsController.php:192 #: src/Admin/SettingsController.php:192 src/Admin/AdminController.php:151
#: src/Admin/AdminController.php:266 src/Admin/AdminController.php:1373
#: src/Admin/AdminController.php:1613
#: src/Admin/DashboardWidgetController.php:136 #: src/Admin/DashboardWidgetController.php:136
#: src/Admin/AdminController.php:151 src/Admin/AdminController.php:266
#: src/Admin/AdminController.php:1373 src/Admin/AdminController.php:1613
#: src/Product/LicensedProductType.php:110 #: src/Product/LicensedProductType.php:110
#: src/Product/LicensedProductType.php:158 #: src/Product/LicensedProductType.php:158
msgid "Lifetime" msgid "Lifetime"
msgstr "Lebenslang" msgstr "Lebenslang"
#: src/Admin/OrderLicenseController.php:208 #: src/Admin/OrderLicenseController.php:235
msgid "View in Licenses" msgid "View in Licenses"
msgstr "In Lizenzen anzeigen" msgstr "In Lizenzen anzeigen"
#: src/Admin/OrderLicenseController.php:221 #: src/Admin/OrderLicenseController.php:248
#, php-format #, php-format
msgid "For more actions (revoke, extend, delete), go to the %s page." msgid "For more actions (revoke, extend, delete), go to the %s page."
msgstr "" msgstr ""
"Für weitere Aktionen (widerrufen, verlängern, löschen), gehen Sie zur Seite " "Für weitere Aktionen (widerrufen, verlängern, löschen), gehen Sie zur Seite "
"%s." "%s."
#: src/Admin/OrderLicenseController.php:285 src/Admin/AdminController.php:144 #: src/Admin/OrderLicenseController.php:261
#, php-format
msgid "%d licensed product is missing a license."
msgid_plural "%d licensed products are missing licenses."
msgstr[0] "%d lizenziertes Produkt hat keine Lizenz."
msgstr[1] "%d lizenzierte Produkte haben keine Lizenzen."
#: src/Admin/OrderLicenseController.php:270
msgid "Generate Missing Licenses"
msgstr "Fehlende Lizenzen generieren"
#: src/Admin/OrderLicenseController.php:338 src/Admin/AdminController.php:144
msgid "Saving..." msgid "Saving..."
msgstr "Speichere..." msgstr "Speichere..."
#: src/Admin/OrderLicenseController.php:286 #: src/Admin/OrderLicenseController.php:339
msgid "Saved!" msgid "Saved!"
msgstr "Gespeichert!" msgstr "Gespeichert!"
#: src/Admin/OrderLicenseController.php:287 #: src/Admin/OrderLicenseController.php:340
msgid "Error saving. Please try again." msgid "Error. Please try again."
msgstr "Fehler beim Speichern. Bitte versuchen Sie es erneut." msgstr "Fehler. Bitte versuchen Sie es erneut."
#: src/Admin/OrderLicenseController.php:288 #: src/Admin/OrderLicenseController.php:341
#: src/Frontend/AccountController.php:314 #: src/Frontend/AccountController.php:314
#: src/Frontend/AccountController.php:346 #: src/Frontend/AccountController.php:346
msgid "Please enter a valid domain." msgid "Please enter a valid domain."
msgstr "Bitte geben Sie eine gültige Domain ein." msgstr "Bitte geben Sie eine gültige Domain ein."
#: src/Admin/OrderLicenseController.php:301 #: src/Admin/OrderLicenseController.php:342
#: src/Admin/OrderLicenseController.php:340 msgid "Generating..."
msgstr "Generiere..."
#: src/Admin/OrderLicenseController.php:355
#: src/Admin/OrderLicenseController.php:394
#: src/Admin/OrderLicenseController.php:458
#: src/Admin/VersionAdminController.php:259 #: src/Admin/VersionAdminController.php:259
#: src/Admin/VersionAdminController.php:328 #: src/Admin/VersionAdminController.php:328
#: src/Admin/VersionAdminController.php:354 src/Admin/AdminController.php:173 #: src/Admin/VersionAdminController.php:354 src/Admin/AdminController.php:173
@@ -181,43 +204,63 @@ msgstr "Bitte geben Sie eine gültige Domain ein."
msgid "Permission denied." msgid "Permission denied."
msgstr "Zugriff verweigert." msgstr "Zugriff verweigert."
#: src/Admin/OrderLicenseController.php:308 #: src/Admin/OrderLicenseController.php:362
#: src/Admin/OrderLicenseController.php:464
msgid "Invalid order ID." msgid "Invalid order ID."
msgstr "Ungültige Bestellungs-ID." msgstr "Ungültige Bestellungs-ID."
#: src/Admin/OrderLicenseController.php:319 #: src/Admin/OrderLicenseController.php:373
#: src/Admin/OrderLicenseController.php:357 #: src/Admin/OrderLicenseController.php:411
msgid "Invalid domain format." msgid "Invalid domain format."
msgstr "Ungültiges Domain-Format." msgstr "Ungültiges Domain-Format."
#: src/Admin/OrderLicenseController.php:327 #: src/Admin/OrderLicenseController.php:381
msgid "Order domain updated." msgid "Order domain updated."
msgstr "Bestellungs-Domain aktualisiert." msgstr "Bestellungs-Domain aktualisiert."
#: src/Admin/OrderLicenseController.php:347 src/Admin/AdminController.php:220 #: src/Admin/OrderLicenseController.php:401 src/Admin/AdminController.php:220
#: src/Admin/AdminController.php:256 src/Admin/AdminController.php:308 #: src/Admin/AdminController.php:256 src/Admin/AdminController.php:308
#: src/Admin/AdminController.php:345 #: src/Admin/AdminController.php:345
msgid "Invalid license ID." msgid "Invalid license ID."
msgstr "Ungültige Lizenz-ID." msgstr "Ungültige Lizenz-ID."
#: src/Admin/OrderLicenseController.php:351 src/Admin/AdminController.php:312 #: src/Admin/OrderLicenseController.php:405 src/Admin/AdminController.php:312
msgid "Domain cannot be empty." msgid "Domain cannot be empty."
msgstr "Domain darf nicht leer sein." msgstr "Domain darf nicht leer sein."
#: src/Admin/OrderLicenseController.php:363 #: src/Admin/OrderLicenseController.php:417
#: src/Frontend/DownloadController.php:117
#: src/Frontend/AccountController.php:352 #: src/Frontend/AccountController.php:352
#: src/Frontend/DownloadController.php:117
msgid "License not found." msgid "License not found."
msgstr "Lizenz nicht gefunden." msgstr "Lizenz nicht gefunden."
#: src/Admin/OrderLicenseController.php:371 #: src/Admin/OrderLicenseController.php:425
msgid "License domain updated." msgid "License domain updated."
msgstr "Lizenz-Domain aktualisiert." msgstr "Lizenz-Domain aktualisiert."
#: src/Admin/OrderLicenseController.php:375 #: src/Admin/OrderLicenseController.php:429
msgid "Failed to update license domain." msgid "Failed to update license domain."
msgstr "Lizenz-Domain konnte nicht aktualisiert werden." msgstr "Lizenz-Domain konnte nicht aktualisiert werden."
#: src/Admin/OrderLicenseController.php:474
msgid "Order must be paid before licenses can be generated."
msgstr "Die Bestellung muss bezahlt sein, bevor Lizenzen generiert werden können."
#: src/Admin/OrderLicenseController.php:480
msgid "Please set the order domain before generating licenses."
msgstr "Bitte legen Sie die Bestellungs-Domain fest, bevor Sie Lizenzen generieren."
#: src/Admin/OrderLicenseController.php:521
#, php-format
msgid "%d license generated successfully."
msgid_plural "%d licenses generated successfully."
msgstr[0] "%d Lizenz erfolgreich generiert."
msgstr[1] "%d Lizenzen erfolgreich generiert."
#: src/Admin/OrderLicenseController.php:534
msgid "All licenses already exist for this order."
msgstr "Alle Lizenzen für diese Bestellung existieren bereits."
#: src/Admin/SettingsController.php:54 #: src/Admin/SettingsController.php:54
msgid "Licensed Products" msgid "Licensed Products"
msgstr "Lizensierte Produkte" msgstr "Lizensierte Produkte"
@@ -320,9 +363,6 @@ msgid ""
"Configure when expiration warning emails are sent. To customize the email " "Configure when expiration warning emails are sent. To customize the email "
"template, enable/disable, or change the subject, go to %s." "template, enable/disable, or change the subject, go to %s."
msgstr "" msgstr ""
"Konfigurieren Sie, wann Ablaufwarnungs-E-Mails gesendet werden. Um die "
"E-Mail-Vorlage anzupassen, zu aktivieren/deaktivieren oder den Betreff zu "
"ändern, gehen Sie zu %s."
"Konfigurieren Sie, wann Ablaufwarnungs-E-Mails gesendet werden. Um die E-" "Konfigurieren Sie, wann Ablaufwarnungs-E-Mails gesendet werden. Um die E-"
"Mail-Vorlage anzupassen, zu aktivieren/deaktivieren oder den Betreff zu " "Mail-Vorlage anzupassen, zu aktivieren/deaktivieren oder den Betreff zu "
"ändern, gehen Sie zu %s." "ändern, gehen Sie zu %s."
@@ -485,10 +525,10 @@ msgid "No download file"
msgstr "Keine Download-Datei" msgstr "Keine Download-Datei"
#: src/Admin/VersionAdminController.php:182 #: src/Admin/VersionAdminController.php:182
#: src/Admin/VersionAdminController.php:413 #: src/Admin/VersionAdminController.php:413 src/Admin/AdminController.php:156
#: src/Admin/AdminController.php:907 src/Admin/AdminController.php:1232
#: src/Admin/AdminController.php:1355
#: src/Admin/DashboardWidgetController.php:117 #: src/Admin/DashboardWidgetController.php:117
#: src/Admin/AdminController.php:156 src/Admin/AdminController.php:907
#: src/Admin/AdminController.php:1232 src/Admin/AdminController.php:1355
msgid "Active" msgid "Active"
msgstr "Aktiv" msgstr "Aktiv"
@@ -603,34 +643,6 @@ msgstr "Version konnte nicht aktualisiert werden."
msgid "Version updated successfully." msgid "Version updated successfully."
msgstr "Version erfolgreich aktualisiert." msgstr "Version erfolgreich aktualisiert."
#: src/Admin/DashboardWidgetController.php:47
msgid "License Statistics"
msgstr "Lizenzstatistiken"
#: src/Admin/DashboardWidgetController.php:113
#: src/Admin/AdminController.php:900
msgid "Total Licenses"
msgstr "Lizenzen insgesamt"
#: src/Admin/DashboardWidgetController.php:121
msgid "Expiring Soon"
msgstr "Bald ablaufend"
#: src/Admin/DashboardWidgetController.php:125
#: src/Admin/AdminController.php:158 src/Admin/AdminController.php:921
#: src/Admin/AdminController.php:1234 src/Admin/AdminController.php:1357
#: src/Email/LicenseExpiredEmail.php:210 src/Email/LicenseExpiredEmail.php:259
msgid "Expired"
msgstr "Abgelaufen"
#: src/Admin/DashboardWidgetController.php:132
msgid "Time-limited"
msgstr "Zeitbegrenzt"
#: src/Admin/DashboardWidgetController.php:142
msgid "View All Licenses"
msgstr "Alle Lizenzen anzeigen"
#: src/Admin/AdminController.php:93 #: src/Admin/AdminController.php:93
msgid "Overview" msgid "Overview"
msgstr "Übersicht" msgstr "Übersicht"
@@ -675,6 +687,13 @@ msgstr "Kopiert!"
msgid "Copy failed" msgid "Copy failed"
msgstr "Kopieren fehlgeschlagen" msgstr "Kopieren fehlgeschlagen"
#: src/Admin/AdminController.php:158 src/Admin/AdminController.php:921
#: src/Admin/AdminController.php:1234 src/Admin/AdminController.php:1357
#: src/Admin/DashboardWidgetController.php:125
#: src/Email/LicenseExpiredEmail.php:210 src/Email/LicenseExpiredEmail.php:259
msgid "Expired"
msgstr "Abgelaufen"
#: src/Admin/AdminController.php:159 src/Admin/AdminController.php:928 #: src/Admin/AdminController.php:159 src/Admin/AdminController.php:928
#: src/Admin/AdminController.php:1235 src/Admin/AdminController.php:1358 #: src/Admin/AdminController.php:1235 src/Admin/AdminController.php:1358
msgid "Revoked" msgid "Revoked"
@@ -757,6 +776,11 @@ msgstr "Import der Lizenz für Domain %s fehlgeschlagen"
msgid "License Dashboard" msgid "License Dashboard"
msgstr "Lizenz-Dashboard" msgstr "Lizenz-Dashboard"
#: src/Admin/AdminController.php:900
#: src/Admin/DashboardWidgetController.php:113
msgid "Total Licenses"
msgstr "Lizenzen insgesamt"
#: src/Admin/AdminController.php:937 #: src/Admin/AdminController.php:937
msgid "Attention:" msgid "Attention:"
msgstr "Achtung:" msgstr "Achtung:"
@@ -1180,6 +1204,22 @@ msgstr "Lizenz"
msgid "No domain specified" msgid "No domain specified"
msgstr "Keine Domain angegeben" msgstr "Keine Domain angegeben"
#: src/Admin/DashboardWidgetController.php:47
msgid "License Statistics"
msgstr "Lizenzstatistiken"
#: src/Admin/DashboardWidgetController.php:121
msgid "Expiring Soon"
msgstr "Bald ablaufend"
#: src/Admin/DashboardWidgetController.php:132
msgid "Time-limited"
msgstr "Zeitbegrenzt"
#: src/Admin/DashboardWidgetController.php:142
msgid "View All Licenses"
msgstr "Alle Lizenzen anzeigen"
#: src/Admin/DownloadWidgetController.php:46 #: src/Admin/DownloadWidgetController.php:46
msgid "Download Statistics" msgid "Download Statistics"
msgstr "Download-Statistiken" msgstr "Download-Statistiken"
@@ -1305,15 +1345,6 @@ msgstr "Diese Lizenz ist für diese Domain nicht gültig."
msgid "Unknown Product" msgid "Unknown Product"
msgstr "Unbekanntes Produkt" msgstr "Unbekanntes Produkt"
#: src/Product/VersionManager.php:166
msgid "Attachment file not found."
msgstr "Anhangs-Datei nicht gefunden."
#: 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/LicensedProductType.php:61 #: src/Product/LicensedProductType.php:61
msgid "Licensed Product" msgid "Licensed Product"
msgstr "Lizensiertes Produkt" msgstr "Lizensiertes Produkt"
@@ -1379,56 +1410,14 @@ msgstr "Nein"
msgid "Version:" msgid "Version:"
msgstr "Version:" msgstr "Version:"
#: src/Frontend/DownloadController.php:77 #: src/Product/VersionManager.php:166
#: src/Frontend/DownloadController.php:101 msgid "Attachment file not found."
msgid "Invalid download link." msgstr "Anhangs-Datei nicht gefunden."
msgstr "Ungültiger Download-Link."
#: src/Frontend/DownloadController.php:78 #: src/Product/VersionManager.php:177
#: src/Frontend/DownloadController.php:88 #, php-format
#: src/Frontend/DownloadController.php:102 msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
#: src/Frontend/DownloadController.php:118 msgstr "Datei-Prüfsumme stimmt nicht überein. Erwartet: %1$s, Erhalten: %2$s"
#: src/Frontend/DownloadController.php:128
#: src/Frontend/DownloadController.php:137
#: src/Frontend/DownloadController.php:147
#: src/Frontend/DownloadController.php:156
#: src/Frontend/DownloadController.php:165
#: src/Frontend/DownloadController.php:187
#: src/Frontend/DownloadController.php:203
msgid "Download Error"
msgstr "Download-Fehler"
#: src/Frontend/DownloadController.php:87
msgid "Invalid download link format."
msgstr "Ungültiges Download-Link-Format."
#: src/Frontend/DownloadController.php:127
msgid "You do not have permission to download this file."
msgstr "Sie haben keine Berechtigung, diese Datei herunterzuladen."
#: src/Frontend/DownloadController.php:136
msgid "Your license is not active. Please contact support."
msgstr "Ihre Lizenz ist nicht aktiv. Bitte kontaktieren Sie den Support."
#: src/Frontend/DownloadController.php:146
msgid "Version not found."
msgstr "Version nicht gefunden."
#: src/Frontend/DownloadController.php:155
msgid "Version does not match your licensed product."
msgstr "Version stimmt nicht mit Ihrem lizensierten Produkt überein."
#: src/Frontend/DownloadController.php:164
msgid "This version is no longer available for download."
msgstr "Diese Version ist nicht mehr zum Download verfügbar."
#: src/Frontend/DownloadController.php:186
msgid "No download file available for this version."
msgstr "Keine Download-Datei für diese Version verfügbar."
#: src/Frontend/DownloadController.php:202
msgid "Download file not found."
msgstr "Download-Datei nicht gefunden."
#: src/Frontend/AccountController.php:104 #: src/Frontend/AccountController.php:104
msgid "Please log in to view your licenses." msgid "Please log in to view your licenses."
@@ -1522,6 +1511,57 @@ msgstr "Die neue Domain ist dieselbe wie die aktuelle Domain."
msgid "Failed to transfer license. Please try again." msgid "Failed to transfer license. Please try again."
msgstr "Lizenzübertragung fehlgeschlagen. Bitte versuchen Sie es erneut." msgstr "Lizenzübertragung fehlgeschlagen. Bitte versuchen Sie es erneut."
#: src/Frontend/DownloadController.php:77
#: src/Frontend/DownloadController.php:101
msgid "Invalid download link."
msgstr "Ungültiger Download-Link."
#: src/Frontend/DownloadController.php:78
#: src/Frontend/DownloadController.php:88
#: src/Frontend/DownloadController.php:102
#: src/Frontend/DownloadController.php:118
#: src/Frontend/DownloadController.php:128
#: src/Frontend/DownloadController.php:137
#: src/Frontend/DownloadController.php:147
#: src/Frontend/DownloadController.php:156
#: src/Frontend/DownloadController.php:165
#: src/Frontend/DownloadController.php:187
#: src/Frontend/DownloadController.php:203
msgid "Download Error"
msgstr "Download-Fehler"
#: src/Frontend/DownloadController.php:87
msgid "Invalid download link format."
msgstr "Ungültiges Download-Link-Format."
#: src/Frontend/DownloadController.php:127
msgid "You do not have permission to download this file."
msgstr "Sie haben keine Berechtigung, diese Datei herunterzuladen."
#: src/Frontend/DownloadController.php:136
msgid "Your license is not active. Please contact support."
msgstr "Ihre Lizenz ist nicht aktiv. Bitte kontaktieren Sie den Support."
#: src/Frontend/DownloadController.php:146
msgid "Version not found."
msgstr "Version nicht gefunden."
#: src/Frontend/DownloadController.php:155
msgid "Version does not match your licensed product."
msgstr "Version stimmt nicht mit Ihrem lizensierten Produkt überein."
#: src/Frontend/DownloadController.php:164
msgid "This version is no longer available for download."
msgstr "Diese Version ist nicht mehr zum Download verfügbar."
#: src/Frontend/DownloadController.php:186
msgid "No download file available for this version."
msgstr "Keine Download-Datei für diese Version verfügbar."
#: src/Frontend/DownloadController.php:202
msgid "Download file not found."
msgstr "Download-Datei nicht gefunden."
#: src/Email/LicenseExpirationEmail.php:55 #: src/Email/LicenseExpirationEmail.php:55
msgid "License Expiration Warning" msgid "License Expiration Warning"
msgstr "Lizenzablauf-Warnung" msgstr "Lizenzablauf-Warnung"
@@ -1726,112 +1766,3 @@ msgid "WC Licensed Product requires WooCommerce to be installed and active."
msgstr "" msgstr ""
"WC Licensed Product benötigt WooCommerce als installierte und aktivierte " "WC Licensed Product benötigt WooCommerce als installierte und aktivierte "
"Erweiterung." "Erweiterung."
#~ msgid "Status Breakdown"
#~ msgstr "Statusübersicht"
#, php-format
#~ msgid "Active: %d"
#~ msgstr "Aktiv: %d"
#, php-format
#~ msgid "Inactive: %d"
#~ msgstr "Inaktiv: %d"
#, php-format
#~ msgid "Expired: %d"
#~ msgstr "Abgelaufen: %d"
#, php-format
#~ msgid "Revoked: %d"
#~ msgstr "Widerrufen: %d"
#~ msgid "License Types"
#~ msgstr "Lizenztypen"
#, php-format
#~ msgid "Time-limited: %d"
#~ msgstr "Zeitlich begrenzt: %d"
#, php-format
#~ msgid "Lifetime: %d"
#~ msgstr "Lebenslang: %d"
#~ msgid "Or External URL"
#~ msgstr "Oder externe URL"
#~ msgid ""
#~ "Alternative: Enter an external download URL instead of uploading a file."
#~ msgstr ""
#~ "Alternativ: Geben Sie eine externe Download-URL ein, anstatt eine Datei "
#~ "hochzuladen."
#~ msgid "Enter SHA256 checksum..."
#~ msgstr "SHA256 Prüfsumme eingeben..."
#~ msgid ""
#~ "SHA256 checksum of the uploaded file (optional but recommended for "
#~ "integrity verification)."
#~ msgstr ""
#~ "SHA256 Prüfsumme der hochgeladenen Datei (optional, aber empfohlen zur "
#~ "Integritätsprüfung)."
#~ msgid "Maximum number of domain activations per license. Default: 1"
#~ msgstr "Maximale Anzahl der Domain-Aktivierungen pro Lizenz. Standard: 1"
#~ msgid ""
#~ "Number of days the license is valid. Leave empty for lifetime license."
#~ msgstr ""
#~ "Anzahl Tage, die die Lizenz gültig ist. Leer lassen für eine lebenslange "
#~ "Lizenz."
#~ msgid ""
#~ "If enabled, licenses are bound to the major version at purchase time."
#~ msgstr ""
#~ "Falls aktiviert, werden Lizenzen an die Hauptversion zum Kaufzeitpunkt "
#~ "gebunden."
#~ msgid "License is not activated for this domain."
#~ msgstr "Die Lizenz ist für diese Domain nicht aktiviert."
#~ msgid "Failed to deactivate license."
#~ msgstr "Lizenz konnte nicht deaktiviert werden."
#~ msgid "License deactivated successfully."
#~ msgstr "Lizenz erfolgreich deaktiviert."
#~ msgid "Total licenses:"
#~ msgstr "Lizenzen insgesamt:"
#~ msgid "of"
#~ msgstr "von"
#~ msgid "Lifetime Licenses"
#~ msgstr "Lebenslange Lizenzen"
#~ msgid "Licenses Created (Last 12 Months)"
#~ msgstr "Erstellte Lizenzen (letzte 12 Monate)"
#~ msgid "Top Domains"
#~ msgstr "Top-Domains"
#~ msgid "No license data available yet."
#~ msgstr "Noch keine Lizenzdaten verfügbar."
#~ msgid "license is"
#~ msgstr "Lizenz ist"
#~ msgid "licenses are"
#~ msgstr "Lizenzen sind"
#~ msgid "[%2$s] Your license for %1$s expires tomorrow"
#~ msgstr "[%2$s] Ihre Lizenz für %1$s läuft morgen ab"
#~ msgid "[%3$s] Your license for %1$s expires in %2$d days"
#~ msgstr "[%3$s] Ihre Lizenz für %1$s läuft in %2$d Tagen ab"
#~ msgid "This email was sent from %s."
#~ msgstr "Diese E-Mail wurde von %s gesendet."
#~ msgid "No results found"
#~ msgstr "Keine Ergebnisse gefunden"

View File

@@ -6,9 +6,9 @@
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: WC Licensed Product 0.3.7\n" "Project-Id-Version: WC Licensed Product 0.3.8\n"
"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-01-24 10:11+0100\n" "POT-Creation-Date: 2026-01-24 16:06+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,154 +18,179 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: src/Admin/OrderLicenseController.php:56 #: src/Admin/OrderLicenseController.php:57
msgid "Product Licenses" msgid "Product Licenses"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:77 #: src/Admin/OrderLicenseController.php:78
#: src/Admin/OrderLicenseController.php:313 #: src/Admin/OrderLicenseController.php:367
#: src/Admin/OrderLicenseController.php:469
msgid "Order not found." msgid "Order not found."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:92 #: src/Admin/OrderLicenseController.php:93
msgid "This order does not contain licensed products." msgid "This order does not contain licensed products."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:106 #: src/Admin/OrderLicenseController.php:107
msgid "Order Domain" msgid "Order Domain"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:108 #: src/Admin/OrderLicenseController.php:109
msgid "" msgid ""
"The domain specified during checkout. Changing this will not automatically " "The domain specified during checkout. Changing this will not automatically "
"update existing license domains." "update existing license domains."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:116 #: src/Admin/OrderLicenseController.php:117
#: src/Checkout/CheckoutController.php:89 #: src/Checkout/CheckoutController.php:89
#: src/Checkout/CheckoutBlocksIntegration.php:102 #: src/Checkout/CheckoutBlocksIntegration.php:102
msgid "example.com" msgid "example.com"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:118 #: src/Admin/OrderLicenseController.php:119
#: src/Admin/OrderLicenseController.php:182 src/Admin/AdminController.php:150 #: src/Admin/OrderLicenseController.php:209 src/Admin/AdminController.php:150
#: src/Admin/AdminController.php:1340 src/Admin/AdminController.php:1360 #: src/Admin/AdminController.php:1340 src/Admin/AdminController.php:1360
#: src/Admin/AdminController.php:1381 #: src/Admin/AdminController.php:1381
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:127 #: src/Admin/OrderLicenseController.php:128
#: src/Admin/OrderLicenseController.php:222 src/Admin/AdminController.php:76 #: src/Admin/OrderLicenseController.php:249 src/Admin/AdminController.php:76
#: src/Admin/AdminController.php:77 src/Admin/AdminController.php:90 #: src/Admin/AdminController.php:77 src/Admin/AdminController.php:90
#: src/Admin/AdminController.php:1200 src/Frontend/AccountController.php:90 #: src/Admin/AdminController.php:1200 src/Frontend/AccountController.php:90
msgid "Licenses" msgid "Licenses"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:131 #: src/Admin/OrderLicenseController.php:144
msgid "No licenses have been generated for this order yet." msgid "No licenses have been generated for this order yet."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:134 #: src/Admin/OrderLicenseController.php:147
msgid "" msgid ""
"Licenses should be generated automatically when an order is paid. If " "Licenses should be generated automatically when an order is paid. If "
"missing, check that a domain was specified during checkout." "missing, check that a domain was specified during checkout."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:137 #: src/Admin/OrderLicenseController.php:150
msgid "Licenses will be generated when the order is marked as paid/completed." msgid "Licenses will be generated when the order is marked as paid/completed."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:144 #: src/Admin/OrderLicenseController.php:156
msgid "Generate Licenses"
msgstr ""
#: src/Admin/OrderLicenseController.php:164
msgid "Please set the order domain above before generating licenses."
msgstr ""
#: src/Admin/OrderLicenseController.php:171
#: src/Admin/SettingsController.php:142 src/Admin/AdminController.php:1291 #: src/Admin/SettingsController.php:142 src/Admin/AdminController.php:1291
#: src/Admin/AdminController.php:1442 src/Admin/AdminController.php:1491 #: src/Admin/AdminController.php:1442 src/Admin/AdminController.php:1491
#: src/Email/LicenseEmailController.php:269 #: src/Email/LicenseEmailController.php:269
msgid "License Key" msgid "License Key"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:145 src/Admin/AdminController.php:1292 #: src/Admin/OrderLicenseController.php:172 src/Admin/AdminController.php:1292
#: src/Admin/AdminController.php:1443 src/Admin/AdminController.php:1608 #: src/Admin/AdminController.php:1443 src/Admin/AdminController.php:1608
#: src/Email/LicenseEmailController.php:268 #: src/Email/LicenseEmailController.php:268
msgid "Product" msgid "Product"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:146 src/Admin/AdminController.php:1294 #: src/Admin/OrderLicenseController.php:173 src/Admin/AdminController.php:1294
#: src/Admin/AdminController.php:1445 src/Admin/AdminController.php:1495 #: src/Admin/AdminController.php:1445 src/Admin/AdminController.php:1495
msgid "Domain" msgid "Domain"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:147 #: src/Admin/OrderLicenseController.php:174
#: src/Admin/VersionAdminController.php:140 src/Admin/AdminController.php:1295 #: src/Admin/VersionAdminController.php:140 src/Admin/AdminController.php:1295
#: src/Admin/AdminController.php:1446 #: src/Admin/AdminController.php:1446
msgid "Status" msgid "Status"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:148 src/Admin/AdminController.php:1297 #: src/Admin/OrderLicenseController.php:175 src/Admin/AdminController.php:1297
#: src/Admin/AdminController.php:1448 src/Admin/AdminController.php:1611 #: src/Admin/AdminController.php:1448 src/Admin/AdminController.php:1611
#: src/Admin/AdminController.php:1613 src/Email/LicenseEmailController.php:270 #: src/Admin/AdminController.php:1613 src/Email/LicenseEmailController.php:270
msgid "Expires" msgid "Expires"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:149 #: src/Admin/OrderLicenseController.php:176
#: src/Admin/VersionAdminController.php:142 src/Admin/AdminController.php:1298 #: src/Admin/VersionAdminController.php:142 src/Admin/AdminController.php:1298
#: src/Admin/AdminController.php:1449 #: src/Admin/AdminController.php:1449
msgid "Actions" msgid "Actions"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:168 src/Admin/AdminController.php:195 #: src/Admin/OrderLicenseController.php:195 src/Admin/AdminController.php:195
#: src/Admin/AdminController.php:1019 #: src/Admin/AdminController.php:1019
msgid "Unknown" msgid "Unknown"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:178 #: src/Admin/OrderLicenseController.php:205
msgid "Edit domain" msgid "Edit domain"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:185 src/Admin/AdminController.php:149 #: src/Admin/OrderLicenseController.php:212 src/Admin/AdminController.php:149
#: src/Admin/AdminController.php:1341 src/Admin/AdminController.php:1361 #: src/Admin/AdminController.php:1341 src/Admin/AdminController.php:1361
#: src/Admin/AdminController.php:1382 src/Admin/AdminController.php:1537 #: src/Admin/AdminController.php:1382 src/Admin/AdminController.php:1537
#: src/Frontend/AccountController.php:271 #: src/Frontend/AccountController.php:271
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:201 #: src/Admin/OrderLicenseController.php:228
#: src/Admin/SettingsController.php:192 #: src/Admin/SettingsController.php:192 src/Admin/AdminController.php:151
#: src/Admin/AdminController.php:266 src/Admin/AdminController.php:1373
#: src/Admin/AdminController.php:1613
#: src/Admin/DashboardWidgetController.php:136 #: src/Admin/DashboardWidgetController.php:136
#: src/Admin/AdminController.php:151 src/Admin/AdminController.php:266
#: src/Admin/AdminController.php:1373 src/Admin/AdminController.php:1613
#: src/Product/LicensedProductType.php:110 #: src/Product/LicensedProductType.php:110
#: src/Product/LicensedProductType.php:158 #: src/Product/LicensedProductType.php:158
msgid "Lifetime" msgid "Lifetime"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:208 #: src/Admin/OrderLicenseController.php:235
msgid "View in Licenses" msgid "View in Licenses"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:221 #: src/Admin/OrderLicenseController.php:248
#, php-format #, php-format
msgid "For more actions (revoke, extend, delete), go to the %s page." msgid "For more actions (revoke, extend, delete), go to the %s page."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:285 src/Admin/AdminController.php:144 #: src/Admin/OrderLicenseController.php:261
#, php-format
msgid "%d licensed product is missing a license."
msgid_plural "%d licensed products are missing licenses."
msgstr[0] ""
msgstr[1] ""
#: src/Admin/OrderLicenseController.php:270
msgid "Generate Missing Licenses"
msgstr ""
#: src/Admin/OrderLicenseController.php:338 src/Admin/AdminController.php:144
msgid "Saving..." msgid "Saving..."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:286 #: src/Admin/OrderLicenseController.php:339
msgid "Saved!" msgid "Saved!"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:287 #: src/Admin/OrderLicenseController.php:340
msgid "Error saving. Please try again." msgid "Error. Please try again."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:288 #: src/Admin/OrderLicenseController.php:341
#: src/Frontend/AccountController.php:314 #: src/Frontend/AccountController.php:314
#: src/Frontend/AccountController.php:346 #: src/Frontend/AccountController.php:346
msgid "Please enter a valid domain." msgid "Please enter a valid domain."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:301 #: src/Admin/OrderLicenseController.php:342
#: src/Admin/OrderLicenseController.php:340 msgid "Generating..."
msgstr ""
#: src/Admin/OrderLicenseController.php:355
#: src/Admin/OrderLicenseController.php:394
#: src/Admin/OrderLicenseController.php:458
#: src/Admin/VersionAdminController.php:259 #: src/Admin/VersionAdminController.php:259
#: src/Admin/VersionAdminController.php:328 #: src/Admin/VersionAdminController.php:328
#: src/Admin/VersionAdminController.php:354 src/Admin/AdminController.php:173 #: src/Admin/VersionAdminController.php:354 src/Admin/AdminController.php:173
@@ -175,43 +200,63 @@ msgstr ""
msgid "Permission denied." msgid "Permission denied."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:308 #: src/Admin/OrderLicenseController.php:362
#: src/Admin/OrderLicenseController.php:464
msgid "Invalid order ID." msgid "Invalid order ID."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:319 #: src/Admin/OrderLicenseController.php:373
#: src/Admin/OrderLicenseController.php:357 #: src/Admin/OrderLicenseController.php:411
msgid "Invalid domain format." msgid "Invalid domain format."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:327 #: src/Admin/OrderLicenseController.php:381
msgid "Order domain updated." msgid "Order domain updated."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:347 src/Admin/AdminController.php:220 #: src/Admin/OrderLicenseController.php:401 src/Admin/AdminController.php:220
#: src/Admin/AdminController.php:256 src/Admin/AdminController.php:308 #: src/Admin/AdminController.php:256 src/Admin/AdminController.php:308
#: src/Admin/AdminController.php:345 #: src/Admin/AdminController.php:345
msgid "Invalid license ID." msgid "Invalid license ID."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:351 src/Admin/AdminController.php:312 #: src/Admin/OrderLicenseController.php:405 src/Admin/AdminController.php:312
msgid "Domain cannot be empty." msgid "Domain cannot be empty."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:363 #: src/Admin/OrderLicenseController.php:417
#: src/Frontend/DownloadController.php:117
#: src/Frontend/AccountController.php:352 #: src/Frontend/AccountController.php:352
#: src/Frontend/DownloadController.php:117
msgid "License not found." msgid "License not found."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:371 #: src/Admin/OrderLicenseController.php:425
msgid "License domain updated." msgid "License domain updated."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:375 #: src/Admin/OrderLicenseController.php:429
msgid "Failed to update license domain." msgid "Failed to update license domain."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:474
msgid "Order must be paid before licenses can be generated."
msgstr ""
#: src/Admin/OrderLicenseController.php:480
msgid "Please set the order domain before generating licenses."
msgstr ""
#: src/Admin/OrderLicenseController.php:521
#, php-format
msgid "%d license generated successfully."
msgid_plural "%d licenses generated successfully."
msgstr[0] ""
msgstr[1] ""
#: src/Admin/OrderLicenseController.php:534
msgid "All licenses already exist for this order."
msgstr ""
#: src/Admin/SettingsController.php:54 #: src/Admin/SettingsController.php:54
msgid "Licensed Products" msgid "Licensed Products"
msgstr "" msgstr ""
@@ -457,10 +502,10 @@ msgid "No download file"
msgstr "" msgstr ""
#: src/Admin/VersionAdminController.php:182 #: src/Admin/VersionAdminController.php:182
#: src/Admin/VersionAdminController.php:413 #: src/Admin/VersionAdminController.php:413 src/Admin/AdminController.php:156
#: src/Admin/AdminController.php:907 src/Admin/AdminController.php:1232
#: src/Admin/AdminController.php:1355
#: src/Admin/DashboardWidgetController.php:117 #: src/Admin/DashboardWidgetController.php:117
#: src/Admin/AdminController.php:156 src/Admin/AdminController.php:907
#: src/Admin/AdminController.php:1232 src/Admin/AdminController.php:1355
msgid "Active" msgid "Active"
msgstr "" msgstr ""
@@ -571,34 +616,6 @@ msgstr ""
msgid "Version updated successfully." msgid "Version updated successfully."
msgstr "" msgstr ""
#: src/Admin/DashboardWidgetController.php:47
msgid "License Statistics"
msgstr ""
#: src/Admin/DashboardWidgetController.php:113
#: src/Admin/AdminController.php:900
msgid "Total Licenses"
msgstr ""
#: src/Admin/DashboardWidgetController.php:121
msgid "Expiring Soon"
msgstr ""
#: src/Admin/DashboardWidgetController.php:125
#: src/Admin/AdminController.php:158 src/Admin/AdminController.php:921
#: src/Admin/AdminController.php:1234 src/Admin/AdminController.php:1357
#: src/Email/LicenseExpiredEmail.php:210 src/Email/LicenseExpiredEmail.php:259
msgid "Expired"
msgstr ""
#: src/Admin/DashboardWidgetController.php:132
msgid "Time-limited"
msgstr ""
#: src/Admin/DashboardWidgetController.php:142
msgid "View All Licenses"
msgstr ""
#: src/Admin/AdminController.php:93 #: src/Admin/AdminController.php:93
msgid "Overview" msgid "Overview"
msgstr "" msgstr ""
@@ -641,6 +658,13 @@ msgstr ""
msgid "Copy failed" msgid "Copy failed"
msgstr "" msgstr ""
#: src/Admin/AdminController.php:158 src/Admin/AdminController.php:921
#: src/Admin/AdminController.php:1234 src/Admin/AdminController.php:1357
#: src/Admin/DashboardWidgetController.php:125
#: src/Email/LicenseExpiredEmail.php:210 src/Email/LicenseExpiredEmail.php:259
msgid "Expired"
msgstr ""
#: src/Admin/AdminController.php:159 src/Admin/AdminController.php:928 #: src/Admin/AdminController.php:159 src/Admin/AdminController.php:928
#: src/Admin/AdminController.php:1235 src/Admin/AdminController.php:1358 #: src/Admin/AdminController.php:1235 src/Admin/AdminController.php:1358
msgid "Revoked" msgid "Revoked"
@@ -723,6 +747,11 @@ msgstr ""
msgid "License Dashboard" msgid "License Dashboard"
msgstr "" msgstr ""
#: src/Admin/AdminController.php:900
#: src/Admin/DashboardWidgetController.php:113
msgid "Total Licenses"
msgstr ""
#: src/Admin/AdminController.php:937 #: src/Admin/AdminController.php:937
msgid "Attention:" msgid "Attention:"
msgstr "" msgstr ""
@@ -1139,6 +1168,22 @@ msgstr ""
msgid "No domain specified" msgid "No domain specified"
msgstr "" msgstr ""
#: src/Admin/DashboardWidgetController.php:47
msgid "License Statistics"
msgstr ""
#: src/Admin/DashboardWidgetController.php:121
msgid "Expiring Soon"
msgstr ""
#: src/Admin/DashboardWidgetController.php:132
msgid "Time-limited"
msgstr ""
#: src/Admin/DashboardWidgetController.php:142
msgid "View All Licenses"
msgstr ""
#: src/Admin/DownloadWidgetController.php:46 #: src/Admin/DownloadWidgetController.php:46
msgid "Download Statistics" msgid "Download Statistics"
msgstr "" msgstr ""
@@ -1262,15 +1307,6 @@ msgstr ""
msgid "Unknown Product" msgid "Unknown Product"
msgstr "" msgstr ""
#: src/Product/VersionManager.php:166
msgid "Attachment file not found."
msgstr ""
#: src/Product/VersionManager.php:177
#, php-format
msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
msgstr ""
#: src/Product/LicensedProductType.php:61 #: src/Product/LicensedProductType.php:61
msgid "Licensed Product" msgid "Licensed Product"
msgstr "" msgstr ""
@@ -1334,55 +1370,13 @@ msgstr ""
msgid "Version:" msgid "Version:"
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:77 #: src/Product/VersionManager.php:166
#: src/Frontend/DownloadController.php:101 msgid "Attachment file not found."
msgid "Invalid download link."
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:78 #: src/Product/VersionManager.php:177
#: src/Frontend/DownloadController.php:88 #, php-format
#: src/Frontend/DownloadController.php:102 msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
#: src/Frontend/DownloadController.php:118
#: src/Frontend/DownloadController.php:128
#: src/Frontend/DownloadController.php:137
#: src/Frontend/DownloadController.php:147
#: src/Frontend/DownloadController.php:156
#: src/Frontend/DownloadController.php:165
#: src/Frontend/DownloadController.php:187
#: src/Frontend/DownloadController.php:203
msgid "Download Error"
msgstr ""
#: src/Frontend/DownloadController.php:87
msgid "Invalid download link format."
msgstr ""
#: src/Frontend/DownloadController.php:127
msgid "You do not have permission to download this file."
msgstr ""
#: src/Frontend/DownloadController.php:136
msgid "Your license is not active. Please contact support."
msgstr ""
#: src/Frontend/DownloadController.php:146
msgid "Version not found."
msgstr ""
#: src/Frontend/DownloadController.php:155
msgid "Version does not match your licensed product."
msgstr ""
#: src/Frontend/DownloadController.php:164
msgid "This version is no longer available for download."
msgstr ""
#: src/Frontend/DownloadController.php:186
msgid "No download file available for this version."
msgstr ""
#: src/Frontend/DownloadController.php:202
msgid "Download file not found."
msgstr "" msgstr ""
#: src/Frontend/AccountController.php:104 #: src/Frontend/AccountController.php:104
@@ -1475,6 +1469,57 @@ msgstr ""
msgid "Failed to transfer license. Please try again." msgid "Failed to transfer license. Please try again."
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:77
#: src/Frontend/DownloadController.php:101
msgid "Invalid download link."
msgstr ""
#: src/Frontend/DownloadController.php:78
#: src/Frontend/DownloadController.php:88
#: src/Frontend/DownloadController.php:102
#: src/Frontend/DownloadController.php:118
#: src/Frontend/DownloadController.php:128
#: src/Frontend/DownloadController.php:137
#: src/Frontend/DownloadController.php:147
#: src/Frontend/DownloadController.php:156
#: src/Frontend/DownloadController.php:165
#: src/Frontend/DownloadController.php:187
#: src/Frontend/DownloadController.php:203
msgid "Download Error"
msgstr ""
#: src/Frontend/DownloadController.php:87
msgid "Invalid download link format."
msgstr ""
#: src/Frontend/DownloadController.php:127
msgid "You do not have permission to download this file."
msgstr ""
#: src/Frontend/DownloadController.php:136
msgid "Your license is not active. Please contact support."
msgstr ""
#: src/Frontend/DownloadController.php:146
msgid "Version not found."
msgstr ""
#: src/Frontend/DownloadController.php:155
msgid "Version does not match your licensed product."
msgstr ""
#: src/Frontend/DownloadController.php:164
msgid "This version is no longer available for download."
msgstr ""
#: src/Frontend/DownloadController.php:186
msgid "No download file available for this version."
msgstr ""
#: src/Frontend/DownloadController.php:202
msgid "Download file not found."
msgstr ""
#: src/Email/LicenseExpirationEmail.php:55 #: src/Email/LicenseExpirationEmail.php:55
msgid "License Expiration Warning" msgid "License Expiration Warning"
msgstr "" msgstr ""

Binary file not shown.

View File

@@ -0,0 +1 @@
e93b2ab06f6d43c2179167090e07eda5db6809df6e391baece4ceba321cf33f6 wc-licensed-product-0.3.7.zip

View File

@@ -36,6 +36,7 @@ final class OrderLicenseController
// Handle AJAX actions // Handle AJAX actions
add_action('wp_ajax_wclp_update_order_domain', [$this, 'ajaxUpdateOrderDomain']); add_action('wp_ajax_wclp_update_order_domain', [$this, 'ajaxUpdateOrderDomain']);
add_action('wp_ajax_wclp_update_license_domain', [$this, 'ajaxUpdateLicenseDomain']); add_action('wp_ajax_wclp_update_license_domain', [$this, 'ajaxUpdateLicenseDomain']);
add_action('wp_ajax_wclp_generate_order_licenses', [$this, 'ajaxGenerateOrderLicenses']);
// Enqueue admin scripts // Enqueue admin scripts
add_action('admin_enqueue_scripts', [$this, 'enqueueScripts']); add_action('admin_enqueue_scripts', [$this, 'enqueueScripts']);
@@ -126,6 +127,18 @@ final class OrderLicenseController
<h4><?php esc_html_e('Licenses', 'wc-licensed-product'); ?></h4> <h4><?php esc_html_e('Licenses', 'wc-licensed-product'); ?></h4>
<?php
// Count licensed products to check if all have licenses
$licensedProductCount = 0;
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if ($product && $product->is_type('licensed')) {
$licensedProductCount++;
}
}
$missingLicenses = $licensedProductCount - count($licenses);
?>
<?php if (empty($licenses)): ?> <?php if (empty($licenses)): ?>
<p class="description"> <p class="description">
<?php esc_html_e('No licenses have been generated for this order yet.', 'wc-licensed-product'); ?> <?php esc_html_e('No licenses have been generated for this order yet.', 'wc-licensed-product'); ?>
@@ -137,6 +150,20 @@ final class OrderLicenseController
<em><?php esc_html_e('Licenses will be generated when the order is marked as paid/completed.', 'wc-licensed-product'); ?></em> <em><?php esc_html_e('Licenses will be generated when the order is marked as paid/completed.', 'wc-licensed-product'); ?></em>
<?php endif; ?> <?php endif; ?>
</p> </p>
<?php if ($orderDomain && $order->is_paid()): ?>
<p style="margin-top: 10px;">
<button type="button" class="button button-primary" id="wclp-generate-licenses" data-order-id="<?php echo esc_attr($order->get_id()); ?>">
<?php esc_html_e('Generate Licenses', 'wc-licensed-product'); ?>
</button>
<span class="spinner" style="float: none; margin-top: 4px;"></span>
<span class="wclp-generate-status"></span>
</p>
<?php elseif (!$orderDomain): ?>
<p class="description" style="margin-top: 10px; color: #d63638;">
<span class="dashicons dashicons-warning"></span>
<?php esc_html_e('Please set the order domain above before generating licenses.', 'wc-licensed-product'); ?>
</p>
<?php endif; ?>
<?php else: ?> <?php else: ?>
<table class="widefat striped wclp-licenses-table"> <table class="widefat striped wclp-licenses-table">
<thead> <thead>
@@ -223,6 +250,29 @@ final class OrderLicenseController
); );
?> ?>
</p> </p>
<?php if ($missingLicenses > 0 && $orderDomain && $order->is_paid()): ?>
<p style="margin-top: 10px;">
<span class="dashicons dashicons-warning" style="color: #dba617;"></span>
<?php
printf(
/* translators: %d: Number of missing licenses */
esc_html(_n(
'%d licensed product is missing a license.',
'%d licensed products are missing licenses.',
$missingLicenses,
'wc-licensed-product'
)),
$missingLicenses
);
?>
<button type="button" class="button" id="wclp-generate-licenses" data-order-id="<?php echo esc_attr($order->get_id()); ?>">
<?php esc_html_e('Generate Missing Licenses', 'wc-licensed-product'); ?>
</button>
<span class="spinner" style="float: none; margin-top: 4px;"></span>
<span class="wclp-generate-status"></span>
</p>
<?php endif; ?>
<?php endif; ?> <?php endif; ?>
</div> </div>
@@ -248,6 +298,9 @@ final class OrderLicenseController
.wclp-lifetime { color: #0073aa; font-weight: 500; } .wclp-lifetime { color: #0073aa; font-weight: 500; }
.wclp-edit-domain-btn { color: #0073aa; text-decoration: none; } .wclp-edit-domain-btn { color: #0073aa; text-decoration: none; }
.wclp-edit-domain-btn .dashicons { font-size: 16px; width: 16px; height: 16px; } .wclp-edit-domain-btn .dashicons { font-size: 16px; width: 16px; height: 16px; }
.wclp-generate-status { font-style: italic; margin-left: 8px; }
.wclp-generate-status.success { color: #46b450; }
.wclp-generate-status.error { color: #dc3232; }
</style> </style>
<?php <?php
} }
@@ -284,8 +337,9 @@ final class OrderLicenseController
'strings' => [ 'strings' => [
'saving' => __('Saving...', 'wc-licensed-product'), 'saving' => __('Saving...', 'wc-licensed-product'),
'saved' => __('Saved!', 'wc-licensed-product'), 'saved' => __('Saved!', 'wc-licensed-product'),
'error' => __('Error saving. Please try again.', 'wc-licensed-product'), 'error' => __('Error. Please try again.', 'wc-licensed-product'),
'invalidDomain' => __('Please enter a valid domain.', 'wc-licensed-product'), 'invalidDomain' => __('Please enter a valid domain.', 'wc-licensed-product'),
'generating' => __('Generating...', 'wc-licensed-product'),
], ],
]); ]);
} }
@@ -392,4 +446,96 @@ final class OrderLicenseController
$pattern = '/^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/'; $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); return (bool) preg_match($pattern, $domain);
} }
/**
* AJAX handler for generating order licenses
*/
public function ajaxGenerateOrderLicenses(): void
{
check_ajax_referer('wclp_order_license_actions', 'nonce');
if (!current_user_can('manage_woocommerce')) {
wp_send_json_error(['message' => __('Permission denied.', 'wc-licensed-product')]);
}
$orderId = absint($_POST['order_id'] ?? 0);
if (!$orderId) {
wp_send_json_error(['message' => __('Invalid order ID.', 'wc-licensed-product')]);
}
$order = wc_get_order($orderId);
if (!$order) {
wp_send_json_error(['message' => __('Order not found.', 'wc-licensed-product')]);
}
// Check if order is paid
if (!$order->is_paid()) {
wp_send_json_error(['message' => __('Order must be paid before licenses can be generated.', 'wc-licensed-product')]);
}
// Get domain
$domain = $order->get_meta('_licensed_product_domain');
if (empty($domain)) {
wp_send_json_error(['message' => __('Please set the order domain before generating licenses.', 'wc-licensed-product')]);
}
// Generate licenses for each licensed product
$generated = 0;
$skipped = 0;
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if ($product && $product->is_type('licensed')) {
$license = $this->licenseManager->generateLicense(
$orderId,
$product->get_id(),
$order->get_customer_id(),
$domain
);
if ($license) {
// Check if this is a new license or existing
$existingLicenses = $this->licenseManager->getLicensesByOrder($orderId);
$isNew = true;
foreach ($existingLicenses as $existing) {
if ($existing->getProductId() === $product->get_id() && $existing->getId() !== $license->getId()) {
$isNew = false;
break;
}
}
if ($isNew) {
$generated++;
} else {
$skipped++;
}
}
}
}
if ($generated > 0) {
wp_send_json_success([
'message' => sprintf(
/* translators: %d: Number of licenses generated */
_n(
'%d license generated successfully.',
'%d licenses generated successfully.',
$generated,
'wc-licensed-product'
),
$generated
),
'generated' => $generated,
'skipped' => $skipped,
'reload' => true,
]);
} else {
wp_send_json_success([
'message' => __('All licenses already exist for this order.', 'wc-licensed-product'),
'generated' => 0,
'skipped' => $skipped,
'reload' => false,
]);
}
}
} }

View File

@@ -3,7 +3,7 @@
* Plugin Name: WooCommerce Licensed Product * Plugin Name: WooCommerce Licensed Product
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-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. * Description: WooCommerce plugin to sell software products using license keys with domain-based validation.
* Version: 0.3.7 * Version: 0.3.9
* Author: Marco Graetsch * Author: Marco Graetsch
* Author URI: https://src.bundespruefstelle.ch/magdev * Author URI: https://src.bundespruefstelle.ch/magdev
* License: GPL-2.0-or-later * License: GPL-2.0-or-later
@@ -28,7 +28,7 @@ if (!defined('ABSPATH')) {
} }
// Plugin constants // Plugin constants
define('WC_LICENSED_PRODUCT_VERSION', '0.3.7'); define('WC_LICENSED_PRODUCT_VERSION', '0.3.9');
define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__); define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__);
define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__)); define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));