Prvi commit: Začetna verzija vtičnika Wheel of Fortune

This commit is contained in:
Mark Poljanšek committed 2025-06-22 12:50:46 +02:00
commit 0d28b08727
21 files changed
+13814

No files matched your search

+420
View File
@@ -0,0 +1,420 @@
<?php
/**
* Admin page for editing a single wheel and its prizes
*/
if (!defined('ABSPATH')) exit;
// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
if ($_POST['action'] === 'add_prize' && check_admin_referer('wheel_prizes_nonce')) {
global $wpdb;
$prizes_table = $wpdb->prefix . 'wheel_prizes';
$wheel_id = isset($_POST['wheel_id']) ? intval($_POST['wheel_id']) : 0;
$name = isset($_POST['prize_name']) ? sanitize_text_field($_POST['prize_name']) : '';
$description = isset($_POST['prize_description']) ? sanitize_textarea_field($_POST['prize_description']) : '';
$probability = isset($_POST['prize_probability']) ? floatval($_POST['prize_probability']) : 0;
$is_active = isset($_POST['prize_is_active']) ? 1 : 0;
$redemption_code = isset($_POST['prize_redemption_code']) ? sanitize_text_field($_POST['prize_redemption_code']) : '';
$is_discount = isset($_POST['prize_is_discount']) ? 1 : 0;
$discount_value = isset($_POST['prize_discount_value']) ? floatval($_POST['prize_discount_value']) : 0;
$email_subject = isset($_POST['prize_email_subject']) ? sanitize_text_field($_POST['prize_email_subject']) : '';
$email_template = isset($_POST['prize_email_template']) ? wp_kses_post($_POST['prize_email_template']) : '';
if (!empty($name) && $wheel_id > 0) {
$result = $wpdb->insert(
$prizes_table,
[
'wheel_id' => $wheel_id,
'name' => $name,
'description' => $description,
'probability' => $probability,
'is_active' => $is_active,
'redemption_code' => $redemption_code,
'is_discount' => $is_discount,
'discount_value' => $discount_value,
'email_subject' => $email_subject,
'email_template' => $email_template,
],
['%d', '%s', '%s', '%f', '%d', '%s', '%d', '%f', '%s', '%s']
);
if ($result !== false) {
echo '<div class="notice notice-success is-dismissible"><p>' . __('Prize added successfully!', 'wheel-of-fortune') . '</p></div>';
} else {
echo '<div class="notice notice-error is-dismissible"><p>' . __('Error adding prize. Please try again.', 'wheel-of-fortune') . '</p></div>';
}
} else {
echo '<div class="notice notice-error is-dismissible"><p>' . __('Please fill in all required fields.', 'wheel-of-fortune') . '</p></div>';
}
} elseif ($_POST['action'] === 'edit_prize' && check_admin_referer('wheel_prizes_nonce')) {
global $wpdb;
$prizes_table = $wpdb->prefix . 'wheel_prizes';
$prize_id = isset($_POST['prize_id']) ? intval($_POST['prize_id']) : 0;
$wheel_id = isset($_POST['wheel_id']) ? intval($_POST['wheel_id']) : 0;
$name = isset($_POST['prize_name']) ? sanitize_text_field($_POST['prize_name']) : '';
$description = isset($_POST['prize_description']) ? sanitize_textarea_field($_POST['prize_description']) : '';
$probability = isset($_POST['prize_probability']) ? floatval($_POST['prize_probability']) : 0;
$is_active = isset($_POST['prize_is_active']) ? 1 : 0;
$redemption_code = isset($_POST['prize_redemption_code']) ? sanitize_text_field($_POST['prize_redemption_code']) : '';
$is_discount = isset($_POST['prize_is_discount']) ? 1 : 0;
$discount_value = isset($_POST['prize_discount_value']) ? floatval($_POST['prize_discount_value']) : 0;
$email_subject = isset($_POST['prize_email_subject']) ? sanitize_text_field($_POST['prize_email_subject']) : '';
$email_template = isset($_POST['prize_email_template']) ? wp_kses_post($_POST['prize_email_template']) : '';
if (!empty($name) && $prize_id > 0 && $wheel_id > 0) {
$result = $wpdb->update(
$prizes_table,
[
'wheel_id' => $wheel_id,
'name' => $name,
'description' => $description,
'probability' => $probability,
'is_active' => $is_active,
'redemption_code' => $redemption_code,
'is_discount' => $is_discount,
'discount_value' => $discount_value,
'email_subject' => $email_subject,
'email_template' => $email_template,
],
['id' => $prize_id],
['%d', '%s', '%s', '%f', '%d', '%s', '%d', '%f', '%s', '%s'],
['%d']
);
if ($result !== false) {
echo '<div class="notice notice-success is-dismissible"><p>' . __('Prize updated successfully!', 'wheel-of-fortune') . '</p></div>';
} else {
echo '<div class="notice notice-error is-dismissible"><p>' . __('Error updating prize. Please try again.', 'wheel-of-fortune') . '</p></div>';
}
} else {
echo '<div class="notice notice-error is-dismissible"><p>' . __('Please fill in all required fields.', 'wheel-of-fortune') . '</p></div>';
}
}
}
if (
$_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) &&
in_array($_POST['action'], ['add_wheel_product', 'delete_wheel_product'])
) {
global $wpdb;
$wheels_table = $wpdb->prefix . 'wof_wheels';
$wheel_products_table = $wpdb->prefix . 'wheel_of_fortune_products';
if ($_POST['action'] === 'add_wheel_product' && check_admin_referer('wheel_products_nonce')) {
$wheel_id = isset($_POST['wheel_id']) ? intval($_POST['wheel_id']) : 0;
$product_id = isset($_POST['product_id']) ? intval($_POST['product_id']) : 0;
$spins_per_purchase = isset($_POST['spins_per_purchase']) ? intval($_POST['spins_per_purchase']) : 1;
// Debug informacije
error_log("=== WHEEL PRODUCT DEBUG ===");
error_log("POST data: " . print_r($_POST, true));
error_log("Wheel ID: " . $wheel_id);
error_log("Product ID: " . $product_id);
error_log("Spins per purchase: " . $spins_per_purchase);
error_log("Table name: " . $wheel_products_table);
// Preveri, ali tabela obstaja
$table_exists = $wpdb->get_var("SHOW TABLES LIKE '$wheel_products_table'") == $wheel_products_table;
error_log("Table exists: " . ($table_exists ? 'YES' : 'NO'));
if (!$table_exists) {
error_log("ERROR: Tabela $wheel_products_table ne obstaja!");
echo '<div class="notice notice-error is-dismissible"><p>' . __('Napaka: Tabela za produkte ne obstaja. Prosimo, deaktivirajte in ponovno aktivirajte plugin.', 'wheel-of-fortune') . '</p></div>';
return;
}
if ($wheel_id > 0 && $product_id > 0 && $spins_per_purchase > 0) {
// Preveri, ali kolo obstaja
$wheel_exists = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $wheels_table WHERE id = %d", $wheel_id));
error_log("Wheel exists: " . $wheel_exists);
if (!$wheel_exists) {
error_log("ERROR: Kolo z ID $wheel_id ne obstaja!");
echo '<div class="notice notice-error is-dismissible"><p>' . __('Napaka: Izbrano kolo ne obstaja.', 'wheel-of-fortune') . '</p></div>';
return;
}
// Preveri, ali produkt obstaja
if (class_exists('WooCommerce')) {
$product = wc_get_product($product_id);
if (!$product) {
error_log("ERROR: Produkt z ID $product_id ne obstaja!");
echo '<div class="notice notice-error is-dismissible"><p>' . __('Napaka: Izbrani produkt ne obstaja.', 'wheel-of-fortune') . '</p></div>';
return;
}
}
$data = [
'wheel_id' => $wheel_id,
'product_id' => $product_id,
'spins_per_purchase' => $spins_per_purchase
];
error_log("Data to insert: " . print_r($data, true));
// Preveri, ali je produkt že povezan s tem kolesom
$existing_product = $wpdb->get_var($wpdb->prepare(
"SELECT id FROM $wheel_products_table WHERE wheel_id = %d AND product_id = %d",
$wheel_id, $product_id
));
if ($existing_product) {
error_log("Product already exists for this wheel, updating...");
} else {
error_log("Adding new product to wheel...");
}
$result = $wpdb->replace(
$wheel_products_table,
$data,
['%d', '%d', '%d']
);
error_log("SQL result: " . $result);
error_log("Last SQL query: " . $wpdb->last_query);
error_log("Last SQL error: " . $wpdb->last_error);
if ($result !== false) {
echo '<div class="notice notice-success is-dismissible"><p>' . __('Produkt je bil uspešno dodan ali posodobljen.', 'wheel-of-fortune') . '</p></div>';
} else {
echo '<div class="notice notice-error is-dismissible"><p>' . __('Napaka pri dodajanju produkta. Preveri vnos.', 'wheel-of-fortune') . '</p></div>';
}
} else {
error_log("Validation failed - Wheel ID: $wheel_id, Product ID: $product_id, Spins: $spins_per_purchase");
echo '<div class="notice notice-error is-dismissible"><p>' . __('Napaka pri dodajanju produkta. Preveri vnos.', 'wheel-of-fortune') . '</p></div>';
}
} elseif ($_POST['action'] === 'delete_wheel_product' && check_admin_referer('wheel_products_nonce')) {
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
if ($id > 0) {
$wpdb->delete($wheel_products_table, ['id' => $id], ['%d']);
echo '<div class="notice notice-success is-dismissible"><p>' . __('Produkt je bil izbrisan.', 'wheel-of-fortune') . '</p></div>';
}
}
}
global $wpdb;
$wheels_table = $wpdb->prefix . 'wof_wheels';
$prizes_table = $wpdb->prefix . 'wheel_prizes';
// Get the current wheel ID from URL
$wheel_id = isset($_GET['wheel_id']) ? intval($_GET['wheel_id']) : 0;
// Fetch wheel data
$wheel = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wheels_table WHERE id = %d", $wheel_id), ARRAY_A);
if (!$wheel) {
echo '<div class="notice notice-error"><p>' . __('Wheel not found.', 'wheel-of-fortune') . '</p></div>';
return;
}
// Fetch prizes for this specific wheel
$prizes = $wpdb->get_results($wpdb->prepare("SELECT * FROM $prizes_table WHERE wheel_id = %d ORDER BY id ASC", $wheel_id), ARRAY_A);
$total_probability = array_sum(wp_list_pluck($prizes, 'probability'));
// Fetch povezane produkte za to kolo
$wheel_products_table = $wpdb->prefix . 'wheel_of_fortune_products';
$products = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wheel_products_table WHERE wheel_id = %d", $wheel_id), ARRAY_A);
// Pridobi vse WooCommerce produkte za dropdown
if (class_exists('WooCommerce')) {
$all_products = wc_get_products(array('limit' => -1, 'status' => 'publish'));
} else {
$all_products = array();
}
?>
<div class="wrap wheel-admin-page">
<h1><?php printf(__('Editing Wheel: %s', 'wheel-of-fortune'), esc_html($wheel['name'])); ?></h1>
<a href="<?php echo admin_url('admin.php?page=wof-wheels'); ?>">&larr; <?php _e('Back to all wheels', 'wheel-of-fortune'); ?></a>
<hr class="wp-header-end">
<div class="wheel-card">
<h2><?php echo esc_html__('Prizes for this Wheel', 'wheel-of-fortune'); ?></h2>
<?php if ($total_probability > 1): ?>
<div class="notice notice-error"><p><?php printf(__('Warning: The total probability is %s, which is greater than 1 (100%%). Please adjust.', 'wheel-of-fortune'), '<strong>' . esc_html($total_probability) . '</strong>'); ?></p></div>
<?php elseif ($total_probability > 0 && $total_probability < 1): ?>
<div class="notice notice-warning"><p><?php printf(__('Notice: The total probability is %s, which is less than 1 (100%%).', 'wheel-of-fortune'), '<strong>' . esc_html($total_probability) . '</strong>'); ?></p></div>
<?php endif; ?>
<p><button class="button button-primary add-new-prize"><?php _e('Add New Prize', 'wheel-of-fortune'); ?></button></p>
<table class="wheel-prizes-table widefat fixed striped">
<thead>
<tr>
<th><?php _e('ID', 'wheel-of-fortune'); ?></th>
<th><?php _e('Name', 'wheel-of-fortune'); ?></th>
<th><?php _e('Description', 'wheel-of-fortune'); ?></th>
<th><?php _e('Probability', 'wheel-of-fortune'); ?></th>
<th><?php _e('Status', 'wheel-of-fortune'); ?></th>
<th><?php _e('Actions', 'wheel-of-fortune'); ?></th>
</tr>
</thead>
<tbody>
<?php if (empty($prizes)): ?>
<tr><td colspan="6"><?php _e('No prizes found. Add your first prize using the button above.', 'wheel-of-fortune'); ?></td></tr>
<?php else: ?>
<?php foreach ($prizes as $prize): ?>
<tr>
<td><?php echo esc_html($prize['id']); ?></td>
<td><?php echo esc_html($prize['name']); ?></td>
<td><?php echo esc_html($prize['description']); ?></td>
<td><?php echo esc_html($prize['probability']); ?></td>
<td><?php echo $prize['is_active'] ? __('Active', 'wheel-of-fortune') : __('Inactive', 'wheel-of-fortune'); ?></td>
<td>
<button class="button edit-prize" data-id="<?php echo esc_attr($prize['id']); ?>"><?php _e('Edit', 'wheel-of-fortune'); ?></button>
<button class="button delete-prize" data-id="<?php echo esc_attr($prize['id']); ?>"><?php _e('Delete', 'wheel-of-fortune'); ?></button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<div class="wheel-card">
<h2><?php echo esc_html__('Add New Prize to this Wheel', 'wheel-of-fortune'); ?></h2>
<form method="post" action="">
<?php wp_nonce_field('wheel_prizes_nonce'); ?>
<input type="hidden" name="action" value="add_prize">
<input type="hidden" name="wheel_id" value="<?php echo esc_attr($wheel_id); ?>">
<table class="wheel-form-table">
<?php include 'partials/prize-form-fields.php'; ?>
</table>
<p class="submit"><input type="submit" class="button button-primary" value="<?php esc_attr_e('Add Prize', 'wheel-of-fortune'); ?>"></p>
</form>
</div>
<div class="wheel-card">
<h2><?php echo esc_html__('Produkti & spini', 'wheel-of-fortune'); ?></h2>
<table class="wheel-products-table widefat fixed striped">
<thead>
<tr>
<th><?php _e('Produkt', 'wheel-of-fortune'); ?></th>
<th><?php _e('Število spinov na nakup', 'wheel-of-fortune'); ?></th>
<th><?php _e('Akcije', 'wheel-of-fortune'); ?></th>
</tr>
</thead>
<tbody>
<?php if (empty($products)): ?>
<tr><td colspan="3"><?php _e('Ni povezanih produktov.', 'wheel-of-fortune'); ?></td></tr>
<?php else: ?>
<?php foreach ($products as $prod): ?>
<?php $wc_product = wc_get_product($prod['product_id']); ?>
<tr>
<td><?php echo $wc_product ? esc_html($wc_product->get_name()) : esc_html($prod['product_id']); ?></td>
<td class="spins-editable" data-id="<?php echo esc_attr($prod['id']); ?>"><?php echo intval($prod['spins_per_purchase']); ?></td>
<td>
<button class="button edit-wheel-product" data-id="<?php echo esc_attr($prod['id']); ?>"><?php _e('Uredi', 'wheel-of-fortune'); ?></button>
<button class="button delete-wheel-product" data-id="<?php echo esc_attr($prod['id']); ?>"><?php _e('Izbriši', 'wheel-of-fortune'); ?></button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<h3><?php _e('Dodaj produkt', 'wheel-of-fortune'); ?></h3>
<form method="post" action="">
<?php wp_nonce_field('wheel_products_nonce'); ?>
<input type="hidden" name="action" value="add_wheel_product">
<input type="hidden" name="wheel_id" value="<?php echo esc_attr($wheel_id); ?>">
<p>
<label for="product_id"><?php _e('Izberi produkt:', 'wheel-of-fortune'); ?></label>
<select name="product_id" id="product_id" required>
<option value=""><?php _e('Izberi produkt', 'wheel-of-fortune'); ?></option>
<?php foreach ($all_products as $product): ?>
<option value="<?php echo esc_attr($product->get_id()); ?>"><?php echo esc_html($product->get_name()); ?></option>
<?php endforeach; ?>
</select>
</p>
<p>
<label for="spins_per_purchase"><?php _e('Število spinov na nakup:', 'wheel-of-fortune'); ?></label>
<input type="number" name="spins_per_purchase" id="spins_per_purchase" min="1" value="1" required style="width: 80px;">
</p>
<p class="submit">
<input type="submit" class="button button-primary" value="<?php esc_attr_e('Dodaj', 'wheel-of-fortune'); ?>">
</p>
</form>
</div>
</div>
<!-- Edit Prize Modal (ostaja večinoma nespremenjen, wheel_id se doda dinamično z JS) -->
<div id="edit-prize-modal" style="display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.4);" data-wheel-id="<?php echo esc_attr($wheel_id); ?>">
<div style="background-color: #fefefe; margin: 5% auto; padding: 20px; border: 1px solid #888; width: 60%; max-width: 700px;">
<span class="close" style="color: #aaa; float: right; font-size: 28px; font-weight: bold; cursor: pointer;">×</span>
<h2><?php echo esc_html__('Edit Prize', 'wheel-of-fortune'); ?></h2>
<form id="edit-prize-form" method="post" action="">
<?php wp_nonce_field('wheel_prizes_nonce'); ?>
<input type="hidden" name="action" value="edit_prize">
<input type="hidden" id="edit-prize-id" name="prize_id" value="">
<input type="hidden" id="edit-wheel-id" name="wheel_id" value="<?php echo esc_attr($wheel_id); ?>">
<table class="wheel-form-table">
<tr><th scope="row"><label for="edit-prize-name"><?php _e('Prize Name', 'wheel-of-fortune'); ?></label></th><td><input type="text" id="edit-prize-name" name="prize_name" class="regular-text" required></td></tr>
<tr><th scope="row"><label for="edit-prize-description"><?php _e('Description', 'wheel-of-fortune'); ?></label></th><td><textarea id="edit-prize-description" name="prize_description" rows="3" class="large-text"></textarea></td></tr>
<tr><th scope="row"><label for="edit-prize-probability"><?php _e('Probability', 'wheel-of-fortune'); ?></label></th><td><input type="number" id="edit-prize-probability" name="prize_probability" step="any" min="0" max="1" required><p class="description"><?php _e('Enter a value between 0 and 1. Use 0 for prizes that cannot be won.', 'wheel-of-fortune'); ?></p></td></tr>
<tr><th scope="row"><?php _e('Status', 'wheel-of-fortune'); ?></th><td><label for="edit-prize-is-active"><input type="checkbox" id="edit-prize-is-active" name="prize_is_active" value="1"><?php _e('Prize is active', 'wheel-of-fortune'); ?></label></td></tr>
<tr><th scope="row"><label for="edit-prize-redemption-code"><?php _e('Redemption Code', 'wheel-of-fortune'); ?></label></th><td><input type="text" id="edit-prize-redemption-code" name="prize_redemption_code" class="regular-text"><p class="description"><?php _e('Optional code for the user to redeem the prize.', 'wheel-of-fortune'); ?></p></td></tr>
<tr><th scope="row"><label for="edit-prize-is-discount"><?php _e('Is Discount?', 'wheel-of-fortune'); ?></label></th><td><input type="checkbox" id="edit-prize-is-discount" name="prize_is_discount" value="1"><p class="description"><?php _e('Check if the prize is a discount.', 'wheel-of-fortune'); ?></p></td></tr>
<tr><th scope="row"><label for="edit-prize-discount-value"><?php _e('Discount Value (%)', 'wheel-of-fortune'); ?></label></th><td><input type="number" id="edit-prize-discount-value" name="prize_discount_value" step="0.01" min="0" max="100"><p class="description"><?php _e('Enter the discount value in %.', 'wheel-of-fortune'); ?></p></td></tr>
<tr><th scope="row"><label for="edit-prize-email-subject"><?php _e('Email Subject', 'wheel-of-fortune'); ?></label></th><td><input type="text" id="edit-prize-email-subject" name="prize_email_subject" class="large-text"><p class="description"><?php _e('Subject for this prize\'s email. If empty, the default subject will be used.', 'wheel-of-fortune'); ?></p></td></tr>
<tr><th scope="row"><label for="edit-prize-email-template"><?php _e('Email Template', 'wheel-of-fortune'); ?></label></th><td><textarea id="edit-prize-email-template" name="prize_email_template" rows="10" class="large-text code"></textarea><p class="description"><?php _e('Available template tags:', 'wheel-of-fortune'); ?> <code>{user_name}</code>, <code>{prize_name}</code>, etc.</p></td></tr>
</table>
<p class="submit"><input type="submit" class="button button-primary" value="<?php esc_attr_e('Save Changes', 'wheel-of-fortune'); ?>"></p>
</form>
</div>
</div>
<script>
jQuery(document).ready(function($) {
$('.delete-wheel-product').on('click', function(e) {
e.preventDefault();
if (!confirm('Ali res želiš izbrisati ta produkt?')) return;
var row = $(this).closest('tr');
var id = $(this).data('id');
$.post(ajaxurl, {
action: 'wof_delete_wheel_product',
id: id,
_ajax_nonce: '<?php echo wp_create_nonce('wof_delete_wheel_product'); ?>'
}, function(response) {
if (response.success) {
row.fadeOut(300, function() { $(this).remove(); });
} else {
alert(response.data || 'Napaka pri brisanju.');
}
});
});
$('.spins-editable').on('click', function() {
var td = $(this);
if (td.find('input').length) return;
var current = td.text();
var id = td.data('id');
var input = $('<input type="number" min="1" style="width:60px;">').val(current);
td.html(input);
input.focus();
input.on('blur', function() {
var val = input.val();
if (val && val != current) {
$.post(ajaxurl, {
action: 'wof_update_wheel_product_spins',
id: id,
spins: val,
_ajax_nonce: '<?php echo wp_create_nonce('wof_update_wheel_product_spins'); ?>'
}, function(response) {
if (response.success) {
td.text(val);
} else {
alert(response.data || 'Napaka pri shranjevanju.');
td.text(current);
}
});
} else {
td.text(current);
}
});
});
});
</script>