From a2f3260854b805c29887b0c7ec2c6de53faaaba4 Mon Sep 17 00:00:00 2001
From: M_Viper
Date: Sun, 15 Feb 2026 10:00:44 +0000
Subject: [PATCH] wp-ingame-shop/wp-ingame-shop.php aktualisiert
---
wp-ingame-shop/wp-ingame-shop.php | 3746 +++++++++++++++++------------
1 file changed, 2155 insertions(+), 1591 deletions(-)
diff --git a/wp-ingame-shop/wp-ingame-shop.php b/wp-ingame-shop/wp-ingame-shop.php
index 915f41a..e809d36 100644
--- a/wp-ingame-shop/wp-ingame-shop.php
+++ b/wp-ingame-shop/wp-ingame-shop.php
@@ -1,153 +1,38 @@
10]
- );
-
- if ( ! is_wp_error($response) && 200 === wp_remote_retrieve_response_code($response) ) {
- $body = wp_remote_retrieve_body($response);
- $data = json_decode($body, true);
-
- if ( $data && isset($data['tag_name']) ) {
- $tag = ltrim( $data['tag_name'], 'vV' );
-
- $release_info = [
- 'version' => $tag,
- 'download_url' => $data['zipball_url'] ?? '',
- 'notes' => $data['body'] ?? '',
- 'published_at' => $data['published_at'] ?? '',
- ];
-
- set_transient( $transient_key, $release_info, 6 * HOUR_IN_SECONDS );
- } else {
- set_transient( $transient_key, [], HOUR_IN_SECONDS );
- }
- } else {
- set_transient( $transient_key, [], HOUR_IN_SECONDS );
- }
- }
-
- return $release_info;
-}
-
-// Admin-Update-Hinweis anzeigen
-function wis_show_update_notice() {
- if ( ! current_user_can('manage_options') ) {
- return;
- }
-
- $current_version = wis_get_plugin_version();
- $latest_release = wis_get_latest_release_info();
-
- if ( ! empty($latest_release['version']) && version_compare($current_version, $latest_release['version'], '<') ) {
-
- $refresh_url = wp_nonce_url(
- admin_url('plugins.php?wis_clear_cache=1'),
- 'wis_clear_cache_action'
- );
- ?>
-
- prefix . 'wis_orders';
- $coupon_table_name = $wpdb->prefix . 'wis_coupons';
$charset_collate = $wpdb->get_charset_collate();
- $sql = "CREATE TABLE $table_name (
+ $tables = [];
+
+ // Items
+ $tables[] = "CREATE TABLE {$wpdb->prefix}wis_items (
+ id mediumint(9) NOT NULL AUTO_INCREMENT,
+ item_id varchar(100) NOT NULL,
+ name varchar(255) NOT NULL,
+ description text,
+ price int(11) DEFAULT 0,
+ offer_price int(11) DEFAULT 0,
+ is_offer tinyint(1) DEFAULT 0,
+ is_daily_deal tinyint(1) DEFAULT 0,
+ servers text,
+ categories text,
+ status varchar(20) DEFAULT 'draft',
+ created_at datetime DEFAULT CURRENT_TIMESTAMP,
+ updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ PRIMARY KEY (id),
+ UNIQUE KEY item_id (item_id),
+ KEY status (status)
+ ) $charset_collate;";
+
+ // Orders
+ $tables[] = "CREATE TABLE {$wpdb->prefix}wis_orders (
id mediumint(9) NOT NULL AUTO_INCREMENT,
player_name varchar(100) NOT NULL,
server varchar(100) NOT NULL,
@@ -172,567 +78,1377 @@ class WIS_Activator {
quantity int(11) DEFAULT 1,
status varchar(20) DEFAULT 'pending',
response text,
- created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
- PRIMARY KEY (id)
+ created_at datetime DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (id),
+ KEY player_name (player_name),
+ KEY status (status)
) $charset_collate;";
- $sql2 = "CREATE TABLE $coupon_table_name (
+ // Coupons
+ $tables[] = "CREATE TABLE {$wpdb->prefix}wis_coupons (
id mediumint(9) NOT NULL AUTO_INCREMENT,
code varchar(50) NOT NULL,
value int(11) NOT NULL,
- type varchar(10) DEFAULT 'fixed',
+ type varchar(10) DEFAULT 'fixed',
usage_limit int(11) DEFAULT 1,
used_count int(11) DEFAULT 0,
expiry date DEFAULT NULL,
- created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
- PRIMARY KEY (id)
+ created_at datetime DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (id),
+ UNIQUE KEY code (code)
+ ) $charset_collate;";
+
+ // Servers
+ $tables[] = "CREATE TABLE {$wpdb->prefix}wis_servers (
+ id mediumint(9) NOT NULL AUTO_INCREMENT,
+ slug varchar(100) NOT NULL,
+ name varchar(255) NOT NULL,
+ created_at datetime DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (id),
+ UNIQUE KEY slug (slug)
+ ) $charset_collate;";
+
+ // Categories
+ $tables[] = "CREATE TABLE {$wpdb->prefix}wis_categories (
+ id mediumint(9) NOT NULL AUTO_INCREMENT,
+ name varchar(255) NOT NULL,
+ slug varchar(100) NOT NULL,
+ created_at datetime DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (id),
+ UNIQUE KEY slug (slug)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
- dbDelta($sql);
- dbDelta($sql2);
-
- // Alte Installationen updaten (type Spalte hinzufügen)
- $existing_columns = $wpdb->get_col_info("SELECT * FROM $coupon_table_name LIMIT 1");
- if(!in_array('type', $existing_columns)) {
- $wpdb->query("ALTER TABLE $coupon_table_name ADD COLUMN type varchar(10) DEFAULT 'fixed'");
+ foreach ($tables as $sql) {
+ dbDelta($sql);
}
}
- public static function setup_daily_deal() {
- // Initial setup beim ersten Aktivieren
+ private static function set_default_options() {
+ $defaults = [
+ 'wis_currency_name' => 'Coins',
+ 'wis_image_base_url' => 'https://git.viper.ipv64.net/M_Viper/minecraft-items/raw/branch/main/images/',
+ 'wis_header_text' => '✅ Auto-Bilder | 💰 Sicherer Checkout | 🎮 Ingame-Bestätigung',
+ 'wis_coupon_exclude_offers' => '0',
+ 'wis_daily_deal_enabled' => '0',
+ 'wis_daily_deal_discount' => '20'
+ ];
+
+ foreach ($defaults as $key => $value) {
+ if (get_option($key) === false) {
+ add_option($key, $value);
+ }
+ }
}
public static function run_daily_deal() {
- if(get_option('wis_daily_deal_enabled') === '0') return;
+ if (get_option('wis_daily_deal_enabled') !== '1') return;
global $wpdb;
- $discount_percent = intval(get_option('wis_daily_deal_discount', 20));
+ $table = $wpdb->prefix . 'wis_items';
+ $discount = intval(get_option('wis_daily_deal_discount', 20));
- // 1. Aktuellen Daily Deal deaktivieren
- $wpdb->update(
- $wpdb->prefix.'postmeta',
- ['meta_value' => 0],
- ['meta_key' => '_wis_daily_deal', 'meta_value' => 1]
+ // Reset old daily deal
+ $wpdb->update($table, ['is_daily_deal' => 0], ['is_daily_deal' => 1]);
+
+ // Select random item
+ $item = $wpdb->get_row("SELECT * FROM $table WHERE status = 'publish' AND price > 0 ORDER BY RAND() LIMIT 1");
+
+ if ($item) {
+ // Syntax Error Fix here: removed extra parent
+ $offer_price = max(0, floor($item->price - ($item->price * ($discount / 100))));
+ $wpdb->update($table, [
+ 'is_daily_deal' => 1,
+ 'is_offer' => 1,
+ 'offer_price' => $offer_price
+ ], ['id' => $item->id]);
+ }
+ }
+
+ public static function reset_shop() {
+ global $wpdb;
+
+ $tables = [
+ 'wis_items', 'wis_orders', 'wis_coupons',
+ 'wis_servers', 'wis_categories'
+ ];
+
+ foreach ($tables as $table) {
+ $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}$table");
+ }
+
+ self::set_default_options();
+ return true;
+ }
+}
+
+// ===========================================================
+// DATABASE HELPER
+// ===========================================================
+class WIS_DB {
+ public static function get_items($args = []) {
+ global $wpdb;
+ $table = $wpdb->prefix . 'wis_items';
+
+ $where = isset($args['status']) ? $wpdb->prepare("WHERE status = %s", $args['status']) : "WHERE 1=1";
+ $limit = isset($args['limit']) ? "LIMIT " . intval($args['limit']) : "";
+ $orderby = isset($args['orderby']) ? "ORDER BY " . sanitize_text_field($args['orderby']) : "ORDER BY name ASC";
+
+ return $wpdb->get_results("SELECT * FROM $table $where $orderby $limit");
+ }
+
+ public static function get_item($id) {
+ global $wpdb;
+ return $wpdb->get_row($wpdb->prepare(
+ "SELECT * FROM {$wpdb->prefix}wis_items WHERE id = %d",
+ $id
+ ));
+ }
+
+ public static function get_item_by_item_id($item_id) {
+ global $wpdb;
+ return $wpdb->get_row($wpdb->prepare(
+ "SELECT * FROM {$wpdb->prefix}wis_items WHERE item_id = %s",
+ $item_id
+ ));
+ }
+
+ public static function insert_item($data) {
+ global $wpdb;
+ return $wpdb->insert($wpdb->prefix . 'wis_items', $data);
+ }
+
+ public static function update_item($id, $data) {
+ global $wpdb;
+ return $wpdb->update($wpdb->prefix . 'wis_items', $data, ['id' => $id]);
+ }
+
+ public static function delete_item($id) {
+ global $wpdb;
+ return $wpdb->delete($wpdb->prefix . 'wis_items', ['id' => $id]);
+ }
+
+ // Servers
+ public static function get_servers() {
+ global $wpdb;
+ return $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wis_servers ORDER BY name ASC");
+ }
+
+ public static function insert_server($slug, $name) {
+ global $wpdb;
+ return $wpdb->insert($wpdb->prefix . 'wis_servers', [
+ 'slug' => sanitize_title($slug),
+ 'name' => sanitize_text_field($name)
+ ]);
+ }
+
+ public static function delete_server($id) {
+ global $wpdb;
+ return $wpdb->delete($wpdb->prefix . 'wis_servers', ['id' => $id]);
+ }
+
+ // Categories
+ public static function get_categories() {
+ global $wpdb;
+ return $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wis_categories ORDER BY name ASC");
+ }
+
+ public static function insert_category($name) {
+ global $wpdb;
+ return $wpdb->insert($wpdb->prefix . 'wis_categories', [
+ 'name' => sanitize_text_field($name),
+ 'slug' => sanitize_title($name)
+ ]);
+ }
+
+ public static function delete_category($id) {
+ global $wpdb;
+ return $wpdb->delete($wpdb->prefix . 'wis_categories', ['id' => $id]);
+ }
+
+ // Coupons
+ public static function get_coupons() {
+ global $wpdb;
+ return $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wis_coupons ORDER BY created_at DESC");
+ }
+
+ public static function get_coupon_by_code($code) {
+ global $wpdb;
+ return $wpdb->get_row($wpdb->prepare(
+ "SELECT * FROM {$wpdb->prefix}wis_coupons WHERE code = %s",
+ strtoupper($code)
+ ));
+ }
+
+ public static function insert_coupon($data) {
+ global $wpdb;
+ $data['code'] = strtoupper($data['code']);
+ return $wpdb->insert($wpdb->prefix . 'wis_coupons', $data);
+ }
+
+ public static function update_coupon($id, $data) {
+ global $wpdb;
+ if (isset($data['code'])) {
+ $data['code'] = strtoupper($data['code']);
+ }
+ return $wpdb->update($wpdb->prefix . 'wis_coupons', $data, ['id' => $id]);
+ }
+
+ public static function delete_coupon($id) {
+ global $wpdb;
+ return $wpdb->delete($wpdb->prefix . 'wis_coupons', ['id' => $id]);
+ }
+
+ // Orders
+ public static function get_orders($limit = 100) {
+ global $wpdb;
+ return $wpdb->get_results($wpdb->prepare(
+ "SELECT * FROM {$wpdb->prefix}wis_orders ORDER BY created_at DESC LIMIT %d",
+ $limit
+ ));
+ }
+
+ public static function get_order($id) {
+ global $wpdb;
+ return $wpdb->get_row($wpdb->prepare(
+ "SELECT * FROM {$wpdb->prefix}wis_orders WHERE id = %d",
+ $id
+ ));
+ }
+
+ public static function insert_order($data) {
+ global $wpdb;
+ return $wpdb->insert($wpdb->prefix . 'wis_orders', $data);
+ }
+
+ public static function update_order_status($id, $status) {
+ global $wpdb;
+ return $wpdb->update(
+ $wpdb->prefix . 'wis_orders',
+ ['status' => $status],
+ ['id' => $id]
);
-
- // 2. Zufälliges Item auswählen
- $args = [
- 'post_type' => 'wis_item',
- 'post_status' => 'publish',
- 'posts_per_page' => 1,
- 'meta_query' => [
- 'relation' => 'AND',
- ['key' => '_wis_price', 'value' => 0, 'compare' => '>'],
- ['key' => '_wis_daily_deal', 'compare' => 'NOT EXISTS'] // Eines holen, das noch kein Daily Deal ist
- ]
- ];
- $items = get_posts($args);
-
- if(!empty($items)) {
- $item_id = $items[0]->ID;
- $price = intval(get_post_meta($item_id, '_wis_price', true));
-
- // Rabatt berechnen
- $offer_price = max(0, floor($price - ($price * ($discount_percent / 100))));
-
- // Flags setzen
- update_post_meta($item_id, '_wis_daily_deal', 1);
- update_post_meta($item_id, '_wis_is_offer', 1);
- update_post_meta($item_id, '_wis_offer_price', $offer_price);
- }
+ }
+
+ public static function delete_order($id) {
+ global $wpdb;
+ return $wpdb->delete($wpdb->prefix . 'wis_orders', ['id' => $id]);
}
}
// ===========================================================
-// 2. ADMIN & CPT
-// ===========================================================
-class WIS_CPT {
- public static function register_post_types() {
- register_post_type('wis_item', [
- 'labels' => ['name' => 'Shop Items', 'singular_name' => 'Shop Item'],
- 'public' => false,
- 'show_ui' => true,
- 'show_in_menu' => false,
- 'show_in_admin_all_list' => true,
- 'capability_type' => 'post',
- 'capabilities' => [
- 'edit_post' => 'manage_options',
- 'read_post' => 'manage_options',
- 'delete_post' => 'manage_options',
- 'edit_posts' => 'manage_options',
- 'delete_posts' => 'manage_options',
- 'delete_others_posts' => 'manage_options'
- ],
- 'supports' => ['title', 'editor'],
- 'taxonomies' => ['wis_category']
- ]);
- register_post_type('wis_server', [
- 'labels' => ['name' => 'Servers', 'singular_name' => 'Server'],
- 'public' => false,
- 'show_ui' => true,
- 'show_in_menu' => false,
- 'capability_type' => 'post',
- 'supports' => ['title']
- ]);
- register_post_type('wis_coupon', [
- 'labels' => ['name' => 'Gutscheine', 'singular_name' => 'Gutschein'],
- 'public' => false,
- 'show_ui' => true,
- 'show_in_menu' => false,
- 'capability_type' => 'post',
- 'supports' => ['title']
- ]);
-
- // NEU: Kategorien Taxonomie
- $labels = [
- 'name' => 'Kategorien',
- 'singular_name' => 'Kategorie',
- 'search_items' => 'Kategorien suchen',
- 'all_items' => 'Alle Kategorien',
- 'parent_item' => 'Übergeordnete Kategorie',
- 'edit_item' => 'Kategorie bearbeiten',
- 'update_item' => 'Kategorie aktualisieren',
- 'add_new_item' => 'Neue Kategorie',
- 'new_item_name' => 'Kategorie Name',
- 'menu_name' => 'Kategorien',
- 'popular_items' => 'Beliebte Kategorien',
- 'separate_items_with_commas' => "Kategorien mit Kommas trennen",
- 'add_or_remove_items' => 'Kategorien hinzufügen oder entfernen',
- 'choose_from_most_used' => 'Häufigste Kategorien auswählen',
- 'not_found' => 'Keine Kategorien gefunden'
- ];
- $args = [
- 'hierarchical' => true,
- 'labels' => $labels,
- 'show_ui' => true,
- 'show_in_menu' => true, // Erscheint als Menüpunkt
- 'show_in_nav_menus' => false,
- 'show_admin_column' => true,
- 'public' => false,
- 'rewrite' => false,
- ];
- register_taxonomy('wis_category', 'wis_item', $args);
- }
-
- public static function add_meta_boxes() {
- add_meta_box('wis_item_meta', 'Item Einstellungen', [self::class, 'render_item_meta'], 'wis_item', 'normal', 'high');
- add_meta_box('wis_server_meta', 'Server Einstellungen', [self::class, 'render_server_meta'], 'wis_server', 'normal', 'high');
- add_meta_box('wis_coupon_meta', 'Gutschein Einstellungen', [self::class, 'render_coupon_meta'], 'wis_coupon', 'normal', 'high');
- }
-
- public static function render_item_meta($post) {
- wp_nonce_field('wis_save_item', 'wis_item_nonce');
- $price = get_post_meta($post->ID,'_wis_price',true);
- $item_id = get_post_meta($post->ID,'_wis_item_id',true);
- $servers = get_post_meta($post->ID,'_wis_servers',true);
- if(!is_array($servers)) $servers = [];
-
- $is_offer = get_post_meta($post->ID,'_wis_is_offer',true);
- $is_daily_deal = get_post_meta($post->ID,'_wis_daily_deal',true);
- $offer_price = get_post_meta($post->ID,'_wis_offer_price',true);
- $manual_daily = get_post_meta($post->ID,'_wis_manual_daily_deal',true);
-
- $all_servers = get_posts(['post_type'=>'wis_server','numberposts'=>-1]);
- $currency = get_option('wis_currency_name', 'Coins');
- $exclude_offers = get_option('wis_coupon_exclude_offers');
-
- // NEU: Kategorien
- $cats = wp_get_object_terms($post->ID, 'wis_category');
- $cat_ids = array_map(function($t) { return $t->term_id; }, $cats);
-
- $current_status = get_post_status($post->ID);
- $is_active = ($current_status === 'publish') && ($price > 0);
- $status_msg = $is_active ? '✅ Aktiv im Shop ' : '⏸️ Inaktiv (Kein Preis oder Entwurf) ';
-
- echo ''.$status_msg.'
';
- echo 'Titel (Anzeige im Shop) ';
- echo '
Wird automatisch aus dem Post-Titel übernommen
';
-
- echo 'Preis ('.esc_html($currency).')
';
- echo 'Wenn du hier einen Preis einträgst (>0), wird das Item automatisch aktiv.
';
-
- echo 'Item ID (z.B. minecraft:diamond) ';
- echo '
✅ Daraus wird automatisch das Bild generiert.
';
-
- // NEU: Kategorie Auswahl
- echo 'Kategorie(n) ';
- $terms = get_terms([
- 'taxonomy' => 'wis_category',
- 'hide_empty' => false,
- ]);
- echo '
';
- if(!empty($terms)) {
- foreach($terms as $term) {
- $selected = in_array($term->term_id, $cat_ids) ? 'checked' : '';
- echo '';
- echo ' '.esc_html($term->name);
- echo ' ';
- }
- } else {
- echo 'Noch keine Kategorien erstellt. ';
- }
- echo '
';
-
- echo '';
- echo '
Daily Deal (Angebot des Tages)
';
- echo '
Manuell als "Angebot des Tages" setzen 🎁 ';
- echo 'Überschreibt die Automatik bis Mitternacht. Praktisch zum Testen. ';
- if($is_daily_deal) {
- echo 'ℹ️ Info: Dieses Item ist aktuell das Angebot des Tages. ';
- echo 'Der Rabatt wurde automatisch berechnet.';
- }
- echo '
';
-
- echo '';
- echo '
Angebot / Sale
';
- echo '
Als "Angebot" markieren 🔥 ';
-
- echo 'Hervorgehobenes Item im Shop (rot/gold Badge). ';
-
- if($exclude_offers) {
- echo 'Hinweis: Gutscheine sind aktuell global für Angebote deaktiviert.';
- }
-
- echo '
';
- echo '
Angebots-Preis (Optional - wird ignoriert wenn Daily Deal aktiv) ';
- echo ' ';
- echo 'Wenn ausgefüllt, wird der normale Preis durchgestrichen und dieser angezeigt.
';
- echo '
';
-
- echo 'Beschreibung ';
- echo '
Dies ist der lange Text, der unter dem Titel im Shop angezeigt wird.
';
-
- echo 'Server zuweisen (Mehrfachauswahl möglich) ';
- echo '
';
- if(empty($all_servers)) echo 'Noch keine Server erstellt. ';
- foreach($all_servers as $s){
- $checked = in_array($s->post_name, $servers) ? 'checked' : '';
- echo '';
- echo ' ';
- echo esc_html($s->post_title);
- echo ' ';
- }
- echo '
';
- }
-
- public static function render_server_meta($post){
- echo '';
- echo 'Info: Da keine RCON-Verbindung benötigt wird (Vault/Plugin bestätigt), sind hier keine weiteren Einstellungen nötig. ';
- echo 'Der Servername dient nur zur Identifikat im Shop-Frontend.';
- echo '
';
- }
-
- public static function render_coupon_meta($post) {
- wp_nonce_field('wis_save_coupon', 'wis_coupon_nonce');
- $code = get_post_meta($post->ID,'_wis_code',true);
- $value = get_post_meta($post->ID,'_wis_value',true);
- $limit = get_post_meta($post->ID,'_wis_usage_limit',true);
- $expiry = get_post_meta($post->ID,'_wis_expiry',true);
- $type = get_post_meta($post->ID,'_wis_type',true);
- $exclude_offers = get_option('wis_coupon_exclude_offers');
-
- if(empty($type)) $type = 'fixed';
-
- echo 'Gutschein Code ';
- echo ' ';
-
- echo '
Rabattart ';
- echo '';
- echo 'Festbetrag (z.B. -100 Coins) ';
- echo 'Prozentual (z.B. 10% Rabatt) ';
- echo ' ';
-
- echo '
Wert ';
- echo ' ';
-
- if($exclude_offers) {
- echo '
';
- echo '⚠️ Achtung: In den Shop-Einstellungen ist aktiviert, dass Gutscheine nicht auf Angebot-Items (Sale) angewendet werden. Dieser Gutschein wirkt nur auf reguläre Items.';
- echo '
';
- }
-
- echo 'Nutzungslimit ';
- echo ' ';
-
- echo '
Ablaufdatum (Optional) ';
- echo ' ';
- }
-
- public static function save_meta($post_id){
- if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
-
- if(get_post_type($post_id)==='wis_item' && isset($_POST['wis_item_nonce']) && wp_verify_nonce($_POST['wis_item_nonce'],'wis_save_item')){
- update_post_meta($post_id,'_wis_price',intval($_POST['wis_price']));
- update_post_meta($post_id,'_wis_item_id',sanitize_text_field($_POST['wis_item_id']));
-
- $is_offer = isset($_POST['wis_is_offer']) ? 1 : 0;
- update_post_meta($post_id,'_wis_is_offer', $is_offer);
- update_post_meta($post_id,'_wis_offer_price', intval($_POST['wis_offer_price']));
-
- // NEU: Manual Daily Deal Logic
- $manual_daily = isset($_POST['wis_manual_daily_deal']) ? 1 : 0;
- if($manual_daily) {
- update_post_meta($post_id,'_wis_daily_deal', 1);
- update_post_meta($post_id,'_wis_is_offer', 1);
- } else {
- // Wenn manuell abgewählt, löschen wir das Flag, damit der Cron ran darf
- // update_post_meta($post_id,'_wis_daily_deal', 0); // Optional: Reset flag
- }
-
- $servers = isset($_POST['wis_servers']) && is_array($_POST['wis_servers']) ? array_map('sanitize_text_field', $_POST['wis_servers']) : [];
- update_post_meta($post_id,'_wis_servers', $servers);
-
- $cats = isset($_POST['wis_cats']) ? array_map('intval', $_POST['wis_cats']) : [];
- wp_set_object_terms($post_id, $cats, 'wis_category');
- }
- if(get_post_type($post_id)==='wis_server' && isset($_POST['wis_server_nonce']) && wp_verify_nonce($_POST['wis_server_nonce'],'wis_save_server')){
- // Nichts zu tun
- }
- if(get_post_type($post_id)==='wis_coupon' && isset($_POST['wis_coupon_nonce']) && wp_verify_nonce($_POST['wis_coupon_nonce'],'wis_save_coupon')){
- $code = sanitize_text_field(strtoupper($_POST['wis_code']));
- $value = intval($_POST['wis_value']);
- $limit = intval($_POST['wis_usage_limit']);
- $expiry = sanitize_text_field($_POST['wis_expiry']);
- $type = sanitize_text_field($_POST['wis_type']);
- if(!in_array($type, ['fixed', 'percent'])) $type = 'fixed';
-
- update_post_meta($post_id,'_wis_code', $code);
- update_post_meta($post_id,'_wis_value', $value);
- update_post_meta($post_id,'_wis_type', $type);
- update_post_meta($post_id,'_wis_usage_limit', $limit);
- update_post_meta($post_id,'_wis_expiry', $expiry);
-
- global $wpdb;
- $table_name = $wpdb->prefix . 'wis_coupons';
-
- $data = ['code' => $code, 'value' => $value, 'type' => $type, 'usage_limit' => $limit, 'expiry' => $expiry];
-
- $existing = $wpdb->get_row($wpdb->prepare("SELECT id FROM $table_name WHERE code = %s", $code));
-
- if($existing) {
- $wpdb->update($table_name, $data, ['id' => $existing->id]);
- } else {
- $wpdb->insert($table_name, $data);
- }
-
- $db_coupon = $wpdb->get_row($wpdb->prepare("SELECT used_count FROM $table_name WHERE code = %s", $code));
- if($db_coupon) {
- update_post_meta($post_id, '_wis_used_count', $db_coupon->used_count);
- }
- }
- }
-
- public static function auto_update_status($post_id) {
- static $processing = [];
- if (isset($processing[$post_id])) return;
- $processing[$post_id] = true;
- if (get_post_type($post_id) != 'wis_item') {
- unset($processing[$post_id]);
- return;
- }
- $price = get_post_meta($post_id, '_wis_price', true);
- $current_status = get_post_status($post_id);
- $new_status = ($price > 0) ? 'publish' : 'draft';
- if ($current_status !== $new_status) {
- remove_action('save_post', [__CLASS__, 'auto_update_status'], 10);
- wp_update_post(['ID' => $post_id, 'post_status' => $new_status]);
- add_action('save_post', [__CLASS__, 'auto_update_status'], 10);
- }
- unset($processing[$post_id]);
- }
-
- public static function delete_coupon_from_table($post_id) {
- if(get_post_type($post_id) != 'wis_coupon') return;
- $code = get_post_meta($post_id, '_wis_code', true);
- if($code) {
- global $wpdb;
- $wpdb->delete($wpdb->prefix . 'wis_coupons', ['code' => $code]);
- }
- }
-}
-
-// ===========================================================
-// Bulk Delete Funktionalität
-// ===========================================================
-class WIS_Bulk_Actions {
- public static function register_bulk_actions($bulk_actions) {
- $bulk_actions['delete'] = __('Löschen', 'wis');
- return $bulk_actions;
- }
- public static function handle_bulk_actions($redirect_to, $action, $post_ids) {
- if ($action !== 'delete') return $redirect_to;
- $deleted = 0;
- foreach ($post_ids as $post_id) {
- if (current_user_can('delete_post', $post_id)) {
- wp_delete_post($post_id, true);
- $deleted++;
- }
- }
- if ($deleted > 0) {
- $redirect_to = add_query_arg([
- 'bulk_deleted' => $deleted,
- 'post_type' => get_post_type($post_ids[0] ?? 0)
- ], $redirect_to);
- }
- return $redirect_to;
- }
- public static function admin_notices() {
- if (!empty($_GET['bulk_deleted'])) {
- $count = intval($_GET['bulk_deleted']);
- $msg = sprintf(_n('%d Eintrag gelöscht.', '%d Einträge gelöscht.', $count, 'wis'), $count);
- echo '
';
- }
- }
-}
-
-// ===========================================================
-// 3. ADMIN MENU
+// ADMIN PAGES
// ===========================================================
class WIS_Admin {
public static function register_menu() {
- add_menu_page('Ingame Shop', 'Ingame Shop', 'manage_options', 'wis_shop', [self::class, 'page_overview'], 'dashicons-cart', 6);
+ add_menu_page(
+ 'Ingame Shop',
+ 'Ingame Shop',
+ 'manage_options',
+ 'wis_shop',
+ [self::class, 'page_overview'],
+ 'dashicons-cart',
+ 6
+ );
+
+ add_submenu_page('wis_shop', 'Einstellungen', 'Einstellungen', 'manage_options', 'wis_shop');
+ add_submenu_page('wis_shop', 'Items', 'Items', 'manage_options', 'wis_items', [self::class, 'page_items']);
add_submenu_page('wis_shop', 'Bestellungen', 'Bestellungen', 'manage_options', 'wis_orders', [self::class, 'page_orders']);
+ add_submenu_page('wis_shop', 'Server', 'Server', 'manage_options', 'wis_servers', [self::class, 'page_servers']);
+ add_submenu_page('wis_shop', 'Kategorien', 'Kategorien', 'manage_options', 'wis_categories', [self::class, 'page_categories']);
+ add_submenu_page('wis_shop', 'Gutscheine', 'Gutscheine', 'manage_options', 'wis_coupons', [self::class, 'page_coupons']);
+ add_submenu_page('wis_shop', 'JSON Export/Import', 'JSON Tools', 'manage_options', 'wis_json', [self::class, 'page_json']);
+ add_submenu_page('wis_shop', 'Shop Reset', '🔄 Reset', 'manage_options', 'wis_reset', [self::class, 'page_reset']);
add_submenu_page('wis_shop', 'Top Spender', 'Top Spender', 'manage_options', 'wis_top_spenders', [self::class, 'page_top_spenders']);
- add_submenu_page('wis_shop', 'Items', 'Items', 'manage_options', 'edit.php?post_type=wis_item');
- add_submenu_page('wis_shop', 'Kategorien', 'Kategorien', 'manage_options', 'edit-tags.php?taxonomy=wis_category');
- add_submenu_page('wis_shop', 'Servers', 'Servers', 'manage_options', 'edit.php?post_type=wis_server');
- add_submenu_page('wis_shop', 'Gutscheine', 'Gutscheine', 'manage_options', 'edit.php?post_type=wis_coupon');
}
-
+
public static function page_overview() {
- if(isset($_POST['wis_save_settings']) && check_admin_referer('wis_settings_nonce')) {
+ // Handle settings save
+ if (isset($_POST['wis_save_settings']) && check_admin_referer('wis_settings')) {
update_option('wis_currency_name', sanitize_text_field($_POST['wis_currency_name']));
- update_option('wis_image_base_url', sanitize_text_field($_POST['wis_image_base_url']));
+ update_option('wis_image_base_url', esc_url_raw($_POST['wis_image_base_url']));
update_option('wis_header_text', sanitize_textarea_field($_POST['wis_header_text']));
update_option('wis_coupon_exclude_offers', isset($_POST['wis_coupon_exclude_offers']) ? '1' : '0');
-
- // NEU: Daily Deal Settings
update_option('wis_daily_deal_enabled', isset($_POST['wis_daily_deal_enabled']) ? '1' : '0');
update_option('wis_daily_deal_discount', intval($_POST['wis_daily_deal_discount']));
-
echo '✅ Einstellungen gespeichert!
';
}
- $currency = get_option('wis_currency_name', 'Coins');
- $img_base = get_option('wis_image_base_url', 'https://assets.minecraft-ids.com/1_21_10/');
- $header_text = get_option('wis_header_text', '✅ Auto-Bilder | 💰 Sicherer Checkout');
- $exclude_offers = get_option('wis_coupon_exclude_offers', '0');
- // NEU: Daily Deal Settings
- $daily_deal_enabled = get_option('wis_daily_deal_enabled', '0');
- $daily_deal_discount = get_option('wis_daily_deal_discount', '20');
-
- echo '🛒 Ingame Shop Pro v1.0.0 ';
-
- echo '
✅ Feature Übersicht ';
- echo '🛒 Warenkorb: Kauf mehrerer Items auf einmal. ';
- echo '🔗 Einzelne Bestellung: Alles wird in einer einzigen Datenbankzeile gespeichert. ';
- echo '📋 Detail-Anzeige: Im Backend siehst du genau "1x Diamant, 64x Stein" etc. & Gutschein. ';
- echo '✨ Sauberer Prozess: Alle Items werden sofort nach einer Bestätigung ausgegeben. ';
- echo '🔥 Angebote: Items können hervorgehoben werden. ';
- echo '🎁 Daily Deal: Automatisches Angebot des Tages. ';
- echo '🎫 Smart Coupons: Gutscheine (Festbetrag & Prozent) werden korrekt bei reinen Angeboten ignoriert. ';
- echo '🏷️ Kategorien: Items können in Kategorien gruppiert werden. ';
- echo '🏆 Top Spender: Statistiken im Backend. ';
- echo ' ';
+ global $wpdb;
+ $stats = [
+ 'items' => $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}wis_items"),
+ 'orders' => $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}wis_orders"),
+ 'servers' => $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}wis_servers"),
+ 'coupons' => $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}wis_coupons")
+ ];
- echo '
';
- echo '
⚙️ Globale Einstellungen ';
- echo '
';
- echo '
';
-
- echo '
';
- echo '
🚀 Bulk Import ';
- echo '
Smart Import: Lädt Items in Paketen (20 pro Durchlauf). Vorhandene Items werden übersprungen.
';
- echo '
';
- echo '
Import URL: ';
- echo '
';
- echo '
';
- echo '1. Daten laden ';
- echo '2. Import starten ';
- echo '
';
- echo '
';
- echo '
';
- echo '0 / 0 0%
';
- echo '
';
- echo '
';
?>
-
';
+ }
+
+ public static function page_servers() {
+ // Handle add
+ if (isset($_POST['wis_add_server'])) {
+ check_admin_referer('wis_server_form');
+ WIS_DB::insert_server($_POST['slug'], $_POST['name']);
+ echo '
';
+ }
+ // Handle delete
+ if (isset($_GET['action'], $_GET['id']) && $_GET['action'] === 'delete') {
+ check_admin_referer('wis_server_action', '_wpnonce');
+ WIS_DB::delete_server(intval($_GET['id']));
+ echo '
';
+ }
+
+ $servers = WIS_DB::get_servers();
+ ?>
+
+
Server
+
+
+
Neuen Server erstellen
+
+
+
+
Vorhandene Server
+
+
+
+ ID
+ Name
+ Slug
+ Aktionen
+
+
+
+
+ Noch keine Server vorhanden.
+
+
+
+ id); ?>
+ name); ?>
+ slug); ?>
+
+ Löschen
+
+
+
+
+
+
+
+
✅ Kategorie erstellt!
';
+ }
+
+ // Handle delete
+ if (isset($_GET['action'], $_GET['id']) && $_GET['action'] === 'delete') {
+ check_admin_referer('wis_category_action', '_wpnonce');
+ WIS_DB::delete_category(intval($_GET['id']));
+ echo '';
+ }
+
+ $categories = WIS_DB::get_categories();
+ ?>
+
+
Kategorien
+
+
+
Neue Kategorie erstellen
+
+
+
+
Vorhandene Kategorien
+
+
+
+ ID
+ Name
+ Slug
+ Aktionen
+
+
+
+
+ Noch keine Kategorien vorhanden.
+
+
+
+ id); ?>
+ name); ?>
+ slug); ?>
+
+ Löschen
+
+
+
+
+
+
+
+ sanitize_text_field($_POST['code']),
+ 'value' => intval($_POST['value']),
+ 'type' => sanitize_text_field($_POST['type']),
+ 'usage_limit' => intval($_POST['usage_limit']),
+ 'expiry' => !empty($_POST['expiry']) ? sanitize_text_field($_POST['expiry']) : null
+ ];
+
+ if (isset($_GET['edit'])) {
+ unset($data['used_count']); // Don't reset usage count
+ WIS_DB::update_coupon(intval($_GET['edit']), $data);
+ echo '';
+ } else {
+ $data['used_count'] = 0;
+ WIS_DB::insert_coupon($data);
+ echo '';
+ }
+ }
+
+ // Handle delete
+ if (isset($_GET['action'], $_GET['id']) && $_GET['action'] === 'delete') {
+ check_admin_referer('wis_coupon_action', '_wpnonce');
+ WIS_DB::delete_coupon(intval($_GET['id']));
+ echo '';
+ }
+
+ // Show form
+ if (isset($_GET['add']) || isset($_GET['edit'])) {
+ global $wpdb;
+ $coupon = isset($_GET['edit']) ? $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wis_coupons WHERE id = %d", intval($_GET['edit']))) : null;
+ $currency = get_option('wis_currency_name', 'Coins');
+ ?>
+
+
+
+
+
+
+
+
+ Code
+ Rabatt
+ Genutzt
+ Gültig bis
+ Aktionen
+
+
+
+
+ Noch keine Gutscheine vorhanden.
+
+
+
+ code); ?>
+
+ type === 'percent'): ?>
+ value); ?>%
+
+ value); ?>
+
+
+ used_count); ?> / usage_limit); ?>
+ expiry ? esc_html(date('d.m.Y', strtotime($coupon->expiry))) : '∞'; ?>
+
+ Bearbeiten
+ Löschen
+
+
+
+
+
+
+
+ ✅ Bestellung gelöscht!
';
+ }
+
+ // Handle status change
+ if (isset($_GET['action'], $_GET['id']) && $_GET['action'] === 'complete') {
+ check_admin_referer('wis_order_action', '_wpnonce');
+ WIS_DB::update_order_status(intval($_GET['id']), 'completed');
+ echo '';
+ }
+
+ // Show details
+ if (isset($_GET['view'])) {
+ $order = WIS_DB::get_order(intval($_GET['view']));
+ if (!$order) {
+ echo 'Bestellung nicht gefunden.
';
+ return;
+ }
+
+ $currency = get_option('wis_currency_name', 'Coins');
+ $status_colors = [
+ 'pending' => '#ffc107',
+ 'processing' => '#0073aa',
+ 'completed' => 'green',
+ 'cancelled' => 'red',
+ 'failed' => 'red'
+ ];
+ $status_labels = [
+ 'pending' => 'Warte auf Ingame',
+ 'processing' => 'In Bearbeitung',
+ 'completed' => 'Erledigt',
+ 'cancelled' => 'Abgebrochen',
+ 'failed' => 'Fehler'
+ ];
+
+ $decoded = json_decode($order->response, true);
+ ?>
+
+
Bestellung #id; ?> - Details
+
← Zurück
+
+
+ ID id); ?>
+ Datum created_at))); ?>
+ Spieler player_name); ?>
+ Server server); ?>
+ Zusammenfassung item_title); ?>
+ Preis price); ?>
+ Status status] ?? $order->status; ?>
+
+ Details (JSON)
+ response); ?>
+
+
+
+
+
+
Bestellungen
+
+
+
+
+ Datum
+ Spieler
+ Inhalt
+ Preis
+ Status
+ Aktionen
+
+
+
+
+ Noch keine Bestellungen vorhanden.
+
+
+ 'Warte',
+ 'processing' => 'Geben...',
+ 'completed' => 'Fertig',
+ 'cancelled' => 'Abgebrochen',
+ 'failed' => 'Fehler'
+ ];
+ $status_colors = [
+ 'pending' => '#ffc107',
+ 'processing' => '#0073aa',
+ 'completed' => 'green',
+ 'cancelled' => 'red',
+ 'failed' => 'red'
+ ];
+ ?>
+
+ created_at))); ?>
+ player_name); ?>
+ item_title, 0, 50)) . (strlen($order->item_title) > 50 ? '...' : ''); ?>
+ price); ?>
+ status] ?? $order->status; ?>
+
+ 👁️ Details
+ 🗑️ Löschen
+
+
+
+
+
+
+
+ 'publish']);
+ $img_base = get_option('wis_image_base_url', '');
+
+ $json_data = ['items' => []];
+
+ foreach ($items as $item) {
+ $img_name = str_replace(':', '_', $item->item_id) . '.png';
+ $json_data['items'][] = [
+ 'id' => $item->item_id,
+ 'name' => $item->name,
+ 'description' => $item->description,
+ 'price' => intval($item->price),
+ 'image' => $img_base . $img_name
+ ];
+ }
+
+ $json_output = json_encode($json_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
+
+ echo '📦 JSON Export ';
+ echo '
✅ JSON erfolgreich generiert!
';
+ echo '
';
+ echo '
💾 Als items.json herunterladen
';
+ echo '';
+ echo '
📤 Nächste Schritte: ';
+ echo '
';
+ echo 'Lade die JSON-Datei herunter ';
+ echo 'Gehe zu deinem Gitea Repository ';
+ echo 'Lade die items.json hoch unter: https://git.viper.ipv64.net/M_Viper/WP-Ingame-Shop-Pro ';
+ echo 'Klicke dann auf den Quick-Import Button unten! ';
+ echo ' ';
+ echo '
';
+ return;
+ }
+
+ // Default Gitea URL
+ $default_url = 'https://git.viper.ipv64.net/M_Viper/WP-Ingame-Shop-Pro/raw/branch/main/items.json';
+ ?>
+
+
📦 JSON Export/Import
+
+
+
📤 JSON Export
+
Generiere eine JSON-Datei mit allen deinen Items für Gitea.
+
+
+
+
+
⚡ Quick-Import von Gitea
+
Importiert direkt von deinem Gitea Repository!
+
+
+
+
+ ⚡ Quick-Import starten
+
+
+
+
+
+
📥 JSON Import (Manuelle URL)
+
Importiere Items aus einer beliebigen JSON-URL.
+
+
+
+
+
+
+ ✅ Shop wurde komplett zurückgesetzt!
';
+ }
+
+ ?>
+
+
🔄 Shop Reset
+
+
+
⚠️ WARNUNG
+
Diese Aktion löscht ALLE Daten:
+
+ ❌ Alle Items
+ ❌ Alle Bestellungen
+ ❌ Alle Gutscheine
+ ❌ Alle Server
+ ❌ Alle Kategorien
+
+
Diese Aktion kann NICHT rückgängig gemacht werden!
+
+
+
+
+ get_results("
SELECT player_name, SUM(price) as total_spent, COUNT(*) as order_count
FROM {$wpdb->prefix}wis_orders
- WHERE status = 'completed' OR status = 'cancelled'
+ WHERE status = 'completed'
GROUP BY player_name
ORDER BY total_spent DESC
LIMIT 50
");
- echo '🏆 Top Spender ';
- echo '
Hier siehst du die Spieler, die insgesamt am meisten in deinem Shop ausgegeben haben.
';
-
- echo '
';
- echo 'Rang Spieler Ausgegeben (Total) Anzahl Bestellungen ';
-
- if(empty($results)) {
- echo 'Noch keine Statistiken vorhanden. ';
- } else {
- $rank = 1;
- foreach($results as $row) {
- $total = intval($row->total_spent);
- $count = intval($row->order_count);
- echo '';
- echo '#' . esc_html($rank++) . ' ';
- echo '' . esc_html($row->player_name) . ' ';
- echo '' . esc_html($total) . ' ' . esc_html($currency) . ' ';
- echo '' . esc_html($count) . ' ';
- echo ' ';
- }
- }
-
- echo '
';
- echo '
';
- }
-
- public static function page_orders() {
- global $wpdb;
- $currency = get_option('wis_currency_name', 'Coins');
-
- if(isset($_GET['action']) && isset($_GET['order_id']) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'wis_order_action')) {
- $action = sanitize_text_field($_GET['action']);
- $id = intval($_GET['order_id']);
- if($action === 'delete') { $wpdb->delete($wpdb->prefix.'wis_orders', ['id' => $id]); echo ''; }
- elseif($action === 'complete') { $wpdb->update($wpdb->prefix.'wis_orders', ['status' => 'completed'], ['id' => $id]); echo ''; }
- }
-
- if(isset($_GET['order_id'])) {
- $order = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wis_orders WHERE id = %d", intval($_GET['order_id'])));
- if($order) {
- $status_colors = ['pending' => '#ffc107', 'processing' => '#0073aa', 'completed' => 'green', 'cancelled' => 'red', 'failed' => 'red'];
- $status_labels = ['pending' => 'Warte auf Ingame', 'processing' => 'In Bearbeitung', 'completed' => 'Erledigt', 'cancelled' => 'Abgebrochen', 'failed' => 'Fehler'];
- $status_label = $status_labels[$order->status] ?? $order->status;
- $status_color = $status_colors[$order->status] ?? 'red';
-
- $items_list = 'Keine Daten ';
- $coupon_row = 'Kein Gutschein ';
- $json_data = $order->response;
- $decoded = json_decode($json_data, true);
-
- if(is_array($decoded)) {
- if(isset($decoded['items']) && is_array($decoded['items'])) {
- $items_list = '';
- foreach($decoded['items'] as $item) {
- $amount = isset($item['amount']) ? intval($item['amount']) :1;
- $id = isset($item['id']) ? esc_html($item['id']) : 'Unbekannt';
- $items_list .= "{$amount}x {$id} ";
- }
- $items_list .= ' ';
-
- if(isset($decoded['coupon']) && !empty($decoded['coupon']['code'])) {
- $code = esc_html($decoded['coupon']['code']);
- $disc = intval($decoded['coupon']['discount']);
- $coupon_row = "{$code} (-{$disc} {$currency})";
- }
- } elseif(!empty($decoded)) {
- $items_list = '';
- foreach($decoded as $item) {
- $amount = isset($item['amount']) ? intval($item['amount']) :1;
- $id = isset($item['id']) ? esc_html($item['id']) : 'Unbekannt';
- $items_list .= "{$amount}x {$id} ";
- }
- $items_list .= ' ';
- }
- }
-
- echo 'Bestellung #'.$order->id.' - Details ';
- echo '
← Zurück ';
- echo '
';
- echo 'ID '.$order->id.' ';
- echo 'Datum '.date('d.m.Y H:i', strtotime($order->created_at)).' ';
- echo 'Spieler '.$order->player_name.' ';
- echo 'Server '.$order->server.' ';
- echo 'Zusammenfassung '.esc_html($order->item_title).' ';
- echo 'Gutschein '.$coupon_row.' ';
- echo 'Gekaufte Items '.$items_list.' ';
- echo 'Gesamtpreis '.$order->price.' '.esc_html($currency).' ';
- echo 'Status '.esc_html($status_label).' ';
- echo 'JSON (Debug) '.esc_html($json_data).' ';
- echo '
';
- echo '
';
- return;
- }
- }
-
- $orders = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wis_orders ORDER BY created_at DESC LIMIT 100");
- echo 'Bestellungen ';
- echo '
Datum Spieler Inhalt Preis Status Aktion ';
-
- if(empty($orders)) { echo 'Noch keine Bestellungen vorhanden. '; }
-
- foreach($orders as $o){
- $status_map = ['pending' => 'Warte', 'processing' => 'Geben...', 'completed' => 'Fertig', 'cancelled' => 'Abgebrochen', 'failed' => 'Fehler'];
- $status_label = $status_map[$o->status] ?? $o->status;
- $status_colors = ['pending' => '#ffc107', 'processing' => '#0073aa', 'completed' => 'green', 'cancelled' => 'red', 'failed' => 'red'];
- $status_color = $status_colors[$o->status] ?? 'red';
-
- $delete_url = wp_nonce_url(admin_url('admin.php?page=wis_orders&action=delete&order_id='.$o->id), 'wis_order_action');
- $details_url = admin_url('admin.php?page=wis_orders&order_id='.$o->id);
+ ?>
+
+
🏆 Top Spender
+
Spieler mit den höchsten Gesamtausgaben
- $item_label = strlen($o->item_title) > 50 ? substr($o->item_title, 0, 50).'...' : $o->item_title;
-
- echo '
';
- echo ''.esc_html(date('d.m.Y H:i', strtotime($o->created_at))).' ';
- echo ''.esc_html($o->player_name).' ';
- echo ''.esc_html($item_label).' ';
- echo ''.esc_html($o->price).' '.esc_html($currency).' ';
- echo ''.esc_html($status_label).' ';
- echo '';
- echo '👁️ Details ';
- echo '🗑️ Löschen ';
- echo ' ';
- echo ' ';
- }
- echo '
';
+
+
+
+ Rang
+ Spieler
+ Ausgegeben
+ Bestellungen
+
+
+
+
+ Noch keine Statistiken vorhanden.
+
+
+
+ #
+ player_name); ?>
+ total_spent)); ?>
+ order_count); ?>
+
+
+
+
+
+
+ 'POST','callback'=>[self::class,'create_order'],'permission_callback'=> '__return_true']);
- register_rest_route('wis/v1','/pending_orders', ['methods'=>'GET','callback'=>[self::class,'get_pending_orders'],'permission_callback'=> '__return_true']);
- register_rest_route('wis/v1','/execute_order', ['methods'=>'POST','callback'=>[self::class,'execute_order'],'permission_callback'=> '__return_true']);
- register_rest_route('wis/v1','/complete_order', ['methods'=>'POST','callback'=>[self::class,'complete_order'],'permission_callback'=> '__return_true']);
- register_rest_route('wis/v1','/cancel_order', ['methods'=>'POST','callback'=>[self::class,'cancel_order'],'permission_callback'=> '__return_true']);
- register_rest_route('wis/v1','/fetch_remote_data', ['methods'=>'POST','callback'=>[self::class,'fetch_remote_data'],'permission_callback'=> '__return_true']);
- register_rest_route('wis/v1','/import_batch', ['methods'=>'POST','callback'=>[self::class,'import_batch'],'permission_callback'=> '__return_true']);
- register_rest_route('wis/v1','/validate_coupon', ['methods'=>'POST','callback'=>[self::class,'validate_coupon'],'permission_callback'=> '__return_true']);
- }
-
- public static function create_order($request) {
- global $wpdb;
- $data = $request->get_json_params();
- $player = sanitize_text_field($data['player'] ?? '');
- $cart = $data['cart'] ?? [];
- $server_slug = sanitize_text_field($data['server'] ?? '');
- $coupon_code = isset($data['coupon_code']) ? sanitize_text_field(strtoupper($data['coupon_code'])) : '';
-
- if(!$player || empty($cart) || !$server_slug) { return new WP_REST_Response(['success'=>false,'message'=>'Fehlende Eingabedaten'], 400); }
-
- $exclude_offers_setting = get_option('wis_coupon_exclude_offers', '0');
-
- $valid_cart = [];
- $total_normal = 0;
- $total_offer = 0;
-
- foreach($cart as $item) {
- $post_id = intval($item['id'] ?? 0);
- $qty = intval($item['quantity'] ?? 1);
- if($post_id <= 0 || $qty <= 0) continue;
-
- $price = intval(get_post_meta($post_id, '_wis_price', true));
- $item_servers = get_post_meta($post_id, '_wis_servers', true);
- $is_offer = get_post_meta($post_id, '_wis_is_offer', true);
-
- if(!is_array($item_servers)) $item_servers = [];
- if($price <= 0) continue;
- if(!in_array($server_slug, $item_servers)) continue;
-
- $offer_price = intval(get_post_meta($post_id, '_wis_offer_price', true));
- $display_price = ($offer_price > 0) ? $offer_price : $price;
-
- $real_item_id = get_post_meta($post_id, '_wis_item_id', true);
-
- $valid_cart[] = [
- 'id' => $post_id,
- 'title' => get_the_title($post_id),
- 'price' => $display_price,
- 'qty' => $qty,
- 'is_offer' => $is_offer,
- 'real_item_id' => $real_item_id
- ];
-
- $item_total = $display_price * $qty;
-
- if($is_offer && $exclude_offers_setting) {
- $total_offer += $item_total;
- } else {
- $total_normal += $item_total;
- }
- }
-
- if(empty($valid_cart)) return new WP_REST_Response(['success'=>false,'message'=>'Keine gültigen Items im Warenkorb.'], 400);
-
- // Gutschein Logik
- $coupon_discount = 0;
- $coupon_msg = '';
- $coupon_applied = false;
- $currency = get_option('wis_currency_name', 'Coins');
-
- if(!empty($coupon_code)) {
- $coupon = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wis_coupons WHERE code = %s", $coupon_code));
-
- if($coupon) {
- // Basis Checks
- if($coupon->expiry && date('Y-m-d') > $coupon->expiry) {
- $coupon_msg = 'Gutschein abgelaufen.';
- } elseif($coupon->used_count >= $coupon->usage_limit) {
- $coupon_msg = 'Gutschein wurde zu oft verwendet.';
- } else {
- // Prüfen ob Gutschein angewendet werden darf
- $apply_coupon = false;
- $calculate_discount = false;
-
- if($exclude_offers_setting === '1') {
- if($total_normal > 0) {
- $apply_coupon = true;
- }
- } else {
- if($total_normal > 0 || $total_offer > 0) {
- $apply_coupon = true;
- }
- }
-
- if($apply_coupon) {
- $calculate_discount = true;
- }
- }
- } else {
- $coupon_msg = 'Ungültiger Gutscheincode.';
- }
- }
-
- // Wenn angewendet, berechnen
- if($calculate_discount) {
- $coupon_type = $coupon->type;
- if($coupon_type === 'percent') {
- $coupon_discount = $total_normal * ($coupon->value / 100);
- $coupon_msg = "Gutschein eingelöst: -{$coupon->value}% (-{$coupon_discount} {$currency})";
- } else {
- $coupon_discount = $coupon->value;
- $coupon_msg = "Gutschein eingelöst: -{$coupon_discount} {$currency}";
- }
-
- // Aufrunden
- $coupon_discount = floor($coupon_discount);
-
- $wpdb->update($wpdb->prefix.'wis_coupons', ['used_count' => $coupon->used_count + 1], ['id' => $coupon->id]);
- $coupon_applied = true;
- }
-
- $final_normal = max(0, $total_normal - $coupon_discount);
- $final_price = $final_normal + $total_offer;
-
- // Speichern in DB
- $items_payload = [];
- $title_parts = [];
-
- foreach($valid_cart as $item) {
- $items_payload[] = [
- 'id' => $item['real_item_id'],
- 'amount' => $item['qty']
- ];
- $title_parts[] = $item['qty'] . 'x ' . $item['title'];
- }
-
- $readable_title = "Warenkorb: " . implode(', ', $title_parts);
- if (strlen($readable_title) > 240) $readable_title = substr($readable_title, 0, 237) . '...';
-
- $coupon_data = [];
- if($coupon_applied) {
- $coupon_data = [
- 'code' => $coupon_code,
- 'discount' => $coupon_discount
- ];
- }
-
- $json_payload = json_encode([
- 'items' => $items_payload,
- 'coupon' => $coupon_data
+ register_rest_route('wis/v1', '/import_json', [
+ 'methods' => 'POST',
+ 'callback' => [self::class, 'import_json'],
+ 'permission_callback' => '__return_true'
]);
- $inserted = $wpdb->insert($wpdb->prefix.'wis_orders', [
- 'player_name' => $player,
- 'server' => $server_slug,
- 'item_id' => 'multi_item_cart',
- 'item_title' => $readable_title,
- 'price' => $final_price,
- 'quantity' => count($valid_cart),
- 'status' => 'pending',
- 'response' => $json_payload,
- 'created_at' => current_time('mysql')
+ register_rest_route('wis/v1', '/order', [
+ 'methods' => 'POST',
+ 'callback' => [self::class, 'create_order'],
+ 'permission_callback' => '__return_true'
+ ]);
+
+ register_rest_route('wis/v1', '/validate_coupon', [
+ 'methods' => 'POST',
+ 'callback' => [self::class, 'validate_coupon'],
+ 'permission_callback' => '__return_true'
+ ]);
+
+ // =================== SPIGOT COMPATIBILITY ROUTES ===================
+
+ // Get pending orders for a specific player (called by Spigot plugin)
+ register_rest_route('wis/v1', '/pending_orders', [
+ 'methods' => 'GET',
+ 'callback' => [self::class, 'get_pending_orders'],
+ 'permission_callback' => '__return_true'
+ ]);
+
+ // Execute order (called when player clicks Yes in Spigot GUI)
+ register_rest_route('wis/v1', '/execute_order', [
+ 'methods' => 'POST',
+ 'callback' => [self::class, 'execute_order'],
+ 'permission_callback' => '__return_true'
+ ]);
+
+ // Complete order (called after items given in Spigot)
+ register_rest_route('wis/v1', '/complete_order', [
+ 'methods' => 'POST',
+ 'callback' => [self::class, 'complete_order'],
+ 'permission_callback' => '__return_true'
+ ]);
+
+ // Cancel order (called when player clicks No in Spigot GUI)
+ register_rest_route('wis/v1', '/cancel_order', [
+ 'methods' => 'POST',
+ 'callback' => [self::class, 'cancel_order'],
+ 'permission_callback' => '__return_true'
]);
-
- if($inserted) {
- $msg = '✅ Bestellung erfolgreich erstellt!';
- if($coupon_msg) $msg .= ' ('.$coupon_msg.')';
- return new WP_REST_Response(['success'=>true,'message'=>$msg], 200);
- } else {
- return new WP_REST_Response(['success'=>false,'message'=>'Fehler beim Speichern.'], 500);
- }
}
-
- public static function validate_coupon($request) {
- global $wpdb;
- $data = $request->get_json_params();
- $code = sanitize_text_field(strtoupper($data['code'] ?? ''));
- $cart = $data['cart'] ?? [];
- $currency = get_option('wis_currency_name', 'Coins');
-
- if(!$code) {
- return new WP_REST_Response(['success'=>false, 'message'=>'Kein Code angegeben']);
- }
- $coupon = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wis_coupons WHERE code = %s", $code));
-
- if(!$coupon) {
- return new WP_REST_Response(['success'=>false, 'message'=>'Gutschein nicht gefunden']);
- }
- if($coupon->expiry && date('Y-m-d') > $coupon->expiry) {
- return new WP_REST_Response(['success'=>false, 'message'=>'Gutschein abgelaufen']);
- }
- if($coupon->used_count >= $coupon->usage_limit) {
- return new WP_REST_Response(['success'=>false, 'message'=>'Dieser Gutschein wurde bereits maximal eingelöst']);
- }
-
- $exclude_offers_setting = get_option('wis_coupon_exclude_offers', '0');
-
- if($exclude_offers_setting === '1' && !empty($cart)) {
- $has_normal_items = false;
- foreach($cart as $item) {
- $post_id = intval($item['id'] ?? 0);
- $is_offer = get_post_meta($post_id, '_wis_is_offer', true);
- if(empty($is_offer) || $is_offer == 0) {
- $has_normal_items = true;
- break;
- }
- }
-
- if(!$has_normal_items) {
- return new WP_REST_Response(['success'=>false, 'message'=>'⚠️ Dieser Gutschein gilt nicht für Angebote.']);
- }
- }
-
- $message = '';
- if($coupon->type === 'percent') {
- $message = "Gutschein gültig (-{$coupon->value}%)";
- } else {
- $message = "Gutschein gültig (-{$coupon->value} {$currency})";
- }
-
- return new WP_REST_Response(['success'=>true, 'type'=>$coupon->type, 'value'=>$coupon->value, 'message'=>$message]);
- }
-
+
+ // --- SPIGOT ENDPOINTS ---
+
public static function get_pending_orders($request) {
global $wpdb;
$player = sanitize_text_field($request->get_param('player'));
- if(!$player) return new WP_REST_Response(['orders'=>[]]);
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wis_orders WHERE player_name = %s AND status = 'pending' ORDER BY created_at ASC LIMIT 10", $player));
+
+ if (!$player) {
+ return new WP_REST_Response(['orders' => []]);
+ }
+
+ $results = $wpdb->get_results($wpdb->prepare(
+ "SELECT * FROM {$wpdb->prefix}wis_orders WHERE player_name = %s AND status = 'pending' ORDER BY created_at ASC LIMIT 10",
+ $player
+ ));
+
return new WP_REST_Response(['orders' => $results]);
}
@@ -1116,580 +1574,786 @@ class WIS_API {
global $wpdb;
$data = $request->get_json_params();
$id = intval($data['id'] ?? 0);
- if(!$id) return new WP_REST_Response(['success'=>false], 400);
- $order = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wis_orders WHERE id = %d", $id));
- if($order) {
- $wpdb->update($wpdb->prefix.'wis_orders', ['status' => 'processing'], ['id' => $id]);
- return new WP_REST_Response(['success'=>true]);
- }
- return new WP_REST_Response(['success'=>false], 400);
+ if (!$id) return new WP_REST_Response(['success' => false], 400);
+
+ $wpdb->update(
+ $wpdb->prefix . 'wis_orders',
+ ['status' => 'processing'],
+ ['id' => $id]
+ );
+
+ return new WP_REST_Response(['success' => true]);
}
public static function complete_order($request) {
global $wpdb;
$data = $request->get_json_params();
$id = intval($data['id'] ?? 0);
- if(!$id) return new WP_REST_Response(['success'=>false], 400);
- $wpdb->update($wpdb->prefix.'wis_orders', ['status' => 'completed'], ['id' => $id]);
- return new WP_REST_Response(['success'=>true]);
+ if (!$id) return new WP_REST_Response(['success' => false], 400);
+
+ $wpdb->update(
+ $wpdb->prefix . 'wis_orders',
+ ['status' => 'completed'],
+ ['id' => $id]
+ );
+
+ return new WP_REST_Response(['success' => true]);
}
public static function cancel_order($request) {
global $wpdb;
$data = $request->get_json_params();
$id = intval($data['id'] ?? 0);
- if(!$id) return new WP_REST_Response(['success'=>false], 400);
- $updated = $wpdb->update($wpdb->prefix.'wis_orders', ['status' => 'cancelled'], ['id' => $id]);
+ if (!$id) return new WP_REST_Response(['success' => false], 400);
- if($updated !== false) {
- return new WP_REST_Response(['success'=>true]);
- }
- return new WP_REST_Response(['success'=>false], 400);
+ $wpdb->update(
+ $wpdb->prefix . 'wis_orders',
+ ['status' => 'cancelled'],
+ ['id' => $id]
+ );
+
+ return new WP_REST_Response(['success' => true]);
}
-
- public static function fetch_remote_data($request) {
- $url = esc_url_raw($request->get_json_params()['url']);
+
+ // --- EXISTING ENDPOINTS ---
+
+ public static function import_json($request) {
+ $data = $request->get_json_params();
+ $url = esc_url_raw($data['url'] ?? '');
+
+ if (!$url) {
+ return new WP_REST_Response(['success' => false, 'message' => 'Keine URL angegeben'], 400);
+ }
+
$response = wp_remote_get($url, ['timeout' => 30]);
- if(is_wp_error($response)) return new WP_REST_Response(['success'=>false, 'message'=>$response->get_error_message()], 400);
- $body = wp_remote_retrieve_body($response);
- $data = json_decode($body, true);
- $import_data = [];
- if (isset($data['items']) && is_array($data['items'])) { $import_data = $data['items']; } elseif (is_array($data)) { $import_data = $data; }
- if(empty($import_data)) return new WP_REST_Response(['success'=>false, 'message'=>'Keine gültigen Daten gefunden'], 400);
- return new WP_REST_Response(['success'=>true, 'items' => $import_data]);
- }
-
- public static function import_batch($request) {
- $items = $request->get_json_params()['items'] ?? [];
- if(!is_array($items) || empty($items)) return new WP_REST_Response(['success'=>false], 400);
- set_time_limit(300);
- $processed = 0; $skipped = 0;
- foreach($items as $item) {
- $item_id_val = $item['id'] ?? ''; $title_val = $item['name'] ?? 'Unbekannt';
- if(empty($item_id_val)) continue;
- $exists = get_posts(['post_type' => 'wis_item', 'meta_key' => '_wis_item_id', 'meta_value' => $item_id_val, 'posts_per_page' => 1]);
- if($exists) { $skipped++; continue; }
- $new_post_id = wp_insert_post(['post_title' => $title_val, 'post_content' => '', 'post_type' => 'wis_item', 'post_status' => 'draft', 'meta_input' => ['_wis_item_id' => $item_id_val, '_wis_price' => 0]]);
- if(!is_wp_error($new_post_id)) $processed++;
+
+ if (is_wp_error($response)) {
+ return new WP_REST_Response(['success' => false, 'message' => $response->get_error_message()], 400);
}
- return new WP_REST_Response(['success'=>true, 'processed' => $processed, 'skipped' => $skipped]);
+
+ $body = wp_remote_retrieve_body($response);
+ $json = json_decode($body, true);
+
+ if (!isset($json['items']) || !is_array($json['items'])) {
+ return new WP_REST_Response(['success' => false, 'message' => 'Ungültiges JSON Format'], 400);
+ }
+
+ $imported = 0;
+ $skipped = 0;
+
+ foreach ($json['items'] as $item) {
+ $item_id = sanitize_text_field($item['id'] ?? '');
+ $name = sanitize_text_field($item['name'] ?? 'Unbekannt');
+
+ if (empty($item_id)) continue;
+
+ $exists = WIS_DB::get_item_by_item_id($item_id);
+
+ if ($exists) {
+ $skipped++;
+ continue;
+ }
+
+ WIS_DB::insert_item([
+ 'item_id' => $item_id,
+ 'name' => $name,
+ 'description' => sanitize_textarea_field($item['description'] ?? ''),
+ 'price' => intval($item['price'] ?? 0),
+ 'status' => intval($item['price'] ?? 0) > 0 ? 'publish' : 'draft',
+ 'servers' => '[]',
+ 'categories' => '[]'
+ ]);
+
+ $imported++;
+ }
+
+ return new WP_REST_Response(['success' => true, 'imported' => $imported, 'skipped' => $skipped]);
+ }
+
+ public static function create_order($request) {
+ global $wpdb;
+ $data = $request->get_json_params();
+
+ $player = sanitize_text_field($data['player'] ?? '');
+ $cart = $data['cart'] ?? [];
+ $server = sanitize_text_field($data['server'] ?? '');
+ $coupon_code = isset($data['coupon_code']) ? sanitize_text_field(strtoupper($data['coupon_code'])) : '';
+
+ if (!$player || empty($cart) || !$server) {
+ return new WP_REST_Response(['success' => false, 'message' => 'Fehlende Daten'], 400);
+ }
+
+ $exclude_offers = get_option('wis_coupon_exclude_offers', '0');
+ $currency = get_option('wis_currency_name', 'Coins');
+
+ $valid_cart = [];
+ $total_normal = 0;
+ $total_offer = 0;
+
+ foreach ($cart as $item_data) {
+ $item = WIS_DB::get_item(intval($item_data['id'] ?? 0));
+ if (!$item || $item->status !== 'publish') continue;
+
+ $qty = intval($item_data['quantity'] ?? 1);
+ if ($qty <= 0) continue;
+
+ $servers = json_decode($item->servers, true);
+ if (!in_array($server, $servers ?: [])) continue;
+
+ $price = $item->offer_price > 0 ? $item->offer_price : $item->price;
+
+ $valid_cart[] = [
+ 'id' => $item->item_id, // Important: Spigot needs the item ID (e.g., minecraft:diamond)
+ 'title' => $item->name,
+ 'price' => $price,
+ 'qty' => $qty,
+ 'is_offer' => $item->is_offer
+ ];
+
+ $item_total = $price * $qty;
+
+ if ($item->is_offer && $exclude_offers === '1') {
+ $total_offer += $item_total;
+ } else {
+ $total_normal += $item_total;
+ }
+ }
+
+ if (empty($valid_cart)) {
+ return new WP_REST_Response(['success' => false, 'message' => 'Keine gültigen Items'], 400);
+ }
+
+ // Coupon validation
+ $coupon_discount = 0;
+ $coupon_msg = '';
+ $coupon_applied = false;
+
+ if (!empty($coupon_code)) {
+ $coupon = WIS_DB::get_coupon_by_code($coupon_code);
+
+ if ($coupon) {
+ if ($coupon->expiry && date('Y-m-d') > $coupon->expiry) {
+ $coupon_msg = 'Gutschein abgelaufen';
+ } elseif ($coupon->used_count >= $coupon->usage_limit) {
+ $coupon_msg = 'Gutschein bereits aufgebraucht';
+ } else {
+ if ($exclude_offers === '1' && $total_normal <= 0) {
+ $coupon_msg = 'Gutschein gilt nicht für Angebote';
+ } else {
+ if ($coupon->type === 'percent') {
+ $coupon_discount = floor($total_normal * ($coupon->value / 100));
+ } else {
+ $coupon_discount = $coupon->value;
+ }
+
+ WIS_DB::update_coupon($coupon->id, ['used_count' => $coupon->used_count + 1]);
+ $coupon_applied = true;
+ $coupon_msg = "Gutschein eingelöst: -{$coupon_discount} {$currency}";
+ }
+ }
+ } else {
+ $coupon_msg = 'Ungültiger Code';
+ }
+ }
+
+ $final_price = max(0, $total_normal - $coupon_discount) + $total_offer;
+
+ // Build order
+ $items_payload = [];
+ $title_parts = [];
+
+ foreach ($valid_cart as $item) {
+ $items_payload[] = [
+ 'id' => $item['id'], // minecraft:diamond
+ 'amount' => $item['qty']
+ ];
+ $title_parts[] = $item['qty'] . 'x ' . $item['title'];
+ }
+
+ $title = "Warenkorb: " . implode(', ', $title_parts);
+ if (strlen($title) > 240) $title = substr($title, 0, 237) . '...';
+
+ $payload = [
+ 'items' => $items_payload,
+ 'coupon' => $coupon_applied ? ['code' => $coupon_code, 'discount' => $coupon_discount] : []
+ ];
+
+ WIS_DB::insert_order([
+ 'player_name' => $player,
+ 'server' => $server,
+ 'item_id' => 'cart',
+ 'item_title' => $title,
+ 'price' => $final_price,
+ 'quantity' => count($valid_cart),
+ 'status' => 'pending',
+ 'response' => json_encode($payload)
+ ]);
+
+ $msg = '✅ Bestellung erfolgreich!';
+ if ($coupon_msg) $msg .= ' (' . $coupon_msg . ')';
+
+ return new WP_REST_Response(['success' => true, 'message' => $msg]);
+ }
+
+ public static function validate_coupon($request) {
+ $data = $request->get_json_params();
+ $code = sanitize_text_field(strtoupper($data['code'] ?? ''));
+ $cart = $data['cart'] ?? [];
+
+ if (!$code) {
+ return new WP_REST_Response(['success' => false, 'message' => 'Kein Code']);
+ }
+
+ $coupon = WIS_DB::get_coupon_by_code($code);
+
+ if (!$coupon) {
+ return new WP_REST_Response(['success' => false, 'message' => 'Gutschein nicht gefunden']);
+ }
+
+ if ($coupon->expiry && date('Y-m-d') > $coupon->expiry) {
+ return new WP_REST_Response(['success' => false, 'message' => 'Gutschein abgelaufen']);
+ }
+
+ if ($coupon->used_count >= $coupon->usage_limit) {
+ return new WP_REST_Response(['success' => false, 'message' => 'Bereits aufgebraucht']);
+ }
+
+ $exclude_offers = get_option('wis_coupon_exclude_offers', '0');
+
+ if ($exclude_offers === '1' && !empty($cart)) {
+ $has_normal = false;
+ foreach ($cart as $item_data) {
+ $item = WIS_DB::get_item(intval($item_data['id'] ?? 0));
+ if ($item && !$item->is_offer) {
+ $has_normal = true;
+ break;
+ }
+ }
+
+ if (!$has_normal) {
+ return new WP_REST_Response(['success' => false, 'message' => 'Gutschein gilt nicht für Angebote']);
+ }
+ }
+
+ $currency = get_option('wis_currency_name', 'Coins');
+ $msg = $coupon->type === 'percent'
+ ? "Gutschein gültig (-{$coupon->value}%)"
+ : "Gutschein gültig (-{$coupon->value} {$currency})";
+
+ return new WP_REST_Response([
+ 'success' => true,
+ 'type' => $coupon->type,
+ 'value' => $coupon->value,
+ 'message' => $msg
+ ]);
}
}
// ===========================================================
-// 5. SHORTCODE
+// SHORTCODE - FRONTEND SHOP
// ===========================================================
class WIS_Shortcode {
- public static function register_shortcode() {
- add_shortcode('ingame_shop_form', [self::class, 'render_form']);
+ public static function register() {
+ add_shortcode('ingame_shop_form', [self::class, 'render']);
}
-
- public static function render_form() {
- $servers = get_posts(['post_type'=>'wis_server','numberposts'=>-1]);
- $items = get_posts(['post_type'=>'wis_item','numberposts'=>-1]);
+
+ public static function render() {
+ $servers = WIS_DB::get_servers();
+ $items = WIS_DB::get_items(['status' => 'publish']);
+ $categories = WIS_DB::get_categories();
$currency = get_option('wis_currency_name', 'Coins');
- $img_base = get_option('wis_image_base_url', 'https://assets.minecraft-ids.com/1_21_10/');
- $header_text = get_option('wis_header_text', '✅ Auto-Bilder | 💰 Sicherer Checkout');
+ $img_base = get_option('wis_image_base_url', '');
+ $header_text = get_option('wis_header_text', '');
$exclude_offers = get_option('wis_coupon_exclude_offers', '0');
- // NEU: Kategorien
- $categories = get_terms(['taxonomy'=>'wis_category', 'hide_empty'=>true]);
-
ob_start();
?>
-
+
+
-
+
-
-
-
+
+
+
Alle
-
- =esc_html($cat->name)?>
+
+ name); ?>
-
-
-
-
Keine Items im Shop verfügbar.
-
- ID, '_wis_servers', true);
- if(!is_array($item_servers)) $item_servers = [];
- $price = get_post_meta($item->ID, '_wis_price', true);
- $item_id_code = get_post_meta($item->ID, '_wis_item_id', true);
- $item_desc = $item->post_content;
-
- $is_offer = get_post_meta($item->ID, '_wis_is_offer', true);
- $is_daily_deal = get_post_meta($item->ID, '_wis_daily_deal', true);
- $offer_price = get_post_meta($item->ID, '_wis_offer_price', true);
- $display_price = ($offer_price > 0) ? $offer_price : $price;
- $show_old_price = ($offer_price > 0 && $offer_price != $price);
-
- // NEU: Kategorien
- $item_cats = wp_get_post_terms($item->ID, 'wis_category');
- $cat_ids = array_map(function($t) { return $t->term_id; }, $item_cats);
- $cat_data = json_encode($cat_ids);
-
- $img_name = str_replace(':', '_', $item_id_code) . '.png';
- $full_img_url = $img_base . $img_name;
-
- $server_names = [];
- foreach($item_servers as $slug) {
- $srv = get_page_by_path($slug, OBJECT, 'wis_server');
- if($srv) $server_names[] = $srv->post_title;
- }
- $servers_display = !empty($server_names) ? implode(', ', $server_names) : 'Kein Server';
- $servers_data = json_encode($item_servers);
- ?>
-
-
-
🎁 Angebot des Tages
-
🔥 Angebot
-
-
-
-
-
-
=esc_html($item->post_title)?>
-
-
-
=esc_html($price)?> =esc_html($currency)?>
-
=esc_html($display_price)?> =esc_html($currency)?>
-
-
-
📡 =esc_html($servers_display)?>
-
-
-
⚠️ Gutschein ungültig
-
-
-
- -
-
- +
-
-
-
- ➕ In den Warenkorb
-
-
+
+
+
+
+
+ Keine Items im Shop verfügbar.
-
+
+ servers, true) ?: [];
+ $cats_arr = json_decode($item->categories, true) ?: [];
+ $price = $item->offer_price > 0 ? $item->offer_price : $item->price;
+ $show_old = $item->offer_price > 0 && $item->offer_price != $item->price;
+
+ $img_name = str_replace(':', '_', $item->item_id) . '.png';
+ $img_url = $img_base . $img_name;
+
+ $server_names = [];
+ foreach ($servers_arr as $slug) {
+ foreach ($servers as $s) {
+ if ($s->slug === $slug) {
+ $server_names[] = $s->name;
+ break;
+ }
+ }
+ }
+ $servers_display = !empty($server_names) ? implode(', ', $server_names) : 'Kein Server';
+ ?>
+
+
+ is_daily_deal): ?>
+
🎁 Angebot des Tages
+ is_offer): ?>
+
🔥 Angebot
+
+
+
+
+
+
+
+
+ name); ?>
+
+
+ description): ?>
+
description); ?>
+
+
+
+
+
📡
+
+
+ -
+
+ +
+
+
+
+ ➕ In den Warenkorb
+
+
+
+
+
-
-
+
+
🛒 Dein Warenkorb
-
Dein Warenkorb ist leer
+
Dein Warenkorb ist leer
-
-
-
🎫 Gutscheincode (Optional)
+
+
🎫 Gutscheincode
-
- Einlösen
+
+ Einlösen
-
+
-
- Gesamt:
- 0 =esc_html($currency)?>
-
+
Gesamt:
+
0
-
-
+
+
-- Server wählen --
-
- =esc_html($s->post_title)?>
+
+ name); ?>
-
-
-
+
+
+
💰 Kauf abschließen
Abbrechen
+
-
+
'Zeigt das aktuelle Angebot oder Daily Deal an mit anpassbarem Link.' ) // Args
+ 'wis_sidebar_offer',
+ 'WIS Shop Angebot',
+ ['description' => 'Zeigt Daily Deal oder Angebot an']
);
}
-
- // Backend: Formular im Widget-Bereich
- public function form( $instance ) {
- // Standardwerte definieren
- $defaults = [
- 'title' => '🔥 Angebot des Tages',
- 'btn_text' => 'Zum Shop',
- 'shop_url' => ''
- ];
- // Werte mergen (falls noch nichts gespeichert wurde)
- $instance = wp_parse_args( (array) $instance, $defaults );
-
- ?>
-
- Titel:
-
-
-
-
- Button Text:
-
- Standard: "Zum Shop"
-
-
-
- Shop URL (Link Ziel):
-
- Wenn leer, wird zur Startseite verlinkt.
-
- '🔥 Angebot des Tages',
- 'btn_text' => 'Zum Shop',
- 'shop_url' => ''
- ];
- $instance = wp_parse_args( (array) $instance, $defaults );
-
- if ( ! empty( $instance['title'] ) ) {
- echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
- }
-
- $currency = get_option('wis_currency_name', 'Coins');
- $img_base = get_option('wis_image_base_url', 'https://assets.minecraft-ids.com/1_21.10/');
- // 1. Suche Daily Deal (Prio 1)
- $daily_deal = get_posts([
- 'post_type' => 'wis_item',
- 'posts_per_page' => 1,
- 'meta_key' => '_wis_daily_deal',
- 'meta_value' => 1
- ]);
-
- $item = null;
- $is_daily = false;
-
- if (!empty($daily_deal)) {
- $item = $daily_deal[0];
- $is_daily = true;
- } else {
- // 2. Fallback: Suche normales Angebot (Prio 2)
- $offers = get_posts([
- 'post_type' => 'wis_item',
- 'posts_per_page' => 1,
- 'meta_key' => '_wis_is_offer',
- 'meta_value' => 1,
- 'orderby' => 'modified',
- 'order' => 'DESC'
- ]);
- if (!empty($offers)) {
- $item = $offers[0];
- }
+ if (!empty($instance['title'])) {
+ echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
}
-
- // Ziel-URL für den Button bestimmen
- $target_url = !empty($instance['shop_url']) ? $instance['shop_url'] : home_url();
-
+
+ global $wpdb;
+ $currency = get_option('wis_currency_name', 'Coins');
+ $img_base = get_option('wis_image_base_url', '');
+
+ // Try daily deal first
+ $item = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}wis_items WHERE is_daily_deal = 1 AND status = 'publish' LIMIT 1");
+
+ // Fallback to regular offer
+ if (!$item) {
+ $item = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}wis_items WHERE is_offer = 1 AND status = 'publish' ORDER BY updated_at DESC LIMIT 1");
+ }
+
if ($item) {
- $price = get_post_meta($item->ID, '_wis_price', true);
- $offer_price = get_post_meta($item->ID, '_wis_offer_price', true);
- $item_id_code = get_post_meta($item->ID, '_wis_item_id', true);
+ $price = $item->offer_price > 0 ? $item->offer_price : $item->price;
+ $show_old = $item->offer_price > 0 && $item->offer_price != $item->price;
+ $img_name = str_replace(':', '_', $item->item_id) . '.png';
+ $img_url = $img_base . $img_name;
+ $target_url = !empty($instance['shop_url']) ? $instance['shop_url'] : home_url();
- $final_price = ($offer_price > 0) ? $offer_price : $price;
- $show_old_price = ($offer_price > 0 && $offer_price < $price);
-
- // Bild URL generieren
- $img_name = str_replace(':', '_', $item_id_code) . '.png';
- $full_img_url = $img_base . $img_name;
-
- // Modernes Card Design
?>
-
-
-
+
-
-
🎁 DAILY DEAL
- 0): ?>
-
🔥 ANGEBOT
+ is_daily_deal): ?>
+
🎁 DAILY DEAL
+ is_offer): ?>
+
🔥 ANGEBOT
-
-
+
-
-
-
post_title); ?>
-
-
-
-
+
name); ?>
+
+
+ price); ?>
-
+
-
-
-
- 🛒
+
+ 🛒
-
-
Kein Angebot verfügbar.
';
}
-
+
echo $args['after_widget'];
}
+
+ public function form($instance) {
+ $title = !empty($instance['title']) ? $instance['title'] : '🔥 Angebot des Tages';
+ $btn_text = !empty($instance['btn_text']) ? $instance['btn_text'] : 'Zum Shop';
+ $shop_url = !empty($instance['shop_url']) ? $instance['shop_url'] : '';
+ ?>
+
+ Titel:
+
+
+
+ Button Text:
+
+
+
+ Shop URL:
+
+
+
+add_action('wis_daily_deal_event', [WIS_Activator::class, 'run_daily_deal']);
\ No newline at end of file