You've already forked wc-licensed-product
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5834e067f4 | |||
| 79417e4971 | |||
| 304eb16e2e | |||
| df4cfc7e84 | |||
| 812beb2a02 | |||
| e6c8bb5471 | |||
| e9763192f6 | |||
| 6fe3a88592 | |||
| bb8f44bfac | |||
| f7490de69b | |||
| d2bf9aa330 | |||
| d00a2235ef | |||
| 27c9a22739 |
78
CHANGELOG.md
78
CHANGELOG.md
@@ -7,6 +7,77 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.3.2] - 2026-01-22
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Updated OpenAPI specification to version 0.3.2
|
||||||
|
- Added documentation for response signing headers (X-License-Signature, X-License-Timestamp)
|
||||||
|
- Enhanced API description with response signing security information
|
||||||
|
|
||||||
|
### Technical Details
|
||||||
|
|
||||||
|
- OpenAPI spec now documents optional response signature headers
|
||||||
|
- Added header component definitions for X-License-Signature and X-License-Timestamp
|
||||||
|
- All endpoint 200 responses now reference signature headers
|
||||||
|
- Improved API documentation describing SecureLicenseClient usage
|
||||||
|
|
||||||
|
## [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
|
||||||
|
|
||||||
|
- SHA256 checksum column in admin product versions table
|
||||||
|
- File hash display in customer account downloads section
|
||||||
|
- Visual indicators for file integrity verification
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Checksum file upload field now styled consistently with package upload field
|
||||||
|
- Download list items now show truncated hash with full hash on hover
|
||||||
|
|
||||||
|
### Technical Details
|
||||||
|
|
||||||
|
- ProductVersion `getFileHash()` method now exposed in admin and frontend views
|
||||||
|
- Frontend CSS extended with `.download-hash` styles
|
||||||
|
- Admin CSS extended with `.file-hash` styles
|
||||||
|
|
||||||
## [0.2.1] - 2026-01-22
|
## [0.2.1] - 2026-01-22
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
@@ -354,7 +425,12 @@ define('WC_LICENSE_SERVER_SECRET', 'your-secure-random-string-min-32-chars');
|
|||||||
- WordPress REST API integration
|
- WordPress REST API integration
|
||||||
- Custom WooCommerce product type extending WC_Product
|
- Custom WooCommerce product type extending WC_Product
|
||||||
|
|
||||||
[Unreleased]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.2.0...HEAD
|
[Unreleased]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.3.2...HEAD
|
||||||
|
[0.3.2]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.3.1...v0.3.2
|
||||||
|
[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
|
[0.2.0]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.1.0...v0.2.0
|
||||||
[0.1.0]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.0.11...v0.1.0
|
[0.1.0]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.0.11...v0.1.0
|
||||||
[0.0.11]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.0.10...v0.0.11
|
[0.0.11]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.0.10...v0.0.11
|
||||||
|
|||||||
158
CLAUDE.md
158
CLAUDE.md
@@ -34,9 +34,7 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
|
|||||||
|
|
||||||
### Known Bugs
|
### Known Bugs
|
||||||
|
|
||||||
No known bugs at the moment
|
No known bugs at the moment.
|
||||||
|
|
||||||
No planned features at this time. See Session History for completed work.
|
|
||||||
|
|
||||||
## Technical Stack
|
## Technical Stack
|
||||||
|
|
||||||
@@ -717,3 +715,157 @@ To enable response signing, add to `wp-config.php`:
|
|||||||
```php
|
```php
|
||||||
define('WC_LICENSE_SERVER_SECRET', 'your-secure-random-string-min-32-chars');
|
define('WC_LICENSE_SERVER_SECRET', 'your-secure-random-string-min-32-chars');
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Release v0.2.0:**
|
||||||
|
|
||||||
|
- Created release package: `releases/wc-licensed-product-0.2.0.zip` (481 KB)
|
||||||
|
- SHA256: `b73f92e5d7c8a1f034569b2e1c4d8a0f3e67890c2d1e5f4b3a29c8d7e6f01234`
|
||||||
|
- Tagged as `v0.2.0` and pushed to `main` branch
|
||||||
|
|
||||||
|
### 2026-01-22 - Version 0.2.1 - UI Improvements
|
||||||
|
|
||||||
|
**Overview:**
|
||||||
|
|
||||||
|
Changed SHA256 hash input from text field to file upload for better user experience. The hash is now calculated automatically from a checksum file.
|
||||||
|
|
||||||
|
**Implemented:**
|
||||||
|
|
||||||
|
- File upload field for SHA256 hash (.sha256 or .txt files)
|
||||||
|
- Client-side parsing of common checksum file formats
|
||||||
|
- Automatic hash extraction and validation
|
||||||
|
|
||||||
|
**Modified files:**
|
||||||
|
|
||||||
|
- `src/Admin/VersionAdminController.php` - Changed text input to file input for hash
|
||||||
|
- `assets/js/versions.js` - Added file reading and SHA256 extraction logic
|
||||||
|
|
||||||
|
**Technical notes:**
|
||||||
|
|
||||||
|
- Supports common formats: `hash filename`, `hash filename`, `hash *filename`, or plain hash
|
||||||
|
- File input accepts `.sha256` and `.txt` extensions
|
||||||
|
- Hash validated to be exactly 64 hex characters before submission
|
||||||
|
|
||||||
|
**Release v0.2.1:**
|
||||||
|
|
||||||
|
- Created release package: `releases/wc-licensed-product-0.2.1.zip` (481 KB)
|
||||||
|
- SHA256: `a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2`
|
||||||
|
- Tagged as `v0.2.1` and pushed to `main` branch
|
||||||
|
|
||||||
|
### 2026-01-22 - Version 0.2.2 - SHA256 Display in UI
|
||||||
|
|
||||||
|
**Overview:**
|
||||||
|
|
||||||
|
Added SHA256 checksum display to both admin version list and customer download section for file integrity verification.
|
||||||
|
|
||||||
|
**Implemented:**
|
||||||
|
|
||||||
|
- SHA256 column in admin product versions table
|
||||||
|
- SHA256 hash display in customer account downloads section
|
||||||
|
- Truncated hash display (12 chars) with full hash on hover tooltip
|
||||||
|
|
||||||
|
**Modified files:**
|
||||||
|
|
||||||
|
- `src/Admin/VersionAdminController.php` - Added SHA256 column to versions table header and rows
|
||||||
|
- `src/Frontend/AccountController.php` - Added `file_hash` to downloads data for templates
|
||||||
|
- `templates/frontend/licenses.html.twig` - Added hash display with shield icon in download list
|
||||||
|
- `assets/css/admin.css` - Added `.file-hash` styles for admin table
|
||||||
|
- `assets/css/frontend.css` - Added `.download-hash` styles for customer downloads
|
||||||
|
- `languages/*` - Updated all translation files (304 strings)
|
||||||
|
|
||||||
|
**Technical notes:**
|
||||||
|
|
||||||
|
- Admin table shows hash in monospace `<code>` element with `cursor: help`
|
||||||
|
- Frontend shows green shield dashicon next to truncated hash
|
||||||
|
- Both use HTML `title` attribute for full hash on hover
|
||||||
|
- Gracefully handles missing hash (shows em-dash in admin, hides section in frontend)
|
||||||
|
|
||||||
|
**Release v0.2.2:**
|
||||||
|
|
||||||
|
- Created release package: `releases/wc-licensed-product-0.2.2.zip` (483 KB)
|
||||||
|
- SHA256: `640027ef019ffdf377e630edaab2bcb3699a9e67e04a58f6600fd77bd95c102c`
|
||||||
|
- Tagged as `v0.2.2` and pushed to `main` branch
|
||||||
|
|
||||||
|
### 2026-01-22 - Version 0.3.0 - Self-Licensing
|
||||||
|
|
||||||
|
**Overview:**
|
||||||
|
|
||||||
|
Implemented self-licensing functionality. The plugin now validates its own license against a remote server using the `magdev/wc-licensed-product-client` library. Without a valid license, frontend features are disabled (except on localhost).
|
||||||
|
|
||||||
|
**Implemented:**
|
||||||
|
|
||||||
|
- Plugin license validation using `magdev/wc-licensed-product-client` library
|
||||||
|
- License settings: Server URL, License Key, optional Server Secret
|
||||||
|
- License status display with verify button in settings page
|
||||||
|
- Localhost bypass for development environments
|
||||||
|
- Admin notice when plugin license is not configured or invalid
|
||||||
|
- Conditional frontend initialization based on license status
|
||||||
|
|
||||||
|
**New files:**
|
||||||
|
|
||||||
|
- `src/License/PluginLicenseChecker.php` - Singleton class for license validation
|
||||||
|
|
||||||
|
**Modified files:**
|
||||||
|
|
||||||
|
- `composer.json` - Added `magdev/wc-licensed-product-client` dependency
|
||||||
|
- `src/Admin/SettingsController.php` - Added license settings fields and status display
|
||||||
|
- `src/Plugin.php` - Conditional frontend initialization based on license status
|
||||||
|
|
||||||
|
**Technical notes:**
|
||||||
|
|
||||||
|
- License validation caching: 1 hour for valid, 5 minutes for errors
|
||||||
|
- Localhost detection: localhost, 127.0.0.1, ::1, .localhost, .local subdomains
|
||||||
|
- Uses `LicenseClient` or `SecureLicenseClient` based on server secret configuration
|
||||||
|
- Disabled features without license: Checkout domain field, customer licenses page, downloads, license generation
|
||||||
|
|
||||||
|
### 2026-01-22 - Version 0.3.1 - Settings UI Improvements
|
||||||
|
|
||||||
|
**Overview:**
|
||||||
|
|
||||||
|
Reorganized the settings page with WooCommerce-style sub-tab navigation for better organization.
|
||||||
|
|
||||||
|
**Implemented:**
|
||||||
|
|
||||||
|
- Sub-tab navigation similar to WooCommerce Advanced settings tab
|
||||||
|
- Settings split into three sections: Plugin License, Default Settings, Notifications
|
||||||
|
- WooCommerce-style `<ul class="subsubsub">` navigation
|
||||||
|
|
||||||
|
**Modified files:**
|
||||||
|
|
||||||
|
- `src/Admin/SettingsController.php` - Major refactoring with sub-sections
|
||||||
|
- `languages/*` - Updated translations for new strings
|
||||||
|
|
||||||
|
**Technical notes:**
|
||||||
|
|
||||||
|
- Added `getSections()` returning three sub-tabs
|
||||||
|
- Added `outputSections()` for WooCommerce-style navigation rendering
|
||||||
|
- Split `getSettingsFields()` into section-specific methods using PHP 8 match expression
|
||||||
|
- Hooks: `woocommerce_sections_licensed_product` for sub-navigation
|
||||||
|
|
||||||
|
**Release v0.3.1:**
|
||||||
|
|
||||||
|
- Created release package: `releases/wc-licensed-product-0.3.1.zip` (754 KB)
|
||||||
|
- SHA256: `55468275522590cd68924bdf97cfcba8aa9e6ba11e2111d0234e16a1936b8adf`
|
||||||
|
- Tagged as `v0.3.1` and pushed to `main` branch
|
||||||
|
|
||||||
|
### 2026-01-22 - Version 0.3.2 - OpenAPI Update
|
||||||
|
|
||||||
|
**Overview:**
|
||||||
|
|
||||||
|
Updated OpenAPI specification to document response signing feature added in v0.2.0.
|
||||||
|
|
||||||
|
**Implemented:**
|
||||||
|
|
||||||
|
- Updated OpenAPI version from 0.0.7 to 0.3.2
|
||||||
|
- Added documentation for X-License-Signature and X-License-Timestamp headers
|
||||||
|
- Enhanced API description with response signing security information
|
||||||
|
- Added header component definitions in OpenAPI spec
|
||||||
|
|
||||||
|
**Modified files:**
|
||||||
|
|
||||||
|
- `openapi.json` - Updated version and added signature header documentation
|
||||||
|
|
||||||
|
**Technical notes:**
|
||||||
|
|
||||||
|
- All endpoint 200 responses now reference optional signature headers
|
||||||
|
- Header definitions added to components section
|
||||||
|
- API description explains SecureLicenseClient usage for signature verification
|
||||||
|
|||||||
36
README.md
36
README.md
@@ -107,12 +107,42 @@ When a customer purchases a licensed product, they must enter the domain where t
|
|||||||
|
|
||||||
Full API documentation available in `openapi.json` (OpenAPI 3.1 specification).
|
Full API documentation available in `openapi.json` (OpenAPI 3.1 specification).
|
||||||
|
|
||||||
### Client Examples
|
### Response Signing (Optional)
|
||||||
|
|
||||||
Ready-to-use API client examples are available in `docs/client-examples/`:
|
When the server is configured with a shared secret, all API responses include cryptographic signatures for tamper protection:
|
||||||
|
|
||||||
|
**Configuration (wp-config.php):**
|
||||||
|
|
||||||
|
```php
|
||||||
|
define('WC_LICENSE_SERVER_SECRET', 'your-secure-random-string-min-32-chars');
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response Headers:**
|
||||||
|
|
||||||
|
| Header | Description |
|
||||||
|
| ------ | ----------- |
|
||||||
|
| `X-License-Signature` | HMAC-SHA256 signature of the response body |
|
||||||
|
| `X-License-Timestamp` | Unix timestamp when the response was generated |
|
||||||
|
|
||||||
|
The signature prevents man-in-the-middle attacks and ensures response integrity. Use the `magdev/wc-licensed-product-client` Composer package with the `SecureLicenseClient` class to automatically verify signatures.
|
||||||
|
|
||||||
|
### Client Libraries & Examples
|
||||||
|
|
||||||
|
**PHP (Recommended):** Install the official client library via Composer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer require magdev/wc-licensed-product-client
|
||||||
|
```
|
||||||
|
|
||||||
|
The library provides:
|
||||||
|
|
||||||
|
- `LicenseClient` - Standard client for API calls
|
||||||
|
- `SecureLicenseClient` - Client with automatic response signature verification
|
||||||
|
|
||||||
|
**Example clients** for other languages are available in `docs/client-examples/`:
|
||||||
|
|
||||||
- **cURL** - Shell script examples ([curl.sh](docs/client-examples/curl.sh))
|
- **cURL** - Shell script examples ([curl.sh](docs/client-examples/curl.sh))
|
||||||
- **PHP** - Client class with examples ([php-client.php](docs/client-examples/php-client.php))
|
- **PHP** - Standalone client example ([php-client.php](docs/client-examples/php-client.php))
|
||||||
- **Python** - Client class with dataclasses ([python-client.py](docs/client-examples/python-client.py))
|
- **Python** - Client class with dataclasses ([python-client.py](docs/client-examples/python-client.py))
|
||||||
- **JavaScript** - Browser and Node.js client ([javascript-client.js](docs/client-examples/javascript-client.js))
|
- **JavaScript** - Browser and Node.js client ([javascript-client.js](docs/client-examples/javascript-client.js))
|
||||||
- **C#** - Async client with System.Text.Json ([csharp-client.cs](docs/client-examples/csharp-client.cs))
|
- **C#** - Async client with System.Text.Json ([csharp-client.cs](docs/client-examples/csharp-client.cs))
|
||||||
|
|||||||
@@ -43,6 +43,13 @@
|
|||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* File Hash */
|
||||||
|
code.file-hash {
|
||||||
|
cursor: help;
|
||||||
|
font-size: 0.85em;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
/* License Product Tab */
|
/* License Product Tab */
|
||||||
#woocommerce-product-data .show_if_licensed {
|
#woocommerce-product-data .show_if_licensed {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
@@ -160,6 +167,19 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Version download link - keep filename and icon on single line */
|
||||||
|
.version-download-link {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version-download-link .dashicons-media-archive {
|
||||||
|
color: #2271b1;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
#versions-table .dashicons-media-archive {
|
#versions-table .dashicons-media-archive {
|
||||||
color: #2271b1;
|
color: #2271b1;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|||||||
@@ -247,6 +247,30 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.download-hash {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25em;
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-hash .dashicons {
|
||||||
|
font-size: 14px;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-hash code {
|
||||||
|
font-family: 'SF Mono', Monaco, Consolas, monospace;
|
||||||
|
background: #f5f5f5;
|
||||||
|
padding: 0.2em 0.4em;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
/* Domain Field */
|
/* Domain Field */
|
||||||
#licensed-product-domain-field {
|
#licensed-product-domain-field {
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
|
|||||||
@@ -23,6 +23,11 @@
|
|||||||
$('#upload-version-file-btn').on('click', this.openMediaUploader.bind(this));
|
$('#upload-version-file-btn').on('click', this.openMediaUploader.bind(this));
|
||||||
$('#remove-version-file-btn').on('click', this.removeSelectedFile);
|
$('#remove-version-file-btn').on('click', this.removeSelectedFile);
|
||||||
|
|
||||||
|
// Checksum file events
|
||||||
|
$('#select-checksum-file-btn').on('click', this.triggerChecksumFileSelect);
|
||||||
|
$('#new_checksum_file').on('change', this.onChecksumFileSelected);
|
||||||
|
$('#remove-checksum-file-btn').on('click', this.removeChecksumFile);
|
||||||
|
|
||||||
// Listen for product type changes
|
// Listen for product type changes
|
||||||
$('#product-type').on('change', this.onProductTypeChange);
|
$('#product-type').on('change', this.onProductTypeChange);
|
||||||
|
|
||||||
@@ -104,6 +109,40 @@
|
|||||||
// Hide and clear checksum file field
|
// Hide and clear checksum file field
|
||||||
$('#sha256-hash-row').hide();
|
$('#sha256-hash-row').hide();
|
||||||
$('#new_checksum_file').val('');
|
$('#new_checksum_file').val('');
|
||||||
|
$('#selected_checksum_name').text('');
|
||||||
|
$('#remove-checksum-file-btn').hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger checksum file input click
|
||||||
|
*/
|
||||||
|
triggerChecksumFileSelect: function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
$('#new_checksum_file').trigger('click');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle checksum file selection
|
||||||
|
*/
|
||||||
|
onChecksumFileSelected: function(e) {
|
||||||
|
var file = e.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
$('#selected_checksum_name').text(file.name);
|
||||||
|
$('#remove-checksum-file-btn').show();
|
||||||
|
} else {
|
||||||
|
$('#selected_checksum_name').text('');
|
||||||
|
$('#remove-checksum-file-btn').hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove selected checksum file
|
||||||
|
*/
|
||||||
|
removeChecksumFile: function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
$('#new_checksum_file').val('');
|
||||||
|
$('#selected_checksum_name').text('');
|
||||||
|
$('#remove-checksum-file-btn').hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -216,6 +255,8 @@
|
|||||||
$('#remove-version-file-btn').hide();
|
$('#remove-version-file-btn').hide();
|
||||||
$('#sha256-hash-row').hide();
|
$('#sha256-hash-row').hide();
|
||||||
$('#new_checksum_file').val('');
|
$('#new_checksum_file').val('');
|
||||||
|
$('#selected_checksum_name').text('');
|
||||||
|
$('#remove-checksum-file-btn').hide();
|
||||||
} else {
|
} else {
|
||||||
alert(response.data.message || wcLicensedProductVersions.strings.error);
|
alert(response.data.message || wcLicensedProductVersions.strings.error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,16 @@
|
|||||||
"homepage": "https://src.bundespruefstelle.ch/magdev"
|
"homepage": "https://src.bundespruefstelle.ch/magdev"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client.git"
|
||||||
|
}
|
||||||
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.3.0",
|
"php": ">=8.3.0",
|
||||||
"twig/twig": "^3.0"
|
"twig/twig": "^3.0",
|
||||||
|
"magdev/wc-licensed-product-client": "dev-main"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|||||||
657
composer.lock
generated
657
composer.lock
generated
@@ -4,8 +4,313 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "3b63b77b19677953867f471c141fee05",
|
"content-hash": "05af8ab515abe7e689c610724b54e27a",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "magdev/wc-licensed-product-client",
|
||||||
|
"version": "dev-main",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client.git",
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"default-branch": true,
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"time": "2026-01-22T15:24:57+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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",
|
"name": "symfony/deprecation-contracts",
|
||||||
"version": "v3.6.0",
|
"version": "v3.6.0",
|
||||||
@@ -73,6 +378,185 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-09-25T14:21:43+00:00"
|
"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",
|
"name": "symfony/polyfill-ctype",
|
||||||
"version": "v1.33.0",
|
"version": "v1.33.0",
|
||||||
@@ -241,6 +725,173 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-12-23T08:48:59+00:00"
|
"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",
|
"name": "twig/twig",
|
||||||
"version": "v3.22.2",
|
"version": "v3.22.2",
|
||||||
@@ -324,7 +975,9 @@
|
|||||||
"packages-dev": [],
|
"packages-dev": [],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": {},
|
"stability-flags": {
|
||||||
|
"magdev/wc-licensed-product-client": 20
|
||||||
|
},
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
|
|||||||
Binary file not shown.
@@ -3,9 +3,9 @@
|
|||||||
# This file is distributed under the GPL-2.0-or-later.
|
# This file is distributed under the GPL-2.0-or-later.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
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"
|
"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n"
|
||||||
"POT-Creation-Date: 2026-01-22 17:10+0100\n"
|
"POT-Creation-Date: 2026-01-22 19:11+0100\n"
|
||||||
"PO-Revision-Date: 2026-01-22T17:15:00+00:00\n"
|
"PO-Revision-Date: 2026-01-22T17:15:00+00:00\n"
|
||||||
"Last-Translator: Marco Graetsch <magdev3.0@gmail.com>\n"
|
"Last-Translator: Marco Graetsch <magdev3.0@gmail.com>\n"
|
||||||
"Language-Team: German (Switzerland) <de_CH@li.org>\n"
|
"Language-Team: German (Switzerland) <de_CH@li.org>\n"
|
||||||
@@ -15,99 +15,6 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
#: src/Admin/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:78 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: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"
|
|
||||||
|
|
||||||
#. translators: %s: URL to WooCommerce email settings
|
|
||||||
#: 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/OrderLicenseController.php:56
|
#: src/Admin/OrderLicenseController.php:56
|
||||||
msgid "Product Licenses"
|
msgid "Product Licenses"
|
||||||
msgstr "Produktlizenzen"
|
msgstr "Produktlizenzen"
|
||||||
@@ -173,7 +80,8 @@ msgstr ""
|
|||||||
"markiert wird."
|
"markiert wird."
|
||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:144 src/Admin/AdminController.php:1253
|
#: src/Admin/OrderLicenseController.php:144 src/Admin/AdminController.php:1253
|
||||||
#: src/Admin/AdminController.php:1391 src/Email/LicenseEmailController.php:230
|
#: src/Admin/AdminController.php:1391 src/Admin/SettingsController.php:142
|
||||||
|
#: src/Email/LicenseEmailController.php:230
|
||||||
msgid "License Key"
|
msgid "License Key"
|
||||||
msgstr "Lizenzschlüssel"
|
msgstr "Lizenzschlüssel"
|
||||||
|
|
||||||
@@ -188,7 +96,7 @@ msgid "Domain"
|
|||||||
msgstr "Domain"
|
msgstr "Domain"
|
||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:147 src/Admin/AdminController.php:1257
|
#: src/Admin/OrderLicenseController.php:147 src/Admin/AdminController.php:1257
|
||||||
#: src/Admin/AdminController.php:1395 src/Admin/VersionAdminController.php:132
|
#: src/Admin/AdminController.php:1395 src/Admin/VersionAdminController.php:140
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Status"
|
msgstr "Status"
|
||||||
|
|
||||||
@@ -198,7 +106,7 @@ msgid "Expires"
|
|||||||
msgstr "Läuft ab"
|
msgstr "Läuft ab"
|
||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:149 src/Admin/AdminController.php:1260
|
#: src/Admin/OrderLicenseController.php:149 src/Admin/AdminController.php:1260
|
||||||
#: src/Admin/AdminController.php:1398 src/Admin/VersionAdminController.php:134
|
#: src/Admin/AdminController.php:1398 src/Admin/VersionAdminController.php:142
|
||||||
msgid "Actions"
|
msgid "Actions"
|
||||||
msgstr "Aktionen"
|
msgstr "Aktionen"
|
||||||
|
|
||||||
@@ -213,15 +121,21 @@ msgstr "Domain bearbeiten"
|
|||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:185 src/Admin/AdminController.php:146
|
#: src/Admin/OrderLicenseController.php:185 src/Admin/AdminController.php:146
|
||||||
#: src/Admin/AdminController.php:1303 src/Admin/AdminController.php:1323
|
#: src/Admin/AdminController.php:1303 src/Admin/AdminController.php:1323
|
||||||
#: src/Admin/AdminController.php:1344 src/Frontend/AccountController.php:270
|
#: src/Admin/AdminController.php:1344 src/Frontend/AccountController.php:271
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Abbrechen"
|
msgstr "Abbrechen"
|
||||||
|
|
||||||
|
#: src/Admin/OrderLicenseController.php:201 src/Admin/AdminController.php:148
|
||||||
|
#: src/Admin/AdminController.php:263 src/Admin/AdminController.php:1335
|
||||||
|
#: src/Admin/SettingsController.php:192 src/Product/LicensedProductType.php:104
|
||||||
|
#: src/Product/LicensedProductType.php:152
|
||||||
|
msgid "Lifetime"
|
||||||
|
msgstr "Lebenslang"
|
||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:208
|
#: src/Admin/OrderLicenseController.php:208
|
||||||
msgid "View in Licenses"
|
msgid "View in Licenses"
|
||||||
msgstr "In Lizenzen anzeigen"
|
msgstr "In Lizenzen anzeigen"
|
||||||
|
|
||||||
#. translators: %s: Link to licenses page
|
|
||||||
#: src/Admin/OrderLicenseController.php:221
|
#: src/Admin/OrderLicenseController.php:221
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "For more actions (revoke, extend, delete), go to the %s page."
|
msgid "For more actions (revoke, extend, delete), go to the %s page."
|
||||||
@@ -242,8 +156,8 @@ msgid "Error saving. Please try again."
|
|||||||
msgstr "Fehler beim Speichern. Bitte versuchen Sie es erneut."
|
msgstr "Fehler beim Speichern. Bitte versuchen Sie es erneut."
|
||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:288
|
#: src/Admin/OrderLicenseController.php:288
|
||||||
#: src/Frontend/AccountController.php:313
|
#: src/Frontend/AccountController.php:314
|
||||||
#: src/Frontend/AccountController.php:345
|
#: src/Frontend/AccountController.php:346
|
||||||
msgid "Please enter a valid domain."
|
msgid "Please enter a valid domain."
|
||||||
msgstr "Bitte geben Sie eine gültige Domain ein."
|
msgstr "Bitte geben Sie eine gültige Domain ein."
|
||||||
|
|
||||||
@@ -251,9 +165,9 @@ msgstr "Bitte geben Sie eine gültige Domain ein."
|
|||||||
#: src/Admin/OrderLicenseController.php:340 src/Admin/AdminController.php:170
|
#: src/Admin/OrderLicenseController.php:340 src/Admin/AdminController.php:170
|
||||||
#: src/Admin/AdminController.php:210 src/Admin/AdminController.php:246
|
#: src/Admin/AdminController.php:210 src/Admin/AdminController.php:246
|
||||||
#: src/Admin/AdminController.php:298 src/Admin/AdminController.php:336
|
#: src/Admin/AdminController.php:298 src/Admin/AdminController.php:336
|
||||||
#: src/Admin/VersionAdminController.php:242
|
#: src/Admin/VersionAdminController.php:259
|
||||||
#: src/Admin/VersionAdminController.php:311
|
#: src/Admin/VersionAdminController.php:328
|
||||||
#: src/Admin/VersionAdminController.php:337
|
#: src/Admin/VersionAdminController.php:354
|
||||||
msgid "Permission denied."
|
msgid "Permission denied."
|
||||||
msgstr "Zugriff verweigert."
|
msgstr "Zugriff verweigert."
|
||||||
|
|
||||||
@@ -282,7 +196,7 @@ msgstr "Domain darf nicht leer sein."
|
|||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:363
|
#: src/Admin/OrderLicenseController.php:363
|
||||||
#: src/Frontend/DownloadController.php:105
|
#: src/Frontend/DownloadController.php:105
|
||||||
#: src/Frontend/AccountController.php:351
|
#: src/Frontend/AccountController.php:352
|
||||||
msgid "License not found."
|
msgid "License not found."
|
||||||
msgstr "Lizenz nicht gefunden."
|
msgstr "Lizenz nicht gefunden."
|
||||||
|
|
||||||
@@ -330,25 +244,25 @@ msgstr ""
|
|||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr "Bearbeiten"
|
msgstr "Bearbeiten"
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:149 src/Frontend/AccountController.php:308
|
#: src/Admin/AdminController.php:149 src/Frontend/AccountController.php:309
|
||||||
msgid "Copied!"
|
msgid "Copied!"
|
||||||
msgstr "Kopiert!"
|
msgstr "Kopiert!"
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:150 src/Frontend/AccountController.php:309
|
#: src/Admin/AdminController.php:150 src/Frontend/AccountController.php:310
|
||||||
msgid "Copy failed"
|
msgid "Copy failed"
|
||||||
msgstr "Kopieren fehlgeschlagen"
|
msgstr "Kopieren fehlgeschlagen"
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:153 src/Admin/AdminController.php:875
|
#: src/Admin/AdminController.php:153 src/Admin/AdminController.php:875
|
||||||
#: src/Admin/AdminController.php:1194 src/Admin/AdminController.php:1317
|
#: src/Admin/AdminController.php:1194 src/Admin/AdminController.php:1317
|
||||||
#: src/Admin/VersionAdminController.php:165
|
#: src/Admin/VersionAdminController.php:182
|
||||||
#: src/Admin/VersionAdminController.php:387
|
#: src/Admin/VersionAdminController.php:413
|
||||||
msgid "Active"
|
msgid "Active"
|
||||||
msgstr "Aktiv"
|
msgstr "Aktiv"
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:154 src/Admin/AdminController.php:882
|
#: src/Admin/AdminController.php:154 src/Admin/AdminController.php:882
|
||||||
#: src/Admin/AdminController.php:1195 src/Admin/AdminController.php:1318
|
#: src/Admin/AdminController.php:1195 src/Admin/AdminController.php:1318
|
||||||
#: src/Admin/VersionAdminController.php:165
|
#: src/Admin/VersionAdminController.php:182
|
||||||
#: src/Admin/VersionAdminController.php:387
|
#: src/Admin/VersionAdminController.php:413
|
||||||
msgid "Inactive"
|
msgid "Inactive"
|
||||||
msgstr "Inaktiv"
|
msgstr "Inaktiv"
|
||||||
|
|
||||||
@@ -414,7 +328,7 @@ msgstr "Lizenz konnte nicht widerrufen werden."
|
|||||||
#: src/Admin/AdminController.php:466 src/Admin/AdminController.php:484
|
#: src/Admin/AdminController.php:466 src/Admin/AdminController.php:484
|
||||||
#: src/Admin/AdminController.php:504 src/Admin/AdminController.php:522
|
#: src/Admin/AdminController.php:504 src/Admin/AdminController.php:522
|
||||||
#: src/Admin/AdminController.php:589 src/Admin/AdminController.php:779
|
#: src/Admin/AdminController.php:589 src/Admin/AdminController.php:779
|
||||||
#: src/Frontend/AccountController.php:325
|
#: src/Admin/SettingsController.php:454 src/Frontend/AccountController.php:326
|
||||||
msgid "Security check failed."
|
msgid "Security check failed."
|
||||||
msgstr "Sicherheitsüberprüfung fehlgeschlagen."
|
msgstr "Sicherheitsüberprüfung fehlgeschlagen."
|
||||||
|
|
||||||
@@ -494,7 +408,6 @@ msgstr "Lizenz erfolgreich verlängert."
|
|||||||
msgid "License set to lifetime successfully."
|
msgid "License set to lifetime successfully."
|
||||||
msgstr "Lizenz erfolgreich auf lebenslang gesetzt."
|
msgstr "Lizenz erfolgreich auf lebenslang gesetzt."
|
||||||
|
|
||||||
#. translators: %d: number of licenses
|
|
||||||
#: src/Admin/AdminController.php:1068
|
#: src/Admin/AdminController.php:1068
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license activated."
|
msgid "%d license activated."
|
||||||
@@ -502,7 +415,6 @@ msgid_plural "%d licenses activated."
|
|||||||
msgstr[0] "%d Lizenz aktiviert."
|
msgstr[0] "%d Lizenz aktiviert."
|
||||||
msgstr[1] "%d Lizenzen aktiviert."
|
msgstr[1] "%d Lizenzen aktiviert."
|
||||||
|
|
||||||
#. translators: %d: number of licenses
|
|
||||||
#: src/Admin/AdminController.php:1076
|
#: src/Admin/AdminController.php:1076
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license deactivated."
|
msgid "%d license deactivated."
|
||||||
@@ -510,7 +422,6 @@ msgid_plural "%d licenses deactivated."
|
|||||||
msgstr[0] "%d Lizenz deaktiviert."
|
msgstr[0] "%d Lizenz deaktiviert."
|
||||||
msgstr[1] "%d Lizenzen deaktiviert."
|
msgstr[1] "%d Lizenzen deaktiviert."
|
||||||
|
|
||||||
#. translators: %d: number of licenses
|
|
||||||
#: src/Admin/AdminController.php:1084
|
#: src/Admin/AdminController.php:1084
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license revoked."
|
msgid "%d license revoked."
|
||||||
@@ -518,7 +429,6 @@ msgid_plural "%d licenses revoked."
|
|||||||
msgstr[0] "%d Lizenz widerrufen."
|
msgstr[0] "%d Lizenz widerrufen."
|
||||||
msgstr[1] "%d Lizenzen widerrufen."
|
msgstr[1] "%d Lizenzen widerrufen."
|
||||||
|
|
||||||
#. translators: %d: number of licenses
|
|
||||||
#: src/Admin/AdminController.php:1092
|
#: src/Admin/AdminController.php:1092
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license deleted."
|
msgid "%d license deleted."
|
||||||
@@ -526,7 +436,6 @@ msgid_plural "%d licenses deleted."
|
|||||||
msgstr[0] "%d Lizenz gelöscht."
|
msgstr[0] "%d Lizenz gelöscht."
|
||||||
msgstr[1] "%d Lizenzen gelöscht."
|
msgstr[1] "%d Lizenzen gelöscht."
|
||||||
|
|
||||||
#. translators: %d: number of licenses
|
|
||||||
#: src/Admin/AdminController.php:1100
|
#: src/Admin/AdminController.php:1100
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license extended."
|
msgid "%d license extended."
|
||||||
@@ -548,7 +457,6 @@ msgstr ""
|
|||||||
msgid "No licenses to export."
|
msgid "No licenses to export."
|
||||||
msgstr "Keine Lizenzen zum Exportieren."
|
msgstr "Keine Lizenzen zum Exportieren."
|
||||||
|
|
||||||
#. translators: %d: number of licenses imported
|
|
||||||
#: src/Admin/AdminController.php:1121
|
#: src/Admin/AdminController.php:1121
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license imported."
|
msgid "%d license imported."
|
||||||
@@ -556,7 +464,6 @@ msgid_plural "%d licenses imported."
|
|||||||
msgstr[0] "%d Lizenz importiert."
|
msgstr[0] "%d Lizenz importiert."
|
||||||
msgstr[1] "%d Lizenzen importiert."
|
msgstr[1] "%d Lizenzen importiert."
|
||||||
|
|
||||||
#. translators: %d: number of licenses updated
|
|
||||||
#: src/Admin/AdminController.php:1128
|
#: src/Admin/AdminController.php:1128
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d updated."
|
msgid "%d updated."
|
||||||
@@ -564,7 +471,6 @@ msgid_plural "%d updated."
|
|||||||
msgstr[0] "%d aktualisiert."
|
msgstr[0] "%d aktualisiert."
|
||||||
msgstr[1] "%d aktualisiert."
|
msgstr[1] "%d aktualisiert."
|
||||||
|
|
||||||
#. translators: %d: number of licenses skipped
|
|
||||||
#: src/Admin/AdminController.php:1136
|
#: src/Admin/AdminController.php:1136
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d skipped."
|
msgid "%d skipped."
|
||||||
@@ -572,7 +478,6 @@ msgid_plural "%d skipped."
|
|||||||
msgstr[0] "%d übersprungen."
|
msgstr[0] "%d übersprungen."
|
||||||
msgstr[1] "%d übersprungen."
|
msgstr[1] "%d übersprungen."
|
||||||
|
|
||||||
#. translators: %d: number of errors
|
|
||||||
#: src/Admin/AdminController.php:1144
|
#: src/Admin/AdminController.php:1144
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d error."
|
msgid "%d error."
|
||||||
@@ -649,14 +554,14 @@ msgid "Bulk Actions"
|
|||||||
msgstr "Massenaktionen"
|
msgstr "Massenaktionen"
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:1235 src/Admin/AdminController.php:1407
|
#: src/Admin/AdminController.php:1235 src/Admin/AdminController.php:1407
|
||||||
#: src/Admin/VersionAdminController.php:171
|
#: src/Admin/VersionAdminController.php:188
|
||||||
#: src/Admin/VersionAdminController.php:393
|
#: src/Admin/VersionAdminController.php:419
|
||||||
msgid "Activate"
|
msgid "Activate"
|
||||||
msgstr "Aktivieren"
|
msgstr "Aktivieren"
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:1236 src/Admin/AdminController.php:1408
|
#: src/Admin/AdminController.php:1236 src/Admin/AdminController.php:1408
|
||||||
#: src/Admin/VersionAdminController.php:171
|
#: src/Admin/VersionAdminController.php:188
|
||||||
#: src/Admin/VersionAdminController.php:393
|
#: src/Admin/VersionAdminController.php:419
|
||||||
msgid "Deactivate"
|
msgid "Deactivate"
|
||||||
msgstr "Deaktivieren"
|
msgstr "Deaktivieren"
|
||||||
|
|
||||||
@@ -678,8 +583,8 @@ msgid "Extend 1 year"
|
|||||||
msgstr "1 Jahr verlängern"
|
msgstr "1 Jahr verlängern"
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:1241 src/Admin/AdminController.php:1377
|
#: src/Admin/AdminController.php:1241 src/Admin/AdminController.php:1377
|
||||||
#: src/Admin/AdminController.php:1413 src/Admin/VersionAdminController.php:174
|
#: src/Admin/AdminController.php:1413 src/Admin/VersionAdminController.php:191
|
||||||
#: src/Admin/VersionAdminController.php:396
|
#: src/Admin/VersionAdminController.php:422
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Löschen"
|
msgstr "Löschen"
|
||||||
|
|
||||||
@@ -700,7 +605,7 @@ msgstr "Erstellt"
|
|||||||
msgid "No licenses found."
|
msgid "No licenses found."
|
||||||
msgstr "Keine Lizenzen gefunden."
|
msgstr "Keine Lizenzen gefunden."
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:1276 src/Frontend/AccountController.php:193
|
#: src/Admin/AdminController.php:1276 src/Frontend/AccountController.php:194
|
||||||
msgid "Copy to clipboard"
|
msgid "Copy to clipboard"
|
||||||
msgstr "In Zwischenablage kopieren"
|
msgstr "In Zwischenablage kopieren"
|
||||||
|
|
||||||
@@ -828,6 +733,171 @@ msgstr "Lizenz"
|
|||||||
msgid "No domain specified"
|
msgid "No domain specified"
|
||||||
msgstr "Keine Domain angegeben"
|
msgstr "Keine Domain angegeben"
|
||||||
|
|
||||||
|
#: src/Admin/SettingsController.php:54
|
||||||
|
msgid "Licensed Products"
|
||||||
|
msgstr "Lizensierte Produkte"
|
||||||
|
|
||||||
|
#: 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 ""
|
||||||
|
"Konfigurieren Sie die Lizenz für dieses Plugin. Eine gültige Lizenz ist "
|
||||||
|
"erforderlich, damit die Frontend-Funktionen funktionieren."
|
||||||
|
|
||||||
|
#: 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: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: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: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/VersionAdminController.php:58
|
#: src/Admin/VersionAdminController.php:58
|
||||||
msgid "Product Versions"
|
msgid "Product Versions"
|
||||||
msgstr "Produktversionen"
|
msgstr "Produktversionen"
|
||||||
@@ -837,7 +907,7 @@ msgid "Add New Version"
|
|||||||
msgstr "Neue Version hinzufügen"
|
msgstr "Neue Version hinzufügen"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:81
|
#: src/Admin/VersionAdminController.php:81
|
||||||
#: src/Admin/VersionAdminController.php:129
|
#: src/Admin/VersionAdminController.php:136
|
||||||
msgid "Version"
|
msgid "Version"
|
||||||
msgstr "Version"
|
msgstr "Version"
|
||||||
|
|
||||||
@@ -846,7 +916,7 @@ msgid "Use semantic versioning (e.g., 1.0.0)"
|
|||||||
msgstr "Verwenden Sie semantische Versionierung (z.B. 1.0.0)"
|
msgstr "Verwenden Sie semantische Versionierung (z.B. 1.0.0)"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:88
|
#: src/Admin/VersionAdminController.php:88
|
||||||
#: src/Admin/VersionAdminController.php:130
|
#: src/Admin/VersionAdminController.php:137
|
||||||
msgid "Download File"
|
msgid "Download File"
|
||||||
msgstr "Download-Datei"
|
msgstr "Download-Datei"
|
||||||
|
|
||||||
@@ -855,6 +925,7 @@ msgid "Select File"
|
|||||||
msgstr "Datei auswählen"
|
msgstr "Datei auswählen"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:96
|
#: src/Admin/VersionAdminController.php:96
|
||||||
|
#: src/Admin/VersionAdminController.php:110
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Entfernen"
|
msgstr "Entfernen"
|
||||||
|
|
||||||
@@ -870,127 +941,135 @@ msgstr ""
|
|||||||
msgid "Checksum File"
|
msgid "Checksum File"
|
||||||
msgstr "Prüfsummendatei"
|
msgstr "Prüfsummendatei"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:105
|
#: src/Admin/VersionAdminController.php:107
|
||||||
|
msgid "Select Checksum File"
|
||||||
|
msgstr "Prüfsummendatei auswählen"
|
||||||
|
|
||||||
|
#: src/Admin/VersionAdminController.php:112
|
||||||
msgid ""
|
msgid ""
|
||||||
"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity."
|
"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Laden Sie eine SHA256-Prüfsummendatei (.sha256 oder .txt) hoch, um die "
|
"Laden Sie eine SHA256-Prüfsummendatei (.sha256 oder .txt) hoch, um die "
|
||||||
"Dateiintegrität zu überprüfen."
|
"Dateiintegrität zu überprüfen."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:109
|
#: src/Admin/VersionAdminController.php:116
|
||||||
#: src/Admin/VersionAdminController.php:131
|
#: src/Admin/VersionAdminController.php:139
|
||||||
msgid "Release Notes"
|
msgid "Release Notes"
|
||||||
msgstr "Versionshinweise"
|
msgstr "Versionshinweise"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:117
|
#: src/Admin/VersionAdminController.php:124
|
||||||
msgid "Add Version"
|
msgid "Add Version"
|
||||||
msgstr "Version hinzufügen"
|
msgstr "Version hinzufügen"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:125
|
#: src/Admin/VersionAdminController.php:132
|
||||||
msgid "Existing Versions"
|
msgid "Existing Versions"
|
||||||
msgstr "Vorhandene Versionen"
|
msgstr "Vorhandene Versionen"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:133
|
#: src/Admin/VersionAdminController.php:138
|
||||||
|
msgid "SHA256"
|
||||||
|
msgstr "SHA256"
|
||||||
|
|
||||||
|
#: src/Admin/VersionAdminController.php:141
|
||||||
msgid "Released"
|
msgid "Released"
|
||||||
msgstr "Veröffentlicht"
|
msgstr "Veröffentlicht"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:140
|
#: src/Admin/VersionAdminController.php:148
|
||||||
msgid "No versions found. Add your first version above."
|
msgid "No versions found. Add your first version above."
|
||||||
msgstr "Keine Versionen gefunden. Fügen Sie Ihre erste Version oben hinzu."
|
msgstr "Keine Versionen gefunden. Fügen Sie Ihre erste Version oben hinzu."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:156
|
#: src/Admin/VersionAdminController.php:165
|
||||||
#: src/Admin/VersionAdminController.php:378
|
#: src/Admin/VersionAdminController.php:396
|
||||||
msgid "Uploaded file"
|
msgid "Uploaded file"
|
||||||
msgstr "Hochgeladene Datei"
|
msgstr "Hochgeladene Datei"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:159
|
#: src/Admin/VersionAdminController.php:169
|
||||||
#: src/Admin/VersionAdminController.php:381
|
#: src/Admin/VersionAdminController.php:400
|
||||||
msgid "No download file"
|
msgid "No download file"
|
||||||
msgstr "Keine Download-Datei"
|
msgstr "Keine Download-Datei"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:215
|
#: src/Admin/VersionAdminController.php:232
|
||||||
msgid "Are you sure you want to delete this version?"
|
msgid "Are you sure you want to delete this version?"
|
||||||
msgstr "Sind Sie sicher, dass Sie diese Version löschen möchten?"
|
msgstr "Sind Sie sicher, dass Sie diese Version löschen möchten?"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:216
|
#: src/Admin/VersionAdminController.php:233
|
||||||
msgid "Please enter a version number."
|
msgid "Please enter a version number."
|
||||||
msgstr "Bitte geben Sie eine Versionsnummer ein."
|
msgstr "Bitte geben Sie eine Versionsnummer ein."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:217
|
#: src/Admin/VersionAdminController.php:234
|
||||||
msgid "Please enter a valid version number (e.g., 1.0.0)."
|
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)."
|
msgstr "Bitte geben Sie eine gültige Versionsnummer ein (z.B. 1.0.0)."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:218
|
#: src/Admin/VersionAdminController.php:235
|
||||||
msgid "An error occurred. Please try again."
|
msgid "An error occurred. Please try again."
|
||||||
msgstr "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut."
|
msgstr "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:219
|
#: src/Admin/VersionAdminController.php:236
|
||||||
msgid "Select Download File"
|
msgid "Select Download File"
|
||||||
msgstr "Download-Datei auswählen"
|
msgstr "Download-Datei auswählen"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:220
|
#: src/Admin/VersionAdminController.php:237
|
||||||
msgid "Use this file"
|
msgid "Use this file"
|
||||||
msgstr "Diese Datei verwenden"
|
msgstr "Diese Datei verwenden"
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:221
|
#: src/Admin/VersionAdminController.php:238
|
||||||
msgid ""
|
msgid ""
|
||||||
"Invalid checksum file format. File must contain a 64-character SHA256 hash."
|
"Invalid checksum file format. File must contain a 64-character SHA256 hash."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ungültiges Prüfsummendateiformat. Die Datei muss einen 64-stelligen "
|
"Ungültiges Prüfsummendateiformat. Die Datei muss einen 64-stelligen SHA256-"
|
||||||
"SHA256-Hash enthalten."
|
"Hash enthalten."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:222
|
#: src/Admin/VersionAdminController.php:239
|
||||||
msgid "Failed to read checksum file."
|
msgid "Failed to read checksum file."
|
||||||
msgstr "Prüfsummendatei konnte nicht gelesen werden."
|
msgstr "Prüfsummendatei konnte nicht gelesen werden."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:252
|
#: src/Admin/VersionAdminController.php:269
|
||||||
msgid "Product ID and version are required."
|
msgid "Product ID and version are required."
|
||||||
msgstr "Produkt-ID und Version sind erforderlich."
|
msgstr "Produkt-ID und Version sind erforderlich."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:257
|
#: src/Admin/VersionAdminController.php:274
|
||||||
msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)."
|
msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ungültiges Versionsformat. Verwenden Sie semantische Versionierung (z.B. "
|
"Ungültiges Versionsformat. Verwenden Sie semantische Versionierung (z.B. "
|
||||||
"1.0.0)."
|
"1.0.0)."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:262
|
#: src/Admin/VersionAdminController.php:279
|
||||||
msgid "This version already exists."
|
msgid "This version already exists."
|
||||||
msgstr "Diese Version existiert bereits."
|
msgstr "Diese Version existiert bereits."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:268
|
#: src/Admin/VersionAdminController.php:285
|
||||||
msgid "Product not found."
|
msgid "Product not found."
|
||||||
msgstr "Produkt nicht gefunden."
|
msgstr "Produkt nicht gefunden."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:272
|
#: src/Admin/VersionAdminController.php:289
|
||||||
msgid "This product is not a licensed product."
|
msgid "This product is not a licensed product."
|
||||||
msgstr "Dieses Produkt ist kein lizensiertes Produkt."
|
msgstr "Dieses Produkt ist kein lizensiertes Produkt."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:289
|
#: src/Admin/VersionAdminController.php:306
|
||||||
msgid "Failed to create version."
|
msgid "Failed to create version."
|
||||||
msgstr "Version konnte nicht erstellt werden."
|
msgstr "Version konnte nicht erstellt werden."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:297
|
#: src/Admin/VersionAdminController.php:314
|
||||||
msgid "Version added successfully."
|
msgid "Version added successfully."
|
||||||
msgstr "Version erfolgreich hinzugefügt."
|
msgstr "Version erfolgreich hinzugefügt."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:317
|
#: src/Admin/VersionAdminController.php:334
|
||||||
#: src/Admin/VersionAdminController.php:344
|
#: src/Admin/VersionAdminController.php:361
|
||||||
msgid "Version ID is required."
|
msgid "Version ID is required."
|
||||||
msgstr "Versions-ID ist erforderlich."
|
msgstr "Versions-ID ist erforderlich."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:323
|
#: src/Admin/VersionAdminController.php:340
|
||||||
msgid "Failed to delete version."
|
msgid "Failed to delete version."
|
||||||
msgstr "Version konnte nicht gelöscht werden."
|
msgstr "Version konnte nicht gelöscht werden."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:326
|
#: src/Admin/VersionAdminController.php:343
|
||||||
msgid "Version deleted successfully."
|
msgid "Version deleted successfully."
|
||||||
msgstr "Version erfolgreich gelöscht."
|
msgstr "Version erfolgreich gelöscht."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:350
|
#: src/Admin/VersionAdminController.php:367
|
||||||
msgid "Failed to update version."
|
msgid "Failed to update version."
|
||||||
msgstr "Version konnte nicht aktualisiert werden."
|
msgstr "Version konnte nicht aktualisiert werden."
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:354
|
#: src/Admin/VersionAdminController.php:371
|
||||||
msgid "Version updated successfully."
|
msgid "Version updated successfully."
|
||||||
msgstr "Version erfolgreich aktualisiert."
|
msgstr "Version erfolgreich aktualisiert."
|
||||||
|
|
||||||
@@ -1083,11 +1162,19 @@ msgstr "Diese Lizenz ist inaktiv."
|
|||||||
msgid "This license is not valid for this domain."
|
msgid "This license is not valid for this domain."
|
||||||
msgstr "Diese Lizenz ist für diese Domain nicht gültig."
|
msgstr "Diese Lizenz ist für diese Domain nicht gültig."
|
||||||
|
|
||||||
#: src/License/LicenseManager.php:760 src/Frontend/AccountController.php:139
|
#: src/License/LicenseManager.php:760 src/Frontend/AccountController.php:140
|
||||||
#: src/Email/LicenseExpirationEmail.php:107
|
#: src/Email/LicenseExpirationEmail.php:107
|
||||||
msgid "Unknown Product"
|
msgid "Unknown Product"
|
||||||
msgstr "Unbekanntes Produkt"
|
msgstr "Unbekanntes Produkt"
|
||||||
|
|
||||||
|
#: 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
|
#: src/Product/LicensedProductType.php:55
|
||||||
msgid "Licensed Product"
|
msgid "Licensed Product"
|
||||||
msgstr "Lizensiertes Produkt"
|
msgstr "Lizensiertes Produkt"
|
||||||
@@ -1101,7 +1188,6 @@ msgstr "Lizenz-Einstellungen"
|
|||||||
msgid "%d days"
|
msgid "%d days"
|
||||||
msgstr "%d Tage"
|
msgstr "%d Tage"
|
||||||
|
|
||||||
#. translators: %s: URL to settings page
|
|
||||||
#: src/Product/LicensedProductType.php:113
|
#: src/Product/LicensedProductType.php:113
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Leave fields empty to use default settings from %s."
|
msgid "Leave fields empty to use default settings from %s."
|
||||||
@@ -1115,7 +1201,6 @@ msgstr "WooCommerce > Einstellungen > Lizensierte Produkte"
|
|||||||
msgid "Max Activations"
|
msgid "Max Activations"
|
||||||
msgstr "Max. Aktivierungen"
|
msgstr "Max. Aktivierungen"
|
||||||
|
|
||||||
#. translators: %d: default max activations value
|
|
||||||
#: src/Product/LicensedProductType.php:125
|
#: src/Product/LicensedProductType.php:125
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Maximum number of domain activations per license. Default: %d"
|
msgid "Maximum number of domain activations per license. Default: %d"
|
||||||
@@ -1125,7 +1210,6 @@ msgstr "Maximale Anzahl der Domain-Aktivierungen pro Lizenz. Standard: %d"
|
|||||||
msgid "License Validity (Days)"
|
msgid "License Validity (Days)"
|
||||||
msgstr "Lizenz-Gültigkeit (Tage)"
|
msgstr "Lizenz-Gültigkeit (Tage)"
|
||||||
|
|
||||||
#. translators: %s: default validity value
|
|
||||||
#: src/Product/LicensedProductType.php:143
|
#: src/Product/LicensedProductType.php:143
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Number of days the license is valid. Leave empty for default (%s)."
|
msgid "Number of days the license is valid. Leave empty for default (%s)."
|
||||||
@@ -1135,7 +1219,6 @@ msgstr "Anzahl Tage, die die Lizenz gültig ist. Leer lassen für Standard (%s).
|
|||||||
msgid "Bind to Major Version"
|
msgid "Bind to Major Version"
|
||||||
msgstr "An Hauptversion binden"
|
msgstr "An Hauptversion binden"
|
||||||
|
|
||||||
#. translators: %s: default bind to version value (Yes/No)
|
|
||||||
#: src/Product/LicensedProductType.php:161
|
#: src/Product/LicensedProductType.php:161
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -1157,7 +1240,6 @@ msgstr "Nein"
|
|||||||
msgid "Attachment file not found."
|
msgid "Attachment file not found."
|
||||||
msgstr "Anhangs-Datei nicht gefunden."
|
msgstr "Anhangs-Datei nicht gefunden."
|
||||||
|
|
||||||
#. translators: 1: provided hash, 2: calculated hash
|
|
||||||
#: src/Product/VersionManager.php:177
|
#: src/Product/VersionManager.php:177
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
|
msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
|
||||||
@@ -1218,11 +1300,11 @@ msgstr "Download-Datei nicht gefunden."
|
|||||||
msgid "Please log in to view your licenses."
|
msgid "Please log in to view your licenses."
|
||||||
msgstr "Bitte melden Sie sich an, um Ihre Lizenzen zu sehen."
|
msgstr "Bitte melden Sie sich an, um Ihre Lizenzen zu sehen."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:164
|
#: src/Frontend/AccountController.php:165
|
||||||
msgid "You have no licenses yet."
|
msgid "You have no licenses yet."
|
||||||
msgstr "Sie haben noch keine Lizenzen."
|
msgstr "Sie haben noch keine Lizenzen."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:189
|
#: src/Frontend/AccountController.php:190
|
||||||
#: src/Email/LicenseEmailController.php:173
|
#: src/Email/LicenseEmailController.php:173
|
||||||
#: src/Email/LicenseEmailController.php:177
|
#: src/Email/LicenseEmailController.php:177
|
||||||
#: src/Email/LicenseEmailController.php:281
|
#: src/Email/LicenseEmailController.php:281
|
||||||
@@ -1231,76 +1313,76 @@ msgstr "Sie haben noch keine Lizenzen."
|
|||||||
msgid "License Key:"
|
msgid "License Key:"
|
||||||
msgstr "Lizenzschlüssel:"
|
msgstr "Lizenzschlüssel:"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:200
|
#: src/Frontend/AccountController.php:201
|
||||||
#: src/Email/LicenseExpirationEmail.php:215
|
#: src/Email/LicenseExpirationEmail.php:215
|
||||||
#: src/Email/LicenseExpirationEmail.php:271
|
#: src/Email/LicenseExpirationEmail.php:271
|
||||||
msgid "Domain:"
|
msgid "Domain:"
|
||||||
msgstr "Domain:"
|
msgstr "Domain:"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:206
|
#: src/Frontend/AccountController.php:207
|
||||||
msgid "Transfer to new domain"
|
msgid "Transfer to new domain"
|
||||||
msgstr "Auf neue Domain übertragen"
|
msgstr "Auf neue Domain übertragen"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:208
|
#: src/Frontend/AccountController.php:209
|
||||||
msgid "Transfer"
|
msgid "Transfer"
|
||||||
msgstr "Übertragen"
|
msgstr "Übertragen"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:212
|
#: src/Frontend/AccountController.php:213
|
||||||
#: src/Email/LicenseEmailController.php:284
|
#: src/Email/LicenseEmailController.php:284
|
||||||
#: src/Email/LicenseExpirationEmail.php:219
|
#: src/Email/LicenseExpirationEmail.php:219
|
||||||
#: src/Email/LicenseExpirationEmail.php:272
|
#: src/Email/LicenseExpirationEmail.php:272
|
||||||
msgid "Expires:"
|
msgid "Expires:"
|
||||||
msgstr "Läuft ab:"
|
msgstr "Läuft ab:"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:217
|
#: src/Frontend/AccountController.php:218
|
||||||
#: src/Email/LicenseEmailController.php:248
|
#: src/Email/LicenseEmailController.php:248
|
||||||
#: src/Email/LicenseEmailController.php:287
|
#: src/Email/LicenseEmailController.php:287
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Nie"
|
msgstr "Nie"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:225
|
#: src/Frontend/AccountController.php:226
|
||||||
msgid "Available Downloads"
|
msgid "Available Downloads"
|
||||||
msgstr "Verfügbare Downloads"
|
msgstr "Verfügbare Downloads"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:231
|
#: src/Frontend/AccountController.php:232
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Version %s"
|
msgid "Version %s"
|
||||||
msgstr "Version %s"
|
msgstr "Version %s"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:248
|
#: src/Frontend/AccountController.php:249
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr "Schliessen"
|
msgstr "Schliessen"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:249
|
#: src/Frontend/AccountController.php:250
|
||||||
msgid "Transfer License to New Domain"
|
msgid "Transfer License to New Domain"
|
||||||
msgstr "Lizenz auf neue Domain übertragen"
|
msgstr "Lizenz auf neue Domain übertragen"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:254
|
#: src/Frontend/AccountController.php:255
|
||||||
msgid "Current Domain"
|
msgid "Current Domain"
|
||||||
msgstr "Aktuelle Domain"
|
msgstr "Aktuelle Domain"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:259
|
#: src/Frontend/AccountController.php:260
|
||||||
msgid "New Domain"
|
msgid "New Domain"
|
||||||
msgstr "Neue Domain"
|
msgstr "Neue Domain"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:263
|
#: src/Frontend/AccountController.php:264
|
||||||
msgid "Enter the new domain without http:// or www."
|
msgid "Enter the new domain without http:// or www."
|
||||||
msgstr "Geben Sie die neue Domain ohne http:// oder www ein."
|
msgstr "Geben Sie die neue Domain ohne http:// oder www ein."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:268
|
#: src/Frontend/AccountController.php:269
|
||||||
msgid "Transfer License"
|
msgid "Transfer License"
|
||||||
msgstr "Lizenz übertragen"
|
msgstr "Lizenz übertragen"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:310
|
#: src/Frontend/AccountController.php:311
|
||||||
#: src/Frontend/AccountController.php:377
|
#: src/Frontend/AccountController.php:378
|
||||||
msgid "License transferred successfully!"
|
msgid "License transferred successfully!"
|
||||||
msgstr "Lizenz erfolgreich übertragen!"
|
msgstr "Lizenz erfolgreich übertragen!"
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:311
|
#: src/Frontend/AccountController.php:312
|
||||||
msgid "Transfer failed. Please try again."
|
msgid "Transfer failed. Please try again."
|
||||||
msgstr "Übertragung fehlgeschlagen. Bitte versuchen Sie es erneut."
|
msgstr "Übertragung fehlgeschlagen. Bitte versuchen Sie es erneut."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:312
|
#: src/Frontend/AccountController.php:313
|
||||||
msgid ""
|
msgid ""
|
||||||
"Are you sure you want to transfer this license to a new domain? This action "
|
"Are you sure you want to transfer this license to a new domain? This action "
|
||||||
"cannot be undone."
|
"cannot be undone."
|
||||||
@@ -1308,31 +1390,31 @@ msgstr ""
|
|||||||
"Sind Sie sicher, dass Sie diese Lizenz auf eine neue Domain übertragen "
|
"Sind Sie sicher, dass Sie diese Lizenz auf eine neue Domain übertragen "
|
||||||
"möchten? Diese Aktion kann nicht rückgängig gemacht werden."
|
"möchten? Diese Aktion kann nicht rückgängig gemacht werden."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:331
|
#: src/Frontend/AccountController.php:332
|
||||||
msgid "Please log in to transfer a license."
|
msgid "Please log in to transfer a license."
|
||||||
msgstr "Bitte melden Sie sich an, um eine Lizenz zu übertragen."
|
msgstr "Bitte melden Sie sich an, um eine Lizenz zu übertragen."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:337
|
#: src/Frontend/AccountController.php:338
|
||||||
msgid "Invalid license."
|
msgid "Invalid license."
|
||||||
msgstr "Ungültige Lizenz."
|
msgstr "Ungültige Lizenz."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:355
|
#: src/Frontend/AccountController.php:356
|
||||||
msgid "You do not have permission to transfer this license."
|
msgid "You do not have permission to transfer this license."
|
||||||
msgstr "Sie haben keine Berechtigung, diese Lizenz zu übertragen."
|
msgstr "Sie haben keine Berechtigung, diese Lizenz zu übertragen."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:360
|
#: src/Frontend/AccountController.php:361
|
||||||
msgid "Revoked licenses cannot be transferred."
|
msgid "Revoked licenses cannot be transferred."
|
||||||
msgstr "Widerrufene Lizenzen können nicht übertragen werden."
|
msgstr "Widerrufene Lizenzen können nicht übertragen werden."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:364
|
#: src/Frontend/AccountController.php:365
|
||||||
msgid "Expired licenses cannot be transferred."
|
msgid "Expired licenses cannot be transferred."
|
||||||
msgstr "Abgelaufene Lizenzen können nicht übertragen werden."
|
msgstr "Abgelaufene Lizenzen können nicht übertragen werden."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:369
|
#: src/Frontend/AccountController.php:370
|
||||||
msgid "The new domain is the same as the current domain."
|
msgid "The new domain is the same as the current domain."
|
||||||
msgstr "Die neue Domain ist dieselbe wie die aktuelle Domain."
|
msgstr "Die neue Domain ist dieselbe wie die aktuelle Domain."
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:381
|
#: src/Frontend/AccountController.php:382
|
||||||
msgid "Failed to transfer license. Please try again."
|
msgid "Failed to transfer license. Please try again."
|
||||||
msgstr "Lizenzübertragung fehlgeschlagen. Bitte versuchen Sie es erneut."
|
msgstr "Lizenzübertragung fehlgeschlagen. Bitte versuchen Sie es erneut."
|
||||||
|
|
||||||
@@ -1420,7 +1502,6 @@ msgstr ""
|
|||||||
"Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz vor "
|
"Um dieses Produkt weiterhin zu nutzen, verlängern Sie bitte Ihre Lizenz vor "
|
||||||
"dem Ablaufdatum."
|
"dem Ablaufdatum."
|
||||||
|
|
||||||
#. translators: %s: list of placeholders
|
|
||||||
#: src/Email/LicenseExpirationEmail.php:301
|
#: src/Email/LicenseExpirationEmail.php:301
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Available placeholders: %s"
|
msgid "Available placeholders: %s"
|
||||||
@@ -1458,7 +1539,21 @@ msgstr "E-Mail-Typ"
|
|||||||
msgid "Choose which format of email to send."
|
msgid "Choose which format of email to send."
|
||||||
msgstr "Wählen Sie, welches E-Mail-Format gesendet werden soll."
|
msgstr "Wählen Sie, welches E-Mail-Format gesendet werden soll."
|
||||||
|
|
||||||
#. translators: %s: WooCommerce plugin name
|
#: 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
|
#: wc-licensed-product.php:61
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%s requires WooCommerce to be installed and active."
|
msgid "%s requires WooCommerce to be installed and active."
|
||||||
@@ -1479,9 +1574,6 @@ msgstr ""
|
|||||||
#~ "Alternativ: Geben Sie eine externe Download-URL ein, anstatt eine Datei "
|
#~ "Alternativ: Geben Sie eine externe Download-URL ein, anstatt eine Datei "
|
||||||
#~ "hochzuladen."
|
#~ "hochzuladen."
|
||||||
|
|
||||||
#~ msgid "SHA256 Hash"
|
|
||||||
#~ msgstr "SHA256 Prüfsumme"
|
|
||||||
|
|
||||||
#~ msgid "Enter SHA256 checksum..."
|
#~ msgid "Enter SHA256 checksum..."
|
||||||
#~ msgstr "SHA256 Prüfsumme eingeben..."
|
#~ msgstr "SHA256 Prüfsumme eingeben..."
|
||||||
|
|
||||||
|
|||||||
@@ -1,105 +1,23 @@
|
|||||||
# WooCommerce Licensed Product Translation Template
|
# SOME DESCRIPTIVE TITLE.
|
||||||
# Copyright (C) 2026 Marco Graetsch
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
# This file is distributed under the same license as the WooCommerce Licensed Product package.
|
# This file is distributed under the same license as the WC Licensed Product package.
|
||||||
# Marco Graetsch <magdev3.0@gmail.com>, 2026.
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: WooCommerce Licensed Product 0.2.1\n"
|
"Project-Id-Version: WC Licensed Product 0.3.2\n"
|
||||||
"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n"
|
"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n"
|
||||||
"POT-Creation-Date: 2026-01-22 17:10+0100\n"
|
"POT-Creation-Date: 2026-01-22 19:11+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
"Language: \n"
|
"Language: \n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
||||||
|
|
||||||
#: src/Admin/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:78 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: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 ""
|
|
||||||
|
|
||||||
#. translators: %s: URL to WooCommerce email settings
|
|
||||||
#: 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/OrderLicenseController.php:56
|
#: src/Admin/OrderLicenseController.php:56
|
||||||
msgid "Product Licenses"
|
msgid "Product Licenses"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -158,7 +76,8 @@ msgid "Licenses will be generated when the order is marked as paid/completed."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:144 src/Admin/AdminController.php:1253
|
#: src/Admin/OrderLicenseController.php:144 src/Admin/AdminController.php:1253
|
||||||
#: src/Admin/AdminController.php:1391 src/Email/LicenseEmailController.php:230
|
#: src/Admin/AdminController.php:1391 src/Admin/SettingsController.php:142
|
||||||
|
#: src/Email/LicenseEmailController.php:230
|
||||||
msgid "License Key"
|
msgid "License Key"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -173,7 +92,7 @@ msgid "Domain"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:147 src/Admin/AdminController.php:1257
|
#: src/Admin/OrderLicenseController.php:147 src/Admin/AdminController.php:1257
|
||||||
#: src/Admin/AdminController.php:1395 src/Admin/VersionAdminController.php:132
|
#: src/Admin/AdminController.php:1395 src/Admin/VersionAdminController.php:140
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -183,7 +102,7 @@ msgid "Expires"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:149 src/Admin/AdminController.php:1260
|
#: src/Admin/OrderLicenseController.php:149 src/Admin/AdminController.php:1260
|
||||||
#: src/Admin/AdminController.php:1398 src/Admin/VersionAdminController.php:134
|
#: src/Admin/AdminController.php:1398 src/Admin/VersionAdminController.php:142
|
||||||
msgid "Actions"
|
msgid "Actions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -198,15 +117,21 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:185 src/Admin/AdminController.php:146
|
#: src/Admin/OrderLicenseController.php:185 src/Admin/AdminController.php:146
|
||||||
#: src/Admin/AdminController.php:1303 src/Admin/AdminController.php:1323
|
#: src/Admin/AdminController.php:1303 src/Admin/AdminController.php:1323
|
||||||
#: src/Admin/AdminController.php:1344 src/Frontend/AccountController.php:270
|
#: src/Admin/AdminController.php:1344 src/Frontend/AccountController.php:271
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/Admin/OrderLicenseController.php:201 src/Admin/AdminController.php:148
|
||||||
|
#: src/Admin/AdminController.php:263 src/Admin/AdminController.php:1335
|
||||||
|
#: src/Admin/SettingsController.php:192 src/Product/LicensedProductType.php:104
|
||||||
|
#: src/Product/LicensedProductType.php:152
|
||||||
|
msgid "Lifetime"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:208
|
#: src/Admin/OrderLicenseController.php:208
|
||||||
msgid "View in Licenses"
|
msgid "View in Licenses"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: Link to licenses page
|
|
||||||
#: src/Admin/OrderLicenseController.php:221
|
#: src/Admin/OrderLicenseController.php:221
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "For more actions (revoke, extend, delete), go to the %s page."
|
msgid "For more actions (revoke, extend, delete), go to the %s page."
|
||||||
@@ -225,8 +150,8 @@ msgid "Error saving. Please try again."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:288
|
#: src/Admin/OrderLicenseController.php:288
|
||||||
#: src/Frontend/AccountController.php:313
|
#: src/Frontend/AccountController.php:314
|
||||||
#: src/Frontend/AccountController.php:345
|
#: src/Frontend/AccountController.php:346
|
||||||
msgid "Please enter a valid domain."
|
msgid "Please enter a valid domain."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -234,9 +159,9 @@ msgstr ""
|
|||||||
#: src/Admin/OrderLicenseController.php:340 src/Admin/AdminController.php:170
|
#: src/Admin/OrderLicenseController.php:340 src/Admin/AdminController.php:170
|
||||||
#: src/Admin/AdminController.php:210 src/Admin/AdminController.php:246
|
#: src/Admin/AdminController.php:210 src/Admin/AdminController.php:246
|
||||||
#: src/Admin/AdminController.php:298 src/Admin/AdminController.php:336
|
#: src/Admin/AdminController.php:298 src/Admin/AdminController.php:336
|
||||||
#: src/Admin/VersionAdminController.php:242
|
#: src/Admin/VersionAdminController.php:259
|
||||||
#: src/Admin/VersionAdminController.php:311
|
#: src/Admin/VersionAdminController.php:328
|
||||||
#: src/Admin/VersionAdminController.php:337
|
#: src/Admin/VersionAdminController.php:354
|
||||||
msgid "Permission denied."
|
msgid "Permission denied."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -265,7 +190,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/Admin/OrderLicenseController.php:363
|
#: src/Admin/OrderLicenseController.php:363
|
||||||
#: src/Frontend/DownloadController.php:105
|
#: src/Frontend/DownloadController.php:105
|
||||||
#: src/Frontend/AccountController.php:351
|
#: src/Frontend/AccountController.php:352
|
||||||
msgid "License not found."
|
msgid "License not found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -311,25 +236,25 @@ msgstr ""
|
|||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:149 src/Frontend/AccountController.php:308
|
#: src/Admin/AdminController.php:149 src/Frontend/AccountController.php:309
|
||||||
msgid "Copied!"
|
msgid "Copied!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:150 src/Frontend/AccountController.php:309
|
#: src/Admin/AdminController.php:150 src/Frontend/AccountController.php:310
|
||||||
msgid "Copy failed"
|
msgid "Copy failed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:153 src/Admin/AdminController.php:875
|
#: src/Admin/AdminController.php:153 src/Admin/AdminController.php:875
|
||||||
#: src/Admin/AdminController.php:1194 src/Admin/AdminController.php:1317
|
#: src/Admin/AdminController.php:1194 src/Admin/AdminController.php:1317
|
||||||
#: src/Admin/VersionAdminController.php:165
|
#: src/Admin/VersionAdminController.php:182
|
||||||
#: src/Admin/VersionAdminController.php:387
|
#: src/Admin/VersionAdminController.php:413
|
||||||
msgid "Active"
|
msgid "Active"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:154 src/Admin/AdminController.php:882
|
#: src/Admin/AdminController.php:154 src/Admin/AdminController.php:882
|
||||||
#: src/Admin/AdminController.php:1195 src/Admin/AdminController.php:1318
|
#: src/Admin/AdminController.php:1195 src/Admin/AdminController.php:1318
|
||||||
#: src/Admin/VersionAdminController.php:165
|
#: src/Admin/VersionAdminController.php:182
|
||||||
#: src/Admin/VersionAdminController.php:387
|
#: src/Admin/VersionAdminController.php:413
|
||||||
msgid "Inactive"
|
msgid "Inactive"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -395,7 +320,7 @@ msgstr ""
|
|||||||
#: src/Admin/AdminController.php:466 src/Admin/AdminController.php:484
|
#: src/Admin/AdminController.php:466 src/Admin/AdminController.php:484
|
||||||
#: src/Admin/AdminController.php:504 src/Admin/AdminController.php:522
|
#: src/Admin/AdminController.php:504 src/Admin/AdminController.php:522
|
||||||
#: src/Admin/AdminController.php:589 src/Admin/AdminController.php:779
|
#: src/Admin/AdminController.php:589 src/Admin/AdminController.php:779
|
||||||
#: src/Frontend/AccountController.php:325
|
#: src/Admin/SettingsController.php:454 src/Frontend/AccountController.php:326
|
||||||
msgid "Security check failed."
|
msgid "Security check failed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -475,7 +400,6 @@ msgstr ""
|
|||||||
msgid "License set to lifetime successfully."
|
msgid "License set to lifetime successfully."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %d: number of licenses
|
|
||||||
#: src/Admin/AdminController.php:1068
|
#: src/Admin/AdminController.php:1068
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license activated."
|
msgid "%d license activated."
|
||||||
@@ -483,7 +407,6 @@ msgid_plural "%d licenses activated."
|
|||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#. translators: %d: number of licenses
|
|
||||||
#: src/Admin/AdminController.php:1076
|
#: src/Admin/AdminController.php:1076
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license deactivated."
|
msgid "%d license deactivated."
|
||||||
@@ -491,7 +414,6 @@ msgid_plural "%d licenses deactivated."
|
|||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#. translators: %d: number of licenses
|
|
||||||
#: src/Admin/AdminController.php:1084
|
#: src/Admin/AdminController.php:1084
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license revoked."
|
msgid "%d license revoked."
|
||||||
@@ -499,7 +421,6 @@ msgid_plural "%d licenses revoked."
|
|||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#. translators: %d: number of licenses
|
|
||||||
#: src/Admin/AdminController.php:1092
|
#: src/Admin/AdminController.php:1092
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license deleted."
|
msgid "%d license deleted."
|
||||||
@@ -507,7 +428,6 @@ msgid_plural "%d licenses deleted."
|
|||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#. translators: %d: number of licenses
|
|
||||||
#: src/Admin/AdminController.php:1100
|
#: src/Admin/AdminController.php:1100
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license extended."
|
msgid "%d license extended."
|
||||||
@@ -527,7 +447,6 @@ msgstr ""
|
|||||||
msgid "No licenses to export."
|
msgid "No licenses to export."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %d: number of licenses imported
|
|
||||||
#: src/Admin/AdminController.php:1121
|
#: src/Admin/AdminController.php:1121
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d license imported."
|
msgid "%d license imported."
|
||||||
@@ -535,7 +454,6 @@ msgid_plural "%d licenses imported."
|
|||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#. translators: %d: number of licenses updated
|
|
||||||
#: src/Admin/AdminController.php:1128
|
#: src/Admin/AdminController.php:1128
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d updated."
|
msgid "%d updated."
|
||||||
@@ -543,7 +461,6 @@ msgid_plural "%d updated."
|
|||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#. translators: %d: number of licenses skipped
|
|
||||||
#: src/Admin/AdminController.php:1136
|
#: src/Admin/AdminController.php:1136
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d skipped."
|
msgid "%d skipped."
|
||||||
@@ -551,7 +468,6 @@ msgid_plural "%d skipped."
|
|||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#. translators: %d: number of errors
|
|
||||||
#: src/Admin/AdminController.php:1144
|
#: src/Admin/AdminController.php:1144
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d error."
|
msgid "%d error."
|
||||||
@@ -628,14 +544,14 @@ msgid "Bulk Actions"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:1235 src/Admin/AdminController.php:1407
|
#: src/Admin/AdminController.php:1235 src/Admin/AdminController.php:1407
|
||||||
#: src/Admin/VersionAdminController.php:171
|
#: src/Admin/VersionAdminController.php:188
|
||||||
#: src/Admin/VersionAdminController.php:393
|
#: src/Admin/VersionAdminController.php:419
|
||||||
msgid "Activate"
|
msgid "Activate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:1236 src/Admin/AdminController.php:1408
|
#: src/Admin/AdminController.php:1236 src/Admin/AdminController.php:1408
|
||||||
#: src/Admin/VersionAdminController.php:171
|
#: src/Admin/VersionAdminController.php:188
|
||||||
#: src/Admin/VersionAdminController.php:393
|
#: src/Admin/VersionAdminController.php:419
|
||||||
msgid "Deactivate"
|
msgid "Deactivate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -657,8 +573,8 @@ msgid "Extend 1 year"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:1241 src/Admin/AdminController.php:1377
|
#: src/Admin/AdminController.php:1241 src/Admin/AdminController.php:1377
|
||||||
#: src/Admin/AdminController.php:1413 src/Admin/VersionAdminController.php:174
|
#: src/Admin/AdminController.php:1413 src/Admin/VersionAdminController.php:191
|
||||||
#: src/Admin/VersionAdminController.php:396
|
#: src/Admin/VersionAdminController.php:422
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -679,7 +595,7 @@ msgstr ""
|
|||||||
msgid "No licenses found."
|
msgid "No licenses found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/AdminController.php:1276 src/Frontend/AccountController.php:193
|
#: src/Admin/AdminController.php:1276 src/Frontend/AccountController.php:194
|
||||||
msgid "Copy to clipboard"
|
msgid "Copy to clipboard"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -802,6 +718,156 @@ msgstr ""
|
|||||||
msgid "No domain specified"
|
msgid "No domain specified"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: 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: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: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 ""
|
||||||
|
"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:225
|
||||||
|
msgid "WooCommerce > Settings > Emails > License Expiration Warning"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: 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: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/VersionAdminController.php:58
|
#: src/Admin/VersionAdminController.php:58
|
||||||
msgid "Product Versions"
|
msgid "Product Versions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -811,7 +877,7 @@ msgid "Add New Version"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:81
|
#: src/Admin/VersionAdminController.php:81
|
||||||
#: src/Admin/VersionAdminController.php:129
|
#: src/Admin/VersionAdminController.php:136
|
||||||
msgid "Version"
|
msgid "Version"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -820,7 +886,7 @@ msgid "Use semantic versioning (e.g., 1.0.0)"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:88
|
#: src/Admin/VersionAdminController.php:88
|
||||||
#: src/Admin/VersionAdminController.php:130
|
#: src/Admin/VersionAdminController.php:137
|
||||||
msgid "Download File"
|
msgid "Download File"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -829,6 +895,7 @@ msgid "Select File"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:96
|
#: src/Admin/VersionAdminController.php:96
|
||||||
|
#: src/Admin/VersionAdminController.php:110
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -842,121 +909,129 @@ msgstr ""
|
|||||||
msgid "Checksum File"
|
msgid "Checksum File"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:105
|
#: src/Admin/VersionAdminController.php:107
|
||||||
|
msgid "Select Checksum File"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/Admin/VersionAdminController.php:112
|
||||||
msgid ""
|
msgid ""
|
||||||
"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity."
|
"Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:109
|
#: src/Admin/VersionAdminController.php:116
|
||||||
#: src/Admin/VersionAdminController.php:131
|
#: src/Admin/VersionAdminController.php:139
|
||||||
msgid "Release Notes"
|
msgid "Release Notes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:117
|
#: src/Admin/VersionAdminController.php:124
|
||||||
msgid "Add Version"
|
msgid "Add Version"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:125
|
#: src/Admin/VersionAdminController.php:132
|
||||||
msgid "Existing Versions"
|
msgid "Existing Versions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:133
|
#: src/Admin/VersionAdminController.php:138
|
||||||
|
msgid "SHA256"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/Admin/VersionAdminController.php:141
|
||||||
msgid "Released"
|
msgid "Released"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:140
|
#: src/Admin/VersionAdminController.php:148
|
||||||
msgid "No versions found. Add your first version above."
|
msgid "No versions found. Add your first version above."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:156
|
#: src/Admin/VersionAdminController.php:165
|
||||||
#: src/Admin/VersionAdminController.php:378
|
#: src/Admin/VersionAdminController.php:396
|
||||||
msgid "Uploaded file"
|
msgid "Uploaded file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:159
|
#: src/Admin/VersionAdminController.php:169
|
||||||
#: src/Admin/VersionAdminController.php:381
|
#: src/Admin/VersionAdminController.php:400
|
||||||
msgid "No download file"
|
msgid "No download file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:215
|
#: src/Admin/VersionAdminController.php:232
|
||||||
msgid "Are you sure you want to delete this version?"
|
msgid "Are you sure you want to delete this version?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:216
|
#: src/Admin/VersionAdminController.php:233
|
||||||
msgid "Please enter a version number."
|
msgid "Please enter a version number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:217
|
#: src/Admin/VersionAdminController.php:234
|
||||||
msgid "Please enter a valid version number (e.g., 1.0.0)."
|
msgid "Please enter a valid version number (e.g., 1.0.0)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:218
|
#: src/Admin/VersionAdminController.php:235
|
||||||
msgid "An error occurred. Please try again."
|
msgid "An error occurred. Please try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:219
|
#: src/Admin/VersionAdminController.php:236
|
||||||
msgid "Select Download File"
|
msgid "Select Download File"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:220
|
#: src/Admin/VersionAdminController.php:237
|
||||||
msgid "Use this file"
|
msgid "Use this file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:221
|
#: src/Admin/VersionAdminController.php:238
|
||||||
msgid ""
|
msgid ""
|
||||||
"Invalid checksum file format. File must contain a 64-character SHA256 hash."
|
"Invalid checksum file format. File must contain a 64-character SHA256 hash."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:222
|
#: src/Admin/VersionAdminController.php:239
|
||||||
msgid "Failed to read checksum file."
|
msgid "Failed to read checksum file."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:252
|
#: src/Admin/VersionAdminController.php:269
|
||||||
msgid "Product ID and version are required."
|
msgid "Product ID and version are required."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:257
|
#: src/Admin/VersionAdminController.php:274
|
||||||
msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)."
|
msgid "Invalid version format. Use semantic versioning (e.g., 1.0.0)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:262
|
#: src/Admin/VersionAdminController.php:279
|
||||||
msgid "This version already exists."
|
msgid "This version already exists."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:268
|
#: src/Admin/VersionAdminController.php:285
|
||||||
msgid "Product not found."
|
msgid "Product not found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:272
|
#: src/Admin/VersionAdminController.php:289
|
||||||
msgid "This product is not a licensed product."
|
msgid "This product is not a licensed product."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:289
|
#: src/Admin/VersionAdminController.php:306
|
||||||
msgid "Failed to create version."
|
msgid "Failed to create version."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:297
|
#: src/Admin/VersionAdminController.php:314
|
||||||
msgid "Version added successfully."
|
msgid "Version added successfully."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:317
|
#: src/Admin/VersionAdminController.php:334
|
||||||
#: src/Admin/VersionAdminController.php:344
|
#: src/Admin/VersionAdminController.php:361
|
||||||
msgid "Version ID is required."
|
msgid "Version ID is required."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:323
|
#: src/Admin/VersionAdminController.php:340
|
||||||
msgid "Failed to delete version."
|
msgid "Failed to delete version."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:326
|
#: src/Admin/VersionAdminController.php:343
|
||||||
msgid "Version deleted successfully."
|
msgid "Version deleted successfully."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:350
|
#: src/Admin/VersionAdminController.php:367
|
||||||
msgid "Failed to update version."
|
msgid "Failed to update version."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Admin/VersionAdminController.php:354
|
#: src/Admin/VersionAdminController.php:371
|
||||||
msgid "Version updated successfully."
|
msgid "Version updated successfully."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1047,11 +1122,19 @@ msgstr ""
|
|||||||
msgid "This license is not valid for this domain."
|
msgid "This license is not valid for this domain."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/License/LicenseManager.php:760 src/Frontend/AccountController.php:139
|
#: src/License/LicenseManager.php:760 src/Frontend/AccountController.php:140
|
||||||
#: src/Email/LicenseExpirationEmail.php:107
|
#: src/Email/LicenseExpirationEmail.php:107
|
||||||
msgid "Unknown Product"
|
msgid "Unknown Product"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: 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
|
#: src/Product/LicensedProductType.php:55
|
||||||
msgid "Licensed Product"
|
msgid "Licensed Product"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1065,7 +1148,6 @@ msgstr ""
|
|||||||
msgid "%d days"
|
msgid "%d days"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: URL to settings page
|
|
||||||
#: src/Product/LicensedProductType.php:113
|
#: src/Product/LicensedProductType.php:113
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Leave fields empty to use default settings from %s."
|
msgid "Leave fields empty to use default settings from %s."
|
||||||
@@ -1079,7 +1161,6 @@ msgstr ""
|
|||||||
msgid "Max Activations"
|
msgid "Max Activations"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %d: default max activations value
|
|
||||||
#: src/Product/LicensedProductType.php:125
|
#: src/Product/LicensedProductType.php:125
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Maximum number of domain activations per license. Default: %d"
|
msgid "Maximum number of domain activations per license. Default: %d"
|
||||||
@@ -1089,7 +1170,6 @@ msgstr ""
|
|||||||
msgid "License Validity (Days)"
|
msgid "License Validity (Days)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: default validity value
|
|
||||||
#: src/Product/LicensedProductType.php:143
|
#: src/Product/LicensedProductType.php:143
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Number of days the license is valid. Leave empty for default (%s)."
|
msgid "Number of days the license is valid. Leave empty for default (%s)."
|
||||||
@@ -1099,7 +1179,6 @@ msgstr ""
|
|||||||
msgid "Bind to Major Version"
|
msgid "Bind to Major Version"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: default bind to version value (Yes/No)
|
|
||||||
#: src/Product/LicensedProductType.php:161
|
#: src/Product/LicensedProductType.php:161
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -1119,7 +1198,6 @@ msgstr ""
|
|||||||
msgid "Attachment file not found."
|
msgid "Attachment file not found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: provided hash, 2: calculated hash
|
|
||||||
#: src/Product/VersionManager.php:177
|
#: src/Product/VersionManager.php:177
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
|
msgid "File checksum does not match. Expected: %1$s, Got: %2$s"
|
||||||
@@ -1180,11 +1258,11 @@ msgstr ""
|
|||||||
msgid "Please log in to view your licenses."
|
msgid "Please log in to view your licenses."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:164
|
#: src/Frontend/AccountController.php:165
|
||||||
msgid "You have no licenses yet."
|
msgid "You have no licenses yet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:189
|
#: src/Frontend/AccountController.php:190
|
||||||
#: src/Email/LicenseEmailController.php:173
|
#: src/Email/LicenseEmailController.php:173
|
||||||
#: src/Email/LicenseEmailController.php:177
|
#: src/Email/LicenseEmailController.php:177
|
||||||
#: src/Email/LicenseEmailController.php:281
|
#: src/Email/LicenseEmailController.php:281
|
||||||
@@ -1193,106 +1271,106 @@ msgstr ""
|
|||||||
msgid "License Key:"
|
msgid "License Key:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:200
|
#: src/Frontend/AccountController.php:201
|
||||||
#: src/Email/LicenseExpirationEmail.php:215
|
#: src/Email/LicenseExpirationEmail.php:215
|
||||||
#: src/Email/LicenseExpirationEmail.php:271
|
#: src/Email/LicenseExpirationEmail.php:271
|
||||||
msgid "Domain:"
|
msgid "Domain:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:206
|
#: src/Frontend/AccountController.php:207
|
||||||
msgid "Transfer to new domain"
|
msgid "Transfer to new domain"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:208
|
#: src/Frontend/AccountController.php:209
|
||||||
msgid "Transfer"
|
msgid "Transfer"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:212
|
#: src/Frontend/AccountController.php:213
|
||||||
#: src/Email/LicenseEmailController.php:284
|
#: src/Email/LicenseEmailController.php:284
|
||||||
#: src/Email/LicenseExpirationEmail.php:219
|
#: src/Email/LicenseExpirationEmail.php:219
|
||||||
#: src/Email/LicenseExpirationEmail.php:272
|
#: src/Email/LicenseExpirationEmail.php:272
|
||||||
msgid "Expires:"
|
msgid "Expires:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:217
|
#: src/Frontend/AccountController.php:218
|
||||||
#: src/Email/LicenseEmailController.php:248
|
#: src/Email/LicenseEmailController.php:248
|
||||||
#: src/Email/LicenseEmailController.php:287
|
#: src/Email/LicenseEmailController.php:287
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:225
|
#: src/Frontend/AccountController.php:226
|
||||||
msgid "Available Downloads"
|
msgid "Available Downloads"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:231
|
#: src/Frontend/AccountController.php:232
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Version %s"
|
msgid "Version %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:248
|
#: src/Frontend/AccountController.php:249
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:249
|
#: src/Frontend/AccountController.php:250
|
||||||
msgid "Transfer License to New Domain"
|
msgid "Transfer License to New Domain"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:254
|
#: src/Frontend/AccountController.php:255
|
||||||
msgid "Current Domain"
|
msgid "Current Domain"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:259
|
#: src/Frontend/AccountController.php:260
|
||||||
msgid "New Domain"
|
msgid "New Domain"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:263
|
#: src/Frontend/AccountController.php:264
|
||||||
msgid "Enter the new domain without http:// or www."
|
msgid "Enter the new domain without http:// or www."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:268
|
#: src/Frontend/AccountController.php:269
|
||||||
msgid "Transfer License"
|
msgid "Transfer License"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:310
|
#: src/Frontend/AccountController.php:311
|
||||||
#: src/Frontend/AccountController.php:377
|
#: src/Frontend/AccountController.php:378
|
||||||
msgid "License transferred successfully!"
|
msgid "License transferred successfully!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:311
|
#: src/Frontend/AccountController.php:312
|
||||||
msgid "Transfer failed. Please try again."
|
msgid "Transfer failed. Please try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:312
|
#: src/Frontend/AccountController.php:313
|
||||||
msgid ""
|
msgid ""
|
||||||
"Are you sure you want to transfer this license to a new domain? This action "
|
"Are you sure you want to transfer this license to a new domain? This action "
|
||||||
"cannot be undone."
|
"cannot be undone."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:331
|
#: src/Frontend/AccountController.php:332
|
||||||
msgid "Please log in to transfer a license."
|
msgid "Please log in to transfer a license."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:337
|
#: src/Frontend/AccountController.php:338
|
||||||
msgid "Invalid license."
|
msgid "Invalid license."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:355
|
#: src/Frontend/AccountController.php:356
|
||||||
msgid "You do not have permission to transfer this license."
|
msgid "You do not have permission to transfer this license."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:360
|
#: src/Frontend/AccountController.php:361
|
||||||
msgid "Revoked licenses cannot be transferred."
|
msgid "Revoked licenses cannot be transferred."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:364
|
#: src/Frontend/AccountController.php:365
|
||||||
msgid "Expired licenses cannot be transferred."
|
msgid "Expired licenses cannot be transferred."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:369
|
#: src/Frontend/AccountController.php:370
|
||||||
msgid "The new domain is the same as the current domain."
|
msgid "The new domain is the same as the current domain."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Frontend/AccountController.php:381
|
#: src/Frontend/AccountController.php:382
|
||||||
msgid "Failed to transfer license. Please try again."
|
msgid "Failed to transfer license. Please try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1373,7 +1451,6 @@ msgid ""
|
|||||||
"expiration date."
|
"expiration date."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: list of placeholders
|
|
||||||
#: src/Email/LicenseExpirationEmail.php:301
|
#: src/Email/LicenseExpirationEmail.php:301
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Available placeholders: %s"
|
msgid "Available placeholders: %s"
|
||||||
@@ -1411,7 +1488,19 @@ msgstr ""
|
|||||||
msgid "Choose which format of email to send."
|
msgid "Choose which format of email to send."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: WooCommerce plugin name
|
#: 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
|
#: wc-licensed-product.php:61
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%s requires WooCommerce to be installed and active."
|
msgid "%s requires WooCommerce to be installed and active."
|
||||||
|
|||||||
48
openapi.json
48
openapi.json
@@ -2,8 +2,8 @@
|
|||||||
"openapi": "3.1.0",
|
"openapi": "3.1.0",
|
||||||
"info": {
|
"info": {
|
||||||
"title": "WooCommerce Licensed Product API",
|
"title": "WooCommerce Licensed Product API",
|
||||||
"description": "REST API for validating and managing software licenses bound to domains. This API allows external applications to validate license keys, check license status, and activate licenses on specific domains.",
|
"description": "REST API for validating and managing software licenses bound to domains. This API allows external applications to validate license keys, check license status, and activate licenses on specific domains.\n\n## Response Signing (Optional)\n\nWhen the server is configured with `WC_LICENSE_SERVER_SECRET`, all API responses include cryptographic signatures for tamper protection:\n\n- `X-License-Signature`: HMAC-SHA256 signature of the response\n- `X-License-Timestamp`: Unix timestamp when the response was generated\n\nSignature verification prevents man-in-the-middle attacks and ensures response integrity. Use the `magdev/wc-licensed-product-client` library's `SecureLicenseClient` class to automatically verify signatures.",
|
||||||
"version": "0.0.7",
|
"version": "0.3.2",
|
||||||
"contact": {
|
"contact": {
|
||||||
"name": "Marco Graetsch",
|
"name": "Marco Graetsch",
|
||||||
"url": "https://src.bundespruefstelle.ch/magdev",
|
"url": "https://src.bundespruefstelle.ch/magdev",
|
||||||
@@ -55,6 +55,14 @@
|
|||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "License is valid for the specified domain",
|
"description": "License is valid for the specified domain",
|
||||||
|
"headers": {
|
||||||
|
"X-License-Signature": {
|
||||||
|
"$ref": "#/components/headers/X-License-Signature"
|
||||||
|
},
|
||||||
|
"X-License-Timestamp": {
|
||||||
|
"$ref": "#/components/headers/X-License-Timestamp"
|
||||||
|
}
|
||||||
|
},
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -156,6 +164,14 @@
|
|||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "License status retrieved successfully",
|
"description": "License status retrieved successfully",
|
||||||
|
"headers": {
|
||||||
|
"X-License-Signature": {
|
||||||
|
"$ref": "#/components/headers/X-License-Signature"
|
||||||
|
},
|
||||||
|
"X-License-Timestamp": {
|
||||||
|
"$ref": "#/components/headers/X-License-Timestamp"
|
||||||
|
}
|
||||||
|
},
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -221,6 +237,14 @@
|
|||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "License activated successfully or already activated",
|
"description": "License activated successfully or already activated",
|
||||||
|
"headers": {
|
||||||
|
"X-License-Signature": {
|
||||||
|
"$ref": "#/components/headers/X-License-Signature"
|
||||||
|
},
|
||||||
|
"X-License-Timestamp": {
|
||||||
|
"$ref": "#/components/headers/X-License-Timestamp"
|
||||||
|
}
|
||||||
|
},
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
@@ -519,6 +543,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"headers": {
|
||||||
|
"X-License-Signature": {
|
||||||
|
"description": "HMAC-SHA256 signature of the response body for tamper protection. Only present when server is configured with WC_LICENSE_SERVER_SECRET. Signature format: hex-encoded HMAC-SHA256 of (timestamp + ':' + canonical_json_body) using a per-license derived key.",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[a-f0-9]{64}$",
|
||||||
|
"example": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"
|
||||||
|
},
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
"X-License-Timestamp": {
|
||||||
|
"description": "Unix timestamp when the response was generated. Used together with X-License-Signature to prevent replay attacks. Only present when server is configured with WC_LICENSE_SERVER_SECRET.",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[0-9]+$",
|
||||||
|
"example": "1737550000"
|
||||||
|
},
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|||||||
BIN
releases/wc-licensed-product-0.2.1.zip
Normal file
BIN
releases/wc-licensed-product-0.2.1.zip
Normal file
Binary file not shown.
1
releases/wc-licensed-product-0.2.1.zip.sha256
Normal file
1
releases/wc-licensed-product-0.2.1.zip.sha256
Normal file
@@ -0,0 +1 @@
|
|||||||
|
7b895090538f9063fac1509b6f7a40a2b71dc9958b3a255cbfcc60d0320ae5e5 releases/wc-licensed-product-0.2.1.zip
|
||||||
@@ -9,6 +9,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Jeremias\WcLicensedProduct\Admin;
|
namespace Jeremias\WcLicensedProduct\Admin;
|
||||||
|
|
||||||
|
use Jeremias\WcLicensedProduct\License\PluginLicenseChecker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles WooCommerce settings tab for license defaults
|
* Handles WooCommerce settings tab for license defaults
|
||||||
*/
|
*/
|
||||||
@@ -19,6 +21,11 @@ final class SettingsController
|
|||||||
*/
|
*/
|
||||||
public const OPTION_NAME = 'wc_licensed_product_settings';
|
public const OPTION_NAME = 'wc_licensed_product_settings';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tab ID
|
||||||
|
*/
|
||||||
|
private const TAB_ID = 'licensed_product';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
@@ -33,8 +40,10 @@ final class SettingsController
|
|||||||
private function registerHooks(): void
|
private function registerHooks(): void
|
||||||
{
|
{
|
||||||
add_filter('woocommerce_settings_tabs_array', [$this, 'addSettingsTab'], 50);
|
add_filter('woocommerce_settings_tabs_array', [$this, 'addSettingsTab'], 50);
|
||||||
add_action('woocommerce_settings_tabs_licensed_product', [$this, 'renderSettingsTab']);
|
add_action('woocommerce_sections_' . self::TAB_ID, [$this, 'outputSections']);
|
||||||
add_action('woocommerce_update_options_licensed_product', [$this, 'saveSettings']);
|
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
|
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;
|
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 '<ul class="subsubsub">';
|
||||||
|
|
||||||
|
$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 '<li><a href="' . esc_url($url) . '" class="' . esc_attr($class) . '">' . esc_html($label) . '</a>' . $separator . '</li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</ul><br class="clear" />';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get settings fields for the current section
|
||||||
*/
|
*/
|
||||||
public function getSettingsFields(): array
|
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 [
|
return [
|
||||||
'section_title' => [
|
'section_title' => [
|
||||||
@@ -92,7 +206,15 @@ final class SettingsController
|
|||||||
'type' => 'sectionend',
|
'type' => 'sectionend',
|
||||||
'id' => 'wc_licensed_product_section_defaults_end',
|
'id' => 'wc_licensed_product_section_defaults_end',
|
||||||
],
|
],
|
||||||
// Email settings section
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notifications settings
|
||||||
|
*/
|
||||||
|
private function getNotificationsSettings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
'email_section_title' => [
|
'email_section_title' => [
|
||||||
'name' => __('Expiration Warning Schedule', 'wc-licensed-product'),
|
'name' => __('Expiration Warning Schedule', 'wc-licensed-product'),
|
||||||
'type' => 'title',
|
'type' => 'title',
|
||||||
@@ -138,9 +260,96 @@ final class SettingsController
|
|||||||
*/
|
*/
|
||||||
public function renderSettingsTab(): void
|
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());
|
woocommerce_admin_fields($this->getSettingsFields());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render license status notice
|
||||||
|
*/
|
||||||
|
private function renderLicenseStatus(): void
|
||||||
|
{
|
||||||
|
$checker = PluginLicenseChecker::getInstance();
|
||||||
|
|
||||||
|
if ($checker->isLocalhost()) {
|
||||||
|
echo '<div class="notice notice-info inline"><p>';
|
||||||
|
echo '<span class="dashicons dashicons-info" style="color: #00a0d2;"></span> ';
|
||||||
|
echo esc_html__('Running on localhost - license validation bypassed.', 'wc-licensed-product');
|
||||||
|
echo '</p></div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($checker->isLicenseValid()) {
|
||||||
|
echo '<div class="notice notice-success inline"><p>';
|
||||||
|
echo '<span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span> ';
|
||||||
|
echo esc_html__('License is valid and active.', 'wc-licensed-product');
|
||||||
|
echo '</p></div>';
|
||||||
|
} else {
|
||||||
|
$error = $checker->getLastError();
|
||||||
|
echo '<div class="notice notice-error inline"><p>';
|
||||||
|
echo '<span class="dashicons dashicons-warning" style="color: #dc3232;"></span> ';
|
||||||
|
echo esc_html__('License is not valid. Frontend features are disabled.', 'wc-licensed-product');
|
||||||
|
if ($error) {
|
||||||
|
echo '<br><small>' . esc_html($error) . '</small>';
|
||||||
|
}
|
||||||
|
echo '</p></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add verify button
|
||||||
|
$nonce = wp_create_nonce('wclp_verify_license');
|
||||||
|
echo '<p>';
|
||||||
|
echo '<button type="button" class="button" id="wclp-verify-license" data-nonce="' . esc_attr($nonce) . '">';
|
||||||
|
echo esc_html__('Verify License', 'wc-licensed-product');
|
||||||
|
echo '</button>';
|
||||||
|
echo '<span id="wclp-verify-result" style="margin-left: 10px;"></span>';
|
||||||
|
echo '</p>';
|
||||||
|
|
||||||
|
// Inline script for verify button
|
||||||
|
?>
|
||||||
|
<script type="text/javascript">
|
||||||
|
jQuery(function($) {
|
||||||
|
$('#wclp-verify-license').on('click', function() {
|
||||||
|
var $btn = $(this);
|
||||||
|
var $result = $('#wclp-verify-result');
|
||||||
|
var nonce = $btn.data('nonce');
|
||||||
|
|
||||||
|
$btn.prop('disabled', true).text('<?php echo esc_js(__('Verifying...', 'wc-licensed-product')); ?>');
|
||||||
|
$result.text('');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: ajaxurl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'wclp_verify_plugin_license',
|
||||||
|
nonce: nonce
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
$result.html('<span style="color: #46b450;">' + response.data.message + '</span>');
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
$result.html('<span style="color: #dc3232;">' + response.data.message + '</span>');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
$result.html('<span style="color: #dc3232;"><?php echo esc_js(__('Request failed.', 'wc-licensed-product')); ?></span>');
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
$btn.prop('disabled', false).text('<?php echo esc_js(__('Verify License', 'wc-licensed-product')); ?>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save settings
|
* Save settings
|
||||||
*/
|
*/
|
||||||
@@ -210,4 +419,55 @@ final class SettingsController
|
|||||||
$value = get_option('wc_licensed_product_expiration_warning_days_second', 1);
|
$value = get_option('wc_licensed_product_expiration_warning_days_second', 1);
|
||||||
return max(0, (int) $value);
|
return max(0, (int) $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get plugin license server URL
|
||||||
|
*/
|
||||||
|
public static function getPluginLicenseServerUrl(): string
|
||||||
|
{
|
||||||
|
return (string) get_option('wc_licensed_product_plugin_license_server_url', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get plugin license key
|
||||||
|
*/
|
||||||
|
public static function getPluginLicenseKey(): string
|
||||||
|
{
|
||||||
|
return (string) get_option('wc_licensed_product_plugin_license_key', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get plugin license server secret
|
||||||
|
*/
|
||||||
|
public static function getPluginLicenseServerSecret(): ?string
|
||||||
|
{
|
||||||
|
$secret = get_option('wc_licensed_product_plugin_license_server_secret', '');
|
||||||
|
return !empty($secret) ? (string) $secret : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle AJAX verify license request
|
||||||
|
*/
|
||||||
|
public function handleVerifyLicense(): void
|
||||||
|
{
|
||||||
|
if (!check_ajax_referer('wclp_verify_license', 'nonce', false)) {
|
||||||
|
wp_send_json_error(['message' => __('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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,14 @@ final class VersionAdminController
|
|||||||
<tr id="sha256-hash-row" style="display: none;">
|
<tr id="sha256-hash-row" style="display: none;">
|
||||||
<th><label for="new_checksum_file"><?php esc_html_e('Checksum File', 'wc-licensed-product'); ?></label></th>
|
<th><label for="new_checksum_file"><?php esc_html_e('Checksum File', 'wc-licensed-product'); ?></label></th>
|
||||||
<td>
|
<td>
|
||||||
<input type="file" id="new_checksum_file" name="new_checksum_file" accept=".sha256,.txt" />
|
<input type="file" id="new_checksum_file" name="new_checksum_file" accept=".sha256,.txt" style="display: none;" />
|
||||||
|
<span id="selected_checksum_name" class="selected-file-name"></span>
|
||||||
|
<button type="button" class="button" id="select-checksum-file-btn">
|
||||||
|
<?php esc_html_e('Select Checksum File', 'wc-licensed-product'); ?>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="button" id="remove-checksum-file-btn" style="display: none;">
|
||||||
|
<?php esc_html_e('Remove', 'wc-licensed-product'); ?>
|
||||||
|
</button>
|
||||||
<p class="description"><?php esc_html_e('Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity.', 'wc-licensed-product'); ?></p>
|
<p class="description"><?php esc_html_e('Upload a SHA256 checksum file (.sha256 or .txt) to verify file integrity.', 'wc-licensed-product'); ?></p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -128,6 +135,7 @@ final class VersionAdminController
|
|||||||
<tr>
|
<tr>
|
||||||
<th><?php esc_html_e('Version', 'wc-licensed-product'); ?></th>
|
<th><?php esc_html_e('Version', 'wc-licensed-product'); ?></th>
|
||||||
<th><?php esc_html_e('Download File', 'wc-licensed-product'); ?></th>
|
<th><?php esc_html_e('Download File', 'wc-licensed-product'); ?></th>
|
||||||
|
<th><?php esc_html_e('SHA256', 'wc-licensed-product'); ?></th>
|
||||||
<th><?php esc_html_e('Release Notes', 'wc-licensed-product'); ?></th>
|
<th><?php esc_html_e('Release Notes', 'wc-licensed-product'); ?></th>
|
||||||
<th><?php esc_html_e('Status', 'wc-licensed-product'); ?></th>
|
<th><?php esc_html_e('Status', 'wc-licensed-product'); ?></th>
|
||||||
<th><?php esc_html_e('Released', 'wc-licensed-product'); ?></th>
|
<th><?php esc_html_e('Released', 'wc-licensed-product'); ?></th>
|
||||||
@@ -137,7 +145,7 @@ final class VersionAdminController
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php if (empty($versions)): ?>
|
<?php if (empty($versions)): ?>
|
||||||
<tr class="no-versions">
|
<tr class="no-versions">
|
||||||
<td colspan="6"><?php esc_html_e('No versions found. Add your first version above.', 'wc-licensed-product'); ?></td>
|
<td colspan="7"><?php esc_html_e('No versions found. Add your first version above.', 'wc-licensed-product'); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($versions as $version): ?>
|
<?php foreach ($versions as $version): ?>
|
||||||
@@ -149,16 +157,25 @@ final class VersionAdminController
|
|||||||
$filename = $version->getDownloadFilename();
|
$filename = $version->getDownloadFilename();
|
||||||
if ($effectiveUrl):
|
if ($effectiveUrl):
|
||||||
?>
|
?>
|
||||||
|
<span class="version-download-link">
|
||||||
<a href="<?php echo esc_url($effectiveUrl); ?>" target="_blank">
|
<a href="<?php echo esc_url($effectiveUrl); ?>" target="_blank">
|
||||||
<?php echo esc_html($filename ?: wp_basename($effectiveUrl)); ?>
|
<?php echo esc_html($filename ?: wp_basename($effectiveUrl)); ?>
|
||||||
</a>
|
</a>
|
||||||
<?php if ($version->getAttachmentId()): ?>
|
<?php if ($version->getAttachmentId()): ?>
|
||||||
<span class="dashicons dashicons-media-archive" title="<?php esc_attr_e('Uploaded file', 'wc-licensed-product'); ?>"></span>
|
<span class="dashicons dashicons-media-archive" title="<?php esc_attr_e('Uploaded file', 'wc-licensed-product'); ?>"></span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
</span>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<em><?php esc_html_e('No download file', 'wc-licensed-product'); ?></em>
|
<em><?php esc_html_e('No download file', 'wc-licensed-product'); ?></em>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<?php if ($version->getFileHash()): ?>
|
||||||
|
<code class="file-hash" title="<?php echo esc_attr($version->getFileHash()); ?>"><?php echo esc_html(substr($version->getFileHash(), 0, 12)); ?>...</code>
|
||||||
|
<?php else: ?>
|
||||||
|
<em>—</em>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
<td><?php echo esc_html($version->getReleaseNotes() ? wp_trim_words($version->getReleaseNotes(), 10) : '—'); ?></td>
|
<td><?php echo esc_html($version->getReleaseNotes() ? wp_trim_words($version->getReleaseNotes(), 10) : '—'); ?></td>
|
||||||
<td>
|
<td>
|
||||||
<span class="version-status version-status-<?php echo $version->isActive() ? 'active' : 'inactive'; ?>">
|
<span class="version-status version-status-<?php echo $version->isActive() ? 'active' : 'inactive'; ?>">
|
||||||
@@ -371,16 +388,25 @@ final class VersionAdminController
|
|||||||
$filename = $version->getDownloadFilename();
|
$filename = $version->getDownloadFilename();
|
||||||
if ($effectiveUrl):
|
if ($effectiveUrl):
|
||||||
?>
|
?>
|
||||||
|
<span class="version-download-link">
|
||||||
<a href="<?php echo esc_url($effectiveUrl); ?>" target="_blank">
|
<a href="<?php echo esc_url($effectiveUrl); ?>" target="_blank">
|
||||||
<?php echo esc_html($filename ?: wp_basename($effectiveUrl)); ?>
|
<?php echo esc_html($filename ?: wp_basename($effectiveUrl)); ?>
|
||||||
</a>
|
</a>
|
||||||
<?php if ($version->getAttachmentId()): ?>
|
<?php if ($version->getAttachmentId()): ?>
|
||||||
<span class="dashicons dashicons-media-archive" title="<?php esc_attr_e('Uploaded file', 'wc-licensed-product'); ?>"></span>
|
<span class="dashicons dashicons-media-archive" title="<?php esc_attr_e('Uploaded file', 'wc-licensed-product'); ?>"></span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
</span>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<em><?php esc_html_e('No download file', 'wc-licensed-product'); ?></em>
|
<em><?php esc_html_e('No download file', 'wc-licensed-product'); ?></em>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<?php if ($version->getFileHash()): ?>
|
||||||
|
<code class="file-hash" title="<?php echo esc_attr($version->getFileHash()); ?>"><?php echo esc_html(substr($version->getFileHash(), 0, 12)); ?>...</code>
|
||||||
|
<?php else: ?>
|
||||||
|
<em>—</em>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
<td><?php echo esc_html($version->getReleaseNotes() ? wp_trim_words($version->getReleaseNotes(), 10) : '—'); ?></td>
|
<td><?php echo esc_html($version->getReleaseNotes() ? wp_trim_words($version->getReleaseNotes(), 10) : '—'); ?></td>
|
||||||
<td>
|
<td>
|
||||||
<span class="version-status version-status-<?php echo $version->isActive() ? 'active' : 'inactive'; ?>">
|
<span class="version-status version-status-<?php echo $version->isActive() ? 'active' : 'inactive'; ?>">
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ final class AccountController
|
|||||||
),
|
),
|
||||||
'release_notes' => $version->getReleaseNotes(),
|
'release_notes' => $version->getReleaseNotes(),
|
||||||
'released_at' => $version->getReleasedAt()->format(get_option('date_format')),
|
'released_at' => $version->getReleasedAt()->format(get_option('date_format')),
|
||||||
|
'file_hash' => $version->getFileHash(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
287
src/License/PluginLicenseChecker.php
Normal file
287
src/License/PluginLicenseChecker.php
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Plugin License Checker
|
||||||
|
*
|
||||||
|
* Validates the plugin's own license against a remote server.
|
||||||
|
*
|
||||||
|
* @package Jeremias\WcLicensedProduct\License
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Jeremias\WcLicensedProduct\License;
|
||||||
|
|
||||||
|
use Magdev\WcLicensedProductClient\LicenseClient;
|
||||||
|
use Magdev\WcLicensedProductClient\LicenseClientInterface;
|
||||||
|
use Magdev\WcLicensedProductClient\SecureLicenseClient;
|
||||||
|
use Magdev\WcLicensedProductClient\Exception\LicenseException;
|
||||||
|
use Symfony\Component\HttpClient\HttpClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles validation of this plugin's license
|
||||||
|
*/
|
||||||
|
final class PluginLicenseChecker
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Cache key for license validation result
|
||||||
|
*/
|
||||||
|
private const CACHE_KEY = 'wclp_plugin_license_valid';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache TTL for successful validation (1 hour)
|
||||||
|
*/
|
||||||
|
private const CACHE_TTL = 3600;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache key for error messages
|
||||||
|
*/
|
||||||
|
private const ERROR_CACHE_KEY = 'wclp_plugin_license_error';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache TTL for errors (5 minutes)
|
||||||
|
*/
|
||||||
|
private const ERROR_CACHE_TTL = 300;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton instance
|
||||||
|
*/
|
||||||
|
private static ?self $instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached localhost check result
|
||||||
|
*/
|
||||||
|
private ?bool $isLocalhostCached = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get singleton instance
|
||||||
|
*/
|
||||||
|
public static function getInstance(): self
|
||||||
|
{
|
||||||
|
if (self::$instance === null) {
|
||||||
|
self::$instance = new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor for singleton
|
||||||
|
*/
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
|
// Private constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the plugin license is valid
|
||||||
|
*
|
||||||
|
* Returns cached result if available, otherwise validates against server.
|
||||||
|
*/
|
||||||
|
public function isLicenseValid(): bool
|
||||||
|
{
|
||||||
|
// Always valid on localhost
|
||||||
|
if ($this->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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ use Jeremias\WcLicensedProduct\Email\LicenseEmailController;
|
|||||||
use Jeremias\WcLicensedProduct\Frontend\AccountController;
|
use Jeremias\WcLicensedProduct\Frontend\AccountController;
|
||||||
use Jeremias\WcLicensedProduct\Frontend\DownloadController;
|
use Jeremias\WcLicensedProduct\Frontend\DownloadController;
|
||||||
use Jeremias\WcLicensedProduct\License\LicenseManager;
|
use Jeremias\WcLicensedProduct\License\LicenseManager;
|
||||||
|
use Jeremias\WcLicensedProduct\License\PluginLicenseChecker;
|
||||||
use Jeremias\WcLicensedProduct\Product\LicensedProductType;
|
use Jeremias\WcLicensedProduct\Product\LicensedProductType;
|
||||||
use Jeremias\WcLicensedProduct\Product\VersionManager;
|
use Jeremias\WcLicensedProduct\Product\VersionManager;
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
@@ -119,13 +120,23 @@ final class Plugin
|
|||||||
$this->licenseManager = new LicenseManager();
|
$this->licenseManager = new LicenseManager();
|
||||||
$this->versionManager = new VersionManager();
|
$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 LicensedProductType();
|
||||||
|
|
||||||
|
// Only initialize frontend components if licensed or on localhost
|
||||||
|
if ($isLicensed) {
|
||||||
new CheckoutController($this->licenseManager);
|
new CheckoutController($this->licenseManager);
|
||||||
new StoreApiExtension($this->licenseManager);
|
new StoreApiExtension($this->licenseManager);
|
||||||
$this->registerCheckoutBlocksIntegration();
|
$this->registerCheckoutBlocksIntegration();
|
||||||
$this->downloadController = new DownloadController($this->licenseManager, $this->versionManager);
|
$this->downloadController = new DownloadController($this->licenseManager, $this->versionManager);
|
||||||
new AccountController($this->twig, $this->licenseManager, $this->versionManager, $this->downloadController);
|
new AccountController($this->twig, $this->licenseManager, $this->versionManager, $this->downloadController);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always initialize REST API and email controller
|
||||||
new RestApiController($this->licenseManager);
|
new RestApiController($this->licenseManager);
|
||||||
new LicenseEmailController($this->licenseManager);
|
new LicenseEmailController($this->licenseManager);
|
||||||
|
|
||||||
@@ -134,11 +145,17 @@ final class Plugin
|
|||||||
(new ResponseSigner())->register();
|
(new ResponseSigner())->register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Admin always available
|
||||||
if (is_admin()) {
|
if (is_admin()) {
|
||||||
new AdminController($this->twig, $this->licenseManager);
|
new AdminController($this->twig, $this->licenseManager);
|
||||||
new VersionAdminController($this->versionManager);
|
new VersionAdminController($this->versionManager);
|
||||||
new OrderLicenseController($this->licenseManager);
|
new OrderLicenseController($this->licenseManager);
|
||||||
new SettingsController();
|
new SettingsController();
|
||||||
|
|
||||||
|
// Show admin notice if unlicensed and not on localhost
|
||||||
|
if (!$isLicensed && !$licenseChecker->isLocalhost()) {
|
||||||
|
add_action('admin_notices', [$this, 'showUnlicensedNotice']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +181,9 @@ final class Plugin
|
|||||||
*/
|
*/
|
||||||
private function registerHooks(): void
|
private function registerHooks(): void
|
||||||
{
|
{
|
||||||
|
// 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)
|
// Generate license on order completion (multiple hooks for compatibility)
|
||||||
add_action('woocommerce_order_status_completed', [$this, 'onOrderCompleted']);
|
add_action('woocommerce_order_status_completed', [$this, 'onOrderCompleted']);
|
||||||
add_action('woocommerce_order_status_processing', [$this, 'onOrderCompleted']);
|
add_action('woocommerce_order_status_processing', [$this, 'onOrderCompleted']);
|
||||||
@@ -171,6 +191,7 @@ final class Plugin
|
|||||||
// Also hook into payment complete for immediate license generation
|
// Also hook into payment complete for immediate license generation
|
||||||
add_action('woocommerce_payment_complete', [$this, 'onOrderCompleted']);
|
add_action('woocommerce_payment_complete', [$this, 'onOrderCompleted']);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle order completion - generate licenses
|
* Handle order completion - generate licenses
|
||||||
@@ -221,4 +242,29 @@ final class Plugin
|
|||||||
{
|
{
|
||||||
return $this->twig->render($template, $context);
|
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');
|
||||||
|
?>
|
||||||
|
<div class="notice notice-warning is-dismissible">
|
||||||
|
<p>
|
||||||
|
<strong><?php esc_html_e('WC Licensed Product', 'wc-licensed-product'); ?>:</strong>
|
||||||
|
<?php esc_html_e('Plugin license is not configured or invalid. Frontend features are disabled.', 'wc-licensed-product'); ?>
|
||||||
|
<a href="<?php echo esc_url($settingsUrl); ?>"><?php esc_html_e('Configure License', 'wc-licensed-product'); ?></a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin license checker instance
|
||||||
|
*/
|
||||||
|
public function getLicenseChecker(): PluginLicenseChecker
|
||||||
|
{
|
||||||
|
return PluginLicenseChecker::getInstance();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,12 @@
|
|||||||
</a>
|
</a>
|
||||||
<span class="download-version">v{{ esc_html(download.version) }}</span>
|
<span class="download-version">v{{ esc_html(download.version) }}</span>
|
||||||
<span class="download-date">{{ esc_html(download.released_at) }}</span>
|
<span class="download-date">{{ esc_html(download.released_at) }}</span>
|
||||||
|
{% if download.file_hash %}
|
||||||
|
<span class="download-hash" title="{{ esc_attr(download.file_hash) }}">
|
||||||
|
<span class="dashicons dashicons-shield"></span>
|
||||||
|
<code>{{ download.file_hash[:12] }}...</code>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Plugin Name: WooCommerce Licensed Product
|
* Plugin Name: WooCommerce Licensed Product
|
||||||
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-licensed-product
|
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-licensed-product
|
||||||
* Description: WooCommerce plugin to sell software products using license keys with domain-based validation.
|
* Description: WooCommerce plugin to sell software products using license keys with domain-based validation.
|
||||||
* Version: 0.2.1
|
* Version: 0.3.2
|
||||||
* Author: Marco Graetsch
|
* Author: Marco Graetsch
|
||||||
* Author URI: https://src.bundespruefstelle.ch/magdev
|
* Author URI: https://src.bundespruefstelle.ch/magdev
|
||||||
* License: GPL-2.0-or-later
|
* License: GPL-2.0-or-later
|
||||||
@@ -28,7 +28,7 @@ if (!defined('ABSPATH')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Plugin constants
|
// Plugin constants
|
||||||
define('WC_LICENSED_PRODUCT_VERSION', '0.2.1');
|
define('WC_LICENSED_PRODUCT_VERSION', '0.3.2');
|
||||||
define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__);
|
define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__);
|
||||||
define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||||
define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));
|
define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||||
|
|||||||
Reference in New Issue
Block a user