Upload via Git Manager GUI

This commit is contained in:
Git Manager GUI
2026-04-28 22:17:25 +02:00
parent f7b274a794
commit 10f5fb03a7

View File

@@ -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 {
</div>
<div id="wis_item_fly_abo" style="display:none;">
<table style="border-collapse:collapse;">
<tr>
<td style="padding:4px 10px 4px 0;"><label for="abo_days"><strong>Laufzeit (Tage):</strong></label></td>
<td>
<input type="number" id="abo_days" name="abo_days"
value="<?php echo esc_attr($cur_abo_days); ?>"
min="1" style="width:80px;">
<span style="margin-left:6px; color:#666;">Tage</span>
</td>
</tr>
</table>
<p class="description" style="margin-top:6px;">
Spieler erhalten täglich bis zu <strong>6 Stunden</strong> Fly-Zeit (konfigurierbar per <code>fly-abo.max-daily-hours</code> im Plugin).<br>
Mehrfachkauf verlängert das bestehende Abo kumulativ.<br>
Gespeicherte Item-ID: <code>fly_abo_{tage}</code> z.B. <code>fly_abo_30</code>
<p class="description" style="margin-top:4px; padding:10px; background:#f0f6fc; border-left:3px solid #2271b1; border-radius:2px;">
<strong>✈ Fly-Abo monatliches Abonnement</strong><br><br>
Spieler zahlen den <strong>Artikelpreis einmalig beim Kauf</strong>.<br>
Danach wird am <strong>1. jedes Monats</strong> automatisch der gleiche Betrag per Vault abgebucht.<br>
Kann der Spieler nicht zahlen, wird das Abo automatisch gekündigt.<br>
Kündigung jederzeit ingame mit <code>/flyabocancel</code> läuft bis Monatsende.<br><br>
<strong>Artikelpreis</strong> = monatlicher Betrag &nbsp;|&nbsp;
Tägl. Fly-Limit: konfigurierbar per <code>fly-abo.max-daily-hours</code> im Plugin.<br>
Gespeicherte Item-ID: <code>fly_abo</code>
</p>
</div>
@@ -2135,8 +2221,8 @@ class WIS_Admin {
} elseif (preg_match('/^rank_(.+)_(\d+)$/', $item->item_id, $rm2)) {
$rd = intval($rm2[2]);
echo '<span title="' . esc_attr($item->item_id) . '">👑 <code>' . esc_html($rm2[1]) . '</code> &mdash; ' . ($rd === 0 ? '<em>dauerhaft</em>' : esc_html($rd) . ' Tage') . '</span>';
} elseif (preg_match('/^fly_abo_(\d+)$/', $item->item_id, $abo_m2)) {
echo '<span title="' . esc_attr($item->item_id) . '">✈ Fly-Abo &mdash; ' . esc_html($abo_m2[1]) . ' Tage</span>';
} elseif ($item->item_id === 'fly_abo' || preg_match('/^fly_abo_/', $item->item_id)) {
echo '<span title="' . esc_attr($item->item_id) . '">✈ Fly-Abo &mdash; monatlich</span>';
} else {
echo '<code>' . esc_html($item->item_id) . '</code>';
}
@@ -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']);
add_action('wis_daily_deal_event', [WIS_Activator::class, 'run_daily_deal']);
add_action('wis_abo_renewal_event', [WIS_Activator::class, 'run_abo_renewal']);