Upload folder via GUI - includes

This commit is contained in:
Git Manager GUI
2026-05-05 21:18:59 +02:00
parent 1abc412e1d
commit cd5c99d852
2 changed files with 130 additions and 13 deletions

View File

@@ -49,6 +49,30 @@ class WBF_Abo {
];
}
// Item-Abos aus WordPress DB (wis_item_abo_subs)
$item_abos = $wpdb->get_results( $wpdb->prepare(
"SELECT id, label, item_id, daily_qty, cancelled,
DATE_FORMAT(expires_at, '%%d.%%m.%%Y') AS expires_at_fmt
FROM {$wpdb->prefix}wis_item_abo_subs
WHERE player_name = %s
AND status = 'active'
AND expires_at > NOW()
ORDER BY created_at ASC",
$mc_name
), ARRAY_A );
if ( $item_abos ) {
foreach ( $item_abos as &$row ) {
$row['id'] = (int) $row['id'];
$row['daily_qty'] = (int) $row['daily_qty'];
$row['cancelled'] = (bool) $row['cancelled'];
}
unset($row);
$result['item_abos'] = $item_abos;
} else {
$result['item_abos'] = [];
}
// Spigot MySQL für Fly-Usage + Plot-Daten
$conn = self::get_spigot_db();
if ( $conn ) {
@@ -78,7 +102,7 @@ class WBF_Abo {
return $result;
}
public static function cancel_abo( string $mc_name, string $type ): bool {
public static function cancel_abo( string $mc_name, string $type, int $abo_id = 0 ): bool {
global $wpdb;
if ( $type === 'fly_abo' ) {
$rows = $wpdb->update(
@@ -97,6 +121,22 @@ class WBF_Abo {
$a = $stmt->affected_rows; $stmt->close(); $conn->close();
return $a > 0;
}
if ( $type === 'item_abo' ) {
if ( $abo_id <= 0 ) return false;
// Sicherheitscheck: Abo muss dem Spieler gehören
$existing = $wpdb->get_row( $wpdb->prepare(
"SELECT id, label FROM {$wpdb->prefix}wis_item_abo_subs
WHERE id = %d AND player_name = %s AND status = 'active' AND cancelled = 0",
$abo_id, $mc_name
) );
if ( ! $existing ) return false;
$rows = $wpdb->update(
$wpdb->prefix . 'wis_item_abo_subs',
['cancelled' => 1, 'cancelled_at' => current_time('mysql')],
['id' => $abo_id]
);
return $rows > 0;
}
return false;
}
@@ -110,6 +150,7 @@ class WBF_Abo {
$abos = self::get_all_abos($mc_name);
$fly_abo = $abos['fly_abo'] ?? null;
$plot_abo = $abos['plot_abo'] ?? null;
$item_abos = $abos['item_abos'] ?? [];
$plot_extra = (int)($abos['plot_extra'] ?? 0);
$fly_used = (int)($abos['fly_used_sec'] ?? 0);
$fly_max = (int) get_option('wis_fly_abo_max_daily_hours', 6) * 3600;
@@ -117,7 +158,7 @@ class WBF_Abo {
$shop_url = esc_url(get_option('wis_shop_url', home_url('/ingame-shop/')));
$nonce = wp_create_nonce('wbf_nonce');
$ajax_url = admin_url('admin-ajax.php');
$has_any = $fly_abo || $plot_abo || $plot_extra > 0;
$has_any = $fly_abo || $plot_abo || $plot_extra > 0 || !empty($item_abos);
ob_start(); ?>
<style>
@@ -306,8 +347,66 @@ class WBF_Abo {
</div>
<?php endif; // plot_abo ?>
<?php /* ITEM-ABOS */ foreach ($item_abos as $idx => $ia):
$ia_nr = $idx + 1;
$ia_id = (int) $ia['id'];
$ia_label = $ia['label'] ?? 'Item-Abo';
$ia_item = $ia['item_id'] ?? '?';
$ia_qty = (int)($ia['daily_qty'] ?? 1);
$ia_expires = $ia['expires_at_fmt'] ?? '?';
$ia_cancelled = !empty($ia['cancelled']);
?>
<div class="wbf-abo-item <?php echo $ia_cancelled ? 'wbf-abo-item--cancelled' : 'wbf-abo-item--active'; ?>" id="wbf-abo-item-<?php echo $ia_id; ?>">
<div class="wbf-abo-item__head">
<div class="wbf-abo-item__icon-wrap">📦</div>
<div class="wbf-abo-item__info">
<div class="wbf-abo-item__name"><?php echo esc_html($ia_label); ?></div>
<div class="wbf-abo-item__price"><?php echo $ia_qty; ?>× täglich · <code style="font-size:.78rem;opacity:.8"><?php echo esc_html($ia_item); ?></code></div>
</div>
<div class="wbf-abo-item__status">
<?php if ($ia_cancelled): ?>
<span class="wbf-abo-badge wbf-abo-badge--cancelled"><i class="fas fa-clock"></i> Gekündigt</span>
<?php else: ?>
<span class="wbf-abo-badge wbf-abo-badge--active"><i class="fas fa-circle-check"></i> Aktiv</span>
<?php endif; ?>
</div>
</div>
<div class="wbf-abo-item__body">
<div class="wbf-abo-grid">
<div class="wbf-abo-grid__item">
<span class="wbf-abo-grid__label"><i class="fas fa-calendar-day"></i> Läuft bis</span>
<span class="wbf-abo-grid__value <?php echo $ia_cancelled ? 'wbf-abo-grid__value--warn' : ''; ?>"><?php echo esc_html($ia_expires); ?></span>
</div>
<div class="wbf-abo-grid__item">
<span class="wbf-abo-grid__label"><i class="fas fa-box-open"></i> Tageslieferung</span>
<span class="wbf-abo-grid__value"><?php echo $ia_qty; ?>× <?php echo esc_html($ia_item); ?></span>
</div>
</div>
</div>
<?php if (!$ia_cancelled): ?>
<div class="wbf-abo-item__foot">
<button class="wbf-btn wbf-btn--danger wbf-btn--sm wbf-abo-cancel-btn"
data-type="item_abo"
data-abo-id="<?php echo $ia_id; ?>"
data-nonce="<?php echo $nonce; ?>"
data-label="<?php echo esc_attr($ia_label); ?>"
data-period="<?php echo esc_attr($ia_expires); ?>">
<i class="fas fa-xmark"></i> Kündigen
</button>
<span class="wbf-abo-item__hint">Bleibt bis <?php echo esc_html($ia_expires); ?> aktiv</span>
</div>
<?php else: ?>
<div class="wbf-abo-item__foot wbf-abo-item__foot--cancelled">
<div class="wbf-abo-notice wbf-abo-notice--info">
<i class="fas fa-circle-info"></i>
Kündigung vorgemerkt Lieferungen laufen bis <strong><?php echo esc_html($ia_expires); ?></strong> weiter.
</div>
</div>
<?php endif; ?>
</div>
<?php endforeach; // item_abos ?>
<?php if ($plot_extra > 0 || $plot_abo): ?>
<div class="wbf-abo-item wbf-abo-item--info">
<div class="wbf-abo-item__head">
<div class="wbf-abo-item__icon-wrap">🗺️</div>
<div class="wbf-abo-item__info">
@@ -363,7 +462,7 @@ class WBF_Abo {
<script>
document.addEventListener('DOMContentLoaded', function() {
var AJAX = <?php echo json_encode($ajax_url); ?>;
var p = {type:null, nonce:null, btn:null};
var p = {type:null, nonce:null, btn:null, aboId:0};
var modal = document.getElementById('wbf-abo-modal');
var yesBtn = document.getElementById('wbf-abo-modal-yes');
var noBtn = document.getElementById('wbf-abo-modal-no');
@@ -371,7 +470,7 @@ document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.wbf-abo-cancel-btn').forEach(function(b) {
b.addEventListener('click', function(e) {
e.preventDefault();
p = {type:b.dataset.type, nonce:b.dataset.nonce, btn:b};
p = {type:b.dataset.type, nonce:b.dataset.nonce, btn:b, aboId:parseInt(b.dataset.aboId||'0',10)};
document.getElementById('wbf-abo-modal-label').textContent = b.dataset.label || 'dieses Abo';
document.getElementById('wbf-abo-modal-period').textContent = b.dataset.period || '';
modal.style.display = 'flex';
@@ -389,15 +488,23 @@ document.addEventListener('DOMContentLoaded', function() {
yesBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Kündigen…';
closeModal();
var params = {action:'wbf_cancel_abo', nonce:p.nonce, type:p.type};
if (p.type === 'item_abo' && p.aboId > 0) params.abo_id = p.aboId;
fetch(AJAX, {
method:'POST',
headers:{'Content-Type':'application/x-www-form-urlencoded'},
body: new URLSearchParams({action:'wbf_cancel_abo', nonce:p.nonce, type:p.type}).toString()
body: new URLSearchParams(params).toString()
})
.then(function(r){return r.json();})
.then(function(res) {
if (res.success) {
var card = document.getElementById(p.type==='fly_abo'?'wbf-abo-fly':'wbf-abo-plot');
var card;
if (p.type === 'item_abo') {
card = p.aboId > 0 ? document.getElementById('wbf-abo-item-'+p.aboId) : null;
} else {
card = document.getElementById(p.type==='fly_abo'?'wbf-abo-fly':'wbf-abo-plot');
}
if (card) {
card.classList.replace('wbf-abo-item--active','wbf-abo-item--cancelled');
var badge = card.querySelector('.wbf-abo-badge');
@@ -412,13 +519,13 @@ document.addEventListener('DOMContentLoaded', function() {
});
}
} else {
alert((res.data&&res.data.message)?res.data.message:'Fehler beim Kündigen.\nAlternativ: /flyabocancel confirm ingame');
alert((res.data&&res.data.message)?res.data.message:'Fehler beim Kündigen.');
}
yesBtn.disabled=false;
yesBtn.innerHTML='<i class="fas fa-xmark"></i> Ja, kündigen';
p={type:null,nonce:null,btn:null};
p={type:null,nonce:null,btn:null,aboId:0};
})
.catch(function(){ alert('Verbindungsfehler. Bitte ingame kündigen.'); yesBtn.disabled=false; p={type:null,nonce:null,btn:null}; });
.catch(function(){ alert('Verbindungsfehler. Bitte ingame kündigen.'); yesBtn.disabled=false; p={type:null,nonce:null,btn:null,aboId:0}; });
});
});
</script>

View File

@@ -1846,11 +1846,21 @@ class WBF_Ajax {
}
$type = sanitize_key($_POST['type'] ?? '');
if ( ! in_array($type, ['fly_abo', 'plot_abo'], true) ) {
if ( ! in_array($type, ['fly_abo', 'plot_abo', 'item_abo'], true) ) {
wp_send_json_error(['message' => 'Ungültiger Abo-Typ.']);
return;
}
// Bei item_abo: abo_id pflichtfeld
$abo_id = 0;
if ( $type === 'item_abo' ) {
$abo_id = (int)($_POST['abo_id'] ?? 0);
if ( $abo_id <= 0 ) {
wp_send_json_error(['message' => 'Abo-ID fehlt oder ungültig.']);
return;
}
}
// MC-Name ermitteln (Spielername = Forum-Username oder verknüpfter MC-Name)
$mc_name = '';
if ( class_exists('WBF_MC_Bridge') ) {
@@ -1866,7 +1876,7 @@ class WBF_Ajax {
return;
}
$ok = WBF_Abo::cancel_abo($mc_name, $type);
$ok = WBF_Abo::cancel_abo($mc_name, $type, $abo_id);
if ($ok) {
wp_send_json_success(['message' => 'Abo erfolgreich gekündigt.']);