diff --git a/functions.php b/functions.php new file mode 100644 index 0000000..a61b1b7 --- /dev/null +++ b/functions.php @@ -0,0 +1,1582 @@ +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')); + ?> + + +
⚠️ Rang ist leer! Bitte Rang eintragen und speichern — sonst wird "—" auf der Team-Seite angezeigt.
| In-Game Name * | Minecraft Username — Skin wird automatisch geladen (Original-Account vorausgesetzt). | Skin-Vorschau |
|---|---|---|
| Rangfarbe | Kann rgba() oder #hex sein. | |
| Gruppe | Bestimmt die Gruppenüberschrift auf der Team-Seite. | |
| Eigene Skin-URL | Nur für Cracked/Offline-Accounts nötig. | |
| Reihenfolge |
| Vote URL * | |
|---|---|
| Beschreibung |
| Features (kommagetrennt) | Werden als Liste unter dem Text angezeigt. |
|---|
Eine Regel pro Zeile eintragen. Der WordPress-Inhaltseditor wird für Regeln nicht genutzt.
+Für Verlinkung wie /regeln/#regel-1
+BlueSky MC Theme — ' . esc_html($title) . '
'; +} + +function bluesky_admin_intro($headline, $description, $steps = []) { + echo '' . esc_html($description) . '
'; + if (!empty($steps)) { + echo '✅ Gespeichert!
✅ Farben & Design gespeichert!
'; + + 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'], + ]; + ?> + + print(""), 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 '✅ Navbar & Footer gespeichert!
✅ Homepage-Texte gespeichert!
'; + + 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' + ] + ); + ?> + +✅ Bilder gespeichert!
'; + + 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'], + ]; + ?> + +✅ Gespeichert!
'; + } + 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' + ] + ); + ?> + + [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/')], + ]; + ?> + + + + '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 ''; +} +add_action('wp_head', 'bluesky_output_custom_css', 99); + +// Force dark background +add_action('wp_head', fn() => print(''), 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 "".esc_html($r).""; } + 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() { + ?> + + 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'], + ]; + ?> + + '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 '✅ ' . esc_html($result) . '
Falls Links immer noch auf die Startseite zeigen, einmal Permalinks flushen:
+ ⚙️ Permalinks-Einstellungen öffnen +Dort einfach auf "Änderungen speichern" klicken — kein anderer Änderung nötig.
+ + + ['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 '⚠️ BlueSky MC Theme: Einige Seiten fehlen noch. Jetzt reparieren →
| + |
+ Niedrigere Zahl = weiter oben |
+
|---|---|
| + |
+ Emoji für die Kachel |
+
+ 💡 Tipp: Beitragsbild setzen → wird als Icon auf der Wiki-Übersicht angezeigt. +
+ description) : ''; + ?> +Ein Emoji das neben dem Kategorie-Titel angezeigt wird. z.B. ⚔️ 🏠 💰 🐾 📜
+