Dashboard widget improvements and download counter feature (v0.3.7)

- Fixed: Dashboard widget "View All Licenses" link used wrong page slug
- Fixed: Download links in customer account resulted in 404 errors
- Removed: Redundant "Status Breakdown" section from dashboard widget
- Changed: License Types section now uses card style layout
- Added: Download counter for licensed product versions
- Added: Download Statistics admin dashboard widget
- Updated translations (356 strings)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-24 10:17:46 +01:00
parent 202f8a6dc0
commit 034593f896
11 changed files with 937 additions and 721 deletions

View File

@@ -38,7 +38,12 @@ No known bugs at the moment.
### Version 0.3.7 ### Version 0.3.7
No changes at the moment. - Fixed: Dashboard widget "View All Licenses" link used wrong page slug
- 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

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: \n" "Report-Msgid-Bugs-To: magdev3.0@gmail.com\n"
"POT-Creation-Date: 2026-01-23 21:09+0100\n" "POT-Creation-Date: 2026-01-24 10:11+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"
@@ -97,8 +97,9 @@ msgstr "Produkt"
msgid "Domain" msgid "Domain"
msgstr "Domain" msgstr "Domain"
#: src/Admin/OrderLicenseController.php:147 src/Admin/AdminController.php:1295 #: src/Admin/OrderLicenseController.php:147
#: src/Admin/AdminController.php:1446 src/Admin/VersionAdminController.php:140 #: src/Admin/VersionAdminController.php:140 src/Admin/AdminController.php:1295
#: src/Admin/AdminController.php:1446
msgid "Status" msgid "Status"
msgstr "Status" msgstr "Status"
@@ -108,8 +109,9 @@ msgstr "Status"
msgid "Expires" msgid "Expires"
msgstr "Läuft ab" msgstr "Läuft ab"
#: src/Admin/OrderLicenseController.php:149 src/Admin/AdminController.php:1298 #: src/Admin/OrderLicenseController.php:149
#: src/Admin/AdminController.php:1449 src/Admin/VersionAdminController.php:142 #: src/Admin/VersionAdminController.php:142 src/Admin/AdminController.php:1298
#: src/Admin/AdminController.php:1449
msgid "Actions" msgid "Actions"
msgstr "Aktionen" msgstr "Aktionen"
@@ -130,9 +132,11 @@ msgid "Cancel"
msgstr "Abbrechen" msgstr "Abbrechen"
#: src/Admin/OrderLicenseController.php:201 #: src/Admin/OrderLicenseController.php:201
#: src/Admin/SettingsController.php:192 src/Admin/AdminController.php:151 #: src/Admin/SettingsController.php:192
#: src/Admin/AdminController.php:266 src/Admin/AdminController.php:1373 #: src/Admin/DashboardWidgetController.php:136
#: src/Admin/AdminController.php:1613 src/Product/LicensedProductType.php:110 #: 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:158 #: src/Product/LicensedProductType.php:158
msgid "Lifetime" msgid "Lifetime"
msgstr "Lebenslang" msgstr "Lebenslang"
@@ -141,7 +145,6 @@ msgstr "Lebenslang"
msgid "View in Licenses" msgid "View in Licenses"
msgstr "In Lizenzen anzeigen" msgstr "In Lizenzen anzeigen"
#. translators: %s: Link to licenses page
#: src/Admin/OrderLicenseController.php:221 #: src/Admin/OrderLicenseController.php:221
#, 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."
@@ -168,12 +171,13 @@ 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:301
#: src/Admin/OrderLicenseController.php:340 src/Admin/AdminController.php:173 #: src/Admin/OrderLicenseController.php:340
#: src/Admin/VersionAdminController.php:259
#: src/Admin/VersionAdminController.php:328
#: src/Admin/VersionAdminController.php:354 src/Admin/AdminController.php:173
#: src/Admin/AdminController.php:213 src/Admin/AdminController.php:249 #: src/Admin/AdminController.php:213 src/Admin/AdminController.php:249
#: src/Admin/AdminController.php:301 src/Admin/AdminController.php:339 #: src/Admin/AdminController.php:301 src/Admin/AdminController.php:339
#: src/Admin/AdminController.php:369 src/Admin/VersionAdminController.php:259 #: src/Admin/AdminController.php:369
#: src/Admin/VersionAdminController.php:328
#: src/Admin/VersionAdminController.php:354
msgid "Permission denied." msgid "Permission denied."
msgstr "Zugriff verweigert." msgstr "Zugriff verweigert."
@@ -201,7 +205,7 @@ 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:363
#: src/Frontend/DownloadController.php:105 #: src/Frontend/DownloadController.php:117
#: src/Frontend/AccountController.php:352 #: src/Frontend/AccountController.php:352
msgid "License not found." msgid "License not found."
msgstr "Lizenz nicht gefunden." msgstr "Lizenz nicht gefunden."
@@ -310,13 +314,15 @@ msgstr ""
msgid "Expiration Warning Schedule" msgid "Expiration Warning Schedule"
msgstr "Ablaufwarnung Zeitplan" msgstr "Ablaufwarnung Zeitplan"
#. translators: %s: URL to WooCommerce email settings
#: src/Admin/SettingsController.php:223 #: src/Admin/SettingsController.php:223
#, php-format #, php-format
msgid "" 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."
@@ -389,6 +395,242 @@ msgstr "Lizenz erfolgreich überprüft!"
msgid "License validation failed." msgid "License validation failed."
msgstr "Lizenzvalidierung fehlgeschlagen." msgstr "Lizenzvalidierung fehlgeschlagen."
#: src/Admin/VersionAdminController.php:58
msgid "Product Versions"
msgstr "Produktversionen"
#: src/Admin/VersionAdminController.php:78
msgid "Add New Version"
msgstr "Neue Version hinzufügen"
#: src/Admin/VersionAdminController.php:81
#: src/Admin/VersionAdminController.php:136 src/Admin/AdminController.php:1609
msgid "Version"
msgstr "Version"
#: src/Admin/VersionAdminController.php:84
msgid "Use semantic versioning (e.g., 1.0.0)"
msgstr "Verwenden Sie semantische Versionierung (z.B. 1.0.0)"
#: src/Admin/VersionAdminController.php:88
#: src/Admin/VersionAdminController.php:137
msgid "Download File"
msgstr "Download-Datei"
#: src/Admin/VersionAdminController.php:93
msgid "Select File"
msgstr "Datei auswählen"
#: src/Admin/VersionAdminController.php:96
#: src/Admin/VersionAdminController.php:110
msgid "Remove"
msgstr "Entfernen"
#: src/Admin/VersionAdminController.php:98
msgid ""
"Upload or select a file from the media library. Version will be auto-"
"detected from filename (e.g., plugin-v1.2.3.zip)."
msgstr ""
"Laden Sie eine Datei hoch oder wählen Sie eine aus der Mediathek. Die "
"Version wird automatisch aus dem Dateinamen erkannt (z.B. plugin-v1.2.3.zip)."
#: src/Admin/VersionAdminController.php:102
msgid "Checksum File"
msgstr "Prüfsummendatei"
#: src/Admin/VersionAdminController.php:107
msgid "Select Checksum File"
msgstr "Prüfsummendatei auswählen"
#: src/Admin/VersionAdminController.php:112
msgid ""
"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity."
msgstr ""
"Laden Sie eine SHA256-Prüfsummendatei (.sha256 oder .txt) hoch, um die "
"Dateiintegrität zu überprüfen."
#: src/Admin/VersionAdminController.php:116
#: src/Admin/VersionAdminController.php:139
msgid "Release Notes"
msgstr "Versionshinweise"
#: src/Admin/VersionAdminController.php:124
msgid "Add Version"
msgstr "Version hinzufügen"
#: src/Admin/VersionAdminController.php:132
msgid "Existing Versions"
msgstr "Vorhandene Versionen"
#: src/Admin/VersionAdminController.php:138
msgid "SHA256"
msgstr "SHA256"
#: src/Admin/VersionAdminController.php:141
msgid "Released"
msgstr "Veröffentlicht"
#: src/Admin/VersionAdminController.php:148
msgid "No versions found. Add your first version above."
msgstr "Keine Versionen gefunden. Fügen Sie Ihre erste Version oben hinzu."
#: src/Admin/VersionAdminController.php:165
#: src/Admin/VersionAdminController.php:396
msgid "Uploaded file"
msgstr "Hochgeladene Datei"
#: src/Admin/VersionAdminController.php:169
#: src/Admin/VersionAdminController.php:400
msgid "No download file"
msgstr "Keine Download-Datei"
#: src/Admin/VersionAdminController.php:182
#: src/Admin/VersionAdminController.php:413
#: 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"
msgstr "Aktiv"
#: src/Admin/VersionAdminController.php:182
#: src/Admin/VersionAdminController.php:413 src/Admin/AdminController.php:157
#: src/Admin/AdminController.php:914 src/Admin/AdminController.php:1233
#: src/Admin/AdminController.php:1356
msgid "Inactive"
msgstr "Inaktiv"
#: src/Admin/VersionAdminController.php:188
#: src/Admin/VersionAdminController.php:419 src/Admin/AdminController.php:1274
#: src/Admin/AdminController.php:1459
msgid "Deactivate"
msgstr "Deaktivieren"
#: src/Admin/VersionAdminController.php:188
#: src/Admin/VersionAdminController.php:419 src/Admin/AdminController.php:1273
#: src/Admin/AdminController.php:1458
msgid "Activate"
msgstr "Aktivieren"
#: src/Admin/VersionAdminController.php:191
#: src/Admin/VersionAdminController.php:422 src/Admin/AdminController.php:1279
#: src/Admin/AdminController.php:1428 src/Admin/AdminController.php:1464
msgid "Delete"
msgstr "Löschen"
#: src/Admin/VersionAdminController.php:232
msgid "Are you sure you want to delete this version?"
msgstr "Sind Sie sicher, dass Sie diese Version löschen möchten?"
#: src/Admin/VersionAdminController.php:233
msgid "Please enter a version number."
msgstr "Bitte geben Sie eine Versionsnummer ein."
#: src/Admin/VersionAdminController.php:234
msgid "Please enter a valid version number (e.g., 1.0.0)."
msgstr "Bitte geben Sie eine gültige Versionsnummer ein (z.B. 1.0.0)."
#: src/Admin/VersionAdminController.php:235
msgid "An error occurred. Please try again."
msgstr "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut."
#: src/Admin/VersionAdminController.php:236
msgid "Select Download File"
msgstr "Download-Datei auswählen"
#: src/Admin/VersionAdminController.php:237
msgid "Use this file"
msgstr "Diese Datei verwenden"
#: src/Admin/VersionAdminController.php:238
msgid ""
"Invalid checksum file format. File must contain a 64-character SHA256 hash."
msgstr ""
"Ungültiges Prüfsummendateiformat. Die Datei muss einen 64-stelligen SHA256-"
"Hash enthalten."
#: src/Admin/VersionAdminController.php:239
msgid "Failed to read checksum file."
msgstr "Prüfsummendatei konnte nicht gelesen werden."
#: src/Admin/VersionAdminController.php:269
msgid "Product ID and version are required."
msgstr "Produkt-ID und Version sind erforderlich."
#: src/Admin/VersionAdminController.php:274
msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)."
msgstr ""
"Ungültiges Versionsformat. Verwenden Sie semantische Versionierung (z.B. "
"1.0.0)."
#: src/Admin/VersionAdminController.php:279
msgid "This version already exists."
msgstr "Diese Version existiert bereits."
#: src/Admin/VersionAdminController.php:285
msgid "Product not found."
msgstr "Produkt nicht gefunden."
#: src/Admin/VersionAdminController.php:289
msgid "This product is not a licensed product."
msgstr "Dieses Produkt ist kein lizensiertes Produkt."
#: src/Admin/VersionAdminController.php:306
msgid "Failed to create version."
msgstr "Version konnte nicht erstellt werden."
#: src/Admin/VersionAdminController.php:314
msgid "Version added successfully."
msgstr "Version erfolgreich hinzugefügt."
#: src/Admin/VersionAdminController.php:334
#: src/Admin/VersionAdminController.php:361
msgid "Version ID is required."
msgstr "Versions-ID ist erforderlich."
#: src/Admin/VersionAdminController.php:340
msgid "Failed to delete version."
msgstr "Version konnte nicht gelöscht werden."
#: src/Admin/VersionAdminController.php:343
msgid "Version deleted successfully."
msgstr "Version erfolgreich gelöscht."
#: src/Admin/VersionAdminController.php:367
msgid "Failed to update version."
msgstr "Version konnte nicht aktualisiert werden."
#: src/Admin/VersionAdminController.php:371
msgid "Version updated successfully."
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"
@@ -433,28 +675,6 @@ msgstr "Kopiert!"
msgid "Copy failed" msgid "Copy failed"
msgstr "Kopieren fehlgeschlagen" msgstr "Kopieren fehlgeschlagen"
#: src/Admin/AdminController.php:156 src/Admin/AdminController.php:907
#: src/Admin/AdminController.php:1232 src/Admin/AdminController.php:1355
#: src/Admin/VersionAdminController.php:182
#: src/Admin/VersionAdminController.php:413
#: src/Admin/DashboardWidgetController.php:151
msgid "Active"
msgstr "Aktiv"
#: src/Admin/AdminController.php:157 src/Admin/AdminController.php:914
#: src/Admin/AdminController.php:1233 src/Admin/AdminController.php:1356
#: src/Admin/VersionAdminController.php:182
#: src/Admin/VersionAdminController.php:413
msgid "Inactive"
msgstr "Inaktiv"
#: src/Admin/AdminController.php:158 src/Admin/AdminController.php:921
#: src/Admin/AdminController.php:1234 src/Admin/AdminController.php:1357
#: src/Admin/DashboardWidgetController.php:159
#: 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"
@@ -537,11 +757,6 @@ 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:147
msgid "Total Licenses"
msgstr "Lizenzen insgesamt"
#: src/Admin/AdminController.php:937 #: src/Admin/AdminController.php:937
msgid "Attention:" msgid "Attention:"
msgstr "Achtung:" msgstr "Achtung:"
@@ -589,7 +804,6 @@ msgstr "Lizenz erfolgreich verlängert."
msgid "License set to lifetime successfully." msgid "License set to lifetime successfully."
msgstr "Lizenz erfolgreich auf lebenslang gesetzt." msgstr "Lizenz erfolgreich auf lebenslang gesetzt."
#. translators: %d: number of licenses
#: src/Admin/AdminController.php:1106 #: src/Admin/AdminController.php:1106
#, php-format #, php-format
msgid "%d license activated." msgid "%d license activated."
@@ -597,7 +811,6 @@ msgid_plural "%d licenses activated."
msgstr[0] "%d Lizenz aktiviert." msgstr[0] "%d Lizenz aktiviert."
msgstr[1] "%d Lizenzen aktiviert." msgstr[1] "%d Lizenzen aktiviert."
#. translators: %d: number of licenses
#: src/Admin/AdminController.php:1114 #: src/Admin/AdminController.php:1114
#, php-format #, php-format
msgid "%d license deactivated." msgid "%d license deactivated."
@@ -605,7 +818,6 @@ msgid_plural "%d licenses deactivated."
msgstr[0] "%d Lizenz deaktiviert." msgstr[0] "%d Lizenz deaktiviert."
msgstr[1] "%d Lizenzen deaktiviert." msgstr[1] "%d Lizenzen deaktiviert."
#. translators: %d: number of licenses
#: src/Admin/AdminController.php:1122 #: src/Admin/AdminController.php:1122
#, php-format #, php-format
msgid "%d license revoked." msgid "%d license revoked."
@@ -613,7 +825,6 @@ msgid_plural "%d licenses revoked."
msgstr[0] "%d Lizenz widerrufen." msgstr[0] "%d Lizenz widerrufen."
msgstr[1] "%d Lizenzen widerrufen." msgstr[1] "%d Lizenzen widerrufen."
#. translators: %d: number of licenses
#: src/Admin/AdminController.php:1130 #: src/Admin/AdminController.php:1130
#, php-format #, php-format
msgid "%d license deleted." msgid "%d license deleted."
@@ -621,7 +832,6 @@ msgid_plural "%d licenses deleted."
msgstr[0] "%d Lizenz gelöscht." msgstr[0] "%d Lizenz gelöscht."
msgstr[1] "%d Lizenzen gelöscht." msgstr[1] "%d Lizenzen gelöscht."
#. translators: %d: number of licenses
#: src/Admin/AdminController.php:1138 #: src/Admin/AdminController.php:1138
#, php-format #, php-format
msgid "%d license extended." msgid "%d license extended."
@@ -643,7 +853,6 @@ msgstr ""
msgid "No licenses to export." msgid "No licenses to export."
msgstr "Keine Lizenzen zum Exportieren." msgstr "Keine Lizenzen zum Exportieren."
#. translators: %d: number of licenses imported
#: src/Admin/AdminController.php:1159 #: src/Admin/AdminController.php:1159
#, php-format #, php-format
msgid "%d license imported." msgid "%d license imported."
@@ -651,7 +860,6 @@ msgid_plural "%d licenses imported."
msgstr[0] "%d Lizenz importiert." msgstr[0] "%d Lizenz importiert."
msgstr[1] "%d Lizenzen importiert." msgstr[1] "%d Lizenzen importiert."
#. translators: %d: number of licenses updated
#: src/Admin/AdminController.php:1166 #: src/Admin/AdminController.php:1166
#, php-format #, php-format
msgid "%d updated." msgid "%d updated."
@@ -659,7 +867,6 @@ msgid_plural "%d updated."
msgstr[0] "%d aktualisiert." msgstr[0] "%d aktualisiert."
msgstr[1] "%d aktualisiert." msgstr[1] "%d aktualisiert."
#. translators: %d: number of licenses skipped
#: src/Admin/AdminController.php:1174 #: src/Admin/AdminController.php:1174
#, php-format #, php-format
msgid "%d skipped." msgid "%d skipped."
@@ -667,7 +874,6 @@ msgid_plural "%d skipped."
msgstr[0] "%d übersprungen." msgstr[0] "%d übersprungen."
msgstr[1] "%d übersprungen." msgstr[1] "%d übersprungen."
#. translators: %d: number of errors
#: src/Admin/AdminController.php:1182 #: src/Admin/AdminController.php:1182
#, php-format #, php-format
msgid "%d error." msgid "%d error."
@@ -743,18 +949,6 @@ msgstr "Dashboard anzeigen"
msgid "Bulk Actions" msgid "Bulk Actions"
msgstr "Massenaktionen" msgstr "Massenaktionen"
#: src/Admin/AdminController.php:1273 src/Admin/AdminController.php:1458
#: src/Admin/VersionAdminController.php:188
#: src/Admin/VersionAdminController.php:419
msgid "Activate"
msgstr "Aktivieren"
#: src/Admin/AdminController.php:1274 src/Admin/AdminController.php:1459
#: src/Admin/VersionAdminController.php:188
#: src/Admin/VersionAdminController.php:419
msgid "Deactivate"
msgstr "Deaktivieren"
#: src/Admin/AdminController.php:1275 src/Admin/AdminController.php:1419 #: src/Admin/AdminController.php:1275 src/Admin/AdminController.php:1419
#: src/Admin/AdminController.php:1460 #: src/Admin/AdminController.php:1460
msgid "Revoke" msgid "Revoke"
@@ -772,12 +966,6 @@ msgstr "90 Tage verlängern"
msgid "Extend 1 year" msgid "Extend 1 year"
msgstr "1 Jahr verlängern" msgstr "1 Jahr verlängern"
#: src/Admin/AdminController.php:1279 src/Admin/AdminController.php:1428
#: src/Admin/AdminController.php:1464 src/Admin/VersionAdminController.php:191
#: src/Admin/VersionAdminController.php:422
msgid "Delete"
msgstr "Löschen"
#: src/Admin/AdminController.php:1281 src/Admin/AdminController.php:1466 #: src/Admin/AdminController.php:1281 src/Admin/AdminController.php:1466
msgid "Apply" msgid "Apply"
msgstr "Anwenden" msgstr "Anwenden"
@@ -872,11 +1060,6 @@ msgstr "Lizenz übertragen"
msgid "License is VALID" msgid "License is VALID"
msgstr "Lizenz ist GÜLTIG" msgstr "Lizenz ist GÜLTIG"
#: src/Admin/AdminController.php:1609 src/Admin/VersionAdminController.php:81
#: src/Admin/VersionAdminController.php:136
msgid "Version"
msgstr "Version"
#: src/Admin/AdminController.php:1617 #: src/Admin/AdminController.php:1617
msgid "License is INVALID" msgid "License is INVALID"
msgstr "Lizenz ist UNGÜLTIG" msgstr "Lizenz ist UNGÜLTIG"
@@ -997,225 +1180,26 @@ msgstr "Lizenz"
msgid "No domain specified" msgid "No domain specified"
msgstr "Keine Domain angegeben" msgstr "Keine Domain angegeben"
#: src/Admin/VersionAdminController.php:58 #: src/Admin/DownloadWidgetController.php:46
msgid "Product Versions" msgid "Download Statistics"
msgstr "Produktversionen" msgstr "Download-Statistiken"
#: src/Admin/VersionAdminController.php:78 #: src/Admin/DownloadWidgetController.php:140
msgid "Add New Version" msgid "Total Downloads"
msgstr "Neue Version hinzufügen" msgstr "Gesamte Downloads"
#: src/Admin/VersionAdminController.php:84 #: src/Admin/DownloadWidgetController.php:145
msgid "Use semantic versioning (e.g., 1.0.0)" msgid "Top Products"
msgstr "Verwenden Sie semantische Versionierung (z.B. 1.0.0)" msgstr "Top-Produkte"
#: src/Admin/VersionAdminController.php:88 #: src/Admin/DownloadWidgetController.php:159
#: src/Admin/VersionAdminController.php:137 #: src/Admin/DownloadWidgetController.php:180
msgid "Download File" msgid "No downloads yet"
msgstr "Download-Datei" msgstr "Noch keine Downloads"
#: src/Admin/VersionAdminController.php:93 #: src/Admin/DownloadWidgetController.php:163
msgid "Select File" msgid "Top Versions"
msgstr "Datei auswählen" msgstr "Top-Versionen"
#: src/Admin/VersionAdminController.php:96
#: src/Admin/VersionAdminController.php:110
msgid "Remove"
msgstr "Entfernen"
#: src/Admin/VersionAdminController.php:98
msgid ""
"Upload or select a file from the media library. Version will be auto-"
"detected from filename (e.g., plugin-v1.2.3.zip)."
msgstr ""
"Laden Sie eine Datei hoch oder wählen Sie eine aus der Mediathek. Die "
"Version wird automatisch aus dem Dateinamen erkannt (z.B. plugin-v1.2.3.zip)."
#: src/Admin/VersionAdminController.php:102
msgid "Checksum File"
msgstr "Prüfsummendatei"
#: src/Admin/VersionAdminController.php:107
msgid "Select Checksum File"
msgstr "Prüfsummendatei auswählen"
#: src/Admin/VersionAdminController.php:112
msgid ""
"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity."
msgstr ""
"Laden Sie eine SHA256-Prüfsummendatei (.sha256 oder .txt) hoch, um die "
"Dateiintegrität zu überprüfen."
#: src/Admin/VersionAdminController.php:116
#: src/Admin/VersionAdminController.php:139
msgid "Release Notes"
msgstr "Versionshinweise"
#: src/Admin/VersionAdminController.php:124
msgid "Add Version"
msgstr "Version hinzufügen"
#: src/Admin/VersionAdminController.php:132
msgid "Existing Versions"
msgstr "Vorhandene Versionen"
#: src/Admin/VersionAdminController.php:138
msgid "SHA256"
msgstr "SHA256"
#: src/Admin/VersionAdminController.php:141
msgid "Released"
msgstr "Veröffentlicht"
#: src/Admin/VersionAdminController.php:148
msgid "No versions found. Add your first version above."
msgstr "Keine Versionen gefunden. Fügen Sie Ihre erste Version oben hinzu."
#: src/Admin/VersionAdminController.php:165
#: src/Admin/VersionAdminController.php:396
msgid "Uploaded file"
msgstr "Hochgeladene Datei"
#: src/Admin/VersionAdminController.php:169
#: src/Admin/VersionAdminController.php:400
msgid "No download file"
msgstr "Keine Download-Datei"
#: src/Admin/VersionAdminController.php:232
msgid "Are you sure you want to delete this version?"
msgstr "Sind Sie sicher, dass Sie diese Version löschen möchten?"
#: src/Admin/VersionAdminController.php:233
msgid "Please enter a version number."
msgstr "Bitte geben Sie eine Versionsnummer ein."
#: src/Admin/VersionAdminController.php:234
msgid "Please enter a valid version number (e.g., 1.0.0)."
msgstr "Bitte geben Sie eine gültige Versionsnummer ein (z.B. 1.0.0)."
#: src/Admin/VersionAdminController.php:235
msgid "An error occurred. Please try again."
msgstr "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut."
#: src/Admin/VersionAdminController.php:236
msgid "Select Download File"
msgstr "Download-Datei auswählen"
#: src/Admin/VersionAdminController.php:237
msgid "Use this file"
msgstr "Diese Datei verwenden"
#: src/Admin/VersionAdminController.php:238
msgid ""
"Invalid checksum file format. File must contain a 64-character SHA256 hash."
msgstr ""
"Ungültiges Prüfsummendateiformat. Die Datei muss einen 64-stelligen SHA256-"
"Hash enthalten."
#: src/Admin/VersionAdminController.php:239
msgid "Failed to read checksum file."
msgstr "Prüfsummendatei konnte nicht gelesen werden."
#: src/Admin/VersionAdminController.php:269
msgid "Product ID and version are required."
msgstr "Produkt-ID und Version sind erforderlich."
#: src/Admin/VersionAdminController.php:274
msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)."
msgstr ""
"Ungültiges Versionsformat. Verwenden Sie semantische Versionierung (z.B. "
"1.0.0)."
#: src/Admin/VersionAdminController.php:279
msgid "This version already exists."
msgstr "Diese Version existiert bereits."
#: src/Admin/VersionAdminController.php:285
msgid "Product not found."
msgstr "Produkt nicht gefunden."
#: src/Admin/VersionAdminController.php:289
msgid "This product is not a licensed product."
msgstr "Dieses Produkt ist kein lizensiertes Produkt."
#: src/Admin/VersionAdminController.php:306
msgid "Failed to create version."
msgstr "Version konnte nicht erstellt werden."
#: src/Admin/VersionAdminController.php:314
msgid "Version added successfully."
msgstr "Version erfolgreich hinzugefügt."
#: src/Admin/VersionAdminController.php:334
#: src/Admin/VersionAdminController.php:361
msgid "Version ID is required."
msgstr "Versions-ID ist erforderlich."
#: src/Admin/VersionAdminController.php:340
msgid "Failed to delete version."
msgstr "Version konnte nicht gelöscht werden."
#: src/Admin/VersionAdminController.php:343
msgid "Version deleted successfully."
msgstr "Version erfolgreich gelöscht."
#: src/Admin/VersionAdminController.php:367
msgid "Failed to update version."
msgstr "Version konnte nicht aktualisiert werden."
#: src/Admin/VersionAdminController.php:371
msgid "Version updated successfully."
msgstr "Version erfolgreich aktualisiert."
#: src/Admin/DashboardWidgetController.php:47
msgid "License Statistics"
msgstr "Lizenzstatistiken"
#: src/Admin/DashboardWidgetController.php:155
msgid "Expiring Soon"
msgstr "Bald ablaufend"
#: src/Admin/DashboardWidgetController.php:166
msgid "Status Breakdown"
msgstr "Statusübersicht"
#: src/Admin/DashboardWidgetController.php:172
#, php-format
msgid "Active: %d"
msgstr "Aktiv: %d"
#: src/Admin/DashboardWidgetController.php:179
#, php-format
msgid "Inactive: %d"
msgstr "Inaktiv: %d"
#: src/Admin/DashboardWidgetController.php:186
#, php-format
msgid "Expired: %d"
msgstr "Abgelaufen: %d"
#: src/Admin/DashboardWidgetController.php:193
#, php-format
msgid "Revoked: %d"
msgstr "Widerrufen: %d"
#: src/Admin/DashboardWidgetController.php:202
msgid "License Types"
msgstr "Lizenztypen"
#: src/Admin/DashboardWidgetController.php:207
#, php-format
msgid "Time-limited: %d"
msgstr "Zeitlich begrenzt: %d"
#: src/Admin/DashboardWidgetController.php:213
#, php-format
msgid "Lifetime: %d"
msgstr "Lebenslang: %d"
#: src/Admin/DashboardWidgetController.php:220
msgid "View All Licenses"
msgstr "Alle Lizenzen anzeigen"
#: src/Api/RestApiController.php:84 #: src/Api/RestApiController.php:84
msgid "Too many requests. Please try again later." msgid "Too many requests. Please try again later."
@@ -1314,7 +1298,8 @@ msgstr "Diese Lizenz ist inaktiv."
msgid "This license is not valid for this domain." msgid "This license is not valid for this domain."
msgstr "Diese Lizenz ist für diese Domain nicht gültig." msgstr "Diese Lizenz ist für diese Domain nicht gültig."
#: src/License/LicenseManager.php:760 src/Frontend/AccountController.php:140 #: src/License/LicenseManager.php:760 src/Product/VersionManager.php:349
#: src/Product/VersionManager.php:361 src/Frontend/AccountController.php:140
#: src/Email/LicenseExpirationEmail.php:107 #: src/Email/LicenseExpirationEmail.php:107
#: src/Email/LicenseExpiredEmail.php:99 #: src/Email/LicenseExpiredEmail.php:99
msgid "Unknown Product" msgid "Unknown Product"
@@ -1324,7 +1309,6 @@ msgstr "Unbekanntes Produkt"
msgid "Attachment file not found." msgid "Attachment file not found."
msgstr "Anhangs-Datei nicht gefunden." msgstr "Anhangs-Datei nicht gefunden."
#. translators: 1: provided hash, 2: calculated hash
#: src/Product/VersionManager.php:177 #: src/Product/VersionManager.php:177
#, php-format #, php-format
msgid "File checksum does not match. Expected: %1$s, Got: %2$s" msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
@@ -1343,7 +1327,6 @@ msgstr "Lizenz-Einstellungen"
msgid "%d days" msgid "%d days"
msgstr "%d Tage" msgstr "%d Tage"
#. translators: %s: URL to settings page
#: src/Product/LicensedProductType.php:119 #: src/Product/LicensedProductType.php:119
#, php-format #, php-format
msgid "Leave fields empty to use default settings from %s." msgid "Leave fields empty to use default settings from %s."
@@ -1357,7 +1340,6 @@ msgstr "WooCommerce > Einstellungen > Lizensierte Produkte"
msgid "Max Activations" msgid "Max Activations"
msgstr "Max. Aktivierungen" msgstr "Max. Aktivierungen"
#. translators: %d: default max activations value
#: src/Product/LicensedProductType.php:131 #: src/Product/LicensedProductType.php:131
#, php-format #, php-format
msgid "Maximum number of domain activations per license. Default: %d" msgid "Maximum number of domain activations per license. Default: %d"
@@ -1367,7 +1349,6 @@ msgstr "Maximale Anzahl der Domain-Aktivierungen pro Lizenz. Standard: %d"
msgid "License Validity (Days)" msgid "License Validity (Days)"
msgstr "Lizenz-Gültigkeit (Tage)" msgstr "Lizenz-Gültigkeit (Tage)"
#. translators: %s: default validity value
#: src/Product/LicensedProductType.php:149 #: src/Product/LicensedProductType.php:149
#, php-format #, php-format
msgid "Number of days the license is valid. Leave empty for default (%s)." msgid "Number of days the license is valid. Leave empty for default (%s)."
@@ -1377,7 +1358,6 @@ msgstr "Anzahl Tage, die die Lizenz gültig ist. Leer lassen für Standard (%s).
msgid "Bind to Major Version" msgid "Bind to Major Version"
msgstr "An Hauptversion binden" msgstr "An Hauptversion binden"
#. translators: %s: default bind to version value (Yes/No)
#: src/Product/LicensedProductType.php:167 #: src/Product/LicensedProductType.php:167
#, php-format #, php-format
msgid "" msgid ""
@@ -1399,54 +1379,54 @@ msgstr "Nein"
msgid "Version:" msgid "Version:"
msgstr "Version:" msgstr "Version:"
#: src/Frontend/DownloadController.php:65 #: src/Frontend/DownloadController.php:77
#: src/Frontend/DownloadController.php:89 #: src/Frontend/DownloadController.php:101
msgid "Invalid download link." msgid "Invalid download link."
msgstr "Ungültiger Download-Link." msgstr "Ungültiger Download-Link."
#: src/Frontend/DownloadController.php:66 #: src/Frontend/DownloadController.php:78
#: src/Frontend/DownloadController.php:76 #: src/Frontend/DownloadController.php:88
#: src/Frontend/DownloadController.php:90 #: src/Frontend/DownloadController.php:102
#: src/Frontend/DownloadController.php:106 #: src/Frontend/DownloadController.php:118
#: src/Frontend/DownloadController.php:116 #: src/Frontend/DownloadController.php:128
#: src/Frontend/DownloadController.php:125 #: src/Frontend/DownloadController.php:137
#: src/Frontend/DownloadController.php:135 #: src/Frontend/DownloadController.php:147
#: src/Frontend/DownloadController.php:144 #: src/Frontend/DownloadController.php:156
#: src/Frontend/DownloadController.php:153 #: src/Frontend/DownloadController.php:165
#: src/Frontend/DownloadController.php:171
#: src/Frontend/DownloadController.php:187 #: src/Frontend/DownloadController.php:187
#: src/Frontend/DownloadController.php:203
msgid "Download Error" msgid "Download Error"
msgstr "Download-Fehler" msgstr "Download-Fehler"
#: src/Frontend/DownloadController.php:75 #: src/Frontend/DownloadController.php:87
msgid "Invalid download link format." msgid "Invalid download link format."
msgstr "Ungültiges Download-Link-Format." msgstr "Ungültiges Download-Link-Format."
#: src/Frontend/DownloadController.php:115 #: src/Frontend/DownloadController.php:127
msgid "You do not have permission to download this file." msgid "You do not have permission to download this file."
msgstr "Sie haben keine Berechtigung, diese Datei herunterzuladen." msgstr "Sie haben keine Berechtigung, diese Datei herunterzuladen."
#: src/Frontend/DownloadController.php:124 #: src/Frontend/DownloadController.php:136
msgid "Your license is not active. Please contact support." msgid "Your license is not active. Please contact support."
msgstr "Ihre Lizenz ist nicht aktiv. Bitte kontaktieren Sie den Support." msgstr "Ihre Lizenz ist nicht aktiv. Bitte kontaktieren Sie den Support."
#: src/Frontend/DownloadController.php:134 #: src/Frontend/DownloadController.php:146
msgid "Version not found." msgid "Version not found."
msgstr "Version nicht gefunden." msgstr "Version nicht gefunden."
#: src/Frontend/DownloadController.php:143 #: src/Frontend/DownloadController.php:155
msgid "Version does not match your licensed product." msgid "Version does not match your licensed product."
msgstr "Version stimmt nicht mit Ihrem lizensierten Produkt überein." msgstr "Version stimmt nicht mit Ihrem lizensierten Produkt überein."
#: src/Frontend/DownloadController.php:152 #: src/Frontend/DownloadController.php:164
msgid "This version is no longer available for download." msgid "This version is no longer available for download."
msgstr "Diese Version ist nicht mehr zum Download verfügbar." msgstr "Diese Version ist nicht mehr zum Download verfügbar."
#: src/Frontend/DownloadController.php:170 #: src/Frontend/DownloadController.php:186
msgid "No download file available for this version." msgid "No download file available for this version."
msgstr "Keine Download-Datei für diese Version verfügbar." msgstr "Keine Download-Datei für diese Version verfügbar."
#: src/Frontend/DownloadController.php:186 #: src/Frontend/DownloadController.php:202
msgid "Download file not found." msgid "Download file not found."
msgstr "Download-Datei nicht gefunden." msgstr "Download-Datei nicht gefunden."
@@ -1610,7 +1590,6 @@ msgstr ""
"Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz vor " "Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz vor "
"dem Ablaufdatum." "dem Ablaufdatum."
#. translators: %s: list of placeholders
#: src/Email/LicenseExpirationEmail.php:301 #: src/Email/LicenseExpirationEmail.php:301
#: src/Email/LicenseExpiredEmail.php:288 #: src/Email/LicenseExpiredEmail.php:288
#, php-format #, php-format
@@ -1722,22 +1701,21 @@ msgid "To continue using this product, please renew your license."
msgstr "" msgstr ""
"Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz." "Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz."
#: src/Plugin.php:258 #: src/Plugin.php:260
msgid "WC Licensed Product" msgid "WC Licensed Product"
msgstr "WC Licensed Product" msgstr "WC Licensed Product"
#: src/Plugin.php:259 #: src/Plugin.php:261
msgid "" msgid ""
"Plugin license is not configured or invalid. Frontend features are disabled." "Plugin license is not configured or invalid. Frontend features are disabled."
msgstr "" msgstr ""
"Plugin-Lizenz ist nicht konfiguriert oder ungültig. Frontend-Funktionen sind " "Plugin-Lizenz ist nicht konfiguriert oder ungültig. Frontend-Funktionen sind "
"deaktiviert." "deaktiviert."
#: src/Plugin.php:260 #: src/Plugin.php:262
msgid "Configure License" msgid "Configure License"
msgstr "Lizenz konfigurieren" msgstr "Lizenz konfigurieren"
#. translators: %s: WooCommerce plugin name
#: wc-licensed-product.php:61 #: wc-licensed-product.php:61
#, php-format #, php-format
msgid "%s requires WooCommerce to be installed and active." msgid "%s requires WooCommerce to be installed and active."
@@ -1749,6 +1727,36 @@ 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" #~ msgid "Or External URL"
#~ msgstr "Oder externe URL" #~ msgstr "Oder externe URL"

View File

@@ -1,14 +1,14 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the wc-licensed-product package. # This file is distributed under the same license as the WC Licensed Product package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# #
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: wc-licensed-product 0.3.6\n" "Project-Id-Version: WC Licensed Product 0.3.7\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: magdev3.0@gmail.com\n"
"POT-Creation-Date: 2026-01-23 21:09+0100\n" "POT-Creation-Date: 2026-01-24 10:11+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"
@@ -93,8 +93,9 @@ msgstr ""
msgid "Domain" msgid "Domain"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:147 src/Admin/AdminController.php:1295 #: src/Admin/OrderLicenseController.php:147
#: src/Admin/AdminController.php:1446 src/Admin/VersionAdminController.php:140 #: src/Admin/VersionAdminController.php:140 src/Admin/AdminController.php:1295
#: src/Admin/AdminController.php:1446
msgid "Status" msgid "Status"
msgstr "" msgstr ""
@@ -104,8 +105,9 @@ msgstr ""
msgid "Expires" msgid "Expires"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:149 src/Admin/AdminController.php:1298 #: src/Admin/OrderLicenseController.php:149
#: src/Admin/AdminController.php:1449 src/Admin/VersionAdminController.php:142 #: src/Admin/VersionAdminController.php:142 src/Admin/AdminController.php:1298
#: src/Admin/AdminController.php:1449
msgid "Actions" msgid "Actions"
msgstr "" msgstr ""
@@ -126,9 +128,11 @@ msgid "Cancel"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:201 #: src/Admin/OrderLicenseController.php:201
#: src/Admin/SettingsController.php:192 src/Admin/AdminController.php:151 #: src/Admin/SettingsController.php:192
#: src/Admin/AdminController.php:266 src/Admin/AdminController.php:1373 #: src/Admin/DashboardWidgetController.php:136
#: src/Admin/AdminController.php:1613 src/Product/LicensedProductType.php:110 #: 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:158 #: src/Product/LicensedProductType.php:158
msgid "Lifetime" msgid "Lifetime"
msgstr "" msgstr ""
@@ -137,7 +141,6 @@ msgstr ""
msgid "View in Licenses" msgid "View in Licenses"
msgstr "" msgstr ""
#. translators: %s: Link to licenses page
#: src/Admin/OrderLicenseController.php:221 #: src/Admin/OrderLicenseController.php:221
#, 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."
@@ -162,12 +165,13 @@ msgid "Please enter a valid domain."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:301 #: src/Admin/OrderLicenseController.php:301
#: src/Admin/OrderLicenseController.php:340 src/Admin/AdminController.php:173 #: src/Admin/OrderLicenseController.php:340
#: src/Admin/VersionAdminController.php:259
#: src/Admin/VersionAdminController.php:328
#: src/Admin/VersionAdminController.php:354 src/Admin/AdminController.php:173
#: src/Admin/AdminController.php:213 src/Admin/AdminController.php:249 #: src/Admin/AdminController.php:213 src/Admin/AdminController.php:249
#: src/Admin/AdminController.php:301 src/Admin/AdminController.php:339 #: src/Admin/AdminController.php:301 src/Admin/AdminController.php:339
#: src/Admin/AdminController.php:369 src/Admin/VersionAdminController.php:259 #: src/Admin/AdminController.php:369
#: src/Admin/VersionAdminController.php:328
#: src/Admin/VersionAdminController.php:354
msgid "Permission denied." msgid "Permission denied."
msgstr "" msgstr ""
@@ -195,7 +199,7 @@ msgid "Domain cannot be empty."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:363 #: src/Admin/OrderLicenseController.php:363
#: src/Frontend/DownloadController.php:105 #: src/Frontend/DownloadController.php:117
#: src/Frontend/AccountController.php:352 #: src/Frontend/AccountController.php:352
msgid "License not found." msgid "License not found."
msgstr "" msgstr ""
@@ -294,7 +298,6 @@ msgstr ""
msgid "Expiration Warning Schedule" msgid "Expiration Warning Schedule"
msgstr "" msgstr ""
#. translators: %s: URL to WooCommerce email settings
#: src/Admin/SettingsController.php:223 #: src/Admin/SettingsController.php:223
#, php-format #, php-format
msgid "" msgid ""
@@ -368,6 +371,234 @@ msgstr ""
msgid "License validation failed." msgid "License validation failed."
msgstr "" msgstr ""
#: src/Admin/VersionAdminController.php:58
msgid "Product Versions"
msgstr ""
#: src/Admin/VersionAdminController.php:78
msgid "Add New Version"
msgstr ""
#: src/Admin/VersionAdminController.php:81
#: src/Admin/VersionAdminController.php:136 src/Admin/AdminController.php:1609
msgid "Version"
msgstr ""
#: src/Admin/VersionAdminController.php:84
msgid "Use semantic versioning (e.g., 1.0.0)"
msgstr ""
#: src/Admin/VersionAdminController.php:88
#: src/Admin/VersionAdminController.php:137
msgid "Download File"
msgstr ""
#: src/Admin/VersionAdminController.php:93
msgid "Select File"
msgstr ""
#: src/Admin/VersionAdminController.php:96
#: src/Admin/VersionAdminController.php:110
msgid "Remove"
msgstr ""
#: src/Admin/VersionAdminController.php:98
msgid ""
"Upload or select a file from the media library. Version will be auto-"
"detected from filename (e.g., plugin-v1.2.3.zip)."
msgstr ""
#: src/Admin/VersionAdminController.php:102
msgid "Checksum File"
msgstr ""
#: src/Admin/VersionAdminController.php:107
msgid "Select Checksum File"
msgstr ""
#: src/Admin/VersionAdminController.php:112
msgid ""
"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity."
msgstr ""
#: src/Admin/VersionAdminController.php:116
#: src/Admin/VersionAdminController.php:139
msgid "Release Notes"
msgstr ""
#: src/Admin/VersionAdminController.php:124
msgid "Add Version"
msgstr ""
#: src/Admin/VersionAdminController.php:132
msgid "Existing Versions"
msgstr ""
#: src/Admin/VersionAdminController.php:138
msgid "SHA256"
msgstr ""
#: src/Admin/VersionAdminController.php:141
msgid "Released"
msgstr ""
#: src/Admin/VersionAdminController.php:148
msgid "No versions found. Add your first version above."
msgstr ""
#: src/Admin/VersionAdminController.php:165
#: src/Admin/VersionAdminController.php:396
msgid "Uploaded file"
msgstr ""
#: src/Admin/VersionAdminController.php:169
#: src/Admin/VersionAdminController.php:400
msgid "No download file"
msgstr ""
#: src/Admin/VersionAdminController.php:182
#: src/Admin/VersionAdminController.php:413
#: 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"
msgstr ""
#: src/Admin/VersionAdminController.php:182
#: src/Admin/VersionAdminController.php:413 src/Admin/AdminController.php:157
#: src/Admin/AdminController.php:914 src/Admin/AdminController.php:1233
#: src/Admin/AdminController.php:1356
msgid "Inactive"
msgstr ""
#: src/Admin/VersionAdminController.php:188
#: src/Admin/VersionAdminController.php:419 src/Admin/AdminController.php:1274
#: src/Admin/AdminController.php:1459
msgid "Deactivate"
msgstr ""
#: src/Admin/VersionAdminController.php:188
#: src/Admin/VersionAdminController.php:419 src/Admin/AdminController.php:1273
#: src/Admin/AdminController.php:1458
msgid "Activate"
msgstr ""
#: src/Admin/VersionAdminController.php:191
#: src/Admin/VersionAdminController.php:422 src/Admin/AdminController.php:1279
#: src/Admin/AdminController.php:1428 src/Admin/AdminController.php:1464
msgid "Delete"
msgstr ""
#: src/Admin/VersionAdminController.php:232
msgid "Are you sure you want to delete this version?"
msgstr ""
#: src/Admin/VersionAdminController.php:233
msgid "Please enter a version number."
msgstr ""
#: src/Admin/VersionAdminController.php:234
msgid "Please enter a valid version number (e.g., 1.0.0)."
msgstr ""
#: src/Admin/VersionAdminController.php:235
msgid "An error occurred. Please try again."
msgstr ""
#: src/Admin/VersionAdminController.php:236
msgid "Select Download File"
msgstr ""
#: src/Admin/VersionAdminController.php:237
msgid "Use this file"
msgstr ""
#: src/Admin/VersionAdminController.php:238
msgid ""
"Invalid checksum file format. File must contain a 64-character SHA256 hash."
msgstr ""
#: src/Admin/VersionAdminController.php:239
msgid "Failed to read checksum file."
msgstr ""
#: src/Admin/VersionAdminController.php:269
msgid "Product ID and version are required."
msgstr ""
#: src/Admin/VersionAdminController.php:274
msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)."
msgstr ""
#: src/Admin/VersionAdminController.php:279
msgid "This version already exists."
msgstr ""
#: src/Admin/VersionAdminController.php:285
msgid "Product not found."
msgstr ""
#: src/Admin/VersionAdminController.php:289
msgid "This product is not a licensed product."
msgstr ""
#: src/Admin/VersionAdminController.php:306
msgid "Failed to create version."
msgstr ""
#: src/Admin/VersionAdminController.php:314
msgid "Version added successfully."
msgstr ""
#: src/Admin/VersionAdminController.php:334
#: src/Admin/VersionAdminController.php:361
msgid "Version ID is required."
msgstr ""
#: src/Admin/VersionAdminController.php:340
msgid "Failed to delete version."
msgstr ""
#: src/Admin/VersionAdminController.php:343
msgid "Version deleted successfully."
msgstr ""
#: src/Admin/VersionAdminController.php:367
msgid "Failed to update version."
msgstr ""
#: src/Admin/VersionAdminController.php:371
msgid "Version updated successfully."
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 ""
@@ -410,28 +641,6 @@ msgstr ""
msgid "Copy failed" msgid "Copy failed"
msgstr "" msgstr ""
#: src/Admin/AdminController.php:156 src/Admin/AdminController.php:907
#: src/Admin/AdminController.php:1232 src/Admin/AdminController.php:1355
#: src/Admin/VersionAdminController.php:182
#: src/Admin/VersionAdminController.php:413
#: src/Admin/DashboardWidgetController.php:151
msgid "Active"
msgstr ""
#: src/Admin/AdminController.php:157 src/Admin/AdminController.php:914
#: src/Admin/AdminController.php:1233 src/Admin/AdminController.php:1356
#: src/Admin/VersionAdminController.php:182
#: src/Admin/VersionAdminController.php:413
msgid "Inactive"
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:159
#: 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"
@@ -514,11 +723,6 @@ msgstr ""
msgid "License Dashboard" msgid "License Dashboard"
msgstr "" msgstr ""
#: src/Admin/AdminController.php:900
#: src/Admin/DashboardWidgetController.php:147
msgid "Total Licenses"
msgstr ""
#: src/Admin/AdminController.php:937 #: src/Admin/AdminController.php:937
msgid "Attention:" msgid "Attention:"
msgstr "" msgstr ""
@@ -566,7 +770,6 @@ msgstr ""
msgid "License set to lifetime successfully." msgid "License set to lifetime successfully."
msgstr "" msgstr ""
#. translators: %d: number of licenses
#: src/Admin/AdminController.php:1106 #: src/Admin/AdminController.php:1106
#, php-format #, php-format
msgid "%d license activated." msgid "%d license activated."
@@ -574,7 +777,6 @@ msgid_plural "%d licenses activated."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#. translators: %d: number of licenses
#: src/Admin/AdminController.php:1114 #: src/Admin/AdminController.php:1114
#, php-format #, php-format
msgid "%d license deactivated." msgid "%d license deactivated."
@@ -582,7 +784,6 @@ msgid_plural "%d licenses deactivated."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#. translators: %d: number of licenses
#: src/Admin/AdminController.php:1122 #: src/Admin/AdminController.php:1122
#, php-format #, php-format
msgid "%d license revoked." msgid "%d license revoked."
@@ -590,7 +791,6 @@ msgid_plural "%d licenses revoked."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#. translators: %d: number of licenses
#: src/Admin/AdminController.php:1130 #: src/Admin/AdminController.php:1130
#, php-format #, php-format
msgid "%d license deleted." msgid "%d license deleted."
@@ -598,7 +798,6 @@ msgid_plural "%d licenses deleted."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#. translators: %d: number of licenses
#: src/Admin/AdminController.php:1138 #: src/Admin/AdminController.php:1138
#, php-format #, php-format
msgid "%d license extended." msgid "%d license extended."
@@ -618,7 +817,6 @@ msgstr ""
msgid "No licenses to export." msgid "No licenses to export."
msgstr "" msgstr ""
#. translators: %d: number of licenses imported
#: src/Admin/AdminController.php:1159 #: src/Admin/AdminController.php:1159
#, php-format #, php-format
msgid "%d license imported." msgid "%d license imported."
@@ -626,7 +824,6 @@ msgid_plural "%d licenses imported."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#. translators: %d: number of licenses updated
#: src/Admin/AdminController.php:1166 #: src/Admin/AdminController.php:1166
#, php-format #, php-format
msgid "%d updated." msgid "%d updated."
@@ -634,7 +831,6 @@ msgid_plural "%d updated."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#. translators: %d: number of licenses skipped
#: src/Admin/AdminController.php:1174 #: src/Admin/AdminController.php:1174
#, php-format #, php-format
msgid "%d skipped." msgid "%d skipped."
@@ -642,7 +838,6 @@ msgid_plural "%d skipped."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#. translators: %d: number of errors
#: src/Admin/AdminController.php:1182 #: src/Admin/AdminController.php:1182
#, php-format #, php-format
msgid "%d error." msgid "%d error."
@@ -718,18 +913,6 @@ msgstr ""
msgid "Bulk Actions" msgid "Bulk Actions"
msgstr "" msgstr ""
#: src/Admin/AdminController.php:1273 src/Admin/AdminController.php:1458
#: src/Admin/VersionAdminController.php:188
#: src/Admin/VersionAdminController.php:419
msgid "Activate"
msgstr ""
#: src/Admin/AdminController.php:1274 src/Admin/AdminController.php:1459
#: src/Admin/VersionAdminController.php:188
#: src/Admin/VersionAdminController.php:419
msgid "Deactivate"
msgstr ""
#: src/Admin/AdminController.php:1275 src/Admin/AdminController.php:1419 #: src/Admin/AdminController.php:1275 src/Admin/AdminController.php:1419
#: src/Admin/AdminController.php:1460 #: src/Admin/AdminController.php:1460
msgid "Revoke" msgid "Revoke"
@@ -747,12 +930,6 @@ msgstr ""
msgid "Extend 1 year" msgid "Extend 1 year"
msgstr "" msgstr ""
#: src/Admin/AdminController.php:1279 src/Admin/AdminController.php:1428
#: src/Admin/AdminController.php:1464 src/Admin/VersionAdminController.php:191
#: src/Admin/VersionAdminController.php:422
msgid "Delete"
msgstr ""
#: src/Admin/AdminController.php:1281 src/Admin/AdminController.php:1466 #: src/Admin/AdminController.php:1281 src/Admin/AdminController.php:1466
msgid "Apply" msgid "Apply"
msgstr "" msgstr ""
@@ -847,11 +1024,6 @@ msgstr ""
msgid "License is VALID" msgid "License is VALID"
msgstr "" msgstr ""
#: src/Admin/AdminController.php:1609 src/Admin/VersionAdminController.php:81
#: src/Admin/VersionAdminController.php:136
msgid "Version"
msgstr ""
#: src/Admin/AdminController.php:1617 #: src/Admin/AdminController.php:1617
msgid "License is INVALID" msgid "License is INVALID"
msgstr "" msgstr ""
@@ -967,216 +1139,25 @@ msgstr ""
msgid "No domain specified" msgid "No domain specified"
msgstr "" msgstr ""
#: src/Admin/VersionAdminController.php:58 #: src/Admin/DownloadWidgetController.php:46
msgid "Product Versions" msgid "Download Statistics"
msgstr "" msgstr ""
#: src/Admin/VersionAdminController.php:78 #: src/Admin/DownloadWidgetController.php:140
msgid "Add New Version" msgid "Total Downloads"
msgstr "" msgstr ""
#: src/Admin/VersionAdminController.php:84 #: src/Admin/DownloadWidgetController.php:145
msgid "Use semantic versioning (e.g., 1.0.0)" msgid "Top Products"
msgstr "" msgstr ""
#: src/Admin/VersionAdminController.php:88 #: src/Admin/DownloadWidgetController.php:159
#: src/Admin/VersionAdminController.php:137 #: src/Admin/DownloadWidgetController.php:180
msgid "Download File" msgid "No downloads yet"
msgstr "" msgstr ""
#: src/Admin/VersionAdminController.php:93 #: src/Admin/DownloadWidgetController.php:163
msgid "Select File" msgid "Top Versions"
msgstr ""
#: src/Admin/VersionAdminController.php:96
#: src/Admin/VersionAdminController.php:110
msgid "Remove"
msgstr ""
#: src/Admin/VersionAdminController.php:98
msgid ""
"Upload or select a file from the media library. Version will be auto-"
"detected from filename (e.g., plugin-v1.2.3.zip)."
msgstr ""
#: src/Admin/VersionAdminController.php:102
msgid "Checksum File"
msgstr ""
#: src/Admin/VersionAdminController.php:107
msgid "Select Checksum File"
msgstr ""
#: src/Admin/VersionAdminController.php:112
msgid ""
"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity."
msgstr ""
#: src/Admin/VersionAdminController.php:116
#: src/Admin/VersionAdminController.php:139
msgid "Release Notes"
msgstr ""
#: src/Admin/VersionAdminController.php:124
msgid "Add Version"
msgstr ""
#: src/Admin/VersionAdminController.php:132
msgid "Existing Versions"
msgstr ""
#: src/Admin/VersionAdminController.php:138
msgid "SHA256"
msgstr ""
#: src/Admin/VersionAdminController.php:141
msgid "Released"
msgstr ""
#: src/Admin/VersionAdminController.php:148
msgid "No versions found. Add your first version above."
msgstr ""
#: src/Admin/VersionAdminController.php:165
#: src/Admin/VersionAdminController.php:396
msgid "Uploaded file"
msgstr ""
#: src/Admin/VersionAdminController.php:169
#: src/Admin/VersionAdminController.php:400
msgid "No download file"
msgstr ""
#: src/Admin/VersionAdminController.php:232
msgid "Are you sure you want to delete this version?"
msgstr ""
#: src/Admin/VersionAdminController.php:233
msgid "Please enter a version number."
msgstr ""
#: src/Admin/VersionAdminController.php:234
msgid "Please enter a valid version number (e.g., 1.0.0)."
msgstr ""
#: src/Admin/VersionAdminController.php:235
msgid "An error occurred. Please try again."
msgstr ""
#: src/Admin/VersionAdminController.php:236
msgid "Select Download File"
msgstr ""
#: src/Admin/VersionAdminController.php:237
msgid "Use this file"
msgstr ""
#: src/Admin/VersionAdminController.php:238
msgid ""
"Invalid checksum file format. File must contain a 64-character SHA256 hash."
msgstr ""
#: src/Admin/VersionAdminController.php:239
msgid "Failed to read checksum file."
msgstr ""
#: src/Admin/VersionAdminController.php:269
msgid "Product ID and version are required."
msgstr ""
#: src/Admin/VersionAdminController.php:274
msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)."
msgstr ""
#: src/Admin/VersionAdminController.php:279
msgid "This version already exists."
msgstr ""
#: src/Admin/VersionAdminController.php:285
msgid "Product not found."
msgstr ""
#: src/Admin/VersionAdminController.php:289
msgid "This product is not a licensed product."
msgstr ""
#: src/Admin/VersionAdminController.php:306
msgid "Failed to create version."
msgstr ""
#: src/Admin/VersionAdminController.php:314
msgid "Version added successfully."
msgstr ""
#: src/Admin/VersionAdminController.php:334
#: src/Admin/VersionAdminController.php:361
msgid "Version ID is required."
msgstr ""
#: src/Admin/VersionAdminController.php:340
msgid "Failed to delete version."
msgstr ""
#: src/Admin/VersionAdminController.php:343
msgid "Version deleted successfully."
msgstr ""
#: src/Admin/VersionAdminController.php:367
msgid "Failed to update version."
msgstr ""
#: src/Admin/VersionAdminController.php:371
msgid "Version updated successfully."
msgstr ""
#: src/Admin/DashboardWidgetController.php:47
msgid "License Statistics"
msgstr ""
#: src/Admin/DashboardWidgetController.php:155
msgid "Expiring Soon"
msgstr ""
#: src/Admin/DashboardWidgetController.php:166
msgid "Status Breakdown"
msgstr ""
#: src/Admin/DashboardWidgetController.php:172
#, php-format
msgid "Active: %d"
msgstr ""
#: src/Admin/DashboardWidgetController.php:179
#, php-format
msgid "Inactive: %d"
msgstr ""
#: src/Admin/DashboardWidgetController.php:186
#, php-format
msgid "Expired: %d"
msgstr ""
#: src/Admin/DashboardWidgetController.php:193
#, php-format
msgid "Revoked: %d"
msgstr ""
#: src/Admin/DashboardWidgetController.php:202
msgid "License Types"
msgstr ""
#: src/Admin/DashboardWidgetController.php:207
#, php-format
msgid "Time-limited: %d"
msgstr ""
#: src/Admin/DashboardWidgetController.php:213
#, php-format
msgid "Lifetime: %d"
msgstr ""
#: src/Admin/DashboardWidgetController.php:220
msgid "View All Licenses"
msgstr "" msgstr ""
#: src/Api/RestApiController.php:84 #: src/Api/RestApiController.php:84
@@ -1274,7 +1255,8 @@ msgstr ""
msgid "This license is not valid for this domain." msgid "This license is not valid for this domain."
msgstr "" msgstr ""
#: src/License/LicenseManager.php:760 src/Frontend/AccountController.php:140 #: src/License/LicenseManager.php:760 src/Product/VersionManager.php:349
#: src/Product/VersionManager.php:361 src/Frontend/AccountController.php:140
#: src/Email/LicenseExpirationEmail.php:107 #: src/Email/LicenseExpirationEmail.php:107
#: src/Email/LicenseExpiredEmail.php:99 #: src/Email/LicenseExpiredEmail.php:99
msgid "Unknown Product" msgid "Unknown Product"
@@ -1284,7 +1266,6 @@ msgstr ""
msgid "Attachment file not found." msgid "Attachment file not found."
msgstr "" msgstr ""
#. translators: 1: provided hash, 2: calculated hash
#: src/Product/VersionManager.php:177 #: src/Product/VersionManager.php:177
#, php-format #, php-format
msgid "File checksum does not match. Expected: %1$s, Got: %2$s" msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
@@ -1303,7 +1284,6 @@ msgstr ""
msgid "%d days" msgid "%d days"
msgstr "" msgstr ""
#. translators: %s: URL to settings page
#: src/Product/LicensedProductType.php:119 #: src/Product/LicensedProductType.php:119
#, php-format #, php-format
msgid "Leave fields empty to use default settings from %s." msgid "Leave fields empty to use default settings from %s."
@@ -1317,7 +1297,6 @@ msgstr ""
msgid "Max Activations" msgid "Max Activations"
msgstr "" msgstr ""
#. translators: %d: default max activations value
#: src/Product/LicensedProductType.php:131 #: src/Product/LicensedProductType.php:131
#, php-format #, php-format
msgid "Maximum number of domain activations per license. Default: %d" msgid "Maximum number of domain activations per license. Default: %d"
@@ -1327,7 +1306,6 @@ msgstr ""
msgid "License Validity (Days)" msgid "License Validity (Days)"
msgstr "" msgstr ""
#. translators: %s: default validity value
#: src/Product/LicensedProductType.php:149 #: src/Product/LicensedProductType.php:149
#, php-format #, php-format
msgid "Number of days the license is valid. Leave empty for default (%s)." msgid "Number of days the license is valid. Leave empty for default (%s)."
@@ -1337,7 +1315,6 @@ msgstr ""
msgid "Bind to Major Version" msgid "Bind to Major Version"
msgstr "" msgstr ""
#. translators: %s: default bind to version value (Yes/No)
#: src/Product/LicensedProductType.php:167 #: src/Product/LicensedProductType.php:167
#, php-format #, php-format
msgid "" msgid ""
@@ -1357,54 +1334,54 @@ msgstr ""
msgid "Version:" msgid "Version:"
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:65 #: src/Frontend/DownloadController.php:77
#: src/Frontend/DownloadController.php:89 #: src/Frontend/DownloadController.php:101
msgid "Invalid download link." msgid "Invalid download link."
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:66 #: src/Frontend/DownloadController.php:78
#: src/Frontend/DownloadController.php:76 #: src/Frontend/DownloadController.php:88
#: src/Frontend/DownloadController.php:90 #: src/Frontend/DownloadController.php:102
#: src/Frontend/DownloadController.php:106 #: src/Frontend/DownloadController.php:118
#: src/Frontend/DownloadController.php:116 #: src/Frontend/DownloadController.php:128
#: src/Frontend/DownloadController.php:125 #: src/Frontend/DownloadController.php:137
#: src/Frontend/DownloadController.php:135 #: src/Frontend/DownloadController.php:147
#: src/Frontend/DownloadController.php:144 #: src/Frontend/DownloadController.php:156
#: src/Frontend/DownloadController.php:153 #: src/Frontend/DownloadController.php:165
#: src/Frontend/DownloadController.php:171
#: src/Frontend/DownloadController.php:187 #: src/Frontend/DownloadController.php:187
#: src/Frontend/DownloadController.php:203
msgid "Download Error" msgid "Download Error"
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:75 #: src/Frontend/DownloadController.php:87
msgid "Invalid download link format." msgid "Invalid download link format."
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:115 #: src/Frontend/DownloadController.php:127
msgid "You do not have permission to download this file." msgid "You do not have permission to download this file."
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:124 #: src/Frontend/DownloadController.php:136
msgid "Your license is not active. Please contact support." msgid "Your license is not active. Please contact support."
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:134 #: src/Frontend/DownloadController.php:146
msgid "Version not found." msgid "Version not found."
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:143 #: src/Frontend/DownloadController.php:155
msgid "Version does not match your licensed product." msgid "Version does not match your licensed product."
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:152 #: src/Frontend/DownloadController.php:164
msgid "This version is no longer available for download." msgid "This version is no longer available for download."
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:170 #: src/Frontend/DownloadController.php:186
msgid "No download file available for this version." msgid "No download file available for this version."
msgstr "" msgstr ""
#: src/Frontend/DownloadController.php:186 #: src/Frontend/DownloadController.php:202
msgid "Download file not found." msgid "Download file not found."
msgstr "" msgstr ""
@@ -1560,7 +1537,6 @@ msgid ""
"expiration date." "expiration date."
msgstr "" msgstr ""
#. translators: %s: list of placeholders
#: src/Email/LicenseExpirationEmail.php:301 #: src/Email/LicenseExpirationEmail.php:301
#: src/Email/LicenseExpiredEmail.php:288 #: src/Email/LicenseExpiredEmail.php:288
#, php-format #, php-format
@@ -1666,20 +1642,19 @@ msgstr ""
msgid "To continue using this product, please renew your license." msgid "To continue using this product, please renew your license."
msgstr "" msgstr ""
#: src/Plugin.php:258 #: src/Plugin.php:260
msgid "WC Licensed Product" msgid "WC Licensed Product"
msgstr "" msgstr ""
#: src/Plugin.php:259 #: src/Plugin.php:261
msgid "" msgid ""
"Plugin license is not configured or invalid. Frontend features are disabled." "Plugin license is not configured or invalid. Frontend features are disabled."
msgstr "" msgstr ""
#: src/Plugin.php:260 #: src/Plugin.php:262
msgid "Configure License" msgid "Configure License"
msgstr "" msgstr ""
#. translators: %s: WooCommerce plugin name
#: wc-licensed-product.php:61 #: wc-licensed-product.php:61
#, php-format #, php-format
msgid "%s requires WooCommerce to be installed and active." msgid "%s requires WooCommerce to be installed and active."

View File

@@ -55,7 +55,7 @@ final class DashboardWidgetController
public function renderWidget(): void public function renderWidget(): void
{ {
$stats = $this->licenseManager->getStatistics(); $stats = $this->licenseManager->getStatistics();
$licensesUrl = admin_url('admin.php?page=wc-licensed-product-licenses'); $licensesUrl = admin_url('admin.php?page=wc-licenses');
?> ?>
<style> <style>
.wclp-widget-stats { .wclp-widget-stats {
@@ -96,40 +96,6 @@ final class DashboardWidgetController
letter-spacing: 0.5px; letter-spacing: 0.5px;
margin-top: 4px; margin-top: 4px;
} }
.wclp-widget-divider {
border-top: 1px solid #e2e4e7;
margin: 16px 0;
}
.wclp-status-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.wclp-status-badge {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 4px 10px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
}
.wclp-status-badge.active {
background: #d4edda;
color: #155724;
}
.wclp-status-badge.inactive {
background: #e2e3e5;
color: #383d41;
}
.wclp-status-badge.expired {
background: #f8d7da;
color: #721c24;
}
.wclp-status-badge.revoked {
background: #d6d8db;
color: #1b1e21;
}
.wclp-widget-footer { .wclp-widget-footer {
margin-top: 16px; margin-top: 16px;
padding-top: 12px; padding-top: 12px;
@@ -160,60 +126,16 @@ final class DashboardWidgetController
</div> </div>
</div> </div>
<div class="wclp-widget-divider"></div> <div class="wclp-widget-stats">
<div class="wclp-stat-card">
<h4 style="margin: 0 0 8px 0; font-size: 13px; color: #1d2327;"> <div class="wclp-stat-number"><?php echo esc_html(number_format_i18n($stats['expiring'])); ?></div>
<?php esc_html_e('Status Breakdown', 'wc-licensed-product'); ?> <div class="wclp-stat-label"><?php esc_html_e('Time-limited', 'wc-licensed-product'); ?></div>
</h4> </div>
<div class="wclp-status-list"> <div class="wclp-stat-card">
<span class="wclp-status-badge active"> <div class="wclp-stat-number"><?php echo esc_html(number_format_i18n($stats['lifetime'])); ?></div>
<span class="dashicons dashicons-yes-alt" style="font-size: 14px; width: 14px; height: 14px;"></span> <div class="wclp-stat-label"><?php esc_html_e('Lifetime', 'wc-licensed-product'); ?></div>
<?php printf( </div>
esc_html__('Active: %d', 'wc-licensed-product'),
$stats['by_status'][License::STATUS_ACTIVE]
); ?>
</span>
<span class="wclp-status-badge inactive">
<span class="dashicons dashicons-marker" style="font-size: 14px; width: 14px; height: 14px;"></span>
<?php printf(
esc_html__('Inactive: %d', 'wc-licensed-product'),
$stats['by_status'][License::STATUS_INACTIVE]
); ?>
</span>
<span class="wclp-status-badge expired">
<span class="dashicons dashicons-clock" style="font-size: 14px; width: 14px; height: 14px;"></span>
<?php printf(
esc_html__('Expired: %d', 'wc-licensed-product'),
$stats['by_status'][License::STATUS_EXPIRED]
); ?>
</span>
<span class="wclp-status-badge revoked">
<span class="dashicons dashicons-dismiss" style="font-size: 14px; width: 14px; height: 14px;"></span>
<?php printf(
esc_html__('Revoked: %d', 'wc-licensed-product'),
$stats['by_status'][License::STATUS_REVOKED]
); ?>
</span>
</div> </div>
<div class="wclp-widget-divider"></div>
<h4 style="margin: 0 0 8px 0; font-size: 13px; color: #1d2327;">
<?php esc_html_e('License Types', 'wc-licensed-product'); ?>
</h4>
<p style="margin: 0; font-size: 13px; color: #646970;">
<span class="dashicons dashicons-calendar-alt" style="font-size: 14px; width: 14px; height: 14px; vertical-align: text-bottom;"></span>
<?php printf(
esc_html__('Time-limited: %d', 'wc-licensed-product'),
$stats['expiring']
); ?>
&nbsp;&nbsp;|&nbsp;&nbsp;
<span class="dashicons dashicons-infinity" style="font-size: 14px; width: 14px; height: 14px; vertical-align: text-bottom;"></span>
<?php printf(
esc_html__('Lifetime: %d', 'wc-licensed-product'),
$stats['lifetime']
); ?>
</p>
<div class="wclp-widget-footer"> <div class="wclp-widget-footer">
<a href="<?php echo esc_url($licensesUrl); ?>" class="button button-secondary"> <a href="<?php echo esc_url($licensesUrl); ?>" class="button button-secondary">

View File

@@ -0,0 +1,184 @@
<?php
/**
* Download Statistics Widget Controller
*
* @package Jeremias\WcLicensedProduct\Admin
*/
declare(strict_types=1);
namespace Jeremias\WcLicensedProduct\Admin;
use Jeremias\WcLicensedProduct\Product\VersionManager;
/**
* Handles the WordPress admin dashboard widget for download statistics
*/
final class DownloadWidgetController
{
private VersionManager $versionManager;
public function __construct(VersionManager $versionManager)
{
$this->versionManager = $versionManager;
$this->registerHooks();
}
/**
* Register WordPress hooks
*/
private function registerHooks(): void
{
add_action('wp_dashboard_setup', [$this, 'registerDashboardWidget']);
}
/**
* Register the dashboard widget
*/
public function registerDashboardWidget(): void
{
if (!current_user_can('manage_woocommerce')) {
return;
}
wp_add_dashboard_widget(
'wclp_download_statistics',
__('Download Statistics', 'wc-licensed-product'),
[$this, 'renderWidget']
);
}
/**
* Render the dashboard widget content
*/
public function renderWidget(): void
{
$stats = $this->versionManager->getDownloadStatistics();
?>
<style>
.wclp-download-widget-stats {
display: grid;
grid-template-columns: 1fr;
gap: 12px;
margin-bottom: 16px;
}
.wclp-download-stat-card {
background: #f8f9fa;
border: 1px solid #e2e4e7;
border-radius: 4px;
padding: 12px;
text-align: center;
border-left: 3px solid #2271b1;
}
.wclp-download-stat-number {
font-size: 32px;
font-weight: 600;
color: #1d2327;
line-height: 1.2;
}
.wclp-download-stat-label {
font-size: 12px;
color: #646970;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-top: 4px;
}
.wclp-download-list {
margin: 0;
padding: 0;
list-style: none;
}
.wclp-download-list li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
border-bottom: 1px solid #e2e4e7;
}
.wclp-download-list li:last-child {
border-bottom: none;
}
.wclp-download-list .product-name {
font-weight: 500;
color: #1d2327;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-right: 12px;
}
.wclp-download-list .version-info {
font-size: 12px;
color: #646970;
}
.wclp-download-list .download-count {
background: #e7f5ff;
color: #0a4b78;
padding: 2px 8px;
border-radius: 10px;
font-size: 12px;
font-weight: 600;
white-space: nowrap;
}
.wclp-download-section-title {
margin: 16px 0 8px 0;
font-size: 13px;
color: #1d2327;
font-weight: 600;
}
.wclp-no-downloads {
color: #646970;
font-style: italic;
text-align: center;
padding: 12px 0;
}
</style>
<div class="wclp-download-widget-stats">
<div class="wclp-download-stat-card">
<div class="wclp-download-stat-number"><?php echo esc_html(number_format_i18n($stats['total'])); ?></div>
<div class="wclp-download-stat-label"><?php esc_html_e('Total Downloads', 'wc-licensed-product'); ?></div>
</div>
</div>
<h4 class="wclp-download-section-title">
<?php esc_html_e('Top Products', 'wc-licensed-product'); ?>
</h4>
<?php if (!empty($stats['by_product'])): ?>
<ul class="wclp-download-list">
<?php foreach (array_slice($stats['by_product'], 0, 5) as $product): ?>
<li>
<span class="product-name"><?php echo esc_html($product['product_name']); ?></span>
<span class="download-count">
<?php echo esc_html(number_format_i18n($product['downloads'])); ?>
</span>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p class="wclp-no-downloads"><?php esc_html_e('No downloads yet', 'wc-licensed-product'); ?></p>
<?php endif; ?>
<h4 class="wclp-download-section-title">
<?php esc_html_e('Top Versions', 'wc-licensed-product'); ?>
</h4>
<?php if (!empty($stats['by_version'])): ?>
<ul class="wclp-download-list">
<?php foreach (array_slice($stats['by_version'], 0, 5) as $version): ?>
<li>
<span class="product-name">
<?php echo esc_html($version['product_name']); ?>
<span class="version-info">v<?php echo esc_html($version['version']); ?></span>
</span>
<span class="download-count">
<?php echo esc_html(number_format_i18n($version['downloads'])); ?>
</span>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p class="wclp-no-downloads"><?php esc_html_e('No downloads yet', 'wc-licensed-product'); ?></p>
<?php endif; ?>
<?php
}
}

View File

@@ -35,6 +35,9 @@ final class DownloadController
// Add download endpoint // Add download endpoint
add_action('init', [$this, 'addDownloadEndpoint']); add_action('init', [$this, 'addDownloadEndpoint']);
// Register query var for the endpoint
add_filter('query_vars', [$this, 'addDownloadQueryVar']);
// Handle download requests // Handle download requests
add_action('template_redirect', [$this, 'handleDownloadRequest']); add_action('template_redirect', [$this, 'handleDownloadRequest']);
} }
@@ -47,6 +50,15 @@ final class DownloadController
add_rewrite_endpoint('license-download', EP_ROOT | EP_PAGES); add_rewrite_endpoint('license-download', EP_ROOT | EP_PAGES);
} }
/**
* Register the download query var
*/
public function addDownloadQueryVar(array $vars): array
{
$vars[] = 'license-download';
return $vars;
}
/** /**
* Handle download request * Handle download request
*/ */
@@ -160,8 +172,12 @@ final class DownloadController
$downloadUrl = $version->getDownloadUrl(); $downloadUrl = $version->getDownloadUrl();
if ($attachmentId) { if ($attachmentId) {
// Increment download count before serving
$this->versionManager->incrementDownloadCount($versionId);
$this->serveAttachment($attachmentId, $version->getVersion()); $this->serveAttachment($attachmentId, $version->getVersion());
} elseif ($downloadUrl) { } elseif ($downloadUrl) {
// Increment download count before redirect
$this->versionManager->incrementDownloadCount($versionId);
// Redirect to external URL // Redirect to external URL
wp_redirect($downloadUrl); wp_redirect($downloadUrl);
exit; exit;

View File

@@ -35,8 +35,9 @@ final class Installer
// Set version in options // Set version in options
update_option('wc_licensed_product_version', WC_LICENSED_PRODUCT_VERSION); update_option('wc_licensed_product_version', WC_LICENSED_PRODUCT_VERSION);
// Register the licenses endpoint before flushing rewrite rules // Register endpoints before flushing rewrite rules
add_rewrite_endpoint('licenses', EP_ROOT | EP_PAGES); add_rewrite_endpoint('licenses', EP_ROOT | EP_PAGES);
add_rewrite_endpoint('license-download', EP_ROOT | EP_PAGES);
// Flush rewrite rules for REST API and My Account endpoints // Flush rewrite rules for REST API and My Account endpoints
flush_rewrite_rules(); flush_rewrite_rules();
@@ -103,6 +104,7 @@ final class Installer
download_url VARCHAR(512) DEFAULT NULL, download_url VARCHAR(512) DEFAULT NULL,
attachment_id BIGINT UNSIGNED DEFAULT NULL, attachment_id BIGINT UNSIGNED DEFAULT NULL,
file_hash VARCHAR(64) DEFAULT NULL, file_hash VARCHAR(64) DEFAULT NULL,
download_count BIGINT UNSIGNED NOT NULL DEFAULT 0,
is_active TINYINT(1) NOT NULL DEFAULT 1, is_active TINYINT(1) NOT NULL DEFAULT 1,
released_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, released_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,

View File

@@ -11,6 +11,7 @@ namespace Jeremias\WcLicensedProduct;
use Jeremias\WcLicensedProduct\Admin\AdminController; use Jeremias\WcLicensedProduct\Admin\AdminController;
use Jeremias\WcLicensedProduct\Admin\DashboardWidgetController; use Jeremias\WcLicensedProduct\Admin\DashboardWidgetController;
use Jeremias\WcLicensedProduct\Admin\DownloadWidgetController;
use Jeremias\WcLicensedProduct\Admin\OrderLicenseController; use Jeremias\WcLicensedProduct\Admin\OrderLicenseController;
use Jeremias\WcLicensedProduct\Admin\SettingsController; use Jeremias\WcLicensedProduct\Admin\SettingsController;
use Jeremias\WcLicensedProduct\Admin\VersionAdminController; use Jeremias\WcLicensedProduct\Admin\VersionAdminController;
@@ -154,6 +155,7 @@ final class Plugin
new OrderLicenseController($this->licenseManager); new OrderLicenseController($this->licenseManager);
new SettingsController(); new SettingsController();
new DashboardWidgetController($this->licenseManager); new DashboardWidgetController($this->licenseManager);
new DownloadWidgetController($this->versionManager);
// Show admin notice if unlicensed and not on localhost // Show admin notice if unlicensed and not on localhost
if (!$isLicensed && !$licenseChecker->isLocalhost()) { if (!$isLicensed && !$licenseChecker->isLocalhost()) {

View File

@@ -24,6 +24,7 @@ class ProductVersion
private ?string $downloadUrl; private ?string $downloadUrl;
private ?int $attachmentId; private ?int $attachmentId;
private ?string $fileHash; private ?string $fileHash;
private int $downloadCount;
private bool $isActive; private bool $isActive;
private \DateTimeInterface $releasedAt; private \DateTimeInterface $releasedAt;
private \DateTimeInterface $createdAt; private \DateTimeInterface $createdAt;
@@ -44,6 +45,7 @@ class ProductVersion
$version->downloadUrl = $data['download_url'] ?: null; $version->downloadUrl = $data['download_url'] ?: null;
$version->attachmentId = !empty($data['attachment_id']) ? (int) $data['attachment_id'] : null; $version->attachmentId = !empty($data['attachment_id']) ? (int) $data['attachment_id'] : null;
$version->fileHash = $data['file_hash'] ?? null; $version->fileHash = $data['file_hash'] ?? null;
$version->downloadCount = (int) ($data['download_count'] ?? 0);
$version->isActive = (bool) $data['is_active']; $version->isActive = (bool) $data['is_active'];
$version->releasedAt = new \DateTimeImmutable($data['released_at']); $version->releasedAt = new \DateTimeImmutable($data['released_at']);
$version->createdAt = new \DateTimeImmutable($data['created_at']); $version->createdAt = new \DateTimeImmutable($data['created_at']);
@@ -144,6 +146,11 @@ class ProductVersion
return $this->fileHash; return $this->fileHash;
} }
public function getDownloadCount(): int
{
return $this->downloadCount;
}
/** /**
* Get the download URL from attachment * Get the download URL from attachment
*/ */
@@ -197,6 +204,7 @@ class ProductVersion
'download_url' => $this->downloadUrl, 'download_url' => $this->downloadUrl,
'attachment_id' => $this->attachmentId, 'attachment_id' => $this->attachmentId,
'file_hash' => $this->fileHash, 'file_hash' => $this->fileHash,
'download_count' => $this->downloadCount,
'is_active' => $this->isActive, 'is_active' => $this->isActive,
'released_at' => $this->releasedAt->format('Y-m-d H:i:s'), 'released_at' => $this->releasedAt->format('Y-m-d H:i:s'),
'created_at' => $this->createdAt->format('Y-m-d H:i:s'), 'created_at' => $this->createdAt->format('Y-m-d H:i:s'),

View File

@@ -276,4 +276,98 @@ class VersionManager
return (int) $count > 0; return (int) $count > 0;
} }
/**
* Increment download count for a version
*/
public function incrementDownloadCount(int $versionId): bool
{
global $wpdb;
$tableName = Installer::getVersionsTable();
$result = $wpdb->query(
$wpdb->prepare(
"UPDATE {$tableName} SET download_count = download_count + 1 WHERE id = %d",
$versionId
)
);
return $result !== false;
}
/**
* Get total download count across all versions
*/
public function getTotalDownloadCount(): int
{
global $wpdb;
$tableName = Installer::getVersionsTable();
$count = $wpdb->get_var("SELECT COALESCE(SUM(download_count), 0) FROM {$tableName}");
return (int) $count;
}
/**
* Get download statistics per product
*/
public function getDownloadStatistics(): array
{
global $wpdb;
$tableName = Installer::getVersionsTable();
// Get total downloads
$totalDownloads = $this->getTotalDownloadCount();
// Get downloads per product (top 10)
$byProduct = $wpdb->get_results(
"SELECT product_id, SUM(download_count) as downloads
FROM {$tableName}
GROUP BY product_id
ORDER BY downloads DESC
LIMIT 10",
ARRAY_A
);
// Get downloads per version (top 10)
$byVersion = $wpdb->get_results(
"SELECT id, product_id, version, download_count
FROM {$tableName}
WHERE download_count > 0
ORDER BY download_count DESC
LIMIT 10",
ARRAY_A
);
// Enrich product data with names
$productsWithNames = [];
foreach ($byProduct ?: [] as $row) {
$product = wc_get_product((int) $row['product_id']);
$productsWithNames[] = [
'product_id' => (int) $row['product_id'],
'product_name' => $product ? $product->get_name() : __('Unknown Product', 'wc-licensed-product'),
'downloads' => (int) $row['downloads'],
];
}
// Enrich version data with product names
$versionsWithNames = [];
foreach ($byVersion ?: [] as $row) {
$product = wc_get_product((int) $row['product_id']);
$versionsWithNames[] = [
'version_id' => (int) $row['id'],
'product_id' => (int) $row['product_id'],
'product_name' => $product ? $product->get_name() : __('Unknown Product', 'wc-licensed-product'),
'version' => $row['version'],
'downloads' => (int) $row['download_count'],
];
}
return [
'total' => $totalDownloads,
'by_product' => $productsWithNames,
'by_version' => $versionsWithNames,
];
}
} }