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

+357
View File
@@ -0,0 +1,357 @@
<?php
/**
* Testna skripta za preverjanje različnih načinov ustvarjanja WooCommerce kuponov
*/
// Prepreči neposreden dostop
if (!defined('ABSPATH')) {
exit;
}
/**
* Razred za testiranje različnih metod ustvarjanja WooCommerce kuponov
*/
class WheelCouponTester {
/**
* Zažene različne teste za ustvarjanje kuponov
*
* @return array Rezultati testov
*/
public static function run_tests() {
$results = array(
'success' => false,
'message' => '',
'tests' => array(),
'working_method' => null
);
// Preveri, ali je WooCommerce aktiven
if (!class_exists('WooCommerce')) {
$results['message'] = 'WooCommerce ni aktiven. Prosim aktivirajte WooCommerce vtičnik.';
return $results;
}
// Pridobi trenutnega uporabnika za testiranje
$user = wp_get_current_user();
if (!$user || !$user->exists()) {
$results['message'] = 'Uporabnik ni prijavljen. Prijavite se kot administrator.';
return $results;
}
// Nastavi testno kodo
$test_code = 'TEST-' . strtoupper(substr(bin2hex(random_bytes(4)), 0, 8));
// Test 1: Standardna WooCommerce API metoda
$results['tests']['standard_api'] = self::test_standard_api($test_code . '-1', $user);
// Test 2: Programsko ustvarjanje kupona
$results['tests']['programmatic'] = self::test_programmatic($test_code . '-2', $user);
// Test 3: Uporaba WC_Coupon z dodatnimi preverjanji
$results['tests']['wc_coupon_extended'] = self::test_wc_coupon_extended($test_code . '-3', $user);
// Test 4: Neposredno vstavljanje v podatkovno bazo
$results['tests']['direct_db'] = self::test_direct_db($test_code . '-4', $user);
// Počisti testne kupone
self::cleanup_test_coupons($test_code);
// Določi, katera metoda deluje
foreach ($results['tests'] as $method => $test_result) {
if ($test_result['success']) {
$results['working_method'] = $method;
$results['success'] = true;
break;
}
}
if ($results['success']) {
$results['message'] = 'Našli smo delujočo metodo za ustvarjanje kuponov: ' . $results['working_method'];
} else {
$results['message'] = 'Nobena testirana metoda ne deluje. Preverite dnevnik napak za več informacij.';
}
return $results;
}
/**
* Test 1: Standardna WooCommerce API metoda
*/
private static function test_standard_api($code, $user) {
$result = array(
'success' => false,
'message' => '',
'coupon_id' => 0
);
try {
$coupon = new WC_Coupon();
$coupon->set_code($code);
$coupon->set_description('Test coupon');
$coupon->set_discount_type('percent');
$coupon->set_amount(10);
$coupon->set_individual_use(true);
$coupon->set_usage_limit(1);
$coupon->set_usage_limit_per_user(1);
$coupon->set_email_restrictions(array($user->user_email));
$coupon_id = $coupon->save();
if ($coupon_id) {
$result['success'] = true;
$result['message'] = 'Kupon uspešno ustvarjen z ID: ' . $coupon_id;
$result['coupon_id'] = $coupon_id;
} else {
$result['message'] = 'Napaka: Kupon ni bil ustvarjen (save() je vrnil 0)';
}
} catch (Exception $e) {
$result['message'] = 'Napaka: ' . $e->getMessage();
}
return $result;
}
/**
* Test 2: Programsko ustvarjanje kupona
*/
private static function test_programmatic($code, $user) {
$result = array(
'success' => false,
'message' => '',
'coupon_id' => 0
);
try {
// Ustvari nov post tipa shop_coupon
$coupon_data = array(
'post_title' => $code,
'post_content' => '',
'post_status' => 'publish',
'post_author' => $user->ID,
'post_type' => 'shop_coupon'
);
$coupon_id = wp_insert_post($coupon_data);
if (!is_wp_error($coupon_id)) {
// Dodaj meta podatke za kupon
update_post_meta($coupon_id, 'discount_type', 'percent');
update_post_meta($coupon_id, 'coupon_amount', '10');
update_post_meta($coupon_id, 'individual_use', 'yes');
update_post_meta($coupon_id, 'usage_limit', '1');
update_post_meta($coupon_id, 'usage_limit_per_user', '1');
update_post_meta($coupon_id, 'customer_email', array($user->user_email));
$result['success'] = true;
$result['message'] = 'Kupon uspešno ustvarjen z ID: ' . $coupon_id;
$result['coupon_id'] = $coupon_id;
} else {
$result['message'] = 'Napaka: ' . $coupon_id->get_error_message();
}
} catch (Exception $e) {
$result['message'] = 'Napaka: ' . $e->getMessage();
}
return $result;
}
/**
* Test 3: Uporaba WC_Coupon z dodatnimi preverjanji
*/
private static function test_wc_coupon_extended($code, $user) {
$result = array(
'success' => false,
'message' => '',
'coupon_id' => 0
);
try {
// Preveri, ali koda že obstaja
$existing_id = wc_get_coupon_id_by_code($code);
if ($existing_id) {
$result['message'] = 'Napaka: Kupon s to kodo že obstaja (ID: ' . $existing_id . ')';
return $result;
}
// Ustvari nov kupon z dodatnimi preverjanji
$coupon = new WC_Coupon();
$coupon->set_code($code);
$coupon->set_description('Test coupon with extended checks');
$coupon->set_discount_type('percent');
$coupon->set_amount(10);
$coupon->set_individual_use(true);
$coupon->set_usage_limit(1);
$coupon->set_usage_limit_per_user(1);
$coupon->set_email_restrictions(array($user->user_email));
// Dodatna nastavitev
$coupon->set_date_expires(strtotime('+7 days'));
$coupon_id = $coupon->save();
// Preveri, ali je kupon res ustvarjen
if ($coupon_id) {
$verification_id = wc_get_coupon_id_by_code($code);
if ($verification_id && $verification_id == $coupon_id) {
$result['success'] = true;
$result['message'] = 'Kupon uspešno ustvarjen in preverjen z ID: ' . $coupon_id;
$result['coupon_id'] = $coupon_id;
} else {
$result['message'] = 'Napaka: Kupon je bil ustvarjen, vendar preverjanje ni uspelo';
}
} else {
$result['message'] = 'Napaka: Kupon ni bil ustvarjen (save() je vrnil 0)';
}
} catch (Exception $e) {
$result['message'] = 'Napaka: ' . $e->getMessage();
}
return $result;
}
/**
* Test 4: Neposredno vstavljanje v podatkovno bazo
*/
private static function test_direct_db($code, $user) {
$result = array(
'success' => false,
'message' => '',
'coupon_id' => 0
);
try {
global $wpdb;
// Ustvari nov post tipa shop_coupon
$wpdb->insert(
$wpdb->posts,
array(
'post_title' => $code,
'post_name' => sanitize_title($code),
'post_content' => '',
'post_status' => 'publish',
'post_author' => $user->ID,
'post_type' => 'shop_coupon',
'post_date' => current_time('mysql'),
'post_date_gmt' => current_time('mysql', 1)
)
);
$coupon_id = $wpdb->insert_id;
if ($coupon_id) {
// Dodaj meta podatke za kupon
$meta_data = array(
'discount_type' => 'percent',
'coupon_amount' => '10',
'individual_use' => 'yes',
'usage_limit' => '1',
'usage_limit_per_user' => '1',
'customer_email' => serialize(array($user->user_email))
);
foreach ($meta_data as $meta_key => $meta_value) {
$wpdb->insert(
$wpdb->postmeta,
array(
'post_id' => $coupon_id,
'meta_key' => $meta_key,
'meta_value' => $meta_value
)
);
}
$result['success'] = true;
$result['message'] = 'Kupon uspešno ustvarjen neposredno v bazi z ID: ' . $coupon_id;
$result['coupon_id'] = $coupon_id;
} else {
$result['message'] = 'Napaka: Kupon ni bil ustvarjen v bazi';
}
} catch (Exception $e) {
$result['message'] = 'Napaka: ' . $e->getMessage();
}
return $result;
}
/**
* Počisti testne kupone
*/
private static function cleanup_test_coupons($prefix) {
global $wpdb;
// Poišči vse testne kupone
$test_coupons = $wpdb->get_results(
$wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_title LIKE %s AND post_type = 'shop_coupon'",
$prefix . '%'
)
);
// Izbriši najdene kupone
foreach ($test_coupons as $coupon) {
wp_delete_post($coupon->ID, true);
}
}
}
/**
* Funkcija za obdelavo AJAX zahteve za testiranje kuponov
*/
function wheel_test_coupons_ajax() {
// Preveri varnostno kodo
check_ajax_referer('wheel_admin_nonce', 'nonce');
// Preveri pravice
if (!current_user_can('manage_options')) {
wp_send_json_error(array('message' => 'Nimate pravic za izvedbo tega dejanja.'));
return;
}
// Zaženi teste
$results = WheelCouponTester::run_tests();
// Vrni rezultate
if ($results['success']) {
wp_send_json_success($results);
} else {
wp_send_json_error($results);
}
}
add_action('wp_ajax_wheel_test_coupons', 'wheel_test_coupons_ajax');
/**
* Shrani najboljšo metodo za ustvarjanje kuponov
*/
function wheel_save_best_coupon_method() {
// Preveri varnostno kodo
check_ajax_referer('wheel_admin_nonce', 'nonce');
// Preveri pravice
if (!current_user_can('manage_options')) {
wp_send_json_error(array('message' => 'Nimate pravic za izvedbo tega dejanja.'));
return;
}
// Preveri, ali je metoda podana
if (!isset($_POST['method']) || empty($_POST['method'])) {
wp_send_json_error(array('message' => 'Metoda ni podana.'));
return;
}
$method = sanitize_text_field($_POST['method']);
$valid_methods = array('standard_api', 'programmatic', 'wc_coupon_extended', 'direct_db');
if (!in_array($method, $valid_methods)) {
wp_send_json_error(array('message' => 'Neveljavna metoda.'));
return;
}
// Shrani najboljšo metodo
update_option('wheel_best_coupon_method', $method);
wp_send_json_success(array(
'message' => sprintf(__('Metoda %s je bila uspešno shranjena kot najboljša metoda za ustvarjanje kuponov.', 'wheel-of-fortune'), $method)
));
}
add_action('wp_ajax_wheel_save_best_coupon_method', 'wheel_save_best_coupon_method');
+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>
+285
View File
@@ -0,0 +1,285 @@
jQuery(document).ready(function($) {
'use strict';
// Only run on our plugin's admin pages
if (!$('.wheel-admin-page').length) {
return;
}
// Tab navigation
$('.nav-tab').on('click', function(e) {
e.preventDefault();
$('.nav-tab').removeClass('nav-tab-active');
$(this).addClass('nav-tab-active');
$('.wheel-tab-content').hide();
$('#' + $(this).data('target')).show();
});
// --- Modal Logic ---
var modal = $('#edit-prize-modal');
var span = modal.find('.close');
// Close modal
span.on('click', function() {
modal.hide();
});
$(window).on('click', function(event) {
if ($(event.target).is(modal)) {
modal.hide();
}
});
// --- Add New Prize ---
$('.add-new-prize').on('click', function(e) {
e.preventDefault();
// Clear form for new prize
$('#edit-prize-form')[0].reset();
$('#edit-prize-id').val(''); // Clear prize ID for new prize
// Get wheel_id from the modal's data attribute
var wheelId = $('#edit-prize-modal').data('wheel-id');
$('#edit-wheel-id').val(wheelId);
console.log('Opening modal for new prize with wheel_id:', wheelId);
modal.show();
});
// --- Edit Prize ---
$('.edit-prize').on('click', function(e) {
e.preventDefault();
var prizeId = $(this).data('id');
// AJAX call to get prize details
$.post(ajaxurl, {
action: 'wheel_get_prize_details',
_ajax_nonce: wheel_admin_nonce._ajax_nonce,
prize_id: prizeId
}, function(response) {
if (response.success) {
var prize = response.data;
// Populate form
$('#edit-prize-id').val(prize.id);
$('#edit-wheel-id').val(prize.wheel_id); // wheel_id je že v formi
$('#edit-prize-name').val(prize.name);
$('#edit-prize-description').val(prize.description);
$('#edit-prize-probability').val(prize.probability);
$('#edit-prize-is-active').prop('checked', parseInt(prize.is_active, 10));
$('#edit-prize-redemption-code').val(prize.redemption_code);
$('#edit-prize-is-discount').prop('checked', parseInt(prize.is_discount, 10));
$('#edit-prize-discount-value').val(prize.discount_value);
$('#edit-prize-email-subject').val(prize.email_subject);
$('#edit-prize-email-template').val(prize.email_template);
modal.show();
} else {
alert(response.data.message || 'An error occurred.');
}
}).fail(function() {
alert('An error occurred while loading prize details.');
});
});
// --- Save Prize (via AJAX) ---
$('#edit-prize-form').on('submit', function(e) {
e.preventDefault();
// Pripravimo podatke iz forme
const formData = {
action: 'wheel_save_prize',
_ajax_nonce: wheel_admin_nonce._ajax_nonce,
wheel_id: $('#edit-wheel-id').val(), // **KLJUČNO: pošljemo wheel_id**
prize_id: $('#edit-prize-id').val(),
name: $('#edit-prize-name').val(),
description: $('#edit-prize-description').val(),
probability: $('#edit-prize-probability').val(),
is_active: $('#edit-prize-is-active').is(':checked') ? 1 : 0,
redemption_code: $('#edit-prize-redemption-code').val(),
is_discount: $('#edit-prize-is-discount').is(':checked') ? 1 : 0,
discount_value: $('#edit-prize-discount-value').val(),
email_subject: $('#edit-prize-email-subject').val(),
email_template: $('#edit-prize-email-template').val(),
};
// Debug: preveri wheel_id
console.log('Wheel ID from form:', formData.wheel_id);
console.log('Form data:', formData);
// Validate form fields
if (!formData.name) {
alert('Prize name is required.');
return;
}
if (isNaN(parseFloat(formData.probability)) || formData.probability < 0 || formData.probability > 1) {
alert('Probability must be a number between 0 and 1.');
return;
}
if (!formData.wheel_id || formData.wheel_id == 0) {
alert('Wheel ID is missing. Please refresh the page and try again.');
return;
}
// AJAX call to save the prize
$.post(ajaxurl, formData, function(response) {
console.log('Server response:', response);
if (response.success) {
alert(response.data.message);
modal.hide();
location.reload(); // Refresh page to see changes
} else {
alert(response.data.message || 'An error occurred while saving.');
}
}).fail(function(xhr, status, error) {
console.error('AJAX error:', {xhr: xhr, status: status, error: error});
alert('A critical error occurred. Please try again.');
});
});
// --- Delete Prize ---
$('.delete-prize').on('click', function(e) {
e.preventDefault();
if (confirm('Are you sure you want to delete this prize?')) {
var prizeId = $(this).data('id');
$.post(ajaxurl, {
action: 'wheel_delete_prize',
_ajax_nonce: wheel_admin_nonce._ajax_nonce,
prize_id: prizeId
}, function(response) {
if (response.success) {
alert(response.data.message);
location.reload();
} else {
alert(response.data.message || 'An error occurred.');
}
});
}
});
// --- SETTINGS PAGE - TEST EMAIL ---
if ($('#test-email-button').length) {
$('#test-email-button').on('click', function(e) {
e.preventDefault();
const button = $(this);
const resultDiv = $('#test-email-result');
const recipientEmail = $('#test-email-recipient').val();
const spinner = button.siblings('.spinner');
if (!recipientEmail) {
alert(wheel_admin_i18n.enter_recipient_email || 'Please enter a recipient email address.');
return;
}
button.prop('disabled', true);
spinner.addClass('is-active');
resultDiv.slideUp().removeClass('notice notice-success notice-error is-dismissible').empty();
// Collect all settings from the form to test unsaved values
const data = {
action: 'wheel_test_email',
_ajax_nonce: wheel_admin_nonce._ajax_nonce,
recipient_email: recipientEmail,
smtp_enabled: $('#wheel_smtp_enabled').is(':checked') ? '1' : '0',
smtp_host: $('#wheel_smtp_host').val(),
smtp_port: $('#wheel_smtp_port').val(),
smtp_encryption: $('#wheel_smtp_encryption').val(),
smtp_username: $('#wheel_smtp_username').val(),
smtp_password: $('#wheel_smtp_password').val(),
from_name: $('#wheel_email_from_name').val(),
from_email: $('#wheel_email_from_email').val(),
};
$.ajax({
url: ajaxurl,
method: 'POST',
data: data,
success: function(response) {
if (response.success) {
resultDiv.addClass('notice notice-success is-dismissible').html('<p>' + response.data.message + '</p>').slideDown();
} else {
const errorMessage = response.data.message || (wheel_admin_i18n.error_sending_email || 'An unknown error occurred.');
resultDiv.addClass('notice notice-error is-dismissible').html('<p>' + errorMessage + '</p>').slideDown();
}
},
error: function(xhr) {
let errorMessage = wheel_admin_i18n.error_sending_email || 'A communication error occurred with the server.';
if(xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) {
errorMessage = xhr.responseJSON.data.message;
}
resultDiv.addClass('notice notice-error is-dismissible').html('<p>' + errorMessage + '</p>').slideDown();
},
complete: function() {
button.prop('disabled', false);
spinner.removeClass('is-active');
}
});
});
}
// Dodajanje/brisanje produkta za spine
$('#add-product-button').on('click', function() {
const button = $(this);
const productId = $('#new-product-id').val();
const spins = $('#new-product-spins').val();
const wheelId = button.data('wheel-id');
if (!productId || !spins) {
alert('Prosim vnesite ID produkta in število spinov.');
return;
}
$.ajax({
url: ajaxurl,
method: 'POST',
data: {
action: 'ajax_update_wheel_product_spins',
_ajax_nonce: wheel_admin_nonce._ajax_nonce,
wheel_id: wheelId,
product_id: productId,
spins: spins
},
success: function(response) {
if(response.success) {
location.reload();
} else {
alert('Napaka: ' + response.data.message);
}
},
error: function() {
alert('Prišlo je do kritične napake.');
}
});
});
$('.delete-product-button').on('click', function() {
if(!confirm('Ste prepričani?')) return;
const button = $(this);
const productId = button.data('product-id');
const wheelId = button.data('wheel-id');
$.ajax({
url: ajaxurl,
method: 'POST',
data: {
action: 'ajax_delete_wheel_product',
_ajax_nonce: wheel_admin_nonce._ajax_nonce,
wheel_id: wheelId,
product_id: productId
},
success: function(response) {
if(response.success) {
location.reload();
} else {
alert('Napaka: ' + response.data.message);
}
},
error: function() {
alert('Prišlo je do kritične napake.');
}
});
});
});
+157
View File
@@ -0,0 +1,157 @@
/**
* Wheel of Fortune - JavaScript for wheel functionality
* Robust, smooth animation using requestAnimationFrame and easing functions.
*/
jQuery(document).ready(function($) {
// Check if wheelSettings are available
if (typeof wheelSettings === 'undefined') {
console.error('Wheel of Fortune: Settings (wheelSettings) are not defined. Please check the plugin setup.');
return;
}
// Elements
const wheel = $('.wheel');
const button = $('.wheel-button');
const resultDiv = $('.wheel-result');
const spinsCounter = $('.wheel-spins-counter span');
// Animation state
let isSpinning = false;
let animationFrameId = null;
let accumulatedRotation = 0; // Total rotation is maintained between spins
// Animation settings
const spinDuration = 8000; // 8 seconds for a more dramatic effect
const spinRotations = 5; // Number of full rotations before stopping
/**
* Easing function (cubic-bezier out) for natural deceleration
* @param {number} t - Current time (0 to 1)
* @returns {number} - Animation progress (0 to 1)
*/
function easeOutCubic(t) {
return 1 - Math.pow(1 - t, 3);
}
/**
* Main animation loop
* @param {number} startTime - Animation start time
* @param {number} startRotation - Starting rotation angle
* @param {number} rotationAmount - Total rotation to perform for this spin
*/
function animateWheel(startTime, startRotation, rotationAmount) {
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
if (elapsedTime >= spinDuration) {
wheel.css('transform', `rotate(${startRotation + rotationAmount}deg)`);
accumulatedRotation = startRotation + rotationAmount; // Update the final position
finishSpin();
return;
}
// Calculate progress within the animation duration
const timeProgress = elapsedTime / spinDuration;
// Apply the easing function to determine the rotation progress
const rotationProgress = easeOutCubic(timeProgress);
// Calculate the current rotation
const newRotation = startRotation + (rotationAmount * rotationProgress);
wheel.css('transform', `rotate(${newRotation}deg)`);
// Continue to the next frame
animationFrameId = requestAnimationFrame(() => animateWheel(startTime, startRotation, rotationAmount));
}
/**
* Function to execute after the spin animation is complete
*/
function finishSpin() {
// Display the result with a slight delay for better effect
setTimeout(() => {
const prize = window.spinResult.prize;
resultDiv.html(`<h3>Congratulations!</h3><p>You've won: <strong>${prize.name}</strong></p>`);
resultDiv.addClass('win').fadeIn(300);
isSpinning = false;
// Re-enable the button if there are remaining spins
if (window.spinResult.remaining_spins > 0) {
button.prop('disabled', false);
} else {
button.prop('disabled', true);
}
}, 500); // 500ms pause before showing the result
}
// Spin button click handler
button.on('click', function() {
if (isSpinning) return;
isSpinning = true;
button.prop('disabled', true);
resultDiv.hide().removeClass('win error');
$.ajax({
url: wheelSettings.ajaxUrl,
method: 'POST',
data: {
action: 'wheel_spin',
nonce: wheelSettings.nonce
},
beforeSend: function(xhr) {
xhr.setRequestHeader('X-WP-Nonce', wheelSettings.nonce);
},
success: function(response) {
if (response.success) {
window.spinResult = response;
// The target angle (0-360) for the wheel to stop at, sent by the server.
const targetAngle = response.degree;
// Add several full rotations for a nice visual effect.
const fullSpins = spinRotations * 360;
// Get the current angle of the wheel, normalized to 0-360 degrees.
const currentAngle = accumulatedRotation % 360;
// Calculate the rotation needed to get from the current angle to the target angle.
// We must always rotate forward (clockwise, positive rotation).
let rotationToTarget = targetAngle - currentAngle;
if (rotationToTarget < 0) {
rotationToTarget += 360;
}
// The total amount of rotation for this spin.
const rotationAmount = fullSpins + rotationToTarget;
const startRotation = accumulatedRotation;
// Start the animation. The function will rotate the wheel by 'rotationAmount' degrees.
animateWheel(Date.now(), startRotation, rotationAmount);
// Update the remaining spins counter on the screen.
spinsCounter.text(response.remaining_spins);
} else {
// Display error from server
resultDiv.html(`<p>${response.data.message || 'An error occurred.'}</p>`);
resultDiv.addClass('error').fadeIn(300);
isSpinning = false;
button.prop('disabled', false);
}
},
error: function(xhr) {
const errorMsg = xhr.responseJSON ? xhr.responseJSON.message : 'A communication error occurred.';
resultDiv.html(`<p>${errorMsg}</p>`);
resultDiv.addClass('error').fadeIn(300);
isSpinning = false;
button.prop('disabled', false);
}
});
});
// Initialization
if (wheelSettings.remainingSpins <= 0) {
button.prop('disabled', true);
}
});
+69
View File
@@ -0,0 +1,69 @@
<?php
/**
* Reusable form fields for adding/editing prizes
*/
if (!defined('ABSPATH')) exit;
?>
<tr>
<th scope="row"><label for="prize_name"><?php _e('Prize Name', 'wheel-of-fortune'); ?></label></th>
<td><input type="text" id="prize_name" name="prize_name" class="regular-text" required></td>
</tr>
<tr>
<th scope="row"><label for="prize_description"><?php _e('Description', 'wheel-of-fortune'); ?></label></th>
<td><textarea id="prize_description" name="prize_description" rows="3" class="large-text"></textarea></td>
</tr>
<tr>
<th scope="row"><label for="prize_probability"><?php _e('Probability', 'wheel-of-fortune'); ?></label></th>
<td>
<input type="number" id="prize_probability" name="prize_probability" step="any" min="0" max="1" required>
<p class="description"><?php _e('Enter a value between 0 and 1 (e.g., 0.1 for 10% chance). 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="prize_is_active">
<input type="checkbox" id="prize_is_active" name="prize_is_active" value="1" checked>
<?php _e('Prize is active', 'wheel-of-fortune'); ?>
</label>
</td>
</tr>
<tr>
<th scope="row"><label for="prize_redemption_code"><?php _e('Redemption Code', 'wheel-of-fortune'); ?></label></th>
<td>
<input type="text" id="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="prize_email_subject"><?php _e('Email Subject', 'wheel-of-fortune'); ?></label></th>
<td>
<input type="text" id="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="prize_email_template"><?php _e('Email Template', 'wheel-of-fortune'); ?></label></th>
<td>
<textarea id="prize_email_template" name="prize_email_template" rows="10" class="large-text code"></textarea>
<p class="description"><?php _e('Content for this prize\'s email. Leave blank for default template.', 'wheel-of-fortune'); ?></p>
<p><?php _e('Available template tags:', 'wheel-of-fortune'); ?></p>
<ul class="wheel-template-tags">
<li><code>{user_name}</code>, <code>{user_email}</code>, <code>{prize_name}</code>, <code>{prize_description}</code>, <code>{redemption_code}</code>, <code>{site_name}</code>, <code>{site_url}</code>, <code>{date}</code>, <code>{time}</code></li>
</ul>
</td>
</tr>
<tr>
<th scope="row"><label for="prize_is_discount"><?php _e('Je discount?', 'wheel-of-fortune'); ?></label></th>
<td>
<input type="checkbox" id="prize_is_discount" name="prize_is_discount" value="1">
<p class="description"><?php _e('Označi, če je nagrada popust.', 'wheel-of-fortune'); ?></p>
</td>
</tr>
<tr>
<th scope="row"><label for="prize_discount_value"><?php _e('Vrednost kupona (%)', 'wheel-of-fortune'); ?></label></th>
<td>
<input type="number" id="prize_discount_value" name="prize_discount_value" step="0.01" min="0" max="100">
<p class="description"><?php _e('Vnesi vrednost popusta v %.', 'wheel-of-fortune'); ?></p>
</td>
</tr>
+618
View File
@@ -0,0 +1,618 @@
<?php
/**
* Administratorska stran za nastavitve vtičnika Kolo Sreče
*/
// Prepreči neposreden dostop
if (!defined('ABSPATH')) {
exit;
}
// Preveri, če ima uporabnik pravice za dostop
if (!current_user_can('manage_options')) {
return;
}
// Shrani nastavitve
if (isset($_POST['wheel_save_settings']) && check_admin_referer('wheel_settings_nonce')) {
// Časovna omejitev
$cooldown_minutes = isset($_POST['wheel_cooldown_minutes']) ? intval($_POST['wheel_cooldown_minutes']) : 0;
update_option('wheel_cooldown_minutes', $cooldown_minutes);
// Maksimalno število spinov
$max_spins = isset($_POST['wheel_max_spins']) ? intval($_POST['wheel_max_spins']) : 0;
update_option('wheel_max_spins', $max_spins);
// Email obvestila
$send_emails = isset($_POST['wheel_send_emails']) ? true : false;
update_option('wheel_send_emails', $send_emails);
// SMTP nastavitve
$smtp_enabled = isset($_POST['wheel_smtp_enabled']) ? true : false;
update_option('wheel_smtp_enabled', $smtp_enabled);
$smtp_host = isset($_POST['wheel_smtp_host']) ? sanitize_text_field($_POST['wheel_smtp_host']) : '';
update_option('wheel_smtp_host', $smtp_host);
$smtp_port = isset($_POST['wheel_smtp_port']) ? sanitize_text_field($_POST['wheel_smtp_port']) : '587';
update_option('wheel_smtp_port', $smtp_port);
$smtp_encryption = isset($_POST['wheel_smtp_encryption']) ? sanitize_text_field($_POST['wheel_smtp_encryption']) : 'tls';
update_option('wheel_smtp_encryption', $smtp_encryption);
$smtp_username = isset($_POST['wheel_smtp_username']) ? sanitize_text_field($_POST['wheel_smtp_username']) : '';
update_option('wheel_smtp_username', $smtp_username);
// POPRAVEK: Gesla se ne sme sanitizirati s sanitize_text_field, ker lahko vsebuje posebne znake.
$smtp_password = isset($_POST['wheel_smtp_password']) ? wp_unslash($_POST['wheel_smtp_password']) : '';
update_option('wheel_smtp_password', $smtp_password);
$email_from_name = isset($_POST['wheel_email_from_name']) ? sanitize_text_field($_POST['wheel_email_from_name']) : get_bloginfo('name');
update_option('wheel_email_from_name', $email_from_name);
$email_from_email = isset($_POST['wheel_email_from_email']) ? sanitize_email($_POST['wheel_email_from_email']) : get_bloginfo('admin_email');
update_option('wheel_email_from_email', $email_from_email);
// Izdelki, ki podeljujejo spine
$spin_products = array();
if (isset($_POST['product_ids']) && isset($_POST['product_spins'])) {
$product_ids = $_POST['product_ids'];
$product_spins = $_POST['product_spins'];
foreach ($product_ids as $key => $product_id) {
if (!empty($product_id) && isset($product_spins[$key])) {
$spin_products[$product_id] = intval($product_spins[$key]);
}
}
}
update_option('wheel_spin_products', $spin_products);
// Prikaži sporočilo o uspehu
add_settings_error('wheel_settings', 'settings_updated', __('Nastavitve so bile uspešno shranjene.', 'wheel-of-fortune'), 'updated');
}
// Ročno dodajanje spinov uporabniku se zdaj izvaja preko AJAX
// Pridobi trenutne nastavitve
$cooldown_minutes = get_option('wheel_cooldown_minutes', 0);
$max_spins = get_option('wheel_max_spins', 0);
$send_emails = get_option('wheel_send_emails', false);
$spin_products = get_option('wheel_spin_products', array());
// Prikaži sporočila o napakah/uspehu
settings_errors('wheel_settings');
?>
<div class="wrap wheel-admin-page">
<h1><?php echo esc_html__('Kolo Sreče - Nastavitve', 'wheel-of-fortune'); ?></h1>
<h2 class="nav-tab-wrapper">
<a href="#" class="nav-tab nav-tab-active" data-target="general-settings"><?php echo esc_html__('Splošne nastavitve', 'wheel-of-fortune'); ?></a>
<a href="#" class="nav-tab" data-target="product-settings"><?php echo esc_html__('Izdelki', 'wheel-of-fortune'); ?></a>
<a href="#" class="nav-tab" data-target="wheel-preview"><?php echo esc_html__('Predogled', 'wheel-of-fortune'); ?></a>
</h2>
<form method="post" action="">
<?php wp_nonce_field('wheel_settings_nonce'); ?>
<div id="general-settings" class="wheel-tab-content">
<div class="wheel-card">
<h2><?php echo esc_html__('Splošne nastavitve', 'wheel-of-fortune'); ?></h2>
<table class="wheel-form-table">
<tr>
<th scope="row">
<label for="wheel_cooldown_minutes"><?php echo esc_html__('Časovna omejitev (minute)', 'wheel-of-fortune'); ?></label>
</th>
<td>
<input type="number" id="wheel_cooldown_minutes" name="wheel_cooldown_minutes" value="<?php echo esc_attr($cooldown_minutes); ?>" min="0" step="1" />
<p class="description"><?php echo esc_html__('Število minut, ki mora preteči med dvema vrtljajema. Vrednost 0 pomeni brez omejitve.', 'wheel-of-fortune'); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="wheel_max_spins"><?php echo esc_html__('Maksimalno število spinov', 'wheel-of-fortune'); ?></label>
</th>
<td>
<input type="number" id="wheel_max_spins" name="wheel_max_spins" value="<?php echo esc_attr($max_spins); ?>" min="0" step="1" />
<p class="description"><?php echo esc_html__('Maksimalno število spinov, ki jih lahko ima uporabnik. Vrednost 0 pomeni brez omejitve.', 'wheel-of-fortune'); ?></p>
</td>
</tr>
<!-- Možnost za pošiljanje e-pošte je odstranjena, saj se e-pošta pošlje vedno -->
<input type="hidden" name="wheel_send_emails" value="1" />
</table>
</div>
<div class="wheel-card">
<h2><?php echo esc_html__('SMTP nastavitve', 'wheel-of-fortune'); ?></h2>
<p class="description"><?php echo esc_html__('Nastavitve za pošiljanje e-pošte preko SMTP strežnika. Če so te nastavitve omogočene, bo vtičnik uporabljal SMTP namesto privzete WordPress funkcije za pošiljanje e-pošte.', 'wheel-of-fortune'); ?></p>
<table class="wheel-form-table">
<tr>
<th scope="row">
<?php echo esc_html__('Uporabi SMTP', 'wheel-of-fortune'); ?>
</th>
<td>
<label for="wheel_smtp_enabled">
<input type="checkbox" id="wheel_smtp_enabled" name="wheel_smtp_enabled" <?php checked(get_option('wheel_smtp_enabled', false)); ?> />
<?php echo esc_html__('Omogoči SMTP za pošiljanje e-pošte', 'wheel-of-fortune'); ?>
</label>
</td>
</tr>
<tr>
<th scope="row">
<label for="wheel_smtp_host"><?php echo esc_html__('SMTP gostitelj', 'wheel-of-fortune'); ?></label>
</th>
<td>
<input type="text" id="wheel_smtp_host" name="wheel_smtp_host" value="<?php echo esc_attr(get_option('wheel_smtp_host', '')); ?>" class="regular-text" />
<p class="description"><?php echo esc_html__('Npr. smtp.gmail.com', 'wheel-of-fortune'); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="wheel_smtp_port"><?php echo esc_html__('SMTP vrata', 'wheel-of-fortune'); ?></label>
</th>
<td>
<input type="text" id="wheel_smtp_port" name="wheel_smtp_port" value="<?php echo esc_attr(get_option('wheel_smtp_port', '587')); ?>" />
<p class="description"><?php echo esc_html__('Običajno 587 (TLS) ali 465 (SSL)', 'wheel-of-fortune'); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="wheel_smtp_encryption"><?php echo esc_html__('Šifriranje', 'wheel-of-fortune'); ?></label>
</th>
<td>
<select id="wheel_smtp_encryption" name="wheel_smtp_encryption">
<option value="tls" <?php selected(get_option('wheel_smtp_encryption', 'tls'), 'tls'); ?>><?php echo esc_html__('TLS', 'wheel-of-fortune'); ?></option>
<option value="ssl" <?php selected(get_option('wheel_smtp_encryption', 'tls'), 'ssl'); ?>><?php echo esc_html__('SSL', 'wheel-of-fortune'); ?></option>
<option value="" <?php selected(get_option('wheel_smtp_encryption', 'tls'), ''); ?>><?php echo esc_html__('Brez', 'wheel-of-fortune'); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row">
<label for="wheel_smtp_username"><?php echo esc_html__('SMTP uporabniško ime', 'wheel-of-fortune'); ?></label>
</th>
<td>
<input type="text" id="wheel_smtp_username" name="wheel_smtp_username" value="<?php echo esc_attr(get_option('wheel_smtp_username', '')); ?>" class="regular-text" />
</td>
</tr>
<tr>
<th scope="row">
<label for="wheel_smtp_password"><?php echo esc_html__('SMTP geslo', 'wheel-of-fortune'); ?></label>
</th>
<td>
<input type="password" id="wheel_smtp_password" name="wheel_smtp_password" value="<?php echo esc_attr(get_option('wheel_smtp_password', '')); ?>" class="regular-text" />
</td>
</tr>
<tr>
<th scope="row">
<label for="wheel_email_from_name"><?php echo esc_html__('Ime pošiljatelja', 'wheel-of-fortune'); ?></label>
</th>
<td>
<input type="text" id="wheel_email_from_name" name="wheel_email_from_name" value="<?php echo esc_attr(get_option('wheel_email_from_name', get_bloginfo('name'))); ?>" class="regular-text" />
</td>
</tr>
<tr>
<th scope="row">
<label for="wheel_email_from_email"><?php echo esc_html__('E-pošta pošiljatelja', 'wheel-of-fortune'); ?></label>
</th>
<td>
<input type="email" id="wheel_email_from_email" name="wheel_email_from_email" value="<?php echo esc_attr(get_option('wheel_email_from_email', get_bloginfo('admin_email'))); ?>" class="regular-text" />
</td>
</tr>
<tr>
<th scope="row">
<?php echo esc_html__('Preizkusi nastavitve', 'wheel-of-fortune'); ?>
</th>
<td>
<div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
<input type="email" id="test-email-recipient" class="regular-text" placeholder="<?php esc_attr_e('Email for testing', 'wheel-of-fortune'); ?>" value="<?php echo esc_attr(wp_get_current_user()->user_email); ?>" />
<button type="button" id="test-email-button" class="button button-secondary"><?php echo esc_html__('Pošlji testno e-pošto', 'wheel-of-fortune'); ?></button>
<span class="spinner" style="float: none; vertical-align: middle;"></span>
</div>
<p class="description"><?php echo esc_html__('Vnesite e-poštni naslov in kliknite gumb, da preizkusite trenutno vnešene (ne nujno shranjene) nastavitve.', 'wheel-of-fortune'); ?></p>
<div id="test-email-result" style="margin-top: 10px;"></div>
</td>
</tr>
</table>
</div>
<div class="wheel-card">
<h2><?php echo esc_html__('Upravljanje s spini', 'wheel-of-fortune'); ?></h2>
<div class="wheel-form-table">
<h3><?php echo esc_html__('Ročno dodajanje spinov', 'wheel-of-fortune'); ?></h3>
<div>
<?php wp_nonce_field('wheel_add_spins_nonce', 'wheel_add_spins_nonce'); ?>
<table class="form-table">
<tr>
<th scope="row">
<label for="wheel_user_id"><?php echo esc_html__('Uporabnik', 'wheel-of-fortune'); ?></label>
</th>
<td>
<select id="wheel_user_id" class="wheel-user-select">
<option value=""><?php echo esc_html__('Izberite uporabnika', 'wheel-of-fortune'); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row">
<label for="wheel_spins_to_add"><?php echo esc_html__('Število spinov', 'wheel-of-fortune'); ?></label>
</th>
<td>
<input type="number" id="wheel_spins_to_add" value="1" min="1" step="1" />
</td>
</tr>
</table>
<p class="submit">
<button type="button" id="wheel_add_spins_button" class="button button-primary"><?php echo esc_html__('Dodaj spine', 'wheel-of-fortune'); ?></button>
</p>
</div>
</div>
<div class="wheel-form-table">
<h3><?php echo esc_html__('Ponastavitev spinov', 'wheel-of-fortune'); ?></h3>
<p class="description"><?php echo esc_html__('Ponastavi število spinov za vse uporabnike na 0.', 'wheel-of-fortune'); ?></p>
<p>
<button type="button" id="wheel_reset_all_spins" class="button button-secondary"><?php echo esc_html__('Ponastavi vse spine', 'wheel-of-fortune'); ?></button>
<span class="spinner" style="float: none; vertical-align: middle;"></span>
</p>
<div id="wheel_reset_result" style="margin-top: 10px;"></div>
</div>
<!-- Dodaj nov razdelek za testiranje kuponov -->
<div class="wheel-form-table">
<h3><?php echo esc_html__('Testiranje ustvarjanja kuponov', 'wheel-of-fortune'); ?></h3>
<p class="description"><?php echo esc_html__('Ta funkcija bo preizkusila različne metode za ustvarjanje WooCommerce kuponov in našla tisto, ki deluje na vašem sistemu.', 'wheel-of-fortune'); ?></p>
<p>
<button type="button" id="wheel_test_coupons" class="button button-secondary"><?php echo esc_html__('Testiraj ustvarjanje kuponov', 'wheel-of-fortune'); ?></button>
<span class="spinner coupon-test-spinner" style="float: none; vertical-align: middle;"></span>
</p>
<div id="wheel_coupon_test_result" style="margin-top: 10px;"></div>
</div>
</div>
</div>
<div id="product-settings" class="wheel-tab-content" style="display:none;">
<div class="wheel-card">
<h2><?php echo esc_html__('Izdelki, ki podeljujejo spine', 'wheel-of-fortune'); ?></h2>
<p><?php echo esc_html__('Nastavite izdelke, ki bodo ob nakupu podelili določeno število spinov.', 'wheel-of-fortune'); ?></p>
<table class="wheel-products-table widefat">
<thead>
<tr>
<th><?php echo esc_html__('ID izdelka', 'wheel-of-fortune'); ?></th>
<th><?php echo esc_html__('Ime izdelka', 'wheel-of-fortune'); ?></th>
<th><?php echo esc_html__('Število spinov', 'wheel-of-fortune'); ?></th>
<th><?php echo esc_html__('Akcije', 'wheel-of-fortune'); ?></th>
</tr>
</thead>
<tbody>
<?php if (empty($spin_products)): ?>
<tr>
<td colspan="4"><?php echo esc_html__('Ni nastavljenih izdelkov.', 'wheel-of-fortune'); ?></td>
</tr>
<?php else: ?>
<?php foreach ($spin_products as $product_id => $spins): ?>
<?php $product = wc_get_product($product_id); ?>
<?php if ($product): ?>
<tr>
<td>
<input type="hidden" name="product_ids[]" value="<?php echo esc_attr($product_id); ?>" />
<?php echo esc_html($product_id); ?>
</td>
<td><?php echo esc_html($product->get_name()); ?></td>
<td>
<input type="number" name="product_spins[]" value="<?php echo esc_attr($spins); ?>" min="1" step="1" />
</td>
<td>
<a href="#" class="delete-product" data-id="<?php echo esc_attr($product_id); ?>"><?php echo esc_html__('Odstrani', 'wheel-of-fortune'); ?></a>
</td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
<tfoot>
<tr>
<td>
<input type="number" id="new-product-id" placeholder="<?php echo esc_attr__('ID izdelka', 'wheel-of-fortune'); ?>" />
</td>
<td id="new-product-name"></td>
<td>
<input type="number" id="new-product-spins" placeholder="<?php echo esc_attr__('Število spinov', 'wheel-of-fortune'); ?>" min="1" step="1" />
</td>
<td>
<button type="button" id="add-product-button" class="button button-secondary"><?php echo esc_html__('Dodaj izdelek', 'wheel-of-fortune'); ?></button>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
<div id="wheel-preview" class="wheel-tab-content" style="display:none;">
<div class="wheel-card">
<h2><?php echo esc_html__('Predogled kolesa', 'wheel-of-fortune'); ?></h2>
<div class="wheel-preview-container">
<div id="wheel-preview-svg">
<?php
$wheel = wheel_of_fortune();
$prizes = $wheel->get_wheel_prizes();
echo $wheel->generate_wheel_svg($prizes);
?>
</div>
</div>
<p class="description"><?php echo esc_html__('To je predogled kolesa, ki ga bodo videli uporabniki. Za spreminjanje nagrad pojdite na stran "Nagrade".', 'wheel-of-fortune'); ?></p>
</div>
</div>
<p class="submit">
<input type="submit" name="wheel_save_settings" class="button button-primary" value="<?php echo esc_attr__('Shrani nastavitve', 'wheel-of-fortune'); ?>" />
</p>
</form>
</div>
<script>
jQuery(document).ready(function($) {
// Iskanje izdelka po ID
$('#new-product-id').on('change', function() {
var productId = $(this).val();
if (productId) {
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'wheel_get_product_name',
product_id: productId,
_wpnonce: '<?php echo wp_create_nonce('wheel_product_nonce'); ?>'
},
success: function(response) {
if (response.success) {
$('#new-product-name').text(response.data.name);
} else {
$('#new-product-name').text('<?php echo esc_js(__('Izdelek ni najden', 'wheel-of-fortune')); ?>');
}
},
error: function() {
$('#new-product-name').text('<?php echo esc_js(__('Napaka pri iskanju izdelka', 'wheel-of-fortune')); ?>');
}
});
} else {
$('#new-product-name').text('');
}
});
// Dodajanje novega izdelka
$('#add-product-button').on('click', function() {
var productId = $('#new-product-id').val();
var spins = $('#new-product-spins').val();
var productName = $('#new-product-name').text();
if (!productId || !spins || productName === '<?php echo esc_js(__('Izdelek ni najden', 'wheel-of-fortune')); ?>') {
alert('<?php echo esc_js(__('Vnesite veljaven ID izdelka in število spinov', 'wheel-of-fortune')); ?>');
return;
}
var newRow = '<tr>' +
'<td><input type="hidden" name="product_ids[]" value="' + productId + '" />' + productId + '</td>' +
'<td>' + productName + '</td>' +
'<td><input type="number" name="product_spins[]" value="' + spins + '" min="1" step="1" /></td>' +
'<td><a href="#" class="delete-product" data-id="' + productId + '"><?php echo esc_js(__('Odstrani', 'wheel-of-fortune')); ?></a></td>' +
'</tr>';
var tbody = $('.wheel-products-table tbody');
if (tbody.find('tr:first td').length === 1) {
tbody.empty();
}
tbody.append(newRow);
$('#new-product-id').val('');
$('#new-product-spins').val('');
$('#new-product-name').text('');
});
// Brisanje izdelka
$('.wheel-products-table').on('click', '.delete-product', function(e) {
e.preventDefault();
var row = $(this).closest('tr');
row.remove();
var tbody = $('.wheel-products-table tbody');
if (tbody.find('tr').length === 0) {
tbody.append('<tr><td colspan="4"><?php echo esc_js(__('Ni nastavljenih izdelkov.', 'wheel-of-fortune')); ?></td></tr>');
}
});
// Ponastavi vse spine
$('#wheel_reset_all_spins').on('click', function() {
if (confirm('<?php echo esc_js(__('Ali ste prepričani, da želite ponastaviti vse spine za vse uporabnike? Tega ni mogoče razveljaviti!', 'wheel-of-fortune')); ?>')) {
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'wheel_reset_all_spins',
_wpnonce: '<?php echo wp_create_nonce('wheel_reset_spins_nonce'); ?>'
},
success: function(response) {
if (response.success) {
alert('<?php echo esc_js(__('Vsi spini so bili uspešno ponastavljeni.', 'wheel-of-fortune')); ?>');
} else {
alert('<?php echo esc_js(__('Napaka pri ponastavljanju spinov:', 'wheel-of-fortune')); ?> ' + response.data.message);
}
},
error: function() {
alert('<?php echo esc_js(__('Prišlo je do napake pri komunikaciji s strežnikom.', 'wheel-of-fortune')); ?>');
}
});
}
});
// Iskanje uporabnikov
$('#wheel_user_id').on('change', function() {
var userId = $(this).val();
if (userId) {
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'wheel_get_user_info',
user_id: userId,
_wpnonce: '<?php echo wp_create_nonce('wheel_user_info_nonce'); ?>'
},
success: function(response) {
if (response.success) {
$('#wheel_user_info').html(response.data.info);
} else {
$('#wheel_user_info').html('<?php echo esc_js(__('Uporabnik ni najden', 'wheel-of-fortune')); ?>');
}
},
error: function() {
$('#wheel_user_info').html('<?php echo esc_js(__('Napaka pri iskanju uporabnika', 'wheel-of-fortune')); ?>');
}
});
} else {
$('#wheel_user_info').html('');
}
});
// Dodaj spine uporabniku
$('#wheel_add_spins_button').on('click', function() {
var userId = $('#wheel_user_id').val();
var spins = $('#wheel_spins_to_add').val();
if (!userId || !spins) {
alert('<?php echo esc_js(__('Izberite uporabnika in vnesite število spinov', 'wheel-of-fortune')); ?>');
return;
}
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'wheel_add_user_spins',
user_id: userId,
spins: spins,
_wpnonce: '<?php echo wp_create_nonce('wheel_add_spins_nonce'); ?>'
},
success: function(response) {
if (response.success) {
alert('<?php echo esc_js(__('Spini so bili uspešno dodani.', 'wheel-of-fortune')); ?>');
$('#wheel_user_id').val('');
$('#wheel_spins_to_add').val('');
} else {
alert('<?php echo esc_js(__('Napaka pri dodajanju spinov:', 'wheel-of-fortune')); ?> ' + response.data.message);
}
},
error: function() {
alert('<?php echo esc_js(__('Prišlo je do napake pri komunikaciji s strežnikom.', 'wheel-of-fortune')); ?>');
}
});
});
// Testiranje ustvarjanja kuponov
$('#wheel_test_coupons').on('click', function() {
var $button = $(this);
var $spinner = $('.coupon-test-spinner');
var $result = $('#wheel_coupon_test_result');
$button.prop('disabled', true);
$spinner.addClass('is-active');
$result.html('');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'wheel_test_coupons',
nonce: wheel_admin_nonce
},
dataType: 'json',
success: function(response) {
$button.prop('disabled', false);
$spinner.removeClass('is-active');
if (response.success) {
var html = '<div class="notice notice-success"><p><strong>' + response.data.message + '</strong></p>';
// Prikaži podrobne rezultate testov
html += '<table class="widefat" style="margin-top:10px;">';
html += '<thead><tr><th>Metoda</th><th>Rezultat</th><th>Sporočilo</th></tr></thead><tbody>';
$.each(response.data.tests, function(method, result) {
var statusClass = result.success ? 'success' : 'error';
var statusText = result.success ? '✅ Uspešno' : '❌ Neuspešno';
html += '<tr class="' + statusClass + '">';
html += '<td><strong>' + method + '</strong></td>';
html += '<td>' + statusText + '</td>';
html += '<td>' + result.message + '</td>';
html += '</tr>';
});
html += '</tbody></table>';
if (response.data.working_method) {
html += '<p><strong><?php echo esc_js(__('Priporočilo:', 'wheel-of-fortune')); ?></strong> ';
html += '<?php echo esc_js(__('Uporabite metodo', 'wheel-of-fortune')); ?> <code>' + response.data.working_method + '</code> <?php echo esc_js(__('za ustvarjanje kuponov.', 'wheel-of-fortune')); ?></p>';
// Dodaj gumb za shranjevanje najboljše metode
html += '<p><button type="button" class="button button-primary save-best-method" data-method="' + response.data.working_method + '">';
html += '<?php echo esc_js(__('Shrani to metodo kot privzeto', 'wheel-of-fortune')); ?></button></p>';
}
html += '</div>';
$result.html(html);
// Dodaj poslušalec dogodkov za gumb za shranjevanje najboljše metode
$('.save-best-method').on('click', function() {
var method = $(this).data('method');
saveBestMethod(method);
});
} else {
$result.html('<div class="notice notice-error"><p><strong><?php echo esc_js(__('Napaka pri testiranju:', 'wheel-of-fortune')); ?></strong> ' + response.data.message + '</p></div>');
}
},
error: function(xhr, status, error) {
$button.prop('disabled', false);
$spinner.removeClass('is-active');
$result.html('<div class="notice notice-error"><p><strong><?php echo esc_js(__('Prišlo je do napake pri testiranju:', 'wheel-of-fortune')); ?></strong> ' + error + '</p></div>');
}
});
});
// Funkcija za shranjevanje najboljše metode
function saveBestMethod(method) {
var $result = $('#wheel_coupon_test_result');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'wheel_save_best_coupon_method',
method: method,
nonce: wheel_admin_nonce
},
dataType: 'json',
success: function(response) {
if (response.success) {
$result.prepend('<div class="notice notice-success is-dismissible"><p>' + response.data.message + '</p></div>');
} else {
$result.prepend('<div class="notice notice-error is-dismissible"><p>' + response.data.message + '</p></div>');
}
},
error: function(xhr, status, error) {
$result.prepend('<div class="notice notice-error is-dismissible"><p><?php echo esc_js(__('Napaka pri shranjevanju metode:', 'wheel-of-fortune')); ?> ' + error + '</p></div>');
}
});
}
});
</script>
+257
View File
@@ -0,0 +1,257 @@
<?php
/**
* Stran s statistiko za Kolo Sreče
*/
// Prepreči neposreden dostop
if (!defined('ABSPATH')) {
exit;
}
// Preveri, če ima uporabnik pravice za dostop
if (!current_user_can('manage_options')) {
return;
}
// Pridobi podatke o uporabnikih
global $wpdb;
$users_table = $wpdb->prefix . 'users';
$spins_table = $wpdb->prefix . 'wheel_spins';
$log_table = $wpdb->prefix . 'wheel_log';
$prizes_table = $wpdb->prefix . 'wheel_prizes';
$wheels_table = $wpdb->prefix . 'wof_wheels';
// Pridobi vsa kolesa
$wheels = $wpdb->get_results("SELECT * FROM $wheels_table ORDER BY id ASC", ARRAY_A);
// Izberi kolo (privzeto prvo)
$selected_wheel_id = isset($_GET['wheel_id']) ? intval($_GET['wheel_id']) : 1;
$selected_wheel = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wheels_table WHERE id = %d", $selected_wheel_id), ARRAY_A);
if (!$selected_wheel) {
$selected_wheel_id = 1;
$selected_wheel = $wpdb->get_row("SELECT * FROM $wheels_table WHERE id = 1", ARRAY_A);
}
// Iskanje uporabnikov
$search = isset($_GET['s']) ? sanitize_text_field($_GET['s']) : '';
$search_condition = '';
if (!empty($search)) {
$search_condition = $wpdb->prepare(
"AND (u.user_login LIKE %s OR u.user_email LIKE %s OR u.display_name LIKE %s)",
"%{$search}%",
"%{$search}%",
"%{$search}%"
);
}
// Pridobi uporabnike z spin-i za izbrano kolo
$users_with_spins = $wpdb->get_results(
$wpdb->prepare(
"SELECT u.ID, u.user_email, u.display_name,
COALESCE(s.spins_available, 0) as spins_available,
COUNT(l.id) as total_spins,
MAX(l.spin_date) as last_spin_date
FROM {$users_table} u
LEFT JOIN {$spins_table} s ON u.ID = s.user_id AND s.wheel_id = %d
LEFT JOIN {$log_table} l ON u.ID = l.user_id AND l.wheel_id = %d
WHERE 1=1 {$search_condition}
GROUP BY u.ID
HAVING total_spins > 0 OR spins_available > 0
ORDER BY total_spins DESC",
$selected_wheel_id, $selected_wheel_id
),
ARRAY_A
);
// Označi nagrado kot unovčeno
if (isset($_POST['mark_redeemed']) && isset($_POST['prize_id'])) {
check_admin_referer('mark_prize_redeemed_nonce', 'mark_prize_redeemed_nonce');
$prize_log_id = intval($_POST['prize_id']);
$wpdb->update(
$log_table,
array('redeemed' => 1),
array('id' => $prize_log_id)
);
echo '<div class="notice notice-success is-dismissible"><p>' .
__('Nagrada je bila označena kot unovčena.', 'wheel-of-fortune') .
'</p></div>';
}
// Izberi uporabnika za podrobnosti
$selected_user_id = isset($_GET['user_id']) ? intval($_GET['user_id']) : 0;
// Pridobi podrobnosti o nagradah uporabnika za izbrano kolo, če je izbran
$user_prizes = array();
if ($selected_user_id > 0) {
$user_prizes = $wpdb->get_results(
$wpdb->prepare(
"SELECT l.id, p.name as prize_name, p.description as prize_description,
l.spin_date, l.redeemed
FROM {$log_table} l
JOIN {$prizes_table} p ON l.prize_id = p.id
WHERE l.user_id = %d AND l.wheel_id = %d
ORDER BY l.spin_date DESC",
$selected_user_id, $selected_wheel_id
),
ARRAY_A
);
}
?>
<div class="wrap">
<h1><?php echo esc_html__('Statistika Kolesa Sreče', 'wheel-of-fortune'); ?></h1>
<!-- Izbira kolesa -->
<div class="tablenav top">
<div class="alignleft actions">
<form method="get" style="display: inline-block; margin-right: 20px;">
<input type="hidden" name="page" value="wof-stats">
<label for="wheel-select"><?php echo esc_html__('Izberi kolo:', 'wheel-of-fortune'); ?></label>
<select name="wheel_id" id="wheel-select" onchange="this.form.submit()">
<?php foreach ($wheels as $wheel): ?>
<option value="<?php echo esc_attr($wheel['id']); ?>" <?php selected($selected_wheel_id, $wheel['id']); ?>>
<?php echo esc_html($wheel['name']); ?>
</option>
<?php endforeach; ?>
</select>
</form>
<form method="get" style="display: inline-block;">
<input type="hidden" name="page" value="wof-stats">
<input type="hidden" name="wheel_id" value="<?php echo esc_attr($selected_wheel_id); ?>">
<label for="user-search" class="screen-reader-text"><?php echo esc_html__('Iskanje uporabnikov:', 'wheel-of-fortune'); ?></label>
<input type="search" id="user-search" name="s" value="<?php echo isset($_GET['s']) ? esc_attr($_GET['s']) : ''; ?>">
<input type="submit" class="button" value="<?php echo esc_attr__('Išči uporabnike', 'wheel-of-fortune'); ?>">
</form>
</div>
<br class="clear">
</div>
<h2><?php echo sprintf(esc_html__('Seznam uporabnikov s spini za kolo: %s', 'wheel-of-fortune'), esc_html($selected_wheel['name'])); ?></h2>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th scope="col"><?php echo esc_html__('ID', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('E-pošta', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Skupno št. spinov', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Preostali spini', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Zadnji spin', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Akcije', 'wheel-of-fortune'); ?></th>
</tr>
</thead>
<tbody>
<?php if (empty($users_with_spins)) : ?>
<tr>
<td colspan="6"><?php echo esc_html__('Ni uporabnikov z dodeljenimi spini.', 'wheel-of-fortune'); ?></td>
</tr>
<?php else : ?>
<?php foreach ($users_with_spins as $user) : ?>
<tr<?php echo ($selected_user_id == $user['ID']) ? ' class="active"' : ''; ?>>
<td><?php echo esc_html($user['ID']); ?></td>
<td><?php echo esc_html($user['user_email']); ?></td>
<td><?php echo esc_html($user['total_spins']); ?></td>
<td><?php echo esc_html($user['spins_available']); ?></td>
<td><?php echo !empty($user['last_spin_date']) ? esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($user['last_spin_date']))) : '-'; ?></td>
<td>
<a href="<?php echo esc_url(add_query_arg('user_id', $user['ID'])); ?>" class="button"><?php echo esc_html__('Podrobnosti', 'wheel-of-fortune'); ?></a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<?php if ($selected_user_id > 0) : ?>
<?php $selected_user = get_userdata($selected_user_id); ?>
<?php if ($selected_user) : ?>
<h2><?php echo sprintf(esc_html__('Podrobnosti za uporabnika: %s', 'wheel-of-fortune'), esc_html($selected_user->display_name)); ?></h2>
<table class="form-table">
<tr>
<th scope="row"><?php echo esc_html__('ID uporabnika', 'wheel-of-fortune'); ?></th>
<td><?php echo esc_html($selected_user_id); ?></td>
</tr>
<tr>
<th scope="row"><?php echo esc_html__('E-pošta', 'wheel-of-fortune'); ?></th>
<td><?php echo esc_html($selected_user->user_email); ?></td>
</tr>
<tr>
<th scope="row"><?php echo esc_html__('Skupno število spinov', 'wheel-of-fortune'); ?></th>
<td>
<?php
$total_spins = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$log_table} WHERE user_id = %d AND wheel_id = %d",
$selected_user_id, $selected_wheel_id
));
echo esc_html($total_spins);
?>
</td>
</tr>
<tr>
<th scope="row"><?php echo esc_html__('Preostali spini', 'wheel-of-fortune'); ?></th>
<td>
<?php
$spins = $wpdb->get_var($wpdb->prepare(
"SELECT spins_available FROM {$spins_table} WHERE user_id = %d AND wheel_id = %d",
$selected_user_id, $selected_wheel_id
));
echo esc_html($spins ?: 0);
?>
</td>
</tr>
</table>
<h3><?php echo esc_html__('Zgodovina nagrad', 'wheel-of-fortune'); ?></h3>
<?php if (empty($user_prizes)) : ?>
<p><?php echo esc_html__('Ta uporabnik še ni prejel nobene nagrade.', 'wheel-of-fortune'); ?></p>
<?php else : ?>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th scope="col"><?php echo esc_html__('ID', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Nagrada', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Opis', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Datum', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Status', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Akcije', 'wheel-of-fortune'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($user_prizes as $prize) : ?>
<tr>
<td><?php echo esc_html($prize['id']); ?></td>
<td><?php echo esc_html($prize['prize_name']); ?></td>
<td><?php echo esc_html($prize['prize_description']); ?></td>
<td><?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($prize['spin_date']))); ?></td>
<td>
<?php echo $prize['redeemed'] ?
'<span class="dashicons dashicons-yes" style="color: green;"></span> ' . esc_html__('Unovčeno', 'wheel-of-fortune') :
'<span class="dashicons dashicons-no" style="color: red;"></span> ' . esc_html__('Neunovčeno', 'wheel-of-fortune');
?>
</td>
<td>
<?php if (!$prize['redeemed']) : ?>
<form method="post" style="display: inline;">
<?php wp_nonce_field('mark_prize_redeemed_nonce', 'mark_prize_redeemed_nonce'); ?>
<input type="hidden" name="prize_id" value="<?php echo esc_attr($prize['id']); ?>">
<button type="submit" name="mark_redeemed" class="button"><?php echo esc_html__('Označi kot unovčeno', 'wheel-of-fortune'); ?></button>
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<?php else : ?>
<p><?php echo esc_html__('Uporabnik ni bil najden.', 'wheel-of-fortune'); ?></p>
<?php endif; ?>
<?php endif; ?>
</div>
+381
View File
@@ -0,0 +1,381 @@
<?php
/**
* Stran za upravljanje uporabnikov in spinov za Kolo Sreče
*/
// Prepreči neposreden dostop
if (!defined('ABSPATH')) {
exit;
}
// Preveri, če ima uporabnik pravice za dostop
if (!current_user_can('manage_options')) {
return;
}
// Pridobi vsa kolesa
global $wpdb;
$wheels_table = $wpdb->prefix . 'wof_wheels';
$wheels = $wpdb->get_results("SELECT * FROM $wheels_table ORDER BY id ASC", ARRAY_A);
// Izberi kolo (privzeto prvo)
$selected_wheel_id = isset($_GET['wheel_id']) ? intval($_GET['wheel_id']) : 1;
$selected_wheel = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wheels_table WHERE id = %d", $selected_wheel_id), ARRAY_A);
if (!$selected_wheel) {
$selected_wheel_id = 1;
$selected_wheel = $wpdb->get_row("SELECT * FROM $wheels_table WHERE id = 1", ARRAY_A);
}
// Obdelaj akcije
if (isset($_POST['add_spins_submit'])) {
check_admin_referer('wheel_add_spins_nonce', 'wheel_add_spins_nonce');
$user_id = intval($_POST['user_id']);
$spins = intval($_POST['spins']);
$wheel_id = intval($_POST['wheel_id']);
if ($user_id > 0 && $spins > 0 && $wheel_id > 0) {
$spins_table = $wpdb->prefix . 'wheel_spins';
// Preveri, če uporabnik že ima zapis za to kolo
$existing = $wpdb->get_var($wpdb->prepare(
"SELECT id FROM $spins_table WHERE user_id = %d AND wheel_id = %d",
$user_id, $wheel_id
));
if ($existing) {
$wpdb->query($wpdb->prepare(
"UPDATE $spins_table SET spins_available = spins_available + %d WHERE user_id = %d AND wheel_id = %d",
$spins, $user_id, $wheel_id
));
} else {
$wpdb->insert($spins_table, [
'user_id' => $user_id,
'wheel_id' => $wheel_id,
'spins_available' => $spins,
'last_spin_date' => null
], ['%d', '%d', '%d', '%s']);
}
echo '<div class="notice notice-success is-dismissible"><p>' .
sprintf(__('Uporabniku ID %d je bilo uspešno dodanih %d spinov za kolo %s.', 'wheel-of-fortune'), $user_id, $spins, $selected_wheel['name']) .
'</p></div>';
}
}
if (isset($_POST['reset_spins_submit'])) {
check_admin_referer('wheel_reset_spins_nonce', 'wheel_reset_spins_nonce');
$user_id = intval($_POST['user_id']);
$wheel_id = intval($_POST['wheel_id']);
if ($user_id > 0 && $wheel_id > 0) {
$spins_table = $wpdb->prefix . 'wheel_spins';
$wpdb->update(
$spins_table,
array('spins_available' => 0),
array('user_id' => $user_id, 'wheel_id' => $wheel_id)
);
echo '<div class="notice notice-success is-dismissible"><p>' .
sprintf(__('Spini uporabnika ID %d za kolo %s so bili uspešno ponastavljeni na 0.', 'wheel-of-fortune'), $user_id, $selected_wheel['name']) .
'</p></div>';
}
}
// Pridobi podatke o uporabnikih
$users_table = $wpdb->prefix . 'users';
$spins_table = $wpdb->prefix . 'wheel_spins';
$log_table = $wpdb->prefix . 'wheel_log';
$prizes_table = $wpdb->prefix . 'wheel_prizes';
// Iskanje uporabnikov
$search = isset($_GET['s']) ? sanitize_text_field($_GET['s']) : '';
$search_condition = '';
if (!empty($search)) {
$search_condition = $wpdb->prepare(
"AND (u.user_login LIKE %s OR u.user_email LIKE %s OR u.display_name LIKE %s)",
"%{$search}%",
"%{$search}%",
"%{$search}%"
);
}
// Pridobi uporabnike z spin-i za izbrano kolo
$users = $wpdb->get_results(
$wpdb->prepare(
"SELECT u.ID, u.user_login, u.user_email, u.display_name,
COALESCE(s.spins_available, 0) as spins_available,
COUNT(l.id) as total_spins
FROM {$users_table} u
LEFT JOIN {$spins_table} s ON u.ID = s.user_id AND s.wheel_id = %d
LEFT JOIN {$log_table} l ON u.ID = l.user_id AND l.wheel_id = %d
WHERE 1=1 {$search_condition}
GROUP BY u.ID
HAVING total_spins > 0 OR spins_available > 0
ORDER BY total_spins DESC",
$selected_wheel_id, $selected_wheel_id
),
ARRAY_A
);
// Izbrani uporabnik za urejanje
$selected_user_id = isset($_GET['edit_user']) ? intval($_GET['edit_user']) : 0;
$selected_user = null;
$user_prizes = array();
if ($selected_user_id > 0) {
$selected_user = get_userdata($selected_user_id);
if ($selected_user) {
// Pridobi spine za izbrano kolo
$spins = $wpdb->get_var($wpdb->prepare(
"SELECT spins_available FROM $spins_table WHERE user_id = %d AND wheel_id = %d",
$selected_user_id, $selected_wheel_id
));
$spins = $spins ?: 0;
// Pridobi nagrade uporabnika za izbrano kolo
$user_prizes = $wpdb->get_results(
$wpdb->prepare(
"SELECT l.id, p.name as prize_name, p.description as prize_description,
l.spin_date, l.redeemed
FROM {$log_table} l
JOIN {$prizes_table} p ON l.prize_id = p.id
WHERE l.user_id = %d AND l.wheel_id = %d
ORDER BY l.spin_date DESC",
$selected_user_id, $selected_wheel_id
),
ARRAY_A
);
}
}
?>
<div class="wrap">
<h1><?php echo esc_html__('Uporabniki in spini', 'wheel-of-fortune'); ?></h1>
<!-- Izbira kolesa -->
<div class="tablenav top">
<div class="alignleft actions">
<form method="get" style="display: inline-block; margin-right: 20px;">
<input type="hidden" name="page" value="wof-users">
<label for="wheel-select"><?php echo esc_html__('Izberi kolo:', 'wheel-of-fortune'); ?></label>
<select name="wheel_id" id="wheel-select" onchange="this.form.submit()">
<?php foreach ($wheels as $wheel): ?>
<option value="<?php echo esc_attr($wheel['id']); ?>" <?php selected($selected_wheel_id, $wheel['id']); ?>>
<?php echo esc_html($wheel['name']); ?>
</option>
<?php endforeach; ?>
</select>
</form>
<form method="get" style="display: inline-block;">
<input type="hidden" name="page" value="wof-users">
<input type="hidden" name="wheel_id" value="<?php echo esc_attr($selected_wheel_id); ?>">
<label for="user-search" class="screen-reader-text"><?php echo esc_html__('Iskanje uporabnikov:', 'wheel-of-fortune'); ?></label>
<input type="search" id="user-search" name="s" value="<?php echo esc_attr($search); ?>">
<input type="submit" class="button" value="<?php echo esc_attr__('Išči uporabnike', 'wheel-of-fortune'); ?>">
</form>
</div>
<br class="clear">
</div>
<div class="wheel-users-container">
<div class="wheel-users-list">
<h2><?php echo sprintf(esc_html__('Seznam uporabnikov s spini za kolo: %s', 'wheel-of-fortune'), esc_html($selected_wheel['name'])); ?></h2>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th scope="col"><?php echo esc_html__('ID', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('E-pošta', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Skupno št. spinov', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Preostali spini', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Akcije', 'wheel-of-fortune'); ?></th>
</tr>
</thead>
<tbody>
<?php if (empty($users)) : ?>
<tr>
<td colspan="5"><?php echo esc_html__('Ni najdenih uporabnikov s spini.', 'wheel-of-fortune'); ?></td>
</tr>
<?php else : ?>
<?php foreach ($users as $user) : ?>
<tr<?php echo ($selected_user_id == $user['ID']) ? ' class="active"' : ''; ?>>
<td><?php echo esc_html($user['ID']); ?></td>
<td><?php echo esc_html($user['user_email']); ?></td>
<td><?php echo esc_html($user['total_spins']); ?></td>
<td><?php echo esc_html($user['spins_available']); ?></td>
<td>
<a href="<?php echo esc_url(add_query_arg('edit_user', $user['ID'])); ?>" class="button"><?php echo esc_html__('Podrobnosti', 'wheel-of-fortune'); ?></a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<?php if ($selected_user) : ?>
<div class="wheel-user-edit">
<h2><?php echo sprintf(esc_html__('Podrobnosti za uporabnika: %s', 'wheel-of-fortune'), esc_html($selected_user->display_name)); ?></h2>
<table class="form-table">
<tr>
<th scope="row"><?php echo esc_html__('ID uporabnika', 'wheel-of-fortune'); ?></th>
<td><?php echo esc_html($selected_user_id); ?></td>
</tr>
<tr>
<th scope="row"><?php echo esc_html__('E-pošta', 'wheel-of-fortune'); ?></th>
<td><?php echo esc_html($selected_user->user_email); ?></td>
</tr>
<tr>
<th scope="row"><?php echo esc_html__('Skupno število spinov', 'wheel-of-fortune'); ?></th>
<td>
<?php
$total_spins = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$log_table} WHERE user_id = %d AND wheel_id = %d",
$selected_user_id, $selected_wheel_id
));
echo esc_html($total_spins);
?>
</td>
</tr>
<tr>
<th scope="row"><?php echo esc_html__('Preostali spini', 'wheel-of-fortune'); ?></th>
<td><?php echo esc_html($spins); ?></td>
</tr>
</table>
<div class="wheel-user-actions">
<div class="wheel-action-box">
<h3><?php echo esc_html__('Dodaj spine', 'wheel-of-fortune'); ?></h3>
<form method="post" action="">
<?php wp_nonce_field('wheel_add_spins_nonce', 'wheel_add_spins_nonce'); ?>
<input type="hidden" name="user_id" value="<?php echo esc_attr($selected_user_id); ?>">
<input type="hidden" name="wheel_id" value="<?php echo esc_attr($selected_wheel_id); ?>">
<p>
<label for="spins"><?php echo esc_html__('Število spinov za dodati:', 'wheel-of-fortune'); ?></label>
<input type="number" id="spins" name="spins" value="1" min="1" class="regular-text" required>
</p>
<p class="submit">
<input type="submit" name="add_spins_submit" class="button button-primary" value="<?php echo esc_attr__('Dodaj spine', 'wheel-of-fortune'); ?>">
</p>
</form>
</div>
<div class="wheel-action-box">
<h3><?php echo esc_html__('Ponastavi spine', 'wheel-of-fortune'); ?></h3>
<form method="post" action="">
<?php wp_nonce_field('wheel_reset_spins_nonce', 'wheel_reset_spins_nonce'); ?>
<input type="hidden" name="user_id" value="<?php echo esc_attr($selected_user_id); ?>">
<input type="hidden" name="wheel_id" value="<?php echo esc_attr($selected_wheel_id); ?>">
<p><?php echo esc_html__('S klikom na gumb boste ponastavili število spinov uporabnika na 0.', 'wheel-of-fortune'); ?></p>
<p class="submit">
<input type="submit" name="reset_spins_submit" class="button button-secondary" value="<?php echo esc_attr__('Ponastavi spine na 0', 'wheel-of-fortune'); ?>" onclick="return confirm('<?php echo esc_js(__('Ali ste prepričani, da želite ponastaviti spine tega uporabnika na 0?', 'wheel-of-fortune')); ?>');">
</p>
</form>
</div>
</div>
<h3><?php echo esc_html__('Prejete nagrade', 'wheel-of-fortune'); ?></h3>
<?php if (empty($user_prizes)) : ?>
<p><?php echo esc_html__('Ta uporabnik še ni prejel nobene nagrade.', 'wheel-of-fortune'); ?></p>
<?php else : ?>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th scope="col"><?php echo esc_html__('ID', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Nagrada', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Opis', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Datum', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Status', 'wheel-of-fortune'); ?></th>
<th scope="col"><?php echo esc_html__('Akcije', 'wheel-of-fortune'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($user_prizes as $prize) : ?>
<tr>
<td><?php echo esc_html($prize['id']); ?></td>
<td><?php echo esc_html($prize['prize_name']); ?></td>
<td><?php echo esc_html($prize['prize_description']); ?></td>
<td><?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($prize['spin_date']))); ?></td>
<td>
<?php echo $prize['redeemed'] ?
'<span class="dashicons dashicons-yes" style="color: green;"></span> ' . esc_html__('Unovčeno', 'wheel-of-fortune') :
'<span class="dashicons dashicons-no" style="color: red;"></span> ' . esc_html__('Neunovčeno', 'wheel-of-fortune');
?>
</td>
<td>
<?php if (!$prize['redeemed']) : ?>
<form method="post" action="<?php echo esc_url(admin_url('admin.php?page=wheel-stats&user_id=' . $selected_user_id)); ?>">
<?php wp_nonce_field('mark_prize_redeemed_nonce', 'mark_prize_redeemed_nonce'); ?>
<input type="hidden" name="prize_id" value="<?php echo esc_attr($prize['id']); ?>">
<button type="submit" name="mark_redeemed" class="button"><?php echo esc_html__('Označi kot unovčeno', 'wheel-of-fortune'); ?></button>
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<?php elseif ($selected_user_id > 0) : ?>
<div class="wheel-user-edit">
<p><?php echo esc_html__('Uporabnik ni bil najden.', 'wheel-of-fortune'); ?></p>
</div>
<?php else : ?>
<div class="wheel-user-edit">
<p><?php echo esc_html__('Izberite uporabnika za prikaz podrobnosti.', 'wheel-of-fortune'); ?></p>
</div>
<?php endif; ?>
</div>
<style>
.wheel-users-container {
display: flex;
flex-wrap: wrap;
gap: 20px;
margin-top: 20px;
}
.wheel-users-list {
flex: 2;
min-width: 500px;
}
.wheel-user-edit {
flex: 1;
min-width: 300px;
background: #fff;
padding: 15px;
border: 1px solid #ccd0d4;
box-shadow: 0 1px 1px rgba(0,0,0,.04);
}
.wheel-user-actions {
display: flex;
flex-wrap: wrap;
gap: 20px;
margin-top: 20px;
}
.wheel-action-box {
flex: 1;
min-width: 250px;
padding: 15px;
background: #f9f9f9;
border: 1px solid #e5e5e5;
}
</style>
</div>
</div>
+105
View File
@@ -0,0 +1,105 @@
<?php
/**
* Admin page for managing multiple wheels
*/
if (!defined('ABSPATH')) exit;
global $wpdb;
$wheels_table = $wpdb->prefix . 'wof_wheels';
// Handle adding a new wheel
if (isset($_POST['add_wheel_submit']) && check_admin_referer('wof_add_wheel_nonce')) {
$wheel_name = sanitize_text_field($_POST['wheel_name']);
$wheel_slug = sanitize_title($_POST['wheel_name']); // Generate slug from name
if (!empty($wheel_name)) {
$wpdb->insert(
$wheels_table,
['name' => $wheel_name, 'slug' => $wheel_slug, 'created_at' => current_time('mysql')],
['%s', '%s', '%s']
);
echo '<div class="notice notice-success is-dismissible"><p>' . __('New wheel created successfully!', 'wheel-of-fortune') . '</p></div>';
} else {
echo '<div class="notice notice-error is-dismissible"><p>' . __('Please provide a name for the wheel.', 'wheel-of-fortune') . '</p></div>';
}
}
// Handle deleting a wheel
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['wheel_id']) && check_admin_referer('wof_delete_wheel_' . $_GET['wheel_id'])) {
$wheel_id_to_delete = intval($_GET['wheel_id']);
if ($wheel_id_to_delete !== 1) { // Prevent deleting the default wheel
// TODO: Consider what to do with prizes associated with this wheel. For now, we'll just delete the wheel.
$wpdb->delete($wheels_table, ['id' => $wheel_id_to_delete], ['%d']);
echo '<div class="notice notice-success is-dismissible"><p>' . __('Wheel deleted successfully.', 'wheel-of-fortune') . '</p></div>';
} else {
echo '<div class="notice notice-error is-dismissible"><p>' . __('The default wheel cannot be deleted.', 'wheel-of-fortune') . '</p></div>';
}
}
$wheels = $wpdb->get_results("SELECT * FROM $wheels_table ORDER BY id ASC", ARRAY_A);
?>
<div class="wrap wheel-admin-page">
<h1><?php echo esc_html__('Wheels of Fortune', 'wheel-of-fortune'); ?></h1>
<div id="col-container" class="wp-clearfix">
<div id="col-left">
<div class="col-wrap">
<div class="form-wrap">
<h2><?php echo esc_html__('Add New Wheel', 'wheel-of-fortune'); ?></h2>
<form method="post" action="">
<?php wp_nonce_field('wof_add_wheel_nonce'); ?>
<div class="form-field">
<label for="wheel_name"><?php _e('Wheel Name', 'wheel-of-fortune'); ?></label>
<input type="text" name="wheel_name" id="wheel_name" required>
<p><?php _e('The name is how it appears on your site.', 'wheel-of-fortune'); ?></p>
</div>
<p class="submit">
<input type="submit" name="add_wheel_submit" id="submit" class="button button-primary" value="<?php _e('Add New Wheel', 'wheel-of-fortune'); ?>">
</p>
</form>
</div>
</div>
</div>
<div id="col-right">
<div class="col-wrap">
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th scope="col" class="manage-column"><?php _e('ID', 'wheel-of-fortune'); ?></th>
<th scope="col" class="manage-column"><?php _e('Name', 'wheel-of-fortune'); ?></th>
<th scope="col" class="manage-column"><?php _e('Shortcode', 'wheel-of-fortune'); ?></th>
<th scope="col" class="manage-column"><?php _e('Actions', 'wheel-of-fortune'); ?></th>
</tr>
</thead>
<tbody>
<?php if (!empty($wheels)): ?>
<?php foreach ($wheels as $wheel): ?>
<tr>
<td><?php echo esc_html($wheel['id']); ?></td>
<td>
<strong><a href="<?php echo admin_url('admin.php?page=wof-edit-wheel&wheel_id=' . $wheel['id']); ?>"><?php echo esc_html($wheel['name']); ?></a></strong>
</td>
<td>
<code>[wheel_of_fortune id="<?php echo esc_attr($wheel['slug']); ?>"]</code>
</td>
<td>
<a href="<?php echo admin_url('admin.php?page=wof-edit-wheel&wheel_id=' . $wheel['id']); ?>"><?php _e('Edit', 'wheel-of-fortune'); ?></a>
<?php if ($wheel['id'] != 1): // Cannot delete default wheel ?>
| <a href="<?php echo wp_nonce_url(admin_url('admin.php?page=wof-wheels&action=delete&wheel_id=' . $wheel['id']), 'wof_delete_wheel_' . $wheel['id']); ?>" class="delete-link" style="color:red;" onclick="return confirm('<?php _e('Are you sure you want to delete this wheel? This cannot be undone.', 'wheel-of-fortune'); ?>');"><?php _e('Delete', 'wheel-of-fortune'); ?></a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="4"><?php _e('No wheels found.', 'wheel-of-fortune'); ?></td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>