From 9f18a9a719b7b902d0a8223f8d323f90af39fda0 Mon Sep 17 00:00:00 2001 From: Git Manager GUI Date: Mon, 11 May 2026 09:34:18 +0200 Subject: [PATCH] Upload folder via GUI - includes --- includes/class-mc-gallery-core.php | 1943 ++++++++++---------- includes/class-mc-gallery-forum-bridge.php | 76 +- 2 files changed, 1047 insertions(+), 972 deletions(-) diff --git a/includes/class-mc-gallery-core.php b/includes/class-mc-gallery-core.php index 86966d2..7769064 100644 --- a/includes/class-mc-gallery-core.php +++ b/includes/class-mc-gallery-core.php @@ -1,964 +1,981 @@ -post_type !== 'mc_server') return; - ?> - - ID, 'mc_server_host', true); // REMOVED - $secret = get_post_meta($post->ID, 'mc_server_secret', true); - $active = get_post_meta($post->ID, 'mc_server_active', true); - $id = intval($post->ID); - - $has_secret = !empty($secret); - - wp_nonce_field('mc_server_nonce', 'mc_server_nonce'); - ?> - - - - - - - - - - - - - - -
- -

Aktivieren, damit Spieler diesen Server sehen und Token anfragen können.

-
- - - -

✓ Automatisch generiert. Trage diesen Key in deine Java config.yml ein.

- -
- Wird automatisch generiert... -

Bitte klicke auf "Veröffentlichen". Nach dem Speichern erscheint hier dein Secret und die Server ID.

-
- -
Server ID (WP) - 0 ? $id : '(Wird zugewiesen)'; ?> -

Diese Nummer ist deine server_id. Trage diese Zahl in deine Java Config ein.

-
- Generieren - $final_secret = wp_generate_password(32, false); - } else { - // BESTEHENDER SERVER - if (!empty($input_secret)) { - $final_secret = $input_secret; - } else { - $final_secret = $current_secret; - } - } - - update_post_meta($post_id, 'mc_server_secret', $final_secret); - } - - public static function register_post_types() { - register_post_type('mc_server', [ - 'labels' => ['name' => 'MC Server', 'singular_name' => 'MC Server'], - 'public' => false, - 'show_ui' => true, - 'supports' => ['title'], - 'show_in_menu' => false - ]); - - register_post_type('mc_gallery', [ - 'labels' => ['name' => 'MC Galleries', 'singular_name' => 'MC Gallery'], - 'public' => false, - 'show_ui' => true, - 'supports' => ['title'], - 'has_archive' => false, - 'rewrite' => false, - 'show_in_menu' => false - ]); - - register_post_type('mc_album', [ - 'labels' => ['name' => 'MC Albums', 'singular_name' => 'MC Album'], - 'public' => false, - 'show_ui' => true, - 'supports' => ['title'], - 'has_archive' => false, - 'rewrite' => false, - 'show_in_menu' => false - ]); - } - - public static function admin_menu() { - add_menu_page('MC Gallery PRO', 'MC Gallery PRO', 'manage_options', 'mc-gallery-pro', [__CLASS__, 'settings_page'], 'dashicons-format-gallery', 30); - add_submenu_page('mc-gallery-pro', 'Einstellungen', 'Einstellungen', 'manage_options', 'mc-gallery-pro', [__CLASS__, 'settings_page']); - add_submenu_page('mc-gallery-pro', 'MC Server', 'MC Server', 'manage_options', 'edit.php?post_type=mc_server'); - add_submenu_page('mc-gallery-pro', 'MC Galleries', 'MC Galleries', 'manage_options', 'edit.php?post_type=mc_gallery'); - add_submenu_page('mc-gallery-pro', 'MC Albums', 'MC Albums', 'manage_options', 'edit.php?post_type=mc_album'); - } - - public static function register_settings() { - register_setting('mc_gallery_pro_group', self::OPTION_THUMB_H, ['type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 200]); - register_setting('mc_gallery_pro_group', self::OPTION_RESIZE_PCT, ['type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 100]); - register_setting('mc_gallery_pro_group', self::OPTION_SHOW_DATE, [ - 'type' => 'boolean', - 'sanitize_callback' => function($input) { return $input == '1' || $input === true || $input === 'on'; }, - 'default' => true - ]); - register_setting('mc_gallery_pro_group', self::OPTION_MAX_UPLOADS, [ - 'type' => 'integer', - 'sanitize_callback' => 'absint', - 'default' => 5 - ]); - register_setting('mc_gallery_pro_group', self::OPTION_FORUM_LOGIN, [ - 'type' => 'boolean', - 'sanitize_callback' => function($input) { return !empty($input) && $input !== '0'; }, - 'default' => false - ]); - register_setting('mc_gallery_pro_group', self::OPTION_VOTING, [ - 'type' => 'boolean', - 'sanitize_callback' => function($input) { return !empty($input) && $input !== '0'; }, - 'default' => true - ]); - } - - public static function settings_page() { - $thumb_h = get_option(self::OPTION_THUMB_H, 200); - $resize_pct = get_option(self::OPTION_RESIZE_PCT, 100); - $show_date = get_option(self::OPTION_SHOW_DATE, true); - $max_uploads = get_option(self::OPTION_MAX_UPLOADS, 5); - $forum_login = get_option(self::OPTION_FORUM_LOGIN, false); - $forum_plugin_active = class_exists('WBF_Auth'); - - // Prüfen ob das Forum-Plugin zwar existiert (Datei vorhanden) aber nicht aktiv ist - $forum_plugin_installed = false; - if ( ! $forum_plugin_active ) { - $all_plugins = get_plugins(); - foreach ( $all_plugins as $plugin_file => $plugin_data ) { - if ( stripos( $plugin_data['Name'], 'WP Business Forum' ) !== false - || stripos( $plugin_data['TextDomain'], 'wp-business-forum' ) !== false - || stripos( $plugin_file, 'wp-business-forum' ) !== false ) { - $forum_plugin_installed = true; - break; - } - } - } - ?> -
-

MC Gallery PRO Settings

-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Thumbnail Height (px)
Image Resize % (Upload) - -

Default is 100% (Original). Values like 50 or 70 save space. Aspect ratio is kept.

-
Show Date - -
Max. Images per Upload - -

How many images can a user upload at once? (Default: 5)

-
- Forum-Login für Upload-Verifizierung -
Benötigt: WP Business Forum -
- - - -
- - - WP Business Forum aktiv - -
- -

- Wenn aktiviert, können sich Nutzer die ihren Minecraft-Account im Forum-Profil verknüpft haben, direkt ohne Ingame-Token hochladen.
- Der Shortcode: [mc_gallery_combined] ermöglicht eine kombinierte Verifizierung für Token und Forum. -

- - - - -
- ⚠ WP Business Forum ist installiert, aber nicht aktiviert.
- Aktiviere das Plugin unter Plugins → Installierte Plugins, um diese Funktion zu nutzen. -
- - - - - -
- ✗ WP Business Forum ist nicht installiert.
- - Dieses Feature benötigt das Plugin WP Business Forum von M_Viper.
- - ↓ Jetzt herunterladen (Gitea) - -  ·  - - Plugins → Neu hinzufügen - -
-
- -

- Nach der Installation und Aktivierung von WP Business Forum wird diese Option freigeschaltet. -

- - -
Abstimmung (Daumen hoch/runter) - -

- Besucher können Bilder mit 👍 oder 👎 bewerten. Jeder kann abstimmen (kein Login nötig).
- Shortcode für die Bestenliste: [mc_gallery_vote] -

-
- -
-
- id ); - $verified = MC_Gallery_Forum_Bridge::is_verified( $forum_user->id ); - if ( $mc_user && $verified ) { - $forum_verified_data = [ - 'mc_username' => $mc_user, - 'server_id' => MC_Gallery_Forum_Bridge::get_mc_server( $forum_user->id ), - 'display_name' => $forum_user->display_name, - ]; - } - } - } - - wp_localize_script('mc-gallery-pro-js', 'mcGalleryPro', [ - 'restBase' => esc_url_raw(rest_url('mc-gallery/v1')), - 'uploadUrl' => esc_url_raw(admin_url('admin-ajax.php')), - 'nonce' => wp_create_nonce('mc_gallery_upload_action'), - 'forumNonce' => wp_create_nonce('mc_gallery_forum_bridge'), - 'maxUploads' => intval(get_option(self::OPTION_MAX_UPLOADS, 5)), - 'forumVerified' => $forum_verified_data, - 'votingEnabled' => get_option(self::OPTION_VOTING, true) ? true : false, - ]); - - // Forum-Bridge-JS nur laden, wenn Option aktiv und Forum-Plugin vorhanden - $forum_login = get_option(self::OPTION_FORUM_LOGIN, false); - if ($forum_login && class_exists('WBF_Auth')) { - wp_enqueue_script('mc-gallery-forum-bridge', MCGALLERY_PRO_URL . 'assets/js/forum-bridge.js?v=' . $js_version, ['jquery'], null, true); - } - } - - public static function register_rest_routes() { - register_rest_route('mc-gallery/v1','/servers',[ - 'methods'=>'GET', - 'callback'=>[__CLASS__,'rest_servers'], - 'permission_callback'=>'__return_true' - ]); - register_rest_route('mc-gallery/v1','/request-token',[ - 'methods'=>'POST', - 'callback'=>[__CLASS__,'rest_request_token'], - 'permission_callback'=>'__return_true' - ]); - register_rest_route('mc-gallery/v1','/check-token',[ - 'methods'=>'POST', - 'callback'=>[__CLASS__,'rest_check_token'], - 'permission_callback'=>'__return_true' - ]); - register_rest_route('mc-gallery/v1','/verify',[ - 'methods'=>'POST', - 'callback'=>[__CLASS__,'rest_verify_token'], - 'permission_callback'=>'__return_true' - ]); - register_rest_route('mc-gallery/v1','/albums',[ - 'methods'=>'POST', - 'callback'=>[__CLASS__,'rest_get_albums'], - 'permission_callback'=>'__return_true' - ]); - } - - public static function rest_servers($req) { - $servers = get_posts([ - 'post_type'=>'mc_server', - 'meta_key'=>'mc_server_active', - 'meta_value'=>1, - 'numberposts'=>-1 - ]); - $out = []; - foreach ($servers as $s) { - $out[] = [ - 'id' => intval($s->ID), - 'title' => $s->post_title - // 'host' key entfernt - ]; - } - return MC_Gallery_Helpers::rest_response_success($out); - } - - public static function rest_request_token($req) { - $params = $req->get_json_params(); - $username = sanitize_text_field($params['username'] ?? ''); - $server_id = intval($params['server_id'] ?? 0); - if (!$username || !$server_id) return new WP_REST_Response(['success'=>false,'message'=>'Missing data'],400); - if (!get_post($server_id)) return new WP_REST_Response(['success'=>false,'message'=>'Invalid server'],400); - - $tokens = MC_Gallery_Helpers::get_tokens(); - $token = MC_Gallery_Helpers::generate_token(40); - - $tokens[$token] = [ - 'server_id' => $server_id, - 'username' => $username, - 'created' => time(), - 'expires' => time() + self::SESSION_TTL, - 'claimed' => false, - 'claimed_by' => null, - 'used' => false, - 'session' => true - ]; - MC_Gallery_Helpers::save_tokens($tokens); - MC_Gallery_Helpers::error_log("Session token created for {$username}"); - return MC_Gallery_Helpers::rest_response_success([ - 'token'=>$token, - 'expires'=>date('c',$tokens[$token]['expires']), - 'session_duration' => self::SESSION_TTL - ]); - } - - public static function rest_check_token($req) { - $params = $req->get_json_params(); - $token = sanitize_text_field($params['token'] ?? ''); - if (!$token) return new WP_REST_Response(['success'=>false,'message'=>'Token missing'],400); - $tokens = MC_Gallery_Helpers::get_tokens(); - if (!isset($tokens[$token])) return new WP_REST_Response(['success'=>false,'message'=>'Token not found'],404); - if ($tokens[$token]['expires'] < time()) return new WP_REST_Response(['success'=>false,'message'=>'Session expired'],410); - return MC_Gallery_Helpers::rest_response_success([ - 'claimed' => $tokens[$token]['claimed'], - 'claimed_by' => $tokens[$token]['claimed_by'], - 'session' => $tokens[$token]['session'] ?? false - ]); - } - - public static function rest_verify_token($req) { - $params = $req->get_json_params(); - $player = sanitize_text_field($params['player'] ?? ''); - $token = sanitize_text_field($params['token'] ?? ''); - $server_id = intval($params['server_id'] ?? 0); - $signature = sanitize_text_field($params['signature'] ?? ''); - - MC_Gallery_Helpers::error_log("VERIFY REQUEST: Player={$player}, ServerID={$server_id}"); - - if (!$player || !$token || !$server_id || !$signature) { - MC_Gallery_Helpers::error_log("VERIFY FAIL: Incomplete data"); - return new WP_REST_Response(['success'=>false,'message'=>'Data incomplete'],400); - } - - $secret = get_post_meta($server_id,'mc_server_secret',true); - - if (is_string($secret)) { - $secret = trim($secret); - } - - if (empty($secret)) { - MC_Gallery_Helpers::error_log("VERIFY FAIL: Shared Secret is empty for Server ID {$server_id}"); - return new WP_REST_Response(['success'=>false,'message'=>'Server configuration error (No Secret)'],500); - } - MC_Gallery_Helpers::error_log("VERIFY: Secret loaded (first 10 chars): " . substr($secret, 0, 10)); - - // Name Check - $tokens = MC_Gallery_Helpers::get_tokens(); - if (!isset($tokens[$token])) { - MC_Gallery_Helpers::error_log("VERIFY FAIL: Token not found"); - return new WP_REST_Response(['success'=>false,'message'=>'Token not found'],404); - } - if ($tokens[$token]['expires'] < time()) { - MC_Gallery_Helpers::error_log("VERIFY FAIL: Session expired"); - return new WP_REST_Response(['success'=>false,'message'=>'Session expired'],410); - } - - if ($player !== $tokens[$token]['username']) { - MC_Gallery_Helpers::error_log("VERIFY FAIL: Name mismatch ({$player} vs {$tokens[$token]['username']})"); - return new WP_REST_Response(['success'=>false,'message'=>'Name does not match. Please verify with same name used in form.'], 403); - } - - // Signature Check (An Java Plugin angepasst) - $data_to_hash = $player . $token; - $expected = hash_hmac('sha256', $data_to_hash, $secret); - - MC_Gallery_Helpers::error_log("VERIFY: Data to hash: " . $data_to_hash); - MC_Gallery_Helpers::error_log("VERIFY: Expected Hash (first 10): " . substr($expected, 0, 10)); - MC_Gallery_Helpers::error_log("VERIFY: Received Signature: " . substr($signature, 0, 10)); - - if (!hash_equals($expected, $signature)) { - MC_Gallery_Helpers::error_log("VERIFY FAIL: Hash mismatch"); - return new WP_REST_Response(['success'=>false,'message'=>'Invalid signature'],401); - } - - // Success - $tokens[$token]['claimed'] = true; - $tokens[$token]['claimed_by'] = $player; - $tokens[$token]['claimed_at'] = time(); - MC_Gallery_Helpers::save_tokens($tokens); - MC_Gallery_Helpers::error_log("VERIFY SUCCESS: Player {$player} verified."); - - return MC_Gallery_Helpers::rest_response_success(['message'=>'Verified', 'session'=>true]); - } - - public static function rest_get_albums($req) { - $params = $req->get_json_params(); - $token = sanitize_text_field($params['token'] ?? ''); - $username = sanitize_text_field($params['username'] ?? ''); - $server_id = sanitize_text_field($params['server_id'] ?? ''); - - if (!$username) { - return new WP_REST_Response(['success'=>false,'message'=>'Missing username'],400); - } - - // ── Autorisierung: Token-Session ODER Forum-Login ───────────────────── - $authorized = false; - - if ($token) { - $tokens = MC_Gallery_Helpers::get_tokens(); - if (isset($tokens[$token]) && $tokens[$token]['claimed'] && $tokens[$token]['claimed_by'] === $username) { - if (!$server_id) $server_id = $tokens[$token]['server_id'] ?? ''; - $authorized = true; - } - } elseif (class_exists('WBF_Auth') && class_exists('MC_Gallery_Forum_Bridge')) { - $forum_user = WBF_Auth::get_current_user(); - if ($forum_user) { - $linked = MC_Gallery_Forum_Bridge::get_mc_username($forum_user->id); - if ($linked && MC_Gallery_Forum_Bridge::is_verified($forum_user->id) - && strtolower($linked) === strtolower($username)) { - if (!$server_id) $server_id = MC_Gallery_Forum_Bridge::get_mc_server($forum_user->id); - $authorized = true; - } - } - } - - if (!$authorized) { - return new WP_REST_Response(['success'=>false,'message'=>'Invalid session'],401); - } - - $server_id_val = is_numeric($server_id) ? intval($server_id) : $server_id; - - $gallery = MC_Gallery_Helpers::find_or_create_gallery_post($username, $server_id_val); - if (!$gallery) { - return MC_Gallery_Helpers::rest_response_success(['albums' => []]); - } - - $albums = get_posts([ - 'post_type' => 'mc_album', - 'posts_per_page' => -1, - 'meta_key' => 'mc_gallery_id', - 'meta_value' => $gallery->ID, - 'orderby' => 'date', - 'order' => 'DESC' - ]); - - $out = []; - foreach ($albums as $album) { - $out[] = [ - 'id' => $album->ID, - 'title' => $album->post_title - ]; - } - - return MC_Gallery_Helpers::rest_response_success(['albums' => $out]); - } - - // NEU: View Counter Handler - public static function handle_increment_view() { - if (!isset($_POST['attach_id']) || !is_numeric($_POST['attach_id'])) { - wp_send_json_error(['message' => 'Invalid Attachment ID']); - } - - $attach_id = intval($_POST['attach_id']); - - if (!wp_attachment_is_image($attach_id)) { - wp_send_json_error(['message' => 'Not an image']); - } - - $count = get_post_meta($attach_id, 'mc_views', true); - if ($count === false || $count === '') $count = 0; - - $count++; - update_post_meta($attach_id, 'mc_views', $count); - - wp_send_json_success(['views' => $count]); - } - - // NEU: Vote/Like Handler - public static function handle_vote() { - if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'mc_gallery_upload_action')) { - wp_send_json_error(['message' => 'Security check failed.']); - } - - if (!isset($_POST['attach_id']) || !is_numeric($_POST['attach_id'])) { - wp_send_json_error(['message' => 'Invalid ID.']); - } - - // Voting deaktiviert? - if (!get_option(self::OPTION_VOTING, true)) { - wp_send_json_error(['message' => 'Voting ist deaktiviert.']); - } - - $attach_id = intval($_POST['attach_id']); - $vote_type = sanitize_text_field($_POST['vote_type'] ?? 'up'); // 'up' oder 'down' - $vote_action = sanitize_text_field($_POST['vote_action'] ?? 'add'); // 'add' oder 'remove' - - $post = get_post($attach_id); - if (!$post || $post->post_type !== 'attachment' || strpos($post->post_mime_type, 'image/') !== 0) { - wp_send_json_error(['message' => 'Not a valid image.']); - } - - $meta_key = ($vote_type === 'down') ? 'mc_votes_down' : 'mc_votes_up'; - $count = (int) get_post_meta($attach_id, $meta_key, true); - $count = ($vote_action === 'remove') ? max(0, $count - 1) : $count + 1; - update_post_meta($attach_id, $meta_key, $count); - - wp_send_json_success([ - 'votes_up' => (int) get_post_meta($attach_id, 'mc_votes_up', true), - 'votes_down' => (int) get_post_meta($attach_id, 'mc_votes_down', true), - 'vote_type' => $vote_type, - 'vote_action'=> $vote_action, - ]); - } - - public static function handle_create_album() { - if (!isset($_POST['mc_upload_nonce']) || !wp_verify_nonce($_POST['mc_upload_nonce'], 'mc_gallery_upload_action')) { - wp_send_json_error(['message' => 'Security check failed.']); - } - - $token = sanitize_text_field($_POST['mc_token'] ?? ''); - $username = sanitize_text_field($_POST['mc_username'] ?? ''); - $server_id = sanitize_text_field($_POST['mc_server_id'] ?? ''); - $album_name = sanitize_text_field($_POST['album_name'] ?? ''); - - if (!$username || !$album_name) { - wp_send_json_error(['message' => 'Missing data']); - } - - // ── Autorisierung: Token-Session ODER Forum-Login ───────────────────── - $authorized = false; - - if ($token) { - $tokens = MC_Gallery_Helpers::get_tokens(); - if (isset($tokens[$token]) && $tokens[$token]['claimed'] && $tokens[$token]['claimed_by'] === $username && $tokens[$token]['expires'] >= time()) { - if (!$server_id) $server_id = $tokens[$token]['server_id'] ?? ''; - $authorized = true; - } else { - wp_send_json_error(['message' => 'Invalid or expired session']); - } - } elseif (class_exists('WBF_Auth') && class_exists('MC_Gallery_Forum_Bridge')) { - $forum_user = WBF_Auth::get_current_user(); - if ($forum_user) { - $linked_mc = MC_Gallery_Forum_Bridge::get_mc_username($forum_user->id); - $verified = MC_Gallery_Forum_Bridge::is_verified($forum_user->id); - if ($linked_mc && $verified && strtolower($linked_mc) === strtolower($username)) { - if (!$server_id) $server_id = MC_Gallery_Forum_Bridge::get_mc_server($forum_user->id); - $authorized = true; - } - } - } - - if (!$authorized) { - wp_send_json_error(['message' => 'Nicht autorisiert.']); - } - - $server_id_val = is_numeric($server_id) ? intval($server_id) : $server_id; - - $gallery = MC_Gallery_Helpers::find_or_create_gallery_post($username, $server_id_val); - if (!$gallery) { - wp_send_json_error(['message' => 'Gallery not found']); - } - - $album_id = wp_insert_post([ - 'post_type' => 'mc_album', - 'post_title' => $album_name, - 'post_status' => 'publish', - 'meta_input' => [ - 'mc_gallery_id' => $gallery->ID, - 'mc_image_count' => 0 - ] - ]); - - if (is_wp_error($album_id)) { - wp_send_json_error(['message' => 'Could not create album']); - } - - wp_send_json_success([ - 'message' => 'Album successfully created', - 'album' => [ - 'id' => $album_id, - 'title' => $album_name - ] - ]); - } - - public static function handle_upload() { - if (!isset($_POST['mc_upload_nonce']) || !wp_verify_nonce($_POST['mc_upload_nonce'], 'mc_gallery_upload_action')) { - wp_send_json_error(['message' => 'Security check failed.']); - } - - $token = sanitize_text_field($_POST['mc_token'] ?? ''); - $username = sanitize_text_field($_POST['mc_username'] ?? ''); - $server_id = sanitize_text_field($_POST['mc_server_id'] ?? ''); - $album_id = intval($_POST['mc_album_id'] ?? 0); - - if (!$username) { - wp_send_json_error(['message' => 'Benutzername fehlt.']); - } - - // ── Autorisierung: Token-Session ODER Forum-Login ───────────────────── - $authorized = false; - - if ($token) { - // Standard-Weg: Ingame-Token verifizieren - $tokens = MC_Gallery_Helpers::get_tokens(); - if (!isset($tokens[$token])) { - wp_send_json_error(['message' => 'Invalid token.']); - } - $t = $tokens[$token]; - if ($t['expires'] < time()) { - wp_send_json_error(['message' => 'Session expired.']); - } - if (!$t['claimed'] || $t['claimed_by'] !== $username) { - wp_send_json_error(['message' => 'Verification failed. Please go back to step 2 and use /verify']); - } - // server_id aus Token übernehmen falls nicht per POST übergeben - if (!$server_id) { - $server_id = $t['server_id'] ?? ''; - } - - // Wenn ein Forum-Account mit diesem MC-Namen verknüpft ist, - // den Link bei erfolgreichem Token-Flow automatisch verifizieren. - if (class_exists('MC_Gallery_Forum_Bridge')) { - MC_Gallery_Forum_Bridge::verify_linked_user_by_mc_username($username); - } - - $authorized = true; - } elseif (class_exists('WBF_Auth') && class_exists('MC_Gallery_Forum_Bridge')) { - // Forum-Login-Weg: eingeloggten Forum-User prüfen - $forum_user = WBF_Auth::get_current_user(); - if ($forum_user) { - $linked_mc = MC_Gallery_Forum_Bridge::get_mc_username($forum_user->id); - $verified = MC_Gallery_Forum_Bridge::is_verified($forum_user->id); - if ($linked_mc && $verified && strtolower($linked_mc) === strtolower($username)) { - // server_id aus Profil holen falls nicht übergeben - if (!$server_id) { - $server_id = MC_Gallery_Forum_Bridge::get_mc_server($forum_user->id); - } - $authorized = true; - } - } - } - - if (!$authorized) { - wp_send_json_error(['message' => 'Nicht autorisiert. Bitte zuerst verifizieren.']); - } - - // server_id als Integer für wp_query (falls numeric), sonst als String belassen - $server_id_val = is_numeric($server_id) ? intval($server_id) : $server_id; - if (!$server_id_val) { - wp_send_json_error(['message' => 'Server-ID fehlt.']); - } - - if (empty($_FILES['mc_images']) || !is_array($_FILES['mc_images']['name'])) { - wp_send_json_error(['message' => 'No files uploaded.']); - } - - require_once(ABSPATH . 'wp-admin/includes/file.php'); - require_once(ABSPATH . 'wp-admin/includes/image.php'); - require_once(ABSPATH . 'wp-admin/includes/media.php'); - - $current_user_id = get_current_user_id(); - $temp_user_id = 0; - if ($current_user_id === 0) { - $admins = get_users(['role' => 'administrator', 'number' => 1]); - if ($admins) { - $temp_user_id = $admins[0]->ID; - wp_set_current_user($temp_user_id); - } - } - - $uploaded = []; - $errors = []; - - try { - $gallery_post = MC_Gallery_Helpers::find_or_create_gallery_post($username, $server_id_val); - if (!$gallery_post) throw new Exception('Gallery not found.'); - - if (empty($_FILES['mc_images']) || !is_array($_FILES['mc_images']['name'])) { - wp_send_json_error(['message' => 'No files uploaded or invalid format.']); - } - - $files = $_FILES['mc_images']; - - foreach (array_keys($files['name']) as $i) { - if ($files['error'][$i] !== UPLOAD_ERR_OK) { - $errors[] = $files['name'][$i] . ': Upload error'; - continue; - } - - $file = [ - 'name' => $files['name'][$i], - 'type' => $files['type'][$i], - 'tmp_name' => $files['tmp_name'][$i], - 'error' => $files['error'][$i], - 'size' => $files['size'][$i] - ]; - - $allowed = ['image/jpeg','image/png','image/gif','image/webp']; - if (!in_array($file['type'], $allowed)) { - $errors[] = $file['name'] . ': Only images allowed'; - continue; - } - - $overrides = ['test_form' => false]; - $movefile = wp_handle_upload($file, $overrides); - - if (isset($movefile['error'])) { - $errors[] = $file['name'] . ': ' . $movefile['error']; - continue; - } - - $wp_filetype = wp_check_filetype(basename($movefile['file']), null); - $attachment = [ - 'guid' => $movefile['url'], - 'post_mime_type' => $wp_filetype['type'], - 'post_title' => sanitize_text_field($file['name']), - 'post_content' => '', - 'post_status' => 'inherit' - ]; - - $attach_id = wp_insert_attachment($attachment, $movefile['file']); - if (is_wp_error($attach_id)) { - $errors[] = $file['name'] . ': ' . $attach_id->get_error_message(); - continue; - } - - // View Counter initialisieren - add_post_meta($attach_id, 'mc_views', 0); - - $attach_data = wp_generate_attachment_metadata($attach_id, $movefile['file']); - - // Bildgröße anpassen - $resize_pct = intval(get_option(self::OPTION_RESIZE_PCT, 100)); - if ($resize_pct < 100 && $resize_pct > 0) { - $original_file = $movefile['file']; - $editor = wp_get_image_editor($original_file); - if (!is_wp_error($editor)) { - $size = $editor->get_size(); - $new_w = $size['width'] * ($resize_pct / 100); - $new_h = $size['height'] * ($resize_pct / 100); - $resized_path = image_make_intermediate_size($original_file, $new_w, $new_h, false); - if (!empty($resized_path)) { - $attach_data['sizes']['mc-optimized'] = $resized_path; - } - } - } - - wp_update_attachment_metadata($attach_id, $attach_data); - wp_update_post(['ID' => $attach_id, 'post_parent' => $gallery_post->ID]); - - // Album zuweisen - if ($album_id) { - update_post_meta($attach_id, 'mc_album_id', $album_id); - $count = get_post_meta($album_id, 'mc_image_count', true) ?: 0; - update_post_meta($album_id, 'mc_image_count', $count + 1); - } - - $uploaded[] = $file['name']; - } - - $response = [ - 'message' => count($uploaded) . ' image(s) successfully uploaded!', - 'uploaded' => $uploaded - ]; - - if (!empty($errors)) { - $response['errors'] = $errors; - } - - wp_send_json_success($response); - - } catch (Exception $e) { - wp_send_json_error(['message' => 'Error: ' . $e->getMessage()]); - } finally { - if ($temp_user_id) wp_set_current_user(0); - } - } - - public static function get_default_thumb_h() { - return intval(get_option(self::OPTION_THUMB_H, 200)); - } +post_type !== 'mc_server') return; + ?> + + ID, 'mc_server_host', true); // REMOVED + $secret = get_post_meta($post->ID, 'mc_server_secret', true); + $active = get_post_meta($post->ID, 'mc_server_active', true); + $id = intval($post->ID); + + $has_secret = !empty($secret); + + wp_nonce_field('mc_server_nonce', 'mc_server_nonce'); + ?> + + + + + + + + + + + + + + +
+ +

Aktivieren, damit Spieler diesen Server sehen und Token anfragen können.

+
+ + + +

✓ Automatisch generiert. Trage diesen Key in deine Java config.yml ein.

+ +
+ Wird automatisch generiert... +

Bitte klicke auf "Veröffentlichen". Nach dem Speichern erscheint hier dein Secret und die Server ID.

+
+ +
Server ID (WP) + 0 ? $id : '(Wird zugewiesen)'; ?> +

Diese Nummer ist deine server_id. Trage diese Zahl in deine Java Config ein.

+
+ Generieren + $final_secret = wp_generate_password(32, false); + } else { + // BESTEHENDER SERVER + if (!empty($input_secret)) { + $final_secret = $input_secret; + } else { + $final_secret = $current_secret; + } + } + + update_post_meta($post_id, 'mc_server_secret', $final_secret); + } + + public static function register_post_types() { + register_post_type('mc_server', [ + 'labels' => ['name' => 'MC Server', 'singular_name' => 'MC Server'], + 'public' => false, + 'show_ui' => true, + 'supports' => ['title'], + 'show_in_menu' => false + ]); + + register_post_type('mc_gallery', [ + 'labels' => ['name' => 'MC Galleries', 'singular_name' => 'MC Gallery'], + 'public' => false, + 'show_ui' => true, + 'supports' => ['title'], + 'has_archive' => false, + 'rewrite' => false, + 'show_in_menu' => false + ]); + + register_post_type('mc_album', [ + 'labels' => ['name' => 'MC Albums', 'singular_name' => 'MC Album'], + 'public' => false, + 'show_ui' => true, + 'supports' => ['title'], + 'has_archive' => false, + 'rewrite' => false, + 'show_in_menu' => false + ]); + } + + public static function admin_menu() { + add_menu_page('MC Gallery PRO', 'MC Gallery PRO', 'manage_options', 'mc-gallery-pro', [__CLASS__, 'settings_page'], 'dashicons-format-gallery', 30); + add_submenu_page('mc-gallery-pro', 'Einstellungen', 'Einstellungen', 'manage_options', 'mc-gallery-pro', [__CLASS__, 'settings_page']); + add_submenu_page('mc-gallery-pro', 'MC Server', 'MC Server', 'manage_options', 'edit.php?post_type=mc_server'); + add_submenu_page('mc-gallery-pro', 'MC Galleries', 'MC Galleries', 'manage_options', 'edit.php?post_type=mc_gallery'); + add_submenu_page('mc-gallery-pro', 'MC Albums', 'MC Albums', 'manage_options', 'edit.php?post_type=mc_album'); + } + + public static function register_settings() { + register_setting('mc_gallery_pro_group', self::OPTION_THUMB_H, ['type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 200]); + register_setting('mc_gallery_pro_group', self::OPTION_RESIZE_PCT, ['type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 100]); + register_setting('mc_gallery_pro_group', self::OPTION_SHOW_DATE, [ + 'type' => 'boolean', + 'sanitize_callback' => function($input) { return $input == '1' || $input === true || $input === 'on'; }, + 'default' => true + ]); + register_setting('mc_gallery_pro_group', self::OPTION_MAX_UPLOADS, [ + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'default' => 5 + ]); + register_setting('mc_gallery_pro_group', self::OPTION_FORUM_LOGIN, [ + 'type' => 'boolean', + 'sanitize_callback' => function($input) { return !empty($input) && $input !== '0'; }, + 'default' => false + ]); + register_setting('mc_gallery_pro_group', self::OPTION_VOTING, [ + 'type' => 'boolean', + 'sanitize_callback' => function($input) { return !empty($input) && $input !== '0'; }, + 'default' => true + ]); + } + + public static function settings_page() { + $thumb_h = get_option(self::OPTION_THUMB_H, 200); + $resize_pct = get_option(self::OPTION_RESIZE_PCT, 100); + $show_date = get_option(self::OPTION_SHOW_DATE, true); + $max_uploads = get_option(self::OPTION_MAX_UPLOADS, 5); + $forum_login = get_option(self::OPTION_FORUM_LOGIN, false); + $forum_plugin_active = class_exists('WBF_Auth'); + + // Prüfen ob das Forum-Plugin zwar existiert (Datei vorhanden) aber nicht aktiv ist + $forum_plugin_installed = false; + if ( ! $forum_plugin_active ) { + $all_plugins = get_plugins(); + foreach ( $all_plugins as $plugin_file => $plugin_data ) { + if ( stripos( $plugin_data['Name'], 'WP Business Forum' ) !== false + || stripos( $plugin_data['TextDomain'], 'wp-business-forum' ) !== false + || stripos( $plugin_file, 'wp-business-forum' ) !== false ) { + $forum_plugin_installed = true; + break; + } + } + } + ?> +
+

MC Gallery PRO Settings

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Thumbnail Height (px)
Image Resize % (Upload) + +

Default is 100% (Original). Values like 50 or 70 save space. Aspect ratio is kept.

+
Show Date + +
Max. Images per Upload + +

How many images can a user upload at once? (Default: 5)

+
+ Forum-Login für Upload-Verifizierung +
Benötigt: WP Business Forum +
+ + + +
+ + + WP Business Forum aktiv + +
+ +

+ Wenn aktiviert, können sich Nutzer die ihren Minecraft-Account im Forum-Profil verknüpft haben, direkt ohne Ingame-Token hochladen.
+ Der Shortcode: [mc_gallery_combined] ermöglicht eine kombinierte Verifizierung für Token und Forum. +

+ + + + +
+ ⚠ WP Business Forum ist installiert, aber nicht aktiviert.
+ Aktiviere das Plugin unter Plugins → Installierte Plugins, um diese Funktion zu nutzen. +
+ + + + + +
+ ✗ WP Business Forum ist nicht installiert.
+ + Dieses Feature benötigt das Plugin WP Business Forum von M_Viper.
+ + ↓ Jetzt herunterladen (Gitea) + +  ·  + + Plugins → Neu hinzufügen + +
+
+ +

+ Nach der Installation und Aktivierung von WP Business Forum wird diese Option freigeschaltet. +

+ + +
Abstimmung (Daumen hoch/runter) + +

+ Besucher können Bilder mit 👍 oder 👎 bewerten. Jeder kann abstimmen (kein Login nötig).
+ Shortcode für die Bestenliste: [mc_gallery_vote] +

+
+ +
+
+ id ); + $verified = MC_Gallery_Forum_Bridge::is_verified( $forum_user->id ); + if ( $mc_user && $verified ) { + $raw_sv = MC_Gallery_Forum_Bridge::get_mc_server( $forum_user->id ); + // Sicherstellen dass server_id immer ein Integer (Post-ID) ist + $server_id_int = is_numeric( $raw_sv ) ? intval( $raw_sv ) : 0; + if ( ! $server_id_int && ! empty( $raw_sv ) ) { + // Slug/Titel auflösen + $p = get_page_by_path( $raw_sv, OBJECT, 'mc_server' ); + if ( $p ) { + $server_id_int = $p->ID; + MC_Gallery_Forum_Bridge::set_mc_server( $forum_user->id, $server_id_int ); + } + } + // Fallback: ersten aktiven Server nehmen + if ( ! $server_id_int ) { + $fallback = get_posts( [ 'post_type' => 'mc_server', 'posts_per_page' => 1, + 'post_status' => 'publish', 'meta_key' => 'mc_server_active', 'meta_value' => 1 ] ); + if ( $fallback ) $server_id_int = $fallback[0]->ID; + } + $forum_verified_data = [ + 'mc_username' => $mc_user, + 'server_id' => $server_id_int, + 'display_name' => $forum_user->display_name, + ]; + } + } + } + + wp_localize_script('mc-gallery-pro-js', 'mcGalleryPro', [ + 'restBase' => esc_url_raw(rest_url('mc-gallery/v1')), + 'uploadUrl' => esc_url_raw(admin_url('admin-ajax.php')), + 'nonce' => wp_create_nonce('mc_gallery_upload_action'), + 'forumNonce' => wp_create_nonce('mc_gallery_forum_bridge'), + 'maxUploads' => intval(get_option(self::OPTION_MAX_UPLOADS, 5)), + 'forumVerified' => $forum_verified_data, + 'votingEnabled' => get_option(self::OPTION_VOTING, true) ? true : false, + ]); + + // Forum-Bridge-JS nur laden, wenn Option aktiv und Forum-Plugin vorhanden + $forum_login = get_option(self::OPTION_FORUM_LOGIN, false); + if ($forum_login && class_exists('WBF_Auth')) { + wp_enqueue_script('mc-gallery-forum-bridge', MCGALLERY_PRO_URL . 'assets/js/forum-bridge.js?v=' . $js_version, ['jquery'], null, true); + } + } + + public static function register_rest_routes() { + register_rest_route('mc-gallery/v1','/servers',[ + 'methods'=>'GET', + 'callback'=>[__CLASS__,'rest_servers'], + 'permission_callback'=>'__return_true' + ]); + register_rest_route('mc-gallery/v1','/request-token',[ + 'methods'=>'POST', + 'callback'=>[__CLASS__,'rest_request_token'], + 'permission_callback'=>'__return_true' + ]); + register_rest_route('mc-gallery/v1','/check-token',[ + 'methods'=>'POST', + 'callback'=>[__CLASS__,'rest_check_token'], + 'permission_callback'=>'__return_true' + ]); + register_rest_route('mc-gallery/v1','/verify',[ + 'methods'=>'POST', + 'callback'=>[__CLASS__,'rest_verify_token'], + 'permission_callback'=>'__return_true' + ]); + register_rest_route('mc-gallery/v1','/albums',[ + 'methods'=>'POST', + 'callback'=>[__CLASS__,'rest_get_albums'], + 'permission_callback'=>'__return_true' + ]); + } + + public static function rest_servers($req) { + $servers = get_posts([ + 'post_type'=>'mc_server', + 'meta_key'=>'mc_server_active', + 'meta_value'=>1, + 'numberposts'=>-1 + ]); + $out = []; + foreach ($servers as $s) { + $out[] = [ + 'id' => intval($s->ID), + 'title' => $s->post_title + // 'host' key entfernt + ]; + } + return MC_Gallery_Helpers::rest_response_success($out); + } + + public static function rest_request_token($req) { + $params = $req->get_json_params(); + $username = sanitize_text_field($params['username'] ?? ''); + $server_id = intval($params['server_id'] ?? 0); + if (!$username || !$server_id) return new WP_REST_Response(['success'=>false,'message'=>'Missing data'],400); + if (!get_post($server_id)) return new WP_REST_Response(['success'=>false,'message'=>'Invalid server'],400); + + $tokens = MC_Gallery_Helpers::get_tokens(); + $token = MC_Gallery_Helpers::generate_token(40); + + $tokens[$token] = [ + 'server_id' => $server_id, + 'username' => $username, + 'created' => time(), + 'expires' => time() + self::SESSION_TTL, + 'claimed' => false, + 'claimed_by' => null, + 'used' => false, + 'session' => true + ]; + MC_Gallery_Helpers::save_tokens($tokens); + MC_Gallery_Helpers::error_log("Session token created for {$username}"); + return MC_Gallery_Helpers::rest_response_success([ + 'token'=>$token, + 'expires'=>date('c',$tokens[$token]['expires']), + 'session_duration' => self::SESSION_TTL + ]); + } + + public static function rest_check_token($req) { + $params = $req->get_json_params(); + $token = sanitize_text_field($params['token'] ?? ''); + if (!$token) return new WP_REST_Response(['success'=>false,'message'=>'Token missing'],400); + $tokens = MC_Gallery_Helpers::get_tokens(); + if (!isset($tokens[$token])) return new WP_REST_Response(['success'=>false,'message'=>'Token not found'],404); + if ($tokens[$token]['expires'] < time()) return new WP_REST_Response(['success'=>false,'message'=>'Session expired'],410); + return MC_Gallery_Helpers::rest_response_success([ + 'claimed' => $tokens[$token]['claimed'], + 'claimed_by' => $tokens[$token]['claimed_by'], + 'session' => $tokens[$token]['session'] ?? false + ]); + } + + public static function rest_verify_token($req) { + $params = $req->get_json_params(); + $player = sanitize_text_field($params['player'] ?? ''); + $token = sanitize_text_field($params['token'] ?? ''); + $server_id = intval($params['server_id'] ?? 0); + $signature = sanitize_text_field($params['signature'] ?? ''); + + MC_Gallery_Helpers::error_log("VERIFY REQUEST: Player={$player}, ServerID={$server_id}"); + + if (!$player || !$token || !$server_id || !$signature) { + MC_Gallery_Helpers::error_log("VERIFY FAIL: Incomplete data"); + return new WP_REST_Response(['success'=>false,'message'=>'Data incomplete'],400); + } + + $secret = get_post_meta($server_id,'mc_server_secret',true); + + if (is_string($secret)) { + $secret = trim($secret); + } + + if (empty($secret)) { + MC_Gallery_Helpers::error_log("VERIFY FAIL: Shared Secret is empty for Server ID {$server_id}"); + return new WP_REST_Response(['success'=>false,'message'=>'Server configuration error (No Secret)'],500); + } + MC_Gallery_Helpers::error_log("VERIFY: Secret loaded (first 10 chars): " . substr($secret, 0, 10)); + + // Name Check + $tokens = MC_Gallery_Helpers::get_tokens(); + if (!isset($tokens[$token])) { + MC_Gallery_Helpers::error_log("VERIFY FAIL: Token not found"); + return new WP_REST_Response(['success'=>false,'message'=>'Token not found'],404); + } + if ($tokens[$token]['expires'] < time()) { + MC_Gallery_Helpers::error_log("VERIFY FAIL: Session expired"); + return new WP_REST_Response(['success'=>false,'message'=>'Session expired'],410); + } + + if ($player !== $tokens[$token]['username']) { + MC_Gallery_Helpers::error_log("VERIFY FAIL: Name mismatch ({$player} vs {$tokens[$token]['username']})"); + return new WP_REST_Response(['success'=>false,'message'=>'Name does not match. Please verify with same name used in form.'], 403); + } + + // Signature Check (An Java Plugin angepasst) + $data_to_hash = $player . $token; + $expected = hash_hmac('sha256', $data_to_hash, $secret); + + MC_Gallery_Helpers::error_log("VERIFY: Data to hash: " . $data_to_hash); + MC_Gallery_Helpers::error_log("VERIFY: Expected Hash (first 10): " . substr($expected, 0, 10)); + MC_Gallery_Helpers::error_log("VERIFY: Received Signature: " . substr($signature, 0, 10)); + + if (!hash_equals($expected, $signature)) { + MC_Gallery_Helpers::error_log("VERIFY FAIL: Hash mismatch"); + return new WP_REST_Response(['success'=>false,'message'=>'Invalid signature'],401); + } + + // Success + $tokens[$token]['claimed'] = true; + $tokens[$token]['claimed_by'] = $player; + $tokens[$token]['claimed_at'] = time(); + MC_Gallery_Helpers::save_tokens($tokens); + MC_Gallery_Helpers::error_log("VERIFY SUCCESS: Player {$player} verified."); + + return MC_Gallery_Helpers::rest_response_success(['message'=>'Verified', 'session'=>true]); + } + + public static function rest_get_albums($req) { + $params = $req->get_json_params(); + $token = sanitize_text_field($params['token'] ?? ''); + $username = sanitize_text_field($params['username'] ?? ''); + $server_id = sanitize_text_field($params['server_id'] ?? ''); + + if (!$username) { + return new WP_REST_Response(['success'=>false,'message'=>'Missing username'],400); + } + + // ── Autorisierung: Token-Session ODER Forum-Login ───────────────────── + $authorized = false; + + if ($token) { + $tokens = MC_Gallery_Helpers::get_tokens(); + if (isset($tokens[$token]) && $tokens[$token]['claimed'] && $tokens[$token]['claimed_by'] === $username) { + if (!$server_id) $server_id = $tokens[$token]['server_id'] ?? ''; + $authorized = true; + } + } elseif (class_exists('WBF_Auth') && class_exists('MC_Gallery_Forum_Bridge')) { + $forum_user = WBF_Auth::get_current_user(); + if ($forum_user) { + $linked = MC_Gallery_Forum_Bridge::get_mc_username($forum_user->id); + if ($linked && MC_Gallery_Forum_Bridge::is_verified($forum_user->id) + && strtolower($linked) === strtolower($username)) { + if (!$server_id) $server_id = MC_Gallery_Forum_Bridge::get_mc_server($forum_user->id); + $authorized = true; + } + } + } + + if (!$authorized) { + return new WP_REST_Response(['success'=>false,'message'=>'Invalid session'],401); + } + + $server_id_val = is_numeric($server_id) ? intval($server_id) : $server_id; + + $gallery = MC_Gallery_Helpers::find_or_create_gallery_post($username, $server_id_val); + if (!$gallery) { + return MC_Gallery_Helpers::rest_response_success(['albums' => []]); + } + + $albums = get_posts([ + 'post_type' => 'mc_album', + 'posts_per_page' => -1, + 'meta_key' => 'mc_gallery_id', + 'meta_value' => $gallery->ID, + 'orderby' => 'date', + 'order' => 'DESC' + ]); + + $out = []; + foreach ($albums as $album) { + $out[] = [ + 'id' => $album->ID, + 'title' => $album->post_title + ]; + } + + return MC_Gallery_Helpers::rest_response_success(['albums' => $out]); + } + + // NEU: View Counter Handler + public static function handle_increment_view() { + if (!isset($_POST['attach_id']) || !is_numeric($_POST['attach_id'])) { + wp_send_json_error(['message' => 'Invalid Attachment ID']); + } + + $attach_id = intval($_POST['attach_id']); + + if (!wp_attachment_is_image($attach_id)) { + wp_send_json_error(['message' => 'Not an image']); + } + + $count = get_post_meta($attach_id, 'mc_views', true); + if ($count === false || $count === '') $count = 0; + + $count++; + update_post_meta($attach_id, 'mc_views', $count); + + wp_send_json_success(['views' => $count]); + } + + // NEU: Vote/Like Handler + public static function handle_vote() { + if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'mc_gallery_upload_action')) { + wp_send_json_error(['message' => 'Security check failed.']); + } + + if (!isset($_POST['attach_id']) || !is_numeric($_POST['attach_id'])) { + wp_send_json_error(['message' => 'Invalid ID.']); + } + + // Voting deaktiviert? + if (!get_option(self::OPTION_VOTING, true)) { + wp_send_json_error(['message' => 'Voting ist deaktiviert.']); + } + + $attach_id = intval($_POST['attach_id']); + $vote_type = sanitize_text_field($_POST['vote_type'] ?? 'up'); // 'up' oder 'down' + $vote_action = sanitize_text_field($_POST['vote_action'] ?? 'add'); // 'add' oder 'remove' + + $post = get_post($attach_id); + if (!$post || $post->post_type !== 'attachment' || strpos($post->post_mime_type, 'image/') !== 0) { + wp_send_json_error(['message' => 'Not a valid image.']); + } + + $meta_key = ($vote_type === 'down') ? 'mc_votes_down' : 'mc_votes_up'; + $count = (int) get_post_meta($attach_id, $meta_key, true); + $count = ($vote_action === 'remove') ? max(0, $count - 1) : $count + 1; + update_post_meta($attach_id, $meta_key, $count); + + wp_send_json_success([ + 'votes_up' => (int) get_post_meta($attach_id, 'mc_votes_up', true), + 'votes_down' => (int) get_post_meta($attach_id, 'mc_votes_down', true), + 'vote_type' => $vote_type, + 'vote_action'=> $vote_action, + ]); + } + + public static function handle_create_album() { + if (!isset($_POST['mc_upload_nonce']) || !wp_verify_nonce($_POST['mc_upload_nonce'], 'mc_gallery_upload_action')) { + wp_send_json_error(['message' => 'Security check failed.']); + } + + $token = sanitize_text_field($_POST['mc_token'] ?? ''); + $username = sanitize_text_field($_POST['mc_username'] ?? ''); + $server_id = sanitize_text_field($_POST['mc_server_id'] ?? ''); + $album_name = sanitize_text_field($_POST['album_name'] ?? ''); + + if (!$username || !$album_name) { + wp_send_json_error(['message' => 'Missing data']); + } + + // ── Autorisierung: Token-Session ODER Forum-Login ───────────────────── + $authorized = false; + + if ($token) { + $tokens = MC_Gallery_Helpers::get_tokens(); + if (isset($tokens[$token]) && $tokens[$token]['claimed'] && $tokens[$token]['claimed_by'] === $username && $tokens[$token]['expires'] >= time()) { + if (!$server_id) $server_id = $tokens[$token]['server_id'] ?? ''; + $authorized = true; + } else { + wp_send_json_error(['message' => 'Invalid or expired session']); + } + } elseif (class_exists('WBF_Auth') && class_exists('MC_Gallery_Forum_Bridge')) { + $forum_user = WBF_Auth::get_current_user(); + if ($forum_user) { + $linked_mc = MC_Gallery_Forum_Bridge::get_mc_username($forum_user->id); + $verified = MC_Gallery_Forum_Bridge::is_verified($forum_user->id); + if ($linked_mc && $verified && strtolower($linked_mc) === strtolower($username)) { + if (!$server_id) $server_id = MC_Gallery_Forum_Bridge::get_mc_server($forum_user->id); + $authorized = true; + } + } + } + + if (!$authorized) { + wp_send_json_error(['message' => 'Nicht autorisiert.']); + } + + $server_id_val = is_numeric($server_id) ? intval($server_id) : $server_id; + + $gallery = MC_Gallery_Helpers::find_or_create_gallery_post($username, $server_id_val); + if (!$gallery) { + wp_send_json_error(['message' => 'Gallery not found']); + } + + $album_id = wp_insert_post([ + 'post_type' => 'mc_album', + 'post_title' => $album_name, + 'post_status' => 'publish', + 'meta_input' => [ + 'mc_gallery_id' => $gallery->ID, + 'mc_image_count' => 0 + ] + ]); + + if (is_wp_error($album_id)) { + wp_send_json_error(['message' => 'Could not create album']); + } + + wp_send_json_success([ + 'message' => 'Album successfully created', + 'album' => [ + 'id' => $album_id, + 'title' => $album_name + ] + ]); + } + + public static function handle_upload() { + if (!isset($_POST['mc_upload_nonce']) || !wp_verify_nonce($_POST['mc_upload_nonce'], 'mc_gallery_upload_action')) { + wp_send_json_error(['message' => 'Security check failed.']); + } + + $token = sanitize_text_field($_POST['mc_token'] ?? ''); + $username = sanitize_text_field($_POST['mc_username'] ?? ''); + $server_id = sanitize_text_field($_POST['mc_server_id'] ?? ''); + $album_id = intval($_POST['mc_album_id'] ?? 0); + + if (!$username) { + wp_send_json_error(['message' => 'Benutzername fehlt.']); + } + + // ── Autorisierung: Token-Session ODER Forum-Login ───────────────────── + $authorized = false; + + if ($token) { + // Standard-Weg: Ingame-Token verifizieren + $tokens = MC_Gallery_Helpers::get_tokens(); + if (!isset($tokens[$token])) { + wp_send_json_error(['message' => 'Invalid token.']); + } + $t = $tokens[$token]; + if ($t['expires'] < time()) { + wp_send_json_error(['message' => 'Session expired.']); + } + if (!$t['claimed'] || $t['claimed_by'] !== $username) { + wp_send_json_error(['message' => 'Verification failed. Please go back to step 2 and use /verify']); + } + // server_id aus Token übernehmen falls nicht per POST übergeben + if (!$server_id) { + $server_id = $t['server_id'] ?? ''; + } + + // Wenn ein Forum-Account mit diesem MC-Namen verknüpft ist, + // den Link bei erfolgreichem Token-Flow automatisch verifizieren. + if (class_exists('MC_Gallery_Forum_Bridge')) { + MC_Gallery_Forum_Bridge::verify_linked_user_by_mc_username($username); + } + + $authorized = true; + } elseif (class_exists('WBF_Auth') && class_exists('MC_Gallery_Forum_Bridge')) { + // Forum-Login-Weg: eingeloggten Forum-User prüfen + $forum_user = WBF_Auth::get_current_user(); + if ($forum_user) { + $linked_mc = MC_Gallery_Forum_Bridge::get_mc_username($forum_user->id); + $verified = MC_Gallery_Forum_Bridge::is_verified($forum_user->id); + if ($linked_mc && $verified && strtolower($linked_mc) === strtolower($username)) { + // server_id aus Profil holen falls nicht übergeben + if (!$server_id) { + $server_id = MC_Gallery_Forum_Bridge::get_mc_server($forum_user->id); + } + $authorized = true; + } + } + } + + if (!$authorized) { + wp_send_json_error(['message' => 'Nicht autorisiert. Bitte zuerst verifizieren.']); + } + + // server_id als Integer für wp_query (falls numeric), sonst als String belassen + $server_id_val = is_numeric($server_id) ? intval($server_id) : $server_id; + if (!$server_id_val) { + wp_send_json_error(['message' => 'Server-ID fehlt.']); + } + + if (empty($_FILES['mc_images']) || !is_array($_FILES['mc_images']['name'])) { + wp_send_json_error(['message' => 'No files uploaded.']); + } + + require_once(ABSPATH . 'wp-admin/includes/file.php'); + require_once(ABSPATH . 'wp-admin/includes/image.php'); + require_once(ABSPATH . 'wp-admin/includes/media.php'); + + $current_user_id = get_current_user_id(); + $temp_user_id = 0; + if ($current_user_id === 0) { + $admins = get_users(['role' => 'administrator', 'number' => 1]); + if ($admins) { + $temp_user_id = $admins[0]->ID; + wp_set_current_user($temp_user_id); + } + } + + $uploaded = []; + $errors = []; + + try { + $gallery_post = MC_Gallery_Helpers::find_or_create_gallery_post($username, $server_id_val); + if (!$gallery_post) throw new Exception('Gallery not found.'); + + if (empty($_FILES['mc_images']) || !is_array($_FILES['mc_images']['name'])) { + wp_send_json_error(['message' => 'No files uploaded or invalid format.']); + } + + $files = $_FILES['mc_images']; + + foreach (array_keys($files['name']) as $i) { + if ($files['error'][$i] !== UPLOAD_ERR_OK) { + $errors[] = $files['name'][$i] . ': Upload error'; + continue; + } + + $file = [ + 'name' => $files['name'][$i], + 'type' => $files['type'][$i], + 'tmp_name' => $files['tmp_name'][$i], + 'error' => $files['error'][$i], + 'size' => $files['size'][$i] + ]; + + $allowed = ['image/jpeg','image/png','image/gif','image/webp']; + if (!in_array($file['type'], $allowed)) { + $errors[] = $file['name'] . ': Only images allowed'; + continue; + } + + $overrides = ['test_form' => false]; + $movefile = wp_handle_upload($file, $overrides); + + if (isset($movefile['error'])) { + $errors[] = $file['name'] . ': ' . $movefile['error']; + continue; + } + + $wp_filetype = wp_check_filetype(basename($movefile['file']), null); + $attachment = [ + 'guid' => $movefile['url'], + 'post_mime_type' => $wp_filetype['type'], + 'post_title' => sanitize_text_field($file['name']), + 'post_content' => '', + 'post_status' => 'inherit' + ]; + + $attach_id = wp_insert_attachment($attachment, $movefile['file']); + if (is_wp_error($attach_id)) { + $errors[] = $file['name'] . ': ' . $attach_id->get_error_message(); + continue; + } + + // View Counter initialisieren + add_post_meta($attach_id, 'mc_views', 0); + + $attach_data = wp_generate_attachment_metadata($attach_id, $movefile['file']); + + // Bildgröße anpassen + $resize_pct = intval(get_option(self::OPTION_RESIZE_PCT, 100)); + if ($resize_pct < 100 && $resize_pct > 0) { + $original_file = $movefile['file']; + $editor = wp_get_image_editor($original_file); + if (!is_wp_error($editor)) { + $size = $editor->get_size(); + $new_w = $size['width'] * ($resize_pct / 100); + $new_h = $size['height'] * ($resize_pct / 100); + $resized_path = image_make_intermediate_size($original_file, $new_w, $new_h, false); + if (!empty($resized_path)) { + $attach_data['sizes']['mc-optimized'] = $resized_path; + } + } + } + + wp_update_attachment_metadata($attach_id, $attach_data); + wp_update_post(['ID' => $attach_id, 'post_parent' => $gallery_post->ID]); + + // Album zuweisen + if ($album_id) { + update_post_meta($attach_id, 'mc_album_id', $album_id); + $count = get_post_meta($album_id, 'mc_image_count', true) ?: 0; + update_post_meta($album_id, 'mc_image_count', $count + 1); + } + + $uploaded[] = $file['name']; + } + + $response = [ + 'message' => count($uploaded) . ' image(s) successfully uploaded!', + 'uploaded' => $uploaded + ]; + + if (!empty($errors)) { + $response['errors'] = $errors; + } + + wp_send_json_success($response); + + } catch (Exception $e) { + wp_send_json_error(['message' => 'Error: ' . $e->getMessage()]); + } finally { + if ($temp_user_id) wp_set_current_user(0); + } + } + + public static function get_default_thumb_h() { + return intval(get_option(self::OPTION_THUMB_H, 200)); + } } \ No newline at end of file diff --git a/includes/class-mc-gallery-forum-bridge.php b/includes/class-mc-gallery-forum-bridge.php index 4ad0e73..96b9afd 100644 --- a/includes/class-mc-gallery-forum-bridge.php +++ b/includes/class-mc-gallery-forum-bridge.php @@ -295,8 +295,14 @@ class MC_Gallery_Forum_Bridge { wp_send_json_error( 'Dieser Minecraft-Name ist bereits mit einem anderen Forum-Konto verknüpft.' ); } + // Server-ID auflösen und als Integer-Post-ID speichern + $resolved_server = self::resolve_server_id( $server ); + if ( ! $resolved_server && ! empty( $server ) ) { + // Fallback: rohen Wert speichern wenn Auflösung fehlschlägt + $resolved_server = $server; + } self::set_mc_username( $user->id, $mc_user ); - self::set_mc_server( $user->id, $server ); + self::set_mc_server( $user->id, $resolved_server ); // Verifizierung: automatisch wenn gültiger Ingame-Token vorliegt $auto_verified = self::check_active_token_for( $mc_user ); self::set_verified( $user->id, $auto_verified ); @@ -376,19 +382,31 @@ class MC_Gallery_Forum_Bridge { ] ); } - $server_id = self::get_mc_server( $forum_user->id ) - ?: sanitize_text_field( $_POST['server_id'] ?? '' ); + // Server-ID aus Profil laden und als gültige Post-ID auflösen + $raw_server = self::get_mc_server( $forum_user->id ) + ?: sanitize_text_field( $_POST['server_id'] ?? '' ); + $server_id = self::resolve_server_id( $raw_server ); - if ( empty( $server_id ) ) { + // Kein Server gefunden: ersten verfügbaren nehmen + if ( ! $server_id ) { $servers = self::get_server_list(); if ( ! empty( $servers ) ) { $first = array_key_first( $servers ); if ( $first !== null ) { - $server_id = (string) $first; + $server_id = (int) $first; + // Für diesen User speichern damit es beim nächsten Mal direkt klappt + self::set_mc_server( $forum_user->id, $server_id ); } } } + if ( ! $server_id ) { + wp_send_json_error( [ + 'code' => 'no_server', + 'message' => 'Kein Server gefunden. Bitte einen Admin kontaktieren.', + ] ); + } + wp_send_json_success( [ 'mc_username' => $mc_user, 'server_id' => $server_id, @@ -762,10 +780,50 @@ class MC_Gallery_Forum_Bridge { return false; } - // Server-Liste aus Gallery-Config laden + // Server-Liste aus mc_server Custom Post Type laden (Post-ID => Titel) private static function get_server_list() { - $servers = get_option( 'mc_gallery_servers', [] ); - if ( ! empty( $servers ) && is_array( $servers ) ) return $servers; - return [ 'default' => 'Standard-Server' ]; + $posts = get_posts( [ + 'post_type' => 'mc_server', + 'posts_per_page' => -1, + 'post_status' => 'publish', + 'meta_key' => 'mc_server_active', + 'meta_value' => 1, + ] ); + $out = []; + foreach ( $posts as $p ) { + $out[ $p->ID ] = $p->post_title; + } + if ( ! empty( $out ) ) return $out; + // Fallback: alle mc_server Posts ohne Aktiv-Filter + $posts = get_posts( [ 'post_type' => 'mc_server', 'posts_per_page' => -1, 'post_status' => 'publish' ] ); + foreach ( $posts as $p ) { + $out[ $p->ID ] = $p->post_title; + } + return ! empty( $out ) ? $out : []; + } + + // Löst einen Server-String (Slug oder ID) zu einer gültigen Post-ID auf + private static function resolve_server_id( $raw_server_id ) { + if ( empty( $raw_server_id ) ) return 0; + + // Bereits eine gültige Post-ID? + if ( is_numeric( $raw_server_id ) && get_post_type( (int) $raw_server_id ) === 'mc_server' ) { + return (int) $raw_server_id; + } + + // Slug-Lookup + $post = get_page_by_path( $raw_server_id, OBJECT, 'mc_server' ); + if ( $post ) return $post->ID; + + // Titel-Lookup (case-insensitive) + global $wpdb; + $id = (int) $wpdb->get_var( $wpdb->prepare( + "SELECT ID FROM {$wpdb->posts} + WHERE post_type = 'mc_server' AND post_status = 'publish' + AND LOWER(post_title) = LOWER(%s) + LIMIT 1", + (string) $raw_server_id + ) ); + return $id ?: 0; } } \ No newline at end of file