diff --git a/CHANGELOG.md b/CHANGELOG.md index fa1fb4a..af78363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.3.1] - 2026-01-22 + +### Changed + +- Settings page reorganized with sub-tab navigation similar to WooCommerce Advanced tab +- Settings split into three sections: Plugin License, Default Settings, Notifications +- Improved settings UI with WooCommerce-style section navigation + +### Technical Details + +- SettingsController refactored with `getSections()` and `outputSections()` methods +- Section-specific settings methods using PHP 8 match expression +- Hooks updated to use `woocommerce_sections_licensed_product` for sub-navigation + +## [0.3.0] - 2026-01-22 + +### Added + +- Self-licensing functionality: Plugin validates its own license against a remote server +- Plugin license settings in WooCommerce > Settings > Licensed Products tab +- License Server URL, License Key, and optional Server Secret configuration +- License status display in settings with verify button +- Localhost bypass: All features work without license when running on localhost +- Admin notice when plugin license is not configured or invalid + +### Changed + +- Frontend features now require a valid plugin license to function +- Disabled features without license: Checkout domain field, customer licenses page, downloads, license generation + +### Technical Details + +- New `PluginLicenseChecker` singleton class for license validation +- Integration with `magdev/wc-licensed-product-client` Composer package +- Caching: 1 hour for valid license, 5 minutes for errors +- Localhost detection supports: localhost, 127.0.0.1, ::1, and .localhost/.local subdomains + ## [0.2.2] - 2026-01-22 ### Added @@ -373,7 +410,9 @@ define('WC_LICENSE_SERVER_SECRET', 'your-secure-random-string-min-32-chars'); - WordPress REST API integration - Custom WooCommerce product type extending WC_Product -[Unreleased]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.2.2...HEAD +[Unreleased]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.3.1...HEAD +[0.3.1]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.3.0...v0.3.1 +[0.3.0]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.2.2...v0.3.0 [0.2.2]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.2.1...v0.2.2 [0.2.1]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.2.0...v0.2.1 [0.2.0]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.1.0...v0.2.0 diff --git a/composer.json b/composer.json index 5ddf555..8ab4eff 100644 --- a/composer.json +++ b/composer.json @@ -10,9 +10,16 @@ "homepage": "https://src.bundespruefstelle.ch/magdev" } ], + "repositories": [ + { + "type": "path", + "url": "/home/magdev/workspaces/php/wc-licensed-product-client" + } + ], "require": { "php": ">=8.3.0", - "twig/twig": "^3.0" + "twig/twig": "^3.0", + "magdev/wc-licensed-product-client": "dev-main" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index d85e21b..f1d3041 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,314 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3b63b77b19677953867f471c141fee05", + "content-hash": "0387e179142771dbc12a8dba42895bd0", "packages": [ + { + "name": "magdev/wc-licensed-product-client", + "version": "dev-main", + "dist": { + "type": "path", + "url": "/home/magdev/workspaces/php/wc-licensed-product-client", + "reference": "83037ea0c2d9e365cf9ec0ad50251d3ebc7e4782" + }, + "require": { + "php": "^8.3", + "psr/cache": "^3.0", + "psr/http-client": "^1.0", + "psr/log": "^3.0", + "symfony/http-client": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Magdev\\WcLicensedProductClient\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Magdev\\WcLicensedProductClient\\Tests\\": "tests/" + } + }, + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Marco Graetsch", + "email": "magdev3.0@gmail.com", + "homepage": "https://src.bundespruefstelle.ch/magdev" + } + ], + "description": "Client library for WooCommerce Licensed Product Plugin - Activate, validate and check the status of licenses via REST API", + "homepage": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client", + "support": { + "issues": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client/issues", + "source": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client" + }, + "transport-options": { + "relative": false + } + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, { "name": "symfony/deprecation-contracts", "version": "v3.6.0", @@ -73,6 +379,185 @@ ], "time": "2024-09-25T14:21:43+00:00" }, + { + "name": "symfony/http-client", + "version": "v7.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "d01dfac1e0dc99f18da48b18101c23ce57929616" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/d01dfac1e0dc99f18da48b18101c23ce57929616", + "reference": "d01dfac1e0dc99f18da48b18101c23ce57929616", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", + "symfony/polyfill-php83": "^1.29", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "amphp/amp": "<2.5", + "amphp/socket": "<1.1", + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/http-client": "^4.2.1|^5.0", + "amphp/http-tunnel": "^1.0|^2.0", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/amphp-http-client-meta": "^1.0|^2.0", + "symfony/cache": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/rate-limiter": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-12-23T14:50:43+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "75d7043853a42837e68111812f4d964b01e5101c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/75d7043853a42837e68111812f4d964b01e5101c", + "reference": "75d7043853a42837e68111812f4d964b01e5101c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-04-29T11:18:49+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.33.0", @@ -241,6 +726,173 @@ ], "time": "2024-12-23T08:48:59+00:00" }, + { + "name": "symfony/polyfill-php83", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-08T02:45:35+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T11:30:57+00:00" + }, { "name": "twig/twig", "version": "v3.22.2", @@ -324,7 +976,9 @@ "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": { + "magdev/wc-licensed-product-client": 20 + }, "prefer-stable": true, "prefer-lowest": false, "platform": { diff --git a/languages/wc-licensed-product-de_CH.mo b/languages/wc-licensed-product-de_CH.mo index e3dcc68..e0a6365 100644 Binary files a/languages/wc-licensed-product-de_CH.mo and b/languages/wc-licensed-product-de_CH.mo differ diff --git a/languages/wc-licensed-product-de_CH.po b/languages/wc-licensed-product-de_CH.po index 177c2e3..f763c62 100644 --- a/languages/wc-licensed-product-de_CH.po +++ b/languages/wc-licensed-product-de_CH.po @@ -3,9 +3,9 @@ # This file is distributed under the GPL-2.0-or-later. msgid "" msgstr "" -"Project-Id-Version: WC Licensed Product 0.2.1\n" +"Project-Id-Version: WC Licensed Product 0.3.1\n" "Report-Msgid-Bugs-To: magdev3.0@gmail.com\n" -"POT-Creation-Date: 2026-01-22 17:32+0100\n" +"POT-Creation-Date: 2026-01-22 18:30+0100\n" "PO-Revision-Date: 2026-01-22T17:15:00+00:00\n" "Last-Translator: Marco Graetsch \n" "Language-Team: German (Switzerland) \n" @@ -15,29 +15,373 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: wc-licensed-product.php:61 -#, php-format -msgid "%s requires WooCommerce to be installed and active." -msgstr "%s benötigt WooCommerce als installierte und aktivierte Erweiterung." +#: src/Admin/SettingsController.php:54 +msgid "Licensed Products" +msgstr "Lizensierte Produkte" -#: wc-licensed-product.php:119 -msgid "WC Licensed Product requires WooCommerce to be installed and active." +#: src/Admin/SettingsController.php:64 src/Admin/SettingsController.php:128 +msgid "Plugin License" +msgstr "Plugin-Lizenz" + +#: src/Admin/SettingsController.php:65 +msgid "Default Settings" +msgstr "Standardeinstellungen" + +#: src/Admin/SettingsController.php:66 +msgid "Notifications" +msgstr "Benachrichtigungen" + +#: src/Admin/SettingsController.php:130 +msgid "" +"Configure the license for this plugin. A valid license is required for " +"frontend features to work." msgstr "" -"WC Licensed Product benötigt WooCommerce als installierte und aktivierte " -"Erweiterung." +"Konfigurieren Sie die Lizenz für dieses Plugin. Eine gültige Lizenz ist " +"erforderlich, damit die Frontend-Funktionen funktionieren." -#: wc-licensed-product.php:137 src/Admin/AdminController.php:936 -msgid "Settings" -msgstr "Einstellungen" +#: src/Admin/SettingsController.php:134 +msgid "License Server URL" +msgstr "Lizenzserver-URL" + +#: src/Admin/SettingsController.php:136 +msgid "The URL of the license server (e.g., https://shop.example.com)." +msgstr "Die URL des Lizenzservers (z.B. https://shop.example.com)." + +#: src/Admin/SettingsController.php:142 +#: src/Admin/OrderLicenseController.php:144 src/Admin/AdminController.php:1253 +#: src/Admin/AdminController.php:1391 src/Email/LicenseEmailController.php:230 +msgid "License Key" +msgstr "Lizenzschlüssel" + +#: src/Admin/SettingsController.php:144 +msgid "Your license key in XXXX-XXXX-XXXX-XXXX format." +msgstr "Ihr Lizenzschlüssel im Format XXXX-XXXX-XXXX-XXXX." + +#: src/Admin/SettingsController.php:150 +msgid "Server Secret (Optional)" +msgstr "Server-Secret (Optional)" + +#: src/Admin/SettingsController.php:152 +msgid "" +"If the license server uses signed responses, enter the shared secret here " +"for enhanced security." +msgstr "" +"Falls der Lizenzserver signierte Antworten verwendet, geben Sie hier das " +"gemeinsame Secret für erhöhte Sicherheit ein." + +#: src/Admin/SettingsController.php:170 +msgid "Default License Settings" +msgstr "Standard Lizenz-Einstellungen" + +#: src/Admin/SettingsController.php:172 +msgid "" +"These settings serve as defaults for new licensed products. Individual " +"product settings override these defaults." +msgstr "" +"Diese Einstellungen dienen als Standard für neue lizensierte Produkte. " +"Individuelle Produkteinstellungen überschreiben diese Standards." + +#: src/Admin/SettingsController.php:176 +msgid "Default Max Activations" +msgstr "Standard Max. Aktivierungen" + +#: src/Admin/SettingsController.php:178 +msgid "Default maximum number of domain activations per license." +msgstr "Standard maximale Anzahl der Domain-Aktivierungen pro Lizenz." + +#: src/Admin/SettingsController.php:187 +msgid "Default License Validity (Days)" +msgstr "Standard Lizenz-Gültigkeit (Tage)" + +#: src/Admin/SettingsController.php:189 +msgid "" +"Default number of days a license is valid. Leave empty or set to 0 for " +"lifetime licenses." +msgstr "" +"Standard Anzahl Tage, die eine Lizenz gültig ist. Leer lassen oder auf 0 " +"setzen für lebenslange Lizenzen." + +#: src/Admin/SettingsController.php:192 +#: src/Admin/OrderLicenseController.php:201 src/Admin/AdminController.php:148 +#: src/Admin/AdminController.php:263 src/Admin/AdminController.php:1335 +#: src/Product/LicensedProductType.php:104 +#: src/Product/LicensedProductType.php:152 +msgid "Lifetime" +msgstr "Lebenslang" + +#: src/Admin/SettingsController.php:199 +msgid "Default Bind to Major Version" +msgstr "Standard An Hauptversion binden" + +#: src/Admin/SettingsController.php:201 +msgid "" +"If enabled, licenses are bound to the major version at purchase time by " +"default." +msgstr "" +"Falls aktiviert, werden Lizenzen standardmässig an die Hauptversion zum " +"Kaufzeitpunkt gebunden." + +#: src/Admin/SettingsController.php:219 +msgid "Expiration Warning Schedule" +msgstr "Ablaufwarnung Zeitplan" + +#: 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." + +#: src/Admin/SettingsController.php:225 +msgid "WooCommerce > Settings > Emails > License Expiration Warning" +msgstr "WooCommerce > Einstellungen > E-Mails > Lizenzablauf-Warnung" + +#: src/Admin/SettingsController.php:230 +msgid "First Warning (Days Before)" +msgstr "Erste Warnung (Tage vorher)" + +#: src/Admin/SettingsController.php:232 +msgid "Days before expiration to send the first warning email." +msgstr "Tage vor Ablauf, um die erste Warn-E-Mail zu senden." + +#: src/Admin/SettingsController.php:241 +msgid "Second Warning (Days Before)" +msgstr "Zweite Warnung (Tage vorher)" + +#: src/Admin/SettingsController.php:243 +msgid "" +"Days before expiration to send the second warning email. Set to 0 to disable." +msgstr "" +"Tage vor Ablauf, um die zweite Warn-E-Mail zu senden. Setzen Sie auf 0, um " +"sie zu deaktivieren." + +#: src/Admin/SettingsController.php:283 +msgid "Running on localhost - license validation bypassed." +msgstr "Läuft auf localhost - Lizenzvalidierung übersprungen." + +#: src/Admin/SettingsController.php:291 +msgid "License is valid and active." +msgstr "Lizenz ist gültig und aktiv." + +#: src/Admin/SettingsController.php:297 +msgid "License is not valid. Frontend features are disabled." +msgstr "Lizenz ist ungültig. Frontend-Funktionen sind deaktiviert." + +#: src/Admin/SettingsController.php:308 src/Admin/SettingsController.php:344 +msgid "Verify License" +msgstr "Lizenz überprüfen" + +#: src/Admin/SettingsController.php:322 +msgid "Verifying..." +msgstr "Überprüfe..." + +#: src/Admin/SettingsController.php:341 +msgid "Request failed." +msgstr "Anfrage fehlgeschlagen." + +#: src/Admin/SettingsController.php:454 src/Admin/AdminController.php:428 +#: src/Admin/AdminController.php:448 src/Admin/AdminController.php:466 +#: src/Admin/AdminController.php:484 src/Admin/AdminController.php:504 +#: src/Admin/AdminController.php:522 src/Admin/AdminController.php:589 +#: src/Admin/AdminController.php:779 src/Frontend/AccountController.php:326 +msgid "Security check failed." +msgstr "Sicherheitsüberprüfung fehlgeschlagen." + +#: src/Admin/SettingsController.php:458 +msgid "Insufficient permissions." +msgstr "Unzureichende Berechtigungen." + +#: src/Admin/SettingsController.php:467 +msgid "License verified successfully!" +msgstr "Lizenz erfolgreich überprüft!" + +#: src/Admin/SettingsController.php:469 +msgid "License validation failed." +msgstr "Lizenzvalidierung fehlgeschlagen." + +#: src/Admin/OrderLicenseController.php:56 +msgid "Product Licenses" +msgstr "Produktlizenzen" + +#: src/Admin/OrderLicenseController.php:77 +#: src/Admin/OrderLicenseController.php:313 +msgid "Order not found." +msgstr "Bestellung nicht gefunden." + +#: src/Admin/OrderLicenseController.php:92 +msgid "This order does not contain licensed products." +msgstr "Diese Bestellung enthält keine lizensierten Produkte." + +#: src/Admin/OrderLicenseController.php:106 +msgid "Order Domain" +msgstr "Bestellungs-Domain" + +#: src/Admin/OrderLicenseController.php:108 +msgid "" +"The domain specified during checkout. Changing this will not automatically " +"update existing license domains." +msgstr "" +"Die bei der Bestellung angegebene Domain. Eine Änderung aktualisiert nicht " +"automatisch bestehende Lizenz-Domains." + +#: src/Admin/OrderLicenseController.php:116 +#: src/Checkout/CheckoutController.php:89 +#: src/Checkout/CheckoutBlocksIntegration.php:102 +msgid "example.com" +msgstr "beispiel.ch" + +#: src/Admin/OrderLicenseController.php:118 +#: src/Admin/OrderLicenseController.php:182 src/Admin/AdminController.php:147 +#: src/Admin/AdminController.php:1302 src/Admin/AdminController.php:1322 +#: src/Admin/AdminController.php:1343 +msgid "Save" +msgstr "Speichern" -#: src/Admin/AdminController.php:73 src/Admin/AdminController.php:74 -#: src/Admin/AdminController.php:87 src/Admin/AdminController.php:1162 #: src/Admin/OrderLicenseController.php:127 -#: src/Admin/OrderLicenseController.php:222 -#: src/Frontend/AccountController.php:90 +#: src/Admin/OrderLicenseController.php:222 src/Admin/AdminController.php:73 +#: src/Admin/AdminController.php:74 src/Admin/AdminController.php:87 +#: src/Admin/AdminController.php:1162 src/Frontend/AccountController.php:90 msgid "Licenses" msgstr "Lizenzen" +#: src/Admin/OrderLicenseController.php:131 +msgid "No licenses have been generated for this order yet." +msgstr "Für diese Bestellung wurden noch keine Lizenzen generiert." + +#: src/Admin/OrderLicenseController.php:134 +msgid "" +"Licenses should be generated automatically when an order is paid. If " +"missing, check that a domain was specified during checkout." +msgstr "" +"Lizenzen sollten automatisch generiert werden, wenn eine Bestellung bezahlt " +"wird. Falls fehlend, prüfen Sie, ob bei der Bestellung eine Domain angegeben " +"wurde." + +#: src/Admin/OrderLicenseController.php:137 +msgid "Licenses will be generated when the order is marked as paid/completed." +msgstr "" +"Lizenzen werden generiert, sobald die Bestellung als bezahlt/abgeschlossen " +"markiert wird." + +#: src/Admin/OrderLicenseController.php:145 src/Admin/AdminController.php:1254 +#: src/Admin/AdminController.php:1392 src/Email/LicenseEmailController.php:229 +msgid "Product" +msgstr "Produkt" + +#: src/Admin/OrderLicenseController.php:146 src/Admin/AdminController.php:1256 +#: src/Admin/AdminController.php:1394 +msgid "Domain" +msgstr "Domain" + +#: src/Admin/OrderLicenseController.php:147 src/Admin/AdminController.php:1257 +#: src/Admin/AdminController.php:1395 src/Admin/VersionAdminController.php:140 +msgid "Status" +msgstr "Status" + +#: src/Admin/OrderLicenseController.php:148 src/Admin/AdminController.php:1259 +#: src/Admin/AdminController.php:1397 src/Email/LicenseEmailController.php:231 +msgid "Expires" +msgstr "Läuft ab" + +#: src/Admin/OrderLicenseController.php:149 src/Admin/AdminController.php:1260 +#: src/Admin/AdminController.php:1398 src/Admin/VersionAdminController.php:142 +msgid "Actions" +msgstr "Aktionen" + +#: src/Admin/OrderLicenseController.php:168 src/Admin/AdminController.php:192 +#: src/Admin/AdminController.php:987 +msgid "Unknown" +msgstr "Unbekannt" + +#: src/Admin/OrderLicenseController.php:178 +msgid "Edit domain" +msgstr "Domain bearbeiten" + +#: src/Admin/OrderLicenseController.php:185 src/Admin/AdminController.php:146 +#: src/Admin/AdminController.php:1303 src/Admin/AdminController.php:1323 +#: src/Admin/AdminController.php:1344 src/Frontend/AccountController.php:271 +msgid "Cancel" +msgstr "Abbrechen" + +#: src/Admin/OrderLicenseController.php:208 +msgid "View in Licenses" +msgstr "In Lizenzen anzeigen" + +#: src/Admin/OrderLicenseController.php:221 +#, php-format +msgid "For more actions (revoke, extend, delete), go to the %s page." +msgstr "" +"Für weitere Aktionen (widerrufen, verlängern, löschen), gehen Sie zur Seite " +"%s." + +#: src/Admin/OrderLicenseController.php:285 src/Admin/AdminController.php:141 +msgid "Saving..." +msgstr "Speichere..." + +#: src/Admin/OrderLicenseController.php:286 +msgid "Saved!" +msgstr "Gespeichert!" + +#: src/Admin/OrderLicenseController.php:287 +msgid "Error saving. Please try again." +msgstr "Fehler beim Speichern. Bitte versuchen Sie es erneut." + +#: src/Admin/OrderLicenseController.php:288 +#: src/Frontend/AccountController.php:314 +#: src/Frontend/AccountController.php:346 +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:170 +#: src/Admin/AdminController.php:210 src/Admin/AdminController.php:246 +#: src/Admin/AdminController.php:298 src/Admin/AdminController.php:336 +#: src/Admin/VersionAdminController.php:259 +#: src/Admin/VersionAdminController.php:328 +#: src/Admin/VersionAdminController.php:354 +msgid "Permission denied." +msgstr "Zugriff verweigert." + +#: src/Admin/OrderLicenseController.php:308 +msgid "Invalid order ID." +msgstr "Ungültige Bestellungs-ID." + +#: src/Admin/OrderLicenseController.php:319 +#: src/Admin/OrderLicenseController.php:357 +msgid "Invalid domain format." +msgstr "Ungültiges Domain-Format." + +#: src/Admin/OrderLicenseController.php:327 +msgid "Order domain updated." +msgstr "Bestellungs-Domain aktualisiert." + +#: src/Admin/OrderLicenseController.php:347 src/Admin/AdminController.php:217 +#: src/Admin/AdminController.php:253 src/Admin/AdminController.php:305 +#: src/Admin/AdminController.php:342 +msgid "Invalid license ID." +msgstr "Ungültige Lizenz-ID." + +#: src/Admin/OrderLicenseController.php:351 src/Admin/AdminController.php:309 +msgid "Domain cannot be empty." +msgstr "Domain darf nicht leer sein." + +#: src/Admin/OrderLicenseController.php:363 +#: src/Frontend/DownloadController.php:105 +#: src/Frontend/AccountController.php:352 +msgid "License not found." +msgstr "Lizenz nicht gefunden." + +#: src/Admin/OrderLicenseController.php:371 +msgid "License domain updated." +msgstr "Lizenz-Domain aktualisiert." + +#: src/Admin/OrderLicenseController.php:375 +msgid "Failed to update license domain." +msgstr "Lizenz-Domain konnte nicht aktualisiert werden." + #: src/Admin/AdminController.php:90 msgid "Overview" msgstr "Übersicht" @@ -54,10 +398,6 @@ msgstr "Suche..." msgid "Search failed" msgstr "Suche fehlgeschlagen" -#: src/Admin/AdminController.php:141 src/Admin/OrderLicenseController.php:285 -msgid "Saving..." -msgstr "Speichere..." - #: src/Admin/AdminController.php:142 msgid "Saved" msgstr "Gespeichert" @@ -78,27 +418,6 @@ msgstr "" msgid "Edit" msgstr "Bearbeiten" -#: src/Admin/AdminController.php:146 src/Admin/AdminController.php:1303 -#: src/Admin/AdminController.php:1323 src/Admin/AdminController.php:1344 -#: src/Admin/OrderLicenseController.php:185 -#: src/Frontend/AccountController.php:271 -msgid "Cancel" -msgstr "Abbrechen" - -#: src/Admin/AdminController.php:147 src/Admin/AdminController.php:1302 -#: src/Admin/AdminController.php:1322 src/Admin/AdminController.php:1343 -#: src/Admin/OrderLicenseController.php:118 -#: src/Admin/OrderLicenseController.php:182 -msgid "Save" -msgstr "Speichern" - -#: src/Admin/AdminController.php:148 src/Admin/AdminController.php:263 -#: src/Admin/AdminController.php:1335 src/Admin/OrderLicenseController.php:201 -#: src/Admin/SettingsController.php:78 src/Product/LicensedProductType.php:104 -#: src/Product/LicensedProductType.php:152 -msgid "Lifetime" -msgstr "Lebenslang" - #: src/Admin/AdminController.php:149 src/Frontend/AccountController.php:309 msgid "Copied!" msgstr "Kopiert!" @@ -109,15 +428,15 @@ msgstr "Kopieren fehlgeschlagen" #: src/Admin/AdminController.php:153 src/Admin/AdminController.php:875 #: src/Admin/AdminController.php:1194 src/Admin/AdminController.php:1317 -#: src/Admin/VersionAdminController.php:180 -#: src/Admin/VersionAdminController.php:409 +#: src/Admin/VersionAdminController.php:182 +#: src/Admin/VersionAdminController.php:413 msgid "Active" msgstr "Aktiv" #: src/Admin/AdminController.php:154 src/Admin/AdminController.php:882 #: src/Admin/AdminController.php:1195 src/Admin/AdminController.php:1318 -#: src/Admin/VersionAdminController.php:180 -#: src/Admin/VersionAdminController.php:409 +#: src/Admin/VersionAdminController.php:182 +#: src/Admin/VersionAdminController.php:413 msgid "Inactive" msgstr "Inaktiv" @@ -131,31 +450,10 @@ msgstr "Abgelaufen" msgid "Revoked" msgstr "Widerrufen" -#: src/Admin/AdminController.php:170 src/Admin/AdminController.php:210 -#: src/Admin/AdminController.php:246 src/Admin/AdminController.php:298 -#: src/Admin/AdminController.php:336 src/Admin/OrderLicenseController.php:301 -#: src/Admin/OrderLicenseController.php:340 -#: src/Admin/VersionAdminController.php:257 -#: src/Admin/VersionAdminController.php:326 -#: src/Admin/VersionAdminController.php:352 -msgid "Permission denied." -msgstr "Zugriff verweigert." - -#: src/Admin/AdminController.php:192 src/Admin/AdminController.php:987 -#: src/Admin/OrderLicenseController.php:168 -msgid "Unknown" -msgstr "Unbekannt" - #: src/Admin/AdminController.php:193 src/Admin/AdminController.php:991 msgid "Guest" msgstr "Gast" -#: src/Admin/AdminController.php:217 src/Admin/AdminController.php:253 -#: src/Admin/AdminController.php:305 src/Admin/AdminController.php:342 -#: src/Admin/OrderLicenseController.php:347 -msgid "Invalid license ID." -msgstr "Ungültige Lizenz-ID." - #: src/Admin/AdminController.php:222 msgid "Invalid status." msgstr "Ungültiger Status." @@ -184,10 +482,6 @@ msgstr "Ablaufdatum erfolgreich aktualisiert." msgid "Invalid date format." msgstr "Ungültiges Datumsformat." -#: src/Admin/AdminController.php:309 src/Admin/OrderLicenseController.php:351 -msgid "Domain cannot be empty." -msgstr "Domain darf nicht leer sein." - #: src/Admin/AdminController.php:320 msgid "Domain updated successfully." msgstr "Domain erfolgreich aktualisiert." @@ -204,14 +498,6 @@ msgstr "Lizenz erfolgreich widerrufen." msgid "Failed to revoke license." msgstr "Lizenz konnte nicht widerrufen werden." -#: src/Admin/AdminController.php:428 src/Admin/AdminController.php:448 -#: src/Admin/AdminController.php:466 src/Admin/AdminController.php:484 -#: src/Admin/AdminController.php:504 src/Admin/AdminController.php:522 -#: src/Admin/AdminController.php:589 src/Admin/AdminController.php:779 -#: src/Frontend/AccountController.php:326 -msgid "Security check failed." -msgstr "Sicherheitsüberprüfung fehlgeschlagen." - #: src/Admin/AdminController.php:549 msgid "You do not have permission to export licenses." msgstr "Sie haben keine Berechtigung, Lizenzen zu exportieren." @@ -268,6 +554,10 @@ msgstr "Lizenzen verwalten" msgid "Export to CSV" msgstr "Als CSV exportieren" +#: src/Admin/AdminController.php:936 wc-licensed-product.php:137 +msgid "Settings" +msgstr "Einstellungen" + #: src/Admin/AdminController.php:1050 msgid "License updated successfully." msgstr "Lizenz erfolgreich aktualisiert." @@ -430,14 +720,14 @@ msgid "Bulk Actions" msgstr "Massenaktionen" #: src/Admin/AdminController.php:1235 src/Admin/AdminController.php:1407 -#: src/Admin/VersionAdminController.php:186 -#: src/Admin/VersionAdminController.php:415 +#: src/Admin/VersionAdminController.php:188 +#: src/Admin/VersionAdminController.php:419 msgid "Activate" msgstr "Aktivieren" #: src/Admin/AdminController.php:1236 src/Admin/AdminController.php:1408 -#: src/Admin/VersionAdminController.php:186 -#: src/Admin/VersionAdminController.php:415 +#: src/Admin/VersionAdminController.php:188 +#: src/Admin/VersionAdminController.php:419 msgid "Deactivate" msgstr "Deaktivieren" @@ -459,8 +749,8 @@ msgid "Extend 1 year" msgstr "1 Jahr verlängern" #: src/Admin/AdminController.php:1241 src/Admin/AdminController.php:1377 -#: src/Admin/AdminController.php:1413 src/Admin/VersionAdminController.php:189 -#: src/Admin/VersionAdminController.php:418 +#: src/Admin/AdminController.php:1413 src/Admin/VersionAdminController.php:191 +#: src/Admin/VersionAdminController.php:422 msgid "Delete" msgstr "Löschen" @@ -468,50 +758,15 @@ msgstr "Löschen" msgid "Apply" msgstr "Anwenden" -#: src/Admin/AdminController.php:1253 src/Admin/AdminController.php:1391 -#: src/Admin/OrderLicenseController.php:144 -#: src/Email/LicenseEmailController.php:230 -msgid "License Key" -msgstr "Lizenzschlüssel" - -#: src/Admin/AdminController.php:1254 src/Admin/AdminController.php:1392 -#: src/Admin/OrderLicenseController.php:145 -#: src/Email/LicenseEmailController.php:229 -msgid "Product" -msgstr "Produkt" - #: src/Admin/AdminController.php:1255 src/Admin/AdminController.php:1393 #: src/Email/LicenseExpirationEmail.php:104 msgid "Customer" msgstr "Kunde" -#: src/Admin/AdminController.php:1256 src/Admin/AdminController.php:1394 -#: src/Admin/OrderLicenseController.php:146 -msgid "Domain" -msgstr "Domain" - -#: src/Admin/AdminController.php:1257 src/Admin/AdminController.php:1395 -#: src/Admin/OrderLicenseController.php:147 -#: src/Admin/VersionAdminController.php:140 -msgid "Status" -msgstr "Status" - #: src/Admin/AdminController.php:1258 src/Admin/AdminController.php:1396 msgid "Created" msgstr "Erstellt" -#: src/Admin/AdminController.php:1259 src/Admin/AdminController.php:1397 -#: src/Admin/OrderLicenseController.php:148 -#: src/Email/LicenseEmailController.php:231 -msgid "Expires" -msgstr "Läuft ab" - -#: src/Admin/AdminController.php:1260 src/Admin/AdminController.php:1398 -#: src/Admin/OrderLicenseController.php:149 -#: src/Admin/VersionAdminController.php:142 -msgid "Actions" -msgstr "Aktionen" - #: src/Admin/AdminController.php:1266 msgid "No licenses found." msgstr "Keine Lizenzen gefunden." @@ -644,197 +899,6 @@ msgstr "Lizenz" msgid "No domain specified" msgstr "Keine Domain angegeben" -#: src/Admin/OrderLicenseController.php:56 -msgid "Product Licenses" -msgstr "Produktlizenzen" - -#: src/Admin/OrderLicenseController.php:77 -#: src/Admin/OrderLicenseController.php:313 -msgid "Order not found." -msgstr "Bestellung nicht gefunden." - -#: src/Admin/OrderLicenseController.php:92 -msgid "This order does not contain licensed products." -msgstr "Diese Bestellung enthält keine lizensierten Produkte." - -#: src/Admin/OrderLicenseController.php:106 -msgid "Order Domain" -msgstr "Bestellungs-Domain" - -#: src/Admin/OrderLicenseController.php:108 -msgid "" -"The domain specified during checkout. Changing this will not automatically " -"update existing license domains." -msgstr "" -"Die bei der Bestellung angegebene Domain. Eine Änderung aktualisiert nicht " -"automatisch bestehende Lizenz-Domains." - -#: src/Admin/OrderLicenseController.php:116 -#: src/Checkout/CheckoutBlocksIntegration.php:102 -#: src/Checkout/CheckoutController.php:89 -msgid "example.com" -msgstr "beispiel.ch" - -#: src/Admin/OrderLicenseController.php:131 -msgid "No licenses have been generated for this order yet." -msgstr "Für diese Bestellung wurden noch keine Lizenzen generiert." - -#: src/Admin/OrderLicenseController.php:134 -msgid "" -"Licenses should be generated automatically when an order is paid. If " -"missing, check that a domain was specified during checkout." -msgstr "" -"Lizenzen sollten automatisch generiert werden, wenn eine Bestellung bezahlt " -"wird. Falls fehlend, prüfen Sie, ob bei der Bestellung eine Domain angegeben " -"wurde." - -#: src/Admin/OrderLicenseController.php:137 -msgid "Licenses will be generated when the order is marked as paid/completed." -msgstr "" -"Lizenzen werden generiert, sobald die Bestellung als bezahlt/abgeschlossen " -"markiert wird." - -#: src/Admin/OrderLicenseController.php:178 -msgid "Edit domain" -msgstr "Domain bearbeiten" - -#: src/Admin/OrderLicenseController.php:208 -msgid "View in Licenses" -msgstr "In Lizenzen anzeigen" - -#: src/Admin/OrderLicenseController.php:221 -#, php-format -msgid "For more actions (revoke, extend, delete), go to the %s page." -msgstr "" -"Für weitere Aktionen (widerrufen, verlängern, löschen), gehen Sie zur Seite " -"%s." - -#: src/Admin/OrderLicenseController.php:286 -msgid "Saved!" -msgstr "Gespeichert!" - -#: src/Admin/OrderLicenseController.php:287 -msgid "Error saving. Please try again." -msgstr "Fehler beim Speichern. Bitte versuchen Sie es erneut." - -#: src/Admin/OrderLicenseController.php:288 -#: src/Frontend/AccountController.php:314 -#: src/Frontend/AccountController.php:346 -msgid "Please enter a valid domain." -msgstr "Bitte geben Sie eine gültige Domain ein." - -#: src/Admin/OrderLicenseController.php:308 -msgid "Invalid order ID." -msgstr "Ungültige Bestellungs-ID." - -#: src/Admin/OrderLicenseController.php:319 -#: src/Admin/OrderLicenseController.php:357 -msgid "Invalid domain format." -msgstr "Ungültiges Domain-Format." - -#: src/Admin/OrderLicenseController.php:327 -msgid "Order domain updated." -msgstr "Bestellungs-Domain aktualisiert." - -#: src/Admin/OrderLicenseController.php:363 -#: src/Frontend/AccountController.php:352 -#: src/Frontend/DownloadController.php:105 -msgid "License not found." -msgstr "Lizenz nicht gefunden." - -#: src/Admin/OrderLicenseController.php:371 -msgid "License domain updated." -msgstr "Lizenz-Domain aktualisiert." - -#: src/Admin/OrderLicenseController.php:375 -msgid "Failed to update license domain." -msgstr "Lizenz-Domain konnte nicht aktualisiert werden." - -#: src/Admin/SettingsController.php:45 -msgid "Licensed Products" -msgstr "Lizensierte Produkte" - -#: src/Admin/SettingsController.php:56 -msgid "Default License Settings" -msgstr "Standard Lizenz-Einstellungen" - -#: src/Admin/SettingsController.php:58 -msgid "" -"These settings serve as defaults for new licensed products. Individual " -"product settings override these defaults." -msgstr "" -"Diese Einstellungen dienen als Standard für neue lizensierte Produkte. " -"Individuelle Produkteinstellungen überschreiben diese Standards." - -#: src/Admin/SettingsController.php:62 -msgid "Default Max Activations" -msgstr "Standard Max. Aktivierungen" - -#: src/Admin/SettingsController.php:64 -msgid "Default maximum number of domain activations per license." -msgstr "Standard maximale Anzahl der Domain-Aktivierungen pro Lizenz." - -#: src/Admin/SettingsController.php:73 -msgid "Default License Validity (Days)" -msgstr "Standard Lizenz-Gültigkeit (Tage)" - -#: src/Admin/SettingsController.php:75 -msgid "" -"Default number of days a license is valid. Leave empty or set to 0 for " -"lifetime licenses." -msgstr "" -"Standard Anzahl Tage, die eine Lizenz gültig ist. Leer lassen oder auf 0 " -"setzen für lebenslange Lizenzen." - -#: src/Admin/SettingsController.php:85 -msgid "Default Bind to Major Version" -msgstr "Standard An Hauptversion binden" - -#: src/Admin/SettingsController.php:87 -msgid "" -"If enabled, licenses are bound to the major version at purchase time by " -"default." -msgstr "" -"Falls aktiviert, werden Lizenzen standardmässig an die Hauptversion zum " -"Kaufzeitpunkt gebunden." - -#: src/Admin/SettingsController.php:97 -msgid "Expiration Warning Schedule" -msgstr "Ablaufwarnung Zeitplan" - -#: src/Admin/SettingsController.php:101 -#, 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." - -#: src/Admin/SettingsController.php:103 -msgid "WooCommerce > Settings > Emails > License Expiration Warning" -msgstr "WooCommerce > Einstellungen > E-Mails > Lizenzablauf-Warnung" - -#: src/Admin/SettingsController.php:108 -msgid "First Warning (Days Before)" -msgstr "Erste Warnung (Tage vorher)" - -#: src/Admin/SettingsController.php:110 -msgid "Days before expiration to send the first warning email." -msgstr "Tage vor Ablauf, um die erste Warn-E-Mail zu senden." - -#: src/Admin/SettingsController.php:119 -msgid "Second Warning (Days Before)" -msgstr "Zweite Warnung (Tage vorher)" - -#: src/Admin/SettingsController.php:121 -msgid "" -"Days before expiration to send the second warning email. Set to 0 to disable." -msgstr "" -"Tage vor Ablauf, um die zweite Warn-E-Mail zu senden. Setzen Sie auf 0, um " -"sie zu deaktivieren." - #: src/Admin/VersionAdminController.php:58 msgid "Product Versions" msgstr "Produktversionen" @@ -914,99 +978,99 @@ msgstr "Veröffentlicht" 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:164 -#: src/Admin/VersionAdminController.php:393 +#: src/Admin/VersionAdminController.php:165 +#: src/Admin/VersionAdminController.php:396 msgid "Uploaded file" msgstr "Hochgeladene Datei" -#: src/Admin/VersionAdminController.php:167 -#: src/Admin/VersionAdminController.php:396 +#: src/Admin/VersionAdminController.php:169 +#: src/Admin/VersionAdminController.php:400 msgid "No download file" msgstr "Keine Download-Datei" -#: src/Admin/VersionAdminController.php:230 +#: 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:231 +#: src/Admin/VersionAdminController.php:233 msgid "Please enter a version number." msgstr "Bitte geben Sie eine Versionsnummer ein." -#: src/Admin/VersionAdminController.php:232 +#: 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:233 +#: 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:234 +#: src/Admin/VersionAdminController.php:236 msgid "Select Download File" msgstr "Download-Datei auswählen" -#: src/Admin/VersionAdminController.php:235 +#: src/Admin/VersionAdminController.php:237 msgid "Use this file" msgstr "Diese Datei verwenden" -#: src/Admin/VersionAdminController.php:236 +#: 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:237 +#: src/Admin/VersionAdminController.php:239 msgid "Failed to read checksum file." msgstr "Prüfsummendatei konnte nicht gelesen werden." -#: src/Admin/VersionAdminController.php:267 +#: src/Admin/VersionAdminController.php:269 msgid "Product ID and version are required." msgstr "Produkt-ID und Version sind erforderlich." -#: src/Admin/VersionAdminController.php:272 +#: 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:277 +#: src/Admin/VersionAdminController.php:279 msgid "This version already exists." msgstr "Diese Version existiert bereits." -#: src/Admin/VersionAdminController.php:283 +#: src/Admin/VersionAdminController.php:285 msgid "Product not found." msgstr "Produkt nicht gefunden." -#: src/Admin/VersionAdminController.php:287 +#: src/Admin/VersionAdminController.php:289 msgid "This product is not a licensed product." msgstr "Dieses Produkt ist kein lizensiertes Produkt." -#: src/Admin/VersionAdminController.php:304 +#: src/Admin/VersionAdminController.php:306 msgid "Failed to create version." msgstr "Version konnte nicht erstellt werden." -#: src/Admin/VersionAdminController.php:312 +#: src/Admin/VersionAdminController.php:314 msgid "Version added successfully." msgstr "Version erfolgreich hinzugefügt." -#: src/Admin/VersionAdminController.php:332 -#: src/Admin/VersionAdminController.php:359 +#: src/Admin/VersionAdminController.php:334 +#: src/Admin/VersionAdminController.php:361 msgid "Version ID is required." msgstr "Versions-ID ist erforderlich." -#: src/Admin/VersionAdminController.php:338 +#: src/Admin/VersionAdminController.php:340 msgid "Failed to delete version." msgstr "Version konnte nicht gelöscht werden." -#: src/Admin/VersionAdminController.php:341 +#: src/Admin/VersionAdminController.php:343 msgid "Version deleted successfully." msgstr "Version erfolgreich gelöscht." -#: src/Admin/VersionAdminController.php:365 +#: src/Admin/VersionAdminController.php:367 msgid "Failed to update version." msgstr "Version konnte nicht aktualisiert werden." -#: src/Admin/VersionAdminController.php:369 +#: src/Admin/VersionAdminController.php:371 msgid "Version updated successfully." msgstr "Version erfolgreich aktualisiert." @@ -1039,32 +1103,28 @@ msgstr "Lizenz konnte nicht aktiviert werden." msgid "License activated successfully." msgstr "Lizenz erfolgreich aktiviert." -#: src/Checkout/CheckoutBlocksIntegration.php:101 +#: src/Checkout/CheckoutController.php:78 +#: src/Checkout/CheckoutBlocksIntegration.php:104 +msgid "License Domain" +msgstr "Lizenz-Domain" + #: src/Checkout/CheckoutController.php:81 +#: src/Checkout/CheckoutBlocksIntegration.php:101 msgid "Domain for License Activation" msgstr "Domain für Lizenz-Aktivierung" -#: src/Checkout/CheckoutBlocksIntegration.php:103 +#: src/Checkout/CheckoutController.php:82 +msgid "required" +msgstr "erforderlich" + #: src/Checkout/CheckoutController.php:93 +#: src/Checkout/CheckoutBlocksIntegration.php:103 msgid "" "Enter the domain where you will use this license (without http:// or www)." msgstr "" "Geben Sie die Domain ein, auf der Sie diese Lizenz verwenden möchten (ohne " "http:// oder www)." -#: src/Checkout/CheckoutBlocksIntegration.php:104 -#: src/Checkout/CheckoutController.php:78 -msgid "License Domain" -msgstr "Lizenz-Domain" - -#: src/Checkout/CheckoutBlocksIntegration.php:105 -msgid "Please enter a valid domain for your license activation." -msgstr "Bitte geben Sie eine gültige Domain für Ihre Lizenz-Aktivierung ein." - -#: src/Checkout/CheckoutController.php:82 -msgid "required" -msgstr "erforderlich" - #: src/Checkout/CheckoutController.php:115 msgid "Please enter a domain for your license activation." msgstr "Bitte geben Sie eine Domain für Ihre Lizenz-Aktivierung ein." @@ -1079,163 +1139,163 @@ msgstr "Bitte geben Sie einen gültigen Domain-Namen ein." msgid "License Domain:" msgstr "Lizenz-Domain:" +#: src/Checkout/CheckoutBlocksIntegration.php:105 +msgid "Please enter a valid domain for your license activation." +msgstr "Bitte geben Sie eine gültige Domain für Ihre Lizenz-Aktivierung ein." + #: src/Checkout/StoreApiExtension.php:85 msgid "Domain for license activation" msgstr "Domain für Lizenz-Aktivierung" -#: src/Email/LicenseEmailController.php:173 -#: src/Email/LicenseEmailController.php:177 -#: src/Email/LicenseEmailController.php:281 -#: src/Email/LicenseExpirationEmail.php:207 -#: src/Email/LicenseExpirationEmail.php:270 -#: src/Frontend/AccountController.php:190 -msgid "License Key:" -msgstr "Lizenzschlüssel:" +#: src/License/LicenseManager.php:366 +msgid "This license has been revoked." +msgstr "Diese Lizenz wurde widerrufen." -#: src/Email/LicenseEmailController.php:217 -msgid "Your License Keys" -msgstr "Ihre Lizenzschlüssel" +#: src/License/LicenseManager.php:376 +msgid "This license has expired." +msgstr "Diese Lizenz ist abgelaufen." -#: src/Email/LicenseEmailController.php:221 -#: src/Email/LicenseEmailController.php:276 -msgid "Licensed Domain:" -msgstr "Lizensierte Domain:" +#: src/License/LicenseManager.php:384 +msgid "This license is inactive." +msgstr "Diese Lizenz ist inaktiv." -#: src/Email/LicenseEmailController.php:248 -#: src/Email/LicenseEmailController.php:287 -#: src/Frontend/AccountController.php:218 -msgid "Never" -msgstr "Nie" - -#: src/Email/LicenseEmailController.php:257 -#: src/Email/LicenseEmailController.php:291 -msgid "You can also view your licenses in your account under \"Licenses\"." -msgstr "" -"Sie können Ihre Lizenzen auch in Ihrem Konto unter \"Lizenzen\" einsehen." - -#: src/Email/LicenseEmailController.php:272 -msgid "YOUR LICENSE KEYS" -msgstr "IHRE LIZENZSCHLÜSSEL" - -#: src/Email/LicenseEmailController.php:284 -#: src/Email/LicenseExpirationEmail.php:219 -#: src/Email/LicenseExpirationEmail.php:272 -#: src/Frontend/AccountController.php:213 -msgid "Expires:" -msgstr "Läuft ab:" - -#: src/Email/LicenseExpirationEmail.php:55 -msgid "License Expiration Warning" -msgstr "Lizenzablauf-Warnung" - -#: src/Email/LicenseExpirationEmail.php:56 -msgid "" -"License expiration warning emails are sent to customers when their licenses " -"are about to expire." -msgstr "" -"Lizenzablauf-Warnungs-E-Mails werden an Kunden gesendet, wenn ihre Lizenzen " -"bald ablaufen." - -#: src/Email/LicenseExpirationEmail.php:74 -msgid "" -"[{site_title}] Your license for {product_name} expires in {days_remaining} " -"days" -msgstr "" -"[{site_title}] Ihre Lizenz für {product_name} läuft in {days_remaining} " -"Tagen ab" - -#: src/Email/LicenseExpirationEmail.php:82 -msgid "License Expiration Notice" -msgstr "Lizenzablauf-Benachrichtigung" +#: src/License/LicenseManager.php:394 +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/Email/LicenseExpirationEmail.php:107 -#: src/Frontend/AccountController.php:140 src/License/LicenseManager.php:760 msgid "Unknown Product" msgstr "Unbekanntes Produkt" -#: src/Email/LicenseExpirationEmail.php:176 -#: src/Email/LicenseExpirationEmail.php:246 +#: src/License/PluginLicenseChecker.php:117 +msgid "License settings not configured." +msgstr "Lizenzeinstellungen nicht konfiguriert." + +#: src/License/PluginLicenseChecker.php:153 +msgid "Could not connect to license server." +msgstr "Verbindung zum Lizenzserver konnte nicht hergestellt werden." + +#: src/Product/LicensedProductType.php:55 +msgid "Licensed Product" +msgstr "Lizensiertes Produkt" + +#: src/Product/LicensedProductType.php:76 +msgid "License Settings" +msgstr "Lizenz-Einstellungen" + +#: src/Product/LicensedProductType.php:103 #, php-format -msgid "Hello %s," -msgstr "Guten Tag %s," +msgid "%d days" +msgstr "%d Tage" -#: src/Email/LicenseExpirationEmail.php:181 -#: src/Email/LicenseExpirationEmail.php:251 +#: src/Product/LicensedProductType.php:113 #, php-format -msgid "Your license for %s will expire tomorrow (%s)." -msgstr "Ihre Lizenz für %s läuft morgen ab (%s)." +msgid "Leave fields empty to use default settings from %s." +msgstr "Felder leer lassen, um Standardeinstellungen von %s zu verwenden." -#: src/Email/LicenseExpirationEmail.php:189 -#: src/Email/LicenseExpirationEmail.php:257 +#: src/Product/LicensedProductType.php:115 +msgid "WooCommerce > Settings > Licensed Products" +msgstr "WooCommerce > Einstellungen > Lizensierte Produkte" + +#: src/Product/LicensedProductType.php:122 +msgid "Max Activations" +msgstr "Max. Aktivierungen" + +#: src/Product/LicensedProductType.php:125 #, php-format -msgid "Your license for %1$s will expire in %2$d days (%3$s)." -msgstr "Ihre Lizenz für %1$s läuft in %2$d Tagen ab (%3$s)." +msgid "Maximum number of domain activations per license. Default: %d" +msgstr "Maximale Anzahl der Domain-Aktivierungen pro Lizenz. Standard: %d" -#: src/Email/LicenseExpirationEmail.php:197 -#: src/Email/LicenseExpirationEmail.php:266 -msgid "License Details" -msgstr "Lizenzdetails" +#: src/Product/LicensedProductType.php:140 +msgid "License Validity (Days)" +msgstr "Lizenz-Gültigkeit (Tage)" -#: src/Email/LicenseExpirationEmail.php:203 -#: src/Email/LicenseExpirationEmail.php:269 -msgid "Product:" -msgstr "Produkt:" +#: src/Product/LicensedProductType.php:143 +#, php-format +msgid "Number of days the license is valid. Leave empty for default (%s)." +msgstr "Anzahl Tage, die die Lizenz gültig ist. Leer lassen für Standard (%s)." -#: src/Email/LicenseExpirationEmail.php:215 -#: src/Email/LicenseExpirationEmail.php:271 -#: src/Frontend/AccountController.php:201 -msgid "Domain:" -msgstr "Domain:" +#: src/Product/LicensedProductType.php:158 +msgid "Bind to Major Version" +msgstr "An Hauptversion binden" -#: src/Email/LicenseExpirationEmail.php:235 -#: src/Email/LicenseExpirationEmail.php:281 -msgid "View My Licenses" -msgstr "Meine Lizenzen anzeigen" - -#: src/Email/LicenseExpirationEmail.php:291 +#: src/Product/LicensedProductType.php:161 +#, php-format msgid "" -"To continue using this product, please renew your license before the " -"expiration date." +"If enabled, licenses are bound to the major version at purchase time. " +"Default: %s" msgstr "" -"Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz vor " -"dem Ablaufdatum." +"Falls aktiviert, werden Lizenzen an die Hauptversion zum Kaufzeitpunkt " +"gebunden. Standard: %s" -#: src/Email/LicenseExpirationEmail.php:301 +#: src/Product/LicensedProductType.php:162 +msgid "Yes" +msgstr "Ja" + +#: src/Product/LicensedProductType.php:162 +msgid "No" +msgstr "Nein" + +#: src/Product/VersionManager.php:166 +msgid "Attachment file not found." +msgstr "Anhangs-Datei nicht gefunden." + +#: src/Product/VersionManager.php:177 #, php-format -msgid "Available placeholders: %s" -msgstr "Verfügbare Platzhalter: %s" +msgid "File checksum does not match. Expected: %1$s, Got: %2$s" +msgstr "Datei-Prüfsumme stimmt nicht überein. Erwartet: %1$s, Erhalten: %2$s" -#: src/Email/LicenseExpirationEmail.php:307 -msgid "Enable/Disable" -msgstr "Aktivieren/Deaktivieren" +#: src/Frontend/DownloadController.php:65 +#: src/Frontend/DownloadController.php:89 +msgid "Invalid download link." +msgstr "Ungültiger Download-Link." -#: src/Email/LicenseExpirationEmail.php:309 -msgid "Enable this email notification" -msgstr "Diese E-Mail-Benachrichtigung aktivieren" +#: 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:187 +msgid "Download Error" +msgstr "Download-Fehler" -#: src/Email/LicenseExpirationEmail.php:313 -msgid "Subject" -msgstr "Betreff" +#: src/Frontend/DownloadController.php:75 +msgid "Invalid download link format." +msgstr "Ungültiges Download-Link-Format." -#: src/Email/LicenseExpirationEmail.php:321 -msgid "Email heading" -msgstr "E-Mail-Überschrift" +#: src/Frontend/DownloadController.php:115 +msgid "You do not have permission to download this file." +msgstr "Sie haben keine Berechtigung, diese Datei herunterzuladen." -#: src/Email/LicenseExpirationEmail.php:329 -msgid "Additional content" -msgstr "Zusätzlicher Inhalt" +#: src/Frontend/DownloadController.php:124 +msgid "Your license is not active. Please contact support." +msgstr "Ihre Lizenz ist nicht aktiv. Bitte kontaktieren Sie den Support." -#: src/Email/LicenseExpirationEmail.php:330 -msgid "Text to appear below the main email content." -msgstr "Text, der unter dem Haupt-E-Mail-Inhalt erscheinen soll." +#: src/Frontend/DownloadController.php:134 +msgid "Version not found." +msgstr "Version nicht gefunden." -#: src/Email/LicenseExpirationEmail.php:338 -msgid "Email type" -msgstr "E-Mail-Typ" +#: src/Frontend/DownloadController.php:143 +msgid "Version does not match your licensed product." +msgstr "Version stimmt nicht mit Ihrem lizensierten Produkt überein." -#: src/Email/LicenseExpirationEmail.php:340 -msgid "Choose which format of email to send." -msgstr "Wählen Sie, welches E-Mail-Format gesendet werden soll." +#: src/Frontend/DownloadController.php:152 +msgid "This version is no longer available for download." +msgstr "Diese Version ist nicht mehr zum Download verfügbar." + +#: src/Frontend/DownloadController.php:170 +msgid "No download file available for this version." +msgstr "Keine Download-Datei für diese Version verfügbar." + +#: src/Frontend/DownloadController.php:186 +msgid "Download file not found." +msgstr "Download-Datei nicht gefunden." #: src/Frontend/AccountController.php:104 msgid "Please log in to view your licenses." @@ -1245,6 +1305,21 @@ msgstr "Bitte melden Sie sich an, um Ihre Lizenzen zu sehen." msgid "You have no licenses yet." msgstr "Sie haben noch keine Lizenzen." +#: src/Frontend/AccountController.php:190 +#: src/Email/LicenseEmailController.php:173 +#: src/Email/LicenseEmailController.php:177 +#: src/Email/LicenseEmailController.php:281 +#: src/Email/LicenseExpirationEmail.php:207 +#: src/Email/LicenseExpirationEmail.php:270 +msgid "License Key:" +msgstr "Lizenzschlüssel:" + +#: src/Frontend/AccountController.php:201 +#: src/Email/LicenseExpirationEmail.php:215 +#: src/Email/LicenseExpirationEmail.php:271 +msgid "Domain:" +msgstr "Domain:" + #: src/Frontend/AccountController.php:207 msgid "Transfer to new domain" msgstr "Auf neue Domain übertragen" @@ -1253,6 +1328,19 @@ msgstr "Auf neue Domain übertragen" msgid "Transfer" msgstr "Übertragen" +#: src/Frontend/AccountController.php:213 +#: src/Email/LicenseEmailController.php:284 +#: src/Email/LicenseExpirationEmail.php:219 +#: src/Email/LicenseExpirationEmail.php:272 +msgid "Expires:" +msgstr "Läuft ab:" + +#: src/Frontend/AccountController.php:218 +#: src/Email/LicenseEmailController.php:248 +#: src/Email/LicenseEmailController.php:287 +msgid "Never" +msgstr "Nie" + #: src/Frontend/AccountController.php:226 msgid "Available Downloads" msgstr "Verfügbare Downloads" @@ -1331,142 +1419,152 @@ msgstr "Die neue Domain ist dieselbe wie die aktuelle Domain." msgid "Failed to transfer license. Please try again." msgstr "Lizenzübertragung fehlgeschlagen. Bitte versuchen Sie es erneut." -#: src/Frontend/DownloadController.php:65 -#: src/Frontend/DownloadController.php:89 -msgid "Invalid download link." -msgstr "Ungültiger Download-Link." +#: src/Email/LicenseEmailController.php:217 +msgid "Your License Keys" +msgstr "Ihre Lizenzschlüssel" -#: 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:187 -msgid "Download Error" -msgstr "Download-Fehler" +#: src/Email/LicenseEmailController.php:221 +#: src/Email/LicenseEmailController.php:276 +msgid "Licensed Domain:" +msgstr "Lizensierte Domain:" -#: src/Frontend/DownloadController.php:75 -msgid "Invalid download link format." -msgstr "Ungültiges Download-Link-Format." - -#: src/Frontend/DownloadController.php:115 -msgid "You do not have permission to download this file." -msgstr "Sie haben keine Berechtigung, diese Datei herunterzuladen." - -#: src/Frontend/DownloadController.php:124 -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 -msgid "Version not found." -msgstr "Version nicht gefunden." - -#: src/Frontend/DownloadController.php:143 -msgid "Version does not match your licensed product." -msgstr "Version stimmt nicht mit Ihrem lizensierten Produkt überein." - -#: src/Frontend/DownloadController.php:152 -msgid "This version is no longer available for download." -msgstr "Diese Version ist nicht mehr zum Download verfügbar." - -#: src/Frontend/DownloadController.php:170 -msgid "No download file available for this version." -msgstr "Keine Download-Datei für diese Version verfügbar." - -#: src/Frontend/DownloadController.php:186 -msgid "Download file not found." -msgstr "Download-Datei nicht gefunden." - -#: src/License/LicenseManager.php:366 -msgid "This license has been revoked." -msgstr "Diese Lizenz wurde widerrufen." - -#: src/License/LicenseManager.php:376 -msgid "This license has expired." -msgstr "Diese Lizenz ist abgelaufen." - -#: src/License/LicenseManager.php:384 -msgid "This license is inactive." -msgstr "Diese Lizenz ist inaktiv." - -#: src/License/LicenseManager.php:394 -msgid "This license is not valid for this domain." -msgstr "Diese Lizenz ist für diese Domain nicht gültig." - -#: src/Product/LicensedProductType.php:55 -msgid "Licensed Product" -msgstr "Lizensiertes Produkt" - -#: src/Product/LicensedProductType.php:76 -msgid "License Settings" -msgstr "Lizenz-Einstellungen" - -#: src/Product/LicensedProductType.php:103 -#, php-format -msgid "%d days" -msgstr "%d Tage" - -#: src/Product/LicensedProductType.php:113 -#, php-format -msgid "Leave fields empty to use default settings from %s." -msgstr "Felder leer lassen, um Standardeinstellungen von %s zu verwenden." - -#: src/Product/LicensedProductType.php:115 -msgid "WooCommerce > Settings > Licensed Products" -msgstr "WooCommerce > Einstellungen > Lizensierte Produkte" - -#: src/Product/LicensedProductType.php:122 -msgid "Max Activations" -msgstr "Max. Aktivierungen" - -#: src/Product/LicensedProductType.php:125 -#, php-format -msgid "Maximum number of domain activations per license. Default: %d" -msgstr "Maximale Anzahl der Domain-Aktivierungen pro Lizenz. Standard: %d" - -#: src/Product/LicensedProductType.php:140 -msgid "License Validity (Days)" -msgstr "Lizenz-Gültigkeit (Tage)" - -#: src/Product/LicensedProductType.php:143 -#, php-format -msgid "Number of days the license is valid. Leave empty for default (%s)." -msgstr "Anzahl Tage, die die Lizenz gültig ist. Leer lassen für Standard (%s)." - -#: src/Product/LicensedProductType.php:158 -msgid "Bind to Major Version" -msgstr "An Hauptversion binden" - -#: src/Product/LicensedProductType.php:161 -#, php-format -msgid "" -"If enabled, licenses are bound to the major version at purchase time. " -"Default: %s" +#: src/Email/LicenseEmailController.php:257 +#: src/Email/LicenseEmailController.php:291 +msgid "You can also view your licenses in your account under \"Licenses\"." msgstr "" -"Falls aktiviert, werden Lizenzen an die Hauptversion zum Kaufzeitpunkt " -"gebunden. Standard: %s" +"Sie können Ihre Lizenzen auch in Ihrem Konto unter \"Lizenzen\" einsehen." -#: src/Product/LicensedProductType.php:162 -msgid "Yes" -msgstr "Ja" +#: src/Email/LicenseEmailController.php:272 +msgid "YOUR LICENSE KEYS" +msgstr "IHRE LIZENZSCHLÜSSEL" -#: src/Product/LicensedProductType.php:162 -msgid "No" -msgstr "Nein" +#: src/Email/LicenseExpirationEmail.php:55 +msgid "License Expiration Warning" +msgstr "Lizenzablauf-Warnung" -#: src/Product/VersionManager.php:166 -msgid "Attachment file not found." -msgstr "Anhangs-Datei nicht gefunden." +#: src/Email/LicenseExpirationEmail.php:56 +msgid "" +"License expiration warning emails are sent to customers when their licenses " +"are about to expire." +msgstr "" +"Lizenzablauf-Warnungs-E-Mails werden an Kunden gesendet, wenn ihre Lizenzen " +"bald ablaufen." -#: src/Product/VersionManager.php:177 +#: src/Email/LicenseExpirationEmail.php:74 +msgid "" +"[{site_title}] Your license for {product_name} expires in {days_remaining} " +"days" +msgstr "" +"[{site_title}] Ihre Lizenz für {product_name} läuft in {days_remaining} " +"Tagen ab" + +#: src/Email/LicenseExpirationEmail.php:82 +msgid "License Expiration Notice" +msgstr "Lizenzablauf-Benachrichtigung" + +#: src/Email/LicenseExpirationEmail.php:176 +#: src/Email/LicenseExpirationEmail.php:246 #, php-format -msgid "File checksum does not match. Expected: %1$s, Got: %2$s" -msgstr "Datei-Prüfsumme stimmt nicht überein. Erwartet: %1$s, Erhalten: %2$s" +msgid "Hello %s," +msgstr "Guten Tag %s," + +#: src/Email/LicenseExpirationEmail.php:181 +#: src/Email/LicenseExpirationEmail.php:251 +#, php-format +msgid "Your license for %s will expire tomorrow (%s)." +msgstr "Ihre Lizenz für %s läuft morgen ab (%s)." + +#: src/Email/LicenseExpirationEmail.php:189 +#: src/Email/LicenseExpirationEmail.php:257 +#, php-format +msgid "Your license for %1$s will expire in %2$d days (%3$s)." +msgstr "Ihre Lizenz für %1$s läuft in %2$d Tagen ab (%3$s)." + +#: src/Email/LicenseExpirationEmail.php:197 +#: src/Email/LicenseExpirationEmail.php:266 +msgid "License Details" +msgstr "Lizenzdetails" + +#: src/Email/LicenseExpirationEmail.php:203 +#: src/Email/LicenseExpirationEmail.php:269 +msgid "Product:" +msgstr "Produkt:" + +#: src/Email/LicenseExpirationEmail.php:235 +#: src/Email/LicenseExpirationEmail.php:281 +msgid "View My Licenses" +msgstr "Meine Lizenzen anzeigen" + +#: src/Email/LicenseExpirationEmail.php:291 +msgid "" +"To continue using this product, please renew your license before the " +"expiration date." +msgstr "" +"Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz vor " +"dem Ablaufdatum." + +#: src/Email/LicenseExpirationEmail.php:301 +#, php-format +msgid "Available placeholders: %s" +msgstr "Verfügbare Platzhalter: %s" + +#: src/Email/LicenseExpirationEmail.php:307 +msgid "Enable/Disable" +msgstr "Aktivieren/Deaktivieren" + +#: src/Email/LicenseExpirationEmail.php:309 +msgid "Enable this email notification" +msgstr "Diese E-Mail-Benachrichtigung aktivieren" + +#: src/Email/LicenseExpirationEmail.php:313 +msgid "Subject" +msgstr "Betreff" + +#: src/Email/LicenseExpirationEmail.php:321 +msgid "Email heading" +msgstr "E-Mail-Überschrift" + +#: src/Email/LicenseExpirationEmail.php:329 +msgid "Additional content" +msgstr "Zusätzlicher Inhalt" + +#: src/Email/LicenseExpirationEmail.php:330 +msgid "Text to appear below the main email content." +msgstr "Text, der unter dem Haupt-E-Mail-Inhalt erscheinen soll." + +#: src/Email/LicenseExpirationEmail.php:338 +msgid "Email type" +msgstr "E-Mail-Typ" + +#: src/Email/LicenseExpirationEmail.php:340 +msgid "Choose which format of email to send." +msgstr "Wählen Sie, welches E-Mail-Format gesendet werden soll." + +#: src/Plugin.php:255 +msgid "WC Licensed Product" +msgstr "WC Licensed Product" + +#: src/Plugin.php:256 +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:257 +msgid "Configure License" +msgstr "Lizenz konfigurieren" + +#: wc-licensed-product.php:61 +#, php-format +msgid "%s requires WooCommerce to be installed and active." +msgstr "%s benötigt WooCommerce als installierte und aktivierte Erweiterung." + +#: wc-licensed-product.php:119 +msgid "WC Licensed Product requires WooCommerce to be installed and active." +msgstr "" +"WC Licensed Product benötigt WooCommerce als installierte und aktivierte " +"Erweiterung." #~ msgid "Or External URL" #~ msgstr "Oder externe URL" diff --git a/languages/wc-licensed-product.pot b/languages/wc-licensed-product.pot index b71c042..c7b2fa1 100644 --- a/languages/wc-licensed-product.pot +++ b/languages/wc-licensed-product.pot @@ -1,14 +1,14 @@ # SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Marco Graetsch -# This file is distributed under the same license as the WooCommerce Licensed Product package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the WC Licensed Product package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: WooCommerce Licensed Product 0.2.2\n" +"Project-Id-Version: WC Licensed Product 0.3.1\n" "Report-Msgid-Bugs-To: magdev3.0@gmail.com\n" -"POT-Creation-Date: 2026-01-22 17:32+0100\n" +"POT-Creation-Date: 2026-01-22 18:30+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,27 +18,349 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: wc-licensed-product.php:61 +#: src/Admin/SettingsController.php:54 +msgid "Licensed Products" +msgstr "" + +#: src/Admin/SettingsController.php:64 src/Admin/SettingsController.php:128 +msgid "Plugin License" +msgstr "" + +#: src/Admin/SettingsController.php:65 +msgid "Default Settings" +msgstr "" + +#: src/Admin/SettingsController.php:66 +msgid "Notifications" +msgstr "" + +#: src/Admin/SettingsController.php:130 +msgid "" +"Configure the license for this plugin. A valid license is required for " +"frontend features to work." +msgstr "" + +#: src/Admin/SettingsController.php:134 +msgid "License Server URL" +msgstr "" + +#: src/Admin/SettingsController.php:136 +msgid "The URL of the license server (e.g., https://shop.example.com)." +msgstr "" + +#: src/Admin/SettingsController.php:142 +#: src/Admin/OrderLicenseController.php:144 src/Admin/AdminController.php:1253 +#: src/Admin/AdminController.php:1391 src/Email/LicenseEmailController.php:230 +msgid "License Key" +msgstr "" + +#: src/Admin/SettingsController.php:144 +msgid "Your license key in XXXX-XXXX-XXXX-XXXX format." +msgstr "" + +#: src/Admin/SettingsController.php:150 +msgid "Server Secret (Optional)" +msgstr "" + +#: src/Admin/SettingsController.php:152 +msgid "" +"If the license server uses signed responses, enter the shared secret here " +"for enhanced security." +msgstr "" + +#: src/Admin/SettingsController.php:170 +msgid "Default License Settings" +msgstr "" + +#: src/Admin/SettingsController.php:172 +msgid "" +"These settings serve as defaults for new licensed products. Individual " +"product settings override these defaults." +msgstr "" + +#: src/Admin/SettingsController.php:176 +msgid "Default Max Activations" +msgstr "" + +#: src/Admin/SettingsController.php:178 +msgid "Default maximum number of domain activations per license." +msgstr "" + +#: src/Admin/SettingsController.php:187 +msgid "Default License Validity (Days)" +msgstr "" + +#: src/Admin/SettingsController.php:189 +msgid "" +"Default number of days a license is valid. Leave empty or set to 0 for " +"lifetime licenses." +msgstr "" + +#: src/Admin/SettingsController.php:192 +#: src/Admin/OrderLicenseController.php:201 src/Admin/AdminController.php:148 +#: src/Admin/AdminController.php:263 src/Admin/AdminController.php:1335 +#: src/Product/LicensedProductType.php:104 +#: src/Product/LicensedProductType.php:152 +msgid "Lifetime" +msgstr "" + +#: src/Admin/SettingsController.php:199 +msgid "Default Bind to Major Version" +msgstr "" + +#: src/Admin/SettingsController.php:201 +msgid "" +"If enabled, licenses are bound to the major version at purchase time by " +"default." +msgstr "" + +#: src/Admin/SettingsController.php:219 +msgid "Expiration Warning Schedule" +msgstr "" + +#: src/Admin/SettingsController.php:223 #, php-format -msgid "%s requires WooCommerce to be installed and active." +msgid "" +"Configure when expiration warning emails are sent. To customize the email " +"template, enable/disable, or change the subject, go to %s." msgstr "" -#: wc-licensed-product.php:119 -msgid "WC Licensed Product requires WooCommerce to be installed and active." +#: src/Admin/SettingsController.php:225 +msgid "WooCommerce > Settings > Emails > License Expiration Warning" msgstr "" -#: wc-licensed-product.php:137 src/Admin/AdminController.php:936 -msgid "Settings" +#: src/Admin/SettingsController.php:230 +msgid "First Warning (Days Before)" +msgstr "" + +#: src/Admin/SettingsController.php:232 +msgid "Days before expiration to send the first warning email." +msgstr "" + +#: src/Admin/SettingsController.php:241 +msgid "Second Warning (Days Before)" +msgstr "" + +#: src/Admin/SettingsController.php:243 +msgid "" +"Days before expiration to send the second warning email. Set to 0 to disable." +msgstr "" + +#: src/Admin/SettingsController.php:283 +msgid "Running on localhost - license validation bypassed." +msgstr "" + +#: src/Admin/SettingsController.php:291 +msgid "License is valid and active." +msgstr "" + +#: src/Admin/SettingsController.php:297 +msgid "License is not valid. Frontend features are disabled." +msgstr "" + +#: src/Admin/SettingsController.php:308 src/Admin/SettingsController.php:344 +msgid "Verify License" +msgstr "" + +#: src/Admin/SettingsController.php:322 +msgid "Verifying..." +msgstr "" + +#: src/Admin/SettingsController.php:341 +msgid "Request failed." +msgstr "" + +#: src/Admin/SettingsController.php:454 src/Admin/AdminController.php:428 +#: src/Admin/AdminController.php:448 src/Admin/AdminController.php:466 +#: src/Admin/AdminController.php:484 src/Admin/AdminController.php:504 +#: src/Admin/AdminController.php:522 src/Admin/AdminController.php:589 +#: src/Admin/AdminController.php:779 src/Frontend/AccountController.php:326 +msgid "Security check failed." +msgstr "" + +#: src/Admin/SettingsController.php:458 +msgid "Insufficient permissions." +msgstr "" + +#: src/Admin/SettingsController.php:467 +msgid "License verified successfully!" +msgstr "" + +#: src/Admin/SettingsController.php:469 +msgid "License validation failed." +msgstr "" + +#: src/Admin/OrderLicenseController.php:56 +msgid "Product Licenses" +msgstr "" + +#: src/Admin/OrderLicenseController.php:77 +#: src/Admin/OrderLicenseController.php:313 +msgid "Order not found." +msgstr "" + +#: src/Admin/OrderLicenseController.php:92 +msgid "This order does not contain licensed products." +msgstr "" + +#: src/Admin/OrderLicenseController.php:106 +msgid "Order Domain" +msgstr "" + +#: src/Admin/OrderLicenseController.php:108 +msgid "" +"The domain specified during checkout. Changing this will not automatically " +"update existing license domains." +msgstr "" + +#: src/Admin/OrderLicenseController.php:116 +#: src/Checkout/CheckoutController.php:89 +#: src/Checkout/CheckoutBlocksIntegration.php:102 +msgid "example.com" +msgstr "" + +#: src/Admin/OrderLicenseController.php:118 +#: src/Admin/OrderLicenseController.php:182 src/Admin/AdminController.php:147 +#: src/Admin/AdminController.php:1302 src/Admin/AdminController.php:1322 +#: src/Admin/AdminController.php:1343 +msgid "Save" msgstr "" -#: src/Admin/AdminController.php:73 src/Admin/AdminController.php:74 -#: src/Admin/AdminController.php:87 src/Admin/AdminController.php:1162 #: src/Admin/OrderLicenseController.php:127 -#: src/Admin/OrderLicenseController.php:222 -#: src/Frontend/AccountController.php:90 +#: src/Admin/OrderLicenseController.php:222 src/Admin/AdminController.php:73 +#: src/Admin/AdminController.php:74 src/Admin/AdminController.php:87 +#: src/Admin/AdminController.php:1162 src/Frontend/AccountController.php:90 msgid "Licenses" msgstr "" +#: src/Admin/OrderLicenseController.php:131 +msgid "No licenses have been generated for this order yet." +msgstr "" + +#: src/Admin/OrderLicenseController.php:134 +msgid "" +"Licenses should be generated automatically when an order is paid. If " +"missing, check that a domain was specified during checkout." +msgstr "" + +#: src/Admin/OrderLicenseController.php:137 +msgid "Licenses will be generated when the order is marked as paid/completed." +msgstr "" + +#: src/Admin/OrderLicenseController.php:145 src/Admin/AdminController.php:1254 +#: src/Admin/AdminController.php:1392 src/Email/LicenseEmailController.php:229 +msgid "Product" +msgstr "" + +#: src/Admin/OrderLicenseController.php:146 src/Admin/AdminController.php:1256 +#: src/Admin/AdminController.php:1394 +msgid "Domain" +msgstr "" + +#: src/Admin/OrderLicenseController.php:147 src/Admin/AdminController.php:1257 +#: src/Admin/AdminController.php:1395 src/Admin/VersionAdminController.php:140 +msgid "Status" +msgstr "" + +#: src/Admin/OrderLicenseController.php:148 src/Admin/AdminController.php:1259 +#: src/Admin/AdminController.php:1397 src/Email/LicenseEmailController.php:231 +msgid "Expires" +msgstr "" + +#: src/Admin/OrderLicenseController.php:149 src/Admin/AdminController.php:1260 +#: src/Admin/AdminController.php:1398 src/Admin/VersionAdminController.php:142 +msgid "Actions" +msgstr "" + +#: src/Admin/OrderLicenseController.php:168 src/Admin/AdminController.php:192 +#: src/Admin/AdminController.php:987 +msgid "Unknown" +msgstr "" + +#: src/Admin/OrderLicenseController.php:178 +msgid "Edit domain" +msgstr "" + +#: src/Admin/OrderLicenseController.php:185 src/Admin/AdminController.php:146 +#: src/Admin/AdminController.php:1303 src/Admin/AdminController.php:1323 +#: src/Admin/AdminController.php:1344 src/Frontend/AccountController.php:271 +msgid "Cancel" +msgstr "" + +#: src/Admin/OrderLicenseController.php:208 +msgid "View in Licenses" +msgstr "" + +#: src/Admin/OrderLicenseController.php:221 +#, php-format +msgid "For more actions (revoke, extend, delete), go to the %s page." +msgstr "" + +#: src/Admin/OrderLicenseController.php:285 src/Admin/AdminController.php:141 +msgid "Saving..." +msgstr "" + +#: src/Admin/OrderLicenseController.php:286 +msgid "Saved!" +msgstr "" + +#: src/Admin/OrderLicenseController.php:287 +msgid "Error saving. Please try again." +msgstr "" + +#: src/Admin/OrderLicenseController.php:288 +#: src/Frontend/AccountController.php:314 +#: src/Frontend/AccountController.php:346 +msgid "Please enter a valid domain." +msgstr "" + +#: src/Admin/OrderLicenseController.php:301 +#: src/Admin/OrderLicenseController.php:340 src/Admin/AdminController.php:170 +#: src/Admin/AdminController.php:210 src/Admin/AdminController.php:246 +#: src/Admin/AdminController.php:298 src/Admin/AdminController.php:336 +#: src/Admin/VersionAdminController.php:259 +#: src/Admin/VersionAdminController.php:328 +#: src/Admin/VersionAdminController.php:354 +msgid "Permission denied." +msgstr "" + +#: src/Admin/OrderLicenseController.php:308 +msgid "Invalid order ID." +msgstr "" + +#: src/Admin/OrderLicenseController.php:319 +#: src/Admin/OrderLicenseController.php:357 +msgid "Invalid domain format." +msgstr "" + +#: src/Admin/OrderLicenseController.php:327 +msgid "Order domain updated." +msgstr "" + +#: src/Admin/OrderLicenseController.php:347 src/Admin/AdminController.php:217 +#: src/Admin/AdminController.php:253 src/Admin/AdminController.php:305 +#: src/Admin/AdminController.php:342 +msgid "Invalid license ID." +msgstr "" + +#: src/Admin/OrderLicenseController.php:351 src/Admin/AdminController.php:309 +msgid "Domain cannot be empty." +msgstr "" + +#: src/Admin/OrderLicenseController.php:363 +#: src/Frontend/DownloadController.php:105 +#: src/Frontend/AccountController.php:352 +msgid "License not found." +msgstr "" + +#: src/Admin/OrderLicenseController.php:371 +msgid "License domain updated." +msgstr "" + +#: src/Admin/OrderLicenseController.php:375 +msgid "Failed to update license domain." +msgstr "" + #: src/Admin/AdminController.php:90 msgid "Overview" msgstr "" @@ -55,10 +377,6 @@ msgstr "" msgid "Search failed" msgstr "" -#: src/Admin/AdminController.php:141 src/Admin/OrderLicenseController.php:285 -msgid "Saving..." -msgstr "" - #: src/Admin/AdminController.php:142 msgid "Saved" msgstr "" @@ -77,27 +395,6 @@ msgstr "" msgid "Edit" msgstr "" -#: src/Admin/AdminController.php:146 src/Admin/AdminController.php:1303 -#: src/Admin/AdminController.php:1323 src/Admin/AdminController.php:1344 -#: src/Admin/OrderLicenseController.php:185 -#: src/Frontend/AccountController.php:271 -msgid "Cancel" -msgstr "" - -#: src/Admin/AdminController.php:147 src/Admin/AdminController.php:1302 -#: src/Admin/AdminController.php:1322 src/Admin/AdminController.php:1343 -#: src/Admin/OrderLicenseController.php:118 -#: src/Admin/OrderLicenseController.php:182 -msgid "Save" -msgstr "" - -#: src/Admin/AdminController.php:148 src/Admin/AdminController.php:263 -#: src/Admin/AdminController.php:1335 src/Admin/OrderLicenseController.php:201 -#: src/Admin/SettingsController.php:78 src/Product/LicensedProductType.php:104 -#: src/Product/LicensedProductType.php:152 -msgid "Lifetime" -msgstr "" - #: src/Admin/AdminController.php:149 src/Frontend/AccountController.php:309 msgid "Copied!" msgstr "" @@ -108,15 +405,15 @@ msgstr "" #: src/Admin/AdminController.php:153 src/Admin/AdminController.php:875 #: src/Admin/AdminController.php:1194 src/Admin/AdminController.php:1317 -#: src/Admin/VersionAdminController.php:180 -#: src/Admin/VersionAdminController.php:409 +#: src/Admin/VersionAdminController.php:182 +#: src/Admin/VersionAdminController.php:413 msgid "Active" msgstr "" #: src/Admin/AdminController.php:154 src/Admin/AdminController.php:882 #: src/Admin/AdminController.php:1195 src/Admin/AdminController.php:1318 -#: src/Admin/VersionAdminController.php:180 -#: src/Admin/VersionAdminController.php:409 +#: src/Admin/VersionAdminController.php:182 +#: src/Admin/VersionAdminController.php:413 msgid "Inactive" msgstr "" @@ -130,31 +427,10 @@ msgstr "" msgid "Revoked" msgstr "" -#: src/Admin/AdminController.php:170 src/Admin/AdminController.php:210 -#: src/Admin/AdminController.php:246 src/Admin/AdminController.php:298 -#: src/Admin/AdminController.php:336 src/Admin/OrderLicenseController.php:301 -#: src/Admin/OrderLicenseController.php:340 -#: src/Admin/VersionAdminController.php:257 -#: src/Admin/VersionAdminController.php:326 -#: src/Admin/VersionAdminController.php:352 -msgid "Permission denied." -msgstr "" - -#: src/Admin/AdminController.php:192 src/Admin/AdminController.php:987 -#: src/Admin/OrderLicenseController.php:168 -msgid "Unknown" -msgstr "" - #: src/Admin/AdminController.php:193 src/Admin/AdminController.php:991 msgid "Guest" msgstr "" -#: src/Admin/AdminController.php:217 src/Admin/AdminController.php:253 -#: src/Admin/AdminController.php:305 src/Admin/AdminController.php:342 -#: src/Admin/OrderLicenseController.php:347 -msgid "Invalid license ID." -msgstr "" - #: src/Admin/AdminController.php:222 msgid "Invalid status." msgstr "" @@ -183,10 +459,6 @@ msgstr "" msgid "Invalid date format." msgstr "" -#: src/Admin/AdminController.php:309 src/Admin/OrderLicenseController.php:351 -msgid "Domain cannot be empty." -msgstr "" - #: src/Admin/AdminController.php:320 msgid "Domain updated successfully." msgstr "" @@ -203,14 +475,6 @@ msgstr "" msgid "Failed to revoke license." msgstr "" -#: src/Admin/AdminController.php:428 src/Admin/AdminController.php:448 -#: src/Admin/AdminController.php:466 src/Admin/AdminController.php:484 -#: src/Admin/AdminController.php:504 src/Admin/AdminController.php:522 -#: src/Admin/AdminController.php:589 src/Admin/AdminController.php:779 -#: src/Frontend/AccountController.php:326 -msgid "Security check failed." -msgstr "" - #: src/Admin/AdminController.php:549 msgid "You do not have permission to export licenses." msgstr "" @@ -267,6 +531,10 @@ msgstr "" msgid "Export to CSV" msgstr "" +#: src/Admin/AdminController.php:936 wc-licensed-product.php:137 +msgid "Settings" +msgstr "" + #: src/Admin/AdminController.php:1050 msgid "License updated successfully." msgstr "" @@ -427,14 +695,14 @@ msgid "Bulk Actions" msgstr "" #: src/Admin/AdminController.php:1235 src/Admin/AdminController.php:1407 -#: src/Admin/VersionAdminController.php:186 -#: src/Admin/VersionAdminController.php:415 +#: src/Admin/VersionAdminController.php:188 +#: src/Admin/VersionAdminController.php:419 msgid "Activate" msgstr "" #: src/Admin/AdminController.php:1236 src/Admin/AdminController.php:1408 -#: src/Admin/VersionAdminController.php:186 -#: src/Admin/VersionAdminController.php:415 +#: src/Admin/VersionAdminController.php:188 +#: src/Admin/VersionAdminController.php:419 msgid "Deactivate" msgstr "" @@ -456,8 +724,8 @@ msgid "Extend 1 year" msgstr "" #: src/Admin/AdminController.php:1241 src/Admin/AdminController.php:1377 -#: src/Admin/AdminController.php:1413 src/Admin/VersionAdminController.php:189 -#: src/Admin/VersionAdminController.php:418 +#: src/Admin/AdminController.php:1413 src/Admin/VersionAdminController.php:191 +#: src/Admin/VersionAdminController.php:422 msgid "Delete" msgstr "" @@ -465,50 +733,15 @@ msgstr "" msgid "Apply" msgstr "" -#: src/Admin/AdminController.php:1253 src/Admin/AdminController.php:1391 -#: src/Admin/OrderLicenseController.php:144 -#: src/Email/LicenseEmailController.php:230 -msgid "License Key" -msgstr "" - -#: src/Admin/AdminController.php:1254 src/Admin/AdminController.php:1392 -#: src/Admin/OrderLicenseController.php:145 -#: src/Email/LicenseEmailController.php:229 -msgid "Product" -msgstr "" - #: src/Admin/AdminController.php:1255 src/Admin/AdminController.php:1393 #: src/Email/LicenseExpirationEmail.php:104 msgid "Customer" msgstr "" -#: src/Admin/AdminController.php:1256 src/Admin/AdminController.php:1394 -#: src/Admin/OrderLicenseController.php:146 -msgid "Domain" -msgstr "" - -#: src/Admin/AdminController.php:1257 src/Admin/AdminController.php:1395 -#: src/Admin/OrderLicenseController.php:147 -#: src/Admin/VersionAdminController.php:140 -msgid "Status" -msgstr "" - #: src/Admin/AdminController.php:1258 src/Admin/AdminController.php:1396 msgid "Created" msgstr "" -#: src/Admin/AdminController.php:1259 src/Admin/AdminController.php:1397 -#: src/Admin/OrderLicenseController.php:148 -#: src/Email/LicenseEmailController.php:231 -msgid "Expires" -msgstr "" - -#: src/Admin/AdminController.php:1260 src/Admin/AdminController.php:1398 -#: src/Admin/OrderLicenseController.php:149 -#: src/Admin/VersionAdminController.php:142 -msgid "Actions" -msgstr "" - #: src/Admin/AdminController.php:1266 msgid "No licenses found." msgstr "" @@ -636,177 +869,6 @@ msgstr "" msgid "No domain specified" msgstr "" -#: src/Admin/OrderLicenseController.php:56 -msgid "Product Licenses" -msgstr "" - -#: src/Admin/OrderLicenseController.php:77 -#: src/Admin/OrderLicenseController.php:313 -msgid "Order not found." -msgstr "" - -#: src/Admin/OrderLicenseController.php:92 -msgid "This order does not contain licensed products." -msgstr "" - -#: src/Admin/OrderLicenseController.php:106 -msgid "Order Domain" -msgstr "" - -#: src/Admin/OrderLicenseController.php:108 -msgid "" -"The domain specified during checkout. Changing this will not automatically " -"update existing license domains." -msgstr "" - -#: src/Admin/OrderLicenseController.php:116 -#: src/Checkout/CheckoutBlocksIntegration.php:102 -#: src/Checkout/CheckoutController.php:89 -msgid "example.com" -msgstr "" - -#: src/Admin/OrderLicenseController.php:131 -msgid "No licenses have been generated for this order yet." -msgstr "" - -#: src/Admin/OrderLicenseController.php:134 -msgid "" -"Licenses should be generated automatically when an order is paid. If " -"missing, check that a domain was specified during checkout." -msgstr "" - -#: src/Admin/OrderLicenseController.php:137 -msgid "Licenses will be generated when the order is marked as paid/completed." -msgstr "" - -#: src/Admin/OrderLicenseController.php:178 -msgid "Edit domain" -msgstr "" - -#: src/Admin/OrderLicenseController.php:208 -msgid "View in Licenses" -msgstr "" - -#: src/Admin/OrderLicenseController.php:221 -#, php-format -msgid "For more actions (revoke, extend, delete), go to the %s page." -msgstr "" - -#: src/Admin/OrderLicenseController.php:286 -msgid "Saved!" -msgstr "" - -#: src/Admin/OrderLicenseController.php:287 -msgid "Error saving. Please try again." -msgstr "" - -#: src/Admin/OrderLicenseController.php:288 -#: src/Frontend/AccountController.php:314 -#: src/Frontend/AccountController.php:346 -msgid "Please enter a valid domain." -msgstr "" - -#: src/Admin/OrderLicenseController.php:308 -msgid "Invalid order ID." -msgstr "" - -#: src/Admin/OrderLicenseController.php:319 -#: src/Admin/OrderLicenseController.php:357 -msgid "Invalid domain format." -msgstr "" - -#: src/Admin/OrderLicenseController.php:327 -msgid "Order domain updated." -msgstr "" - -#: src/Admin/OrderLicenseController.php:363 -#: src/Frontend/AccountController.php:352 -#: src/Frontend/DownloadController.php:105 -msgid "License not found." -msgstr "" - -#: src/Admin/OrderLicenseController.php:371 -msgid "License domain updated." -msgstr "" - -#: src/Admin/OrderLicenseController.php:375 -msgid "Failed to update license domain." -msgstr "" - -#: src/Admin/SettingsController.php:45 -msgid "Licensed Products" -msgstr "" - -#: src/Admin/SettingsController.php:56 -msgid "Default License Settings" -msgstr "" - -#: src/Admin/SettingsController.php:58 -msgid "" -"These settings serve as defaults for new licensed products. Individual " -"product settings override these defaults." -msgstr "" - -#: src/Admin/SettingsController.php:62 -msgid "Default Max Activations" -msgstr "" - -#: src/Admin/SettingsController.php:64 -msgid "Default maximum number of domain activations per license." -msgstr "" - -#: src/Admin/SettingsController.php:73 -msgid "Default License Validity (Days)" -msgstr "" - -#: src/Admin/SettingsController.php:75 -msgid "" -"Default number of days a license is valid. Leave empty or set to 0 for " -"lifetime licenses." -msgstr "" - -#: src/Admin/SettingsController.php:85 -msgid "Default Bind to Major Version" -msgstr "" - -#: src/Admin/SettingsController.php:87 -msgid "" -"If enabled, licenses are bound to the major version at purchase time by " -"default." -msgstr "" - -#: src/Admin/SettingsController.php:97 -msgid "Expiration Warning Schedule" -msgstr "" - -#: src/Admin/SettingsController.php:101 -#, 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 "" - -#: src/Admin/SettingsController.php:103 -msgid "WooCommerce > Settings > Emails > License Expiration Warning" -msgstr "" - -#: src/Admin/SettingsController.php:108 -msgid "First Warning (Days Before)" -msgstr "" - -#: src/Admin/SettingsController.php:110 -msgid "Days before expiration to send the first warning email." -msgstr "" - -#: src/Admin/SettingsController.php:119 -msgid "Second Warning (Days Before)" -msgstr "" - -#: src/Admin/SettingsController.php:121 -msgid "" -"Days before expiration to send the second warning email. Set to 0 to disable." -msgstr "" - #: src/Admin/VersionAdminController.php:58 msgid "Product Versions" msgstr "" @@ -882,95 +944,95 @@ msgstr "" msgid "No versions found. Add your first version above." msgstr "" -#: src/Admin/VersionAdminController.php:164 -#: src/Admin/VersionAdminController.php:393 +#: src/Admin/VersionAdminController.php:165 +#: src/Admin/VersionAdminController.php:396 msgid "Uploaded file" msgstr "" -#: src/Admin/VersionAdminController.php:167 -#: src/Admin/VersionAdminController.php:396 +#: src/Admin/VersionAdminController.php:169 +#: src/Admin/VersionAdminController.php:400 msgid "No download file" msgstr "" -#: src/Admin/VersionAdminController.php:230 +#: src/Admin/VersionAdminController.php:232 msgid "Are you sure you want to delete this version?" msgstr "" -#: src/Admin/VersionAdminController.php:231 +#: src/Admin/VersionAdminController.php:233 msgid "Please enter a version number." msgstr "" -#: src/Admin/VersionAdminController.php:232 +#: src/Admin/VersionAdminController.php:234 msgid "Please enter a valid version number (e.g., 1.0.0)." msgstr "" -#: src/Admin/VersionAdminController.php:233 +#: src/Admin/VersionAdminController.php:235 msgid "An error occurred. Please try again." msgstr "" -#: src/Admin/VersionAdminController.php:234 +#: src/Admin/VersionAdminController.php:236 msgid "Select Download File" msgstr "" -#: src/Admin/VersionAdminController.php:235 +#: src/Admin/VersionAdminController.php:237 msgid "Use this file" msgstr "" -#: src/Admin/VersionAdminController.php:236 +#: src/Admin/VersionAdminController.php:238 msgid "" "Invalid checksum file format. File must contain a 64-character SHA256 hash." msgstr "" -#: src/Admin/VersionAdminController.php:237 +#: src/Admin/VersionAdminController.php:239 msgid "Failed to read checksum file." msgstr "" -#: src/Admin/VersionAdminController.php:267 +#: src/Admin/VersionAdminController.php:269 msgid "Product ID and version are required." msgstr "" -#: src/Admin/VersionAdminController.php:272 +#: src/Admin/VersionAdminController.php:274 msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)." msgstr "" -#: src/Admin/VersionAdminController.php:277 +#: src/Admin/VersionAdminController.php:279 msgid "This version already exists." msgstr "" -#: src/Admin/VersionAdminController.php:283 +#: src/Admin/VersionAdminController.php:285 msgid "Product not found." msgstr "" -#: src/Admin/VersionAdminController.php:287 +#: src/Admin/VersionAdminController.php:289 msgid "This product is not a licensed product." msgstr "" -#: src/Admin/VersionAdminController.php:304 +#: src/Admin/VersionAdminController.php:306 msgid "Failed to create version." msgstr "" -#: src/Admin/VersionAdminController.php:312 +#: src/Admin/VersionAdminController.php:314 msgid "Version added successfully." msgstr "" -#: src/Admin/VersionAdminController.php:332 -#: src/Admin/VersionAdminController.php:359 +#: src/Admin/VersionAdminController.php:334 +#: src/Admin/VersionAdminController.php:361 msgid "Version ID is required." msgstr "" -#: src/Admin/VersionAdminController.php:338 +#: src/Admin/VersionAdminController.php:340 msgid "Failed to delete version." msgstr "" -#: src/Admin/VersionAdminController.php:341 +#: src/Admin/VersionAdminController.php:343 msgid "Version deleted successfully." msgstr "" -#: src/Admin/VersionAdminController.php:365 +#: src/Admin/VersionAdminController.php:367 msgid "Failed to update version." msgstr "" -#: src/Admin/VersionAdminController.php:369 +#: src/Admin/VersionAdminController.php:371 msgid "Version updated successfully." msgstr "" @@ -1003,30 +1065,26 @@ msgstr "" msgid "License activated successfully." msgstr "" -#: src/Checkout/CheckoutBlocksIntegration.php:101 -#: src/Checkout/CheckoutController.php:81 -msgid "Domain for License Activation" -msgstr "" - -#: src/Checkout/CheckoutBlocksIntegration.php:103 -#: src/Checkout/CheckoutController.php:93 -msgid "" -"Enter the domain where you will use this license (without http:// or www)." -msgstr "" - -#: src/Checkout/CheckoutBlocksIntegration.php:104 #: src/Checkout/CheckoutController.php:78 +#: src/Checkout/CheckoutBlocksIntegration.php:104 msgid "License Domain" msgstr "" -#: src/Checkout/CheckoutBlocksIntegration.php:105 -msgid "Please enter a valid domain for your license activation." +#: src/Checkout/CheckoutController.php:81 +#: src/Checkout/CheckoutBlocksIntegration.php:101 +msgid "Domain for License Activation" msgstr "" #: src/Checkout/CheckoutController.php:82 msgid "required" msgstr "" +#: src/Checkout/CheckoutController.php:93 +#: src/Checkout/CheckoutBlocksIntegration.php:103 +msgid "" +"Enter the domain where you will use this license (without http:// or www)." +msgstr "" + #: src/Checkout/CheckoutController.php:115 msgid "Please enter a domain for your license activation." msgstr "" @@ -1041,155 +1099,160 @@ msgstr "" msgid "License Domain:" msgstr "" +#: src/Checkout/CheckoutBlocksIntegration.php:105 +msgid "Please enter a valid domain for your license activation." +msgstr "" + #: src/Checkout/StoreApiExtension.php:85 msgid "Domain for license activation" msgstr "" -#: src/Email/LicenseEmailController.php:173 -#: src/Email/LicenseEmailController.php:177 -#: src/Email/LicenseEmailController.php:281 -#: src/Email/LicenseExpirationEmail.php:207 -#: src/Email/LicenseExpirationEmail.php:270 -#: src/Frontend/AccountController.php:190 -msgid "License Key:" +#: src/License/LicenseManager.php:366 +msgid "This license has been revoked." msgstr "" -#: src/Email/LicenseEmailController.php:217 -msgid "Your License Keys" +#: src/License/LicenseManager.php:376 +msgid "This license has expired." msgstr "" -#: src/Email/LicenseEmailController.php:221 -#: src/Email/LicenseEmailController.php:276 -msgid "Licensed Domain:" +#: src/License/LicenseManager.php:384 +msgid "This license is inactive." msgstr "" -#: src/Email/LicenseEmailController.php:248 -#: src/Email/LicenseEmailController.php:287 -#: src/Frontend/AccountController.php:218 -msgid "Never" -msgstr "" - -#: src/Email/LicenseEmailController.php:257 -#: src/Email/LicenseEmailController.php:291 -msgid "You can also view your licenses in your account under \"Licenses\"." -msgstr "" - -#: src/Email/LicenseEmailController.php:272 -msgid "YOUR LICENSE KEYS" -msgstr "" - -#: src/Email/LicenseEmailController.php:284 -#: src/Email/LicenseExpirationEmail.php:219 -#: src/Email/LicenseExpirationEmail.php:272 -#: src/Frontend/AccountController.php:213 -msgid "Expires:" -msgstr "" - -#: src/Email/LicenseExpirationEmail.php:55 -msgid "License Expiration Warning" -msgstr "" - -#: src/Email/LicenseExpirationEmail.php:56 -msgid "" -"License expiration warning emails are sent to customers when their licenses " -"are about to expire." -msgstr "" - -#: src/Email/LicenseExpirationEmail.php:74 -msgid "" -"[{site_title}] Your license for {product_name} expires in {days_remaining} " -"days" -msgstr "" - -#: src/Email/LicenseExpirationEmail.php:82 -msgid "License Expiration Notice" +#: src/License/LicenseManager.php:394 +msgid "This license is not valid for this domain." msgstr "" +#: src/License/LicenseManager.php:760 src/Frontend/AccountController.php:140 #: src/Email/LicenseExpirationEmail.php:107 -#: src/Frontend/AccountController.php:140 src/License/LicenseManager.php:760 msgid "Unknown Product" msgstr "" -#: src/Email/LicenseExpirationEmail.php:176 -#: src/Email/LicenseExpirationEmail.php:246 +#: src/License/PluginLicenseChecker.php:117 +msgid "License settings not configured." +msgstr "" + +#: src/License/PluginLicenseChecker.php:153 +msgid "Could not connect to license server." +msgstr "" + +#: src/Product/LicensedProductType.php:55 +msgid "Licensed Product" +msgstr "" + +#: src/Product/LicensedProductType.php:76 +msgid "License Settings" +msgstr "" + +#: src/Product/LicensedProductType.php:103 #, php-format -msgid "Hello %s," +msgid "%d days" msgstr "" -#: src/Email/LicenseExpirationEmail.php:181 -#: src/Email/LicenseExpirationEmail.php:251 +#: src/Product/LicensedProductType.php:113 #, php-format -msgid "Your license for %s will expire tomorrow (%s)." +msgid "Leave fields empty to use default settings from %s." msgstr "" -#: src/Email/LicenseExpirationEmail.php:189 -#: src/Email/LicenseExpirationEmail.php:257 +#: src/Product/LicensedProductType.php:115 +msgid "WooCommerce > Settings > Licensed Products" +msgstr "" + +#: src/Product/LicensedProductType.php:122 +msgid "Max Activations" +msgstr "" + +#: src/Product/LicensedProductType.php:125 #, php-format -msgid "Your license for %1$s will expire in %2$d days (%3$s)." +msgid "Maximum number of domain activations per license. Default: %d" msgstr "" -#: src/Email/LicenseExpirationEmail.php:197 -#: src/Email/LicenseExpirationEmail.php:266 -msgid "License Details" +#: src/Product/LicensedProductType.php:140 +msgid "License Validity (Days)" msgstr "" -#: src/Email/LicenseExpirationEmail.php:203 -#: src/Email/LicenseExpirationEmail.php:269 -msgid "Product:" +#: src/Product/LicensedProductType.php:143 +#, php-format +msgid "Number of days the license is valid. Leave empty for default (%s)." msgstr "" -#: src/Email/LicenseExpirationEmail.php:215 -#: src/Email/LicenseExpirationEmail.php:271 -#: src/Frontend/AccountController.php:201 -msgid "Domain:" +#: src/Product/LicensedProductType.php:158 +msgid "Bind to Major Version" msgstr "" -#: src/Email/LicenseExpirationEmail.php:235 -#: src/Email/LicenseExpirationEmail.php:281 -msgid "View My Licenses" -msgstr "" - -#: src/Email/LicenseExpirationEmail.php:291 +#: src/Product/LicensedProductType.php:161 +#, php-format msgid "" -"To continue using this product, please renew your license before the " -"expiration date." +"If enabled, licenses are bound to the major version at purchase time. " +"Default: %s" msgstr "" -#: src/Email/LicenseExpirationEmail.php:301 +#: src/Product/LicensedProductType.php:162 +msgid "Yes" +msgstr "" + +#: src/Product/LicensedProductType.php:162 +msgid "No" +msgstr "" + +#: src/Product/VersionManager.php:166 +msgid "Attachment file not found." +msgstr "" + +#: src/Product/VersionManager.php:177 #, php-format -msgid "Available placeholders: %s" +msgid "File checksum does not match. Expected: %1$s, Got: %2$s" msgstr "" -#: src/Email/LicenseExpirationEmail.php:307 -msgid "Enable/Disable" +#: src/Frontend/DownloadController.php:65 +#: src/Frontend/DownloadController.php:89 +msgid "Invalid download link." msgstr "" -#: src/Email/LicenseExpirationEmail.php:309 -msgid "Enable this email notification" +#: 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:187 +msgid "Download Error" msgstr "" -#: src/Email/LicenseExpirationEmail.php:313 -msgid "Subject" +#: src/Frontend/DownloadController.php:75 +msgid "Invalid download link format." msgstr "" -#: src/Email/LicenseExpirationEmail.php:321 -msgid "Email heading" +#: src/Frontend/DownloadController.php:115 +msgid "You do not have permission to download this file." msgstr "" -#: src/Email/LicenseExpirationEmail.php:329 -msgid "Additional content" +#: src/Frontend/DownloadController.php:124 +msgid "Your license is not active. Please contact support." msgstr "" -#: src/Email/LicenseExpirationEmail.php:330 -msgid "Text to appear below the main email content." +#: src/Frontend/DownloadController.php:134 +msgid "Version not found." msgstr "" -#: src/Email/LicenseExpirationEmail.php:338 -msgid "Email type" +#: src/Frontend/DownloadController.php:143 +msgid "Version does not match your licensed product." msgstr "" -#: src/Email/LicenseExpirationEmail.php:340 -msgid "Choose which format of email to send." +#: src/Frontend/DownloadController.php:152 +msgid "This version is no longer available for download." +msgstr "" + +#: src/Frontend/DownloadController.php:170 +msgid "No download file available for this version." +msgstr "" + +#: src/Frontend/DownloadController.php:186 +msgid "Download file not found." msgstr "" #: src/Frontend/AccountController.php:104 @@ -1200,6 +1263,21 @@ msgstr "" msgid "You have no licenses yet." msgstr "" +#: src/Frontend/AccountController.php:190 +#: src/Email/LicenseEmailController.php:173 +#: src/Email/LicenseEmailController.php:177 +#: src/Email/LicenseEmailController.php:281 +#: src/Email/LicenseExpirationEmail.php:207 +#: src/Email/LicenseExpirationEmail.php:270 +msgid "License Key:" +msgstr "" + +#: src/Frontend/AccountController.php:201 +#: src/Email/LicenseExpirationEmail.php:215 +#: src/Email/LicenseExpirationEmail.php:271 +msgid "Domain:" +msgstr "" + #: src/Frontend/AccountController.php:207 msgid "Transfer to new domain" msgstr "" @@ -1208,6 +1286,19 @@ msgstr "" msgid "Transfer" msgstr "" +#: src/Frontend/AccountController.php:213 +#: src/Email/LicenseEmailController.php:284 +#: src/Email/LicenseExpirationEmail.php:219 +#: src/Email/LicenseExpirationEmail.php:272 +msgid "Expires:" +msgstr "" + +#: src/Frontend/AccountController.php:218 +#: src/Email/LicenseEmailController.php:248 +#: src/Email/LicenseEmailController.php:287 +msgid "Never" +msgstr "" + #: src/Frontend/AccountController.php:226 msgid "Available Downloads" msgstr "" @@ -1284,137 +1375,138 @@ msgstr "" msgid "Failed to transfer license. Please try again." msgstr "" -#: src/Frontend/DownloadController.php:65 -#: src/Frontend/DownloadController.php:89 -msgid "Invalid download link." +#: src/Email/LicenseEmailController.php:217 +msgid "Your License Keys" 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:187 -msgid "Download Error" +#: src/Email/LicenseEmailController.php:221 +#: src/Email/LicenseEmailController.php:276 +msgid "Licensed Domain:" msgstr "" -#: src/Frontend/DownloadController.php:75 -msgid "Invalid download link format." +#: src/Email/LicenseEmailController.php:257 +#: src/Email/LicenseEmailController.php:291 +msgid "You can also view your licenses in your account under \"Licenses\"." msgstr "" -#: src/Frontend/DownloadController.php:115 -msgid "You do not have permission to download this file." +#: src/Email/LicenseEmailController.php:272 +msgid "YOUR LICENSE KEYS" msgstr "" -#: src/Frontend/DownloadController.php:124 -msgid "Your license is not active. Please contact support." +#: src/Email/LicenseExpirationEmail.php:55 +msgid "License Expiration Warning" msgstr "" -#: src/Frontend/DownloadController.php:134 -msgid "Version not found." -msgstr "" - -#: src/Frontend/DownloadController.php:143 -msgid "Version does not match your licensed product." -msgstr "" - -#: src/Frontend/DownloadController.php:152 -msgid "This version is no longer available for download." -msgstr "" - -#: src/Frontend/DownloadController.php:170 -msgid "No download file available for this version." -msgstr "" - -#: src/Frontend/DownloadController.php:186 -msgid "Download file not found." -msgstr "" - -#: src/License/LicenseManager.php:366 -msgid "This license has been revoked." -msgstr "" - -#: src/License/LicenseManager.php:376 -msgid "This license has expired." -msgstr "" - -#: src/License/LicenseManager.php:384 -msgid "This license is inactive." -msgstr "" - -#: src/License/LicenseManager.php:394 -msgid "This license is not valid for this domain." -msgstr "" - -#: src/Product/LicensedProductType.php:55 -msgid "Licensed Product" -msgstr "" - -#: src/Product/LicensedProductType.php:76 -msgid "License Settings" -msgstr "" - -#: src/Product/LicensedProductType.php:103 -#, php-format -msgid "%d days" -msgstr "" - -#: src/Product/LicensedProductType.php:113 -#, php-format -msgid "Leave fields empty to use default settings from %s." -msgstr "" - -#: src/Product/LicensedProductType.php:115 -msgid "WooCommerce > Settings > Licensed Products" -msgstr "" - -#: src/Product/LicensedProductType.php:122 -msgid "Max Activations" -msgstr "" - -#: src/Product/LicensedProductType.php:125 -#, php-format -msgid "Maximum number of domain activations per license. Default: %d" -msgstr "" - -#: src/Product/LicensedProductType.php:140 -msgid "License Validity (Days)" -msgstr "" - -#: src/Product/LicensedProductType.php:143 -#, php-format -msgid "Number of days the license is valid. Leave empty for default (%s)." -msgstr "" - -#: src/Product/LicensedProductType.php:158 -msgid "Bind to Major Version" -msgstr "" - -#: src/Product/LicensedProductType.php:161 -#, php-format +#: src/Email/LicenseExpirationEmail.php:56 msgid "" -"If enabled, licenses are bound to the major version at purchase time. " -"Default: %s" +"License expiration warning emails are sent to customers when their licenses " +"are about to expire." msgstr "" -#: src/Product/LicensedProductType.php:162 -msgid "Yes" +#: src/Email/LicenseExpirationEmail.php:74 +msgid "" +"[{site_title}] Your license for {product_name} expires in {days_remaining} " +"days" msgstr "" -#: src/Product/LicensedProductType.php:162 -msgid "No" +#: src/Email/LicenseExpirationEmail.php:82 +msgid "License Expiration Notice" msgstr "" -#: src/Product/VersionManager.php:166 -msgid "Attachment file not found." -msgstr "" - -#: src/Product/VersionManager.php:177 +#: src/Email/LicenseExpirationEmail.php:176 +#: src/Email/LicenseExpirationEmail.php:246 #, php-format -msgid "File checksum does not match. Expected: %1$s, Got: %2$s" +msgid "Hello %s," +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:181 +#: src/Email/LicenseExpirationEmail.php:251 +#, php-format +msgid "Your license for %s will expire tomorrow (%s)." +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:189 +#: src/Email/LicenseExpirationEmail.php:257 +#, php-format +msgid "Your license for %1$s will expire in %2$d days (%3$s)." +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:197 +#: src/Email/LicenseExpirationEmail.php:266 +msgid "License Details" +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:203 +#: src/Email/LicenseExpirationEmail.php:269 +msgid "Product:" +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:235 +#: src/Email/LicenseExpirationEmail.php:281 +msgid "View My Licenses" +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:291 +msgid "" +"To continue using this product, please renew your license before the " +"expiration date." +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:301 +#, php-format +msgid "Available placeholders: %s" +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:307 +msgid "Enable/Disable" +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:309 +msgid "Enable this email notification" +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:313 +msgid "Subject" +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:321 +msgid "Email heading" +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:329 +msgid "Additional content" +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:330 +msgid "Text to appear below the main email content." +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:338 +msgid "Email type" +msgstr "" + +#: src/Email/LicenseExpirationEmail.php:340 +msgid "Choose which format of email to send." +msgstr "" + +#: src/Plugin.php:255 +msgid "WC Licensed Product" +msgstr "" + +#: src/Plugin.php:256 +msgid "" +"Plugin license is not configured or invalid. Frontend features are disabled." +msgstr "" + +#: src/Plugin.php:257 +msgid "Configure License" +msgstr "" + +#: wc-licensed-product.php:61 +#, php-format +msgid "%s requires WooCommerce to be installed and active." +msgstr "" + +#: wc-licensed-product.php:119 +msgid "WC Licensed Product requires WooCommerce to be installed and active." msgstr "" diff --git a/src/Admin/SettingsController.php b/src/Admin/SettingsController.php index 258017c..93b1a1f 100644 --- a/src/Admin/SettingsController.php +++ b/src/Admin/SettingsController.php @@ -9,6 +9,8 @@ declare(strict_types=1); namespace Jeremias\WcLicensedProduct\Admin; +use Jeremias\WcLicensedProduct\License\PluginLicenseChecker; + /** * Handles WooCommerce settings tab for license defaults */ @@ -19,6 +21,11 @@ final class SettingsController */ public const OPTION_NAME = 'wc_licensed_product_settings'; + /** + * Tab ID + */ + private const TAB_ID = 'licensed_product'; + /** * Constructor */ @@ -33,8 +40,10 @@ final class SettingsController private function registerHooks(): void { add_filter('woocommerce_settings_tabs_array', [$this, 'addSettingsTab'], 50); - add_action('woocommerce_settings_tabs_licensed_product', [$this, 'renderSettingsTab']); - add_action('woocommerce_update_options_licensed_product', [$this, 'saveSettings']); + add_action('woocommerce_sections_' . self::TAB_ID, [$this, 'outputSections']); + add_action('woocommerce_settings_' . self::TAB_ID, [$this, 'renderSettingsTab']); + add_action('woocommerce_update_options_' . self::TAB_ID, [$this, 'saveSettings']); + add_action('wp_ajax_wclp_verify_plugin_license', [$this, 'handleVerifyLicense']); } /** @@ -42,14 +51,119 @@ final class SettingsController */ public function addSettingsTab(array $tabs): array { - $tabs['licensed_product'] = __('Licensed Products', 'wc-licensed-product'); + $tabs[self::TAB_ID] = __('Licensed Products', 'wc-licensed-product'); return $tabs; } /** - * Get settings fields + * Get available sections + */ + public function getSections(): array + { + return [ + '' => __('Plugin License', 'wc-licensed-product'), + 'defaults' => __('Default Settings', 'wc-licensed-product'), + 'notifications' => __('Notifications', 'wc-licensed-product'), + ]; + } + + /** + * Get current section from URL + */ + private function getCurrentSection(): string + { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + return isset($_GET['section']) ? sanitize_title(wp_unslash($_GET['section'])) : ''; + } + + /** + * Output sections navigation (sub-tabs) + */ + public function outputSections(): void + { + $sections = $this->getSections(); + + if (empty($sections) || count($sections) <= 1) { + return; + } + + $currentSection = $this->getCurrentSection(); + + echo '
    '; + + $arrayKeys = array_keys($sections); + + foreach ($sections as $id => $label) { + $url = admin_url('admin.php?page=wc-settings&tab=' . self::TAB_ID . '§ion=' . sanitize_title($id)); + $class = ($currentSection === $id) ? 'current' : ''; + $separator = (end($arrayKeys) === $id) ? '' : ' | '; + + echo '
  • ' . esc_html($label) . '' . $separator . '
  • '; + } + + echo '

'; + } + + /** + * Get settings fields for the current section */ public function getSettingsFields(): array + { + $currentSection = $this->getCurrentSection(); + + return match ($currentSection) { + 'defaults' => $this->getDefaultsSettings(), + 'notifications' => $this->getNotificationsSettings(), + default => $this->getPluginLicenseSettings(), + }; + } + + /** + * Get plugin license settings (default section) + */ + private function getPluginLicenseSettings(): array + { + return [ + 'plugin_license_section_title' => [ + 'name' => __('Plugin License', 'wc-licensed-product'), + 'type' => 'title', + 'desc' => __('Configure the license for this plugin. A valid license is required for frontend features to work.', 'wc-licensed-product'), + 'id' => 'wc_licensed_product_section_plugin_license', + ], + 'plugin_license_server_url' => [ + 'name' => __('License Server URL', 'wc-licensed-product'), + 'type' => 'url', + 'desc' => __('The URL of the license server (e.g., https://shop.example.com).', 'wc-licensed-product'), + 'id' => 'wc_licensed_product_plugin_license_server_url', + 'default' => '', + 'placeholder' => 'https://shop.example.com', + ], + 'plugin_license_key' => [ + 'name' => __('License Key', 'wc-licensed-product'), + 'type' => 'text', + 'desc' => __('Your license key in XXXX-XXXX-XXXX-XXXX format.', 'wc-licensed-product'), + 'id' => 'wc_licensed_product_plugin_license_key', + 'default' => '', + 'placeholder' => 'XXXX-XXXX-XXXX-XXXX', + ], + 'plugin_license_server_secret' => [ + 'name' => __('Server Secret (Optional)', 'wc-licensed-product'), + 'type' => 'password', + 'desc' => __('If the license server uses signed responses, enter the shared secret here for enhanced security.', 'wc-licensed-product'), + 'id' => 'wc_licensed_product_plugin_license_server_secret', + 'default' => '', + ], + 'plugin_license_section_end' => [ + 'type' => 'sectionend', + 'id' => 'wc_licensed_product_section_plugin_license_end', + ], + ]; + } + + /** + * Get default license settings + */ + private function getDefaultsSettings(): array { return [ 'section_title' => [ @@ -92,7 +206,15 @@ final class SettingsController 'type' => 'sectionend', 'id' => 'wc_licensed_product_section_defaults_end', ], - // Email settings section + ]; + } + + /** + * Get notifications settings + */ + private function getNotificationsSettings(): array + { + return [ 'email_section_title' => [ 'name' => __('Expiration Warning Schedule', 'wc-licensed-product'), 'type' => 'title', @@ -138,9 +260,96 @@ final class SettingsController */ public function renderSettingsTab(): void { + $currentSection = $this->getCurrentSection(); + + // Only show license status on the plugin license section + if ($currentSection === '') { + $this->renderLicenseStatus(); + } + woocommerce_admin_fields($this->getSettingsFields()); } + /** + * Render license status notice + */ + private function renderLicenseStatus(): void + { + $checker = PluginLicenseChecker::getInstance(); + + if ($checker->isLocalhost()) { + echo '

'; + echo ' '; + echo esc_html__('Running on localhost - license validation bypassed.', 'wc-licensed-product'); + echo '

'; + return; + } + + if ($checker->isLicenseValid()) { + echo '

'; + echo ' '; + echo esc_html__('License is valid and active.', 'wc-licensed-product'); + echo '

'; + } else { + $error = $checker->getLastError(); + echo '

'; + echo ' '; + echo esc_html__('License is not valid. Frontend features are disabled.', 'wc-licensed-product'); + if ($error) { + echo '
' . esc_html($error) . ''; + } + echo '

'; + } + + // Add verify button + $nonce = wp_create_nonce('wclp_verify_license'); + echo '

'; + echo ''; + echo ''; + echo '

'; + + // Inline script for verify button + ?> + + __('Security check failed.', 'wc-licensed-product')], 403); + } + + if (!current_user_can('manage_woocommerce')) { + wp_send_json_error(['message' => __('Insufficient permissions.', 'wc-licensed-product')], 403); + } + + $checker = PluginLicenseChecker::getInstance(); + $checker->clearCache(); + + $valid = $checker->validateLicense(true); + + if ($valid) { + wp_send_json_success(['message' => __('License verified successfully!', 'wc-licensed-product')]); + } else { + $error = $checker->getLastError() ?: __('License validation failed.', 'wc-licensed-product'); + wp_send_json_error(['message' => $error]); + } + } } diff --git a/src/License/PluginLicenseChecker.php b/src/License/PluginLicenseChecker.php new file mode 100644 index 0000000..0193f4f --- /dev/null +++ b/src/License/PluginLicenseChecker.php @@ -0,0 +1,287 @@ +isLocalhost()) { + return true; + } + + // Check cache first + $cached = get_transient(self::CACHE_KEY); + if ($cached !== false) { + return (bool) $cached; + } + + // Validate against server + return $this->validateLicense(); + } + + /** + * Validate license against the server + * + * @param bool $forceRefresh Force refresh even if cached + * @return bool True if license is valid + */ + public function validateLicense(bool $forceRefresh = false): bool + { + // Always valid on localhost + if ($this->isLocalhost()) { + return true; + } + + // Check settings are configured + $serverUrl = $this->getLicenseServerUrl(); + $licenseKey = $this->getLicenseKey(); + + if (empty($serverUrl) || empty($licenseKey)) { + set_transient( + self::ERROR_CACHE_KEY, + __('License settings not configured.', 'wc-licensed-product'), + self::ERROR_CACHE_TTL + ); + return false; + } + + // Check cache unless force refresh + if (!$forceRefresh) { + $cached = get_transient(self::CACHE_KEY); + if ($cached !== false) { + return (bool) $cached; + } + } + + try { + $client = $this->createLicenseClient(); + $domain = $this->getCurrentDomain(); + + // Validate the license + $client->validate($licenseKey, $domain); + + // Valid license - cache success + set_transient(self::CACHE_KEY, 1, self::CACHE_TTL); + delete_transient(self::ERROR_CACHE_KEY); + + return true; + } catch (LicenseException $e) { + // License-specific error (invalid, expired, revoked, etc.) + set_transient(self::CACHE_KEY, 0, self::CACHE_TTL); + set_transient(self::ERROR_CACHE_KEY, $e->getMessage(), self::ERROR_CACHE_TTL); + + return false; + } catch (\Throwable $e) { + // Network/server error - use shorter cache to allow retry + set_transient( + self::ERROR_CACHE_KEY, + __('Could not connect to license server.', 'wc-licensed-product') . ' ' . $e->getMessage(), + self::ERROR_CACHE_TTL + ); + + // Don't cache validation failure on network errors - allow retry on next page load + return false; + } + } + + /** + * Get the last error message + */ + public function getLastError(): ?string + { + $error = get_transient(self::ERROR_CACHE_KEY); + return $error !== false ? (string) $error : null; + } + + /** + * Clear the validation cache + */ + public function clearCache(): void + { + delete_transient(self::CACHE_KEY); + delete_transient(self::ERROR_CACHE_KEY); + $this->isLocalhostCached = null; + } + + /** + * Check if running on localhost + * + * Matches localhost, 127.0.0.1, ::1, and any port number. + */ + public function isLocalhost(): bool + { + if ($this->isLocalhostCached !== null) { + return $this->isLocalhostCached; + } + + $domain = $this->getCurrentDomain(); + + // Remove port number if present + $domainWithoutPort = preg_replace('/:[\d]+$/', '', $domain); + + // Check for localhost variants + $localhostNames = ['localhost', '127.0.0.1', '::1']; + + if (in_array($domainWithoutPort, $localhostNames, true)) { + $this->isLocalhostCached = true; + return true; + } + + // Check for .localhost and .local subdomains + if ( + str_ends_with($domainWithoutPort, '.localhost') || + str_ends_with($domainWithoutPort, '.local') + ) { + $this->isLocalhostCached = true; + return true; + } + + $this->isLocalhostCached = false; + return false; + } + + /** + * Get the current domain from the site URL + */ + private function getCurrentDomain(): string + { + $siteUrl = get_site_url(); + $parsed = parse_url($siteUrl); + $host = $parsed['host'] ?? 'localhost'; + + // Include port if non-standard + if (isset($parsed['port'])) { + $host .= ':' . $parsed['port']; + } + + return strtolower($host); + } + + /** + * Get the license server URL from settings + */ + private function getLicenseServerUrl(): string + { + return (string) get_option('wc_licensed_product_plugin_license_server_url', ''); + } + + /** + * Get the license key from settings + */ + private function getLicenseKey(): string + { + return (string) get_option('wc_licensed_product_plugin_license_key', ''); + } + + /** + * Get the server secret from settings (optional) + */ + private function getServerSecret(): ?string + { + $secret = get_option('wc_licensed_product_plugin_license_server_secret', ''); + return !empty($secret) ? (string) $secret : null; + } + + /** + * Create the license client instance + */ + private function createLicenseClient(): LicenseClientInterface + { + $httpClient = HttpClient::create([ + 'timeout' => 10, + 'verify_peer' => true, + ]); + + $serverUrl = $this->getLicenseServerUrl(); + $serverSecret = $this->getServerSecret(); + + // Use secure client if server secret is configured + if ($serverSecret !== null) { + return new SecureLicenseClient( + httpClient: $httpClient, + baseUrl: $serverUrl, + serverSecret: $serverSecret, + ); + } + + return new LicenseClient( + httpClient: $httpClient, + baseUrl: $serverUrl, + ); + } +} diff --git a/src/Plugin.php b/src/Plugin.php index d429b8c..a216045 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -22,6 +22,7 @@ use Jeremias\WcLicensedProduct\Email\LicenseEmailController; use Jeremias\WcLicensedProduct\Frontend\AccountController; use Jeremias\WcLicensedProduct\Frontend\DownloadController; use Jeremias\WcLicensedProduct\License\LicenseManager; +use Jeremias\WcLicensedProduct\License\PluginLicenseChecker; use Jeremias\WcLicensedProduct\Product\LicensedProductType; use Jeremias\WcLicensedProduct\Product\VersionManager; use Twig\Environment; @@ -119,13 +120,23 @@ final class Plugin $this->licenseManager = new LicenseManager(); $this->versionManager = new VersionManager(); - // Initialize controllers + // Check plugin license + $licenseChecker = PluginLicenseChecker::getInstance(); + $isLicensed = $licenseChecker->isLicenseValid(); + + // Always initialize product type (needed for existing orders) new LicensedProductType(); - new CheckoutController($this->licenseManager); - new StoreApiExtension($this->licenseManager); - $this->registerCheckoutBlocksIntegration(); - $this->downloadController = new DownloadController($this->licenseManager, $this->versionManager); - new AccountController($this->twig, $this->licenseManager, $this->versionManager, $this->downloadController); + + // Only initialize frontend components if licensed or on localhost + if ($isLicensed) { + new CheckoutController($this->licenseManager); + new StoreApiExtension($this->licenseManager); + $this->registerCheckoutBlocksIntegration(); + $this->downloadController = new DownloadController($this->licenseManager, $this->versionManager); + new AccountController($this->twig, $this->licenseManager, $this->versionManager, $this->downloadController); + } + + // Always initialize REST API and email controller new RestApiController($this->licenseManager); new LicenseEmailController($this->licenseManager); @@ -134,11 +145,17 @@ final class Plugin (new ResponseSigner())->register(); } + // Admin always available if (is_admin()) { new AdminController($this->twig, $this->licenseManager); new VersionAdminController($this->versionManager); new OrderLicenseController($this->licenseManager); new SettingsController(); + + // Show admin notice if unlicensed and not on localhost + if (!$isLicensed && !$licenseChecker->isLocalhost()) { + add_action('admin_notices', [$this, 'showUnlicensedNotice']); + } } } @@ -164,12 +181,16 @@ final class Plugin */ private function registerHooks(): void { - // Generate license on order completion (multiple hooks for compatibility) - add_action('woocommerce_order_status_completed', [$this, 'onOrderCompleted']); - add_action('woocommerce_order_status_processing', [$this, 'onOrderCompleted']); + // Only register order hooks if licensed (license generation requires valid license) + $licenseChecker = PluginLicenseChecker::getInstance(); + if ($licenseChecker->isLicenseValid()) { + // Generate license on order completion (multiple hooks for compatibility) + add_action('woocommerce_order_status_completed', [$this, 'onOrderCompleted']); + add_action('woocommerce_order_status_processing', [$this, 'onOrderCompleted']); - // Also hook into payment complete for immediate license generation - add_action('woocommerce_payment_complete', [$this, 'onOrderCompleted']); + // Also hook into payment complete for immediate license generation + add_action('woocommerce_payment_complete', [$this, 'onOrderCompleted']); + } } /** @@ -221,4 +242,29 @@ final class Plugin { return $this->twig->render($template, $context); } + + /** + * Show admin notice when plugin is unlicensed + */ + public function showUnlicensedNotice(): void + { + $settingsUrl = admin_url('admin.php?page=wc-settings&tab=licensed_product'); + ?> +
+

+ : + + +

+
+