Update from Git Manager GUI
This commit is contained in:
691
includes/class-mc-gallery-forum-bridge.php
Normal file
691
includes/class-mc-gallery-forum-bridge.php
Normal file
@@ -0,0 +1,691 @@
|
||||
<?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 (2–32 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' ];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user