diff --git a/includes/class-mc-gallery-core.php b/includes/class-mc-gallery-core.php
new file mode 100644
index 0000000..6eb4760
--- /dev/null
+++ b/includes/class-mc-gallery-core.php
@@ -0,0 +1,706 @@
+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');
+ ?>
+
+ 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'; },
+ 'default' => true
+ ]);
+ register_setting('mc_gallery_pro_group', self::OPTION_MAX_UPLOADS, [
+ 'type' => 'integer',
+ 'sanitize_callback' => 'absint',
+ 'default' => 5
+ ]);
+ }
+
+ 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);
+ ?>
+
+
MC Gallery PRO Settings
+
+
+ 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'),
+ 'maxUploads' => intval(get_option(self::OPTION_MAX_UPLOADS, 5))
+ ]);
+ }
+
+ 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 = intval($params['server_id'] ?? 0);
+
+ if (!$token || !$username || !$server_id) {
+ return new WP_REST_Response(['success'=>false,'message'=>'Missing data'],400);
+ }
+
+ $tokens = MC_Gallery_Helpers::get_tokens();
+ if (!isset($tokens[$token]) || !$tokens[$token]['claimed'] || $tokens[$token]['claimed_by'] !== $username) {
+ return new WP_REST_Response(['success'=>false,'message'=>'Invalid session'],401);
+ }
+
+ $gallery = MC_Gallery_Helpers::find_or_create_gallery_post($username, $server_id);
+ 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]);
+ }
+
+ 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 = intval($_POST['mc_server_id'] ?? 0);
+ $album_name = sanitize_text_field($_POST['album_name'] ?? '');
+
+ if (!$token || !$username || !$server_id || !$album_name) {
+ wp_send_json_error(['message' => 'Missing data']);
+ }
+
+ $tokens = MC_Gallery_Helpers::get_tokens();
+ if (!isset($tokens[$token]) || !$tokens[$token]['claimed'] || $tokens[$token]['claimed_by'] !== $username) {
+ wp_send_json_error(['message' => 'Invalid session']);
+ }
+
+ if ($tokens[$token]['expires'] < time()) {
+ wp_send_json_error(['message' => 'Session expired']);
+ }
+
+ $gallery = MC_Gallery_Helpers::find_or_create_gallery_post($username, $server_id);
+ 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 = intval($_POST['mc_server_id'] ?? 0);
+ $album_id = intval($_POST['mc_album_id'] ?? 0);
+
+ if (!$token || !$username || !$server_id) {
+ wp_send_json_error(['message' => 'Token or data missing.']);
+ }
+
+ $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']);
+ }
+
+ 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);
+ 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-helpers.php b/includes/class-mc-gallery-helpers.php
new file mode 100644
index 0000000..63b200f
--- /dev/null
+++ b/includes/class-mc-gallery-helpers.php
@@ -0,0 +1,51 @@
+ 'mc_gallery',
+ 'posts_per_page' => 1,
+ 'meta_query' => [
+ ['key' => 'mc_player', 'value' => $player],
+ ['key' => 'mc_server', 'value' => $server_id]
+ ]
+ ];
+ $q = get_posts($args);
+ if (!empty($q)) return $q[0];
+
+ $id = wp_insert_post([
+ 'post_type' => 'mc_gallery',
+ 'post_title' => "Galerie $player (Server $server_id)",
+ 'post_status' => 'publish',
+ 'meta_input' => [
+ 'mc_player' => $player,
+ 'mc_server' => $server_id
+ ]
+ ]);
+ return get_post($id);
+ }
+
+ public static function error_log($msg) {
+ if (defined('WP_DEBUG') && WP_DEBUG) error_log("[mc-gallery-pro] " . $msg);
+ }
+
+ public static function rest_response_success($data = []) {
+ return new WP_REST_Response(['success' => true, 'data' => $data], 200);
+ }
+}
\ No newline at end of file
diff --git a/includes/class-mc-gallery-shortcodes.php b/includes/class-mc-gallery-shortcodes.php
new file mode 100644
index 0000000..884466a
--- /dev/null
+++ b/includes/class-mc-gallery-shortcodes.php
@@ -0,0 +1,892 @@
+ 0,
+ 'server_ids' => '',
+ 'thumb_h' => 0
+ ], $atts);
+
+ $thumb_h = intval($atts['thumb_h']) ?: MC_Gallery_Core::get_default_thumb_h();
+ $show_date = get_option(MC_Gallery_Core::OPTION_SHOW_DATE, true);
+
+ $server_ids_to_search = [];
+
+ // Server IDs sammeln
+ if (!empty($atts['server_ids'])) {
+ $raw_ids = explode(',', $atts['server_ids']);
+ foreach ($raw_ids as $id) {
+ $int_id = intval(trim($id));
+ if ($int_id > 0) $server_ids_to_search[] = $int_id;
+ }
+ } else if (!empty($atts['server_id'])) {
+ $server_ids_to_search[] = intval($atts['server_id']);
+ } else {
+ // Alle aktiven Server laden
+ $all_server_posts = get_posts([
+ 'post_type' => 'mc_server',
+ 'meta_key' => 'mc_server_active',
+ 'meta_value' => 1,
+ 'numberposts' => -1
+ ]);
+ foreach ($all_server_posts as $s) {
+ $server_ids_to_search[] = $s->ID;
+ }
+ }
+
+ if (empty($server_ids_to_search)) {
+ return '🚫 Keine aktiven Server gefunden.
';
+ }
+
+ // Parameter auslesen
+ $q_player = isset($_GET['player']) ? sanitize_text_field($_GET['player']) : '';
+ $q_server = isset($_GET['server']) ? intval($_GET['server']) : 0;
+ $q_album = isset($_GET['album']) ? intval($_GET['album']) : 0;
+
+ $current_url = remove_query_arg(['player', 'server', 'album']);
+
+ // ==============================
+ // 1. FALL: Album-Ansicht (wenn ?album=ID)
+ // ==============================
+ if ($q_album) {
+ return self::shortcode_album_view(['album_id' => $q_album]);
+ }
+
+ // ==============================
+ // 2. FALL: Spieler-Spezifische Ansicht
+ // ==============================
+ if ($q_player) {
+
+ // Header erstellen
+ $out = '';
+ $out .= '';
+
+ // Alle Galerien für diesen Spieler laden
+ $all_galleries = get_posts([
+ 'post_type' => 'mc_gallery',
+ 'posts_per_page' => -1,
+ 'meta_query' => [
+ [
+ 'key' => 'mc_server',
+ 'value' => $server_ids_to_search,
+ 'compare' => 'IN'
+ ]
+ ]
+ ]);
+
+ // Filter nach Spielername
+ $player_galleries = [];
+ $player_gallery_ids = [];
+ foreach ($all_galleries as $gal) {
+ $p = get_post_meta($gal->ID, 'mc_player', true);
+ if ($p === $q_player) {
+ $player_galleries[] = $gal;
+ $player_gallery_ids[] = $gal->ID;
+ }
+ }
+
+ // ALBEN dieses Spielers laden
+ $albums = [];
+ if (!empty($player_gallery_ids)) {
+ $albums = get_posts([
+ 'post_type' => 'mc_album',
+ 'posts_per_page' => -1,
+ 'meta_key' => 'mc_gallery_id',
+ 'value' => $player_gallery_ids,
+ 'compare' => 'IN',
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+ }
+
+ // --- HTML Alben ---
+ if (!empty($albums)) {
+ $out .= '
';
+ $out .= '
📁 Alben ('.count($albums).')
';
+ $out .= '
';
+
+ foreach ($albums as $album) {
+ $album_images = get_posts([
+ 'post_type' => 'attachment',
+ 'posts_per_page' => 1,
+ 'post_mime_type' => 'image',
+ 'post_parent' => get_post_meta($album->ID, 'mc_gallery_id', true),
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+
+ $cover_url = '';
+ if (!empty($album_images)) {
+ $cover_array = wp_get_attachment_image_src($album_images[0]->ID, 'medium');
+ $cover_url = $cover_array ? $cover_array[0] : '';
+ }
+
+ $album_count = get_post_meta($album->ID, 'mc_image_count', true) ?: 0;
+ $album_link = add_query_arg(['album' => $album->ID], $current_url);
+
+ $out .= '
';
+ if ($cover_url) {
+ $out .= '';
+ } else {
+ $out .= '📁
';
+ }
+ $out .= '';
+ $out .= '
'.esc_html($album->post_title).'
';
+ $out .= ''.$album_count.' Images';
+ $out .= '';
+ $out .= '';
+ }
+
+ $out .= '
';
+ $out .= '
';
+ }
+
+ // Alle Bilder des Spielers laden
+ $all_images = get_posts([
+ 'post_type' => 'attachment',
+ 'post_parent' => $player_gallery_ids,
+ 'posts_per_page' => -1,
+ 'post_mime_type' => 'image',
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+
+ // BILDER FILTER: Nur Bilder, die in einem Album sind
+ $images_linked_to_albums = [];
+ foreach ($all_images as $img) {
+ $album_id = get_post_meta($img->ID, 'mc_album_id', true);
+ // Prüfen ob Album ID existiert und nicht 0 ist
+ if (!empty($album_id) && $album_id > 0) {
+ $images_linked_to_albums[] = $img;
+ }
+ }
+
+ // --- HTML Bilder (NUR VERKNÜPFTE) ---
+ if (!empty($images_linked_to_albums)) {
+ $out .= '
';
+ $out .= '
🖼️ Alle Bilder ('.count($images_linked_to_albums).')
';
+ $out .= '
';
+
+ foreach ($images_linked_to_albums as $img) {
+ $full = wp_get_attachment_url($img->ID);
+ $upload_date = date_i18n('d.m.Y', strtotime($img->post_date));
+
+ $album_id = get_post_meta($img->ID, 'mc_album_id', true);
+ $album_name = '';
+ if ($album_id) {
+ $album_post = get_post($album_id);
+ if ($album_post) {
+ $album_name = $album_post->post_title;
+ }
+ }
+
+ $metadata = wp_get_attachment_metadata($img->ID);
+ $width = isset($metadata['width']) ? $metadata['width'] : 0;
+ $height = isset($metadata['height']) ? $metadata['height'] : 0;
+ $aspect_ratio = ($width && $height) ? ($width / $height) : 1;
+
+ $resize_pct = intval(get_option(MC_Gallery_Core::OPTION_RESIZE_PCT, 100));
+ if ($resize_pct < 100 && isset($metadata['sizes']['mc-optimized'])) {
+ $upload_dir = wp_upload_dir();
+ $file_path = dirname($metadata['file']) . '/' . $metadata['sizes']['mc-optimized']['file'];
+ $thumb = $upload_dir['baseurl'] . '/' . $file_path;
+ } else {
+ $thumb_array = wp_get_attachment_image_src($img->ID, 'medium');
+ $thumb = $thumb_array ? $thumb_array[0] : $full;
+ }
+
+ $data_date_attr = $show_date ? 'data-date="'.esc_attr($upload_date).'"' : '';
+ $views = get_post_meta($img->ID, 'mc_views', true) ?: 0;
+
+ $out .= '
';
+ $out .= '';
+ $out .= '
👁️ '.$views.'
';
+ if ($show_date) {
+ $out .= '
'.$upload_date.'
';
+ }
+ $out .= '
.')
';
+ $out .= '
';
+ $out .= '
';
+ $out .= '
'.esc_html($q_player).'
';
+ if ($album_name) {
+ $out .= '
📁 '.esc_html($album_name).'
';
+ }
+ $out .= '
';
+ $out .= '
';
+ $out .= '
';
+ $out .= '';
+ }
+
+ $out .= '
';
+ $out .= '
';
+ }
+
+ $out .= '
';
+ return $out;
+ }
+
+ // ==============================
+ // 3. FALL: Haupt-Übersicht (Kein Spieler gewählt)
+ // ==============================
+
+ // Alle mc_gallery Posts laden
+ $galleries = get_posts([
+ 'post_type' => 'mc_gallery',
+ 'posts_per_page' => -1,
+ 'meta_query' => [
+ [
+ 'key' => 'mc_server',
+ 'value' => $server_ids_to_search,
+ 'compare' => 'IN'
+ ]
+ ],
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+
+ if (empty($galleries)) {
+ return '🎮 No galleries on selected servers yet.
';
+ }
+
+ $all_images = [];
+ $players_list = [];
+ $player_counts = [];
+
+ foreach ($galleries as $gallery) {
+ $player = get_post_meta($gallery->ID, 'mc_player', true);
+
+ if (!in_array($player, $players_list)) {
+ $players_list[] = $player;
+ $player_counts[$player] = 0;
+ }
+
+ $images = get_posts([
+ 'post_type' => 'attachment',
+ 'post_parent' => $gallery->ID,
+ 'posts_per_page' => -1,
+ 'post_mime_type' => 'image',
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+
+ foreach ($images as $img) {
+ $img->mc_player_name = $player;
+ $img->mc_upload_date = $img->post_date;
+ $img->mc_gallery_id = $gallery->ID;
+ $all_images[] = $img;
+ $player_counts[$player]++;
+ }
+ }
+
+ usort($all_images, function($a, $b) {
+ return strtotime($b->mc_upload_date) - strtotime($a->mc_upload_date);
+ });
+
+ $out = '';
+
+ // Filter Bar
+ if (!empty($players_list)) {
+ $active_all = empty($q_player) ? 'mc-tag-active' : '';
+
+ $out .= '
';
+ $out .= '';
+ $out .= '
';
+ }
+
+ // Bilder Grid (Gemischt - Alle Bilder, auch unverknüpfte)
+ if (!empty($all_images)) {
+ $out .= '
';
+
+ foreach ($all_images as $img) {
+ $full = wp_get_attachment_url($img->ID);
+ $player_name = esc_html($img->mc_player_name);
+ $upload_date = date_i18n('d.m.Y', strtotime($img->mc_upload_date));
+
+ $album_id = get_post_meta($img->ID, 'mc_album_id', true);
+ $album_name = '';
+ if ($album_id) {
+ $album_post = get_post($album_id);
+ if ($album_post) {
+ $album_name = $album_post->post_title;
+ }
+ }
+
+ $metadata = wp_get_attachment_metadata($img->ID);
+ $width = isset($metadata['width']) ? $metadata['width'] : 0;
+ $height = isset($metadata['height']) ? $metadata['height'] : 0;
+ $aspect_ratio = ($width && $height) ? ($width / $height) : 1;
+
+ $resize_pct = intval(get_option(MC_Gallery_Core::OPTION_RESIZE_PCT, 100));
+
+ if ($resize_pct < 100 && isset($metadata['sizes']['mc-optimized'])) {
+ $upload_dir = wp_upload_dir();
+ $file_path = dirname($metadata['file']) . '/' . $metadata['sizes']['mc-optimized']['file'];
+ $thumb = $upload_dir['baseurl'] . '/' . $file_path;
+ } else {
+ $thumb_array = wp_get_attachment_image_src($img->ID, 'medium');
+ $thumb = $thumb_array ? $thumb_array[0] : $full;
+ }
+
+ $data_date_attr = $show_date ? 'data-date="'.esc_attr($upload_date).'"' : '';
+ $views = get_post_meta($img->ID, 'mc_views', true) ?: 0;
+
+ $out .= '
';
+ $out .= '';
+ $out .= '
👁️ '.$views.'
';
+ if ($show_date) {
+ $out .= '
'.$upload_date.'
';
+ }
+ $out .= '
.')
';
+ $out .= '
';
+ $out .= '
';
+ $out .= '
'.$player_name.'
';
+ if ($album_name) {
+ $out .= '
📁 '.esc_html($album_name).'
';
+ }
+ $out .= '
';
+ $out .= '
';
+ $out .= '
';
+ $out .= '';
+ }
+
+ $out .= '
';
+ } else {
+ $out .= '
🔍 Keine Bilder gefunden für den ausgewählten Filter.
';
+ }
+
+ $out .= '
';
+ return $out;
+ }
+
+ public static function shortcode_player($atts) {
+ $atts = shortcode_atts([
+ 'player' => '',
+ 'server_id' => 0,
+ 'thumb_h' => 0
+ ], $atts);
+
+ $player = sanitize_text_field($atts['player']);
+ $server_id = intval($atts['server_id']);
+ $thumb_h = intval($atts['thumb_h']) ?: MC_Gallery_Core::get_default_thumb_h();
+ $show_date = get_option(MC_Gallery_Core::OPTION_SHOW_DATE, true);
+
+ if (!$player || !$server_id) {
+ return '❌ Invalid request.
';
+ }
+
+ $gallery = MC_Gallery_Helpers::find_or_create_gallery_post($player, $server_id);
+ if (!$gallery) {
+ return '📁 Gallery not found.
';
+ }
+
+ $images = get_posts([
+ 'post_type' => 'attachment',
+ 'post_parent' => $gallery->ID,
+ 'posts_per_page' => -1,
+ 'post_mime_type' => 'image',
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+
+ $albums = get_posts([
+ 'post_type' => 'mc_album',
+ 'posts_per_page' => -1,
+ 'meta_key' => 'mc_gallery_id',
+ 'meta_value' => $gallery->ID,
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+
+ if (empty($images) && empty($albums)) {
+ return '
+
+ 📷 '.esc_html($player).' has not uploaded any images yet.
+
+
';
+ }
+
+ $current_url = remove_query_arg(['player', 'server', 'album']);
+
+ $out = '';
+ $out .= '';
+
+ if (!empty($albums)) {
+ $out .= '
';
+ $out .= '
📁 Albums ('.count($albums).')
';
+ $out .= '
';
+
+ foreach ($albums as $album) {
+ $album_images = get_posts([
+ 'post_type' => 'attachment',
+ 'posts_per_page' => 1,
+ 'post_mime_type' => 'image',
+ 'post_parent' => get_post_meta($album->ID, 'mc_gallery_id', true),
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+
+ $cover_url = '';
+ if (!empty($album_images)) {
+ $cover_array = wp_get_attachment_image_src($album_images[0]->ID, 'medium');
+ $cover_url = $cover_array ? $cover_array[0] : '';
+ }
+
+ $album_count = get_post_meta($album->ID, 'mc_image_count', true) ?: 0;
+ $album_link = add_query_arg(['album' => $album->ID], $current_url);
+
+ $out .= '
';
+ if ($cover_url) {
+ $out .= '';
+ } else {
+ $out .= '📁
';
+ }
+ $out .= '';
+ $out .= '
'.esc_html($album->post_title).'
';
+ $out .= ''.$album_count.' Images';
+ $out .= '';
+ $out .= '';
+ }
+
+ $out .= '
';
+ $out .= '
';
+ }
+
+ if (!empty($images)) {
+ $out .= '
';
+ $out .= '
🖼️ Alle Bilder ('.count($images).')
';
+ $out .= '
';
+
+ foreach ($images as $img) {
+ $full = wp_get_attachment_url($img->ID);
+ $upload_date = date_i18n('d.m.Y', strtotime($img->post_date));
+
+ $metadata = wp_get_attachment_metadata($img->ID);
+ $width = isset($metadata['width']) ? $metadata['width'] : 0;
+ $height = isset($metadata['height']) ? $metadata['height'] : 0;
+ $aspect_ratio = ($width && $height) ? ($width / $height) : 1;
+
+ $resize_pct = intval(get_option(MC_Gallery_Core::OPTION_RESIZE_PCT, 100));
+ if ($resize_pct < 100 && isset($metadata['sizes']['mc-optimized'])) {
+ $upload_dir = wp_upload_dir();
+ $file_path = dirname($metadata['file']) . '/' . $metadata['sizes']['mc-optimized']['file'];
+ $thumb = $upload_dir['baseurl'] . '/' . $file_path;
+ } else {
+ $thumb_array = wp_get_attachment_image_src($img->ID, 'medium');
+ $thumb = $thumb_array ? $thumb_array[0] : $full;
+ }
+
+ $data_date_attr = $show_date ? 'data-date="'.esc_attr($upload_date).'"' : '';
+ $views = get_post_meta($img->ID, 'mc_views', true) ?: 0;
+
+ $out .= '
';
+ $out .= '';
+ $out .= '
👁️ '.$views.'
';
+ if ($show_date) {
+ $out .= '
'.$upload_date.'
';
+ }
+ $out .= '
.')
';
+ $out .= '
';
+ $out .= '
';
+ $out .= '
'.esc_html($player).'
';
+ $out .= '
';
+ $out .= '
';
+ $out .= '
';
+ $out .= '';
+ }
+
+ $out .= '
';
+ $out .= '
';
+ }
+
+ $out .= '
';
+
+ return $out;
+ }
+
+ public static function shortcode_all_albums_overview($atts) {
+ $show_date = get_option(MC_Gallery_Core::OPTION_SHOW_DATE, true);
+ $current_url = remove_query_arg(['player', 'server', 'album']);
+
+ $albums = get_posts([
+ 'post_type' => 'mc_album',
+ 'posts_per_page' => -1,
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+
+ if (empty($albums)) {
+ return '📁 Es wurden noch keine Alben erstellt.
';
+ }
+
+ $out = '';
+ $out .= '';
+
+ $out .= '
';
+
+ foreach ($albums as $album) {
+ $album_count = get_post_meta($album->ID, 'mc_image_count', true) ?: 0;
+
+ $cover_images = get_posts([
+ 'post_type' => 'attachment',
+ 'posts_per_page' => 1,
+ 'post_mime_type' => 'image',
+ 'meta_key' => 'mc_album_id',
+ 'meta_value' => $album->ID,
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+
+ $cover_url = '';
+ if (!empty($cover_images)) {
+ $cover_array = wp_get_attachment_image_src($cover_images[0]->ID, 'medium');
+ $cover_url = $cover_array ? $cover_array[0] : '';
+ }
+
+ $album_link = add_query_arg(['album' => $album->ID], $current_url);
+
+ $gallery_id = get_post_meta($album->ID, 'mc_gallery_id', true);
+ $player_name = '';
+ if ($gallery_id) {
+ $player_name = get_post_meta($gallery_id, 'mc_player', true);
+ }
+
+ $out .= '
';
+ if ($cover_url) {
+ $out .= '';
+ } else {
+ $out .= '📁
';
+ }
+ $out .= '';
+ $out .= '
'.esc_html($album->post_title).'
';
+ $out .= ''.$album_count.' Images';
+ if ($player_name) {
+ $out .= 'by '.esc_html($player_name).'';
+ }
+ $out .= '';
+ $out .= '';
+ }
+
+ $out .= '
';
+ $out .= '
';
+ return $out;
+ }
+
+ public static function shortcode_album_view($atts) {
+ $atts = shortcode_atts([
+ 'album_id' => 0,
+ 'server_id' => 0
+ ], $atts);
+
+ $album_id = intval($atts['album_id']);
+ $album = get_post($album_id);
+ $show_date = get_option(MC_Gallery_Core::OPTION_SHOW_DATE, true);
+
+ if (!$album || $album->post_type !== 'mc_album') {
+ return '❌ Album not found.
';
+ }
+
+ $images = get_posts([
+ 'post_type' => 'attachment',
+ 'posts_per_page' => -1,
+ 'post_mime_type' => 'image',
+ 'meta_key' => 'mc_album_id',
+ 'meta_value' => $album_id,
+ 'orderby' => 'date',
+ 'order' => 'DESC'
+ ]);
+
+ $gallery_id = get_post_meta($album_id, 'mc_gallery_id', true);
+ $gallery = get_post($gallery_id);
+ $player = $gallery ? get_post_meta($gallery_id, 'mc_player', true) : '';
+
+ $current_url = remove_query_arg(['album']);
+
+ $out = '';
+ $out .= '';
+
+ if (!empty($images)) {
+ $out .= '
';
+
+ foreach ($images as $img) {
+ $full = wp_get_attachment_url($img->ID);
+ $upload_date = date_i18n('d.m.Y', strtotime($img->post_date));
+
+ $metadata = wp_get_attachment_metadata($img->ID);
+ $width = isset($metadata['width']) ? $metadata['width'] : 0;
+ $height = isset($metadata['height']) ? $metadata['height'] : 0;
+ $aspect_ratio = ($width && $height) ? ($width / $height) : 1;
+
+ $thumb_array = wp_get_attachment_image_src($img->ID, 'medium');
+ $thumb = $thumb_array ? $thumb_array[0] : $full;
+
+ $data_date_attr = $show_date ? 'data-date="'.esc_attr($upload_date).'"' : '';
+ $views = get_post_meta($img->ID, 'mc_views', true) ?: 0;
+
+ $out .= '
';
+ $out .= '';
+ $out .= '
👁️ '.$views.'
';
+ if ($show_date) {
+ $out .= '
'.$upload_date.'
';
+ }
+ $out .= '
.')
';
+ $out .= '
';
+ $out .= '';
+ }
+
+ $out .= '
';
+ } else {
+ $out .= '
📷 This album contains no images yet.
';
+ }
+
+ $out .= '
';
+ return $out;
+ }
+
+ public static function shortcode_upload($atts) {
+ $atts = shortcode_atts(['show' => '0'], $atts);
+ $show_default = ($atts['show'] === '1');
+
+ ob_start();
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 🎮 Gehe auf den Server und führe den folgenden Befehl aus:
+
+
+
+ Waiting...
+
+
+
+
+ 💡 Gib im Chat ein: /verify [dein-token]
+
+
+
+
+
+
+
+
+
+
+ ✓ Session aktiv
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Keine Bilder gewählt
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+