From 034593f89624a29e6187c1b492abfaa31e6bbfeb Mon Sep 17 00:00:00 2001 From: magdev Date: Sat, 24 Jan 2026 10:17:46 +0100 Subject: [PATCH] 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 --- CLAUDE.md | 7 +- languages/wc-licensed-product-de_CH.mo | Bin 31437 -> 31559 bytes languages/wc-licensed-product-de_CH.po | 650 ++++++++++++------------ languages/wc-licensed-product.pot | 595 +++++++++++----------- src/Admin/DashboardWidgetController.php | 98 +--- src/Admin/DownloadWidgetController.php | 184 +++++++ src/Frontend/DownloadController.php | 16 + src/Installer.php | 4 +- src/Plugin.php | 2 + src/Product/ProductVersion.php | 8 + src/Product/VersionManager.php | 94 ++++ 11 files changed, 937 insertions(+), 721 deletions(-) create mode 100644 src/Admin/DownloadWidgetController.php diff --git a/CLAUDE.md b/CLAUDE.md index c4f5917..f67d72c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -38,7 +38,12 @@ No known bugs at the moment. ### 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 diff --git a/languages/wc-licensed-product-de_CH.mo b/languages/wc-licensed-product-de_CH.mo index 741d764a398c2debd68ed729956f9cf4ff02e798..e4c565eb81ded1f6893626b2c0da999bde7ab418 100644 GIT binary patch delta 7992 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 YlWbqz6=tNnCcnJ4(Zjq4=lKWy4-(GArT_o{ delta 8021 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 Uo{9~t^?dE1RbSR+SNaG47Z{\n" "Language-Team: German (Switzerland) \n" @@ -97,8 +97,9 @@ msgstr "Produkt" msgid "Domain" msgstr "Domain" -#: src/Admin/OrderLicenseController.php:147 src/Admin/AdminController.php:1295 -#: src/Admin/AdminController.php:1446 src/Admin/VersionAdminController.php:140 +#: src/Admin/OrderLicenseController.php:147 +#: src/Admin/VersionAdminController.php:140 src/Admin/AdminController.php:1295 +#: src/Admin/AdminController.php:1446 msgid "Status" msgstr "Status" @@ -108,8 +109,9 @@ msgstr "Status" msgid "Expires" msgstr "Läuft ab" -#: src/Admin/OrderLicenseController.php:149 src/Admin/AdminController.php:1298 -#: src/Admin/AdminController.php:1449 src/Admin/VersionAdminController.php:142 +#: src/Admin/OrderLicenseController.php:149 +#: src/Admin/VersionAdminController.php:142 src/Admin/AdminController.php:1298 +#: src/Admin/AdminController.php:1449 msgid "Actions" msgstr "Aktionen" @@ -130,9 +132,11 @@ msgid "Cancel" msgstr "Abbrechen" #: src/Admin/OrderLicenseController.php:201 -#: 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/Product/LicensedProductType.php:110 +#: src/Admin/SettingsController.php:192 +#: 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:158 msgid "Lifetime" msgstr "Lebenslang" @@ -141,7 +145,6 @@ msgstr "Lebenslang" msgid "View in Licenses" msgstr "In Lizenzen anzeigen" -#. translators: %s: Link to licenses page #: src/Admin/OrderLicenseController.php:221 #, php-format 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." #: 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:301 src/Admin/AdminController.php:339 -#: src/Admin/AdminController.php:369 src/Admin/VersionAdminController.php:259 -#: src/Admin/VersionAdminController.php:328 -#: src/Admin/VersionAdminController.php:354 +#: src/Admin/AdminController.php:369 msgid "Permission denied." msgstr "Zugriff verweigert." @@ -201,7 +205,7 @@ msgid "Domain cannot be empty." msgstr "Domain darf nicht leer sein." #: src/Admin/OrderLicenseController.php:363 -#: src/Frontend/DownloadController.php:105 +#: src/Frontend/DownloadController.php:117 #: src/Frontend/AccountController.php:352 msgid "License not found." msgstr "Lizenz nicht gefunden." @@ -310,13 +314,15 @@ msgstr "" msgid "Expiration Warning Schedule" msgstr "Ablaufwarnung Zeitplan" -#. translators: %s: URL to WooCommerce email settings #: src/Admin/SettingsController.php:223 #, php-format msgid "" "Configure when expiration warning emails are sent. To customize the email " "template, enable/disable, or change the subject, go to %s." 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-" "Mail-Vorlage anzupassen, zu aktivieren/deaktivieren oder den Betreff zu " "ändern, gehen Sie zu %s." @@ -389,6 +395,242 @@ msgstr "Lizenz erfolgreich überprüft!" msgid "License validation failed." 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 msgid "Overview" msgstr "Übersicht" @@ -433,28 +675,6 @@ msgstr "Kopiert!" msgid "Copy failed" 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:1235 src/Admin/AdminController.php:1358 msgid "Revoked" @@ -537,11 +757,6 @@ msgstr "Import der Lizenz für Domain %s fehlgeschlagen" msgid "License 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 msgid "Attention:" msgstr "Achtung:" @@ -589,7 +804,6 @@ msgstr "Lizenz erfolgreich verlängert." msgid "License set to lifetime successfully." msgstr "Lizenz erfolgreich auf lebenslang gesetzt." -#. translators: %d: number of licenses #: src/Admin/AdminController.php:1106 #, php-format msgid "%d license activated." @@ -597,7 +811,6 @@ msgid_plural "%d licenses activated." msgstr[0] "%d Lizenz aktiviert." msgstr[1] "%d Lizenzen aktiviert." -#. translators: %d: number of licenses #: src/Admin/AdminController.php:1114 #, php-format msgid "%d license deactivated." @@ -605,7 +818,6 @@ msgid_plural "%d licenses deactivated." msgstr[0] "%d Lizenz deaktiviert." msgstr[1] "%d Lizenzen deaktiviert." -#. translators: %d: number of licenses #: src/Admin/AdminController.php:1122 #, php-format msgid "%d license revoked." @@ -613,7 +825,6 @@ msgid_plural "%d licenses revoked." msgstr[0] "%d Lizenz widerrufen." msgstr[1] "%d Lizenzen widerrufen." -#. translators: %d: number of licenses #: src/Admin/AdminController.php:1130 #, php-format msgid "%d license deleted." @@ -621,7 +832,6 @@ msgid_plural "%d licenses deleted." msgstr[0] "%d Lizenz gelöscht." msgstr[1] "%d Lizenzen gelöscht." -#. translators: %d: number of licenses #: src/Admin/AdminController.php:1138 #, php-format msgid "%d license extended." @@ -643,7 +853,6 @@ msgstr "" msgid "No licenses to export." msgstr "Keine Lizenzen zum Exportieren." -#. translators: %d: number of licenses imported #: src/Admin/AdminController.php:1159 #, php-format msgid "%d license imported." @@ -651,7 +860,6 @@ msgid_plural "%d licenses imported." msgstr[0] "%d Lizenz importiert." msgstr[1] "%d Lizenzen importiert." -#. translators: %d: number of licenses updated #: src/Admin/AdminController.php:1166 #, php-format msgid "%d updated." @@ -659,7 +867,6 @@ msgid_plural "%d updated." msgstr[0] "%d aktualisiert." msgstr[1] "%d aktualisiert." -#. translators: %d: number of licenses skipped #: src/Admin/AdminController.php:1174 #, php-format msgid "%d skipped." @@ -667,7 +874,6 @@ msgid_plural "%d skipped." msgstr[0] "%d übersprungen." msgstr[1] "%d übersprungen." -#. translators: %d: number of errors #: src/Admin/AdminController.php:1182 #, php-format msgid "%d error." @@ -743,18 +949,6 @@ msgstr "Dashboard anzeigen" msgid "Bulk Actions" 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:1460 msgid "Revoke" @@ -772,12 +966,6 @@ msgstr "90 Tage verlängern" msgid "Extend 1 year" 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 msgid "Apply" msgstr "Anwenden" @@ -872,11 +1060,6 @@ msgstr "Lizenz übertragen" msgid "License is VALID" 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 msgid "License is INVALID" msgstr "Lizenz ist UNGÜLTIG" @@ -997,225 +1180,26 @@ msgstr "Lizenz" msgid "No domain specified" msgstr "Keine Domain angegeben" -#: src/Admin/VersionAdminController.php:58 -msgid "Product Versions" -msgstr "Produktversionen" +#: src/Admin/DownloadWidgetController.php:46 +msgid "Download Statistics" +msgstr "Download-Statistiken" -#: src/Admin/VersionAdminController.php:78 -msgid "Add New Version" -msgstr "Neue Version hinzufügen" +#: src/Admin/DownloadWidgetController.php:140 +msgid "Total Downloads" +msgstr "Gesamte Downloads" -#: 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/DownloadWidgetController.php:145 +msgid "Top Products" +msgstr "Top-Produkte" -#: src/Admin/VersionAdminController.php:88 -#: src/Admin/VersionAdminController.php:137 -msgid "Download File" -msgstr "Download-Datei" +#: src/Admin/DownloadWidgetController.php:159 +#: src/Admin/DownloadWidgetController.php:180 +msgid "No downloads yet" +msgstr "Noch keine Downloads" -#: 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: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/Admin/DownloadWidgetController.php:163 +msgid "Top Versions" +msgstr "Top-Versionen" #: src/Api/RestApiController.php:84 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." 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/LicenseExpiredEmail.php:99 msgid "Unknown Product" @@ -1324,7 +1309,6 @@ msgstr "Unbekanntes Produkt" msgid "Attachment file not found." msgstr "Anhangs-Datei nicht gefunden." -#. translators: 1: provided hash, 2: calculated hash #: src/Product/VersionManager.php:177 #, php-format msgid "File checksum does not match. Expected: %1$s, Got: %2$s" @@ -1343,7 +1327,6 @@ msgstr "Lizenz-Einstellungen" msgid "%d days" msgstr "%d Tage" -#. translators: %s: URL to settings page #: src/Product/LicensedProductType.php:119 #, php-format msgid "Leave fields empty to use default settings from %s." @@ -1357,7 +1340,6 @@ msgstr "WooCommerce > Einstellungen > Lizensierte Produkte" msgid "Max Activations" msgstr "Max. Aktivierungen" -#. translators: %d: default max activations value #: src/Product/LicensedProductType.php:131 #, php-format 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)" msgstr "Lizenz-Gültigkeit (Tage)" -#. translators: %s: default validity value #: src/Product/LicensedProductType.php:149 #, php-format 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" msgstr "An Hauptversion binden" -#. translators: %s: default bind to version value (Yes/No) #: src/Product/LicensedProductType.php:167 #, php-format msgid "" @@ -1399,54 +1379,54 @@ msgstr "Nein" msgid "Version:" msgstr "Version:" -#: src/Frontend/DownloadController.php:65 -#: src/Frontend/DownloadController.php:89 +#: src/Frontend/DownloadController.php:77 +#: src/Frontend/DownloadController.php:101 msgid "Invalid download link." msgstr "Ungültiger Download-Link." -#: src/Frontend/DownloadController.php:66 -#: src/Frontend/DownloadController.php:76 -#: src/Frontend/DownloadController.php:90 -#: src/Frontend/DownloadController.php:106 -#: src/Frontend/DownloadController.php:116 -#: src/Frontend/DownloadController.php:125 -#: src/Frontend/DownloadController.php:135 -#: src/Frontend/DownloadController.php:144 -#: src/Frontend/DownloadController.php:153 -#: src/Frontend/DownloadController.php:171 +#: 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:75 +#: src/Frontend/DownloadController.php:87 msgid "Invalid 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." 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." 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." msgstr "Version nicht gefunden." -#: src/Frontend/DownloadController.php:143 +#: 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:152 +#: 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:170 +#: 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:186 +#: src/Frontend/DownloadController.php:202 msgid "Download file not found." msgstr "Download-Datei nicht gefunden." @@ -1610,7 +1590,6 @@ msgstr "" "Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz vor " "dem Ablaufdatum." -#. translators: %s: list of placeholders #: src/Email/LicenseExpirationEmail.php:301 #: src/Email/LicenseExpiredEmail.php:288 #, php-format @@ -1722,22 +1701,21 @@ msgid "To continue using this product, please renew your license." msgstr "" "Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz." -#: src/Plugin.php:258 +#: src/Plugin.php:260 msgid "WC Licensed Product" msgstr "WC Licensed Product" -#: src/Plugin.php:259 +#: src/Plugin.php:261 msgid "" "Plugin license is not configured or invalid. Frontend features are disabled." msgstr "" "Plugin-Lizenz ist nicht konfiguriert oder ungültig. Frontend-Funktionen sind " "deaktiviert." -#: src/Plugin.php:260 +#: src/Plugin.php:262 msgid "Configure License" msgstr "Lizenz konfigurieren" -#. translators: %s: WooCommerce plugin name #: wc-licensed-product.php:61 #, php-format msgid "%s requires WooCommerce to be installed and active." @@ -1749,6 +1727,36 @@ msgstr "" "WC Licensed Product benötigt WooCommerce als installierte und aktivierte " "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" diff --git a/languages/wc-licensed-product.pot b/languages/wc-licensed-product.pot index 73bf4f3..fef594a 100644 --- a/languages/wc-licensed-product.pot +++ b/languages/wc-licensed-product.pot @@ -1,14 +1,14 @@ # SOME DESCRIPTIVE TITLE. # 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 , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: wc-licensed-product 0.3.6\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-23 21:09+0100\n" +"Project-Id-Version: WC Licensed Product 0.3.7\n" +"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n" +"POT-Creation-Date: 2026-01-24 10:11+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -93,8 +93,9 @@ msgstr "" msgid "Domain" msgstr "" -#: src/Admin/OrderLicenseController.php:147 src/Admin/AdminController.php:1295 -#: src/Admin/AdminController.php:1446 src/Admin/VersionAdminController.php:140 +#: src/Admin/OrderLicenseController.php:147 +#: src/Admin/VersionAdminController.php:140 src/Admin/AdminController.php:1295 +#: src/Admin/AdminController.php:1446 msgid "Status" msgstr "" @@ -104,8 +105,9 @@ msgstr "" msgid "Expires" msgstr "" -#: src/Admin/OrderLicenseController.php:149 src/Admin/AdminController.php:1298 -#: src/Admin/AdminController.php:1449 src/Admin/VersionAdminController.php:142 +#: src/Admin/OrderLicenseController.php:149 +#: src/Admin/VersionAdminController.php:142 src/Admin/AdminController.php:1298 +#: src/Admin/AdminController.php:1449 msgid "Actions" msgstr "" @@ -126,9 +128,11 @@ msgid "Cancel" msgstr "" #: src/Admin/OrderLicenseController.php:201 -#: 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/Product/LicensedProductType.php:110 +#: src/Admin/SettingsController.php:192 +#: 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:158 msgid "Lifetime" msgstr "" @@ -137,7 +141,6 @@ msgstr "" msgid "View in Licenses" msgstr "" -#. translators: %s: Link to licenses page #: src/Admin/OrderLicenseController.php:221 #, php-format msgid "For more actions (revoke, extend, delete), go to the %s page." @@ -162,12 +165,13 @@ msgid "Please enter a valid domain." msgstr "" #: 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:301 src/Admin/AdminController.php:339 -#: src/Admin/AdminController.php:369 src/Admin/VersionAdminController.php:259 -#: src/Admin/VersionAdminController.php:328 -#: src/Admin/VersionAdminController.php:354 +#: src/Admin/AdminController.php:369 msgid "Permission denied." msgstr "" @@ -195,7 +199,7 @@ msgid "Domain cannot be empty." msgstr "" #: src/Admin/OrderLicenseController.php:363 -#: src/Frontend/DownloadController.php:105 +#: src/Frontend/DownloadController.php:117 #: src/Frontend/AccountController.php:352 msgid "License not found." msgstr "" @@ -294,7 +298,6 @@ msgstr "" msgid "Expiration Warning Schedule" msgstr "" -#. translators: %s: URL to WooCommerce email settings #: src/Admin/SettingsController.php:223 #, php-format msgid "" @@ -368,6 +371,234 @@ msgstr "" msgid "License validation failed." 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 msgid "Overview" msgstr "" @@ -410,28 +641,6 @@ msgstr "" msgid "Copy failed" 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:1235 src/Admin/AdminController.php:1358 msgid "Revoked" @@ -514,11 +723,6 @@ msgstr "" msgid "License Dashboard" msgstr "" -#: src/Admin/AdminController.php:900 -#: src/Admin/DashboardWidgetController.php:147 -msgid "Total Licenses" -msgstr "" - #: src/Admin/AdminController.php:937 msgid "Attention:" msgstr "" @@ -566,7 +770,6 @@ msgstr "" msgid "License set to lifetime successfully." msgstr "" -#. translators: %d: number of licenses #: src/Admin/AdminController.php:1106 #, php-format msgid "%d license activated." @@ -574,7 +777,6 @@ msgid_plural "%d licenses activated." msgstr[0] "" msgstr[1] "" -#. translators: %d: number of licenses #: src/Admin/AdminController.php:1114 #, php-format msgid "%d license deactivated." @@ -582,7 +784,6 @@ msgid_plural "%d licenses deactivated." msgstr[0] "" msgstr[1] "" -#. translators: %d: number of licenses #: src/Admin/AdminController.php:1122 #, php-format msgid "%d license revoked." @@ -590,7 +791,6 @@ msgid_plural "%d licenses revoked." msgstr[0] "" msgstr[1] "" -#. translators: %d: number of licenses #: src/Admin/AdminController.php:1130 #, php-format msgid "%d license deleted." @@ -598,7 +798,6 @@ msgid_plural "%d licenses deleted." msgstr[0] "" msgstr[1] "" -#. translators: %d: number of licenses #: src/Admin/AdminController.php:1138 #, php-format msgid "%d license extended." @@ -618,7 +817,6 @@ msgstr "" msgid "No licenses to export." msgstr "" -#. translators: %d: number of licenses imported #: src/Admin/AdminController.php:1159 #, php-format msgid "%d license imported." @@ -626,7 +824,6 @@ msgid_plural "%d licenses imported." msgstr[0] "" msgstr[1] "" -#. translators: %d: number of licenses updated #: src/Admin/AdminController.php:1166 #, php-format msgid "%d updated." @@ -634,7 +831,6 @@ msgid_plural "%d updated." msgstr[0] "" msgstr[1] "" -#. translators: %d: number of licenses skipped #: src/Admin/AdminController.php:1174 #, php-format msgid "%d skipped." @@ -642,7 +838,6 @@ msgid_plural "%d skipped." msgstr[0] "" msgstr[1] "" -#. translators: %d: number of errors #: src/Admin/AdminController.php:1182 #, php-format msgid "%d error." @@ -718,18 +913,6 @@ msgstr "" msgid "Bulk Actions" 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:1460 msgid "Revoke" @@ -747,12 +930,6 @@ msgstr "" msgid "Extend 1 year" 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 msgid "Apply" msgstr "" @@ -847,11 +1024,6 @@ msgstr "" msgid "License is VALID" msgstr "" -#: src/Admin/AdminController.php:1609 src/Admin/VersionAdminController.php:81 -#: src/Admin/VersionAdminController.php:136 -msgid "Version" -msgstr "" - #: src/Admin/AdminController.php:1617 msgid "License is INVALID" msgstr "" @@ -967,216 +1139,25 @@ msgstr "" msgid "No domain specified" msgstr "" -#: src/Admin/VersionAdminController.php:58 -msgid "Product Versions" +#: src/Admin/DownloadWidgetController.php:46 +msgid "Download Statistics" msgstr "" -#: src/Admin/VersionAdminController.php:78 -msgid "Add New Version" +#: src/Admin/DownloadWidgetController.php:140 +msgid "Total Downloads" msgstr "" -#: src/Admin/VersionAdminController.php:84 -msgid "Use semantic versioning (e.g., 1.0.0)" +#: src/Admin/DownloadWidgetController.php:145 +msgid "Top Products" msgstr "" -#: src/Admin/VersionAdminController.php:88 -#: src/Admin/VersionAdminController.php:137 -msgid "Download File" +#: src/Admin/DownloadWidgetController.php:159 +#: src/Admin/DownloadWidgetController.php:180 +msgid "No downloads yet" 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: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" +#: src/Admin/DownloadWidgetController.php:163 +msgid "Top Versions" msgstr "" #: src/Api/RestApiController.php:84 @@ -1274,7 +1255,8 @@ msgstr "" msgid "This license is not valid for this domain." 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/LicenseExpiredEmail.php:99 msgid "Unknown Product" @@ -1284,7 +1266,6 @@ msgstr "" msgid "Attachment file not found." msgstr "" -#. translators: 1: provided hash, 2: calculated hash #: src/Product/VersionManager.php:177 #, php-format msgid "File checksum does not match. Expected: %1$s, Got: %2$s" @@ -1303,7 +1284,6 @@ msgstr "" msgid "%d days" msgstr "" -#. translators: %s: URL to settings page #: src/Product/LicensedProductType.php:119 #, php-format msgid "Leave fields empty to use default settings from %s." @@ -1317,7 +1297,6 @@ msgstr "" msgid "Max Activations" msgstr "" -#. translators: %d: default max activations value #: src/Product/LicensedProductType.php:131 #, php-format msgid "Maximum number of domain activations per license. Default: %d" @@ -1327,7 +1306,6 @@ msgstr "" msgid "License Validity (Days)" msgstr "" -#. translators: %s: default validity value #: src/Product/LicensedProductType.php:149 #, php-format msgid "Number of days the license is valid. Leave empty for default (%s)." @@ -1337,7 +1315,6 @@ msgstr "" msgid "Bind to Major Version" msgstr "" -#. translators: %s: default bind to version value (Yes/No) #: src/Product/LicensedProductType.php:167 #, php-format msgid "" @@ -1357,54 +1334,54 @@ msgstr "" msgid "Version:" msgstr "" -#: src/Frontend/DownloadController.php:65 -#: src/Frontend/DownloadController.php:89 +#: src/Frontend/DownloadController.php:77 +#: src/Frontend/DownloadController.php:101 msgid "Invalid download link." msgstr "" -#: src/Frontend/DownloadController.php:66 -#: src/Frontend/DownloadController.php:76 -#: src/Frontend/DownloadController.php:90 -#: src/Frontend/DownloadController.php:106 -#: src/Frontend/DownloadController.php:116 -#: src/Frontend/DownloadController.php:125 -#: src/Frontend/DownloadController.php:135 -#: src/Frontend/DownloadController.php:144 -#: src/Frontend/DownloadController.php:153 -#: src/Frontend/DownloadController.php:171 +#: 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:75 +#: src/Frontend/DownloadController.php:87 msgid "Invalid download link format." msgstr "" -#: src/Frontend/DownloadController.php:115 +#: src/Frontend/DownloadController.php:127 msgid "You do not have permission to download this file." msgstr "" -#: src/Frontend/DownloadController.php:124 +#: src/Frontend/DownloadController.php:136 msgid "Your license is not active. Please contact support." msgstr "" -#: src/Frontend/DownloadController.php:134 +#: src/Frontend/DownloadController.php:146 msgid "Version not found." msgstr "" -#: src/Frontend/DownloadController.php:143 +#: src/Frontend/DownloadController.php:155 msgid "Version does not match your licensed product." msgstr "" -#: src/Frontend/DownloadController.php:152 +#: src/Frontend/DownloadController.php:164 msgid "This version is no longer available for download." msgstr "" -#: src/Frontend/DownloadController.php:170 +#: src/Frontend/DownloadController.php:186 msgid "No download file available for this version." msgstr "" -#: src/Frontend/DownloadController.php:186 +#: src/Frontend/DownloadController.php:202 msgid "Download file not found." msgstr "" @@ -1560,7 +1537,6 @@ msgid "" "expiration date." msgstr "" -#. translators: %s: list of placeholders #: src/Email/LicenseExpirationEmail.php:301 #: src/Email/LicenseExpiredEmail.php:288 #, php-format @@ -1666,20 +1642,19 @@ msgstr "" msgid "To continue using this product, please renew your license." msgstr "" -#: src/Plugin.php:258 +#: src/Plugin.php:260 msgid "WC Licensed Product" msgstr "" -#: src/Plugin.php:259 +#: src/Plugin.php:261 msgid "" "Plugin license is not configured or invalid. Frontend features are disabled." msgstr "" -#: src/Plugin.php:260 +#: src/Plugin.php:262 msgid "Configure License" msgstr "" -#. translators: %s: WooCommerce plugin name #: wc-licensed-product.php:61 #, php-format msgid "%s requires WooCommerce to be installed and active." diff --git a/src/Admin/DashboardWidgetController.php b/src/Admin/DashboardWidgetController.php index fef22df..01d7669 100644 --- a/src/Admin/DashboardWidgetController.php +++ b/src/Admin/DashboardWidgetController.php @@ -55,7 +55,7 @@ final class DashboardWidgetController public function renderWidget(): void { $stats = $this->licenseManager->getStatistics(); - $licensesUrl = admin_url('admin.php?page=wc-licensed-product-licenses'); + $licensesUrl = admin_url('admin.php?page=wc-licenses'); ?> + +
+
+
+
+
+
+ +

+ +

+ +
    + +
  • + + + + +
  • + +
+ +

+ + +

+ +

+ +
    + +
  • + + + v + + + + +
  • + +
+ +

+ + getDownloadUrl(); if ($attachmentId) { + // Increment download count before serving + $this->versionManager->incrementDownloadCount($versionId); $this->serveAttachment($attachmentId, $version->getVersion()); } elseif ($downloadUrl) { + // Increment download count before redirect + $this->versionManager->incrementDownloadCount($versionId); // Redirect to external URL wp_redirect($downloadUrl); exit; diff --git a/src/Installer.php b/src/Installer.php index 57824b4..8f861b0 100644 --- a/src/Installer.php +++ b/src/Installer.php @@ -35,8 +35,9 @@ final class Installer // Set version in options 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('license-download', EP_ROOT | EP_PAGES); // Flush rewrite rules for REST API and My Account endpoints flush_rewrite_rules(); @@ -103,6 +104,7 @@ final class Installer download_url VARCHAR(512) DEFAULT NULL, attachment_id BIGINT UNSIGNED DEFAULT NULL, file_hash VARCHAR(64) DEFAULT NULL, + download_count BIGINT UNSIGNED NOT NULL DEFAULT 0, is_active TINYINT(1) NOT NULL DEFAULT 1, released_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, diff --git a/src/Plugin.php b/src/Plugin.php index 95d91c8..5b3bc37 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -11,6 +11,7 @@ namespace Jeremias\WcLicensedProduct; use Jeremias\WcLicensedProduct\Admin\AdminController; use Jeremias\WcLicensedProduct\Admin\DashboardWidgetController; +use Jeremias\WcLicensedProduct\Admin\DownloadWidgetController; use Jeremias\WcLicensedProduct\Admin\OrderLicenseController; use Jeremias\WcLicensedProduct\Admin\SettingsController; use Jeremias\WcLicensedProduct\Admin\VersionAdminController; @@ -154,6 +155,7 @@ final class Plugin new OrderLicenseController($this->licenseManager); new SettingsController(); new DashboardWidgetController($this->licenseManager); + new DownloadWidgetController($this->versionManager); // Show admin notice if unlicensed and not on localhost if (!$isLicensed && !$licenseChecker->isLocalhost()) { diff --git a/src/Product/ProductVersion.php b/src/Product/ProductVersion.php index 0fda75c..3099ec0 100644 --- a/src/Product/ProductVersion.php +++ b/src/Product/ProductVersion.php @@ -24,6 +24,7 @@ class ProductVersion private ?string $downloadUrl; private ?int $attachmentId; private ?string $fileHash; + private int $downloadCount; private bool $isActive; private \DateTimeInterface $releasedAt; private \DateTimeInterface $createdAt; @@ -44,6 +45,7 @@ class ProductVersion $version->downloadUrl = $data['download_url'] ?: null; $version->attachmentId = !empty($data['attachment_id']) ? (int) $data['attachment_id'] : null; $version->fileHash = $data['file_hash'] ?? null; + $version->downloadCount = (int) ($data['download_count'] ?? 0); $version->isActive = (bool) $data['is_active']; $version->releasedAt = new \DateTimeImmutable($data['released_at']); $version->createdAt = new \DateTimeImmutable($data['created_at']); @@ -144,6 +146,11 @@ class ProductVersion return $this->fileHash; } + public function getDownloadCount(): int + { + return $this->downloadCount; + } + /** * Get the download URL from attachment */ @@ -197,6 +204,7 @@ class ProductVersion 'download_url' => $this->downloadUrl, 'attachment_id' => $this->attachmentId, 'file_hash' => $this->fileHash, + 'download_count' => $this->downloadCount, 'is_active' => $this->isActive, 'released_at' => $this->releasedAt->format('Y-m-d H:i:s'), 'created_at' => $this->createdAt->format('Y-m-d H:i:s'), diff --git a/src/Product/VersionManager.php b/src/Product/VersionManager.php index 065dbf6..3d0d26c 100644 --- a/src/Product/VersionManager.php +++ b/src/Product/VersionManager.php @@ -276,4 +276,98 @@ class VersionManager 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, + ]; + } }