1583 lines
72 KiB
PHP
1583 lines
72 KiB
PHP
<?php
|
|
/**
|
|
* BlueSky MC Theme - functions.php
|
|
* Vollständiges Backend - alles über WordPress Admin bearbeitbar
|
|
*/
|
|
defined('ABSPATH') || exit;
|
|
|
|
// ============================================================
|
|
// THEME SETUP
|
|
// ============================================================
|
|
function bluesky_setup() {
|
|
add_theme_support('title-tag');
|
|
add_theme_support('custom-logo', ['height'=>40,'width'=>40,'flex-height'=>true,'flex-width'=>true]);
|
|
add_theme_support('post-thumbnails');
|
|
add_theme_support('html5', ['search-form','comment-form','comment-list','gallery','caption']);
|
|
load_theme_textdomain('bluesky-mc', get_template_directory() . '/languages');
|
|
register_nav_menus(['primary' => 'Hauptmenü']);
|
|
}
|
|
add_action('after_setup_theme', 'bluesky_setup');
|
|
|
|
// ============================================================
|
|
// ENQUEUE
|
|
// ============================================================
|
|
function bluesky_enqueue() {
|
|
wp_enqueue_style('bluesky-style', get_stylesheet_uri(), [], '2.0.0');
|
|
// Dynamic CSS-Variablen aus Backend
|
|
$main_color = get_option('bluesky_color_main', '#39BEFF');
|
|
$bg_color = get_option('bluesky_color_bg', '#24272B');
|
|
$desc_color = get_option('bluesky_color_desc', '#D2D0D0');
|
|
$green_color= get_option('bluesky_color_green', '#4AFF6B');
|
|
$red_color = get_option('bluesky_color_red', '#FF7C7C');
|
|
$custom_css = "
|
|
:root {
|
|
--main-color: {$main_color};
|
|
--background-color: {$bg_color};
|
|
--description-color: {$desc_color};
|
|
--green-color: {$green_color};
|
|
--red-color: {$red_color};
|
|
--copy-ip-button-background: " . bluesky_hex_to_rgba($main_color, 0.7) . ";
|
|
--stat-icon-background-2: " . bluesky_hex_to_rgba($main_color, 0.5) . ";
|
|
--ip-copied-background: " . bluesky_hex_to_rgba($green_color, 0.17) . ";
|
|
--warning-background: " . bluesky_hex_to_rgba($red_color, 0.17) . ";
|
|
}
|
|
html, body { background-color: {$bg_color} !important; }
|
|
";
|
|
wp_add_inline_style('bluesky-style', $custom_css);
|
|
|
|
wp_enqueue_script('bluesky-main', get_template_directory_uri() . '/js/main.js', [], '2.0.4', true);
|
|
wp_localize_script('bluesky-main', 'BlueSkyConfig', [
|
|
'serverIp' => get_option('bluesky_server_ip', 'mc.example.com'),
|
|
'discordServerId' => get_option('bluesky_discord_server_id', ''),
|
|
'skinType' => get_option('bluesky_skin_type', 'bust'),
|
|
'teamData' => bluesky_get_team_data_for_js(),
|
|
'ajaxUrl' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('bluesky_nonce'),
|
|
]);
|
|
}
|
|
add_action('wp_enqueue_scripts', 'bluesky_enqueue');
|
|
|
|
// Helper: hex to rgba
|
|
function bluesky_hex_to_rgba($hex, $alpha = 1) {
|
|
$hex = ltrim($hex, '#');
|
|
if (strlen($hex) === 3) $hex = $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2];
|
|
list($r,$g,$b) = array_map('hexdec', str_split($hex, 2));
|
|
return "rgba($r,$g,$b,$alpha)";
|
|
}
|
|
|
|
// ============================================================
|
|
// CUSTOM POST TYPES
|
|
// ============================================================
|
|
function bluesky_register_post_types() {
|
|
$types = [
|
|
'bluesky_team' => ['label'=>'Team Mitglieder','icon'=>'dashicons-groups','pos'=>25,'public'=>false,'supports'=>['title','thumbnail']],
|
|
'bluesky_wiki' => ['label'=>'Wiki Artikel','icon'=>'dashicons-book-alt','pos'=>26,'public'=>true,'supports'=>['title','editor','thumbnail'],'archive'=>true,'slug'=>'wiki-artikel'],
|
|
'bluesky_rule' => ['label'=>'Server Regeln','icon'=>'dashicons-shield','pos'=>27,'public'=>false,'supports'=>['title']],
|
|
'bluesky_faq' => ['label'=>'FAQs','icon'=>'dashicons-editor-help','pos'=>28,'public'=>false,'supports'=>['title','editor']],
|
|
'bluesky_vote' => ['label'=>'Vote Links','icon'=>'dashicons-star-filled','pos'=>29,'public'=>false,'supports'=>['title']],
|
|
'bluesky_gamemode' => ['label'=>'Spielmodi','icon'=>'dashicons-games','pos'=>30,'public'=>true,'supports'=>['title','editor','thumbnail']],
|
|
];
|
|
foreach ($types as $key => $t) {
|
|
$args = [
|
|
'label' => $t['label'],
|
|
'public' => $t['public'],
|
|
'show_ui' => true,
|
|
'show_in_menu' => true,
|
|
'menu_icon' => $t['icon'],
|
|
'menu_position'=> $t['pos'],
|
|
'supports' => $t['supports'],
|
|
'show_in_rest' => true,
|
|
];
|
|
if (!empty($t['archive'])) $args['has_archive'] = true;
|
|
if (!empty($t['slug'])) $args['rewrite'] = ['slug' => $t['slug']];
|
|
register_post_type($key, $args);
|
|
}
|
|
}
|
|
add_action('init', 'bluesky_register_post_types');
|
|
|
|
// Rule entries use a custom editor layout, not Gutenberg.
|
|
add_filter('use_block_editor_for_post_type', function($use_block_editor, $post_type) {
|
|
if ($post_type === 'bluesky_rule') return false;
|
|
return $use_block_editor;
|
|
}, 10, 2);
|
|
|
|
// ============================================================
|
|
// TAXONOMIES
|
|
// ============================================================
|
|
function bluesky_register_taxonomies() {
|
|
register_taxonomy('team_rank', 'bluesky_team', ['label'=>'Ränge','hierarchical'=>false,'show_in_rest'=>true,'rewrite'=>false,'show_admin_column'=>true]);
|
|
register_taxonomy('wiki_category', 'bluesky_wiki', ['label'=>'Wiki Kategorien','hierarchical'=>true,'show_in_rest'=>true,'rewrite'=>['slug'=>'wiki-kategorie'],'show_admin_column'=>true]);
|
|
register_taxonomy('rule_category', 'bluesky_rule', ['label'=>'Regelkategorien','hierarchical'=>true,'show_in_rest'=>true,'rewrite'=>false,'show_admin_column'=>true]);
|
|
}
|
|
add_action('init', 'bluesky_register_taxonomies');
|
|
|
|
// ============================================================
|
|
// META BOXES
|
|
// ============================================================
|
|
function bluesky_add_meta_boxes() {
|
|
add_meta_box('bluesky_team_meta', 'Mitglied Details', 'bluesky_team_meta_cb', 'bluesky_team', 'normal', 'high');
|
|
add_meta_box('bluesky_vote_meta', 'Vote Link Details', 'bluesky_vote_meta_cb', 'bluesky_vote', 'normal', 'high');
|
|
add_meta_box('bluesky_gamemode_meta', 'Spielmodus Details', 'bluesky_gamemode_meta_cb', 'bluesky_gamemode', 'normal', 'high');
|
|
add_meta_box('bluesky_rule_meta', 'Regel Details', 'bluesky_rule_meta_cb', 'bluesky_rule', 'normal', 'high');
|
|
}
|
|
add_action('add_meta_boxes', 'bluesky_add_meta_boxes');
|
|
|
|
function bluesky_team_meta_cb($post) {
|
|
wp_nonce_field('bluesky_team_nonce_action', 'bluesky_team_nonce');
|
|
$f = fn($k) => get_post_meta($post->ID, "_bluesky_$k", true);
|
|
$skin_preview = $f('skin_url') ?: ('https://crafthead.net/bust/' . ($f('in_game_name') ?: 'ec561538f3fd461daff5086b22154bce') . '/128');
|
|
$rank_empty = empty($f('rank'));
|
|
?>
|
|
<style>.bs-meta td{padding:8px 5px;}.bs-meta input,.bs-meta select{width:100%;max-width:400px;} .skin-preview{width:100px;border-radius:5px;image-rendering:pixelated;}</style>
|
|
<?php if ($rank_empty): ?>
|
|
<div class="notice notice-warning inline" style="margin:10px 0"><p>⚠️ <strong>Rang ist leer!</strong> Bitte Rang eintragen und speichern — sonst wird "—" auf der Team-Seite angezeigt.</p></div>
|
|
<?php endif; ?>
|
|
<table class="form-table bs-meta">
|
|
<tr><th>In-Game Name *</th><td><input type="text" name="bluesky_in_game_name" value="<?php echo esc_attr($f('in_game_name')); ?>" placeholder="z.B. MuckiDEE"><p class="description">Minecraft Username — Skin wird automatisch geladen (Original-Account vorausgesetzt).</p></td><td rowspan="6" style="vertical-align:top;padding-left:20px"><img id="skin_preview_img" src="<?php echo esc_url($skin_preview); ?>" class="skin-preview"><br><small style="color:#aaa">Skin-Vorschau</small></td></tr>
|
|
<tr><th><label style="color:<?php echo $rank_empty ? '#ffb900' : 'inherit'; ?>">Rang *<?php echo $rank_empty ? ' ⚠️' : ''; ?></label></th><td><input type="text" name="bluesky_rank" value="<?php echo esc_attr($f('rank')); ?>" placeholder="z.B. Owner, Admin, Moderator" style="<?php echo $rank_empty ? 'border-color:#ffb900;' : ''; ?>"></td></tr>
|
|
<tr><th>Rangfarbe</th><td><input type="color" name="bluesky_rank_color_hex" value="<?php echo esc_attr(bluesky_rgba_to_hex($f('rank_color')) ?: '#ff0000'); ?>" style="width:60px;height:40px;border:none;cursor:pointer"> <input type="text" name="bluesky_rank_color" value="<?php echo esc_attr($f('rank_color') ?: 'rgba(156, 0, 0, 1)'); ?>" style="max-width:280px" placeholder="rgba(156, 0, 0, 1)"><p class="description">Kann rgba() oder #hex sein.</p></td></tr>
|
|
<tr><th>Gruppe</th><td><input type="text" name="bluesky_team_group" value="<?php echo esc_attr($f('team_group') ?: 'Team'); ?>" placeholder="Team, special, ..."><p class="description">Bestimmt die Gruppenüberschrift auf der Team-Seite.</p></td></tr>
|
|
<tr><th>Eigene Skin-URL</th><td><input type="url" name="bluesky_skin_url" value="<?php echo esc_url($f('skin_url')); ?>" placeholder="Leer lassen für Auto-Load (Original-Account)"><p class="description">Nur für Cracked/Offline-Accounts nötig.</p></td></tr>
|
|
<tr><th>Reihenfolge</th><td><input type="number" name="bluesky_sort_order" value="<?php echo esc_attr($f('sort_order') ?: 0); ?>" style="max-width:80px" min="0"></td></tr>
|
|
</table>
|
|
<script>
|
|
document.querySelector('[name="bluesky_rank_color_hex"]').addEventListener('input', function(){
|
|
document.querySelector('[name="bluesky_rank_color"]').value = this.value;
|
|
});
|
|
document.querySelector('[name="bluesky_in_game_name"]').addEventListener('change', function(){
|
|
if(!document.querySelector('[name="bluesky_skin_url"]').value){
|
|
document.getElementById('skin_preview_img').src = 'https://crafthead.net/bust/' + this.value + '/128';
|
|
}
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
function bluesky_vote_meta_cb($post) {
|
|
wp_nonce_field('bluesky_vote_nonce_action', 'bluesky_vote_nonce');
|
|
$url = get_post_meta($post->ID, '_bluesky_vote_url', true);
|
|
$desc = get_post_meta($post->ID, '_bluesky_vote_description', true);
|
|
?>
|
|
<table class="form-table">
|
|
<tr><th>Vote URL *</th><td><input type="url" name="bluesky_vote_url" value="<?php echo esc_url($url); ?>" class="large-text" placeholder="https://minecraft-server.eu/vote/..."></td></tr>
|
|
<tr><th>Beschreibung</th><td><input type="text" name="bluesky_vote_description" value="<?php echo esc_attr($desc ?: 'Klicke hier um jetzt zu Voten.'); ?>" class="large-text"></td></tr>
|
|
</table>
|
|
<?php
|
|
}
|
|
|
|
function bluesky_gamemode_meta_cb($post) {
|
|
wp_nonce_field('bluesky_gamemode_nonce_action', 'bluesky_gamemode_nonce');
|
|
$services = get_post_meta($post->ID, '_bluesky_gamemode_services', true);
|
|
?>
|
|
<table class="form-table">
|
|
<tr><th>Features (kommagetrennt)</th><td><input type="text" name="bluesky_gamemode_services" value="<?php echo esc_attr($services); ?>" class="large-text" placeholder="Jobs, Pet, Shops, und mehr"><p class="description">Werden als Liste unter dem Text angezeigt.</p></td></tr>
|
|
</table>
|
|
<?php
|
|
}
|
|
|
|
function bluesky_rule_meta_cb($post) {
|
|
wp_nonce_field('bluesky_rule_nonce_action', 'bluesky_rule_nonce');
|
|
$section_id = get_post_meta($post->ID, '_bluesky_rule_section_id', true);
|
|
$sort_order = get_post_meta($post->ID, '_bluesky_rule_sort_order', true);
|
|
$rule_items = get_post_meta($post->ID, '_bluesky_rule_items', true);
|
|
?>
|
|
<div class="bluesky-rule-editor">
|
|
<div class="bluesky-rule-editor__intro">
|
|
<strong>Eigener Regeln-Editor</strong>
|
|
<p>Eine Regel pro Zeile eintragen. Der WordPress-Inhaltseditor wird für Regeln nicht genutzt.</p>
|
|
</div>
|
|
|
|
<div class="bluesky-rule-editor__field">
|
|
<label for="bluesky_rule_items"><strong>Regeln (eine Zeile je Regel)</strong></label>
|
|
<textarea id="bluesky_rule_items" name="bluesky_rule_items" rows="10" class="large-text" placeholder="Beleidigungen sind verboten. Cheating ist verboten."><?php echo esc_textarea($rule_items); ?></textarea>
|
|
</div>
|
|
|
|
<div class="bluesky-rule-editor__grid">
|
|
<div class="bluesky-rule-editor__field">
|
|
<label for="bluesky_rule_section_id"><strong>Abschnitts-ID (Anker)</strong></label>
|
|
<input id="bluesky_rule_section_id" type="text" name="bluesky_rule_section_id" value="<?php echo esc_attr($section_id); ?>" class="regular-text" placeholder="regel-1">
|
|
<p class="description">Für Verlinkung wie /regeln/#regel-1</p>
|
|
</div>
|
|
<div class="bluesky-rule-editor__field">
|
|
<label for="bluesky_rule_sort_order"><strong>Reihenfolge</strong></label>
|
|
<input id="bluesky_rule_sort_order" type="number" name="bluesky_rule_sort_order" value="<?php echo esc_attr($sort_order ?: 0); ?>" class="small-text" min="0">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
function bluesky_rule_editor_admin_styles() {
|
|
$screen = get_current_screen();
|
|
if (!$screen || $screen->post_type !== 'bluesky_rule') return;
|
|
?>
|
|
<style>
|
|
body.post-type-bluesky_rule #post-body-content,
|
|
body.post-type-bluesky_rule .edit-form-section {
|
|
margin-bottom: 14px;
|
|
}
|
|
body.post-type-bluesky_rule #titlediv,
|
|
body.post-type-bluesky_rule #poststuff .postbox {
|
|
border: 1px solid #dcdcde;
|
|
border-radius: 10px;
|
|
overflow: hidden;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.04);
|
|
}
|
|
body.post-type-bluesky_rule #titlediv {
|
|
padding: 14px;
|
|
background: #ffffff;
|
|
}
|
|
body.post-type-bluesky_rule #titlediv #title {
|
|
border-radius: 8px;
|
|
border-color: #c3c4c7;
|
|
min-height: 46px;
|
|
padding: 10px 14px;
|
|
font-size: 18px;
|
|
}
|
|
body.post-type-bluesky_rule #poststuff .postbox .hndle {
|
|
border-bottom: 1px solid #e6e6e8;
|
|
background: #f9f9fb;
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
}
|
|
body.post-type-bluesky_rule #poststuff .inside {
|
|
margin: 0;
|
|
padding: 16px;
|
|
background: #fff;
|
|
}
|
|
body.post-type-bluesky_rule .bluesky-rule-editor__intro {
|
|
background: #f6f9fc;
|
|
border: 1px solid #d4e2ef;
|
|
border-left: 4px solid #2271b1;
|
|
border-radius: 8px;
|
|
padding: 10px 12px;
|
|
margin-bottom: 14px;
|
|
}
|
|
body.post-type-bluesky_rule .bluesky-rule-editor__intro p {
|
|
margin: 6px 0 0;
|
|
color: #50575e;
|
|
}
|
|
body.post-type-bluesky_rule .bluesky-rule-editor__field {
|
|
margin-bottom: 12px;
|
|
}
|
|
body.post-type-bluesky_rule .bluesky-rule-editor__field label {
|
|
display: block;
|
|
margin-bottom: 6px;
|
|
}
|
|
body.post-type-bluesky_rule .bluesky-rule-editor__field textarea {
|
|
width: 100%;
|
|
border-radius: 8px;
|
|
border-color: #c3c4c7;
|
|
font-family: Consolas, monospace;
|
|
line-height: 1.5;
|
|
padding: 10px;
|
|
}
|
|
body.post-type-bluesky_rule .bluesky-rule-editor__grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 180px;
|
|
gap: 12px;
|
|
align-items: end;
|
|
}
|
|
@media (max-width: 782px) {
|
|
body.post-type-bluesky_rule .bluesky-rule-editor__grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style>
|
|
<?php
|
|
}
|
|
add_action('admin_head-post.php', 'bluesky_rule_editor_admin_styles');
|
|
add_action('admin_head-post-new.php', 'bluesky_rule_editor_admin_styles');
|
|
|
|
// Save Meta
|
|
function bluesky_save_team_meta($post_id) {
|
|
if (!isset($_POST['bluesky_team_nonce']) || !wp_verify_nonce($_POST['bluesky_team_nonce'], 'bluesky_team_nonce_action')) return;
|
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
|
|
if (!current_user_can('edit_post', $post_id)) return;
|
|
foreach (['in_game_name','rank','rank_color','skin_url','team_group','sort_order'] as $f) {
|
|
if (isset($_POST["bluesky_$f"])) update_post_meta($post_id, "_bluesky_$f", sanitize_text_field($_POST["bluesky_$f"]));
|
|
}
|
|
}
|
|
add_action('save_post_bluesky_team', 'bluesky_save_team_meta');
|
|
|
|
function bluesky_save_vote_meta($post_id) {
|
|
if (!isset($_POST['bluesky_vote_nonce']) || !wp_verify_nonce($_POST['bluesky_vote_nonce'], 'bluesky_vote_nonce_action')) return;
|
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
|
|
if (!current_user_can('edit_post', $post_id)) return;
|
|
if (isset($_POST['bluesky_vote_url'])) update_post_meta($post_id, '_bluesky_vote_url', esc_url_raw($_POST['bluesky_vote_url']));
|
|
if (isset($_POST['bluesky_vote_description'])) update_post_meta($post_id, '_bluesky_vote_description', sanitize_text_field($_POST['bluesky_vote_description']));
|
|
}
|
|
add_action('save_post_bluesky_vote', 'bluesky_save_vote_meta');
|
|
|
|
function bluesky_save_gamemode_meta($post_id) {
|
|
if (!isset($_POST['bluesky_gamemode_nonce']) || !wp_verify_nonce($_POST['bluesky_gamemode_nonce'], 'bluesky_gamemode_nonce_action')) return;
|
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
|
|
if (!current_user_can('edit_post', $post_id)) return;
|
|
if (isset($_POST['bluesky_gamemode_services'])) update_post_meta($post_id, '_bluesky_gamemode_services', sanitize_text_field($_POST['bluesky_gamemode_services']));
|
|
}
|
|
add_action('save_post_bluesky_gamemode', 'bluesky_save_gamemode_meta');
|
|
|
|
function bluesky_save_rule_meta($post_id) {
|
|
if (!isset($_POST['bluesky_rule_nonce']) || !wp_verify_nonce($_POST['bluesky_rule_nonce'], 'bluesky_rule_nonce_action')) return;
|
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
|
|
if (!current_user_can('edit_post', $post_id)) return;
|
|
if (isset($_POST['bluesky_rule_items'])) {
|
|
$normalized = preg_replace("/\r\n?|\n/", "\n", wp_unslash($_POST['bluesky_rule_items']));
|
|
update_post_meta($post_id, '_bluesky_rule_items', sanitize_textarea_field($normalized));
|
|
}
|
|
if (isset($_POST['bluesky_rule_section_id'])) update_post_meta($post_id, '_bluesky_rule_section_id', sanitize_text_field($_POST['bluesky_rule_section_id']));
|
|
if (isset($_POST['bluesky_rule_sort_order'])) update_post_meta($post_id, '_bluesky_rule_sort_order', intval($_POST['bluesky_rule_sort_order']));
|
|
}
|
|
add_action('save_post_bluesky_rule', 'bluesky_save_rule_meta');
|
|
|
|
// ============================================================
|
|
// ADMIN MENÜ
|
|
// ============================================================
|
|
function bluesky_admin_menu() {
|
|
add_menu_page('BlueSky MC', 'BlueSky MC', 'manage_options', 'bluesky-settings', 'bluesky_settings_page', 'dashicons-admin-site-alt3', 3);
|
|
add_submenu_page('bluesky-settings', 'Server & Allgemein', 'Server & Allgemein', 'manage_options', 'bluesky-settings', 'bluesky_settings_page');
|
|
add_submenu_page('bluesky-settings', 'Design & Farben', 'Design & Farben', 'manage_options', 'bluesky-design', 'bluesky_design_page');
|
|
add_submenu_page('bluesky-settings', 'Navbar & Footer', 'Navbar & Footer', 'manage_options', 'bluesky-navbar', 'bluesky_navbar_page');
|
|
add_submenu_page('bluesky-settings', 'Homepage Texte', 'Homepage Texte', 'manage_options', 'bluesky-homepage', 'bluesky_homepage_page');
|
|
add_submenu_page('bluesky-settings', 'Bilder & Medien', 'Bilder & Medien', 'manage_options', 'bluesky-images', 'bluesky_images_page');
|
|
add_submenu_page('bluesky-settings', 'Impressum & Datenschutz','Impressum', 'manage_options', 'bluesky-impressum', 'bluesky_impressum_page');
|
|
}
|
|
add_action('admin_menu', 'bluesky_admin_menu');
|
|
|
|
// Enqueue Media Uploader on our pages
|
|
function bluesky_admin_scripts($hook) {
|
|
if (strpos($hook, 'bluesky') !== false) {
|
|
wp_enqueue_media();
|
|
wp_enqueue_style('wp-color-picker');
|
|
wp_enqueue_script('wp-color-picker');
|
|
wp_add_inline_style('wp-color-picker', '
|
|
.bluesky-admin-subtitle {
|
|
color: #50575e;
|
|
margin: 4px 0 16px;
|
|
font-size: 13px;
|
|
}
|
|
.bluesky-admin-intro {
|
|
background: #fff;
|
|
border: 1px solid #dcdcde;
|
|
border-left: 4px solid #2271b1;
|
|
border-radius: 8px;
|
|
padding: 14px 16px;
|
|
margin: 0 0 18px;
|
|
box-shadow: 0 1px 1px rgba(0,0,0,0.03);
|
|
}
|
|
.bluesky-admin-intro h2 {
|
|
margin: 0 0 8px;
|
|
font-size: 17px;
|
|
line-height: 1.3;
|
|
}
|
|
.bluesky-admin-intro p {
|
|
margin: 0;
|
|
color: #2c3338;
|
|
}
|
|
.bluesky-admin-steps {
|
|
margin: 10px 0 0 20px;
|
|
}
|
|
.bluesky-admin-steps li {
|
|
margin: 5px 0;
|
|
color: #2c3338;
|
|
}
|
|
.bluesky-admin-form {
|
|
background: #fff;
|
|
border: 1px solid #dcdcde;
|
|
border-radius: 8px;
|
|
padding: 10px 18px 18px;
|
|
box-shadow: 0 1px 1px rgba(0,0,0,0.03);
|
|
}
|
|
.bluesky-admin-form h2 {
|
|
margin-top: 24px;
|
|
padding-bottom: 8px;
|
|
border-bottom: 1px solid #dcdcde;
|
|
font-size: 17px;
|
|
}
|
|
.bluesky-admin-form h2:first-of-type {
|
|
margin-top: 6px;
|
|
}
|
|
.bluesky-admin-form .form-table th {
|
|
width: 240px;
|
|
font-weight: 600;
|
|
}
|
|
.bluesky-admin-form .form-table td .description {
|
|
margin-top: 6px;
|
|
color: #50575e;
|
|
}
|
|
.bluesky-admin-form .submit {
|
|
margin-top: 10px;
|
|
padding-top: 10px;
|
|
border-top: 1px solid #dcdcde;
|
|
}
|
|
');
|
|
wp_add_inline_script('wp-color-picker', '
|
|
jQuery(document).ready(function($){
|
|
$(".bluesky-color").wpColorPicker();
|
|
$(".bluesky-upload-btn").on("click", function(e){
|
|
e.preventDefault();
|
|
var btn = $(this);
|
|
var target = btn.data("target");
|
|
var preview = btn.data("preview");
|
|
var frame = wp.media({title: "Bild auswählen", button:{text:"Auswählen"}, multiple:false});
|
|
frame.on("select", function(){
|
|
var att = frame.state().get("selection").first().toJSON();
|
|
$("#"+target).val(att.url);
|
|
if(preview) $("#"+preview).attr("src", att.url).show();
|
|
});
|
|
frame.open();
|
|
});
|
|
});');
|
|
}
|
|
}
|
|
add_action('admin_enqueue_scripts', 'bluesky_admin_scripts');
|
|
|
|
// ============================================================
|
|
// SETTINGS PAGES
|
|
// ============================================================
|
|
|
|
// --- Helper: save & header ---
|
|
function bluesky_save_options($nonce_action, $nonce_field, $fields, $url_fields = [], $wysiwyg_fields = []) {
|
|
if (!isset($_POST[$nonce_field]) || !wp_verify_nonce($_POST[$nonce_field], $nonce_action)) return false;
|
|
foreach ($fields as $f) if (isset($_POST[$f])) update_option($f, sanitize_text_field($_POST[$f]));
|
|
foreach ($url_fields as $f) if (isset($_POST[$f])) update_option($f, esc_url_raw($_POST[$f]));
|
|
foreach ($wysiwyg_fields as $f) if (isset($_POST[$f])) update_option($f, wp_kses_post($_POST[$f]));
|
|
return true;
|
|
}
|
|
|
|
function bluesky_admin_header($title, $icon = '🎮') {
|
|
echo '<div class="wrap"><h1 style="display:flex;align-items:center;gap:10px">' . $icon . ' ' . esc_html($title) . '</h1>';
|
|
echo '<p class="bluesky-admin-subtitle">BlueSky MC Theme — ' . esc_html($title) . '</p>';
|
|
}
|
|
|
|
function bluesky_admin_intro($headline, $description, $steps = []) {
|
|
echo '<div class="bluesky-admin-intro">';
|
|
echo '<h2>' . esc_html($headline) . '</h2>';
|
|
echo '<p>' . esc_html($description) . '</p>';
|
|
if (!empty($steps)) {
|
|
echo '<ol class="bluesky-admin-steps">';
|
|
foreach ($steps as $step) {
|
|
echo '<li>' . esc_html($step) . '</li>';
|
|
}
|
|
echo '</ol>';
|
|
}
|
|
echo '</div>';
|
|
}
|
|
|
|
// 1. Server & Allgemein
|
|
function bluesky_settings_page() {
|
|
if (!current_user_can('manage_options')) wp_die('Kein Zugriff');
|
|
$saved = bluesky_save_options('bluesky_save_settings', 'bluesky_settings_nonce',
|
|
['bluesky_server_name','bluesky_server_ip','bluesky_discord_server_id','bluesky_skin_type'],
|
|
['bluesky_discord_link']);
|
|
if ($saved) echo '<div class="updated notice is-dismissible"><p>✅ Gespeichert!</p></div>';
|
|
|
|
bluesky_admin_header('Server & Allgemein', '🖥️');
|
|
bluesky_admin_intro(
|
|
'Schnellstart',
|
|
'Diese Seite steuert die wichtigsten Basisdaten des Servers.',
|
|
[
|
|
'Server Name und IP eintragen',
|
|
'Discord-ID nur setzen, wenn das Discord-Widget aktiv ist',
|
|
'Speichern klicken und Frontend neu laden'
|
|
]
|
|
);
|
|
$skin_types = ['full','bust','head','face','front','frontFull','skin'];
|
|
?>
|
|
<form method="post" class="bluesky-admin-form">
|
|
<?php wp_nonce_field('bluesky_save_settings', 'bluesky_settings_nonce'); ?>
|
|
<table class="form-table">
|
|
<tr><th>Server Name</th><td><input type="text" name="bluesky_server_name" value="<?php echo esc_attr(get_option('bluesky_server_name','BlueSky')); ?>" class="regular-text"><p class="description">Wird im Navbar, Footer und Titel angezeigt.</p></td></tr>
|
|
<tr><th>Server IP</th><td><input type="text" name="bluesky_server_ip" value="<?php echo esc_attr(get_option('bluesky_server_ip','mc.example.com')); ?>" class="regular-text"><p class="description">Für Copy-IP Button und Online-Spieler-Counter.</p></td></tr>
|
|
<tr><th>Discord Server ID</th><td><input type="text" name="bluesky_discord_server_id" value="<?php echo esc_attr(get_option('bluesky_discord_server_id','')); ?>" class="regular-text"><p class="description">Für Online-User-Anzeige. Discord Widget muss aktiviert sein (Server-Einstellungen → Widget).</p></td></tr>
|
|
<tr><th>Discord Einladungslink</th><td><input type="url" name="bluesky_discord_link" value="<?php echo esc_url(get_option('bluesky_discord_link','#')); ?>" class="large-text" placeholder="https://discord.gg/..."></td></tr>
|
|
<tr><th>Skin Darstellungstyp</th><td>
|
|
<select name="bluesky_skin_type"><?php foreach($skin_types as $t): ?>
|
|
<option value="<?php echo $t; ?>" <?php selected(get_option('bluesky_skin_type','bust'),$t); ?>><?php echo $t; ?></option>
|
|
<?php endforeach; ?></select>
|
|
<p class="description">Wie der Minecraft-Skin auf der Team-Seite aussieht.</p>
|
|
</td></tr>
|
|
</table>
|
|
<?php submit_button('Speichern'); ?>
|
|
</form></div>
|
|
<?php
|
|
}
|
|
|
|
// 2. Design & Farben
|
|
function bluesky_design_page() {
|
|
if (!current_user_can('manage_options')) wp_die('Kein Zugriff');
|
|
$saved = bluesky_save_options('bluesky_save_design', 'bluesky_design_nonce',
|
|
['bluesky_color_main','bluesky_color_bg','bluesky_color_desc','bluesky_color_green','bluesky_color_red','bluesky_custom_css']);
|
|
if ($saved) echo '<div class="updated notice is-dismissible"><p>✅ Farben & Design gespeichert!</p></div>';
|
|
|
|
bluesky_admin_header('Design & Farben', '🎨');
|
|
bluesky_admin_intro(
|
|
'Farben einfach einstellen',
|
|
'Passe zuerst nur die 5 Farben an. Eigenes CSS ist optional für Fortgeschrittene.',
|
|
[
|
|
'Hauptfarbe definieren',
|
|
'Hintergrund und Textfarbe prüfen',
|
|
'Dann optional eigenes CSS ergänzen'
|
|
]
|
|
);
|
|
$colors = [
|
|
'bluesky_color_main' => ['Hauptfarbe (Akzent)', '#39BEFF', 'Links, Buttons, Highlights'],
|
|
'bluesky_color_bg' => ['Hintergrundfarbe', '#24272B', 'Seiten-Hintergrund'],
|
|
'bluesky_color_desc' => ['Text / Beschreibungsfarbe','#D2D0D0', 'Normaler Fließtext'],
|
|
'bluesky_color_green' => ['Erfolgsfarbe (Grün)', '#4AFF6B', 'Bestätigungen, Online-Anzeige'],
|
|
'bluesky_color_red' => ['Warnfarbe (Rot)', '#FF7C7C', 'Warnungen, Fehler'],
|
|
];
|
|
?>
|
|
<form method="post" class="bluesky-admin-form">
|
|
<?php wp_nonce_field('bluesky_save_design', 'bluesky_design_nonce'); ?>
|
|
<h2>Farben</h2>
|
|
<table class="form-table">
|
|
<?php foreach($colors as $key => [$label, $default, $desc]): ?>
|
|
<tr>
|
|
<th><?php echo esc_html($label); ?></th>
|
|
<td>
|
|
<input type="text" name="<?php echo $key; ?>" value="<?php echo esc_attr(get_option($key, $default)); ?>" class="bluesky-color regular-text" data-default-color="<?php echo $default; ?>">
|
|
<p class="description"><?php echo esc_html($desc); ?></p>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</table>
|
|
<h2>Eigenes CSS</h2>
|
|
<p class="description">Hier kannst du eigenes CSS hinzufügen das die Theme-Styles ergänzt oder überschreibt.</p>
|
|
<textarea name="bluesky_custom_css" rows="10" style="width:100%;font-family:monospace;background:#1e1e1e;color:#d4d4d4;padding:15px;border-radius:5px"><?php echo esc_textarea(get_option('bluesky_custom_css','')); ?></textarea>
|
|
<?php submit_button('Farben & Design speichern'); ?>
|
|
</form></div>
|
|
<?php
|
|
// Output custom CSS
|
|
$custom_css = get_option('bluesky_custom_css','');
|
|
if ($custom_css) add_action('wp_head', fn() => print("<style>$custom_css</style>"), 99);
|
|
}
|
|
|
|
// 3. Navbar & Footer
|
|
function bluesky_navbar_page() {
|
|
if (!current_user_can('manage_options')) wp_die('Kein Zugriff');
|
|
$saved = bluesky_save_options('bluesky_save_navbar', 'bluesky_navbar_nonce',
|
|
['bluesky_nav_home_label','bluesky_nav_wiki_label','bluesky_nav_rules_label','bluesky_nav_team_label',
|
|
'bluesky_nav_home_url','bluesky_nav_wiki_url','bluesky_nav_rules_url','bluesky_nav_team_url',
|
|
'bluesky_footer_copyright','bluesky_server_name'],
|
|
['bluesky_footer_impressum_url','bluesky_footer_datenschutz_url']);
|
|
if ($saved) echo '<div class="updated notice is-dismissible"><p>✅ Navbar & Footer gespeichert!</p></div>';
|
|
|
|
bluesky_admin_header('Navbar & Footer', '🔗');
|
|
bluesky_admin_intro(
|
|
'Navigation bearbeiten',
|
|
'Hier passt du Menütexte, Links und Footer-Beschriftungen an.',
|
|
[
|
|
'Label = sichtbarer Text',
|
|
'URL immer mit / beginnen (z.B. /wiki/)',
|
|
'Nach Änderungen speichern'
|
|
]
|
|
);
|
|
?>
|
|
<form method="post" class="bluesky-admin-form">
|
|
<?php wp_nonce_field('bluesky_save_navbar', 'bluesky_navbar_nonce'); ?>
|
|
<h2>Navbar Links</h2>
|
|
<table class="form-table">
|
|
<?php
|
|
$nav_items = [
|
|
'home' => 'Startseite',
|
|
'wiki' => 'Wiki',
|
|
'rules' => 'Regeln',
|
|
'team' => 'Team',
|
|
];
|
|
$defaults_label = ['home'=>'Home','wiki'=>'Wiki','rules'=>'Regeln','team'=>'Team'];
|
|
$defaults_url = ['home'=>'/', 'wiki'=>'/wiki/', 'rules'=>'/regeln/', 'team'=>'/team/'];
|
|
foreach ($nav_items as $key => $desc):
|
|
?>
|
|
<tr>
|
|
<th><?php echo esc_html($desc); ?></th>
|
|
<td>
|
|
Label: <input type="text" name="bluesky_nav_<?php echo $key; ?>_label" value="<?php echo esc_attr(get_option("bluesky_nav_{$key}_label", $defaults_label[$key])); ?>" style="width:120px">
|
|
URL: <input type="text" name="bluesky_nav_<?php echo $key; ?>_url" value="<?php echo esc_attr(get_option("bluesky_nav_{$key}_url", $defaults_url[$key])); ?>" style="width:200px">
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</table>
|
|
<h2>Logo / Server-Name in Navbar</h2>
|
|
<table class="form-table">
|
|
<tr><th>Server Name (Navbar)</th><td><input type="text" name="bluesky_server_name" value="<?php echo esc_attr(get_option('bluesky_server_name','BlueSky')); ?>" class="regular-text"><p class="description">Wird neben dem Logo angezeigt.</p></td></tr>
|
|
</table>
|
|
<h2>Footer</h2>
|
|
<table class="form-table">
|
|
<tr>
|
|
<th>Footer Version</th>
|
|
<td>
|
|
<input type="text" value="Code-gesteuert" class="regular-text" disabled>
|
|
<p class="description">Die Footer-Version bleibt fest im Code und kann hier nicht geaendert werden.</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Impressum Link URL</th>
|
|
<td>
|
|
<input type="url" name="bluesky_footer_impressum_url" value="<?php echo esc_url(get_option('bluesky_footer_impressum_url', home_url('/impressum/#impressum'))); ?>" class="large-text" placeholder="https://... oder /impressum/#impressum">
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Datenschutz Link URL</th>
|
|
<td>
|
|
<input type="url" name="bluesky_footer_datenschutz_url" value="<?php echo esc_url(get_option('bluesky_footer_datenschutz_url', home_url('/impressum/#datenschutz'))); ?>" class="large-text" placeholder="https://... oder /impressum/#datenschutz">
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<?php submit_button('Navbar & Footer speichern'); ?>
|
|
</form></div>
|
|
<?php
|
|
}
|
|
|
|
// 4. Homepage Texte
|
|
function bluesky_homepage_page() {
|
|
if (!current_user_can('manage_options')) wp_die('Kein Zugriff');
|
|
$saved = bluesky_save_options('bluesky_save_homepage', 'bluesky_homepage_nonce',
|
|
['bluesky_header_subtitle','bluesky_header_description','bluesky_about_title1','bluesky_about_text1',
|
|
'bluesky_about_title2','bluesky_about_text2','bluesky_vote_description','bluesky_faq_description',
|
|
'bluesky_discord_section_text','bluesky_copy_ip_btn_label','bluesky_see_more_btn_label',
|
|
'bluesky_rules_warning_text','bluesky_header_tag']);
|
|
if ($saved) echo '<div class="updated notice is-dismissible"><p>✅ Homepage-Texte gespeichert!</p></div>';
|
|
|
|
bluesky_admin_header('Homepage Texte', '🏠');
|
|
bluesky_admin_intro(
|
|
'Texte nach Bereichen',
|
|
'Die Felder sind in Homepage-Blöcke aufgeteilt. Du kannst alles ohne Code anpassen.',
|
|
[
|
|
'Oben mit Header-Texten starten',
|
|
'Dann Über Uns und Discord bearbeiten',
|
|
'Zum Schluss speichern'
|
|
]
|
|
);
|
|
?>
|
|
<form method="post" class="bluesky-admin-form">
|
|
<?php wp_nonce_field('bluesky_save_homepage', 'bluesky_homepage_nonce'); ?>
|
|
|
|
<h2>Header</h2>
|
|
<table class="form-table">
|
|
<tr><th>Untertitel (über der IP)</th><td><input type="text" name="bluesky_header_subtitle" value="<?php echo esc_attr(get_option('bluesky_header_subtitle','Survival Minecraft Server')); ?>" class="large-text"></td></tr>
|
|
<tr><th>Beschreibungstext</th><td><textarea name="bluesky_header_description" rows="3" class="large-text"><?php echo esc_textarea(get_option('bluesky_header_description','Erlebe Survival, eigene Welten, Jobs, Haustiere und ein dynamisches Wirtschaftssystem.')); ?></textarea></td></tr>
|
|
<tr><th>"Copy IP" Button Text</th><td><input type="text" name="bluesky_copy_ip_btn_label" value="<?php echo esc_attr(get_option('bluesky_copy_ip_btn_label','Copy IP')); ?>" class="regular-text"></td></tr>
|
|
<tr><th>"Siehe mehr" Button Text</th><td><input type="text" name="bluesky_see_more_btn_label" value="<?php echo esc_attr(get_option('bluesky_see_more_btn_label','Siehe mehr')); ?>" class="regular-text"></td></tr>
|
|
</table>
|
|
|
|
<h2>Über Uns</h2>
|
|
<table class="form-table">
|
|
<tr><th>Abschnitt 1 — Titel</th><td><input type="text" name="bluesky_about_title1" value="<?php echo esc_attr(get_option('bluesky_about_title1','Wer wir sind?')); ?>" class="large-text"></td></tr>
|
|
<tr><th>Abschnitt 1 — Text</th><td><textarea name="bluesky_about_text1" rows="4" class="large-text"><?php echo esc_textarea(get_option('bluesky_about_text1','Wir sind ein engagiertes Team aus drei kreativen Köpfen, die Minecraft lieben!')); ?></textarea></td></tr>
|
|
<tr><th>Abschnitt 2 — Titel</th><td><input type="text" name="bluesky_about_title2" value="<?php echo esc_attr(get_option('bluesky_about_title2','Was macht BlueSky so besonders?')); ?>" class="large-text"></td></tr>
|
|
<tr><th>Abschnitt 2 — Text</th><td><textarea name="bluesky_about_text2" rows="4" class="large-text"><?php echo esc_textarea(get_option('bluesky_about_text2','BlueSky gibt dir die Freiheit, deine eigene Welt zu erstellen und zu erweitern.')); ?></textarea></td></tr>
|
|
</table>
|
|
|
|
<h2>Discord Sektion</h2>
|
|
<table class="form-table">
|
|
<tr><th>Text</th><td><textarea name="bluesky_discord_section_text" rows="3" class="large-text"><?php echo esc_textarea(get_option('bluesky_discord_section_text',"Du hast ein Problem oder möchtest mit anderen in Kontakt treten?\nTritt unserem Discord bei!")); ?></textarea><p class="description">Die Wörter "Problem" und "Discord" werden automatisch farbig hervorgehoben.</p></td></tr>
|
|
</table>
|
|
|
|
<h2>Vote Sektion</h2>
|
|
<table class="form-table">
|
|
<tr><th>Beschreibungstext</th><td><textarea name="bluesky_vote_description" rows="4" class="large-text"><?php echo esc_textarea(get_option('bluesky_vote_description','Durchs Voten erhältst du nicht nur wertvolle Belohnungen, sondern auch eine zeitbegrenzte Premium-Berechtigung mit zahlreichen Vorteilen!')); ?></textarea></td></tr>
|
|
</table>
|
|
|
|
<h2>FAQ Sektion</h2>
|
|
<table class="form-table">
|
|
<tr><th>Untertitel</th><td><input type="text" name="bluesky_faq_description" value="<?php echo esc_attr(get_option('bluesky_faq_description','Meist gestellte Fragen und Antworten')); ?>" class="large-text"></td></tr>
|
|
</table>
|
|
|
|
<h2>Regeln-Seite</h2>
|
|
<table class="form-table">
|
|
<tr><th>Warntext</th><td><textarea name="bluesky_rules_warning_text" rows="2" class="large-text"><?php echo esc_textarea(get_option('bluesky_rules_warning_text','Achtung: Bei einer Abwesenheit von mehr als 90 Tagen werden alle Spielerinformationen und Daten gelöscht.')); ?></textarea></td></tr>
|
|
</table>
|
|
|
|
<?php submit_button('Alle Texte speichern'); ?>
|
|
</form></div>
|
|
<?php
|
|
}
|
|
|
|
// 5. Bilder & Medien
|
|
function bluesky_images_page() {
|
|
if (!current_user_can('manage_options')) wp_die('Kein Zugriff');
|
|
$saved = bluesky_save_options('bluesky_save_images', 'bluesky_images_nonce',
|
|
[], ['bluesky_header_bg_url','bluesky_logo_url','bluesky_about_image_url','bluesky_navbar_logo_url']);
|
|
if ($saved) echo '<div class="updated notice is-dismissible"><p>✅ Bilder gespeichert!</p></div>';
|
|
|
|
bluesky_admin_header('Bilder & Medien', '🖼️');
|
|
bluesky_admin_intro(
|
|
'Bilder austauschen',
|
|
'Am einfachsten über die Mediathek wählen. Das Vorschaubild zeigt sofort das Ergebnis.',
|
|
[
|
|
'Bildfeld auswählen',
|
|
'Aus Mediathek wählen klicken',
|
|
'Bei Bedarf mit Zurücksetzen auf Standard zurück'
|
|
]
|
|
);
|
|
$images = [
|
|
'bluesky_header_bg_url' => ['Header Hintergrundbild', 'images/header-background.jpg', 'Großes Hintergrundbild im Hero-Bereich und Discord-Sektion'],
|
|
'bluesky_logo_url' => ['Server Logo (Header)', 'images/logo.png', 'Schwebendes Logo rechts im Header'],
|
|
'bluesky_navbar_logo_url' => ['Navbar Logo', 'images/logo.png', 'Kleines Logo links in der Navbar'],
|
|
'bluesky_about_image_url' => ['Über-Uns Bild', 'images/teambild.png', 'Bild rechts im "Über Uns" Bereich'],
|
|
];
|
|
?>
|
|
<form method="post" class="bluesky-admin-form">
|
|
<?php wp_nonce_field('bluesky_save_images', 'bluesky_images_nonce'); ?>
|
|
<table class="form-table">
|
|
<?php foreach ($images as $key => [$label, $default_file, $desc]):
|
|
$current = get_option($key, '');
|
|
$preview = $current ?: get_template_directory_uri() . '/' . $default_file;
|
|
$pid = sanitize_title($key);
|
|
?>
|
|
<tr>
|
|
<th><?php echo esc_html($label); ?></th>
|
|
<td>
|
|
<div style="display:flex;align-items:flex-start;gap:20px">
|
|
<img id="prev_<?php echo $pid; ?>" src="<?php echo esc_url($preview); ?>" style="max-width:200px;max-height:120px;border-radius:8px;border:2px solid #444;object-fit:cover">
|
|
<div>
|
|
<input type="url" id="<?php echo $pid; ?>" name="<?php echo $key; ?>" value="<?php echo esc_url($current); ?>" class="large-text" placeholder="URL oder über Button auswählen">
|
|
<br><br>
|
|
<button type="button" class="button bluesky-upload-btn" data-target="<?php echo $pid; ?>" data-preview="prev_<?php echo $pid; ?>">📁 Aus Mediathek wählen</button>
|
|
<button type="button" class="button" onclick="document.getElementById('<?php echo $pid;?>').value='';document.getElementById('prev_<?php echo $pid;?>').src='<?php echo get_template_directory_uri().'/'.$default_file;?>'">↩ Zurücksetzen</button>
|
|
<p class="description"><?php echo esc_html($desc); ?></p>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</table>
|
|
<?php submit_button('Bilder speichern'); ?>
|
|
</form></div>
|
|
<?php
|
|
}
|
|
|
|
// 6. Impressum
|
|
function bluesky_impressum_page() {
|
|
if (!current_user_can('manage_options')) wp_die('Kein Zugriff');
|
|
if (isset($_POST['bluesky_impressum_nonce']) && wp_verify_nonce($_POST['bluesky_impressum_nonce'], 'bluesky_save_impressum')) {
|
|
if (isset($_POST['bluesky_impressum_content'])) update_option('bluesky_impressum_content', wp_kses_post($_POST['bluesky_impressum_content']));
|
|
if (isset($_POST['bluesky_datenschutz_content'])) update_option('bluesky_datenschutz_content', wp_kses_post($_POST['bluesky_datenschutz_content']));
|
|
echo '<div class="updated notice is-dismissible"><p>✅ Gespeichert!</p></div>';
|
|
}
|
|
bluesky_admin_header('Impressum & Datenschutz', '📄');
|
|
bluesky_admin_intro(
|
|
'Rechtstexte pflegen',
|
|
'Bearbeite Impressum und Datenschutz direkt mit dem WordPress-Editor.',
|
|
[
|
|
'Impressum vollständig eintragen',
|
|
'Datenschutztext aktualisieren',
|
|
'Speichern und Seite prüfen'
|
|
]
|
|
);
|
|
?>
|
|
<form method="post" class="bluesky-admin-form">
|
|
<?php wp_nonce_field('bluesky_save_impressum', 'bluesky_impressum_nonce'); ?>
|
|
<h2>Impressum</h2>
|
|
<?php wp_editor(get_option('bluesky_impressum_content','<h2>Impressum</h2><p>Angaben gemäß §5 TMG</p>'), 'bluesky_impressum_content', ['textarea_rows'=>12,'media_buttons'=>true]); ?>
|
|
<h2 style="margin-top:30px">Datenschutzerklärung</h2>
|
|
<?php wp_editor(get_option('bluesky_datenschutz_content','<h2>Datenschutzerklärung</h2><p>Datenschutzhinweise</p>'), 'bluesky_datenschutz_content', ['textarea_rows'=>12,'media_buttons'=>true]); ?>
|
|
<?php submit_button('Speichern'); ?>
|
|
</form></div>
|
|
<?php
|
|
}
|
|
|
|
// ============================================================
|
|
// HELPER FUNCTIONS (für Templates)
|
|
// ============================================================
|
|
function bluesky_rgba_to_hex($rgba) {
|
|
if (!$rgba) return '';
|
|
if (str_starts_with($rgba, '#')) return $rgba;
|
|
preg_match('/rgba?\((\d+),\s*(\d+),\s*(\d+)/i', $rgba, $m);
|
|
if (count($m) < 4) return '#ff0000';
|
|
return sprintf('#%02x%02x%02x', $m[1], $m[2], $m[3]);
|
|
}
|
|
|
|
function bluesky_get_image($option_key, $fallback_file) {
|
|
$url = get_option($option_key, '');
|
|
return $url ?: get_template_directory_uri() . '/' . $fallback_file;
|
|
}
|
|
|
|
function bluesky_navbar($current = 'home') {
|
|
$server_name = get_option('bluesky_server_name', 'BlueSky');
|
|
$logo_url = bluesky_get_image('bluesky_navbar_logo_url', 'images/logo.png');
|
|
$nav_items = [
|
|
'home' => [get_option('bluesky_nav_home_label','Home'), get_option('bluesky_nav_home_url','/')],
|
|
'wiki' => [get_option('bluesky_nav_wiki_label','Wiki'), get_option('bluesky_nav_wiki_url','/wiki/')],
|
|
'rules' => [get_option('bluesky_nav_rules_label','Regeln'), get_option('bluesky_nav_rules_url','/regeln/')],
|
|
'team' => [get_option('bluesky_nav_team_label','Team'), get_option('bluesky_nav_team_url','/team/')],
|
|
];
|
|
?>
|
|
<div class="navbar">
|
|
<div class="menu-mobile">
|
|
<a href="<?php echo home_url('/'); ?>">
|
|
<div class="logo">
|
|
<img src="<?php echo esc_url($logo_url); ?>" alt="Logo" class="logo-img">
|
|
<h3 class="server-name"><?php echo esc_html($server_name); ?></h3>
|
|
</div>
|
|
</a>
|
|
<div class="hamburger">
|
|
<img src="<?php echo get_template_directory_uri(); ?>/images/namnam.png" alt="Menu" style="max-width:32px">
|
|
</div>
|
|
</div>
|
|
<div class="links">
|
|
<?php foreach ($nav_items as $key => [$label, $url]): ?>
|
|
<a href="<?php echo esc_url(home_url($url)); ?>" class="link <?php echo $current === $key ? 'active' : ''; ?>"><?php echo esc_html($label); ?></a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
function bluesky_footer() {
|
|
$server_name = get_option('bluesky_server_name', 'BlueSky');
|
|
$impressum_url = get_option('bluesky_footer_impressum_url', home_url('/impressum/#impressum'));
|
|
$datenschutz_url = get_option('bluesky_footer_datenschutz_url', home_url('/impressum/#datenschutz'));
|
|
?>
|
|
<footer id="footer">
|
|
<p class="copyright">© <?php echo date('Y'); ?> <span class="server-name-footer"><?php echo esc_html($server_name); ?></span> | Theme by M_Viper</p>
|
|
<div class="footer-links">
|
|
<a href="<?php echo esc_url($impressum_url); ?>" class="link">Impressum</a>
|
|
<span class="sep">|</span>
|
|
<a href="<?php echo esc_url($datenschutz_url); ?>" class="link">Datenschutz</a>
|
|
</div>
|
|
</footer>
|
|
<?php
|
|
}
|
|
|
|
function bluesky_get_team_data_for_js() {
|
|
$team_data = [];
|
|
$q = new WP_Query(['post_type'=>'bluesky_team','posts_per_page'=>-1,'post_status'=>'publish','meta_key'=>'_bluesky_sort_order','orderby'=>'meta_value_num','order'=>'ASC']);
|
|
if ($q->have_posts()) while ($q->have_posts()) { $q->the_post(); $id=get_the_ID(); $g=get_post_meta($id,'_bluesky_team_group',true)?:'Team'; $team_data[$g][]=['inGameName'=>get_post_meta($id,'_bluesky_in_game_name',true),'rank'=>get_post_meta($id,'_bluesky_rank',true),'rankColor'=>get_post_meta($id,'_bluesky_rank_color',true),'skinUrlOrPathToFile'=>get_post_meta($id,'_bluesky_skin_url',true)]; }
|
|
wp_reset_postdata();
|
|
return $team_data;
|
|
}
|
|
|
|
// ============================================================
|
|
// CUSTOM CSS output
|
|
// ============================================================
|
|
function bluesky_output_custom_css() {
|
|
$css = get_option('bluesky_custom_css','');
|
|
if ($css) echo '<style id="bluesky-custom-css">' . wp_strip_all_tags($css) . '</style>';
|
|
}
|
|
add_action('wp_head', 'bluesky_output_custom_css', 99);
|
|
|
|
// Force dark background
|
|
add_action('wp_head', fn() => print('<style>html,body{background-color:' . esc_attr(get_option('bluesky_color_bg','#24272B')) . '!important;margin:0;padding:0}</style>'), 1);
|
|
|
|
// ============================================================
|
|
// ADMIN COLUMNS
|
|
// ============================================================
|
|
add_filter('manage_bluesky_team_posts_columns', fn($c) => array_merge($c, ['in_game_name'=>'In-Game Name','rank'=>'Rang','group'=>'Gruppe']));
|
|
function bluesky_team_col($col, $id) {
|
|
if ($col==='in_game_name') echo esc_html(get_post_meta($id,'_bluesky_in_game_name',true));
|
|
if ($col==='rank') { $r=get_post_meta($id,'_bluesky_rank',true); $c=get_post_meta($id,'_bluesky_rank_color',true)?:'#999'; echo "<span style='background:$c;padding:2px 10px;border-radius:10px;color:#fff;font-size:12px'>".esc_html($r)."</span>"; }
|
|
if ($col==='group') echo esc_html(get_post_meta($id,'_bluesky_team_group',true)?:'Team');
|
|
}
|
|
add_action('manage_bluesky_team_posts_custom_column','bluesky_team_col',10,2);
|
|
|
|
// ============================================================
|
|
// DASHBOARD WIDGET
|
|
// ============================================================
|
|
function bluesky_dash_get_update_info($current_version) {
|
|
$cache_key = 'bluesky_theme_update_info';
|
|
$releases_url = 'https://git.viper.ipv64.net/M_Viper/bluesky-theme/releases';
|
|
$api_url = 'https://git.viper.ipv64.net/api/v1/repos/M_Viper/bluesky-theme/releases/latest';
|
|
$normalized_current = ltrim((string) $current_version, "vV");
|
|
|
|
$default = [
|
|
'latest_version' => $normalized_current,
|
|
'latest_tag' => 'v' . $normalized_current,
|
|
'release_url' => $releases_url,
|
|
'status' => 'unknown',
|
|
];
|
|
|
|
$cached = get_transient($cache_key);
|
|
if (is_array($cached)) {
|
|
$data = array_merge($default, $cached);
|
|
$data['has_update'] = $normalized_current !== '' && version_compare((string) $data['latest_version'], $normalized_current, '>');
|
|
return $data;
|
|
}
|
|
|
|
$result = $default;
|
|
|
|
$response = wp_remote_get($api_url, [
|
|
'timeout' => 8,
|
|
'headers' => ['Accept' => 'application/json'],
|
|
]);
|
|
|
|
if (!is_wp_error($response) && (int) wp_remote_retrieve_response_code($response) === 200) {
|
|
$body = json_decode((string) wp_remote_retrieve_body($response), true);
|
|
|
|
if (is_array($body)) {
|
|
$tag = (string) ($body['tag_name'] ?? '');
|
|
$latest = ltrim($tag, "vV");
|
|
$html_url = (string) ($body['html_url'] ?? '');
|
|
|
|
if ($latest !== '') {
|
|
$result['latest_version'] = $latest;
|
|
$result['latest_tag'] = $tag !== '' ? $tag : ('v' . $latest);
|
|
$result['status'] = 'ok';
|
|
|
|
}
|
|
|
|
if ($html_url !== '') {
|
|
$result['release_url'] = $html_url;
|
|
}
|
|
}
|
|
}
|
|
|
|
set_transient($cache_key, [
|
|
'latest_version' => $result['latest_version'],
|
|
'latest_tag' => $result['latest_tag'],
|
|
'release_url' => $result['release_url'],
|
|
'status' => $result['status'],
|
|
], 6 * HOUR_IN_SECONDS);
|
|
|
|
$result['has_update'] = $normalized_current !== '' && version_compare((string) $result['latest_version'], $normalized_current, '>');
|
|
return $result;
|
|
}
|
|
|
|
add_action('admin_init', 'bluesky_dash_handle_update_refresh');
|
|
function bluesky_dash_handle_update_refresh() {
|
|
if (!is_admin()) {
|
|
return;
|
|
}
|
|
|
|
if (empty($_GET['bluesky_refresh_update'])) {
|
|
return;
|
|
}
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
return;
|
|
}
|
|
|
|
if (empty($_GET['_wpnonce']) || !wp_verify_nonce((string) $_GET['_wpnonce'], 'bluesky_refresh_update')) {
|
|
return;
|
|
}
|
|
|
|
delete_transient('bluesky_theme_update_info');
|
|
|
|
wp_safe_redirect(add_query_arg('bluesky_update_refreshed', '1', admin_url('index.php')));
|
|
exit;
|
|
}
|
|
|
|
add_action('admin_head-index.php', 'bluesky_dash_admin_styles');
|
|
function bluesky_dash_admin_styles() {
|
|
?>
|
|
<style>
|
|
#bluesky_dash.postbox {
|
|
border: 1px solid #c3c4c7;
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
box-shadow: none;
|
|
}
|
|
|
|
#bluesky_dash.postbox .hndle {
|
|
color: #1d2327;
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
#bluesky_dash.postbox .handle-actions .handle-order-higher,
|
|
#bluesky_dash.postbox .handle-actions .handle-order-lower,
|
|
#bluesky_dash.postbox .handle-actions .toggle-indicator {
|
|
color: #646970;
|
|
}
|
|
|
|
#bluesky_dash .inside {
|
|
margin: 0;
|
|
padding: 10px;
|
|
background: #fff;
|
|
}
|
|
|
|
.bluesky-dash-widget {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.bluesky-dash-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
gap: 8px;
|
|
}
|
|
|
|
.bluesky-dash-tile {
|
|
border: 1px solid #dcdcde;
|
|
border-radius: 6px;
|
|
background: #f6f7f7;
|
|
box-shadow: none;
|
|
padding: 9px 8px;
|
|
min-height: 70px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
text-align: center;
|
|
}
|
|
|
|
.bluesky-dash-ip {
|
|
grid-column: 1 / -1;
|
|
min-height: 56px;
|
|
}
|
|
|
|
.bluesky-dash-icon {
|
|
display: none;
|
|
}
|
|
|
|
.bluesky-dash-meta {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
min-width: 0;
|
|
}
|
|
|
|
.bluesky-dash-count {
|
|
color: #1d2327;
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
line-height: 1;
|
|
}
|
|
|
|
.bluesky-dash-label {
|
|
color: #50575e;
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.bluesky-dash-ip .bluesky-dash-count {
|
|
color: #1d2327;
|
|
font-size: 15px;
|
|
line-height: 1.1;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.bluesky-dash-status {
|
|
border-top: 1px solid #dcdcde;
|
|
padding-top: 8px;
|
|
color: #1d2327;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.bluesky-dash-status strong {
|
|
font-weight: 600;
|
|
}
|
|
|
|
.bluesky-dash-status-ok {
|
|
color: #008a20;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.bluesky-dash-status-update {
|
|
color: #b32d2e;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.bluesky-dash-banner {
|
|
border: 1px solid #dcdcde;
|
|
border-radius: 6px;
|
|
padding: 9px 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.bluesky-dash-banner .dashicons {
|
|
width: 14px;
|
|
height: 14px;
|
|
font-size: 14px;
|
|
line-height: 1;
|
|
}
|
|
|
|
.bluesky-dash-banner.is-update {
|
|
background: #fff1f1;
|
|
border-color: #f0b4b4;
|
|
color: #8a2424;
|
|
}
|
|
|
|
.bluesky-dash-banner.is-update .dashicons {
|
|
color: #b32d2e;
|
|
}
|
|
|
|
.bluesky-dash-banner.is-ok {
|
|
background: #f1fbf3;
|
|
border-color: #b8e0c0;
|
|
color: #196127;
|
|
}
|
|
|
|
.bluesky-dash-banner.is-ok .dashicons {
|
|
color: #008a20;
|
|
}
|
|
|
|
.bluesky-dash-update {
|
|
border-top: 1px solid #dcdcde;
|
|
padding-top: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 8px;
|
|
font-size: 12px;
|
|
color: #1d2327;
|
|
}
|
|
|
|
.bluesky-dash-update a {
|
|
color: #2271b1;
|
|
text-decoration: none;
|
|
font-weight: 600;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.bluesky-dash-update a:hover {
|
|
color: #135e96;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.bluesky-dash-update-links {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.bluesky-dash-refresh-note {
|
|
color: #008a20;
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.bluesky-dash-actions {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: 8px;
|
|
border-top: 1px solid #dcdcde;
|
|
padding-top: 10px;
|
|
}
|
|
|
|
.bluesky-dash-actions .button {
|
|
border-radius: 0;
|
|
min-height: 30px;
|
|
padding: 0 10px;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 5px;
|
|
font-weight: 500;
|
|
font-size: 12px;
|
|
border-color: #2271b1;
|
|
color: #2271b1;
|
|
background: #ffffff;
|
|
text-shadow: none;
|
|
box-shadow: none;
|
|
width: 100%;
|
|
}
|
|
|
|
.bluesky-dash-actions .button.button-primary {
|
|
border-color: #2271b1;
|
|
background: #2271b1;
|
|
color: #fff;
|
|
}
|
|
|
|
.bluesky-dash-actions .button:hover {
|
|
border-color: #135e96;
|
|
color: #135e96;
|
|
background: #fff;
|
|
}
|
|
|
|
.bluesky-dash-actions .button.button-primary:hover {
|
|
border-color: #135e96;
|
|
background: #135e96;
|
|
color: #fff;
|
|
}
|
|
|
|
.bluesky-dash-actions .button .dashicons {
|
|
width: 12px;
|
|
height: 12px;
|
|
font-size: 12px;
|
|
line-height: 1;
|
|
margin: 0;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.bluesky-dash-actions .button .dashicons::before {
|
|
line-height: 1;
|
|
}
|
|
|
|
@media screen and (max-width: 782px) {
|
|
.bluesky-dash-grid {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
|
|
.bluesky-dash-ip {
|
|
grid-column: 1 / -1;
|
|
}
|
|
}
|
|
|
|
@media screen and (max-width: 480px) {
|
|
.bluesky-dash-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.bluesky-dash-tile {
|
|
min-height: 64px;
|
|
}
|
|
|
|
.bluesky-dash-actions {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.bluesky-dash-update {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
}
|
|
}
|
|
</style>
|
|
<?php
|
|
}
|
|
|
|
add_action('wp_dashboard_setup', function() {
|
|
add_meta_box('bluesky_dash','WP BlueSky Dashboard','bluesky_dash_content','dashboard','normal','high');
|
|
});
|
|
function bluesky_dash_content() {
|
|
$ip = get_option('bluesky_server_ip','—');
|
|
$t = wp_count_posts('bluesky_team')->publish ?? 0;
|
|
$w = wp_count_posts('bluesky_wiki')->publish ?? 0;
|
|
$f = wp_count_posts('bluesky_faq')->publish ?? 0;
|
|
$r = wp_count_posts('bluesky_rule')->publish ?? 0;
|
|
$theme_version = wp_get_theme()->get('Version');
|
|
$update_info = bluesky_dash_get_update_info($theme_version);
|
|
$has_update = !empty($update_info['has_update']);
|
|
$tiles = [
|
|
['count' => (int) $t, 'label' => 'Team'],
|
|
['count' => (int) $w, 'label' => 'Wiki'],
|
|
['count' => (int) $f, 'label' => 'FAQs'],
|
|
['count' => (int) $r, 'label' => 'Regeln'],
|
|
];
|
|
?>
|
|
<div class="bluesky-dash-widget">
|
|
<div class="bluesky-dash-grid">
|
|
<?php foreach ($tiles as $tile): ?>
|
|
<div class="bluesky-dash-tile">
|
|
<div class="bluesky-dash-meta">
|
|
<strong class="bluesky-dash-count"><?php echo esc_html($tile['count']); ?></strong>
|
|
<span class="bluesky-dash-label"><?php echo esc_html($tile['label']); ?></span>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
|
|
<div class="bluesky-dash-tile bluesky-dash-ip">
|
|
<div class="bluesky-dash-meta">
|
|
<strong class="bluesky-dash-count"><?php echo esc_html($ip); ?></strong>
|
|
<span class="bluesky-dash-label">Server IP</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bluesky-dash-banner <?php echo $has_update ? 'is-update' : 'is-ok'; ?>">
|
|
<span class="dashicons <?php echo $has_update ? 'dashicons-warning' : 'dashicons-yes-alt'; ?>"></span>
|
|
<?php if ($has_update): ?>
|
|
<span>Neues Theme-Update verfügbar: <?php echo esc_html($update_info['latest_tag']); ?> (installiert: v<?php echo esc_html($theme_version); ?>)</span>
|
|
<?php else: ?>
|
|
<span>Theme ist auf dem neuesten Stand (v<?php echo esc_html($theme_version); ?>)</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="bluesky-dash-status">
|
|
<strong>Status:</strong>
|
|
<?php if ($has_update): ?>
|
|
<span class="bluesky-dash-status-update">Update verfügbar (<?php echo esc_html($update_info['latest_tag']); ?>)</span>
|
|
<?php else: ?>
|
|
<span class="bluesky-dash-status-ok">Aktuell (v<?php echo esc_html($theme_version); ?>)</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="bluesky-dash-update">
|
|
<span>Release-Seite: <strong><?php echo esc_html($update_info['latest_tag']); ?></strong></span>
|
|
<span class="bluesky-dash-update-links">
|
|
<?php
|
|
$refresh_url = wp_nonce_url(
|
|
add_query_arg('bluesky_refresh_update', '1', admin_url('index.php')),
|
|
'bluesky_refresh_update'
|
|
);
|
|
?>
|
|
<a href="<?php echo esc_url($refresh_url); ?>">Jetzt neu prüfen</a>
|
|
<a href="<?php echo esc_url($update_info['release_url']); ?>" target="_blank" rel="noopener">Releases öffnen</a>
|
|
<?php if (!empty($_GET['bluesky_update_refreshed'])): ?>
|
|
<span class="bluesky-dash-refresh-note">Neu geprüft</span>
|
|
<?php endif; ?>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="bluesky-dash-actions">
|
|
<a href="<?php echo esc_url(admin_url('admin.php?page=bluesky-settings')); ?>" class="button button-primary"><span class="dashicons dashicons-admin-generic"></span>Settings</a>
|
|
<a href="<?php echo esc_url(admin_url('admin.php?page=bluesky-design')); ?>" class="button"><span class="dashicons dashicons-art"></span>Design</a>
|
|
<a href="<?php echo esc_url(admin_url('post-new.php?post_type=bluesky_team')); ?>" class="button"><span class="dashicons dashicons-groups"></span>Team +</a>
|
|
<a href="<?php echo esc_url(admin_url('post-new.php?post_type=bluesky_faq')); ?>" class="button"><span class="dashicons dashicons-editor-help"></span>FAQ +</a>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
// ============================================================
|
|
// PAGE TEMPLATES
|
|
// ============================================================
|
|
add_filter('theme_page_templates', function($t) {
|
|
return array_merge($t, ['template-home.php'=>'BlueSky - Startseite','template-wiki.php'=>'BlueSky - Wiki','template-regeln.php'=>'BlueSky - Regeln','template-team.php'=>'BlueSky - Team','template-impressum.php'=>'BlueSky - Impressum']);
|
|
});
|
|
|
|
// ============================================================
|
|
// AUTO-CREATE PAGES ON ACTIVATION
|
|
// ============================================================
|
|
// ============================================================
|
|
// SEITEN AUTOMATISCH ERSTELLEN & REPARIEREN
|
|
// Läuft bei jedem Admin-Aufruf — prüft und korrigiert alles
|
|
// ============================================================
|
|
function bluesky_ensure_pages() {
|
|
// Nur einmal pro Stunde prüfen (Performance)
|
|
if (get_transient('bluesky_pages_checked')) return;
|
|
set_transient('bluesky_pages_checked', 1, HOUR_IN_SECONDS);
|
|
|
|
$pages = [
|
|
'wiki' => ['Wiki', 'template-wiki.php'],
|
|
'regeln' => ['Regeln', 'template-regeln.php'],
|
|
'team' => ['Team', 'template-team.php'],
|
|
'impressum' => ['Impressum', 'template-impressum.php'],
|
|
];
|
|
|
|
$changed = false;
|
|
|
|
foreach ($pages as $slug => [$title, $tpl]) {
|
|
$page = get_page_by_path($slug);
|
|
|
|
if (!$page) {
|
|
// Seite fehlt → erstellen
|
|
$id = wp_insert_post([
|
|
'post_title' => $title,
|
|
'post_name' => $slug,
|
|
'post_status' => 'publish',
|
|
'post_type' => 'page',
|
|
]);
|
|
if ($id && !is_wp_error($id)) {
|
|
update_post_meta($id, '_wp_page_template', $tpl);
|
|
$changed = true;
|
|
}
|
|
} else {
|
|
// Seite existiert → Template prüfen & korrigieren
|
|
$current = get_post_meta($page->ID, '_wp_page_template', true);
|
|
if ($current !== $tpl) {
|
|
update_post_meta($page->ID, '_wp_page_template', $tpl);
|
|
$changed = true;
|
|
}
|
|
// Sicherstellen dass Seite published ist
|
|
if ($page->post_status !== 'publish') {
|
|
wp_update_post(['ID' => $page->ID, 'post_status' => 'publish']);
|
|
$changed = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Permalinks neu laden wenn etwas geändert wurde
|
|
if ($changed) {
|
|
flush_rewrite_rules();
|
|
delete_transient('bluesky_pages_checked');
|
|
}
|
|
}
|
|
add_action('admin_init', 'bluesky_ensure_pages');
|
|
add_action('after_switch_theme', 'bluesky_ensure_pages');
|
|
|
|
function bluesky_activation() {
|
|
bluesky_register_post_types();
|
|
bluesky_register_taxonomies();
|
|
delete_transient('bluesky_pages_checked'); // Force check on activation
|
|
bluesky_ensure_pages();
|
|
flush_rewrite_rules();
|
|
}
|
|
add_action('after_switch_theme', 'bluesky_activation');
|
|
|
|
|
|
// ============================================================
|
|
// SETUP-ASSISTENT & SEITEN REPARIEREN
|
|
// ============================================================
|
|
function bluesky_setup_page() {
|
|
if (!current_user_can('manage_options')) wp_die('Kein Zugriff');
|
|
|
|
// Seiten erstellen / reparieren
|
|
if (isset($_POST['bluesky_setup_nonce']) && wp_verify_nonce($_POST['bluesky_setup_nonce'], 'bluesky_run_setup')) {
|
|
$result = bluesky_create_pages_now();
|
|
flush_rewrite_rules();
|
|
echo '<div class="updated notice"><p>✅ ' . esc_html($result) . '</p></div>';
|
|
}
|
|
|
|
bluesky_admin_header('Setup & Seiten', '🔧');
|
|
bluesky_admin_intro(
|
|
'Automatische Seiten-Reparatur',
|
|
'Falls Links auf die Startseite gehen oder Seiten fehlen, kannst du hier alles automatisch korrigieren.',
|
|
[
|
|
'Status-Tabelle prüfen',
|
|
'Seiten erstellen/reparieren klicken',
|
|
'Bei Bedarf Permalinks speichern'
|
|
]
|
|
);
|
|
|
|
// Status aller Seiten prüfen
|
|
$pages_config = [
|
|
'team' => ['Team', 'template-team.php'],
|
|
'wiki' => ['Wiki', 'template-wiki.php'],
|
|
'regeln' => ['Regeln', 'template-regeln.php'],
|
|
'impressum' => ['Impressum', 'template-impressum.php'],
|
|
];
|
|
?>
|
|
<h2>Seiten-Status</h2>
|
|
<table class="widefat" style="max-width:700px">
|
|
<thead><tr><th>Seite</th><th>URL</th><th>Template</th><th>Status</th></tr></thead>
|
|
<tbody>
|
|
<?php foreach ($pages_config as $slug => [$title, $tpl]):
|
|
$page = get_page_by_path($slug);
|
|
$exists = !empty($page);
|
|
$tpl_set = $exists ? get_post_meta($page->ID, '_wp_page_template', true) : '';
|
|
$correct_tpl = ($tpl_set === $tpl);
|
|
$url = home_url('/' . $slug . '/');
|
|
?>
|
|
<tr>
|
|
<td><strong><?php echo esc_html($title); ?></strong></td>
|
|
<td><?php if ($exists): ?><a href="<?php echo esc_url($url); ?>" target="_blank"><?php echo esc_url($url); ?></a><?php else: echo '—'; endif; ?></td>
|
|
<td style="font-size:12px;color:#666"><?php echo esc_html($tpl_set ?: '—'); ?></td>
|
|
<td>
|
|
<?php if ($exists && $correct_tpl): ?>
|
|
<span style="color:#4AFF6B">✅ OK</span>
|
|
<?php elseif ($exists && !$correct_tpl): ?>
|
|
<span style="color:#FF7C7C">⚠️ Falsches Template</span>
|
|
<?php else: ?>
|
|
<span style="color:#FF7C7C">❌ Fehlt</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
|
|
<br>
|
|
<form method="post" class="bluesky-admin-form" style="max-width:700px">
|
|
<?php wp_nonce_field('bluesky_run_setup', 'bluesky_setup_nonce'); ?>
|
|
<p>Klicke auf den Button um alle fehlenden Seiten zu erstellen und die korrekten Templates zuzuweisen. Bereits vorhandene Seiten werden dabei nicht gelöscht.</p>
|
|
<?php submit_button('🔧 Seiten erstellen / reparieren', 'primary large'); ?>
|
|
</form>
|
|
|
|
<hr>
|
|
<h2>Permalinks neu laden</h2>
|
|
<p>Falls Links immer noch auf die Startseite zeigen, einmal Permalinks flushen:</p>
|
|
<a href="<?php echo admin_url('options-permalink.php'); ?>" class="button button-secondary">⚙️ Permalinks-Einstellungen öffnen</a>
|
|
<p class="description" style="margin-top:8px">Dort einfach auf "Änderungen speichern" klicken — kein anderer Änderung nötig.</p>
|
|
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
function bluesky_create_pages_now() {
|
|
delete_transient('bluesky_pages_checked');
|
|
bluesky_ensure_pages();
|
|
|
|
$pages = [
|
|
'wiki' => ['Wiki', 'template-wiki.php'],
|
|
'regeln' => ['Regeln', 'template-regeln.php'],
|
|
'team' => ['Team', 'template-team.php'],
|
|
'impressum' => ['Impressum', 'template-impressum.php'],
|
|
];
|
|
|
|
$ok = 0;
|
|
foreach ($pages as $slug => [$title, $tpl]) {
|
|
$page = get_page_by_path($slug);
|
|
if ($page && get_post_meta($page->ID, '_wp_page_template', true) === $tpl) $ok++;
|
|
}
|
|
|
|
flush_rewrite_rules();
|
|
return "Fertig! $ok/4 Seiten korrekt konfiguriert. Permalinks wurden neu geladen.";
|
|
}
|
|
|
|
|
|
|
|
// Menüeintrag für Setup
|
|
add_action('admin_menu', function() {
|
|
add_submenu_page('bluesky-settings', 'Setup & Seiten reparieren', '🔧 Setup & Reparieren', 'manage_options', 'bluesky-setup', 'bluesky_setup_page');
|
|
}, 20);
|
|
|
|
// Admin-Hinweis falls Seiten fehlen
|
|
add_action('admin_notices', function() {
|
|
if (!current_user_can('manage_options')) return;
|
|
$screen = get_current_screen();
|
|
if ($screen && str_contains($screen->id ?? '', 'bluesky')) return;
|
|
$team_page = get_page_by_path('team');
|
|
if (!$team_page) {
|
|
echo '<div class="notice notice-warning"><p>⚠️ <strong>BlueSky MC Theme:</strong> Einige Seiten fehlen noch. <a href="' . admin_url('admin.php?page=bluesky-setup') . '"><strong>Jetzt reparieren →</strong></a></p></div>';
|
|
}
|
|
});
|
|
|
|
// ============================================================
|
|
// WIKI META BOX — Reihenfolge & Excerpt
|
|
// ============================================================
|
|
function bluesky_wiki_meta_boxes() {
|
|
add_meta_box('bluesky_wiki_meta', 'Wiki Artikel Einstellungen', 'bluesky_wiki_meta_cb', 'bluesky_wiki', 'side', 'high');
|
|
}
|
|
add_action('add_meta_boxes', 'bluesky_wiki_meta_boxes');
|
|
|
|
function bluesky_wiki_meta_cb($post) {
|
|
wp_nonce_field('bluesky_wiki_nonce_action', 'bluesky_wiki_nonce');
|
|
$order = get_post_meta($post->ID, '_bluesky_wiki_order', true);
|
|
$icon = get_post_meta($post->ID, '_bluesky_wiki_icon', true);
|
|
?>
|
|
<table class="form-table" style="margin:0">
|
|
<tr>
|
|
<th style="padding:5px 0"><label>Reihenfolge</label></th>
|
|
<td><input type="number" name="bluesky_wiki_order" value="<?php echo esc_attr($order ?: 0); ?>" style="width:80px" min="0">
|
|
<p class="description" style="font-size:11px">Niedrigere Zahl = weiter oben</p></td>
|
|
</tr>
|
|
<tr>
|
|
<th style="padding:5px 0"><label>Icon / Emoji</label></th>
|
|
<td><input type="text" name="bluesky_wiki_icon" value="<?php echo esc_attr($icon); ?>" style="width:80px" placeholder="📖">
|
|
<p class="description" style="font-size:11px">Emoji für die Kachel</p></td>
|
|
</tr>
|
|
</table>
|
|
<p class="description" style="margin-top:10px">
|
|
💡 <strong>Tipp:</strong> Beitragsbild setzen → wird als Icon auf der Wiki-Übersicht angezeigt.
|
|
</p>
|
|
<?php
|
|
}
|
|
|
|
function bluesky_save_wiki_meta($post_id) {
|
|
if (!isset($_POST['bluesky_wiki_nonce']) || !wp_verify_nonce($_POST['bluesky_wiki_nonce'], 'bluesky_wiki_nonce_action')) return;
|
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
|
|
if (!current_user_can('edit_post', $post_id)) return;
|
|
if (isset($_POST['bluesky_wiki_order'])) update_post_meta($post_id, '_bluesky_wiki_order', intval($_POST['bluesky_wiki_order']));
|
|
if (isset($_POST['bluesky_wiki_icon'])) update_post_meta($post_id, '_bluesky_wiki_icon', sanitize_text_field($_POST['bluesky_wiki_icon']));
|
|
}
|
|
add_action('save_post_bluesky_wiki', 'bluesky_save_wiki_meta');
|
|
|
|
// Wiki Kategorie: Beschreibungsfeld = Emoji/Icon
|
|
// (Das Kategorie-Beschreibungsfeld wird als Icon-Container genutzt)
|
|
function bluesky_wiki_cat_icon_field($term) {
|
|
$icon = is_object($term) ? esc_attr($term->description) : '';
|
|
?>
|
|
<div class="form-field">
|
|
<label>Kategorie-Icon (Emoji)</label>
|
|
<input type="text" name="description" value="<?php echo $icon; ?>" placeholder="📚" style="width:80px">
|
|
<p>Ein Emoji das neben dem Kategorie-Titel angezeigt wird. z.B. ⚔️ 🏠 💰 🐾 📜</p>
|
|
</div>
|
|
<?php
|
|
}
|
|
add_action('wiki_category_add_form_fields', function() { bluesky_wiki_cat_icon_field(null); });
|
|
add_action('wiki_category_edit_form_fields', function($term) { bluesky_wiki_cat_icon_field($term); });
|
|
|
|
// Admin-Columns für Wiki
|
|
add_filter('manage_bluesky_wiki_posts_columns', function($cols) {
|
|
return array_merge($cols, ['wiki_cats' => 'Kategorie', 'wiki_order' => 'Reihenfolge']);
|
|
});
|
|
add_action('manage_bluesky_wiki_posts_custom_column', function($col, $id) {
|
|
if ($col === 'wiki_cats') {
|
|
$terms = get_the_terms($id, 'wiki_category');
|
|
echo $terms ? implode(', ', wp_list_pluck($terms, 'name')) : '—';
|
|
}
|
|
if ($col === 'wiki_order') echo get_post_meta($id, '_bluesky_wiki_order', true) ?: '0';
|
|
}, 10, 2);
|