Upload via Git Manager GUI

This commit is contained in:
Git Manager GUI
2026-05-12 23:24:09 +02:00
parent 01205de952
commit d387424e0f

View File

@@ -246,6 +246,43 @@ add_action('wp_ajax_wis_save_cat_order', function() {
wp_send_json_success('Reihenfolge gespeichert.');
});
// AJAX: Angebot-Flag umschalten (Angebote-Übersicht)
add_action('wp_ajax_wis_angebote_toggle', function() {
check_ajax_referer('wis_angebote_nonce', 'nonce');
if (!current_user_can('manage_options')) wp_send_json_error('Keine Berechtigung.');
global $wpdb;
$table = $wpdb->prefix . 'wis_items';
$id = intval($_POST['id'] ?? 0);
$field = in_array($_POST['field'] ?? '', ['is_offer', 'is_daily_deal'], true) ? $_POST['field'] : null;
if (!$id || !$field) wp_send_json_error('Ungültige Parameter.');
$current = (int) $wpdb->get_var($wpdb->prepare("SELECT $field FROM $table WHERE id = %d", $id));
$new_val = $current ? 0 : 1;
if ($field === 'is_daily_deal' && $new_val === 1) {
$wpdb->query("UPDATE $table SET is_daily_deal = 0 WHERE is_daily_deal = 1");
}
$wpdb->update($table, [$field => $new_val], ['id' => $id]);
wp_send_json_success(['new_val' => $new_val]);
});
// AJAX: Angebotspreis direkt speichern (Angebote-Übersicht)
add_action('wp_ajax_wis_angebote_save_price', function() {
check_ajax_referer('wis_angebote_nonce', 'nonce');
if (!current_user_can('manage_options')) wp_send_json_error('Keine Berechtigung.');
global $wpdb;
$table = $wpdb->prefix . 'wis_items';
$id = intval($_POST['id'] ?? 0);
$offer_price = max(0, intval($_POST['offer_price'] ?? 0));
if (!$id) wp_send_json_error('Ungültige ID.');
$wpdb->update($table, ['offer_price' => $offer_price], ['id' => $id]);
wp_send_json_success(['offer_price' => $offer_price]);
});
// jQuery UI Sortable für die Kategorien-Seite laden
add_action('admin_enqueue_scripts', function($hook) {
if (isset($_GET['page']) && $_GET['page'] === 'wis_categories') {
@@ -565,7 +602,16 @@ class WIS_Activator {
$table = $wpdb->prefix . 'wis_items';
$discount = intval(get_option('wis_daily_deal_discount', 20));
$wpdb->update($table, ['is_daily_deal' => 0], ['is_daily_deal' => 1]);
// Altes Daily-Deal-Item vollständig zurücksetzen:
// is_daily_deal, is_offer und offer_price werden alle auf 0 gesetzt,
// damit das Item nicht als normales Angebot mit gesenktem Preis hängen bleibt.
$wpdb->query(
"UPDATE $table
SET is_daily_deal = 0,
is_offer = 0,
offer_price = 0
WHERE is_daily_deal = 1"
);
$item = $wpdb->get_row("SELECT * FROM $table WHERE status = 'publish' AND price > 0 ORDER BY RAND() LIMIT 1");
@@ -1544,6 +1590,7 @@ class WIS_Admin {
add_submenu_page('wis_shop', 'Bestellungen', 'Bestellungen', 'manage_options', 'wis_orders', [self::class, 'page_orders']);
add_submenu_page('wis_shop', 'Server', 'Server', 'manage_options', 'wis_servers', [self::class, 'page_servers']);
add_submenu_page('wis_shop', 'Kategorien', 'Kategorien', 'manage_options', 'wis_categories', [self::class, 'page_categories']);
add_submenu_page('wis_shop', 'Angebote', 'Angebote', 'manage_options', 'wis_angebote', [self::class, 'page_angebote']);
add_submenu_page('wis_shop', 'Gutscheine', 'Gutscheine', 'manage_options', 'wis_coupons', [self::class, 'page_coupons']);
add_submenu_page('wis_shop', 'Analyse', 'Analyse', 'manage_options', 'wis_analyse', [self::class, 'page_analyse']);
add_submenu_page('wis_shop', 'Top Spender', 'Top Spender', 'manage_options', 'wis_top_spenders', [self::class, 'page_top_spenders']);
@@ -4987,6 +5034,243 @@ class WIS_Admin {
</script>
<?php
}
// ===========================================================
// ANGEBOTE ÜBERSICHT
// ===========================================================
public static function page_angebote() {
global $wpdb;
$table = $wpdb->prefix . 'wis_items';
$currency = get_option('wis_currency_name', 'Coins');
$nonce = wp_create_nonce('wis_angebote_nonce');
$filter = sanitize_text_field($_GET['filter'] ?? 'all');
$search = sanitize_text_field($_GET['s'] ?? '');
$where = "1=1";
if ($filter === 'offer') $where .= " AND is_offer = 1 AND is_daily_deal = 0";
elseif ($filter === 'daily') $where .= " AND is_daily_deal = 1";
elseif ($filter === 'none') $where .= " AND is_offer = 0 AND is_daily_deal = 0";
else $where .= " AND (is_offer = 1 OR is_daily_deal = 1)";
if ($search !== '') {
$like = '%' . $wpdb->esc_like($search) . '%';
$where .= $wpdb->prepare(" AND (name LIKE %s OR item_id LIKE %s)", $like, $like);
}
if ($filter !== 'none') {
$where .= " AND status = 'publish'";
}
$items = $wpdb->get_results("SELECT * FROM $table WHERE $where ORDER BY is_daily_deal DESC, name ASC");
$count_offer = (int) $wpdb->get_var("SELECT COUNT(*) FROM $table WHERE is_offer = 1 AND is_daily_deal = 0 AND status='publish'");
$count_daily = (int) $wpdb->get_var("SELECT COUNT(*) FROM $table WHERE is_daily_deal = 1 AND status='publish'");
$count_all = $count_offer + $count_daily;
$img_base = get_option('wis_image_base_url', '');
$base_url = admin_url('admin.php?page=wis_angebote');
?>
<div class="wrap">
<h1>🔥 Angebote Übersicht</h1>
<p style="color:#666;">Alle Items die als <strong>Angebot</strong> oder <strong>Daily Deal</strong> markiert sind mit direkter Bearbeitung.</p>
<!-- Filterleiste -->
<ul class="subsubsub" style="margin-bottom:12px;">
<?php
$filters = [
'all' => "🔥 Alle Angebote <span class='count'>($count_all)</span>",
'offer' => "🏷️ Nur Angebote <span class='count'>($count_offer)</span>",
'daily' => "🎁 Daily Deal <span class='count'>($count_daily)</span>",
'none' => "📦 Ohne Kennzeichnung",
];
$i = 0;
foreach ($filters as $key => $label) {
$active = ($filter === $key) ? 'current' : '';
$sep = (++$i < count($filters)) ? ' | ' : '';
echo "<li><a href='" . esc_url(add_query_arg('filter', $key, $base_url)) . "' class='$active'>$label</a>$sep</li>";
}
?>
</ul>
<!-- Suche -->
<form method="get" action="<?php echo admin_url('admin.php'); ?>" style="margin-bottom:16px; display:flex; gap:8px; align-items:center;">
<input type="hidden" name="page" value="wis_angebote">
<input type="hidden" name="filter" value="<?php echo esc_attr($filter); ?>">
<input type="search" name="s" value="<?php echo esc_attr($search); ?>" placeholder="Name oder Item-ID …" class="regular-text">
<button type="submit" class="button">Suchen</button>
<?php if ($search): ?>
<a href="<?php echo esc_url(add_query_arg('filter', $filter, $base_url)); ?>" class="button button-secondary">✕ Zurücksetzen</a>
<?php endif; ?>
</form>
<?php if (empty($items)): ?>
<div style="background:#f8f9fa; border:1px dashed #ccd; border-radius:8px; padding:30px; text-align:center; color:#888; margin-top:10px;">
<span style="font-size:2em;">📭</span><br>
Keine Items gefunden<?php echo $search ? ' für „' . esc_html($search) . '"' : ''; ?>.
</div>
<?php else: ?>
<table class="wp-list-table widefat fixed striped" id="wis-angebote-table">
<thead>
<tr>
<th style="width:55px;">Bild</th>
<th>Name</th>
<th style="width:160px;">Item-ID</th>
<th style="width:110px;">Normalpreis</th>
<th style="width:150px;">Angebotspreis</th>
<th style="width:100px;">Rabatt</th>
<th style="width:110px;">🏷️ Angebot</th>
<th style="width:120px;">🎁 Daily Deal</th>
<th style="width:80px;">Aktion</th>
</tr>
</thead>
<tbody>
<?php foreach ($items as $item):
$img_url = !empty($item->custom_image_url)
? esc_url($item->custom_image_url)
: $img_base . str_replace(':', '_', $item->item_id) . '.png';
$normal_price = intval($item->price);
$offer_price = intval($item->offer_price);
$discount_pct = ($normal_price > 0 && $offer_price > 0 && $offer_price < $normal_price)
? round((1 - $offer_price / $normal_price) * 100) : 0;
$is_daily = intval($item->is_daily_deal);
$is_offer = intval($item->is_offer);
$row_bg = $is_daily ? '#fffbe6' : ($is_offer ? '#f0fff4' : '');
?>
<tr id="wis-ang-row-<?php echo $item->id; ?>" style="<?php echo $row_bg ? "background:$row_bg;" : ''; ?>">
<td style="text-align:center;">
<img src="<?php echo $img_url; ?>" alt="<?php echo esc_attr($item->name); ?>"
style="width:40px;height:40px;object-fit:contain;background:#2d2d2d;border-radius:4px;padding:2px;"
onerror="this.style.opacity='0.2'">
</td>
<td>
<strong><?php echo esc_html($item->name); ?></strong>
<?php if ($is_daily) echo '<br><span style="font-size:11px;color:#6f42c1;font-weight:bold;">🎁 DAILY DEAL</span>'; ?>
<?php if ($is_offer && !$is_daily) echo '<br><span style="font-size:11px;color:#dc3545;font-weight:bold;">🔥 ANGEBOT</span>'; ?>
</td>
<td><code style="font-size:11px;"><?php echo esc_html($item->item_id); ?></code></td>
<td><?php echo number_format($normal_price); ?> <small><?php echo esc_html($currency); ?></small></td>
<td>
<div style="display:flex;align-items:center;gap:4px;">
<input type="number" class="wis-ang-price-input small-text"
data-id="<?php echo $item->id; ?>"
value="<?php echo $offer_price; ?>"
style="width:70px;text-align:right;" min="0">
<small><?php echo esc_html($currency); ?></small>
<button class="button button-small wis-ang-save-price" data-id="<?php echo $item->id; ?>"
title="Angebotspreis speichern" style="padding:0 6px;">💾</button>
</div>
</td>
<td>
<?php if ($discount_pct > 0): ?>
<span style="background:#28a745;color:#fff;border-radius:4px;padding:2px 7px;font-size:12px;font-weight:bold;">
<?php echo $discount_pct; ?>%
</span>
<?php else: ?>
<span style="color:#bbb;">—</span>
<?php endif; ?>
</td>
<td style="text-align:center;">
<label class="wis-ang-toggle" title="Angebot umschalten">
<input type="checkbox" class="wis-ang-flag"
data-id="<?php echo $item->id; ?>" data-field="is_offer"
<?php checked($is_offer, 1); ?>>
<span class="wis-ang-slider"></span>
</label>
</td>
<td style="text-align:center;">
<label class="wis-ang-toggle" title="Als Daily Deal setzen">
<input type="checkbox" class="wis-ang-flag"
data-id="<?php echo $item->id; ?>" data-field="is_daily_deal"
<?php checked($is_daily, 1); ?>>
<span class="wis-ang-slider"></span>
</label>
</td>
<td>
<a href="<?php echo esc_url(admin_url('admin.php?page=wis_items&edit=' . $item->id)); ?>"
class="button button-small" title="Item bearbeiten">✏️</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<p style="color:#888;font-size:12px;margin-top:8px;"><?php echo count($items); ?> Item(s) gefunden.</p>
<?php endif; ?>
</div>
<style>
.wis-ang-toggle { position:relative; display:inline-block; width:44px; height:24px; }
.wis-ang-toggle input { opacity:0; width:0; height:0; }
.wis-ang-slider { position:absolute; cursor:pointer; top:0; left:0; right:0; bottom:0; background:#ccc; transition:.3s; border-radius:24px; }
.wis-ang-slider:before { position:absolute; content:""; height:18px; width:18px; left:3px; bottom:3px; background:#fff; transition:.3s; border-radius:50%; }
.wis-ang-toggle input:checked + .wis-ang-slider { background:#28a745; }
.wis-ang-toggle input:checked + .wis-ang-slider:before { transform:translateX(20px); }
.wis-ang-toggle input:disabled + .wis-ang-slider { opacity:.5; cursor:not-allowed; }
#wis-angebote-table td, #wis-angebote-table th { vertical-align:middle; }
</style>
<script>
jQuery(function($) {
var nonce = <?php echo json_encode($nonce); ?>;
// Flag Toggle (is_offer / is_daily_deal)
$('.wis-ang-flag').on('change', function() {
var $cb = $(this);
var id = $cb.data('id');
var field = $cb.data('field');
$cb.prop('disabled', true);
$.post(ajaxurl, { action:'wis_angebote_toggle', nonce:nonce, id:id, field:field }, function(res) {
if (res.success) {
if (field === 'is_daily_deal' && res.data.new_val === 1) {
$('.wis-ang-flag[data-field="is_daily_deal"]').not($cb).prop('checked', false);
}
var $row = $('#wis-ang-row-' + id);
if (res.data.new_val === 1) {
$row.css('background', field === 'is_daily_deal' ? '#fffbe6' : '#f0fff4');
} else {
$row.css('background', '');
}
} else {
alert('Fehler: ' + (res.data || 'Unbekannt'));
$cb.prop('checked', !$cb.prop('checked'));
}
$cb.prop('disabled', false);
}).fail(function() {
alert('Verbindungsfehler.');
$cb.prop('checked', !$cb.prop('checked'));
$cb.prop('disabled', false);
});
});
// Angebotspreis speichern
$('.wis-ang-save-price').on('click', function() {
var $btn = $(this);
var id = $btn.data('id');
var price = $('#wis-ang-row-' + id).find('.wis-ang-price-input').val();
$btn.prop('disabled', true).text('…');
$.post(ajaxurl, { action:'wis_angebote_save_price', nonce:nonce, id:id, offer_price:price }, function(res) {
if (res.success) {
$btn.text('✅');
setTimeout(function() { $btn.prop('disabled', false).text('💾'); }, 1500);
} else {
alert('Fehler: ' + (res.data || 'Unbekannt'));
$btn.prop('disabled', false).text('💾');
}
}).fail(function() {
alert('Verbindungsfehler.');
$btn.prop('disabled', false).text('💾');
});
});
});
</script>
<?php
}
}