diff --git a/wp-ingame-shop/wp-ingame-shop-pro.php b/wp-ingame-shop/wp-ingame-shop-pro.php
index 066e818..739ec80 100644
--- a/wp-ingame-shop/wp-ingame-shop-pro.php
+++ b/wp-ingame-shop/wp-ingame-shop-pro.php
@@ -227,6 +227,14 @@ add_action('admin_notices', [WIS_Dashboard::class, 'show_update_notice']);
// ===========================================================
class WIS_Activator {
public static function activate() {
+ // Spalte custom_image_url nachrüsten (für bestehende Installationen)
+ global $wpdb;
+ $table = $wpdb->prefix . 'wis_items';
+ $col = $wpdb->get_var("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = '$table' AND COLUMN_NAME = 'custom_image_url'");
+ if (!$col) {
+ $wpdb->query("ALTER TABLE $table ADD COLUMN custom_image_url varchar(500) DEFAULT NULL AFTER categories");
+ }
+
self::create_tables();
self::set_default_options();
self::create_default_categories();
@@ -260,6 +268,7 @@ class WIS_Activator {
is_daily_deal tinyint(1) DEFAULT 0,
servers text,
categories text,
+ custom_image_url varchar(500) DEFAULT NULL,
status varchar(20) DEFAULT 'draft',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
@@ -775,6 +784,20 @@ class WIS_Item_Categorizer {
// DATABASE HELPER
// ===========================================================
class WIS_DB {
+
+ /**
+ * Gibt die Bild-URL eines Items zurück.
+ * Priorität: custom_image_url > automatisch generierte URL aus item_id.
+ */
+ public static function get_item_image($item) {
+ if (!empty($item->custom_image_url)) {
+ return esc_url($item->custom_image_url);
+ }
+ $img_base = get_option('wis_image_base_url', '');
+ $img_name = str_replace(':', '_', $item->item_id) . '.png';
+ return $img_base . $img_name;
+ }
+
public static function get_items($args = []) {
global $wpdb;
$table = $wpdb->prefix . 'wis_items';
@@ -836,11 +859,11 @@ class WIS_DB {
$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",
+ "SELECT * FROM {$wpdb->prefix}wis_items WHERE item_id = %s",
$item_id
));
}
@@ -1448,28 +1471,79 @@ class WIS_Admin {
if (isset($_POST['wis_save_item'])) {
check_admin_referer('wis_item_form');
-
- $data = [
- 'item_id' => sanitize_text_field($_POST['item_id']),
- 'name' => sanitize_text_field($_POST['name']),
- 'description' => sanitize_textarea_field($_POST['description']),
- 'price' => intval($_POST['price']),
- 'offer_price' => intval($_POST['offer_price']),
- 'is_offer' => isset($_POST['is_offer']) ? 1 : 0,
- 'servers' => isset($_POST['servers']) ? json_encode($_POST['servers']) : '[]',
- 'categories' => isset($_POST['categories']) ? json_encode($_POST['categories']) : '[]',
- 'status' => intval($_POST['price']) > 0 ? 'publish' : 'draft'
- ];
-
- if (isset($_GET['edit'])) {
- WIS_DB::update_item(intval($_GET['edit']), $data);
- echo '
@@ -1576,7 +1760,7 @@ class WIS_Admin {
$per_page = 24;
$current_page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
- $fetch_args = ['status' => 'publish'];
+ $fetch_args = []; // kein Status-Filter → alle Items zählen
if (!empty($current_category)) $fetch_args['category_slug'] = $current_category;
if (!empty($search_query)) $fetch_args['search'] = $search_query;
@@ -1587,21 +1771,28 @@ class WIS_Admin {
global $wpdb;
$table_items = $wpdb->prefix . 'wis_items';
- $where_parts = ["status = 'publish'"];
+ // Admin-Liste: alle Items anzeigen (publish + draft), Query ohne doppeltes prepare()
+ $where_parts = [];
+ $where_vals = [];
if (!empty($current_category)) {
- $search_pattern = '%"' . $current_category . '"%';
- $where_parts[] = $wpdb->prepare("categories LIKE %s", $search_pattern);
+ $where_parts[] = "categories LIKE %s";
+ $where_vals[] = '%"' . $wpdb->esc_like($current_category) . '"%';
}
if (!empty($search_query)) {
- $search_like = '%' . $wpdb->esc_like($search_query) . '%';
- $where_parts[] = $wpdb->prepare("(name LIKE %s OR item_id LIKE %s)", $search_like, $search_like);
+ $like = '%' . $wpdb->esc_like($search_query) . '%';
+ $where_parts[] = "(name LIKE %s OR item_id LIKE %s)";
+ $where_vals[] = $like;
+ $where_vals[] = $like;
}
- $where_sql = implode(" AND ", $where_parts);
- $items = $wpdb->get_results($wpdb->prepare(
- "SELECT * FROM $table_items WHERE $where_sql ORDER BY name ASC LIMIT %d OFFSET %d",
- $per_page,
- $offset
- ));
+ $where_sql = !empty($where_parts) ? 'WHERE ' . implode(' AND ', $where_parts) : '';
+ $where_vals[] = $per_page;
+ $where_vals[] = $offset;
+ $items = $wpdb->get_results(
+ $wpdb->prepare(
+ "SELECT * FROM $table_items $where_sql ORDER BY name ASC LIMIT %d OFFSET %d",
+ $where_vals
+ )
+ );
$currency = get_option('wis_currency_name', 'Coins');
@@ -1717,7 +1908,19 @@ class WIS_Admin {
| id); ?> |
name); ?> |
- item_id); ?> |
+
+ item_id, $rm2)) {
+ $rd = intval($rm2[4]);
+ echo '👑 LP: ' . esc_html($rm2[2]) . ' — ' . ($rd === 0 ? 'dauerhaft' : esc_html($rd) . ' Tage') . '';
+ } elseif (preg_match('/^rank_(.+)_(\d+)$/', $item->item_id, $rm2)) {
+ $rd = intval($rm2[2]);
+ echo '👑 ' . esc_html($rm2[1]) . ' — ' . ($rd === 0 ? 'dauerhaft' : esc_html($rd) . ' Tage') . '';
+ } else {
+ echo '' . esc_html($item->item_id) . '';
+ }
+ ?>
+ |
price); ?> |
status === 'publish'): ?>
@@ -2171,13 +2374,12 @@ class WIS_Admin {
$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
+ 'image' => WIS_DB::get_item_image($item)
];
}
@@ -2501,7 +2703,6 @@ class WIS_API {
$result = [];
foreach ($items as $item) {
- $img_name = str_replace(':', '_', $item->item_id) . '.png';
$result[] = [
'id' => $item->id,
'item_id' => $item->item_id,
@@ -2513,10 +2714,20 @@ class WIS_API {
'is_daily_deal' => (bool) $item->is_daily_deal,
'servers' => json_decode($item->servers, true) ?: [],
'categories' => json_decode($item->categories, true) ?: [],
- 'image' => $img_base . $img_name,
+ 'image' => WIS_DB::get_item_image($item),
+ 'has_custom_image' => !empty($item->custom_image_url),
];
}
+ // Fly-Items nach Dauer sortieren: 5min→15min→30min→1h→2h→3h
+ $fly_order = ['fly_5min'=>1,'fly_15min'=>2,'fly_30min'=>3,'fly_1h'=>4,'fly_2h'=>5,'fly_3h'=>6];
+ usort($result, function($a, $b) use ($fly_order) {
+ $ap = isset($fly_order[$a['item_id']]) ? $fly_order[$a['item_id']] : 999;
+ $bp = isset($fly_order[$b['item_id']]) ? $fly_order[$b['item_id']] : 999;
+ if ($ap !== 999 || $bp !== 999) return $ap - $bp;
+ return strcmp($a['name'], $b['name']);
+ });
+
return new WP_REST_Response([
'items' => $result,
'total' => $total,
@@ -2786,24 +2997,94 @@ class WIS_API {
}
$final_price = max(0, $total_normal - $coupon_discount) + $total_offer;
-
- $items_payload = [];
- $title_parts = [];
-
+
+ // Fly-Dauern (item_id → Sekunden)
+ // Fly-Dauern und lesbares Label (wird dem Spieler auf dem Code angezeigt)
+ $fly_durations = [
+ 'fly_5min' => 5 * 60,
+ 'fly_15min' => 15 * 60,
+ 'fly_30min' => 30 * 60,
+ 'fly_1h' => 1 * 3600,
+ 'fly_2h' => 2 * 3600,
+ 'fly_3h' => 3 * 3600,
+ ];
+ $fly_labels = [
+ 'fly_5min' => '5 Minuten Fly',
+ 'fly_15min' => '15 Minuten Fly',
+ 'fly_30min' => '30 Minuten Fly',
+ 'fly_1h' => '1 Stunde Fly',
+ 'fly_2h' => '2 Stunden Fly',
+ 'fly_3h' => '3 Stunden Fly',
+ ];
+
+ $items_payload = [];
+ $commands_payload = [];
+ $title_parts = [];
+
foreach ($valid_cart as $item) {
- $items_payload[] = [
- 'id' => $item['id'],
- 'amount' => $item['qty']
- ];
- $title_parts[] = $item['qty'] . 'x ' . $item['title'];
+ $item_id = $item['id']; // Das ist der item_id-String aus wis_items
+
+ if (isset($fly_durations[$item_id])) {
+ // Fly-Gutschein: pro Stueck einen eigenen Code-Eintrag (qty > 1 = mehrere Codes)
+ $base_sec = $fly_durations[$item_id];
+ $base_label = $fly_labels[$item_id];
+ for ($q = 0; $q < intval($item['qty']); $q++) {
+ $commands_payload[] = [
+ 'type' => 'fly',
+ 'duration_sec' => $base_sec,
+ 'label' => $base_label,
+ ];
+ }
+ $title_parts[] = $item['qty'] . 'x ' . $item['title'];
+ } elseif (preg_match('/^rank_([^_]+)_([a-zA-Z0-9_\-]+)_([a-zA-Z0-9_\-]+)_(\d+)$/', $item_id, $rm)) {
+ // Neues Format: rank_{rank_id}_{lp_group}_{default_group}_{days}
+ $rank_id = $rm[1];
+ $lp_group = $rm[2];
+ $default_group = $rm[3];
+ $rank_days = intval($rm[4]);
+ for ($q = 0; $q < intval($item['qty']); $q++) {
+ $commands_payload[] = [
+ 'type' => 'rank',
+ 'rank_id' => $rank_id,
+ 'lp_group' => $lp_group,
+ 'default_group' => $default_group,
+ 'label' => $item['title'],
+ 'days' => $rank_days,
+ ];
+ }
+ $title_parts[] = $item['qty'] . 'x ' . $item['title'];
+ } elseif (preg_match('/^rank_(.+)_(\d+)$/', $item_id, $rm)) {
+ // Altes Format (Fallback): rank_{rank_id}_{days}
+ $rank_id = $rm[1];
+ $rank_days = intval($rm[2]);
+ for ($q = 0; $q < intval($item['qty']); $q++) {
+ $commands_payload[] = [
+ 'type' => 'rank',
+ 'rank_id' => $rank_id,
+ 'lp_group'=> $rank_id,
+ 'default_group' => 'default',
+ 'label' => $item['title'],
+ 'days' => $rank_days,
+ ];
+ }
+ $title_parts[] = $item['qty'] . 'x ' . $item['title'];
+ } else {
+ // Normales Item
+ $items_payload[] = [
+ 'id' => $item_id,
+ '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] : []
+ 'items' => $items_payload,
+ 'commands' => $commands_payload,
+ 'coupon' => $coupon_applied ? ['code' => $coupon_code, 'discount' => $coupon_discount] : [],
];
WIS_DB::insert_order([
@@ -2914,8 +3195,11 @@ class WIS_Shortcode {
.wis-card.offer { border: 2px solid #ffc107; }
.wis-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0,0,0,0.1); }
.wis-card-img { width: 100%; height: 180px; background: #2d2d2d; display: flex; align-items: center; justify-content: center; position: relative; padding: 20px; }
- .wis-card-img img { width: 100px !important; height: 100px !important; object-fit: contain; filter: drop-shadow(0 6px 8px rgba(0,0,0,0.7)); transition: transform 0.3s; image-rendering: pixelated; image-rendering: -moz-crisp-edges; image-rendering: crisp-edges; }
+ .wis-card-img img { width: 160px !important; height: 160px !important; object-fit: contain; filter: drop-shadow(0 6px 8px rgba(0,0,0,0.7)); transition: transform 0.3s; image-rendering: pixelated; image-rendering: -moz-crisp-edges; image-rendering: crisp-edges; }
.wis-card:hover .wis-card-img img { transform: scale(1.15) rotate(5deg); }
+ .wis-card-img--custom { padding: 0 !important; overflow: hidden; }
+ .wis-card-img--custom img { width: 100% !important; height: 100% !important; object-fit: cover !important; image-rendering: auto !important; filter: none !important; border-radius: 0; }
+ .wis-card:hover .wis-card-img--custom img { transform: scale(1.05) !important; }
.wis-offer-badge, .wis-daily-badge { position: absolute; top: 10px; left: 10px; background: linear-gradient(135deg, #ff416c, #ff4b2b); color: white; padding: 6px 12px; border-radius: 20px; font-size: 0.75rem; font-weight: bold; box-shadow: 0 2px 5px rgba(0,0,0,0.3); z-index: 2; }
.wis-daily-badge { background: linear-gradient(135deg, #6f42c1, #8e44ad); border: 1px solid #fff; }
.wis-card-body { padding: 15px; flex-grow: 1; display: flex; flex-direction: column; }
@@ -3235,7 +3519,7 @@ class WIS_Shortcode {
// Wichtig: data-item-id statt onclick mit JSON
return ''
+ badge
- + ' '
+ + ' '
+ '  + ') '
+ ' '
@@ -3506,8 +3790,7 @@ class WIS_Sidebar_Widget extends WP_Widget {
if ($item) {
$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;
+ $img_url = WIS_DB::get_item_image($item);
$target_url = !empty($instance['shop_url']) ? $instance['shop_url'] : home_url();
?>
|