feat: belegte domains als liste mit papierkorb + status-live-refresh

- Bei voller Lizenz werden alle belegten Domains untereinander gelistet, je
  mit Papierkorb-Button + Bestaetigungsdialog (statt Dropdown).
- Trash gibt die Domain frei (deaktiviert serverseitig) und aktiviert diese Seite.
- Lizenz-Tab re-validiert den Status live (max alle 5 Min), damit eine an anderer
  Stelle freigegebene Domain hier sofort als ungueltig erscheint statt stale aktiv.
- EN-Uebersetzung (122) aktualisiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
s4luorth
2026-06-07 15:27:34 +02:00
parent 4f0f8ea170
commit a0972b4bbf
5 changed files with 69 additions and 31 deletions

View File

@@ -324,6 +324,16 @@ class CB_License {
public static function render_tab(): void { public static function render_tab(): void {
$lic = self::get_license(); $lic = self::get_license();
// Keep the shown status honest: if this site was deactivated elsewhere
// (e.g. another site freed this slot), re-validate live when the tab is
// opened — throttled to at most once every 5 minutes.
if ( in_array( $lic['status'], [ 'active', 'invalid' ], true )
&& ( time() - (int) $lic['last_check'] ) > 5 * MINUTE_IN_SECONDS ) {
self::cron_check();
$lic = self::get_license();
}
$status = $lic['status']; $status = $lic['status'];
$badge = match ( $status ) { $badge = match ( $status ) {
@@ -349,27 +359,32 @@ class CB_License {
</tbody></table> </tbody></table>
<?php if ( $status === 'limit' && ! empty( $lic['pending_domains'] ) ) : ?> <?php if ( $status === 'limit' && ! empty( $lic['pending_domains'] ) ) : ?>
<!-- No free slots: let the user release one bound domain and activate here. --> <!-- No free slots: list every bound domain with a trash button to free it. -->
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>"> <h2><?php esc_html_e( 'Belegte Domains', 'gdpr-content-blocker' ); ?></h2>
<p class="description" style="max-width:640px;">
<?php esc_html_e( 'Diese Lizenz ist bereits auf folgenden Domains aktiv. Entfernen Sie eine, um den Platz freizugeben diese Seite wird anschließend automatisch aktiviert.', 'gdpr-content-blocker' ); ?>
</p>
<ul class="cb-domain-list">
<?php
$confirm = esc_attr__( 'Diese Domain wirklich aus der Lizenz entfernen?', 'gdpr-content-blocker' );
foreach ( $lic['pending_domains'] as $d ) :
?>
<li>
<code><?php echo esc_html( $d ); ?></code>
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>"
onsubmit="return confirm('<?php echo $confirm; ?>');">
<?php wp_nonce_field( 'cb_license', 'cb_license_nonce' ); ?> <?php wp_nonce_field( 'cb_license', 'cb_license_nonce' ); ?>
<input type="hidden" name="action" value="cb_license_swap"> <input type="hidden" name="action" value="cb_license_swap">
<table class="form-table" role="presentation"><tbody> <input type="hidden" name="cb_release_domain" value="<?php echo esc_attr( $d ); ?>">
<tr> <button type="submit" class="cb-remove-service"
<th scope="row"><label for="cb_release_domain"><?php esc_html_e( 'Domain freigeben', 'gdpr-content-blocker' ); ?></label></th> aria-label="<?php esc_attr_e( 'Domain entfernen', 'gdpr-content-blocker' ); ?>"
<td> title="<?php esc_attr_e( 'Domain entfernen', 'gdpr-content-blocker' ); ?>">
<select id="cb_release_domain" name="cb_release_domain"> <span class="dashicons dashicons-trash"></span>
<?php foreach ( $lic['pending_domains'] as $d ) : ?> </button>
<option value="<?php echo esc_attr( $d ); ?>"><?php echo esc_html( $d ); ?></option>
<?php endforeach; ?>
</select>
<p class="description">
<?php esc_html_e( 'Diese Lizenz ist bereits auf den genannten Domains aktiv. Wählen Sie eine zum Freigeben aus sie wird deaktiviert und diese Seite stattdessen aktiviert.', 'gdpr-content-blocker' ); ?>
</p>
</td>
</tr>
</tbody></table>
<?php submit_button( __( 'Freigeben und diese Seite aktivieren', 'gdpr-content-blocker' ), 'primary' ); ?>
</form> </form>
</li>
<?php endforeach; ?>
</ul>
<hr> <hr>
<?php endif; ?> <?php endif; ?>

View File

@@ -466,6 +466,25 @@ class CB_Settings {
.cb-admin-wrap .cb-tab-content { .cb-admin-wrap .cb-tab-content {
padding-top: 20px; padding-top: 20px;
} }
/* bound-domains list (license full) */
.cb-admin-wrap .cb-domain-list {
margin: 10px 0 0;
max-width: 480px;
}
.cb-admin-wrap .cb-domain-list li {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 8px 12px;
margin: 0 0 6px;
background: #fff;
border: 1px solid #dcdcde;
border-radius: 4px;
}
.cb-admin-wrap .cb-domain-list form {
margin: 0;
}
.cb-admin-wrap .cb-field label { .cb-admin-wrap .cb-field label {
display: block; display: block;
font-weight: 600; font-weight: 600;

View File

@@ -57,14 +57,17 @@ msgstr "Status"
msgid "Domain" msgid "Domain"
msgstr "Domain" msgstr "Domain"
msgid "Domain freigeben" msgid "Belegte Domains"
msgstr "Release domain" msgstr "Bound domains"
msgid "Diese Lizenz ist bereits auf den genannten Domains aktiv. Wählen Sie eine zum Freigeben aus sie wird deaktiviert und diese Seite stattdessen aktiviert." msgid "Diese Lizenz ist bereits auf folgenden Domains aktiv. Entfernen Sie eine, um den Platz freizugeben diese Seite wird anschließend automatisch aktiviert."
msgstr "This license is already active on the domains listed. Choose one to release — it will be deactivated and this site activated instead." msgstr "This license is already active on the following domains. Remove one to free a seat — this site will then be activated automatically."
msgid "Freigeben und diese Seite aktivieren" msgid "Diese Domain wirklich aus der Lizenz entfernen?"
msgstr "Release and activate this site" msgstr "Really remove this domain from the license?"
msgid "Domain entfernen"
msgstr "Remove domain"
msgid "Aus Sicherheitsgründen verdeckt. Zum Ändern bitte zuerst deaktivieren." msgid "Aus Sicherheitsgründen verdeckt. Zum Ändern bitte zuerst deaktivieren."
msgstr "Hidden for security. To change it, deactivate first." msgstr "Hidden for security. To change it, deactivate first."

View File

@@ -22,9 +22,10 @@ EN = [
"Not activated", "Not activated",
"Status", "Status",
"Domain", "Domain",
"Release domain", "Bound domains",
"This license is already active on the domains listed. Choose one to release — it will be deactivated and this site activated instead.", "This license is already active on the following domains. Remove one to free a seat — this site will then be activated automatically.",
"Release and activate this site", "Really remove this domain from the license?",
"Remove domain",
"Hidden for security. To change it, deactivate first.", "Hidden for security. To change it, deactivate first.",
"Deactivate license", "Deactivate license",
"Try again", "Try again",