957 lines
45 KiB
PHP
957 lines
45 KiB
PHP
<?php
|
|
if (!defined('ABSPATH')) exit;
|
|
|
|
|
|
class MC_Gallery_Core {
|
|
|
|
const OPTION_FORUM_LOGIN = 'mc_gallery_forum_login';
|
|
const OPTION_VOTING = 'mc_gallery_voting_enabled';
|
|
private static $forum_plugin_active = false;
|
|
|
|
const OPTION_THUMB_H = 'mc_gallery_thumb_h';
|
|
const OPTION_RESIZE_PCT = 'mc_gallery_resize_pct';
|
|
const OPTION_SHOW_DATE = 'mc_gallery_show_date';
|
|
const OPTION_MAX_UPLOADS = 'mc_gallery_max_uploads';
|
|
const SESSION_TTL = 3600; // 1 Stunde Session
|
|
|
|
public static function init() {
|
|
// Prüfen, ob das Forum-Plugin aktiv ist
|
|
self::$forum_plugin_active = class_exists('WBF_Auth');
|
|
add_action('init', [__CLASS__, 'register_post_types']);
|
|
add_action('rest_api_init', [__CLASS__, 'register_rest_routes']);
|
|
|
|
add_action('wp_ajax_mc_gallery_upload', [__CLASS__, 'handle_upload']);
|
|
add_action('wp_ajax_nopriv_mc_gallery_upload', [__CLASS__, 'handle_upload']);
|
|
|
|
add_action('wp_ajax_mc_gallery_increment_view', [__CLASS__, 'handle_increment_view']);
|
|
add_action('wp_ajax_nopriv_mc_gallery_increment_view', [__CLASS__, 'handle_increment_view']);
|
|
|
|
add_action('wp_ajax_mc_gallery_create_album', [__CLASS__, 'handle_create_album']);
|
|
add_action('wp_ajax_nopriv_mc_gallery_create_album', [__CLASS__, 'handle_create_album']);
|
|
|
|
add_action('wp_ajax_mc_gallery_vote', [__CLASS__, 'handle_vote']);
|
|
add_action('wp_ajax_nopriv_mc_gallery_vote', [__CLASS__, 'handle_vote']);
|
|
|
|
add_action('wp_enqueue_scripts', [__CLASS__, 'enqueue_assets']);
|
|
|
|
// Meta Boxen & UI
|
|
add_action('add_meta_boxes', [__CLASS__, 'add_meta_boxes']);
|
|
add_action('admin_head', [__CLASS__, 'admin_head_styles']);
|
|
|
|
if (is_admin()) {
|
|
add_action('admin_menu', [__CLASS__, 'admin_menu']);
|
|
add_action('admin_init', [__CLASS__, 'register_settings']);
|
|
add_action('save_post', [__CLASS__, 'save_server_meta'], 10, 2);
|
|
|
|
// Gutenberg für mc_server deaktivieren
|
|
add_filter('use_block_editor_for_post_type_mc_server', '__return_false');
|
|
add_filter('wp_rest_mc_server', '__return_false');
|
|
}
|
|
}
|
|
|
|
public static function admin_head_styles() {
|
|
$screen = get_current_screen();
|
|
if (!$screen || $screen->post_type !== 'mc_server') return;
|
|
?>
|
|
<style type="text/css">
|
|
/* Unnötige Boxen ausblenden */
|
|
#slugdiv, #postexcerpt, #postcustom, #commentstatusdiv {
|
|
display: none !important;
|
|
}
|
|
/* Readonly Styling */
|
|
input[readonly] {
|
|
background-color: #f0f0f0;
|
|
cursor: not-allowed;
|
|
border-color: #ccc;
|
|
}
|
|
</style>
|
|
<?php
|
|
}
|
|
|
|
public static function add_meta_boxes() {
|
|
add_meta_box(
|
|
'mc_server_config',
|
|
'Server Konfiguration',
|
|
[__CLASS__, 'render_server_meta_box'],
|
|
'mc_server',
|
|
'normal',
|
|
'high'
|
|
);
|
|
}
|
|
|
|
public static function render_server_meta_box($post) {
|
|
// Werte laden
|
|
// $host = get_post_meta($post->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');
|
|
?>
|
|
<table class="form-table">
|
|
<tr>
|
|
<th><label for="mc_server_active">Status</label></th>
|
|
<td>
|
|
<label><input type="checkbox" name="mc_server_active" id="mc_server_active" value="1" <?php checked($active); ?> /> Aktiv</label>
|
|
<p class="description">Aktivieren, damit Spieler diesen Server sehen und Token anfragen können.</p>
|
|
</td>
|
|
</tr>
|
|
<!-- HOST FELD ENTFERNT -->
|
|
<tr>
|
|
<th><label>Shared Secret</label></th>
|
|
<td>
|
|
<?php if ($has_secret): ?>
|
|
<input type="text" readonly name="mc_server_secret_readonly" value="<?php echo esc_attr($secret); ?>" style="width: 100%; color: #333;" />
|
|
<input type="hidden" name="mc_server_secret" value="<?php echo esc_attr($secret); ?>" />
|
|
<p class="description">✓ Automatisch generiert. Trage diesen Key in deine Java <code>config.yml</code> ein.</p>
|
|
<?php else: ?>
|
|
<div style="padding: 10px; background: #eef; border-left: 4px solid #2c6eaf;">
|
|
<strong>Wird automatisch generiert...</strong>
|
|
<p style="margin: 5px 0 0 0;">Bitte klicke auf "Veröffentlichen". Nach dem Speichern erscheint hier dein Secret und die Server ID.</p>
|
|
</div>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Server ID (WP)</th>
|
|
<td>
|
|
<strong><?php echo $id > 0 ? $id : '(Wird zugewiesen)'; ?></strong>
|
|
<p class="description">Diese Nummer ist deine <code>server_id</code>. Trage diese Zahl in deine Java Config ein.</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<?php
|
|
}
|
|
|
|
public static function save_server_meta($post_id) {
|
|
// Prüfen ob es sich um 'mc_server' handelt
|
|
if (get_post_type($post_id) !== 'mc_server') return;
|
|
|
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
|
|
|
|
// Sicherheit
|
|
if (!isset($_POST['mc_server_nonce']) || !wp_verify_nonce($_POST['mc_server_nonce'], 'mc_server_nonce')) {
|
|
return;
|
|
}
|
|
|
|
if (!current_user_can('edit_post', $post_id)) {
|
|
return;
|
|
}
|
|
|
|
// HOST SPEICHERUNG ENTFERNT
|
|
|
|
// Active Status speichern
|
|
$active = isset($_POST['mc_server_active']) ? 1 : 0;
|
|
update_post_meta($post_id, 'mc_server_active', $active);
|
|
|
|
// Secret: Auto-Generieren wenn leer
|
|
$current_secret = get_post_meta($post_id, 'mc_server_secret', true);
|
|
|
|
// Hole neues Secret aus Input (wenn das Meta Box angezeigt wurde)
|
|
$input_secret = isset($_POST['mc_server_secret']) ? sanitize_text_field($_POST['mc_server_secret']) : '';
|
|
|
|
$final_secret = '';
|
|
|
|
if (empty($current_secret)) {
|
|
// NEUER SERVER -> 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;
|
|
}
|
|
}
|
|
}
|
|
?>
|
|
<div class="wrap">
|
|
<h1>MC Gallery PRO Settings</h1>
|
|
<form method="post" action="options.php">
|
|
<?php settings_fields('mc_gallery_pro_group'); ?>
|
|
<table class="form-table">
|
|
<tr>
|
|
<th scope="row">Thumbnail Height (px)</th>
|
|
<td><input type="number" name="<?php echo esc_attr(self::OPTION_THUMB_H); ?>" value="<?php echo esc_attr($thumb_h); ?>" min="100" max="600" /></td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">Image Resize % (Upload)</th>
|
|
<td>
|
|
<input type="number" name="<?php echo esc_attr(self::OPTION_RESIZE_PCT); ?>" value="<?php echo esc_attr($resize_pct); ?>" min="10" max="100" />
|
|
<p class="description">Default is 100% (Original). Values like 50 or 70 save space. Aspect ratio is kept.</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">Show Date</th>
|
|
<td>
|
|
<label>
|
|
<input type="checkbox" name="<?php echo esc_attr(self::OPTION_SHOW_DATE); ?>" value="1" <?php checked($show_date, true); ?> />
|
|
Show upload date in gallery and lightbox
|
|
</label>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">Max. Images per Upload</th>
|
|
<td>
|
|
<input type="number" name="<?php echo esc_attr(self::OPTION_MAX_UPLOADS); ?>" value="<?php echo esc_attr($max_uploads); ?>" min="1" max="50" />
|
|
<p class="description">How many images can a user upload at once? (Default: 5)</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">
|
|
Forum-Login für Upload-Verifizierung
|
|
<br><span style="font-weight:400;color:#646970;font-size:12px;">Benötigt: WP Business Forum</span>
|
|
</th>
|
|
<td>
|
|
<?php if ( $forum_plugin_active ) : ?>
|
|
|
|
<?php /* ── Plugin aktiv & bereit ── */ ?>
|
|
<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px;">
|
|
<span style="display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:20px;background:#edfaef;border:1px solid #c3e6cb;color:#1a7431;font-size:12px;font-weight:600;">
|
|
<span style="width:7px;height:7px;border-radius:50%;background:#22c55e;display:inline-block;"></span>
|
|
WP Business Forum aktiv
|
|
</span>
|
|
</div>
|
|
<label>
|
|
<input type="checkbox" name="<?php echo esc_attr(self::OPTION_FORUM_LOGIN); ?>" value="1" <?php checked($forum_login, '1'); ?> />
|
|
Forum-Login für Upload-Verifizierung erlauben
|
|
</label>
|
|
<p class="description" style="margin-top:6px;">
|
|
Wenn aktiviert, können sich Nutzer die ihren Minecraft-Account im Forum-Profil verknüpft haben, direkt ohne Ingame-Token hochladen.<br>
|
|
<strong>Der Shortcode:</strong> <code>[mc_gallery_combined]</code> <strong>ermöglicht eine kombinierte Verifizierung für Token und Forum.</strong>
|
|
</p>
|
|
|
|
<?php elseif ( $forum_plugin_installed ) : ?>
|
|
|
|
<?php /* ── Plugin installiert aber nicht aktiviert ── */ ?>
|
|
<div style="padding:12px 14px;background:#fff8e6;border:1px solid #f0c040;border-left:4px solid #f0c040;border-radius:0 6px 6px 0;margin-bottom:12px;">
|
|
<strong style="color:#7a5400;">⚠ WP Business Forum ist installiert, aber nicht aktiviert.</strong><br>
|
|
<span style="color:#7a5400;font-size:13px;">Aktiviere das Plugin unter <a href="<?php echo esc_url(admin_url('plugins.php')); ?>" style="color:#7a5400;text-decoration:underline;">Plugins → Installierte Plugins</a>, um diese Funktion zu nutzen.</span>
|
|
</div>
|
|
<label style="opacity:.5;pointer-events:none;">
|
|
<input type="checkbox" disabled />
|
|
Forum-Login für Upload-Verifizierung erlauben
|
|
</label>
|
|
|
|
<?php else : ?>
|
|
|
|
<?php /* ── Plugin nicht vorhanden ── */ ?>
|
|
<div style="padding:12px 14px;background:#fef2f2;border:1px solid #fca5a5;border-left:4px solid #ef4444;border-radius:0 6px 6px 0;margin-bottom:12px;">
|
|
<strong style="color:#991b1b;">✗ WP Business Forum ist nicht installiert.</strong><br>
|
|
<span style="color:#991b1b;font-size:13px;">
|
|
Dieses Feature benötigt das Plugin <em>WP Business Forum</em> von M_Viper.<br>
|
|
<a href="https://git.viper.ipv64.net/M_Viper/WP-Business-Forum/releases" target="_blank" rel="noopener" style="color:#b91c1c;font-weight:600;text-decoration:underline;">
|
|
↓ Jetzt herunterladen (Gitea)
|
|
</a>
|
|
·
|
|
<a href="<?php echo esc_url(admin_url('plugin-install.php')); ?>" style="color:#b91c1c;text-decoration:underline;">
|
|
Plugins → Neu hinzufügen
|
|
</a>
|
|
</span>
|
|
</div>
|
|
<label style="opacity:.5;pointer-events:none;">
|
|
<input type="checkbox" disabled />
|
|
Forum-Login für Upload-Verifizierung erlauben
|
|
</label>
|
|
<p class="description" style="margin-top:6px;color:#888;">
|
|
Nach der Installation und Aktivierung von WP Business Forum wird diese Option freigeschaltet.
|
|
</p>
|
|
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th scope="row">Abstimmung (Daumen hoch/runter)</th>
|
|
<td>
|
|
<label>
|
|
<input type="checkbox" name="<?php echo esc_attr(self::OPTION_VOTING); ?>" value="1" <?php checked(get_option(self::OPTION_VOTING, true), true); ?> />
|
|
Abstimmung auf Bilder aktivieren
|
|
</label>
|
|
<p class="description" style="margin-top:6px;">
|
|
Besucher können Bilder mit 👍 oder 👎 bewerten. Jeder kann abstimmen (kein Login nötig).<br>
|
|
Shortcode für die Bestenliste: <code>[mc_gallery_vote]</code>
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<?php submit_button('Änderungen speichern'); ?>
|
|
</form>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
public static function get_image_url($attach_id, $fallback_size = 'medium') {
|
|
$resize_pct = intval(get_option(self::OPTION_RESIZE_PCT, 100));
|
|
if ($resize_pct < 100) {
|
|
$src = wp_get_attachment_image_src($attach_id, 'mc-optimized');
|
|
if ($src && isset($src[0])) return $src[0];
|
|
}
|
|
$src = wp_get_attachment_image_src($attach_id, $fallback_size);
|
|
return ($src && isset($src[0])) ? $src[0] : '';
|
|
}
|
|
|
|
public static function enqueue_assets() {
|
|
$js_version = time(); // Zeitstempel für Cache-Busting
|
|
wp_register_style('mc-gallery-pro-css', MCGALLERY_PRO_URL . 'assets/css/gallery-pro.css', [], MCGALLERY_PRO_VERSION);
|
|
wp_register_script('mc-gallery-pro-js', MCGALLERY_PRO_URL . 'assets/js/gallery-pro.js?v=' . $js_version, ['jquery'], null, true);
|
|
wp_enqueue_style('mc-gallery-pro-css');
|
|
wp_enqueue_script('mc-gallery-pro-js');
|
|
// Forum-Verified-Status für JS ermitteln
|
|
$forum_verified_data = false;
|
|
if ( class_exists('WBF_Auth') && class_exists('MC_Gallery_Forum_Bridge') ) {
|
|
$forum_user = WBF_Auth::get_current_user();
|
|
if ( $forum_user ) {
|
|
$mc_user = MC_Gallery_Forum_Bridge::get_mc_username( $forum_user->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'] ?? '';
|
|
}
|
|
$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));
|
|
}
|
|
}
|