Update from Git Manager GUI
This commit is contained in:
1988
Minecraft-Modern-Theme/inc/assistant-ajax.php
Normal file
1988
Minecraft-Modern-Theme/inc/assistant-ajax.php
Normal file
File diff suppressed because it is too large
Load Diff
854
Minecraft-Modern-Theme/inc/assistant-widget.php
Normal file
854
Minecraft-Modern-Theme/inc/assistant-widget.php
Normal file
@@ -0,0 +1,854 @@
|
||||
<?php
|
||||
/**
|
||||
* Assistant Widget – Virtueller Support-Assistent
|
||||
*
|
||||
* Vollständig integriert mit allen Plugins:
|
||||
* → LiteBans Manager
|
||||
* → MC Player History
|
||||
* → BungeeCord Status
|
||||
* → Multi Rules
|
||||
* → WP Multi Wiki
|
||||
* → WP Ingame Shop Pro
|
||||
* → WP Multi Ticket Pro
|
||||
* → WP Business Forum
|
||||
* → MC MultiServer Gallery PRO
|
||||
* → FAQ (Custom Post Type)
|
||||
*
|
||||
* @version 3.1
|
||||
* @author M_Viper
|
||||
*
|
||||
* WICHTIG: Die eigentliche Antwort-Logik liegt in assistant-ajax.php.
|
||||
* Diese Datei enthält nur: Admin-Backend, Widget-Frontend, JS.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
// =========================================================================
|
||||
// AJAX-Handler laden (assistant-ajax.php)
|
||||
// =========================================================================
|
||||
$mm_ajax_file = get_template_directory() . '/inc/assistant-ajax.php';
|
||||
if ( file_exists( $mm_ajax_file ) ) {
|
||||
require_once $mm_ajax_file;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 1. ADMIN-BACKEND – BOT-ZENTRALE
|
||||
// =========================================================================
|
||||
|
||||
add_action( 'admin_menu', function () {
|
||||
add_menu_page(
|
||||
'Bot Setup',
|
||||
'Bot Setup',
|
||||
'manage_options',
|
||||
'bot-setup',
|
||||
'mm_render_bot_admin',
|
||||
'dashicons-robot',
|
||||
65
|
||||
);
|
||||
} );
|
||||
|
||||
add_action( 'admin_init', function () {
|
||||
register_setting( 'mm_bot_settings', 'mm_bot_data', [
|
||||
'sanitize_callback' => 'mm_bot_sanitize_settings',
|
||||
] );
|
||||
} );
|
||||
|
||||
function mm_bot_sanitize_settings( $input ) {
|
||||
$clean = [];
|
||||
|
||||
$text_fields = [ 'server_ip', 'server_ver', 'server_specs', 'bot_name', 'welcome' ];
|
||||
$url_fields = [
|
||||
'url_wiki', 'url_rules', 'url_tickets', 'url_faq',
|
||||
'url_team', 'url_shop', 'url_gallery', 'url_player_history',
|
||||
'url_forum', 'link_discord', 'litebans_dashboard_url',
|
||||
];
|
||||
|
||||
foreach ( $text_fields as $f ) {
|
||||
$clean[ $f ] = isset( $input[ $f ] ) ? sanitize_text_field( $input[ $f ] ) : '';
|
||||
}
|
||||
foreach ( $url_fields as $f ) {
|
||||
$clean[ $f ] = isset( $input[ $f ] ) ? esc_url_raw( $input[ $f ] ) : '';
|
||||
}
|
||||
|
||||
$clean['qa'] = [];
|
||||
if ( ! empty( $input['qa'] ) && is_array( $input['qa'] ) ) {
|
||||
foreach ( $input['qa'] as $item ) {
|
||||
if ( empty( $item['keys'] ) ) continue;
|
||||
$clean['qa'][] = [
|
||||
'keys' => sanitize_text_field( $item['keys'] ),
|
||||
'val' => wp_kses_post( $item['val'] ),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $clean;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 2. ADMIN-SEITE
|
||||
// =========================================================================
|
||||
|
||||
function mm_render_bot_admin() {
|
||||
$data = get_option( 'mm_bot_data', [] );
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><span class="dashicons dashicons-robot"></span> Bot-Zentrale</h1>
|
||||
|
||||
<style>
|
||||
.bot-card { background:#fff; padding:20px; border:1px solid #ccd0d4; border-radius:8px; margin-top:20px; box-shadow:0 2px 4px rgba(0,0,0,.05); }
|
||||
.bot-card h2 { margin-top:0; color:#0073aa; border-bottom:1px solid #eee; padding-bottom:12px; }
|
||||
.bot-card p.description { color:#666; font-style:italic; margin-top:4px; }
|
||||
.badge { display:inline-block; background:#0099ff; color:#fff; font-size:11px; padding:1px 7px; border-radius:10px; margin-left:6px; vertical-align:middle; }
|
||||
.badge.inactive { background:#999; }
|
||||
</style>
|
||||
|
||||
<form method="post" action="options.php">
|
||||
<?php settings_fields( 'mm_bot_settings' ); ?>
|
||||
|
||||
<!-- KARTE 1: Server -->
|
||||
<div class="bot-card">
|
||||
<h2>1. Server-Infos</h2>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th><label>Server-IP / Adresse</label></th>
|
||||
<td>
|
||||
<input type="text" name="mm_bot_data[server_ip]" value="<?php echo esc_attr( $data['server_ip'] ?? '' ); ?>" class="regular-text" placeholder="play.example.net">
|
||||
<p class="description">Wird bei Fragen nach der Server-IP angezeigt.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label>Minecraft-Version</label></th>
|
||||
<td><input type="text" name="mm_bot_data[server_ver]" value="<?php echo esc_attr( $data['server_ver'] ?? '' ); ?>" class="small-text" placeholder="1.21.1"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label>Hardware / Specs</label></th>
|
||||
<td>
|
||||
<input type="text" name="mm_bot_data[server_specs]" value="<?php echo esc_attr( $data['server_specs'] ?? '' ); ?>" class="large-text" placeholder="z.B. Ryzen 9, 64 GB RAM, NVMe SSD">
|
||||
<p class="description">Wird bei Fragen nach der Server-Hardware angezeigt.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- KARTE 2: Bot-Einstellungen -->
|
||||
<div class="bot-card">
|
||||
<h2>2. Bot-Einstellungen</h2>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th><label>Bot-Name</label></th>
|
||||
<td><input type="text" name="mm_bot_data[bot_name]" value="<?php echo esc_attr( $data['bot_name'] ?? '' ); ?>" class="regular-text" placeholder="Viper-Bot"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label>Minecraft-UUID / Name (Avatar)</label></th>
|
||||
<td>
|
||||
<?php
|
||||
$uuid = get_theme_mod( 'assistant_minecraft_uuid', 'Steve' );
|
||||
?>
|
||||
<input type="text" name="assistant_mc_uuid_preview" value="<?php echo esc_attr( $uuid ); ?>" class="regular-text" disabled>
|
||||
<p class="description">UUID / Name wird im Theme-Customizer unter "Assistent" gesetzt.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label>Begrüßungstext</label></th>
|
||||
<td>
|
||||
<textarea name="mm_bot_data[welcome]" rows="3" class="large-text"><?php echo esc_textarea( $data['welcome'] ?? '' ); ?></textarea>
|
||||
<p class="description">Erster Text der beim Öffnen des Assistenten angezeigt wird.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- KARTE 3: Links -->
|
||||
<div class="bot-card">
|
||||
<h2>3. Wichtige Links</h2>
|
||||
<p class="description" style="margin-bottom:12px;">
|
||||
💡 Wenn eine Seite mit dem passenden Shortcode gefunden wird, erscheint ein <strong>„Vorschlag übernehmen"</strong>-Button.
|
||||
</p>
|
||||
|
||||
<?php
|
||||
// ── Auto-Detect: Seiten mit bekannten Shortcodes suchen ──────────────
|
||||
function mm_find_page_by_shortcode( $shortcodes ) {
|
||||
global $wpdb;
|
||||
$conditions = [];
|
||||
foreach ( (array) $shortcodes as $sc ) {
|
||||
$conditions[] = $wpdb->prepare( 'post_content LIKE %s', '%[' . $wpdb->esc_like( $sc ) . '%' );
|
||||
}
|
||||
if ( empty( $conditions ) ) return '';
|
||||
$where = implode( ' OR ', $conditions );
|
||||
$page = $wpdb->get_row(
|
||||
"SELECT ID FROM {$wpdb->posts}
|
||||
WHERE post_status = 'publish'
|
||||
AND post_type IN ('page','post')
|
||||
AND ({$where})
|
||||
LIMIT 1"
|
||||
);
|
||||
return $page ? get_permalink( $page->ID ) : '';
|
||||
}
|
||||
|
||||
$autodetect = [
|
||||
'url_wiki' => mm_find_page_by_shortcode( ['wmw_wiki', 'wmw_search', 'wmw_article'] ),
|
||||
'url_rules' => mm_find_page_by_shortcode( ['mrp_rules', 'mc_rules', 'multi_rules'] ),
|
||||
'url_tickets' => mm_find_page_by_shortcode( ['wmtp_tickets', 'wm_tickets', 'multi_ticket'] ),
|
||||
'url_shop' => mm_find_page_by_shortcode( ['wis_shop', 'ingame_shop', 'wis_items'] ),
|
||||
'url_gallery' => mm_find_page_by_shortcode( ['mc_gallery', 'mc_gallery_overview', 'mc_gallery_upload', 'mc_gallery_all_albums'] ),
|
||||
'url_faq' => mm_find_page_by_shortcode( ['faq_list', 'faq', 'faq_page'] ),
|
||||
'url_player_history' => mm_find_page_by_shortcode( ['mc_player_history', 'mc_players', 'player_history'] ),
|
||||
'url_forum' => mm_find_page_by_shortcode( ['business_forum'] ),
|
||||
'litebans_dashboard_url' => mm_find_page_by_shortcode( ['litebans_dashboard', 'litebans', 'wp_litebans'] ),
|
||||
];
|
||||
|
||||
$links = [
|
||||
'url_wiki' => [ 'label' => '📖 Wiki-URL', 'plugin' => 'WP Multi Wiki', 'active' => post_type_exists( 'wmw_article' ) ],
|
||||
'url_rules' => [ 'label' => '📜 Regelwerk-URL', 'plugin' => 'Multi Rules', 'active' => function_exists( 'mrp_get_plugin_version' ) ],
|
||||
'url_tickets' => [ 'label' => '🎫 Ticket/Support-URL', 'plugin' => 'WP Multi Ticket Pro', 'active' => class_exists( 'WP_Multi_Ticket_Pro' ) ],
|
||||
'url_shop' => [ 'label' => '🛒 Shop-URL', 'plugin' => 'WP Ingame Shop Pro', 'active' => class_exists( 'WIS_Activator' ) ],
|
||||
'url_gallery' => [ 'label' => '📷 Galerie-URL', 'plugin' => 'MC MultiServer Gallery PRO', 'active' => post_type_exists( 'mc_gallery' ) ],
|
||||
'url_faq' => [ 'label' => '❓ FAQ-URL', 'plugin' => 'FAQ Post Type', 'active' => post_type_exists( 'faq' ) ],
|
||||
'url_player_history' => [ 'label' => '👤 Spieler-History-URL', 'plugin' => 'MC Player History', 'active' => function_exists( 'mcph_get_plugin_version' ) ],
|
||||
'url_forum' => [ 'label' => '💬 Forum-URL', 'plugin' => 'WP Business Forum', 'active' => class_exists( 'WBF_DB' ) ],
|
||||
'url_team' => [ 'label' => '👥 Team-URL', 'plugin' => '', 'active' => true ],
|
||||
'link_discord' => [ 'label' => '💬 Discord-Einladung', 'plugin' => '', 'active' => true ],
|
||||
'litebans_dashboard_url' => [ 'label' => '🔨 LiteBans Dashboard-URL', 'plugin' => 'LiteBans Manager', 'active' => class_exists( 'WP_LiteBans_Pro' ) ],
|
||||
];
|
||||
?>
|
||||
|
||||
<style>
|
||||
.mm-url-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||
.mm-url-row input.large-text { flex: 1; min-width: 200px; }
|
||||
.mm-suggest-btn {
|
||||
background: #e8f5e9; color: #2e7d32; border: 1px solid #a5d6a7;
|
||||
border-radius: 4px; padding: 5px 10px; font-size: 12px;
|
||||
cursor: pointer; white-space: nowrap; line-height: 1.4;
|
||||
transition: background .2s;
|
||||
}
|
||||
.mm-suggest-btn:hover { background: #c8e6c9; }
|
||||
.mm-suggest-url { font-size: 11px; color: #666; max-width: 260px;
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
display: inline-block; vertical-align: middle; }
|
||||
.mm-autofill-all {
|
||||
margin-bottom: 12px; background: #0073aa; color: #fff;
|
||||
border: none; border-radius: 4px; padding: 7px 16px;
|
||||
cursor: pointer; font-size: 13px;
|
||||
}
|
||||
.mm-autofill-all:hover { background: #005f8d; }
|
||||
</style>
|
||||
|
||||
<?php
|
||||
$has_any_suggestion = ! empty( array_filter( $autodetect ) );
|
||||
if ( $has_any_suggestion ) : ?>
|
||||
<button type="button" class="mm-autofill-all" id="mm-autofill-all">
|
||||
⚡ Alle erkannten URLs automatisch übernehmen
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
|
||||
<table class="form-table">
|
||||
<?php foreach ( $links as $key => $cfg ) :
|
||||
$badge = '';
|
||||
if ( $cfg['plugin'] ) {
|
||||
$cls = $cfg['active'] ? 'badge' : 'badge inactive';
|
||||
$txt = $cfg['active'] ? 'aktiv' : 'inaktiv';
|
||||
$badge = '<span class="' . $cls . '">' . esc_html( $cfg['plugin'] ) . ' ' . $txt . '</span>';
|
||||
}
|
||||
$saved = $data[ $key ] ?? '';
|
||||
$suggested = $autodetect[ $key ] ?? '';
|
||||
$show_suggest = $suggested && $suggested !== $saved;
|
||||
?>
|
||||
<tr>
|
||||
<th><label for="mm_link_<?php echo esc_attr( $key ); ?>"><?php echo $cfg['label'] . $badge; ?></label></th>
|
||||
<td>
|
||||
<div class="mm-url-row">
|
||||
<input type="url"
|
||||
id="mm_link_<?php echo esc_attr( $key ); ?>"
|
||||
name="mm_bot_data[<?php echo esc_attr( $key ); ?>]"
|
||||
value="<?php echo esc_url( $saved ); ?>"
|
||||
class="large-text"
|
||||
data-key="<?php echo esc_attr( $key ); ?>">
|
||||
<?php if ( $show_suggest ) : ?>
|
||||
<button type="button"
|
||||
class="mm-suggest-btn"
|
||||
data-target="mm_link_<?php echo esc_attr( $key ); ?>"
|
||||
data-url="<?php echo esc_url( $suggested ); ?>">
|
||||
✓ Vorschlag übernehmen
|
||||
</button>
|
||||
<span class="mm-suggest-url" title="<?php echo esc_attr( $suggested ); ?>">
|
||||
<?php echo esc_html( $suggested ); ?>
|
||||
</span>
|
||||
<?php elseif ( $saved && $suggested && $suggested === $saved ) : ?>
|
||||
<span style="color:#2e7d32;font-size:12px;">✔ Erkannt & gesetzt</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- KARTE 4: Individuelle Q&A -->
|
||||
<div class="bot-card">
|
||||
<h2>4. Individuelle Q&A</h2>
|
||||
<p class="description">
|
||||
Schlüsselwörter (kommagetrennt) → Antwort. Hat höchste Priorität vor allen Plugin-Abfragen.
|
||||
</p>
|
||||
<table class="form-table" style="width:100%;">
|
||||
<tr>
|
||||
<th style="width:200px;">Schlüsselwörter</th>
|
||||
<th>Antwort (HTML erlaubt)</th>
|
||||
<th style="width:50px;"></th>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="mm-qa-rows">
|
||||
<?php
|
||||
$qa = $data['qa'] ?? [];
|
||||
foreach ( $qa as $i => $item ) :
|
||||
if ( empty( $item['keys'] ) ) continue;
|
||||
?>
|
||||
<div class="qa-item" style="display:flex;gap:10px;margin-bottom:10px;align-items:center;">
|
||||
<input type="text" name="mm_bot_data[qa][<?php echo $i; ?>][keys]"
|
||||
value="<?php echo esc_attr( $item['keys'] ); ?>"
|
||||
style="flex:1;" placeholder="discord, invite, join discord">
|
||||
<input type="text" name="mm_bot_data[qa][<?php echo $i; ?>][val]"
|
||||
value="<?php echo esc_attr( $item['val'] ); ?>"
|
||||
style="flex:2;" placeholder="Antworttext oder HTML">
|
||||
<button type="button" class="button remove-qa" title="Entfernen">✕</button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<button type="button" id="add-qa" class="button button-primary">+ Neue Q&A-Zeile</button>
|
||||
</div>
|
||||
|
||||
<?php submit_button( 'Einstellungen speichern' ); ?>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
jQuery(function($){
|
||||
// Q&A Zeilen
|
||||
$('#add-qa').on('click', function(){
|
||||
var i = Date.now();
|
||||
$('#mm-qa-rows').append(
|
||||
'<div class="qa-item" style="display:flex;gap:10px;margin-bottom:10px;align-items:center;">' +
|
||||
'<input type="text" name="mm_bot_data[qa]['+i+'][keys]" style="flex:1;" placeholder="discord, invite">' +
|
||||
'<input type="text" name="mm_bot_data[qa]['+i+'][val]" style="flex:2;" placeholder="Antwort...">' +
|
||||
'<button type="button" class="button remove-qa" title="Entfernen">✕</button>' +
|
||||
'</div>'
|
||||
);
|
||||
});
|
||||
$(document).on('click', '.remove-qa', function(){
|
||||
$(this).closest('.qa-item').remove();
|
||||
});
|
||||
|
||||
// Einzelnen Vorschlag übernehmen
|
||||
$(document).on('click', '.mm-suggest-btn', function(){
|
||||
var $btn = $(this);
|
||||
var target = $btn.data('target');
|
||||
var url = $btn.data('url');
|
||||
$('#' + target).val(url);
|
||||
$btn.replaceWith('<span style="color:#2e7d32;font-size:12px;">✔ Übernommen</span>');
|
||||
$(this).siblings('.mm-suggest-url').remove();
|
||||
});
|
||||
|
||||
// Alle auf einmal übernehmen
|
||||
$('#mm-autofill-all').on('click', function(){
|
||||
$('.mm-suggest-btn').each(function(){
|
||||
var $btn = $(this);
|
||||
var target = $btn.data('target');
|
||||
var url = $btn.data('url');
|
||||
if ( url && ! $('#' + target).val() ) {
|
||||
$('#' + target).val(url);
|
||||
$btn.closest('.mm-url-row').find('.mm-suggest-url').remove();
|
||||
$btn.replaceWith('<span style="color:#2e7d32;font-size:12px;">✔ Übernommen</span>');
|
||||
}
|
||||
});
|
||||
$(this).prop('disabled', true).text('✔ Fertig – bitte speichern');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 3. ASSETS LADEN
|
||||
// =========================================================================
|
||||
|
||||
add_action( 'wp_enqueue_scripts', function () {
|
||||
// CSS aus Theme-Ordner (falls vorhanden), sonst Inline-Fallback
|
||||
$css_file = get_template_directory() . '/css/assistant-widget.css';
|
||||
if ( file_exists( $css_file ) ) {
|
||||
wp_enqueue_style(
|
||||
'mm-assistant-widget',
|
||||
get_template_directory_uri() . '/css/assistant-widget.css',
|
||||
[],
|
||||
'3.1'
|
||||
);
|
||||
}
|
||||
} );
|
||||
|
||||
// =========================================================================
|
||||
// 4. FRONTEND WIDGET
|
||||
// =========================================================================
|
||||
|
||||
add_action( 'wp_footer', 'mm_bot_render_widget', 50 );
|
||||
|
||||
function mm_bot_render_widget() {
|
||||
$data = get_option( 'mm_bot_data', [] );
|
||||
$uuid = sanitize_text_field( trim( get_theme_mod( 'assistant_minecraft_uuid', 'Steve' ) ) );
|
||||
$name = ! empty( $data['bot_name'] ) ? esc_html( $data['bot_name'] ) : 'Viper-Bot';
|
||||
$welcome = ! empty( $data['welcome'] ) ? $data['welcome'] : 'Hallo! Wie kann ich dir helfen? 👋';
|
||||
$nonce = wp_create_nonce( 'mm_bot_nonce' );
|
||||
$ajax = admin_url( 'admin-ajax.php' );
|
||||
|
||||
// ── Quick-Buttons: nur anzeigen wenn Plugin aktiv + URL gesetzt ──────
|
||||
$quick = [];
|
||||
|
||||
// Server-Status (immer wenn IP konfiguriert oder BungeeCord-Plugin aktiv)
|
||||
$servers = get_option( 'mcss_servers', [] );
|
||||
if ( ! empty( $data['server_ip'] ) || ! empty( $servers ) ) {
|
||||
$quick[] = [ 'label' => '🖥️ Server-Status', 'q' => 'server status' ];
|
||||
}
|
||||
|
||||
// Regeln – nur wenn URL im Backend gesetzt
|
||||
if ( ! empty( $data['url_rules'] ) ) {
|
||||
$quick[] = [ 'label' => '📜 Regelwerk', 'q' => 'regeln' ];
|
||||
}
|
||||
|
||||
// Wiki – nur wenn URL im Backend gesetzt
|
||||
if ( ! empty( $data['url_wiki'] ) ) {
|
||||
$quick[] = [ 'label' => '📖 Wiki', 'q' => 'wiki' ];
|
||||
}
|
||||
|
||||
// Shop – nur wenn URL im Backend gesetzt
|
||||
global $wpdb;
|
||||
if ( ! empty( $data['url_shop'] ) ) {
|
||||
$quick[] = [ 'label' => '🛒 Shop', 'q' => 'shop' ];
|
||||
}
|
||||
|
||||
// Ticket / Support – nur wenn URL im Backend gesetzt
|
||||
if ( ! empty( $data['url_tickets'] ) ) {
|
||||
$quick[] = [ 'label' => '🎫 Support-Ticket', 'q' => 'ticket erstellen' ];
|
||||
}
|
||||
|
||||
// Forum
|
||||
if ( class_exists( 'WBF_DB' ) && ! empty( $data['url_forum'] ) ) {
|
||||
$quick[] = [ 'label' => '💬 Forum', 'q' => 'forum' ];
|
||||
}
|
||||
|
||||
// Galerie – nur wenn URL im Backend gesetzt
|
||||
if ( ! empty( $data['url_gallery'] ) ) {
|
||||
$quick[] = [ 'label' => '📷 Galerie', 'q' => 'galerie' ];
|
||||
}
|
||||
|
||||
// Ban-Status
|
||||
$lb = get_option( 'wp_litebans_pro_settings', [] );
|
||||
if ( ! empty( $lb['db_name'] ) ) {
|
||||
$quick[] = [ 'label' => '🔨 Strafen prüfen', 'q' => 'meine strafen' ];
|
||||
}
|
||||
|
||||
// Spieler-History – nur wenn URL im Backend gesetzt
|
||||
if ( ! empty( $data['url_player_history'] ) ) {
|
||||
$quick[] = [ 'label' => '⏱️ Spielzeit', 'q' => 'spielzeit' ];
|
||||
}
|
||||
|
||||
// Discord
|
||||
if ( ! empty( $data['link_discord'] ) ) {
|
||||
$quick[] = [ 'label' => '💬 Discord', 'q' => 'discord' ];
|
||||
}
|
||||
?>
|
||||
|
||||
<div id="mm-bot-root">
|
||||
|
||||
<!-- Chat-Fenster -->
|
||||
<div id="mm-bot-chat" style="display:none;" aria-label="Assistent" role="dialog">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="mm-bot-header">
|
||||
<div class="mm-bot-status" title="Online"></div>
|
||||
<img class="mm-bot-avatar-small"
|
||||
src="https://mc-heads.net/avatar/<?php echo esc_attr( $uuid ); ?>/32"
|
||||
alt="<?php echo $name; ?>">
|
||||
<span class="mm-bot-title"><?php echo $name; ?></span>
|
||||
<button id="mm-bot-close" aria-label="Schließen">×</button>
|
||||
</div>
|
||||
|
||||
<!-- Nachrichten -->
|
||||
<div id="mm-bot-content" role="log" aria-live="polite">
|
||||
<div class="mm-msg bot">
|
||||
<?php echo nl2br( wp_kses_post( $welcome ) ); ?>
|
||||
</div>
|
||||
|
||||
<?php if ( ! empty( $quick ) ) : ?>
|
||||
<div class="mm-bot-quick">
|
||||
<?php foreach ( $quick as $btn ) : ?>
|
||||
<button class="mm-quick-btn"
|
||||
data-q="<?php echo esc_attr( $btn['q'] ); ?>"
|
||||
type="button">
|
||||
<?php echo esc_html( $btn['label'] ); ?>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Eingabe -->
|
||||
<div class="mm-bot-input-area">
|
||||
<input type="text"
|
||||
id="mm-bot-field"
|
||||
placeholder="Deine Frage eingeben…"
|
||||
autocomplete="off"
|
||||
maxlength="300"
|
||||
aria-label="Nachricht eingeben">
|
||||
<button id="mm-bot-send" type="button" aria-label="Senden">➤</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Launcher-Button -->
|
||||
<button id="mm-bot-launcher" type="button" aria-label="Assistenten öffnen" title="<?php echo $name; ?>">
|
||||
<img src="https://mc-heads.net/avatar/<?php echo esc_attr( $uuid ); ?>/60"
|
||||
alt="<?php echo $name; ?>">
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function($){
|
||||
'use strict';
|
||||
|
||||
var $chat = $('#mm-bot-chat');
|
||||
var $field = $('#mm-bot-field');
|
||||
var $content = $('#mm-bot-content');
|
||||
var nonce = <?php echo wp_json_encode( $nonce ); ?>;
|
||||
var ajaxUrl = <?php echo wp_json_encode( $ajax ); ?>;
|
||||
var isLoading = false;
|
||||
|
||||
// ── Öffnen / Schließen ────────────────────────────────────
|
||||
$('#mm-bot-launcher').on('click', function(){
|
||||
$chat.fadeToggle(200);
|
||||
if ($chat.is(':visible')) {
|
||||
$field.trigger('focus');
|
||||
scrollBottom();
|
||||
}
|
||||
});
|
||||
|
||||
$('#mm-bot-close').on('click', function(){
|
||||
$chat.fadeOut(200);
|
||||
});
|
||||
|
||||
// ── Quick-Buttons ─────────────────────────────────────────
|
||||
$(document).on('click', '.mm-quick-btn', function(){
|
||||
sendMessage( $(this).data('q') );
|
||||
});
|
||||
|
||||
// ── Senden ────────────────────────────────────────────────
|
||||
$('#mm-bot-send').on('click', function(){ sendMessage(); });
|
||||
$field.on('keydown', function(e){
|
||||
if (e.which === 13 && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
sendMessage();
|
||||
}
|
||||
});
|
||||
|
||||
function sendMessage(forceText) {
|
||||
if (isLoading) return;
|
||||
|
||||
var val = forceText !== undefined
|
||||
? String(forceText).trim()
|
||||
: $field.val().trim();
|
||||
|
||||
if (!val) return;
|
||||
|
||||
// Nutzernachricht anzeigen
|
||||
appendMsg('user', $('<span>').text(val).html());
|
||||
if (forceText === undefined) $field.val('');
|
||||
|
||||
// Loader
|
||||
isLoading = true;
|
||||
var $loader = $('<div class="mm-msg bot mm-loading" aria-label="Lädt">···</div>');
|
||||
$content.append($loader);
|
||||
scrollBottom();
|
||||
|
||||
$.ajax({
|
||||
url: ajaxUrl,
|
||||
method: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
action: 'mm_assistant_query', // ← Neuer Action-Name
|
||||
q: val,
|
||||
nonce: nonce
|
||||
},
|
||||
success: function(res){
|
||||
$loader.remove();
|
||||
isLoading = false;
|
||||
|
||||
var text;
|
||||
if (res && res.success && res.data && res.data.reply) {
|
||||
// Neues Format: {reply: '...', parts: [...]}
|
||||
text = res.data.reply;
|
||||
} else if (res && res.success && typeof res.data === 'string') {
|
||||
// Altes Format: direkter String (Fallback)
|
||||
text = res.data;
|
||||
} else {
|
||||
text = '⚠️ Keine Antwort erhalten.';
|
||||
}
|
||||
|
||||
appendMsg('bot', text);
|
||||
},
|
||||
error: function(){
|
||||
$loader.remove();
|
||||
isLoading = false;
|
||||
appendMsg('bot', '⚠️ Verbindungsfehler. Bitte versuche es erneut.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function appendMsg(type, html) {
|
||||
var $msg = $('<div class="mm-msg ' + type + '">').html(html);
|
||||
$content.append($msg);
|
||||
scrollBottom();
|
||||
}
|
||||
|
||||
function scrollBottom() {
|
||||
$content.scrollTop($content[0].scrollHeight);
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* ── Wrapper ── */
|
||||
#mm-bot-root {
|
||||
position: fixed;
|
||||
bottom: 30px;
|
||||
right: 30px;
|
||||
z-index: 999999;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
}
|
||||
|
||||
/* ── Launcher ── */
|
||||
#mm-bot-launcher {
|
||||
background: #0099ff;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
width: 62px;
|
||||
height: 62px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 16px rgba(0,153,255,.45);
|
||||
transition: transform .25s, box-shadow .25s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
#mm-bot-launcher:hover {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 6px 22px rgba(0,153,255,.6);
|
||||
}
|
||||
#mm-bot-launcher img {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* ── Chat-Fenster ── */
|
||||
#mm-bot-chat {
|
||||
position: absolute;
|
||||
bottom: 78px;
|
||||
right: 0;
|
||||
width: 350px;
|
||||
background: #1e2124;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 16px 48px rgba(0,0,0,.55);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
border: 1px solid #2a2d31;
|
||||
}
|
||||
|
||||
/* ── Header ── */
|
||||
.mm-bot-header {
|
||||
background: #2f3136;
|
||||
color: #fff;
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
.mm-bot-status {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: #43b581;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 8px #43b581;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.mm-bot-avatar-small {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.mm-bot-title {
|
||||
font-weight: 700;
|
||||
font-size: 15px;
|
||||
flex: 1;
|
||||
}
|
||||
#mm-bot-close {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #888;
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
line-height: 1;
|
||||
padding: 0 2px;
|
||||
transition: color .2s;
|
||||
}
|
||||
#mm-bot-close:hover { color: #fff; }
|
||||
|
||||
/* ── Nachrichten ── */
|
||||
#mm-bot-content {
|
||||
height: 340px;
|
||||
padding: 14px 14px 6px;
|
||||
overflow-y: auto;
|
||||
background: #36393f;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
.mm-msg {
|
||||
padding: 10px 14px;
|
||||
border-radius: 14px;
|
||||
font-size: 13.5px;
|
||||
line-height: 1.55;
|
||||
max-width: 90%;
|
||||
word-break: break-word;
|
||||
}
|
||||
.mm-msg.bot {
|
||||
background: #40444b;
|
||||
color: #dcddde;
|
||||
align-self: flex-start;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.mm-msg.user {
|
||||
background: #0099ff;
|
||||
color: #fff;
|
||||
align-self: flex-end;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
.mm-msg a {
|
||||
color: #5bc0eb;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
.mm-msg a:hover { text-decoration: underline; }
|
||||
.mm-msg code {
|
||||
background: #1a1a1a;
|
||||
color: #ffa500;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: monospace;
|
||||
font-size: 12.5px;
|
||||
}
|
||||
.mm-msg hr {
|
||||
border: 0;
|
||||
border-top: 1px solid rgba(255,255,255,.12);
|
||||
margin: 8px 0;
|
||||
}
|
||||
.mm-msg img {
|
||||
max-width: 100%;
|
||||
border-radius: 6px;
|
||||
margin-top: 6px;
|
||||
display: block;
|
||||
}
|
||||
.mm-msg small { opacity: .75; font-size: 12px; }
|
||||
.mm-msg b { color: #fff; }
|
||||
.mm-msg.bot b { color: #e3e4e6; }
|
||||
|
||||
/* TinyMCE Regelwerk-Inhalt im Chat */
|
||||
.mm-msg p { margin: 4px 0; }
|
||||
.mm-msg ul, .mm-msg ol {
|
||||
margin: 4px 0 4px 16px;
|
||||
padding: 0;
|
||||
}
|
||||
.mm-msg li { margin-bottom: 2px; list-style: disc; }
|
||||
.mm-msg ol li { list-style: decimal; }
|
||||
.mm-msg strong, .mm-msg b { font-weight: 700; }
|
||||
.mm-msg em { font-style: italic; }
|
||||
.mm-msg h1, .mm-msg h2, .mm-msg h3,
|
||||
.mm-msg h4, .mm-msg h5, .mm-msg h6 {
|
||||
margin: 6px 0 4px;
|
||||
font-size: 14px;
|
||||
color: #e3e4e6;
|
||||
}
|
||||
|
||||
.mm-loading {
|
||||
opacity: .55;
|
||||
font-size: 22px;
|
||||
letter-spacing: 5px;
|
||||
padding: 6px 14px;
|
||||
}
|
||||
|
||||
/* ── Quick-Buttons ── */
|
||||
.mm-bot-quick {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.mm-quick-btn {
|
||||
background: #2f3136;
|
||||
color: #b9bbbe;
|
||||
border: 1px solid #3f4147;
|
||||
border-radius: 20px;
|
||||
padding: 5px 12px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: background .2s, color .2s, border-color .2s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.mm-quick-btn:hover {
|
||||
background: #0099ff;
|
||||
color: #fff;
|
||||
border-color: #0099ff;
|
||||
}
|
||||
|
||||
/* ── Eingabe ── */
|
||||
.mm-bot-input-area {
|
||||
padding: 10px 12px;
|
||||
background: #2f3136;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
}
|
||||
#mm-bot-field {
|
||||
flex: 1;
|
||||
background: #40444b;
|
||||
border: 1px solid #1a1a1a;
|
||||
border-radius: 8px;
|
||||
color: #fff;
|
||||
padding: 9px 12px;
|
||||
outline: none;
|
||||
font-size: 13.5px;
|
||||
transition: border-color .2s;
|
||||
}
|
||||
#mm-bot-field::placeholder { color: #72767d; }
|
||||
#mm-bot-field:focus { border-color: #0099ff; }
|
||||
|
||||
#mm-bot-send {
|
||||
background: #0099ff;
|
||||
border: none;
|
||||
color: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 0 16px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
transition: background .2s;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
#mm-bot-send:hover { background: #00b0f4; }
|
||||
|
||||
/* ── Responsive ── */
|
||||
@media (max-width: 420px) {
|
||||
#mm-bot-root { bottom: 16px; right: 12px; }
|
||||
#mm-bot-chat { width: calc(100vw - 24px); right: -12px; }
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
@@ -23,9 +23,22 @@ class MM_Import_Export_Control extends WP_Customize_Control {
|
||||
<div class="mm-import-export-wrapper">
|
||||
<p class="description" style="margin-bottom:16px;">
|
||||
<strong><?php _e('Hinweis:', 'minecraft-modern-theme'); ?></strong>
|
||||
<?php _e('Hier kannst du alle Theme-Einstellungen sichern und wiederherstellen.', 'minecraft-modern-theme'); ?>
|
||||
<?php _e('Hier kannst du alle Theme-Einstellungen und Inhalte sichern und wiederherstellen.', 'minecraft-modern-theme'); ?>
|
||||
</p>
|
||||
|
||||
<div style="background:#e7f3ff;border:1px solid #b3d9ff;border-radius:4px;padding:12px;margin-bottom:16px;font-size:12px;line-height:1.5;">
|
||||
<strong>📦 Was wird gesichert:</strong><br>
|
||||
✓ Customizer-Einstellungen (Farben, Social Links, Menü-Design, etc.)<br>
|
||||
✓ Livestream API Keys (YouTube, Twitch)<br>
|
||||
✓ Homepage-Seite (Titel, Inhalt, Highlight-Bild)<br>
|
||||
✓ Navigation Menüs inkl. aller Items & Struktur<br>
|
||||
✓ Widget-Konfigurationen<br>
|
||||
✓ Team-Mitglieder (mit UUID, Avatar, Banner)<br>
|
||||
✓ FAQ-Einträge & Kategorien<br>
|
||||
✓ Custom CSS<br>
|
||||
✓ Announcement-Bar Einstellungen
|
||||
</div>
|
||||
|
||||
<a href="<?php echo esc_url($export_url); ?>" class="button button-primary" style="display:inline-flex;align-items:center;gap:6px;margin-bottom:20px;">
|
||||
<span class="dashicons dashicons-download"></span>
|
||||
<?php _e('Einstellungen exportieren', 'minecraft-modern-theme'); ?>
|
||||
@@ -87,6 +100,33 @@ endif;
|
||||
// Customizer Register
|
||||
// =========================================================================
|
||||
function minecraft_modern_customize_register( $wp_customize ) {
|
||||
// =========================================================================
|
||||
// 9. Virtueller Assistent
|
||||
// =========================================================================
|
||||
$wp_customize->add_section( 'assistant_settings', array(
|
||||
'title' => __('Virtueller Assistent', 'minecraft-modern-theme'),
|
||||
'priority' => 80,
|
||||
'description' => __('Steuert den virtuellen Assistenten im Frontend. Avatar basiert auf Minecraft-UUID.', 'minecraft-modern-theme'),
|
||||
) );
|
||||
$wp_customize->add_setting( 'assistant_enabled', array(
|
||||
'default' => false,
|
||||
'sanitize_callback' => 'wp_validate_boolean',
|
||||
) );
|
||||
$wp_customize->add_control( 'assistant_enabled', array(
|
||||
'label' => __('Virtuellen Assistenten aktivieren', 'minecraft-modern-theme'),
|
||||
'section' => 'assistant_settings',
|
||||
'type' => 'checkbox',
|
||||
) );
|
||||
$wp_customize->add_setting( 'assistant_minecraft_uuid', array(
|
||||
'default' => '',
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
) );
|
||||
$wp_customize->add_control( 'assistant_minecraft_uuid', array(
|
||||
'label' => __('Minecraft UUID für Avatar', 'minecraft-modern-theme'),
|
||||
'section' => 'assistant_settings',
|
||||
'type' => 'text',
|
||||
'description' => __('Gib die Minecraft-UUID für den Avatar des Assistenten ein.', 'minecraft-modern-theme'),
|
||||
) );
|
||||
|
||||
// =========================================================================
|
||||
// 1. HEADER SLIDER
|
||||
@@ -235,18 +275,18 @@ function minecraft_modern_customize_register( $wp_customize ) {
|
||||
// =========================================================================
|
||||
$wp_customize->add_section( 'social_links', array( 'title' => __('Social Media Links', 'minecraft-modern-theme'), 'priority' => 40 ) );
|
||||
$social_platforms = array(
|
||||
'discord' => 'Discord', 'youtube' => 'YouTube', 'twitter' => 'Twitter (X)',
|
||||
'bluesky' => 'BlueSky', 'discord' => 'Discord', 'youtube' => 'YouTube', 'twitter' => 'Twitter (X)',
|
||||
'facebook' => 'Facebook', 'instagram' => 'Instagram', 'tiktok' => 'TikTok',
|
||||
'twitch' => 'Twitch', 'steam' => 'Steam', 'github' => 'GitHub',
|
||||
'linkedin' => 'LinkedIn', 'pinterest' => 'Pinterest', 'reddit' => 'Reddit',
|
||||
'teamspeak' => 'Teamspeak', 'spotify' => 'Spotify',
|
||||
'mastodon' => 'Mastodon', 'threads' => 'Threads', 'kickstarter' => 'Kickstarter',
|
||||
'teamspeak' => 'Teamspeak', 'spotify' => 'Spotify', 'stoat' => 'Stoat',
|
||||
);
|
||||
foreach ( $social_platforms as $key => $label ) {
|
||||
$wp_customize->add_setting( 'social_' . $key, array( 'sanitize_callback' => 'esc_url_raw' ) );
|
||||
$wp_customize->add_control( 'social_' . $key, array( 'label' => $label . ' URL', 'section' => 'social_links', 'type' => 'url' ) );
|
||||
}
|
||||
|
||||
|
||||
// =========================================================================
|
||||
// 6. FOOTER
|
||||
// =========================================================================
|
||||
@@ -311,6 +351,60 @@ function minecraft_modern_customize_register( $wp_customize ) {
|
||||
) );
|
||||
|
||||
|
||||
// =========================================================================
|
||||
// 8.5. VIDEO / LIVESTREAM EINSTELLUNGEN
|
||||
// =========================================================================
|
||||
$wp_customize->add_section( 'video_livestream_settings', array(
|
||||
'title' => __('Video & Livestream', 'minecraft-modern-theme'),
|
||||
'description' => __('Einstellungen für YouTube Livestream-Erkennung. Hauptmethode: Livestream-Posts unter "Livestreams" erstellen. Optional: Zusätzlichen Hauptkanal hier eintragen.', 'minecraft-modern-theme'),
|
||||
'priority' => 75,
|
||||
) );
|
||||
|
||||
$wp_customize->add_setting( 'youtube_api_key', array(
|
||||
'default' => '',
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
'transport' => 'refresh',
|
||||
) );
|
||||
$wp_customize->add_control( 'youtube_api_key', array(
|
||||
'label' => __('YouTube API Key', 'minecraft-modern-theme'),
|
||||
'description' => __('Erforderlich für automatische YouTube Live-Erkennung. <a href="https://console.cloud.google.com/" target="_blank">Hier API Key erstellen</a>', 'minecraft-modern-theme'),
|
||||
'section' => 'video_livestream_settings',
|
||||
'type' => 'text',
|
||||
'input_attrs' => array(
|
||||
'placeholder' => 'AIzaSyD...',
|
||||
),
|
||||
) );
|
||||
|
||||
$wp_customize->add_setting( 'twitch_client_id', array(
|
||||
'default' => '',
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
'transport' => 'refresh',
|
||||
) );
|
||||
$wp_customize->add_control( 'twitch_client_id', array(
|
||||
'label' => __('Twitch Client ID', 'minecraft-modern-theme'),
|
||||
'description' => __('Erforderlich für Twitch Live-Erkennung. <a href="https://dev.twitch.tv/console/apps" target="_blank">Hier App erstellen</a>', 'minecraft-modern-theme'),
|
||||
'section' => 'video_livestream_settings',
|
||||
'type' => 'text',
|
||||
'input_attrs' => array(
|
||||
'placeholder' => 'xxxxxxxxxxxxxx',
|
||||
),
|
||||
) );
|
||||
|
||||
$wp_customize->add_setting( 'twitch_client_secret', array(
|
||||
'default' => '',
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
'transport' => 'refresh',
|
||||
) );
|
||||
$wp_customize->add_control( 'twitch_client_secret', array(
|
||||
'label' => __('Twitch Client Secret', 'minecraft-modern-theme'),
|
||||
'description' => __('Nur für Live-Prüfung. Wird serverseitig genutzt.', 'minecraft-modern-theme'),
|
||||
'section' => 'video_livestream_settings',
|
||||
'type' => 'text',
|
||||
'input_attrs' => array(
|
||||
'placeholder' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
|
||||
),
|
||||
) );
|
||||
|
||||
// =========================================================================
|
||||
// 9. EXPORT / IMPORT
|
||||
// =========================================================================
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Minecraft Modern Theme - Updater & Dashboard Status
|
||||
* * Diese Datei prüft auf neue Versionen via Gitea API und zeigt den Status im Dashboard an.
|
||||
*
|
||||
* Diese Datei prüft auf neue Versionen via Gitea API und zeigt den Status im Dashboard an.
|
||||
* Aus Sicherheitsgründen ist das automatische Update deaktiviert, um Datenverlust zu vermeiden.
|
||||
*/
|
||||
|
||||
@@ -11,23 +12,23 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||
|
||||
class Minecraft_Modern_Theme_Manager {
|
||||
|
||||
private $theme_slug = 'Minecraft-Modern-Theme';
|
||||
// BUG-FIX: Hardcoded 'Minecraft-Modern-Theme' schlug auf Linux-Servern
|
||||
// (case-sensitive Dateisystem) fehl, wenn das Verzeichnis kleingeschrieben ist.
|
||||
// get_template() liefert immer den echten Verzeichnisnamen.
|
||||
private $theme_slug;
|
||||
private $repo = 'M_Viper/Minecraft-Modern-Theme';
|
||||
private $transient_key = 'mm_theme_update_check';
|
||||
|
||||
public function __construct() {
|
||||
// Update-Prüfung und Benachrichtigung
|
||||
$this->theme_slug = get_template();
|
||||
|
||||
add_action( 'admin_notices', [ $this, 'display_update_notice' ] );
|
||||
|
||||
// Dashboard Widget
|
||||
add_action( 'wp_dashboard_setup', [ $this, 'add_dashboard_widget' ] );
|
||||
|
||||
// Refresh Logik
|
||||
add_action( 'admin_init', [ $this, 'handle_refresh_request' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Holt die API-Daten von Gitea
|
||||
* Holt die API-Daten von Gitea (mit Transient-Cache).
|
||||
*/
|
||||
private function get_latest_release() {
|
||||
$update_data = get_transient( $this->transient_key );
|
||||
@@ -46,7 +47,7 @@ class Minecraft_Modern_Theme_Manager {
|
||||
|
||||
$update_data = [
|
||||
'version' => $new_version,
|
||||
'url' => "https://git.viper.ipv64.net/{$this->repo}/releases"
|
||||
'url' => "https://git.viper.ipv64.net/{$this->repo}/releases",
|
||||
];
|
||||
|
||||
set_transient( $this->transient_key, $update_data, 12 * HOUR_IN_SECONDS );
|
||||
@@ -56,7 +57,7 @@ class Minecraft_Modern_Theme_Manager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeigt die gelbe Info-Box oben im Admin-Bereich
|
||||
* Zeigt die gelbe Info-Box oben im Admin-Bereich an, wenn ein Update verfügbar ist.
|
||||
*/
|
||||
public function display_update_notice() {
|
||||
if ( ! current_user_can( 'update_themes' ) ) return;
|
||||
@@ -65,14 +66,18 @@ class Minecraft_Modern_Theme_Manager {
|
||||
if ( isset( $latest['error'] ) ) return;
|
||||
|
||||
$current_version = wp_get_theme( $this->theme_slug )->get( 'Version' );
|
||||
if ( ! $current_version ) return;
|
||||
|
||||
if ( version_compare( $current_version, $latest['version'], '<' ) ) {
|
||||
?>
|
||||
<div class="notice notice-warning is-dismissible">
|
||||
<p>
|
||||
<span class="dashicons dashicons-update" style="color: #dba617; margin-right: 5px;"></span>
|
||||
<strong>Minecraft Modern Update verfügbar:</strong> Version <strong><?php echo esc_html( $latest['version'] ); ?></strong> ist bereit zum Download.
|
||||
<a href="<?php echo esc_url( $latest['url'] ); ?>" target="_blank" style="margin-left: 10px; font-weight: bold;">Zum Download →</a>
|
||||
<strong>Minecraft Modern Update verfügbar:</strong>
|
||||
Version <strong><?php echo esc_html( $latest['version'] ); ?></strong> ist bereit zum Download.
|
||||
<a href="<?php echo esc_url( $latest['url'] ); ?>" target="_blank" style="margin-left: 10px; font-weight: bold;">
|
||||
Zum Download →
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
@@ -80,7 +85,7 @@ class Minecraft_Modern_Theme_Manager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt das Widget zum Dashboard hinzu
|
||||
* Fügt das Widget zum WordPress-Dashboard hinzu.
|
||||
*/
|
||||
public function add_dashboard_widget() {
|
||||
wp_add_dashboard_widget(
|
||||
@@ -91,19 +96,19 @@ class Minecraft_Modern_Theme_Manager {
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML-Inhalt des Widgets
|
||||
* HTML-Inhalt des Dashboard-Widgets.
|
||||
*/
|
||||
public function render_widget_content() {
|
||||
$current_version = wp_get_theme( $this->theme_slug )->get( 'Version' );
|
||||
$latest = $this->get_latest_release();
|
||||
|
||||
echo '<div class="mm-status-widget">';
|
||||
echo '<p><span class="dashicons dashicons-admin-appearance"></span> <strong>Installiert:</strong> ' . esc_html( $current_version ) . '</p>';
|
||||
echo '<p><span class="dashicons dashicons-admin-appearance"></span> <strong>Installiert:</strong> ' . esc_html( $current_version ?: '–' ) . '</p>';
|
||||
|
||||
if ( isset( $latest['version'] ) ) {
|
||||
echo '<p><span class="dashicons dashicons-cloud"></span> <strong>Aktuellste:</strong> ' . esc_html( $latest['version'] ) . '</p>';
|
||||
|
||||
if ( version_compare( $current_version, $latest['version'], '<' ) ) {
|
||||
if ( $current_version && version_compare( $current_version, $latest['version'], '<' ) ) {
|
||||
echo '<div style="background: #fff8e5; border-left: 4px solid #ffb900; padding: 12px; margin: 15px 0;">';
|
||||
echo '<p style="margin: 0 0 10px; color: #856404;"><strong>Update verfügbar!</strong></p>';
|
||||
echo '<a href="' . esc_url( $latest['url'] ) . '" class="button button-primary" target="_blank">Download ZIP von Gitea</a>';
|
||||
@@ -122,7 +127,7 @@ class Minecraft_Modern_Theme_Manager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verarbeitet den Klick auf "Jetzt prüfen"
|
||||
* Verarbeitet den Klick auf "Update-Cache jetzt leeren".
|
||||
*/
|
||||
public function handle_refresh_request() {
|
||||
if ( isset( $_GET['mm_refresh_check'] ) && check_admin_referer( 'mm_refresh_action' ) ) {
|
||||
@@ -133,5 +138,4 @@ class Minecraft_Modern_Theme_Manager {
|
||||
}
|
||||
}
|
||||
|
||||
// Initialisierung
|
||||
new Minecraft_Modern_Theme_Manager();
|
||||
Reference in New Issue
Block a user