diff --git a/admin/forum-admin.php b/admin/forum-admin.php new file mode 100644 index 0000000..ec6b2d4 --- /dev/null +++ b/admin/forum-admin.php @@ -0,0 +1,1469 @@ +' . (int) $count . ''; + break; + } + } +}, 999 ); + +// ── Export via admin_init (läuft vor WordPress-Output/Headern) ──────────────── +add_action( 'admin_init', function() { + if ( ! isset( $_POST['wbf_do_export'] ) ) return; + if ( ! check_admin_referer( 'wbf_export_nonce' ) ) return; + if ( ! current_user_can( 'manage_options' ) ) return; + + $sections = array_keys( array_filter( $_POST['export_sections'] ?? [] ) ); + $data = [ + '_meta' => [ + 'plugin' => 'WP Business Forum', + 'version' => WBF_VERSION, + 'exported' => date('c'), + 'site' => get_bloginfo('url'), + 'sections' => $sections, + ], + ]; + + global $wpdb; + + foreach ( $sections as $sec ) { + switch ( $sec ) { + case 'settings': + $data['settings'] = get_option('wbf_settings', []); + break; + case 'roles': + $data['roles'] = get_option('wbf_custom_roles', []); + break; + case 'levels': + $data['levels'] = [ + 'config' => get_option('wbf_level_config', []), + 'enabled' => get_option('wbf_levels_enabled', true), + ]; + break; + case 'categories': + $data['categories'] = $wpdb->get_results( + "SELECT * FROM {$wpdb->prefix}forum_categories ORDER BY parent_id ASC, sort_order ASC", + ARRAY_A + ); + break; + case 'users': + $data['users'] = $wpdb->get_results( + "SELECT id, username, email, password, display_name, avatar_url, bio, signature, + role, post_count, registered, last_active, ban_reason + FROM {$wpdb->prefix}forum_users ORDER BY id ASC", + ARRAY_A + ); + break; + case 'threads': + $data['threads'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_threads ORDER BY id ASC", ARRAY_A ); + $data['posts'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_posts ORDER BY id ASC", ARRAY_A ); + $data['thread_tags'] = $wpdb->get_results( + "SELECT tt.*, t.name, t.slug, t.use_count + FROM {$wpdb->prefix}forum_thread_tags tt + JOIN {$wpdb->prefix}forum_tags t ON t.id = tt.tag_id + ORDER BY tt.thread_id 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 ); + $data['notifications'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_notifications ORDER BY id ASC", ARRAY_A ); + break; + case 'messages': + $data['messages'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_messages ORDER BY id ASC", ARRAY_A ); + break; + case 'reports': + $data['reports'] = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}forum_reports ORDER BY id ASC", ARRAY_A ); + break; + } + } + + $json = wp_json_encode( $data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE ); + $filename = 'wbf-backup-' . date('Y-m-d-His') . '.json'; + + header( 'Content-Type: application/json; charset=utf-8' ); + header( 'Content-Disposition: attachment; filename="' . $filename . '"' ); + header( 'Content-Length: ' . strlen( $json ) ); + header( 'Cache-Control: no-cache, no-store, must-revalidate' ); + echo $json; + exit; +} ); + + +// ── Inline Styles ───────────────────────────────────────────────────────────── + +add_action( 'admin_head', function() { + if ( ! isset( $_GET['page'] ) || strpos( $_GET['page'], 'wbf-' ) === false ) return; + echo ''; +} ); + +// ── Dashboard ───────────────────────────────────────────────────────────────── + +function wbf_admin_page() { + $stats = WBF_DB::get_stats(); + $roles = WBF_Roles::get_sorted(); + $open_reports = WBF_DB::count_open_reports(); + $recent = WBF_DB::get_recent_threads(6); + $members = WBF_DB::get_all_users(5); + $newest = $stats['newest'] ?? '—'; + + $admin_url = admin_url('admin.php'); + ?> +
+

Business Forum — Dashboard

+ + +
+ +
+ Forum-Shortcode + Füge [business_forum] auf einer Seite ein, um das Forum anzuzeigen. +
+
+ + +
+ 'fas fa-comments', 'color'=>'#eff6ff','icolor'=>'#3b82f6', 'val'=>$stats['threads'], 'label'=>'Threads'], + ['icon'=>'fas fa-comment-dots','color'=>'#f0fdf4','icolor'=>'#22c55e', 'val'=>$stats['posts'], 'label'=>'Beiträge'], + ['icon'=>'fas fa-users', 'color'=>'#fdf4ff','icolor'=>'#a855f7', 'val'=>$stats['members'], 'label'=>'Mitglieder'], + ['icon'=>'fas fa-flag', 'color'=>'#fff7ed','icolor'=>'#f97316', 'val'=>$open_reports, 'label'=>'Meldungen offen'], + ['icon'=>'fas fa-tags', 'color'=>'#f0fdfa','icolor'=>'#14b8a6', 'val'=>0, 'label'=>'Tags gesamt'], + ]; + // Get tag count + global $wpdb; + $stat_items[4]['val'] = (int)$wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}forum_tags"); + foreach ( $stat_items as $si ): + $link = ''; + if ($si['label']==='Offene Meldungen') $link = esc_url(add_query_arg(['page'=>'wbf-reports'], $admin_url)); + if ($si['label']==='Mitglieder') $link = esc_url(add_query_arg(['page'=>'wbf-members'], $admin_url)); + ?> + +
+
+ +
+
+
+
+
+
+
+ +
+ + +
+ + +
+ +
+
+ Aktive Rollen +
+
+
+ $role ): + $color = esc_attr($role['color']); $bg = esc_attr($role['bg_color']); ?> + + + + Lvl + + +
+

+ + Superadmin ist automatisch an den WordPress-Administrator gebunden. +

+
+
+ +
+
+ Schnellzugriff +
+
+ +
+
+
+ + +
+ +
+
+ Letzte Threads +
+
+ +

Noch keine Threads vorhanden.

+ + + +
+
+ +
+
+ Neueste Mitglieder +
+
+ +

Noch keine Mitglieder.

+ +
    + role); + $col = esc_attr($role['color']); + $bg = esc_attr($role['bg_color']); + ?> +
  • + +
    + + display_name); ?> + +
    + + + + +
    +
    + post_count; ?> Beitr. +
  • + +
+ +
+
+ +
+
+ +
+ $label ) { + if ( ! empty( $_POST['perm_' . $p] ) ) $perms[] = $p; + } + WBF_Roles::save( $key, [ + 'label' => sanitize_text_field( $_POST['role_label'] ), + 'level' => max( -1, min( 99, (int) $_POST['role_level'] ) ), + 'color' => sanitize_hex_color( $_POST['role_color'] ) ?: '#94a3b8', + 'bg_color' => sanitize_text_field( $_POST['role_bg'] ) ?: 'rgba(148,163,184,.1)', + 'icon' => sanitize_text_field( $_POST['role_icon'] ) ?: 'fas fa-user', + 'permissions' => $perms, + 'locked' => false, + 'description' => sanitize_textarea_field( $_POST['role_desc'] ), + ] ); + echo '

Rolle gespeichert!

'; + } + } + + if ( isset( $_POST['wbf_create_role'] ) && check_admin_referer( 'wbf_role_create_nonce' ) ) { + $new_key = sanitize_key( $_POST['new_role_key'] ?? '' ); + if ( $new_key && $new_key !== WBF_Roles::SUPERADMIN ) { + $perms = []; + foreach ( $all_perms as $p => $label ) { + if ( ! empty( $_POST['new_perm_' . $p] ) ) $perms[] = $p; + } + WBF_Roles::save( $new_key, [ + 'label' => sanitize_text_field( $_POST['new_role_label'] ?: ucfirst( $new_key ) ), + 'level' => max( 1, min( 79, (int) ( $_POST['new_role_level'] ?? 10 ) ) ), + 'color' => sanitize_hex_color( $_POST['new_role_color'] ) ?: '#94a3b8', + 'bg_color' => 'rgba(148,163,184,.1)', + 'icon' => sanitize_text_field( $_POST['new_role_icon'] ) ?: 'fas fa-user', + 'permissions' => $perms, + 'locked' => false, + 'description' => sanitize_textarea_field( $_POST['new_role_desc'] ), + ] ); + echo '

Neue Rolle erstellt!

'; + } + } + + if ( isset( $_GET['delete_role'] ) && check_admin_referer( 'delete_role_' . $_GET['delete_role'] ) ) { + $del = sanitize_key( $_GET['delete_role'] ); + if ( WBF_Roles::delete( $del ) ) { + echo '

Rolle gelöscht. Nutzer auf "member" gesetzt.

'; + } else { + echo '

Diese Rolle kann nicht gelöscht werden.

'; + } + } + + $roles = WBF_Roles::get_sorted(); + $edit_key = isset( $_GET['edit_role'] ) ? sanitize_key( $_GET['edit_role'] ) : null; + $edit_role = $edit_key ? WBF_Roles::get( $edit_key ) : null; + + echo '

Rollen-Verwaltung + Neue Rolle

'; + echo ' + '; + + foreach ( $roles as $key => $role ) { + $color = esc_attr( $role['color'] ); $bg = esc_attr( $role['bg_color'] ); + $badge = " + " . esc_html( $role['label'] ) . ""; + $perms = implode( ', ', array_map( fn($p) => esc_html( $all_perms[$p] ?? $p ), $role['permissions'] ?? [] ) ); + if ( in_array( 'all', $role['permissions'] ?? [] ) ) $perms = 'Alle Rechte'; + + $actions = ''; + if ( $key !== WBF_Roles::SUPERADMIN ) { + $actions .= "Bearbeiten"; + if ( ! in_array( $key, ['member'] ) ) { + $del_url = wp_nonce_url( "?page=wbf-roles&delete_role={$key}", "delete_role_{$key}" ); + $actions .= " | Löschen"; + } + } else { + $actions = 'Systemrolle — unveränderlich'; + } + + echo " + + + + + + "; + } + echo '
RolleLevelPermissionsBeschreibungAktionen
$badge " . ( ( $role['locked'] ?? false ) ? '(🔒)' : '' ) . "" . esc_html( $role['level'] ) . "$perms" . esc_html( $role['description'] ?? '' ) . "$actions
'; + + if ( $edit_role && $edit_key !== WBF_Roles::SUPERADMIN ) { + echo '

Bearbeiten: ' . esc_html( $edit_role['label'] ) . '

'; + echo '
'; + wp_nonce_field( 'wbf_role_edit_nonce' ); + echo ''; + wbf_role_form_fields( $edit_role, $all_perms, '' ); + echo '
'; + submit_button( 'Änderungen speichern', 'primary', 'wbf_save_role' ); + echo '

'; + } + + echo '

Neue Rolle erstellen

'; + wp_nonce_field( 'wbf_role_create_nonce' ); + echo ''; + wbf_role_form_fields( null, $all_perms, 'new_' ); + echo '
Rollen-Schlüssel * + +

Nur Kleinbuchstaben, Zahlen, Unterstriche. Unveränderlich.

+
'; + submit_button( 'Rolle erstellen', 'primary', 'wbf_create_role' ); + echo '
'; +} + +function wbf_role_form_fields( $role, $all_perms, $prefix ) { + $v = fn($k, $d = '') => esc_attr( $role[$k] ?? $d ); + $perms = $role['permissions'] ?? []; + echo " + Anzeigename * + Level + +

Superadmin=100, Admin≤80, Mod≤50, Member=10, Banned=-1

+ + Farbe + + + + Icon + +

FontAwesome 6, z.B. fas fa-crown

+ + Beschreibung + Permissions
"; + foreach ( $all_perms as $p => $label ) { + $checked = in_array( $p, $perms ) ? 'checked' : ''; + echo ""; + } + echo "
"; +} + +// ── Kategorien ──────────────────────────────────────────────────────────────── + +function wbf_admin_categories() { + global $wpdb; + $roles = WBF_Roles::get_sorted(); + + // ── Reihenfolge verschieben ────────────────────────────────────────────── + if ( isset( $_POST['wbf_reorder_cat'] ) && check_admin_referer( 'wbf_reorder_nonce' ) ) { + $move_id = (int) $_POST['cat_id']; + $dir = ( $_POST['direction'] ?? '' ) === 'up' ? 'up' : 'down'; + $parent = (int) $_POST['parent_id']; + + $siblings = $wpdb->get_results( $wpdb->prepare( + "SELECT id, sort_order FROM {$wpdb->prefix}forum_categories WHERE parent_id=%d ORDER BY sort_order ASC, id ASC", + $parent + ) ); + $ids = array_column( (array) $siblings, 'id' ); + $pos = array_search( $move_id, $ids ); + + if ( $dir === 'up' && $pos > 0 ) { + $swap_id = $ids[ $pos - 1 ]; + } elseif ( $dir === 'down' && $pos !== false && $pos < count($ids) - 1 ) { + $swap_id = $ids[ $pos + 1 ]; + } + if ( isset( $swap_id ) ) { + $so_a = $siblings[$pos]->sort_order; + $so_b = $siblings[ $dir === 'up' ? $pos - 1 : $pos + 1 ]->sort_order; + if ( $so_a === $so_b ) { $so_b = $dir === 'up' ? $so_a - 1 : $so_a + 1; } + $wpdb->update( "{$wpdb->prefix}forum_categories", ['sort_order' => $so_b], ['id' => $move_id] ); + $wpdb->update( "{$wpdb->prefix}forum_categories", ['sort_order' => $so_a], ['id' => $swap_id] ); + } + // Gleiche Seite neu laden (kein redirect_to nötig) + $tree = WBF_DB::get_categories_tree(); + } + + if ( isset( $_POST['wbf_save_cat'] ) && check_admin_referer( 'wbf_cat_nonce' ) ) { + $data = [ + 'parent_id' => (int) ( $_POST['parent_id'] ?? 0 ), + 'name' => sanitize_text_field( $_POST['name'] ), + 'slug' => sanitize_title( $_POST['name'] ), + 'description' => sanitize_textarea_field( $_POST['description'] ), + 'icon' => sanitize_text_field( $_POST['icon'] ), + 'sort_order' => (int) ( $_POST['sort_order'] ?? 0 ), + 'min_role' => sanitize_key( $_POST['min_role'] ?? 'member' ), + ]; + if ( ! empty( $_POST['cat_id'] ) ) { + $wpdb->update( "{$wpdb->prefix}forum_categories", $data, ['id' => (int) $_POST['cat_id']] ); + echo '

Gespeichert!

'; + } else { + $wpdb->insert( "{$wpdb->prefix}forum_categories", $data ); + echo '

Erstellt!

'; + } + } + + if ( isset( $_GET['delete_cat'] ) && current_user_can( 'manage_options' ) ) { + check_admin_referer( 'delete_cat_' . (int) $_GET['delete_cat'] ); + $wpdb->delete( "{$wpdb->prefix}forum_categories", ['id' => (int) $_GET['delete_cat']] ); + } + + $tree = WBF_DB::get_categories_tree(); + $all = WBF_DB::get_categories_flat(); + $edit = isset( $_GET['edit'] ) ? WBF_DB::get_category( (int) $_GET['edit'] ) : null; + + echo '

Kategorien + Neue Kategorie

'; + echo ' + '; + + foreach ( $tree as $p ) { + $d = wp_nonce_url( "?page=wbf-categories&delete_cat={$p->id}", "delete_cat_{$p->id}" ); + $role = WBF_Roles::get( $p->min_role ?? 'member' ); + $lockbadge = ( $p->min_role ?? 'member' ) !== 'member' + ? " 🔒 " . esc_html( $role['label'] ) . "" : ''; + $reorder_p = + '' + . wp_nonce_field( 'wbf_reorder_nonce', '_wpnonce', true, false ) + . '' + . '' + . '' + . '' + . '' + . '' + . wp_nonce_field( 'wbf_reorder_nonce', '_wpnonce', true, false ) + . '' + . '' + . '' + . '' + . ''; + echo " + + + + + "; + foreach ( $p->children as $c ) { + $cd = wp_nonce_url( "?page=wbf-categories&delete_cat={$c->id}", "delete_cat_{$c->id}" ); + $crole = WBF_Roles::get( $c->min_role ?? 'member' ); + $reorder_c = + '' + . wp_nonce_field( 'wbf_reorder_nonce', '_wpnonce', true, false ) + . '' + . '' + . '' + . '' + . '' + . '' + . wp_nonce_field( 'wbf_reorder_nonce', '_wpnonce', true, false ) + . '' + . '' + . '' + . '' + . ''; + echo " + + + + + "; + } + } + echo '
KategorieThreadsMin. RolleAktionen
" . esc_html( $p->name ) . "$lockbadge" . esc_html( $p->thread_count ) . "" . esc_html( $role['label'] ) . "{$reorder_p} Bearbeiten | Löschen
↳ " . esc_html( $c->name ) . "" . esc_html( $c->thread_count ) . "" . esc_html( $crole['label'] ) . "{$reorder_c} Bearbeiten | Löschen
'; + + $parent_opts = ''; + foreach ( $all as $c ) { + if ( $edit && $c->id == $edit->id ) continue; + $sel = ( $edit && (int) $edit->parent_id === (int) $c->id ) ? ' selected' : ''; + $indent = (int) $c->parent_id > 0 ? '  ↳ ' : ''; + $parent_opts .= ""; + } + + $role_opts = ''; + foreach ( $roles as $k => $r ) { + if ( $k === 'banned' || $k === WBF_Roles::SUPERADMIN ) continue; + $sel = ( $edit && ( $edit->min_role ?? 'member' ) === $k ) ? ' selected' : ''; + $role_opts .= ""; + } + + echo '

' . ( $edit ? 'Bearbeiten: ' . esc_html( $edit->name ) : 'Neue Kategorie' ) . '

'; + echo '
'; + wp_nonce_field( 'wbf_cat_nonce' ); + if ( $edit ) echo ''; + echo ' + + + + + + '; + echo '
Elternkategorie
Name *
Beschreibung
Icon +

z.B. fas fa-home, fas fa-bug

Min. Rolle
Reihenfolge
'; + submit_button( $edit ? 'Speichern' : 'Erstellen', 'primary', 'wbf_save_cat' ); + echo '
'; +} + +// ── Mitglieder ──────────────────────────────────────────────────────────────── + +function wbf_admin_members() { + $roles = WBF_Roles::get_sorted(); + + // ── Rolle ändern ────────────────────────────────────────────────────────── + if ( isset( $_POST['wbf_change_role'] ) && check_admin_referer( 'wbf_member_role_nonce' ) ) { + $uid = (int) $_POST['user_id']; + $role = sanitize_key( $_POST['new_role'] ); + if ( $uid && $role !== WBF_Roles::SUPERADMIN && array_key_exists( $role, WBF_Roles::get_all() ) ) { + $update = ['role' => $role]; + if ( $role === 'banned' ) { + $update['ban_reason'] = sanitize_textarea_field( $_POST['ban_reason'] ?? '' ); + } else { + $update['ban_reason'] = ''; + } + WBF_DB::update_user( $uid, $update ); + echo '

Rolle aktualisiert!

'; + } + } + + // ── Profil bearbeiten ───────────────────────────────────────────────────── + if ( isset( $_POST['wbf_edit_user'] ) && check_admin_referer( 'wbf_edit_user_nonce' ) ) { + $uid = (int) $_POST['user_id']; + $display_name = sanitize_text_field( $_POST['display_name'] ?? '' ); + $email = sanitize_email( $_POST['email'] ?? '' ); + $new_password = $_POST['new_password'] ?? ''; + + if ( $uid && $uid !== 0 ) { + $user = WBF_DB::get_user( $uid ); + if ( $user && $user->role !== WBF_Roles::SUPERADMIN ) { + $update = []; + if ( ! empty($display_name) ) $update['display_name'] = $display_name; + if ( is_email($email) ) $update['email'] = $email; + if ( strlen($new_password) >= 6 ) { + $update['password'] = password_hash( $new_password, PASSWORD_DEFAULT ); + } + if ( ! empty($update) ) { + WBF_DB::update_user( $uid, $update ); + echo '

Profil von ' . esc_html($user->display_name) . ' aktualisiert!

'; + } + } + } + } + + $members = WBF_DB::get_all_users( 200 ); + ?> +
+

Mitglieder

+ + + + + + + + + + role ); + $color = esc_attr( $role['color'] ); + $bg = esc_attr( $role['bg_color'] ); + $icon = esc_attr( $role['icon'] ?? 'fas fa-user' ); + $is_sa = ( $m->role === WBF_Roles::SUPERADMIN ); + $ban_reason = esc_attr( $m->ban_reason ?? '' ); + $opts = ''; + foreach ( $roles as $k => $r ) { + if ( $k === WBF_Roles::SUPERADMIN ) continue; + $sel = $m->role === $k ? ' selected' : ''; + $opts .= ''; + } + ?> + + + + + + + + + + + +
#NutzerE-MailAktuelle RolleBeiträgeRegistriertRolle ändern
id ); ?> + display_name ); ?>
+ @username ); ?> +
email ); ?> + + + + (WP-Admin) + post_count ); ?>registered ) ) ); ?> + + Automatisch (WP-Admin) + +
+ + +
+ + + +
+
+ +
+
+ + + + +
+
+

Meldung aktualisiert.

'; + } + } + + $filter = sanitize_key( $_GET['filter'] ?? 'open' ); + $reports = WBF_DB::get_reports( $filter, 100 ); + $count = WBF_DB::count_open_reports(); + + echo '

Meldungen ' . ( $count > 0 ? '' . (int) $count . '' : '' ) . '

'; + + $tabs = ['open' => 'Offen', 'resolved' => 'Erledigt', 'dismissed' => 'Verworfen', 'all' => 'Alle']; + echo ''; + + if ( empty( $reports ) ) { + echo '

Keine Meldungen vorhanden.

'; + return; + } + + $reason_labels = [ + 'spam' => 'Spam / Werbung', 'harassment' => 'Belästigung', + 'inappropriate' => 'Unangemessen', 'misinformation' => 'Fehlinformation', + 'off-topic' => 'Offtopic', 'other' => 'Sonstiges', + ]; + $status_colors = ['open' => '#f59e0b', 'resolved' => '#56cf7e', 'dismissed' => '#6b7a99']; + + echo ' + '; + + foreach ( $reports as $r ) { + $reason_label = esc_html( $reason_labels[ $r->reason ] ?? $r->reason ); + $preview = esc_html( mb_substr( strip_tags( $r->post_content ?? '' ), 0, 80 ) ); + $sc = $status_colors[ $r->status ] ?? '#999'; + $status_badge = "" . esc_html( ucfirst( $r->status ) ) . ""; + $note_cell = $r->note ? '
' . esc_html( $r->note ) . '' : ''; + + $base = ['page' => 'wbf-reports', 'report_id' => $r->id, 'filter' => $filter]; + if ( $r->status === 'open' ) { + $res_url = esc_url( wp_nonce_url( add_query_arg( array_merge( $base, ['report_action' => 'resolved'] ), admin_url('admin.php') ), 'wbf_report_action' ) ); + $dis_url = esc_url( wp_nonce_url( add_query_arg( array_merge( $base, ['report_action' => 'dismissed'] ), admin_url('admin.php') ), 'wbf_report_action' ) ); + $actions = "✔ Erledigt "; + $actions .= "✖ Verwerfen"; + } else { + $reopen_url = esc_url( wp_nonce_url( add_query_arg( array_merge( $base, ['report_action' => 'open'] ), admin_url('admin.php') ), 'wbf_report_action' ) ); + $actions = "↩ Wieder öffnen"; + } + + echo " + + + + + + + + + "; + } + + echo '
#Gemeldet vonGrundVorschauThreadDatumStatusAktionen
" . esc_html( $r->id ) . "" . esc_html( $r->reporter_name ?? '—' ) . "
@" . esc_html( $r->reporter_username ?? '' ) . "
$reason_label$note_cell$preview…
+ → Zum Beitrag
" . ( $r->thread_id ? esc_html( mb_substr( $r->thread_title ?? '', 0, 35 ) ) : '—' ) . "" . esc_html( date( 'd.m.Y H:i', strtotime( $r->created_at ) ) ) . "$status_badge$actions
'; +} + +// ── Level-System ────────────────────────────────────────────────────────────── + +function wbf_admin_levels() { + + // ── Toggle on/off ──────────────────────────────────────────────────────── + if ( isset( $_POST['wbf_toggle_levels'] ) && check_admin_referer( 'wbf_levels_toggle_nonce' ) ) { + WBF_Levels::set_enabled( ! empty( $_POST['levels_enabled'] ) ); + echo '

Einstellung gespeichert!

'; + } + + // ── Reset ──────────────────────────────────────────────────────────────── + if ( isset( $_POST['wbf_reset_levels'] ) && check_admin_referer( 'wbf_levels_reset_nonce' ) ) { + WBF_Levels::reset_to_defaults(); + echo '

Level auf Standard zurückgesetzt.

'; + } + + // ── Level löschen ──────────────────────────────────────────────────────── + if ( isset( $_GET['delete_level'] ) && check_admin_referer( 'delete_level_' . (int) $_GET['delete_level'] ) ) { + $idx = (int) $_GET['delete_level']; + $levels = WBF_Levels::get_all(); + if ( count($levels) > 1 ) { + unset( $levels[$idx] ); + WBF_Levels::save( array_values($levels) ); + echo '

Level gelöscht.

'; + } else { + echo '

Mindestens ein Level muss vorhanden sein.

'; + } + } + + // ── Level speichern (Bearbeiten) ───────────────────────────────────────── + if ( isset( $_POST['wbf_save_level'] ) && check_admin_referer( 'wbf_levels_edit_nonce' ) ) { + $idx = (int) $_POST['level_index']; + $levels = WBF_Levels::get_all(); + $levels[$idx] = [ + 'min' => max( 0, (int) $_POST['level_min'] ), + 'label' => sanitize_text_field( $_POST['level_label'] ), + 'icon' => sanitize_text_field( $_POST['level_icon'] ), + 'color' => sanitize_hex_color( $_POST['level_color'] ) ?: '#94a3b8', + ]; + WBF_Levels::save( array_values($levels) ); + echo '

Level aktualisiert!

'; + } + + // ── Neues Level erstellen ──────────────────────────────────────────────── + if ( isset( $_POST['wbf_create_level'] ) && check_admin_referer( 'wbf_levels_create_nonce' ) ) { + $levels = WBF_Levels::get_all(); + $levels[] = [ + 'min' => max( 0, (int) $_POST['new_level_min'] ), + 'label' => sanitize_text_field( $_POST['new_level_label'] ), + 'icon' => sanitize_text_field( $_POST['new_level_icon'] ), + 'color' => sanitize_hex_color( $_POST['new_level_color'] ) ?: '#94a3b8', + ]; + WBF_Levels::save( $levels ); + echo '

Neues Level erstellt!

'; + } + + $levels = WBF_Levels::get_all(); + $enabled = WBF_Levels::is_enabled(); + $edit_i = isset( $_GET['edit_level'] ) ? (int) $_GET['edit_level'] : null; + $edit_l = ( $edit_i !== null && isset( $levels[$edit_i] ) ) ? $levels[$edit_i] : null; + + echo '
'; + echo '

⭐ Level-System

'; + + // ── Status-Toggle ──────────────────────────────────────────────────────── + $status_color = $enabled ? '#56cf7e' : '#f05252'; + $status_label = $enabled ? '✅ Aktiviert' : '❌ Deaktiviert'; + echo "
+
+ Level-System ist: + {$status_label} +

Wenn deaktiviert, werden keine Level-Badges im Forum angezeigt.

+
+
+ " . wp_nonce_field( 'wbf_levels_toggle_nonce', '_wpnonce', true, false ) . " + + +
+
"; + + // ── Level-Tabelle ──────────────────────────────────────────────────────── + echo '

Aktuelle Level

'; + echo ' + + + + + + + '; + + foreach ( $levels as $i => $l ) { + $color = esc_attr( $l['color'] ); + $icon = esc_attr( $l['icon'] ); + $label = esc_html( $l['label'] ); + $del_url = wp_nonce_url( "?page=wbf-levels&delete_level={$i}", "delete_level_{$i}" ); + $badge_html = " + {$label} + "; + + echo " + + + + + + "; + } + echo '
#Badge-VorschauAb BeiträgenIconAktionen
" . ( $i + 1 ) . "{$badge_html}≥ " . esc_html( $l['min'] ) . " Beiträge{$icon} + Bearbeiten + " . ( count($levels) > 1 ? " | Löschen" : '' ) . " +
'; + + // ── Reset-Button ───────────────────────────────────────────────────────── + echo "
+ " . wp_nonce_field( 'wbf_levels_reset_nonce', '_wpnonce', true, false ) . " + +
"; + + // ── Bearbeiten-Formular ────────────────────────────────────────────────── + if ( $edit_l !== null ) { + echo '

Level bearbeiten: ' . esc_html( $edit_l['label'] ) . '

'; + echo '
'; + wp_nonce_field( 'wbf_levels_edit_nonce' ); + echo ''; + echo wbf_level_form_fields( $edit_l, '' ); + echo '
'; + submit_button( 'Änderungen speichern', 'primary', 'wbf_save_level' ); + echo '

'; + } + + // ── Neues Level erstellen ──────────────────────────────────────────────── + echo '

Neues Level erstellen

'; + echo '
'; + wp_nonce_field( 'wbf_levels_create_nonce' ); + echo wbf_level_form_fields( null, 'new_' ); + echo '
'; + submit_button( '+ Level erstellen', 'primary', 'wbf_create_level' ); + echo '
'; + + echo '
'; +} + +// ── Hilfsformular für Level-Felder ──────────────────────────────────────────── + +function wbf_level_form_fields( $level, $prefix ) { + $min = esc_attr( $level['min'] ?? '' ); + $label = esc_attr( $level['label'] ?? '' ); + $icon = esc_attr( $level['icon'] ?? 'fas fa-star' ); + $color = esc_attr( $level['color'] ?? '#94a3b8' ); + + return " + + Ab Beiträgen * + + +

Level ab dieser Beitragsanzahl (0 = für alle).

+ + + + Bezeichnung * + + + + Farbe + + + + Icon + + +

FontAwesome 6, z.B. fas fa-crown, fas fa-fire, fas fa-seedling

+ + "; +} + + +// ── Export / Import ─────────────────────────────────────────────────────────── + +function wbf_admin_export() { + if ( ! current_user_can('manage_options') ) return; + + $notice = ''; + + // Export wird von admin_init verarbeitet (vor HTTP-Header-Output) + + // ── IMPORT ──────────────────────────────────────────────────────────────── + if ( isset( $_POST['wbf_do_import'] ) && check_admin_referer('wbf_import_nonce') ) { + + if ( empty( $_FILES['import_file']['tmp_name'] ) ) { + $notice = ['error', 'Keine Datei hochgeladen.']; + } else { + $raw = file_get_contents( $_FILES['import_file']['tmp_name'] ); + $data = json_decode( $raw, true ); + + if ( ! $data || ! isset($data['_meta']) ) { + $notice = ['error', 'Ungültige Datei — kein gültiges WBF-Backup.']; + } else { + global $wpdb; + $imported = []; + $sections = $data['_meta']['sections'] ?? array_keys($data); + + if ( ! empty($data['settings']) ) { + update_option('wbf_settings', $data['settings']); + $imported[] = 'Einstellungen'; + } + if ( ! empty($data['roles']) ) { + // Superadmin-Schutz: niemals überschreiben + $roles = $data['roles']; + unset($roles['superadmin']); + $current = get_option('wbf_custom_roles', []); + $current['superadmin'] = WBF_Roles::get('superadmin'); + update_option('wbf_custom_roles', array_merge($current, $roles)); + $imported[] = 'Rollen'; + } + if ( ! empty($data['levels']) ) { + if ( isset($data['levels']['config']) ) update_option('wbf_level_config', $data['levels']['config']); + if ( isset($data['levels']['enabled']) ) update_option('wbf_levels_enabled', $data['levels']['enabled']); + $imported[] = 'Level'; + } + if ( ! empty($data['categories']) ) { + // Nur importieren wenn Tabelle leer oder Force-Flag gesetzt + $force = ! empty($_POST['import_force_cats']); + $existing = (int)$wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}forum_categories"); + if ( $existing === 0 || $force ) { + if ($force) $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_categories"); + foreach ($data['categories'] as $cat) { + unset($cat['id']); // auto-increment + $wpdb->insert("{$wpdb->prefix}forum_categories", $cat); + } + $imported[] = 'Kategorien (' . count($data['categories']) . ')'; + } else { + $imported[] = 'Kategorien übersprungen (bereits vorhanden — „Überschreiben" aktivieren)'; + } + } + if ( ! empty($data['users']) ) { + $force = ! empty($_POST['import_force_users']); + $count = 0; + foreach ($data['users'] as $u) { + $exists = $wpdb->get_var($wpdb->prepare( + "SELECT id FROM {$wpdb->prefix}forum_users WHERE username=%s OR email=%s", + $u['username'], $u['email'] + )); + if ($exists && !$force) continue; + if ($exists && $force) { + unset($u['id']); + $wpdb->update("{$wpdb->prefix}forum_users", $u, ['id'=>$exists]); + } else { + unset($u['id']); + $u['role'] = ($u['role'] === 'superadmin') ? 'member' : $u['role']; + $wpdb->insert("{$wpdb->prefix}forum_users", $u); + } + $count++; + } + $imported[] = "Benutzer ($count importiert)"; + } + 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"); + } + foreach ($data['threads'] ?? [] as $t) { $wpdb->insert("{$wpdb->prefix}forum_threads", $t); } + foreach ($data['posts'] ?? [] as $p) { $wpdb->insert("{$wpdb->prefix}forum_posts", $p); } + // Re-import tags + if (!empty($data['thread_tags'])) { + $tag_map = []; + foreach ($data['thread_tags'] as $tt) { + if (!isset($tag_map[$tt['slug']])) { + $existing_tag = $wpdb->get_var($wpdb->prepare( + "SELECT id FROM {$wpdb->prefix}forum_tags WHERE slug=%s", $tt['slug'] + )); + if (!$existing_tag) { + $wpdb->insert("{$wpdb->prefix}forum_tags", [ + 'name'=>$tt['name'],'slug'=>$tt['slug'],'use_count'=>$tt['use_count'] + ]); + $tag_map[$tt['slug']] = $wpdb->insert_id; + } else { + $tag_map[$tt['slug']] = $existing_tag; + } + } + $wpdb->replace("{$wpdb->prefix}forum_thread_tags", [ + 'thread_id'=>$tt['thread_id'], 'tag_id'=>$tag_map[$tt['slug']] + ]); + } + } + $imported[] = 'Threads + Posts (' . count($data['threads']) . ' / ' . count($data['posts'] ?? []) . ')'; + } + + if ( ! empty($data['likes']) ) { + $force = ! empty($_POST['import_force_threads']); + if ($force) $wpdb->query("DELETE FROM {$wpdb->prefix}forum_likes"); + $count = 0; + foreach ($data['likes'] as $row) { + unset($row['id']); + $existing = $wpdb->get_var($wpdb->prepare( + "SELECT id FROM {$wpdb->prefix}forum_likes WHERE user_id=%d AND object_id=%d AND object_type=%s", + $row['user_id'], $row['object_id'], $row['object_type'] + )); + if (!$existing) { $wpdb->insert("{$wpdb->prefix}forum_likes", $row); $count++; } + } + $imported[] = "Likes ($count)"; + } + if ( ! empty($data['reactions']) ) { + $force = ! empty($_POST['import_force_threads']); + if ($force) $wpdb->query("DELETE FROM {$wpdb->prefix}forum_reactions"); + foreach ($data['reactions'] as $row) { + unset($row['id']); + $wpdb->replace("{$wpdb->prefix}forum_reactions", $row); + } + $imported[] = 'Reaktionen (' . count($data['reactions']) . ')'; + } + if ( ! empty($data['notifications']) ) { + $force = ! empty($_POST['import_force_threads']); + if ($force) $wpdb->query("DELETE FROM {$wpdb->prefix}forum_notifications"); + $count = 0; + foreach ($data['notifications'] as $row) { + unset($row['id']); + $wpdb->insert("{$wpdb->prefix}forum_notifications", $row); + $count++; + } + $imported[] = "Benachrichtigungen ($count)"; + } + if ( ! empty($data['messages']) ) { + $force = ! empty($_POST['import_force_messages']); + if ($force) $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_messages"); + $count = 0; + foreach ($data['messages'] as $row) { + unset($row['id']); + $wpdb->insert("{$wpdb->prefix}forum_messages", $row); + $count++; + } + $imported[] = "Nachrichten ($count)"; + } + if ( ! empty($data['reports']) ) { + $force = ! empty($_POST['import_force_reports']); + if ($force) $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}forum_reports"); + $count = 0; + foreach ($data['reports'] as $row) { + unset($row['id']); + $wpdb->insert("{$wpdb->prefix}forum_reports", $row); + $count++; + } + $imported[] = "Meldungen ($count)"; + } + + if ( empty($imported) ) { + $notice = ['warning', 'Nichts importiert — Datei enthielt keine gültigen Abschnitte.']; + } else { + $notice = ['success', '✅ Importiert: ' . implode(', ', $imported) . '. Erstellt: ' . $data['_meta']['exported'] . ' · Site: ' . esc_html($data['_meta']['site'] ?? '?')]; + } + } + } + } + + // ── UI ───────────────────────────────────────────────────────────────────── + ?> +
+

+ + Export / Import +

+ + +

+ + +
+ + +
+
+ + Export +
+
+

Wähle was exportiert werden soll. Die Datei wird als .json heruntergeladen.

+
+ + + ['⚙️', 'Einstellungen', 'Forum-Texte, Auto-Logout, Labels'], + 'roles' => ['🛡️', 'Rollen', 'Alle Rollen inkl. Berechtigungen & Farben'], + 'levels' => ['⭐', 'Level-System', 'Level-Konfiguration & Status'], + 'categories' => ['📂', 'Kategorien', 'Alle Kategorien inkl. Hierarchie'], + 'users' => ['👥', 'Benutzer', 'Accounts inkl. Passwort-Hashes'], + 'threads' => ['💬', 'Threads & Posts', 'Alle Inhalte inkl. Tags'], + 'interactions' => ['❤️', 'Likes & Reaktionen', 'Likes, Reaktionen, Benachrichtigungen'], + 'messages' => ['✉️', 'Privatnachrichten', 'Alle DM-Konversationen'], + 'reports' => ['🚩', 'Meldungen', 'Alle gemeldeten Beiträge'], + ]; + foreach ($export_options as $key => [$icon, $label, $desc]): + ?> + + + + + + +
+ + + + +
+
+ + Datei wird sofort heruntergeladen +
+
+
+
+ + +
+
+ + Import +
+
+

Lade eine zuvor exportierte .json-Datei hoch.

+ +
+ ⚠️ Hinweis: Benutzer-Import enthält Passwort-Hashes. Threads-Import kann bestehende Daten überschreiben. Mache vorher ein Backup. +
+ +
+ +
+ + +
+ +
+

Überschreiben-Optionen

+ 'Kategorien überschreiben (löscht bestehende)', + 'import_force_users' => 'Benutzer aktualisieren (bei gleichem Username)', + 'import_force_threads' => 'Threads, Posts, Likes & Reaktionen überschreiben', + 'import_force_messages' => 'Privatnachrichten überschreiben', + 'import_force_reports' => 'Meldungen überschreiben', + ]; + foreach ($overwrite_opts as $name => $label): ?> + + +
+ +
+ + Nur kompatible WBF-Backups +
+
+
+
+
+ + +
+

+ + Export-Inhalte im Überblick +

+
+ +
+ + +
+ +
+
+
+ 'Community Forum', + 'hero_subtitle' => 'Diskutiere, teile Ideen und bleib immer informiert.', + // Topbar + 'topbar_brand' => 'Community', + // Statistik-Labels + 'stat_threads' => 'Threads', + 'stat_posts' => 'Beiträge', + 'stat_members' => 'Mitglieder', + // Abschnitt-Überschriften + 'section_cats' => 'Kategorien', + 'section_recent' => 'Neue Threads', + // Buttons + 'btn_new_thread' => 'Neuer Thread', + 'btn_login' => 'Einloggen', + 'btn_register' => 'Registrieren', + 'btn_logout' => 'Logout', + // Sidebar + 'sidebar_profile' => 'Mein Profil', + 'sidebar_login' => 'Login / Registrieren', + // Sicherheit + 'auto_logout_minutes' => '30', + ]; + + $saved = get_option( 'wbf_settings', [] ); + + // Fehlende Keys mit Defaults auffüllen, leere Strings ignorieren + return array_merge( $defaults, array_filter( (array) $saved, 'strlen' ) ); + } +} + +// ── Admin-Seite ─────────────────────────────────────────────────────────────── + +if ( ! function_exists('wbf_admin_settings') ) { +function wbf_admin_settings() { + + // Speichern + if ( isset( $_POST['wbf_save_settings'] ) && check_admin_referer( 'wbf_settings_nonce' ) ) { + + $fields = [ + 'hero_title', 'hero_subtitle', + 'topbar_brand', + 'stat_threads', 'stat_posts', 'stat_members', + 'section_cats', 'section_recent', + 'btn_new_thread', 'btn_login', 'btn_register', 'btn_logout', + 'sidebar_profile', 'sidebar_login', + 'auto_logout_minutes', + ]; + + $settings = []; + foreach ( $fields as $key ) { + $settings[ $key ] = sanitize_text_field( $_POST[ $key ] ?? '' ); + } + + update_option( 'wbf_settings', $settings ); + echo '

✅ Einstellungen gespeichert!

'; + } + + $s = wbf_get_settings(); + + // Inline-Hilfsfunktion für eine Tabellenzeile + $row = function( $label, $name, $placeholder, $desc = '' ) use ( $s ) { + $val = esc_attr( $s[ $name ] ?? '' ); + echo " + + + + + " . ( $desc ? "

{$desc}

" : '' ) . " + + "; + }; + + ?> +
+

⚙️ Forum-Einstellungen

+

+ Alle sichtbaren Texte des Forums — kein Code nötig. +

+ +
+ + + +

+ 🏠 Hero-Bereich (Startseite) +

+ + + + + + +

+ 🔝 Topbar (Navigationsleiste) +

+ + + + + + + + +

+ 📊 Statistik-Labels +

+ + + + + + + +

+ 📂 Abschnitt-Überschriften +

+ + + + + + + +

+ 👤 Sidebar +

+ + + + + + +

+ 🔒 Sicherheit +

+ + + + + + + + 'margin-top:1rem' ] + ); ?> +
+ + +
+

📋 Aktuelle Werte

+ + + + + + $val ): ?> + + + + + + +
SchlüsselAktueller Wert
+
+ get_var( + "SELECT COUNT(*) FROM {$wpdb->prefix}forum_users WHERE role='superadmin'" + ); + return (int)$count > 0; + } + + /** Hinweisbanner solange kein Superadmin existiert */ + public static function setup_notice() { + if ( self::superadmin_exists() ) return; + if ( isset($_GET['page']) && $_GET['page'] === 'wbf-setup' ) return; + if ( ! current_user_can('manage_options') ) return; + echo '
+ ⚙️ +
+ WP Business Forum — Einrichtung noch nicht abgeschlossen. + Jetzt einrichten +
+
'; + } + + /** Versteckte Admin-Seite für den Wizard */ + public static function register_page() { + add_submenu_page( + null, // kein Menüeintrag — nur direkt aufrufbar + 'Forum Einrichtung', + 'Forum Einrichtung', + 'manage_options', + 'wbf-setup', + [ __CLASS__, 'render_page' ] + ); + } + + /** Wizard verarbeiten & anzeigen */ + public static function render_page() { + $step = (int)( $_GET['step'] ?? 1 ); + $error = ''; + $success = ''; + + // ── Schritt 1: Superadmin-Konto erstellen ───────────────────────────── + if ( $step === 1 && isset($_POST['wbf_setup_step1']) && check_admin_referer('wbf_setup_nonce') ) { + + $username = sanitize_user( $_POST['username'] ?? '' ); + $display_name = sanitize_text_field( $_POST['display_name'] ?? '' ); + $email = sanitize_email( $_POST['email'] ?? '' ); + $password = $_POST['password'] ?? ''; + $password2 = $_POST['password2'] ?? ''; + + if ( strlen($username) < 3 ) $error = 'Benutzername mindestens 3 Zeichen.'; + elseif ( empty($display_name) ) $error = 'Anzeigename darf nicht leer sein.'; + elseif ( ! is_email($email) ) $error = 'Ungültige E-Mail-Adresse.'; + elseif ( strlen($password) < 6 ) $error = 'Passwort mindestens 6 Zeichen.'; + elseif ( $password !== $password2) $error = 'Passwörter stimmen nicht überein.'; + elseif ( WBF_DB::get_user_by('username', $username) ) $error = 'Benutzername bereits vergeben.'; + elseif ( WBF_DB::get_user_by('email', $email) ) $error = 'E-Mail bereits registriert. Bestehendes Konto als Superadmin setzen?'; + + if ( ! $error ) { + $avatar = 'https://www.gravatar.com/avatar/' . md5(strtolower($email)) . '?d=identicon&s=120'; + $id = WBF_DB::create_user([ + 'username' => $username, + 'email' => $email, + 'password' => password_hash($password, PASSWORD_DEFAULT), + 'display_name' => $display_name, + 'avatar_url' => $avatar, + 'role' => 'superadmin', + ]); + if ($id) { + update_option('wbf_superadmin_email', $email); + wp_redirect( admin_url('admin.php?page=wbf-setup&step=2') ); + exit; + } else { + $error = 'Fehler beim Erstellen des Kontos. Bitte versuche es erneut.'; + } + } + } + + // ── Bestehendes Konto hochstufen ────────────────────────────────────── + if ( $step === 1 && isset($_POST['wbf_setup_promote']) && check_admin_referer('wbf_setup_nonce') ) { + $email = sanitize_email($_POST['existing_email'] ?? ''); + $user = WBF_DB::get_user_by('email', $email); + if ($user) { + WBF_DB::update_user($user->id, ['role' => 'superadmin']); + update_option('wbf_superadmin_email', $email); + wp_redirect( admin_url('admin.php?page=wbf-setup&step=2') ); + exit; + } else { + $error = 'Kein Forum-Konto mit dieser E-Mail gefunden.'; + } + } + + // ── Schritt 2: Forum-Seite erstellen (optional) ─────────────────────── + if ( $step === 2 && isset($_POST['wbf_setup_step2']) && check_admin_referer('wbf_setup_nonce') ) { + $create_page = ! empty($_POST['create_forum_page']); + $page_title = sanitize_text_field($_POST['page_title'] ?? 'Forum'); + + if ($create_page) { + $existing = get_posts(['post_type'=>'page','s'=>$page_title,'posts_per_page'=>1]); + if (empty($existing)) { + $page_id = wp_insert_post([ + 'post_title' => $page_title, + 'post_content' => '[business_forum]', + 'post_status' => 'publish', + 'post_type' => 'page', + ]); + if ($page_id) { + update_option('wbf_forum_page_id', $page_id); + $success = get_permalink($page_id); + } + } else { + $success = get_permalink($existing[0]->ID); + } + } + update_option(self::OPTION_DONE, true); + wp_redirect( admin_url('admin.php?page=wbf-setup&step=3&forum_url='.urlencode($success)) ); + exit; + } + + // ── Schritt 3: Überspringen ─────────────────────────────────────────── + if ( $step === 3 ) { + update_option(self::OPTION_DONE, true); + } + + self::render_wizard($step, $error, isset($_GET['use_existing'])); + } + + private static function render_wizard($step, $error = '', $show_promote = false) { + $wp_user = wp_get_current_user(); + $forum_url = urldecode($_GET['forum_url'] ?? ''); + $forum_page = get_option('wbf_forum_page_id') ? get_permalink(get_option('wbf_forum_page_id')) : ''; + ?> + + + + +Forum Einrichtung + + + +
+ +
+ +
+
1 · Superadmin
+
2 · Forum-Seite
+
3 · Fertig
+
+
+ +
+ + +
⚠️
+ + + + +

Dein Superadmin-Konto

+

Erstelle dein persönliches Forum-Konto. Als WordPress-Administrator bekommst du automatisch die Superadmin-Rolle — dauerhaft und unveränderlich.

+ +
👑 Superadmin wird automatisch zugewiesen
+ +
+ +
+
+ + +

↑ Aus deinem WP-Konto vorausgefüllt

+
+
+ + +
+
+
+ + +

Nutze deine WP-Admin-E-Mail — das verknüpft dein Forum-Konto dauerhaft mit dem Superadmin-Status.

+
+
+
+ + +
+
+ + +
+
+ +
+ +
oder
+ +
+ + + + +
+ + + +

Bestehendes Konto hochstufen

+

Gib die E-Mail-Adresse deines vorhandenen Forum-Kontos ein. Es wird sofort auf Superadmin hochgestuft.

+ +
+ +
+ + +
+ +
+ +
+ + + +
+ + + +
✓ Superadmin-Konto erstellt!
+ +

Forum-Seite einrichten

+

Soll eine WordPress-Seite mit dem Forum-Shortcode automatisch erstellt werden?

+ +
+ + +
+ + +
+ +
+ +
+ + +
+ + + +
+
🎉
+

Forum ist bereit!

+

Dein Superadmin-Konto ist aktiv. Das Forum ist einsatzbereit — viel Spaß mit deiner Community!

+
+ + + + + + + + Zum Forum-Dashboard → + + + + +
+
+ + +