From 10f5fb03a7c77e0c3c041815d1f0d026b80345be Mon Sep 17 00:00:00 2001 From: Git Manager GUI Date: Tue, 28 Apr 2026 22:17:25 +0200 Subject: [PATCH] Upload via Git Manager GUI --- wp-ingame-shop/wp-ingame-shop-pro.php | 189 ++++++++++++++++++++++---- 1 file changed, 160 insertions(+), 29 deletions(-) diff --git a/wp-ingame-shop/wp-ingame-shop-pro.php b/wp-ingame-shop/wp-ingame-shop-pro.php index 304e2e3..12914fa 100644 --- a/wp-ingame-shop/wp-ingame-shop-pro.php +++ b/wp-ingame-shop/wp-ingame-shop-pro.php @@ -266,11 +266,18 @@ class WIS_Activator { if (!wp_next_scheduled('wis_daily_deal_event')) { wp_schedule_event(time(), 'daily', 'wis_daily_deal_event'); } + // Fly-Abo Renewal: täglich prüfen (läuft nur durch am 1. des Monats) + if (!wp_next_scheduled('wis_abo_renewal_event')) { + // Nächsten Mitternacht-Zeitstempel berechnen + $midnight = strtotime('tomorrow midnight'); + wp_schedule_event($midnight, 'daily', 'wis_abo_renewal_event'); + } flush_rewrite_rules(); } public static function deactivate() { wp_clear_scheduled_hook('wis_daily_deal_event'); + wp_clear_scheduled_hook('wis_abo_renewal_event'); flush_rewrite_rules(); } @@ -442,6 +449,92 @@ class WIS_Activator { ], ['id' => $item->id]); } } + + /** + * Fly-Abo Renewal – läuft täglich, handelt aber nur am 1. des Monats. + * Verlängert alle aktiven (nicht gekündigten) Abos automatisch um 30 Tage + * und legt je einen Order-Eintrag als Buchungsnachweis an. + * Gekündigte Abos laufen bis zum letzten Tag des laufenden Monats und werden dann entfernt. + */ + public static function run_abo_renewal() { + // Nur am 1. des Monats ausführen + if (date('j') !== '1') return; + + global $wpdb; + $subs_table = $wpdb->prefix . 'wis_fly_abo_subs'; + $orders_table = $wpdb->prefix . 'wis_orders'; + + // Tabelle anlegen falls noch nicht vorhanden (Migration) + self::create_abo_subs_table(); + + // Alle aktiven, nicht gekündigten Abos verlängern + $active = $wpdb->get_results( + "SELECT * FROM {$subs_table} WHERE cancelled = 0 AND status = 'active'" + ); + + foreach ($active as $sub) { + // expires_at um 30 Tage verlängern + $wpdb->query($wpdb->prepare( + "UPDATE {$subs_table} + SET expires_at = DATE_ADD(expires_at, INTERVAL 30 DAY), + renewed_at = NOW(), + renewal_count = renewal_count + 1 + WHERE id = %d", + $sub->id + )); + + // Buchungsnachweis als Order anlegen (status: completed) + $wpdb->insert($orders_table, [ + 'player_name' => $sub->player_name, + 'server' => $sub->server, + 'item_id' => 'fly_abo_renewal', + 'item_title' => '✈ Fly-Abo Verlängerung: ' . $sub->label, + 'price' => $sub->price, + 'quantity' => 1, + 'status' => 'completed', + 'response' => json_encode([ + 'commands' => [[ + 'type' => 'fly_abo', + 'days' => 30, + 'label' => $sub->label, + ]], + ]), + ]); + } + + // Gekündigte Abos die abgelaufen sind deaktivieren + $wpdb->query( + "UPDATE {$subs_table} + SET status = 'expired' + WHERE cancelled = 1 + AND expires_at < NOW() + AND status = 'active'" + ); + + // Log + $count = count($active); + error_log("[WIS] Fly-Abo Renewal: {$count} Abo(s) verlängert am " . date('d.m.Y')); + } + + public static function create_abo_subs_table() { + global $wpdb; + $table = $wpdb->prefix . 'wis_fly_abo_subs'; + $wpdb->query("CREATE TABLE IF NOT EXISTS {$table} ( + id INT AUTO_INCREMENT PRIMARY KEY, + player_name VARCHAR(64) NOT NULL, + server VARCHAR(64) NOT NULL DEFAULT '', + label VARCHAR(128) NOT NULL, + price INT NOT NULL DEFAULT 0, + status VARCHAR(20) NOT NULL DEFAULT 'active', + cancelled TINYINT(1) NOT NULL DEFAULT 0, + cancelled_at DATETIME DEFAULT NULL, + expires_at DATETIME NOT NULL, + renewed_at DATETIME DEFAULT NULL, + renewal_count INT NOT NULL DEFAULT 0, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + UNIQUE KEY uq_player_server (player_name, server) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); + } public static function reset_shop() { global $wpdb; @@ -1041,8 +1134,7 @@ class WIS_Admin { if (empty($default_group)) $default_group = 'default'; $resolved_item_id = 'rank_' . $rank_id . '_' . $lp_group . '_' . $default_group . '_' . $rank_days; } elseif ($item_type === 'fly_abo') { - $abo_days = max(1, intval($_POST['abo_days'] ?? 30)); - $resolved_item_id = 'fly_abo_' . $abo_days; + $resolved_item_id = 'fly_abo'; } else { $resolved_item_id = sanitize_text_field($_POST['item_id'] ?? ''); } @@ -1725,8 +1817,8 @@ class WIS_Admin { // Format: rank_{rank_id}_{lp_group}_{default_group}_{days} // Fallback für altes Format rank_{rank_id}_{days} $is_rank_old = !$is_rank && $item && preg_match('/^rank_(.+)_(\d+)$/', $item->item_id, $rm_old); - $is_fly_abo = $item && preg_match('/^fly_abo_(\d+)$/', $item->item_id, $abo_m); - $cur_abo_days = $is_fly_abo ? intval($abo_m[1]) : 30; + $is_fly_abo = $item && ($item->item_id === 'fly_abo' || preg_match('/^fly_abo_\d+$/', $item->item_id)); + $cur_abo_days = 0; // nicht mehr relevant $cur_rank_id = $is_rank ? $rm[1] : ($is_rank_old ? $rm_old[1] : 'vip'); $cur_lp_group = $is_rank ? $rm[2] : $cur_rank_id; $cur_default_group = $is_rank ? $rm[3] : 'default'; @@ -1790,21 +1882,15 @@ class WIS_Admin { @@ -2135,8 +2221,8 @@ class WIS_Admin { } 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') . ''; - } elseif (preg_match('/^fly_abo_(\d+)$/', $item->item_id, $abo_m2)) { - echo '✈ Fly-Abo — ' . esc_html($abo_m2[1]) . ' Tage'; + } elseif ($item->item_id === 'fly_abo' || preg_match('/^fly_abo_/', $item->item_id)) { + echo '✈ Fly-Abo — monatlich'; } else { echo '' . esc_html($item->item_id) . ''; } @@ -3441,16 +3527,14 @@ class WIS_API { ]; } $title_parts[] = $item['qty'] . 'x ' . $item['title']; - } elseif (preg_match('/^fly_abo_(\d+)$/', $item_id, $abo_m)) { - // Fly-Abo: qty > 1 verlängert das Abo (addiert Tage) - $abo_days = intval($abo_m[1]); - $total_days = $abo_days * intval($item['qty']); + } elseif (preg_match('/^fly_abo$/', $item_id) || preg_match('/^fly_abo_\d*$/', $item_id)) { + // Fly-Abo: monatlich abonniert, Preis = Monatsbeitrag + // qty > 1 wird ignoriert (nur 1 Abo pro Spieler möglich, Mehrfachkauf = keine Wirkung) $commands_payload[] = [ 'type' => 'fly_abo', - 'days' => $total_days, 'label' => $item['title'], ]; - $title_parts[] = $item['qty'] . 'x ' . $item['title']; + $title_parts[] = $item['title']; } else { // Normales Item $items_payload[] = [ @@ -3480,7 +3564,53 @@ class WIS_API { 'status' => 'pending', 'response' => json_encode($payload) ]); - + + // Fly-Abo Abonnements registrieren / verlängern + foreach ($commands_payload as $cmd) { + if (($cmd['type'] ?? '') !== 'fly_abo') continue; + $abo_days = intval($cmd['days'] ?? 30); + $abo_label = sanitize_text_field($cmd['label'] ?? 'Fly-Abo'); + $abo_price = 0; + // Preis aus dem Warenkorb ermitteln (erstes passendes fly_abo Item) + foreach ($valid_cart as $ci) { + if (preg_match('/^fly_abo_\d+$/', $ci['id'])) { + $abo_price = intval($ci['price'] ?? 0); + break; + } + } + global $wpdb; + WIS_Activator::create_abo_subs_table(); + $subs_table = $wpdb->prefix . 'wis_fly_abo_subs'; + $existing = $wpdb->get_row($wpdb->prepare( + "SELECT * FROM {$subs_table} WHERE player_name = %s AND server = %s", + $player, $server + )); + if ($existing && $existing->status === 'active') { + // Bestehendes aktives Abo verlängern (kumulativ) + $wpdb->query($wpdb->prepare( + "UPDATE {$subs_table} + SET expires_at = DATE_ADD(IF(expires_at > NOW(), expires_at, NOW()), INTERVAL %d DAY), + cancelled = 0, + cancelled_at = NULL, + label = %s, + price = %d + WHERE id = %d", + $abo_days, $abo_label, $abo_price, $existing->id + )); + } else { + // Neues Abo anlegen + $wpdb->replace($subs_table, [ + 'player_name' => $player, + 'server' => $server, + 'label' => $abo_label, + 'price' => $abo_price, + 'status' => 'active', + 'cancelled' => 0, + 'expires_at' => date('Y-m-d H:i:s', strtotime("+{$abo_days} days")), + ]); + } + } + $msg = '✅ Bestellung erfolgreich!'; if ($coupon_msg) $msg .= ' (' . $coupon_msg . ')'; @@ -4265,4 +4395,5 @@ add_action('init', [WIS_Shortcode::class, 'register']); add_action('widgets_init', function() { register_widget('WIS_Sidebar_Widget'); }); -add_action('wis_daily_deal_event', [WIS_Activator::class, 'run_daily_deal']); \ No newline at end of file +add_action('wis_daily_deal_event', [WIS_Activator::class, 'run_daily_deal']); +add_action('wis_abo_renewal_event', [WIS_Activator::class, 'run_abo_renewal']); \ No newline at end of file