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);
?>
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));
}
}