Implement version 0.0.1 - Licensed Product type for WooCommerce

Add complete plugin infrastructure for selling software with license keys:

- New "Licensed Product" WooCommerce product type
- License key generation (XXXX-XXXX-XXXX-XXXX format) on order completion
- Domain-based license validation system
- REST API endpoints (validate, status, activate, deactivate)
- Customer My Account "Licenses" page
- Admin license management under WooCommerce > Licenses
- Checkout domain field for licensed products
- Custom database tables for licenses and product versions
- Twig template engine integration
- Full i18n support with German (de_CH) translation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-21 18:55:18 +01:00
parent 8a4802248c
commit 404083f023
22 changed files with 3746 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
<div class="wrap">
<h1>{{ __('Licenses') }}</h1>
{% for notice in notices %}
<div class="notice notice-{{ notice.type }} is-dismissible">
<p>{{ esc_html(notice.message) }}</p>
</div>
{% endfor %}
<p class="description">
{{ __('Total licenses:') }} <strong>{{ total_licenses }}</strong>
</p>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>{{ __('License Key') }}</th>
<th>{{ __('Product') }}</th>
<th>{{ __('Customer') }}</th>
<th>{{ __('Domain') }}</th>
<th>{{ __('Status') }}</th>
<th>{{ __('Expires') }}</th>
<th>{{ __('Actions') }}</th>
</tr>
</thead>
<tbody>
{% if licenses is empty %}
<tr>
<td colspan="7">{{ __('No licenses found.') }}</td>
</tr>
{% else %}
{% for item in licenses %}
<tr>
<td><code>{{ item.license.licenseKey }}</code></td>
<td>
{% if item.product_edit_url %}
<a href="{{ esc_url(item.product_edit_url) }}">{{ esc_html(item.product_name) }}</a>
{% else %}
{{ esc_html(item.product_name) }}
{% endif %}
</td>
<td>
{{ esc_html(item.customer_name) }}
{% if item.customer_email %}
<br><small>{{ esc_html(item.customer_email) }}</small>
{% endif %}
</td>
<td>{{ esc_html(item.license.domain) }}</td>
<td>
<span class="license-status license-status-{{ item.license.status }}">
{{ item.license.status|capitalize }}
</span>
</td>
<td>
{% if item.license.expiresAt %}
{{ item.license.expiresAt|date('Y-m-d') }}
{% else %}
{{ __('Never') }}
{% endif %}
</td>
<td>
{% if item.license.status != 'revoked' %}
<a href="{{ admin_url ~ '?page=wc-licenses&action=revoke&license_id=' ~ item.license.id ~ '&_wpnonce=' }}"
class="button button-small"
onclick="return confirm('{{ __('Are you sure?') }}')">
{{ __('Revoke') }}
</a>
{% endif %}
<a href="{{ admin_url ~ '?page=wc-licenses&action=delete&license_id=' ~ item.license.id ~ '&_wpnonce=' }}"
class="button button-small button-link-delete"
onclick="return confirm('{{ __('Are you sure you want to delete this license?') }}')">
{{ __('Delete') }}
</a>
</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
{% if total_pages > 1 %}
<div class="tablenav bottom">
<div class="tablenav-pages">
<span class="pagination-links">
{% if current_page > 1 %}
<a class="prev-page button" href="{{ admin_url ~ '&paged=' ~ (current_page - 1) }}">
<span aria-hidden="true"></span>
</a>
{% endif %}
<span class="paging-input">
{{ current_page }} {{ __('of') }} {{ total_pages }}
</span>
{% if current_page < total_pages %}
<a class="next-page button" href="{{ admin_url ~ '&paged=' ~ (current_page + 1) }}">
<span aria-hidden="true"></span>
</a>
{% endif %}
</span>
</div>
</div>
{% endif %}
</div>