Upload via Git Manager GUI
This commit is contained in:
@@ -266,11 +266,18 @@ class WIS_Activator {
|
|||||||
if (!wp_next_scheduled('wis_daily_deal_event')) {
|
if (!wp_next_scheduled('wis_daily_deal_event')) {
|
||||||
wp_schedule_event(time(), 'daily', '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();
|
flush_rewrite_rules();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function deactivate() {
|
public static function deactivate() {
|
||||||
wp_clear_scheduled_hook('wis_daily_deal_event');
|
wp_clear_scheduled_hook('wis_daily_deal_event');
|
||||||
|
wp_clear_scheduled_hook('wis_abo_renewal_event');
|
||||||
flush_rewrite_rules();
|
flush_rewrite_rules();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,6 +449,92 @@ class WIS_Activator {
|
|||||||
], ['id' => $item->id]);
|
], ['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() {
|
public static function reset_shop() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
@@ -1041,8 +1134,7 @@ class WIS_Admin {
|
|||||||
if (empty($default_group)) $default_group = 'default';
|
if (empty($default_group)) $default_group = 'default';
|
||||||
$resolved_item_id = 'rank_' . $rank_id . '_' . $lp_group . '_' . $default_group . '_' . $rank_days;
|
$resolved_item_id = 'rank_' . $rank_id . '_' . $lp_group . '_' . $default_group . '_' . $rank_days;
|
||||||
} elseif ($item_type === 'fly_abo') {
|
} elseif ($item_type === 'fly_abo') {
|
||||||
$abo_days = max(1, intval($_POST['abo_days'] ?? 30));
|
$resolved_item_id = 'fly_abo';
|
||||||
$resolved_item_id = 'fly_abo_' . $abo_days;
|
|
||||||
} else {
|
} else {
|
||||||
$resolved_item_id = sanitize_text_field($_POST['item_id'] ?? '');
|
$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}
|
// Format: rank_{rank_id}_{lp_group}_{default_group}_{days}
|
||||||
// Fallback für altes Format rank_{rank_id}_{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_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);
|
$is_fly_abo = $item && ($item->item_id === 'fly_abo' || preg_match('/^fly_abo_\d+$/', $item->item_id));
|
||||||
$cur_abo_days = $is_fly_abo ? intval($abo_m[1]) : 30;
|
$cur_abo_days = 0; // nicht mehr relevant
|
||||||
$cur_rank_id = $is_rank ? $rm[1] : ($is_rank_old ? $rm_old[1] : 'vip');
|
$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_lp_group = $is_rank ? $rm[2] : $cur_rank_id;
|
||||||
$cur_default_group = $is_rank ? $rm[3] : 'default';
|
$cur_default_group = $is_rank ? $rm[3] : 'default';
|
||||||
@@ -1790,21 +1882,15 @@ class WIS_Admin {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="wis_item_fly_abo" style="display:none;">
|
<div id="wis_item_fly_abo" style="display:none;">
|
||||||
<table style="border-collapse:collapse;">
|
<p class="description" style="margin-top:4px; padding:10px; background:#f0f6fc; border-left:3px solid #2271b1; border-radius:2px;">
|
||||||
<tr>
|
<strong>✈ Fly-Abo – monatliches Abonnement</strong><br><br>
|
||||||
<td style="padding:4px 10px 4px 0;"><label for="abo_days"><strong>Laufzeit (Tage):</strong></label></td>
|
Spieler zahlen den <strong>Artikelpreis einmalig beim Kauf</strong>.<br>
|
||||||
<td>
|
Danach wird am <strong>1. jedes Monats</strong> automatisch der gleiche Betrag per Vault abgebucht.<br>
|
||||||
<input type="number" id="abo_days" name="abo_days"
|
Kann der Spieler nicht zahlen, wird das Abo automatisch gekündigt.<br>
|
||||||
value="<?php echo esc_attr($cur_abo_days); ?>"
|
Kündigung jederzeit ingame mit <code>/flyabocancel</code> – läuft bis Monatsende.<br><br>
|
||||||
min="1" style="width:80px;">
|
<strong>Artikelpreis</strong> = monatlicher Betrag |
|
||||||
<span style="margin-left:6px; color:#666;">Tage</span>
|
Tägl. Fly-Limit: konfigurierbar per <code>fly-abo.max-daily-hours</code> im Plugin.<br>
|
||||||
</td>
|
Gespeicherte Item-ID: <code>fly_abo</code>
|
||||||
</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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -2135,8 +2221,8 @@ class WIS_Admin {
|
|||||||
} elseif (preg_match('/^rank_(.+)_(\d+)$/', $item->item_id, $rm2)) {
|
} elseif (preg_match('/^rank_(.+)_(\d+)$/', $item->item_id, $rm2)) {
|
||||||
$rd = intval($rm2[2]);
|
$rd = intval($rm2[2]);
|
||||||
echo '<span title="' . esc_attr($item->item_id) . '">👑 <code>' . esc_html($rm2[1]) . '</code> — ' . ($rd === 0 ? '<em>dauerhaft</em>' : esc_html($rd) . ' Tage') . '</span>';
|
echo '<span title="' . esc_attr($item->item_id) . '">👑 <code>' . esc_html($rm2[1]) . '</code> — ' . ($rd === 0 ? '<em>dauerhaft</em>' : esc_html($rd) . ' Tage') . '</span>';
|
||||||
} elseif (preg_match('/^fly_abo_(\d+)$/', $item->item_id, $abo_m2)) {
|
} elseif ($item->item_id === 'fly_abo' || preg_match('/^fly_abo_/', $item->item_id)) {
|
||||||
echo '<span title="' . esc_attr($item->item_id) . '">✈ Fly-Abo — ' . esc_html($abo_m2[1]) . ' Tage</span>';
|
echo '<span title="' . esc_attr($item->item_id) . '">✈ Fly-Abo — monatlich</span>';
|
||||||
} else {
|
} else {
|
||||||
echo '<code>' . esc_html($item->item_id) . '</code>';
|
echo '<code>' . esc_html($item->item_id) . '</code>';
|
||||||
}
|
}
|
||||||
@@ -3441,16 +3527,14 @@ class WIS_API {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
$title_parts[] = $item['qty'] . 'x ' . $item['title'];
|
$title_parts[] = $item['qty'] . 'x ' . $item['title'];
|
||||||
} elseif (preg_match('/^fly_abo_(\d+)$/', $item_id, $abo_m)) {
|
} elseif (preg_match('/^fly_abo$/', $item_id) || preg_match('/^fly_abo_\d*$/', $item_id)) {
|
||||||
// Fly-Abo: qty > 1 verlängert das Abo (addiert Tage)
|
// Fly-Abo: monatlich abonniert, Preis = Monatsbeitrag
|
||||||
$abo_days = intval($abo_m[1]);
|
// qty > 1 wird ignoriert (nur 1 Abo pro Spieler möglich, Mehrfachkauf = keine Wirkung)
|
||||||
$total_days = $abo_days * intval($item['qty']);
|
|
||||||
$commands_payload[] = [
|
$commands_payload[] = [
|
||||||
'type' => 'fly_abo',
|
'type' => 'fly_abo',
|
||||||
'days' => $total_days,
|
|
||||||
'label' => $item['title'],
|
'label' => $item['title'],
|
||||||
];
|
];
|
||||||
$title_parts[] = $item['qty'] . 'x ' . $item['title'];
|
$title_parts[] = $item['title'];
|
||||||
} else {
|
} else {
|
||||||
// Normales Item
|
// Normales Item
|
||||||
$items_payload[] = [
|
$items_payload[] = [
|
||||||
@@ -3480,7 +3564,53 @@ class WIS_API {
|
|||||||
'status' => 'pending',
|
'status' => 'pending',
|
||||||
'response' => json_encode($payload)
|
'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!';
|
$msg = '✅ Bestellung erfolgreich!';
|
||||||
if ($coupon_msg) $msg .= ' (' . $coupon_msg . ')';
|
if ($coupon_msg) $msg .= ' (' . $coupon_msg . ')';
|
||||||
|
|
||||||
@@ -4265,4 +4395,5 @@ add_action('init', [WIS_Shortcode::class, 'register']);
|
|||||||
add_action('widgets_init', function() {
|
add_action('widgets_init', function() {
|
||||||
register_widget('WIS_Sidebar_Widget');
|
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']);
|
||||||
Reference in New Issue
Block a user