From dfdc74bcf9e534d50d6c695b9a7330f790f9e511 Mon Sep 17 00:00:00 2001 From: M_Viper Date: Sun, 22 Mar 2026 00:40:15 +0100 Subject: [PATCH] Update from Git Manager GUI --- admin/forum-admin.php | 482 ++++++++++++++++++++++++++++++++++++++- admin/forum-settings.php | 91 ++++++++ 2 files changed, 566 insertions(+), 7 deletions(-) diff --git a/admin/forum-admin.php b/admin/forum-admin.php index 3786939..a277909 100644 --- a/admin/forum-admin.php +++ b/admin/forum-admin.php @@ -31,6 +31,7 @@ add_action( 'admin_menu', function() { add_submenu_page( 'wbf-admin', 'Wortfilter', 'Wortfilter', 'manage_options', 'wbf-wordfilter', 'wbf_admin_wordfilter' ); add_submenu_page( 'wbf-admin', 'Export / Import','Export / Import','manage_options', 'wbf-export', 'wbf_admin_export' ); add_submenu_page( 'wbf-admin', '⚠️ Deinstallieren', '⚠️ Deinstallieren', 'manage_options', 'wbf-uninstall', 'wbf_admin_uninstall' ); + add_submenu_page( 'wbf-admin', 'πŸ”” Updates', 'πŸ”” Updates', 'manage_options', 'wbf-updates', 'wbf_admin_updates' ); }, 10 ); // Meldungs-Badge im MenΓΌ (separater Hook mit PrioritΓ€t 999, lΓ€uft nach der Registrierung) @@ -84,6 +85,7 @@ add_action( 'admin_init', function() { case 'settings': $data['settings'] = get_option('wbf_settings', []); $data['profile_fields'] = get_option('wbf_profile_fields', []); + $data['reactions_cfg'] = get_option('wbf_reactions', []); break; case 'roles': $data['roles'] = get_option('wbf_custom_roles', []); @@ -125,6 +127,16 @@ add_action( 'admin_init', function() { ); $data['subscriptions'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_subscriptions ORDER BY id ASC", ARRAY_A ); break; + case 'polls': + $data['polls'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_polls ORDER BY id ASC", ARRAY_A ); + $data['poll_votes'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_poll_votes ORDER BY id ASC", ARRAY_A ); + break; + case 'bookmarks': + $data['bookmarks'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_bookmarks ORDER BY id ASC", ARRAY_A ); + break; + case 'prefixes': + $data['prefixes'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_prefixes ORDER BY sort_order ASC", ARRAY_A ); + break; case 'interactions': $data['likes'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_likes ORDER BY id ASC", ARRAY_A ); $data['reactions'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_reactions ORDER BY id ASC", ARRAY_A ); @@ -139,6 +151,9 @@ add_action( 'admin_init', function() { case 'invites': $data['invites'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_invites ORDER BY id ASC", ARRAY_A ); break; + case 'ignore_list': + $data['ignore_list'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_ignore_list ORDER BY id ASC", ARRAY_A ); + break; } } @@ -339,6 +354,7 @@ function wbf_admin_page() { $online_count = (int)$wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}forum_users WHERE last_active >= DATE_SUB(NOW(), INTERVAL 15 MINUTE)"); $invite_count = (int)$wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}forum_invites WHERE use_count < max_uses AND (expires_at IS NULL OR expires_at > NOW())"); $banned_count = (int)$wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}forum_users WHERE role='banned'"); + $update_info = wbf_update_available(); // null oder array mit Versionsdaten // ── System ──────────────────────────────────────────────────────────────── $php_ver = PHP_VERSION; @@ -537,6 +553,7 @@ function wbf_admin_page() { ['wbf-trash', 'fas fa-trash-can', 'Papierkorb', $deleted_count>0?$deleted_count:0, true], ['wbf-export', 'fas fa-database', 'Export / Import'], ['wbf-settings', 'fas fa-gear', 'Einstellungen'], + ['wbf-updates', 'fas fa-arrow-up-from-bracket', 'πŸ”” Updates', $update_info ? 1 : 0], ]; foreach ($nav as $n): if ($n===null) { echo '
'; continue; } @@ -1201,6 +1218,65 @@ function wbf_admin_members() { } } + + // ── Nutzer lΓΆschen (DSGVO Art. 17 / Hard Delete) ───────────────────────── + if ( isset( $_POST['wbf_delete_member'] ) && check_admin_referer( 'wbf_delete_member_nonce' ) ) { + $uid = (int) ( $_POST['user_id'] ?? 0 ); + $mode = sanitize_key( $_POST['delete_mode'] ?? 'anonymize' ); + if ( $uid ) { + $target = WBF_DB::get_user( $uid ); + if ( ! $target ) { + echo '

❌ Nutzer nicht gefunden.

'; + } elseif ( $target->role === WBF_Roles::SUPERADMIN ) { + echo '

❌ Der Superadmin kann nicht gelΓΆscht werden.

'; + } else { + global $wpdb; + $name = esc_html( $target->display_name ); + + if ( $mode === 'hard' ) { + // Alle nutzerbezogenen Daten entfernen + $dep_tables = [ + 'forum_messages' => [ 'from_id', 'to_id' ], + 'forum_notifications' => [ 'user_id', 'actor_id' ], + 'forum_subscriptions' => [ 'user_id' ], + 'forum_bookmarks' => [ 'user_id' ], + 'forum_likes' => [ 'user_id' ], + 'forum_reactions' => [ 'user_id' ], + 'forum_reports' => [ 'reporter_id' ], + 'forum_poll_votes' => [ 'user_id' ], + 'forum_remember_tokens' => [ 'user_id' ], + 'forum_user_meta' => [ 'user_id' ], + 'forum_ignore_list' => [ 'user_id', 'ignored_id' ], + ]; + foreach ( $dep_tables as $tbl => $cols ) { + $full = $wpdb->prefix . $tbl; + if ( $wpdb->get_var( "SHOW TABLES LIKE '$full'" ) !== $full ) continue; + foreach ( $cols as $col ) { + $wpdb->delete( $full, [ $col => $uid ], [ '%d' ] ); + } + } + // Threads/Posts auf user_id=0 setzen (Inhalt bleibt) + $wpdb->update( "{$wpdb->prefix}forum_threads", [ 'user_id' => 0 ], [ 'user_id' => $uid ], [ '%d' ], [ '%d' ] ); + $wpdb->update( "{$wpdb->prefix}forum_posts", [ 'user_id' => 0 ], [ 'user_id' => $uid ], [ '%d' ], [ '%d' ] ); + // Nutzer-Datensatz hart loeschen + $wpdb->delete( "{$wpdb->prefix}forum_users", [ 'id' => $uid ], [ '%d' ] ); + echo "

🗑 Nutzer {$name} dauerhaft geloescht. Threads/Posts anonym gesetzt.

"; + + } else { + // DSGVO Art. 17 Anonymisierung (Standard) + $ok = WBF_DB::delete_user_gdpr( $uid ); + if ( $ok ) { + echo "

✅ Nutzer {$name} anonymisiert (DSGVO Art. 17). Threads und Beitraege bleiben erhalten.

"; + } else { + echo "

❌ Anonymisierung fehlgeschlagen.

"; + } + } + delete_transient( 'wbf_flood_' . $uid ); + delete_transient( 'wbf_flood_ts_' . $uid ); + } + } + } + // ── Profil bearbeiten ───────────────────────────────────────────────────── if ( isset( $_POST['wbf_edit_user'] ) && check_admin_referer( 'wbf_edit_user_nonce' ) ) { $uid = (int) $_POST['user_id']; @@ -1238,6 +1314,35 @@ function wbf_admin_members() { } } + // ── Admin: einzelnen Ignore-Eintrag entfernen ───────────────────────────── + if ( isset( $_POST['wbf_admin_remove_ignore'] ) && check_admin_referer( 'wbf_admin_ignore_nonce' ) ) { + if ( current_user_can('manage_options') ) { + $uid = (int) ( $_POST['user_id'] ?? 0 ); + $ignored_id = (int) ( $_POST['ignored_id'] ?? 0 ); + if ( $uid && $ignored_id ) { + global $wpdb; + $wpdb->delete( + "{$wpdb->prefix}forum_ignore_list", + [ 'user_id' => $uid, 'ignored_id' => $ignored_id ], + [ '%d', '%d' ] + ); + echo '

Ignore-Eintrag entfernt.

'; + } + } + } + + // ── Admin: gesamte Ignore-Liste eines Users leeren ──────────────────────── + if ( isset( $_POST['wbf_admin_clear_ignores'] ) && check_admin_referer( 'wbf_admin_ignore_nonce' ) ) { + if ( current_user_can('manage_options') ) { + $uid = (int) ( $_POST['user_id'] ?? 0 ); + if ( $uid ) { + global $wpdb; + $wpdb->delete( "{$wpdb->prefix}forum_ignore_list", [ 'user_id' => $uid ], [ '%d' ] ); + echo '

Ignore-Liste vollstΓ€ndig geleert.

'; + } + } + } + $members = WBF_DB::get_all_users( 200 ); ?>
@@ -1350,6 +1455,11 @@ function wbf_admin_members() { onclick="var d=document.getElementById('wbf-edit-user-id; ?>');d.style.display=d.style.display==='none'?'block':'none'"> Profil bearbeiten +
Γ„nderungen speichern
+ + + id ); + ?> +
+ + + Ignorierte Nutzer () + + +

Dieser Nutzer ignoriert niemanden.

+ + + + + + + + + + + + + + + + + + +
NutzerIgnoriert seitEntfernen
+ display_name); ?> + @username); ?> + + ignored_since))); ?> + +
+ + + + +
+
+
+ + + +
+ +
+ + + + @@ -2353,6 +2585,11 @@ function wbf_admin_export() { update_option('wbf_profile_fields', $data['profile_fields']); $imported[] = 'Profilfelder-Definitionen (' . count($data['profile_fields']) . ')'; } + // Reaktionen-Konfiguration + if ( isset($data['reactions_cfg']) && is_array($data['reactions_cfg']) ) { + update_option('wbf_reactions', $data['reactions_cfg']); + $imported[] = 'Reaktionen-Konfiguration'; + } // ── Rollen ──────────────────────────────────────────────── if ( ! empty($data['roles']) ) { @@ -2378,8 +2615,21 @@ function wbf_admin_export() { if ( $existing === 0 || $force ) { if ($force) $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_categories"); foreach ($data['categories'] as $cat) { - unset($cat['id']); - $wpdb->insert("{$wpdb->prefix}forum_categories", $cat); + // BUGFIX: Original-ID behalten! Threads zeigen direkt auf diese IDs. + $wpdb->query( $wpdb->prepare( + "INSERT INTO {$wpdb->prefix}forum_categories + (id, parent_id, name, slug, description, icon, sort_order, thread_count, post_count, min_role, guest_visible) + VALUES (%d,%d,%s,%s,%s,%s,%d,%d,%d,%s,%d) + ON DUPLICATE KEY UPDATE parent_id=%d, name=%s, slug=%s, description=%s, icon=%s, sort_order=%d, thread_count=%d, post_count=%d, min_role=%s, guest_visible=%d", + (int)($cat['id']), (int)($cat['parent_id'] ?? 0), $cat['name'] ?? '', $cat['slug'] ?? '', + $cat['description'] ?? '', $cat['icon'] ?? 'fas fa-comments', + (int)($cat['sort_order'] ?? 0), (int)($cat['thread_count'] ?? 0), + (int)($cat['post_count'] ?? 0), $cat['min_role'] ?? 'member', (int)($cat['guest_visible'] ?? 1), + (int)($cat['parent_id'] ?? 0), $cat['name'] ?? '', $cat['slug'] ?? '', + $cat['description'] ?? '', $cat['icon'] ?? 'fas fa-comments', + (int)($cat['sort_order'] ?? 0), (int)($cat['thread_count'] ?? 0), + (int)($cat['post_count'] ?? 0), $cat['min_role'] ?? 'member', (int)($cat['guest_visible'] ?? 1) + ) ); } $imported[] = 'Kategorien (' . count($data['categories']) . ')'; } else { @@ -2439,11 +2689,17 @@ function wbf_admin_export() { if ( ! empty($data['threads']) ) { $force = ! empty($_POST['import_force_threads']); if ($force) { - $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_posts"); - $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_threads"); - $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_thread_tags"); - $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_tags"); - $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_subscriptions"); + // Alle abhΓ€ngigen Tabellen mitbereinigen (verhindert verwaiste EintrΓ€ge) + $wpdb->query("SET FOREIGN_KEY_CHECKS=0"); + foreach ([ + 'forum_posts', 'forum_threads', 'forum_thread_tags', 'forum_tags', + 'forum_subscriptions', 'forum_polls', 'forum_poll_votes', + 'forum_bookmarks', 'forum_prefixes', 'forum_likes', 'forum_reactions', + 'forum_notifications', 'forum_ignore_list', + ] as $_tbl) { + $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}$_tbl"); + } + $wpdb->query("SET FOREIGN_KEY_CHECKS=1"); } foreach ($data['threads'] ?? [] as $t) { $wpdb->insert("{$wpdb->prefix}forum_threads", $t); } foreach ($data['posts'] ?? [] as $p) { $wpdb->insert("{$wpdb->prefix}forum_posts", $p); } @@ -2478,6 +2734,61 @@ function wbf_admin_export() { $imported[] = 'Threads + Posts (' . count($data['threads']) . ' / ' . count($data['posts'] ?? []) . ')'; } + // ── Thread-PrΓ€fixe ──────────────────────────────────────── + // ── Thread-PrΓ€fixe ──────────────────────────────────────── + if ( ! empty($data['prefixes']) ) { + $force = ! empty($_POST['import_force_prefixes']); + if ($force) $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_prefixes"); + $pc = 0; + foreach ($data['prefixes'] as $row) { + $wpdb->query( $wpdb->prepare( + "INSERT INTO {$wpdb->prefix}forum_prefixes (id, label, color, bg_color, sort_order) + VALUES (%d,%s,%s,%s,%d) + ON DUPLICATE KEY UPDATE label=%s, color=%s, bg_color=%s, sort_order=%d", + (int)$row['id'], $row['label'], $row['color'] ?? '#ffffff', + $row['bg_color'] ?? '#475569', (int)($row['sort_order'] ?? 0), + $row['label'], $row['color'] ?? '#ffffff', + $row['bg_color'] ?? '#475569', (int)($row['sort_order'] ?? 0) + ) ); + $pc++; + } + if ($pc) $imported[] = "Thread-PrΓ€fixe ($pc)"; + } + + // ── Umfragen + Abstimmungen ─────────────────────────────── + if ( ! empty($data['polls']) ) { + $force = ! empty($_POST['import_force_polls']); + if ($force) { + $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_poll_votes"); + $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_polls"); + } + $pc = 0; + foreach ($data['polls'] as $row) { + $wpdb->query( $wpdb->prepare( + "INSERT INTO {$wpdb->prefix}forum_polls (id, thread_id, question, options, multi, ends_at, created_at) + VALUES (%d,%d,%s,%s,%d,%s,%s) + ON DUPLICATE KEY UPDATE thread_id=%d, question=%s, options=%s, multi=%d, ends_at=%s", + (int)$row['id'], (int)$row['thread_id'], $row['question'] ?? '', + $row['options'] ?? '[]', (int)($row['multi'] ?? 0), + $row['ends_at'] ?? null, $row['created_at'] ?? current_time('mysql'), + (int)$row['thread_id'], $row['question'] ?? '', + $row['options'] ?? '[]', (int)($row['multi'] ?? 0), $row['ends_at'] ?? null + ) ); + $pc++; + } + foreach ($data['poll_votes'] ?? [] as $row) { unset($row['id']); $wpdb->replace("{$wpdb->prefix}forum_poll_votes", $row); } + $imported[] = "Umfragen ($pc)"; + } + + // ── Lesezeichen ─────────────────────────────────────────── + if ( ! empty($data['bookmarks']) ) { + $force = ! empty($_POST['import_force_bookmarks']); + if ($force) $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_bookmarks"); + $bc = 0; + foreach ($data['bookmarks'] as $row) { unset($row['id']); $wpdb->replace("{$wpdb->prefix}forum_bookmarks", $row); $bc++; } + if ($bc) $imported[] = "Lesezeichen ($bc)"; + } + // ── Likes, Reaktionen, Benachrichtigungen ───────────────── if ( ! empty($data['likes']) ) { $force = ! empty($_POST['import_force_threads']); @@ -2539,6 +2850,19 @@ function wbf_admin_export() { if ($count) $imported[] = "Einladungen ($count)"; } + // ── Ignore-Liste ────────────────────────────────────────── + if ( ! empty($data['ignore_list']) ) { + $force = ! empty($_POST['import_force_ignore']); + if ($force) $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_ignore_list"); + $count = 0; + foreach ($data['ignore_list'] as $row) { + unset($row['id']); + $wpdb->replace("{$wpdb->prefix}forum_ignore_list", $row); + $count++; + } + if ($count) $imported[] = "Ignore-EintrΓ€ge ($count)"; + } + if ( empty($imported) ) { $notice = ['warning', 'Nichts importiert β€” Datei enthielt keine gΓΌltigen Abschnitte.']; } else { @@ -2581,8 +2905,12 @@ function wbf_admin_export() { 'categories' => ['πŸ“‚', 'Kategorien', 'Alle Kategorien inkl. Hierarchie'], 'users' => ['πŸ‘₯', 'Benutzer & Profilfelder', 'Accounts, Ban-Status, Profilfeld-Werte'], 'threads' => ['πŸ’¬', 'Threads, Posts & Abos', 'Alle Inhalte, Tags & Abonnements'], + 'polls' => ['πŸ“Š', 'Umfragen', 'Alle Umfragen inkl. Abstimmungen'], + 'bookmarks' => ['πŸ”–', 'Lesezeichen', 'Alle gespeicherten Thread-Lesezeichen'], + 'prefixes' => ['🏷️', 'Thread-PrΓ€fixe', 'Alle konfigurierten PrΓ€fix-Labels & Farben'], 'interactions' => ['❀️', 'Likes & Reaktionen', 'Likes, Reaktionen, Benachrichtigungen'], 'messages' => ['βœ‰οΈ', 'Privatnachrichten', 'Alle DM-Konversationen'], + 'ignore_list' => ['🚫', 'Ignore-Liste', 'Alle Nutzer-Blockierungen'], 'reports' => ['🚩', 'Meldungen', 'Gemeldete BeitrΓ€ge inkl. Status'], 'invites' => ['πŸ“¨', 'Einladungen', 'Alle Einladungscodes inkl. Nutzungsstand'], ]; @@ -2644,6 +2972,10 @@ function wbf_admin_export() { 'import_force_cats' => 'Kategorien ΓΌberschreiben (lΓΆscht bestehende)', 'import_force_users' => 'Benutzer aktualisieren (bei gleichem Username) inkl. Profilfeld-Werte', 'import_force_threads' => 'Threads, Posts, Likes, Reaktionen & Abonnements ΓΌberschreiben', + 'import_force_polls' => 'Umfragen & Abstimmungen ΓΌberschreiben', + 'import_force_bookmarks'=> 'Lesezeichen ΓΌberschreiben', + 'import_force_prefixes' => 'Thread-PrΓ€fixe ΓΌberschreiben', + 'import_force_ignore' => 'Ignore-Liste ΓΌberschreiben', 'import_force_messages' => 'Privatnachrichten ΓΌberschreiben', 'import_force_reports' => 'Meldungen ΓΌberschreiben', 'import_force_invites' => 'Einladungen ΓΌberschreiben', @@ -2868,6 +3200,142 @@ function wbf_admin_profile_fields() { } // ── Deinstallations-Seite ───────────────────────────────────────────────────── +// ── Update-Seite ────────────────────────────────────────────────────────────── + +function wbf_admin_updates() { + if ( ! current_user_can('manage_options') ) return; + + $latest = wbf_get_latest_release(); + $update = wbf_update_available(); + $cur_ver = WBF_VERSION; + $admin_url = admin_url('admin.php?page=wbf-updates'); + + // Manuelles Refresh + $refresh_url = wp_nonce_url( add_query_arg('wbf_refresh_update', '1', $admin_url), 'wbf_refresh_update' ); + ?> +
+

+ πŸ”” WP Business Forum β€” Updates +

+ + +
+ + + +
+ πŸ“¦ +
+ Update verfΓΌgbar! +

+ Version wurde verΓΆffentlicht. + Du verwendest aktuell . +

+
+ + πŸ“₯ Zum Download + +
+ + +
+ βœ… +
+ Du verwendest die neueste Version +

Version ist aktuell.

+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Installierte Version
Neueste Version + + + + NEU + + + Nicht abrufbar + +
VerΓΆffentlicht am Uhr
Update-Quelle + + + git.viper.ipv64.net β€” WP-Business-Forum + +
Letzter Check + βœ” Cache aktiv (12h)' : 'β€”'; + ?> + + πŸ”„ Jetzt prΓΌfen + +
+ + + +
+

+ πŸ“‹ Release Notes β€” v +

+
+ +
+ + + +
+ πŸ“– Update-Anleitung +
    +
  1. Lade die neue .zip von der Release-Seite herunter.
  2. +
  3. Erstelle vorher ein Backup ΓΌber Export / Import.
  4. +
  5. Lade die neue Version per FTP/SFTP hoch und ΓΌberschreibe die alten Dateien β€” oder nutze den WP-Plugins-Bereich (Plugin deaktivieren β†’ lΓΆschen β†’ neu hochladen).
  6. +
  7. Aktiviere das Plugin. Das DB-Schema wird automatisch aktualisiert.
  8. +
+
+ +
+
+
+ '1', 'rules_title' => 'Forum-Regeln & Nutzungsbedingungen', 'rules_content' => "**1. Respektvoller Umgang**\nBehandle alle Mitglieder freundlich und respektvoll. Beleidigungen, Mobbing und Diskriminierung sind nicht toleriert.\n\n**2. Keine Spam-Inhalte**\nWerbung, Spam und irrelevante Links sind verboten.\n\n**3. Keine illegalen Inhalte**\nJegliche Inhalte, die gegen geltendes Recht verstoßen, sind streng verboten.\n\n**4. Themenrelevanz**\nBeitrΓ€ge sollten zur jeweiligen Kategorie passen.\n\n**5. Urheberrecht**\nVerΓΆffentliche keine Inhalte, an denen du keine Rechte besitzt.\n\n**6. Datenschutz**\nTeile keine persΓΆnlichen Daten anderer Personen ohne deren Zustimmung.\n\n**7. Moderations-Entscheidungen**\nEntscheidungen der Moderatoren sind zu respektieren. Bei Fragen wende dich direkt ans Team.\n\nVerstâße kΓΆnnen zur Verwarnung oder dauerhaften Sperrung fΓΌhren.", + // Ignore/Block-System: Rollen die nicht geblockt werden kΓΆnnen (kommagetrennte SchlΓΌssel) + 'ignore_blocked_roles' => 'superadmin,admin,moderator', ]; $saved = get_option( 'wbf_settings', [] ); @@ -63,6 +65,38 @@ if ( ! function_exists('wbf_get_settings') ) { // ── Admin-Seite ─────────────────────────────────────────────────────────────── +/** + * Gibt ein Array der Rollen-Keys zurΓΌck die nicht geblockt/ignoriert werden kΓΆnnen. + * Superadmin ist immer enthalten β€” unabhΓ€ngig von der Einstellung. + * + * @return string[] z.B. ['superadmin', 'admin', 'moderator'] + */ +if ( ! function_exists('wbf_get_ignore_blocked_roles') ) { + function wbf_get_ignore_blocked_roles() { + $raw = wbf_get_settings()['ignore_blocked_roles'] ?? 'superadmin,admin,moderator'; + $keys = array_filter( array_map( 'trim', explode( ',', $raw ) ) ); + // superadmin immer schΓΌtzen + if ( ! in_array('superadmin', $keys, true) ) { + $keys[] = 'superadmin'; + } + return array_values( $keys ); + } +} + +/** + * PrΓΌft ob ein User ignoriert/geblockt werden darf. + * + * @param object $target Forum-User-Objekt + * @return bool true = darf ignoriert werden, false = nicht erlaubt + */ +if ( ! function_exists('wbf_can_be_ignored') ) { + function wbf_can_be_ignored( $target ) { + if ( ! $target ) return false; + $blocked_roles = wbf_get_ignore_blocked_roles(); + return ! in_array( $target->role, $blocked_roles, true ); + } +} + if ( ! function_exists('wbf_admin_settings') ) { function wbf_admin_settings() { @@ -96,6 +130,18 @@ function wbf_admin_settings() { // rules_content separat (nicht in $fields, da textarea mit eigener Behandlung) $settings['rules_content'] = sanitize_textarea_field( $_POST['rules_content'] ?? '' ); + // ignore_blocked_roles: kommagetrennte Liste der gewΓ€hlten Rollen-Keys + $all_role_keys = array_keys( WBF_Roles::get_all() ); + $checked_roles = array_intersect( + array_map( 'sanitize_key', (array)( $_POST['ignore_blocked_roles'] ?? [] ) ), + $all_role_keys + ); + // superadmin ist immer blockiert β€” kann nicht entfernt werden + if ( ! in_array('superadmin', $checked_roles, true) ) { + $checked_roles[] = 'superadmin'; + } + $settings['ignore_blocked_roles'] = implode( ',', $checked_roles ); + update_option( 'wbf_settings', $settings ); echo '

βœ… Einstellungen gespeichert!

'; } @@ -401,6 +447,51 @@ function wbf_admin_settings() { + +

+ 🚫 Ignore / Block-System +

+ + + + + + +