Files
Wordpress-MC-Gallery/includes/class-mc-gallery-forum-bridge.php
2026-03-29 13:35:46 +02:00

691 lines
31 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
if ( ! defined( 'ABSPATH' ) ) exit;
/**
* MC_Gallery_Forum_Bridge
*
* Optionale Integration zwischen MC MultiServer Gallery PRO und WP Business Forum.
* Wird nur initialisiert wenn beide Plugins aktiv sind (class_exists-Check).
*
* Features:
* - Forum-User können ihren Minecraft-Account im Profil verknüpfen
* - Verknüpfte + verifizierte User können in der Galerie ohne Ingame-Token hochladen
* - Admin kann Verknüpfungen in der Forum-Benutzerverwaltung einsehen & bestätigen
* - Automatische Verifikation wenn ein gültiger Ingame-Token für diesen MC-Namen vorliegt
*
* Datenspeicherung: forum_user_meta (bereits vorhanden im Forum-Schema)
*/
class MC_Gallery_Forum_Bridge {
// Meta-Keys (gespeichert in forum_user_meta)
const META_MC_USER = 'mc_linked_username';
const META_MC_SERVER = 'mc_linked_server';
const META_VERIFIED = 'mc_link_verified';
const NONCE_ACTION = 'mc_gallery_forum_bridge';
// ── Bootstrap ─────────────────────────────────────────────────────────────
public static function init() {
// Nur laden wenn beide Plugins aktiv sind
if ( ! class_exists( 'WBF_Auth' ) || ! class_exists( 'MC_Gallery_Helpers' ) ) {
return;
}
// AJAX-Handler
add_action( 'wp_ajax_mc_forum_link_account', [ __CLASS__, 'ajax_link_account' ] );
add_action( 'wp_ajax_mc_forum_unlink_account', [ __CLASS__, 'ajax_unlink_account' ] );
add_action( 'wp_ajax_mc_forum_verify_upload', [ __CLASS__, 'ajax_verify_upload' ] );
add_action( 'wp_ajax_nopriv_mc_forum_verify_upload', [ __CLASS__, 'ajax_verify_upload' ] );
add_action( 'wp_ajax_mc_forum_admin_approve', [ __CLASS__, 'ajax_admin_approve' ] );
// Hooks in die Gallery-Ausgabe (sofern vorhanden)
add_filter( 'mc_gallery_verify_ui_extra', [ __CLASS__, 'render_verify_panel' ], 10, 2 );
add_filter( 'mc_gallery_can_upload', [ __CLASS__, 'filter_upload_permission' ], 10, 3 );
// Hooks ins Forum
add_filter( 'wbf_profile_tabs', [ __CLASS__, 'add_profile_tab' ], 10, 2 );
add_filter( 'wbf_profile_tab_content', [ __CLASS__, 'render_profile_tab' ], 10, 3 );
add_action( 'wbf_admin_user_row_extra',[ __CLASS__, 'render_admin_user_col' ] );
// CSS laden
add_action( 'wp_enqueue_scripts', [ __CLASS__, 'enqueue_assets' ] );
add_action( 'admin_enqueue_scripts', [ __CLASS__, 'enqueue_assets' ] );
}
public static function enqueue_assets() {
wp_enqueue_style(
'mc-gallery-forum-bridge',
MCGALLERY_PRO_URL . 'assets/css/mc-gallery-forum-bridge.css',
[],
MCGALLERY_PRO_VERSION
);
}
// ── Forum-Profil: Minecraft-Tab ───────────────────────────────────────────
/**
* Neuen Tab "Minecraft" zum Forum-Profil hinzufügen.
* Erwartet dass WBF einen `wbf_profile_tabs`-Filter anbietet.
* Falls nicht: Tab wird ignoriert, kein Fehler.
*/
public static function add_profile_tab( $tabs, $profile_user ) {
$tabs['minecraft'] = [
'label' => '<i class="fas fa-cubes"></i> Minecraft',
'order' => 50,
];
return $tabs;
}
public static function render_profile_tab( $content, $tab, $profile_user ) {
if ( $tab !== 'minecraft' ) return $content;
$current = WBF_Auth::get_current_user();
$is_own = $current && (int) $current->id === (int) $profile_user->id;
$is_mod = $current && WBF_Roles::can( $current, 'manage_users' );
$mc_user = self::get_mc_username( $profile_user->id );
$verified = self::is_verified( $profile_user->id );
$servers = self::get_server_list();
ob_start();
?>
<div class="mc-bridge-profile-tab">
<?php if ( $mc_user ) : ?>
<div class="mc-bridge-linked-card <?php echo $verified ? 'is-verified' : 'is-pending'; ?>">
<img class="mc-bridge-head"
src="https://mc-heads.net/avatar/<?php echo esc_attr( $mc_user ); ?>/48"
alt="" loading="lazy">
<div class="mc-bridge-linked-info">
<span class="mc-bridge-mc-name"><?php echo esc_html( $mc_user ); ?></span>
<?php if ( $verified ) : ?>
<span class="mc-bridge-badge mc-bridge-badge--ok">
<i class="fas fa-check-circle"></i> Verifiziert
</span>
<?php else : ?>
<span class="mc-bridge-badge mc-bridge-badge--wait">
<i class="fas fa-clock"></i> Ausstehend
</span>
<?php endif; ?>
<?php
$sv = self::get_mc_server( $profile_user->id );
if ( $sv ) echo '<span class="mc-bridge-server-hint"><i class="fas fa-server"></i> ' . esc_html( $sv ) . '</span>';
?>
</div>
<?php if ( $is_own || $is_mod ) : ?>
<div class="mc-bridge-actions">
<?php if ( ! $verified && $is_mod ) : ?>
<button type="button" class="mc-bridge-btn mc-bridge-btn--approve"
data-uid="<?php echo (int) $profile_user->id; ?>"
data-nonce="<?php echo wp_create_nonce( self::NONCE_ACTION ); ?>">
<i class="fas fa-check"></i> Bestätigen
</button>
<?php endif; ?>
<?php if ( $is_own ) : ?>
<button type="button" class="mc-bridge-btn mc-bridge-btn--unlink"
data-nonce="<?php echo wp_create_nonce( self::NONCE_ACTION ); ?>">
<i class="fas fa-unlink"></i> Trennen
</button>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php if ( $is_own && ! $verified ) : ?>
<div class="mc-bridge-pending-hint">
<i class="fas fa-info-circle"></i>
Noch nicht verifiziert. Du kannst entweder auf Admin-Bestätigung warten
oder deinen Ingame-Token normal in der Galerie eingeben — dann wird
die Verknüpfung automatisch bestätigt.
</div>
<?php endif; ?>
<?php elseif ( $is_own ) : ?>
<p class="mc-bridge-intro">
Verknüpfe deinen Minecraft-Account mit deinem Forum-Profil.
Danach kannst du Bilder in der Galerie ohne Ingame-Token hochladen.
</p>
<div class="mc-bridge-link-form">
<label>
<span>Minecraft-Benutzername</span>
<input type="text" id="mc-bridge-username"
placeholder="z. B. MvViper123" maxlength="32" autocomplete="off">
</label>
<?php if ( count( $servers ) > 1 ) : ?>
<label>
<span>Server</span>
<select id="mc-bridge-server">
<?php foreach ( $servers as $sid => $sname ) : ?>
<option value="<?php echo esc_attr( $sid ); ?>">
<?php echo esc_html( $sname ); ?>
</option>
<?php endforeach; ?>
</select>
</label>
<?php else :
$first_key = array_key_first( $servers );
echo '<input type="hidden" id="mc-bridge-server" value="' . esc_attr( $first_key ) . '">';
endif; ?>
<button type="button" class="mc-bridge-btn mc-bridge-btn--link"
data-nonce="<?php echo wp_create_nonce( self::NONCE_ACTION ); ?>">
<i class="fas fa-link"></i> Verknüpfen
</button>
</div>
<?php else : ?>
<p class="mc-bridge-intro">Kein Minecraft-Account verknüpft.</p>
<?php endif; ?>
</div>
<script>
(function($){
// Account verknüpfen
$('.mc-bridge-btn--link').on('click', function(){
var mc = $('#mc-bridge-username').val().trim();
var sv = $('#mc-bridge-server').val() || '';
if ( ! mc ) { alert('Bitte einen Minecraft-Namen eingeben.'); return; }
var $btn = $(this).prop('disabled', true).text('Bitte warten…');
$.post(<?php echo json_encode( admin_url('admin-ajax.php') ); ?>, {
action: 'mc_forum_link_account',
mc_username: mc,
server_id: sv,
nonce: $btn.data('nonce')
})
.done(function(r){
if ( r.success ) location.reload();
else { alert(r.data || 'Fehler beim Verknüpfen.'); $btn.prop('disabled', false).html('<i class="fas fa-link"></i> Verknüpfen'); }
})
.fail(function(){ alert('Netzwerkfehler.'); $btn.prop('disabled', false).html('<i class="fas fa-link"></i> Verknüpfen'); });
});
// Trennen
$('.mc-bridge-btn--unlink').on('click', function(){
if ( ! confirm('Minecraft-Konto wirklich trennen?') ) return;
$.post(<?php echo json_encode( admin_url('admin-ajax.php') ); ?>, {
action: 'mc_forum_unlink_account',
nonce: $(this).data('nonce')
})
.done(function(r){
if ( r.success ) location.reload();
else alert(r.data || 'Fehler.');
});
});
// Admin: Bestätigen
$('.mc-bridge-btn--approve').on('click', function(){
var uid = $(this).data('uid');
var nonce = $(this).data('nonce');
var $btn = $(this).prop('disabled', true);
$.post(<?php echo json_encode( admin_url('admin-ajax.php') ); ?>, {
action: 'mc_forum_admin_approve',
user_id: uid,
nonce: nonce
})
.done(function(r){
if ( r.success ) location.reload();
else { alert(r.data || 'Fehler.'); $btn.prop('disabled', false); }
});
});
})(jQuery);
</script>
<?php
return ob_get_clean();
}
// ── AJAX-Handler ──────────────────────────────────────────────────────────
/** Account verknüpfen (eigenes Profil) */
public static function ajax_link_account() {
check_ajax_referer( self::NONCE_ACTION, 'nonce' );
$user = WBF_Auth::get_current_user();
if ( ! $user ) wp_send_json_error( 'Nicht eingeloggt.' );
$mc_user = sanitize_text_field( $_POST['mc_username'] ?? '' );
$server = sanitize_text_field( $_POST['server_id'] ?? '' );
// Validierung
if ( strlen( $mc_user ) < 2 || strlen( $mc_user ) > 32 ) {
wp_send_json_error( 'Ungültiger Minecraft-Name (232 Zeichen).' );
}
if ( ! preg_match( '/^[a-zA-Z0-9_]+$/', $mc_user ) ) {
wp_send_json_error( 'Nur Buchstaben, Zahlen und _ erlaubt.' );
}
// Doppelte Verknüpfung verhindern
if ( self::mc_user_taken( $mc_user, $user->id ) ) {
wp_send_json_error( 'Dieser Minecraft-Name ist bereits mit einem anderen Forum-Konto verknüpft.' );
}
self::set_mc_username( $user->id, $mc_user );
self::set_mc_server( $user->id, $server );
// Verifizierung: automatisch wenn gültiger Ingame-Token vorliegt
$auto_verified = self::check_active_token_for( $mc_user );
self::set_verified( $user->id, $auto_verified );
wp_send_json_success( [
'mc_username' => $mc_user,
'verified' => $auto_verified,
] );
}
/** Account-Verknüpfung trennen */
public static function ajax_unlink_account() {
check_ajax_referer( self::NONCE_ACTION, 'nonce' );
$user = WBF_Auth::get_current_user();
if ( ! $user ) wp_send_json_error( 'Nicht eingeloggt.' );
self::delete_mc_link( $user->id );
wp_send_json_success();
}
/** Admin bestätigt eine ausstehende Verknüpfung */
public static function ajax_admin_approve() {
check_ajax_referer( self::NONCE_ACTION, 'nonce' );
$current = WBF_Auth::get_current_user();
if ( ! $current || ! WBF_Roles::can( $current, 'manage_users' ) ) {
wp_send_json_error( 'Keine Berechtigung.' );
}
$target_id = (int) ( $_POST['user_id'] ?? 0 );
if ( ! $target_id ) wp_send_json_error( 'Ungültige Benutzer-ID.' );
self::set_verified( $target_id, true );
wp_send_json_success();
}
/**
* Galerie-Verify via Forum-Login.
* Wird vom Frontend aufgerufen wenn der User auf "Mit Forum-Login verifizieren" klickt.
* Gibt bei Erfolg MC-Username + Server zurück, die das Gallery-JS dann als würden
* sie aus einem Token-Verify stammen weiterverarbeiten kann.
*/
public static function ajax_verify_upload() {
check_ajax_referer( self::NONCE_ACTION, 'nonce' );
$forum_user = WBF_Auth::get_current_user();
if ( ! $forum_user ) {
wp_send_json_error( [
'code' => 'not_logged_in',
'message' => 'Du musst im Forum eingeloggt sein.',
] );
}
$mc_user = self::get_mc_username( $forum_user->id );
$verified = self::is_verified( $forum_user->id );
if ( ! $mc_user ) {
wp_send_json_error( [
'code' => 'no_mc_link',
'message' => 'Kein Minecraft-Konto verknüpft. Bitte zuerst im Profil verknüpfen.',
] );
}
// Noch nicht verifiziert → Ingame-Token als letzten Ausweg prüfen
if ( ! $verified ) {
if ( self::check_active_token_for( $mc_user ) ) {
self::set_verified( $forum_user->id, true );
$verified = true;
}
}
if ( ! $verified ) {
wp_send_json_error( [
'code' => 'not_verified',
'message' => 'Dein Account ist noch nicht verifiziert. Bitte einen Admin um Bestätigung oder nutze einmalig das Ingame-Token.',
] );
}
$server_id = self::get_mc_server( $forum_user->id )
?: sanitize_text_field( $_POST['server_id'] ?? '' );
wp_send_json_success( [
'mc_username' => $mc_user,
'server_id' => $server_id,
'display_name' => $forum_user->display_name,
'verify_type' => 'forum_login',
] );
}
// ── Filter: Gallery-Upload-Berechtigung ───────────────────────────────────
/**
* Gibt true zurück wenn ein eingeloggter Forum-User einen verifizierten
* Link zu $mc_username hat — ersetzt dann die normale Token-Prüfung.
* Wird nur aufgerufen wenn die Gallery `apply_filters('mc_gallery_can_upload', …)` nutzt.
*/
public static function filter_upload_permission( $allowed, $mc_username, $server_id ) {
if ( $allowed ) return true; // schon erlaubt, nicht überschreiben
$forum_user = WBF_Auth::get_current_user();
if ( ! $forum_user ) return false;
$linked = self::get_mc_username( $forum_user->id );
if ( ! $linked ) return false;
if ( strtolower( $linked ) !== strtolower( $mc_username ) ) return false;
return self::is_verified( $forum_user->id );
}
// ── Filter: Zusätzliche Verify-UI in der Gallery ──────────────────────────
/**
* Hängt unter das normale Verify-Formular einen "Mit Forum-Login"-Bereich.
* Funktioniert wenn die Gallery `apply_filters('mc_gallery_verify_ui_extra', '', $server_id)` aufruft.
*
* Falls der Hook nicht existiert: eigenen Shortcode [mc_gallery_forum_login] nutzen.
*/
public static function render_verify_panel( $html, $server_id ) {
return $html . self::build_verify_panel( $server_id );
}
/**
* Shortcode [mc_gallery_forum_login server_id="survival"]
* Kann manuell auf der Upload-Seite eingebettet werden falls der Hook-Ansatz
* nicht greift.
*/
public static function shortcode_verify_panel( $atts ) {
$atts = shortcode_atts( [ 'server_id' => '' ], $atts );
return self::build_verify_panel( sanitize_text_field( $atts['server_id'] ) );
}
/** Eigentliches HTML für das Verify-Panel */
public static function build_verify_panel( $server_id ) {
$forum_user = WBF_Auth::get_current_user();
$nonce = wp_create_nonce( self::NONCE_ACTION );
$ajax_url = admin_url( 'admin-ajax.php' );
ob_start();
?>
<div class="mc-bridge-verify-wrap" data-server="<?php echo esc_attr( $server_id ); ?>">
<div class="mc-bridge-divider"><span>oder</span></div>
<?php if ( ! $forum_user ) :
$forum_url = function_exists('wbf_get_forum_url') ? wbf_get_forum_url() : '#';
$register_url = function_exists('wbf_get_forum_url') ? wbf_get_forum_url() . '?register=1' : '#';
?>
<div class="mc-bridge-card">
<div class="mc-bridge-card-inner">
<div class="mc-bridge-card-icon">
<i class="fas fa-comments"></i>
</div>
<div class="mc-bridge-card-text">
<div class="mc-bridge-card-label">Forum-Login</div>
<div class="mc-bridge-card-desc">
Direkt hochladen ohne Ingame-Token wenn dein <strong>Minecraft-Account</strong> mit dem Forum verknüpft ist.
</div>
</div>
<div class="mc-bridge-card-actions">
<a href="<?php echo esc_url( $forum_url ); ?>" class="mc-bridge-action-btn">
<i class="fas fa-sign-in-alt"></i> Einloggen
</a>
<a href="<?php echo esc_url( $register_url ); ?>" class="mc-bridge-action-btn-ghost">
<i class="fas fa-external-link-alt"></i> Konto erstellen
</a>
</div>
</div>
</div>
<?php else :
$mc_user = self::get_mc_username( $forum_user->id );
$verified = self::is_verified( $forum_user->id );
$forum_url = function_exists('wbf_get_forum_url')
? wbf_get_forum_url() . '?forum_profile=' . (int) $forum_user->id . '#tab-minecraft'
: '#';
?>
<?php if ( $mc_user && $verified ) : ?>
<div class="mc-bridge-success">
<i class="fas fa-check-circle"></i>
Verifiziert als <strong><?php echo esc_html( $mc_user ); ?></strong>
</div>
<?php elseif ( $mc_user ) : ?>
<div class="mc-bridge-card mc-bridge-card--warn">
<div class="mc-bridge-card-inner">
<img class="mc-bridge-head-sm"
src="https://mc-heads.net/avatar/<?php echo esc_attr( $mc_user ); ?>/44"
alt="" loading="lazy">
<div class="mc-bridge-card-text">
<div class="mc-bridge-card-label">Verknüpft · ausstehend</div>
<div class="mc-bridge-card-desc">
<strong><?php echo esc_html( $mc_user ); ?></strong>
· Noch nicht bestätigt
</div>
</div>
<button type="button"
class="mc-bridge-verify-trigger"
data-ajax="<?php echo esc_attr( $ajax_url ); ?>"
data-nonce="<?php echo esc_attr( $nonce ); ?>"
data-server="<?php echo esc_attr( $server_id ); ?>">
<i class="fas fa-sign-in-alt"></i> Mit Forum verifizieren
</button>
</div>
</div>
<?php else : ?>
<div class="mc-bridge-card">
<div class="mc-bridge-card-inner">
<div class="mc-bridge-card-icon">
<i class="fas fa-user-circle"></i>
</div>
<div class="mc-bridge-card-text">
<div class="mc-bridge-card-label">Eingeloggt als <?php echo esc_html( $forum_user->display_name ); ?></div>
<div class="mc-bridge-card-desc">
Noch kein Minecraft-Konto verknüpft.
</div>
</div>
<div class="mc-bridge-card-actions">
<a href="<?php echo esc_url( $forum_url ); ?>" class="mc-bridge-action-btn">
<i class="fas fa-link"></i> Konto verknüpfen
</a>
</div>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
<script>
(function($){
$(document).on('click', '.mc-bridge-verify-trigger', function(){
console.log('[MC-Gallery] Forum-Login Button geklickt!');
if (typeof $ === 'undefined') { alert('jQuery nicht geladen!'); return; }
var $btn = $(this).prop('disabled', true);
var ajax = $btn.data('ajax');
var nonce = $btn.data('nonce');
var server = $btn.data('server') || $btn.closest('[data-server]').data('server') || '';
$btn.html('<i class="fas fa-spinner fa-spin"></i> Prüfe…');
$.post(ajax, {
action: 'mc_forum_verify_upload',
nonce: nonce,
server_id: server
})
.done(function(r){
if ( r.success ) {
// Galerie-JS über erfolgreiche Verify informieren
// Standard-Event — Gallery-JS kann darauf lauschen
$(document).trigger('mc_gallery_forum_verified', [ r.data ]);
// Falls Gallery eigenes globales Callback hat
if ( typeof window.mcGalleryOnVerified === 'function' ) {
window.mcGalleryOnVerified( r.data );
}
// Statusanzeige aktualisieren
$btn.closest('.mc-bridge-verify-wrap')
.html('<div class="mc-bridge-success">'
+ '<i class="fas fa-check-circle"></i> Verifiziert als <strong>'
+ $('<span>').text(r.data.mc_username).html()
+ '</strong></div>');
} else {
var msg = (r.data && r.data.message) ? r.data.message : 'Fehler bei der Verifikation.';
$btn.closest('.mc-bridge-verify-wrap').find('.mc-bridge-error').remove();
$btn.closest('.mc-bridge-forum-linked, .mc-bridge-not-linked')
.after('<p class="mc-bridge-error"><i class="fas fa-times-circle"></i> ' + msg + '</p>');
$btn.prop('disabled', false).html('<i class="fas fa-sign-in-alt"></i> Mit Forum-Login verifizieren');
}
})
.fail(function(){
$btn.prop('disabled', false).html('<i class="fas fa-sign-in-alt"></i> Mit Forum-Login verifizieren');
alert('Netzwerkfehler. Bitte erneut versuchen.');
});
});
})(jQuery);
</script>
<?php
return ob_get_clean();
}
// ── Admin: Spalte in Forum-Benutzertabelle ────────────────────────────────
/**
* Zeigt verknüpfte MC-Accounts in der Forum-Admin-Usertabelle.
* Voraussetzung: Forum rendert `do_action('wbf_admin_user_row_extra', $user)`.
*/
public static function render_admin_user_col( $user ) {
$mc_user = self::get_mc_username( $user->id );
if ( ! $mc_user ) return;
$verified = self::is_verified( $user->id );
$nonce = wp_create_nonce( self::NONCE_ACTION );
?>
<span class="mc-bridge-admin-mc-badge"
title="Verknüpfter Minecraft-Account<?php echo $verified ? ' (verifiziert)' : ' (ausstehend)'; ?>">
<img src="https://mc-heads.net/avatar/<?php echo esc_attr( $mc_user ); ?>/20" alt="">
<?php echo esc_html( $mc_user ); ?>
<?php if ( $verified ) : ?>
<i class="fas fa-check" style="color:#22c55e"></i>
<?php else : ?>
<a href="#"
class="mc-bridge-btn--approve"
style="color:#f59e0b;margin-left:4px"
data-uid="<?php echo (int) $user->id; ?>"
data-nonce="<?php echo esc_attr( $nonce ); ?>"
title="Verknüpfung bestätigen">
<i class="fas fa-check-circle"></i>
</a>
<script>
(function($){
$(document).on('click', '.mc-bridge-btn--approve[data-uid]', function(e){
e.preventDefault();
var $a = $(this);
var uid = $a.data('uid');
var nonce = $a.data('nonce');
$.post(<?php echo json_encode( admin_url('admin-ajax.php') ); ?>, {
action: 'mc_forum_admin_approve',
user_id: uid,
nonce: nonce
}).done(function(r){
if ( r.success ) location.reload();
else alert(r.data || 'Fehler.');
});
});
})(jQuery);
</script>
<?php endif; ?>
</span>
<?php
}
// ── Hilfsmethoden: forum_user_meta Zugriff ────────────────────────────────
private static function get_meta( $user_id, $key ) {
global $wpdb;
return $wpdb->get_var( $wpdb->prepare(
"SELECT meta_value FROM {$wpdb->prefix}forum_user_meta
WHERE user_id = %d AND meta_key = %s
LIMIT 1",
(int) $user_id, $key
) );
}
private static function set_meta( $user_id, $key, $value ) {
global $wpdb;
$table = $wpdb->prefix . 'forum_user_meta';
$exists = $wpdb->get_var( $wpdb->prepare(
"SELECT id FROM {$table} WHERE user_id = %d AND meta_key = %s",
(int) $user_id, $key
) );
if ( $exists ) {
$wpdb->update( $table,
[ 'meta_value' => $value ],
[ 'user_id' => (int) $user_id, 'meta_key' => $key ]
);
} else {
$wpdb->insert( $table, [
'user_id' => (int) $user_id,
'meta_key' => $key,
'meta_value' => $value,
] );
}
}
private static function delete_meta( $user_id, $key ) {
global $wpdb;
$wpdb->delete( $wpdb->prefix . 'forum_user_meta',
[ 'user_id' => (int) $user_id, 'meta_key' => $key ]
);
}
// Öffentliche Getter/Setter
public static function get_mc_username( $user_id ) { return self::get_meta( $user_id, self::META_MC_USER ); }
public static function get_mc_server ( $user_id ) { return self::get_meta( $user_id, self::META_MC_SERVER ); }
public static function is_verified ( $user_id ) { return '1' === self::get_meta( $user_id, self::META_VERIFIED ); }
public static function set_mc_username( $user_id, $val ) { self::set_meta( $user_id, self::META_MC_USER, $val ); }
public static function set_mc_server ( $user_id, $val ) { self::set_meta( $user_id, self::META_MC_SERVER, $val ); }
public static function set_verified ( $user_id, $bool ) { self::set_meta( $user_id, self::META_VERIFIED, $bool ? '1' : '0' ); }
public static function delete_mc_link( $user_id ) {
self::delete_meta( $user_id, self::META_MC_USER );
self::delete_meta( $user_id, self::META_MC_SERVER );
self::delete_meta( $user_id, self::META_VERIFIED );
}
// Prüft ob ein MC-Name schon einem anderen Forum-User gehört
private static function mc_user_taken( $mc_user, $exclude_user_id ) {
global $wpdb;
return (bool) $wpdb->get_var( $wpdb->prepare(
"SELECT m.id FROM {$wpdb->prefix}forum_user_meta m
WHERE m.meta_key = %s
AND m.meta_value = %s
AND m.user_id != %d
LIMIT 1",
self::META_MC_USER, $mc_user, (int) $exclude_user_id
) );
}
// Gibt true zurück wenn gerade ein gültiger Ingame-Token für diesen MC-Namen existiert
private static function check_active_token_for( $mc_username ) {
if ( ! class_exists( 'MC_Gallery_Helpers' ) ) return false;
$tokens = MC_Gallery_Helpers::get_tokens();
$now = time();
foreach ( $tokens as $token => $data ) {
if ( ! is_array( $data ) ) continue;
if ( ( $data['expires'] ?? 0 ) < $now ) continue;
if ( strtolower( $data['player'] ?? '' ) === strtolower( $mc_username ) ) {
return true;
}
}
return false;
}
// Server-Liste aus Gallery-Config laden
private static function get_server_list() {
$servers = get_option( 'mc_gallery_servers', [] );
if ( ! empty( $servers ) && is_array( $servers ) ) return $servers;
return [ 'default' => 'Standard-Server' ];
}
}