Files
WP-Business-Forum/includes/class-forum-roles.php
2026-03-29 22:25:37 +02:00

228 lines
9.0 KiB
PHP

<?php
if ( ! defined( 'ABSPATH' ) ) exit;
/**
* WBF_Roles — Dynamisches Rollensystem
* Rollen werden in wp_options gespeichert und können im Admin verwaltet werden.
* Der Superadmin ist immer an den WP-Administrator gebunden und kann nicht geändert werden.
*/
class WBF_Roles {
const OPTION_KEY = 'wbf_custom_roles';
const SUPERADMIN = 'superadmin';
/** Standard-Rollen beim ersten Aktivieren */
private static function default_roles() {
return [
'superadmin' => [
'label' => 'Admin',
'level' => 100,
'color' => '#e11d48',
'bg_color' => 'rgba(225,29,72,.15)',
'icon' => 'fas fa-crown',
'permissions' => ['all'],
'locked' => true, // unveränderlich
'description' => 'Vollständige Kontrolle — immer an den WordPress-Admin gebunden.',
],
'admin' => [
'label' => 'Admin',
'level' => 80,
'color' => '#f87171',
'bg_color' => 'rgba(248,113,113,.13)',
'icon' => 'fas fa-shield-halved',
'permissions' => ['post','create_thread','like','pin_thread','close_thread','delete_post','delete_thread','manage_users','manage_cats','post_announcement'],
'locked' => false,
'description' => 'Volle Moderations- und Verwaltungsrechte.',
],
'moderator' => [
'label' => 'Moderator',
'level' => 50,
'color' => '#fbbf24',
'bg_color' => 'rgba(251,191,36,.12)',
'icon' => 'fas fa-shield',
'permissions' => ['post','create_thread','like','pin_thread','close_thread','delete_post','delete_thread','post_announcement'],
'locked' => false,
'description' => 'Kann Threads & Posts moderieren.',
],
'vip' => [
'label' => 'VIP',
'level' => 20,
'color' => '#38bdf8',
'bg_color' => 'rgba(56,189,248,.12)',
'icon' => 'fas fa-star',
'permissions' => ['post','create_thread','like'],
'locked' => false,
'description' => 'VIP-Mitglied mit besonderem Badge.',
],
'member' => [
'label' => 'Member',
'level' => 10,
'color' => '#94a3b8',
'bg_color' => 'rgba(148,163,184,.1)',
'icon' => 'fas fa-user',
'permissions' => ['post','create_thread','like'],
'locked' => false,
'description' => 'Standard-Mitglied.',
],
'banned' => [
'label' => 'Gesperrt',
'level' => -1,
'color' => '#475569',
'bg_color' => 'rgba(71,85,105,.2)',
'icon' => 'fas fa-ban',
'permissions' => [],
'locked' => false,
'description' => 'Kein Forum-Zugang.',
],
];
}
/** Alle Rollen laden (aus DB oder Defaults) */
public static function get_all() {
$saved = get_option(self::OPTION_KEY, null);
if ( $saved === null ) {
$defaults = self::default_roles();
update_option(self::OPTION_KEY, $defaults);
return $defaults;
}
// Superadmin immer aus defaults übernehmen (kann nicht manipuliert werden)
$saved[self::SUPERADMIN] = self::default_roles()[self::SUPERADMIN];
return $saved;
}
/** Einzelne Rolle */
public static function get( $key ) {
$all = self::get_all();
return $all[$key] ?? $all['member'];
}
/** Alle verfügbaren Rollen als key=>label Array */
public static function labels() {
$out = [];
foreach ( self::get_sorted() as $key => $role ) {
$out[$key] = $role['label'];
}
return $out;
}
/** Nach Level sortiert (höchstes zuerst) */
public static function get_sorted() {
$all = self::get_all();
uasort($all, function($a, $b) { return $b['level'] <=> $a['level']; });
return $all;
}
/** Rolle speichern / erstellen */
public static function save( $key, $data ) {
if ( $key === self::SUPERADMIN ) return false; // nie überschreiben
$all = self::get_all();
$all[$key] = $data;
update_option(self::OPTION_KEY, $all);
return true;
}
/** Rolle löschen */
public static function delete( $key ) {
if ( $key === self::SUPERADMIN ) return false;
if ( $key === 'member' ) return false; // member darf nicht gelöscht werden
$all = self::get_all();
unset($all[$key]);
update_option(self::OPTION_KEY, $all);
// Alle Nutzer dieser Rolle zu 'member' degradieren
global $wpdb;
$wpdb->update("{$wpdb->prefix}forum_users", ['role'=>'member'], ['role'=>$key]);
return true;
}
/** Level einer Rolle */
public static function level( $key ) {
return (int)( self::get($key)['level'] ?? 10 );
}
/** Hat Rolle eine bestimmte Permission? */
public static function has_permission( $role_key, $permission ) {
$role = self::get($role_key);
$perms = $role['permissions'] ?? [];
return in_array('all', $perms) || in_array($permission, $perms);
}
/** Darf User eine Aktion ausführen? */
public static function can( $user, $action ) {
if ( ! $user ) return false;
// Superadmin — immer alles erlaubt
if ( $user->role === self::SUPERADMIN ) return true;
if ( self::level($user->role) < 0 ) return false; // banned
return self::has_permission($user->role, $action);
}
/** Darf User in Kategorie posten? */
public static function can_post_in( $user, $cat ) {
if ( ! $user ) return false;
if ( $user->role === self::SUPERADMIN ) return true;
$min = $cat->min_role ?? 'member';
return self::level($user->role) >= self::level($min);
}
/** Badge HTML */
public static function badge( $role_key ) {
$role = self::get($role_key);
$label = esc_html($role['label']);
$color = esc_attr($role['color']);
$bg = esc_attr($role['bg_color']);
$icon = esc_attr($role['icon'] ?? 'fas fa-user');
$border = esc_attr($role['color']);
return "<span class=\"wbf-role-badge\" style=\"color:{$color};background:{$bg};border-color:{$border}\">
<i class=\"{$icon}\"></i> {$label}
</span>";
}
/** Alle erlaubten Permissions (für Checkboxen im Admin) */
public static function all_permissions() {
return [
'post' => 'Beiträge schreiben',
'create_thread' => 'Threads erstellen',
'like' => 'Beiträge liken',
'pin_thread' => 'Threads pinnen',
'close_thread' => 'Threads schließen',
'delete_post' => 'Posts löschen',
'delete_thread' => 'Threads löschen',
'manage_users' => 'Nutzer verwalten',
'manage_cats' => 'Kategorien verwalten',
'post_announcement' => 'Ankündigungen posten',
];
}
/**
* Gibt die WP-User-ID des echten Superadmins zurück.
* Das ist immer der bei der WordPress-Installation angelegte erste Nutzer (ID 1).
* Alle anderen WP-Administratoren sind KEINE Forum-Superadmins.
*/
public static function get_wp_superadmin_id() {
// Primär: gespeicherte ID aus den Plugin-Einstellungen (falls manuell überschrieben)
$saved_id = (int) get_option( 'wbf_superadmin_wp_id', 0 );
if ( $saved_id > 0 ) return $saved_id;
// Fallback: WP-Installations-User (ID 1)
return 1;
}
/** Ist der aktuelle eingeloggte WP-User der echte Superadmin (nur ID 1 bzw. gespeicherte ID)? */
public static function is_wp_superadmin() {
if ( ! is_user_logged_in() ) return false;
return get_current_user_id() === self::get_wp_superadmin_id();
}
/**
* Superadmin-Status erzwingen — aber NUR für den einen echten WP-Superadmin (ID 1).
* Alle anderen WP-Admins können normale Forum-Rollen haben und behalten diese auch.
*/
public static function sync_superadmin() {
if ( ! is_user_logged_in() ) return;
if ( ! self::is_wp_superadmin() ) return; // nur ID 1 kommt durch
$wp_user = wp_get_current_user();
$forum_user = WBF_DB::get_user_by( 'email', $wp_user->user_email );
if ( $forum_user && $forum_user->role !== self::SUPERADMIN ) {
WBF_DB::update_user( $forum_user->id, [ 'role' => self::SUPERADMIN ] );
}
}
}