feat: Werbe-Badge im content blocker (unten rechts) + abschaltbar nur mit unlimited (v1.5.0)
- Kleines Badge "GDPR Content Blocker" unten rechts im platzhalter, verlinkt
auf die kaufseite (rel=nofollow sponsored). Server- und client-seitig.
- Wird IMMER angezeigt; abschaltbar via checkbox im Darstellung-tab
("Werbe-Badge ausblenden") - die checkbox ist aber nur mit aktiver
Unlimited-lizenz nutzbar (sonst disabled) und greift am render-punkt nur,
wenn is_unlimited() true ist.
- Dafuer speichert das plugin jetzt max_activations aus der backend-antwort
(activate/validate/swap) und bietet is_unlimited().
+ i18n DE/EN (134 strings). version 1.5.0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -64,6 +64,7 @@ class CB_License {
|
||||
'last_check' => 0,
|
||||
'message' => '',
|
||||
'pending_domains' => [],
|
||||
'max_activations' => 0, // -1 = unlimited (from the backend)
|
||||
] );
|
||||
if ( ! is_array( $lic['pending_domains'] ) ) {
|
||||
$lic['pending_domains'] = [];
|
||||
@@ -75,6 +76,12 @@ class CB_License {
|
||||
return self::get_license()['status'] === 'active';
|
||||
}
|
||||
|
||||
/** True only for an active, unlimited-seat (max_activations = -1) license. */
|
||||
public static function is_unlimited(): bool {
|
||||
$lic = self::get_license();
|
||||
return $lic['status'] === 'active' && (int) ( $lic['max_activations'] ?? 0 ) === -1;
|
||||
}
|
||||
|
||||
/** Mask a key for display: keep dashes + last 4 chars, hide the rest. */
|
||||
public static function mask_key( string $key ): string {
|
||||
$n = strlen( $key );
|
||||
@@ -148,7 +155,7 @@ class CB_License {
|
||||
}
|
||||
|
||||
if ( ! empty( $result['ok'] ) && ( $result['status'] ?? '' ) === 'valid' ) {
|
||||
self::store( $key, 'active', __( 'Lizenz erfolgreich aktiviert.', 'gdpr-content-blocker' ) );
|
||||
self::store( $key, 'active', __( 'Lizenz erfolgreich aktiviert.', 'gdpr-content-blocker' ), [], isset( $result['max_activations'] ) ? (int) $result['max_activations'] : null );
|
||||
} elseif ( ( $result['code'] ?? '' ) === 'limit_reached' ) {
|
||||
// No free slots: keep the key and offer to release one of the bound domains.
|
||||
$domains = is_array( $result['domains'] ?? null ) ? $result['domains'] : [];
|
||||
@@ -216,7 +223,7 @@ class CB_License {
|
||||
/* translators: %s: released domain */
|
||||
__( 'Domain %s freigegeben und diese Seite aktiviert.', 'gdpr-content-blocker' ),
|
||||
$release
|
||||
) );
|
||||
), [], isset( $result['max_activations'] ) ? (int) $result['max_activations'] : null );
|
||||
} else {
|
||||
$domains = is_array( $result['domains'] ?? null ) ? $result['domains'] : $lic['pending_domains'];
|
||||
$msg = $result['error'] ?? __( 'Aktivierung fehlgeschlagen.', 'gdpr-content-blocker' );
|
||||
@@ -269,14 +276,18 @@ class CB_License {
|
||||
}
|
||||
|
||||
if ( ! empty( $result['ok'] ) && ( $result['status'] ?? '' ) === 'valid' ) {
|
||||
self::store( $lic['key'], 'active', '' );
|
||||
self::store( $lic['key'], 'active', '', [], isset( $result['max_activations'] ) ? (int) $result['max_activations'] : null );
|
||||
} else {
|
||||
$msg = $result['error'] ?? __( 'Lizenz nicht mehr gültig.', 'gdpr-content-blocker' );
|
||||
self::store( $lic['key'], 'invalid', $msg );
|
||||
}
|
||||
}
|
||||
|
||||
private static function store( string $key, string $status, string $message, array $pending_domains = [] ): void {
|
||||
private static function store( string $key, string $status, string $message, array $pending_domains = [], ?int $max = null ): void {
|
||||
// Preserve the previously stored seat count unless a fresh one is given.
|
||||
$prev = get_option( CB_LICENSE_OPTION, [] );
|
||||
$prev_max = is_array( $prev ) && isset( $prev['max_activations'] ) ? (int) $prev['max_activations'] : 0;
|
||||
|
||||
update_option( CB_LICENSE_OPTION, [
|
||||
'key' => $key,
|
||||
'status' => $status,
|
||||
@@ -284,6 +295,7 @@ class CB_License {
|
||||
'last_check' => time(),
|
||||
'message' => $message,
|
||||
'pending_domains' => array_values( array_filter( array_map( 'strval', $pending_domains ) ) ),
|
||||
'max_activations' => $max !== null ? $max : $prev_max,
|
||||
] );
|
||||
|
||||
// License state changed → invalidate cached update info and force WP to
|
||||
|
||||
@@ -107,8 +107,9 @@ class CB_Renderer {
|
||||
// Service data + i18n for client-side detection (JS-injected iframes such
|
||||
// as Elementor video widgets, sliders, …).
|
||||
wp_localize_script( 'cb-frontend', 'cbConfig', [
|
||||
'services' => self::services_for_js(),
|
||||
'i18n' => [
|
||||
'services' => self::services_for_js(),
|
||||
'showBadge' => self::show_badge(),
|
||||
'i18n' => [
|
||||
'recipient' => __( 'Empfänger:', 'gdpr-content-blocker' ),
|
||||
'purpose' => __( 'Zweck:', 'gdpr-content-blocker' ),
|
||||
'thirdCountry' => __( 'Datenübermittlung in ein Drittland außerhalb der EU/des EWR', 'gdpr-content-blocker' ),
|
||||
@@ -366,9 +367,25 @@ class CB_Renderer {
|
||||
. esc_html__( 'Diesen Dienst künftig immer laden', 'gdpr-content-blocker' )
|
||||
. '</label>'
|
||||
. '</div>'
|
||||
. ( self::show_badge() ? self::badge_html() : '' )
|
||||
. '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to show the promo badge. Always shown, EXCEPT when the site owner
|
||||
* has an active unlimited licence AND ticked "hide badge" in Appearance.
|
||||
*/
|
||||
public static function show_badge(): bool {
|
||||
$style = CB_Settings::get_style();
|
||||
return ! ( ! empty( $style['hide_badge'] ) && CB_License::is_unlimited() );
|
||||
}
|
||||
|
||||
/** Small "GDPR Content Blocker" badge in the bottom-right of the placeholder. */
|
||||
private static function badge_html(): string {
|
||||
return '<a class="cb-blocker__badge" href="https://lucas-orth.de/wp-plugins/gdpr-content-blocker/"'
|
||||
. ' target="_blank" rel="noopener noreferrer nofollow sponsored">GDPR Content Blocker</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull src + width + height out of an iframe string.
|
||||
* Height is also read from an inline style="height:NNNpx" if no attribute.
|
||||
|
||||
@@ -50,6 +50,9 @@ class CB_Settings {
|
||||
$clean['custom_css'] = isset( $input['custom_css'] )
|
||||
? wp_strip_all_tags( $input['custom_css'] )
|
||||
: '';
|
||||
// Hiding the promo badge only ever takes effect with an active unlimited
|
||||
// licence (enforced again at render time), but we store the choice as-is.
|
||||
$clean['hide_badge'] = ! empty( $input['hide_badge'] );
|
||||
return $clean;
|
||||
}
|
||||
|
||||
@@ -69,6 +72,7 @@ class CB_Settings {
|
||||
'button_hover_bg' => '#1a369a',
|
||||
'button_hover_text' => '#ffffff',
|
||||
'custom_css' => '',
|
||||
'hide_badge' => false,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -666,6 +670,18 @@ class CB_Settings {
|
||||
echo '<tr><th scope="row"><label>' . esc_html( $label ) . '</label></th>';
|
||||
echo '<td><input type="text" class="cb-color-picker" name="' . esc_attr( CB_STYLE_OPTION . '[' . $key . ']' ) . '" value="' . $val . '" data-default-color="' . $val . '"></td></tr>';
|
||||
}
|
||||
// Promo-badge toggle — only effective with an active unlimited licence.
|
||||
$unlimited = CB_License::is_unlimited();
|
||||
echo '<tr><th scope="row">' . esc_html__( 'Werbe-Badge', 'gdpr-content-blocker' ) . '</th><td>';
|
||||
echo '<label><input type="checkbox" name="' . esc_attr( CB_STYLE_OPTION . '[hide_badge]' ) . '" value="1" '
|
||||
. checked( ! empty( $style['hide_badge'] ), true, false )
|
||||
. ( $unlimited ? '' : ' disabled' ) . '> '
|
||||
. esc_html__( 'Badge „GDPR Content Blocker" im Platzhalter ausblenden', 'gdpr-content-blocker' ) . '</label>';
|
||||
if ( ! $unlimited ) {
|
||||
echo '<p class="description">' . esc_html__( 'Das Ausblenden ist nur mit einer aktiven Unlimited-Lizenz möglich.', 'gdpr-content-blocker' ) . '</p>';
|
||||
}
|
||||
echo '</td></tr>';
|
||||
|
||||
echo '<tr><th scope="row"><label>' . esc_html__( 'Custom CSS', 'gdpr-content-blocker' ) . '</label></th>';
|
||||
echo '<td><textarea name="' . esc_attr( CB_STYLE_OPTION . '[custom_css]' ) . '" rows="8" class="large-text code">' . esc_textarea( $style['custom_css'] ) . '</textarea>';
|
||||
echo '<p class="description">' . esc_html__( 'Wird nach den CSS-Variablen eingebunden und kann diese überschreiben. Tipp: denselben Präfix verwenden, z. B. .cb-blocker .cb-blocker__button { … }', 'gdpr-content-blocker' ) . '</p>';
|
||||
|
||||
Reference in New Issue
Block a user