diff --git a/admin/edit-wheel-page-new.php b/admin/edit-wheel-page-new.php new file mode 100644 index 0000000..933146b --- /dev/null +++ b/admin/edit-wheel-page-new.php @@ -0,0 +1,569 @@ +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']) : ''; + + // Dodaj nova polja + $email_template_id = isset($_POST['email_template_id']) ? intval($_POST['email_template_id']) : 0; + $funded_account_name = isset($_POST['funded_account_name']) ? sanitize_text_field($_POST['funded_account_name']) : null; + $funded_account_value = isset($_POST['funded_account_value']) ? floatval($_POST['funded_account_value']) : null; + + 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, + + // Dodaj nova polja + 'email_template_id' => $email_template_id, + 'funded_account_name' => $funded_account_name, + 'funded_account_value' => $funded_account_value + ], + ['%d', '%s', '%s', '%f', '%d', '%s', '%d', '%f', '%s', '%s', '%d', '%s', '%f'] + ); + + if ($result !== false) { + echo '
' . __('Prize added successfully!', 'wheel-of-fortune') . '
' . __('Error adding prize. Please try again.', 'wheel-of-fortune') . '
' . __('Please fill in all required fields.', 'wheel-of-fortune') . '
' . __('Prize updated successfully!', 'wheel-of-fortune') . '
' . __('Error updating prize. Please try again.', 'wheel-of-fortune') . '
' . __('Please fill in all required fields.', 'wheel-of-fortune') . '
' . __('Napaka: Tabela za produkte ne obstaja. Prosimo, deaktivirajte in ponovno aktivirajte plugin.', 'wheel-of-fortune') . '
' . __('Napaka: Izbrano kolo ne obstaja.', 'wheel-of-fortune') . '
' . __('Napaka: Izbrani produkt ne obstaja.', 'wheel-of-fortune') . '
' . __('Produkt je bil uspešno dodan ali posodobljen.', 'wheel-of-fortune') . '
' . __('Napaka pri dodajanju produkta. Preveri vnos.', 'wheel-of-fortune') . '
' . __('Napaka pri dodajanju produkta. Preveri vnos.', 'wheel-of-fortune') . '
' . __('Produkt je bil izbrisan.', 'wheel-of-fortune') . '
' . __('Wheel not found.', 'wheel-of-fortune') . '
' . esc_html($total_probability) . ''); ?>
' . esc_html($total_probability) . ''); ?>
| + | + | + | + | + | + |
|---|---|---|---|---|---|
| + | + | + | + | + | + + + | +
| + | + | + |
|---|---|---|
| get_name()) : esc_html($prod['product_id']); ?> | ++ | + + + | +
{user_name}, {prize_name}, {prize_description}, {redemption_code}, {site_name}, {site_url}, {date}, {time}, {funded_account_name}, {funded_account_value}
{user_name}, {prize_name}, etc.
' . __('Email template added successfully!', 'wheel-of-fortune') . '
' . __('Error adding email template. Please try again.', 'wheel-of-fortune') . '
' . __('Please fill in all required fields.', 'wheel-of-fortune') . '
' . __('Email template updated successfully!', 'wheel-of-fortune') . '
' . __('Error updating email template. Please try again.', 'wheel-of-fortune') . '
' . __('Please fill in all required fields.', 'wheel-of-fortune') . '
' . __('Email template deleted successfully!', 'wheel-of-fortune') . '
' . __('Error deleting email template. Please try again.', 'wheel-of-fortune') . '
' . __('Invalid template ID.', 'wheel-of-fortune') . '
| + | + | + | + |
|---|---|---|---|
| + | + | + | + + + | +
Zadeli ste: ' + response.prize.name + '
'); - result.addClass('win').show(); - spinning = false; - - if (response.remaining_spins > 0) { - button.prop('disabled', false); - } - }, 5500); - } - }, - error: function(xhr) { - var errorMsg = 'Prišlo je do napake.'; - if (xhr.responseJSON && xhr.responseJSON.message) { - errorMsg = xhr.responseJSON.message; - } - - result.html('' + errorMsg + '
'); - result.removeClass('win').show(); - spinning = false; - button.prop('disabled', false); - } - }); - }); -}); -``` - -### SVG implementacija kolesa - -```php -function generate_wheel_svg($prizes) { - $num_prizes = count($prizes); - $angle = 360 / $num_prizes; - $svg = ''; - return $svg; -} -``` - -## Namestitev in uporaba - -### Namestitev vtičnika - -1. Prenesite ZIP datoteko vtičnika -2. V WordPress administratorski plošči pojdite na "Vtičniki" > "Dodaj nov" -3. Kliknite "Naloži vtičnik" in izberite preneseno ZIP datoteko -4. Aktivirajte vtičnik - -### Konfiguracija - -1. V administratorski plošči pojdite na "Kolo Sreče" > "Nastavitve" -2. Konfigurirajte izdelke, ki podeljujejo spine -3. Nastavite časovne omejitve in druge možnosti - -### Dodajanje nagrad - -1. Pojdite na "Kolo Sreče" > "Nagrade" -2. Dodajte nove nagrade z imenom, opisom, verjetnostjo in barvo -3. Zagotovite, da skupna vsota verjetnosti ne presega 1.0 - -### Prikaz kolesa na strani - -Dodajte kratko kodo `[wheel_of_fortune]` na želeno stran ali prispevek. - -Za prilagoditev videza uporabite dodatne parametre: -``` -[wheel_of_fortune size="large" theme="dark"] -``` - -### Prilagajanje velikosti kolesa - -Če želite dodatno prilagoditi velikost kolesa, da bo vse prišlo na zaslon, lahko uporabite parameter `scale`: - -- `scale-90`: Zmanjša kolo na 90% privzete velikosti -- `scale-80`: Zmanjša kolo na 80% privzete velikosti -- `scale-70`: Zmanjša kolo na 70% privzete velikosti -- `scale-60`: Zmanjša kolo na 60% privzete velikosti -- `scale-50`: Zmanjša kolo na 50% privzete velikosti - -Primer: `[wheel_of_fortune scale="scale-70"]` - -### Dodeljevanje spinov uporabnikom - -Spine lahko uporabnikom dodelite na naslednje načine: - -1. **Avtomatsko ob nakupu**: Nastavite število spinov za posamezne izdelke v nastavitvah vtičnika -2. **Ročno**: Uporabite stran "Uporabniki" v meniju "Kolo sreče" za ročno dodeljevanje spinov - -## Nastavitve - -### Splošne nastavitve - -- **Zahtevaj prijavo**: Če je omogočeno, morajo biti uporabniki prijavljeni za vrtenje kolesa -- **Dovoli samo en spin na dan**: Če je omogočeno, lahko uporabniki zavrtijo kolo samo enkrat na dan -- **Pošlji e-pošto ob zmagi**: Če je omogočeno, se uporabniku pošlje e-pošta ob zmagi - -### Nagrade - -Upravljajte z nagradami, ki jih lahko uporabniki zadanejo: - -- **Ime**: Ime nagrade -- **Opis**: Opis nagrade -- **Verjetnost**: Verjetnost, da uporabnik zadane to nagrado (v odstotkih) -- **Barva**: Barva segmenta na kolesu -- **Aktivna**: Ali je nagrada aktivna - -### Izdelki - -Nastavite število spinov, ki jih uporabnik prejme ob nakupu določenih izdelkov: - -1. Vnesite ID izdelka -2. Nastavite število spinov -3. Kliknite "Dodaj izdelek" - -## Statistika - -Spremljajte statistiko vrtljajev in zadetkov: - -- **Skupno število vrtljajev**: Skupno število vrtljajev vseh uporabnikov -- **Zadetki po nagradah**: Število zadetkov za vsako nagrado -- **Uporabniki z največ vrtljaji**: Seznam uporabnikov z največ vrtljaji - -## Razvijalcem - -### Filtri - -Vtičnik ponuja naslednje filtre za prilagajanje: - -- `wheel_of_fortune_prizes`: Prilagodite seznam nagrad -- `wheel_of_fortune_spin_result`: Prilagodite rezultat vrtljaja -- `wheel_of_fortune_email_content`: Prilagodite vsebino e-pošte ob zmagi - -### Akcije - -Vtičnik ponuja naslednje akcije: - -- `wheel_of_fortune_before_spin`: Izvede se pred vrtljajem -- `wheel_of_fortune_after_spin`: Izvede se po vrtljaju -- `wheel_of_fortune_prize_won`: Izvede se, ko uporabnik zadane nagrado - -## Pogosta vprašanja - -### Kolo se ne prikaže na strani - -Preverite naslednje: - -1. Ali je kratka koda pravilno vstavljena? -2. Ali so nagrade nastavljene in aktivne? -3. Ali je uporabnik prijavljen (če je to zahtevano)? -4. Ali ima uporabnik na voljo spine? -5. Poskusite zmanjšati velikost kolesa z uporabo parametra `scale`: `[wheel_of_fortune scale="scale-80"]` - -### Uporabnik ne prejme spinov ob nakupu - -Preverite naslednje: - -1. Ali je WooCommerce aktiviran? -2. Ali je izdelek pravilno nastavljen v nastavitvah vtičnika? -3. Ali je naročilo označeno kot "Zaključeno"? - -## Podpora - -Za podporo nas kontaktirajte na support@example.com """ - - -"./admin/coupon-test.php" : -""" - 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'); """ - - -"./admin/edit-wheel-page.php" : -""" -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 '' . __('Prize added successfully!', 'wheel-of-fortune') . '
' . __('Error adding prize. Please try again.', 'wheel-of-fortune') . '
' . __('Please fill in all required fields.', 'wheel-of-fortune') . '
' . __('Prize updated successfully!', 'wheel-of-fortune') . '
' . __('Error updating prize. Please try again.', 'wheel-of-fortune') . '
' . __('Please fill in all required fields.', 'wheel-of-fortune') . '
' . __('Napaka: Tabela za produkte ne obstaja. Prosimo, deaktivirajte in ponovno aktivirajte plugin.', 'wheel-of-fortune') . '
' . __('Napaka: Izbrano kolo ne obstaja.', 'wheel-of-fortune') . '
' . __('Napaka: Izbrani produkt ne obstaja.', 'wheel-of-fortune') . '
' . __('Produkt je bil uspešno dodan ali posodobljen.', 'wheel-of-fortune') . '
' . __('Napaka pri dodajanju produkta. Preveri vnos.', 'wheel-of-fortune') . '
' . __('Napaka pri dodajanju produkta. Preveri vnos.', 'wheel-of-fortune') . '
' . __('Produkt je bil izbrisan.', 'wheel-of-fortune') . '
' . __('Wheel not found.', 'wheel-of-fortune') . '
' . esc_html($total_probability) . ''); ?>
' . esc_html($total_probability) . ''); ?>
| - | - | - | - | - | - |
|---|---|---|---|---|---|
| - | - | - | - | - | - - - | -
| - | - | - |
|---|---|---|
| get_name()) : esc_html($prod['product_id']); ?> | -- | - - - | -
' + response.data.message + '
').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('' + errorMessage + '
').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('' + errorMessage + '
').slideDown(); - }, - complete: function() { - button.prop('disabled', false); - spinner.removeClass('is-active'); - } - }); - }); - } -});""" - - -"./admin/js/wheel.js" : -""" -/** - * 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(`You've won: ${prize.name}
`); - 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(`${response.data.message || 'An error occurred.'}
`); - 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(`${errorMsg}
`); - resultDiv.addClass('error').fadeIn(300); - isSpinning = false; - button.prop('disabled', false); - } - }); - }); - - // Initialization - if (wheelSettings.remainingSpins <= 0) { - button.prop('disabled', true); - } -});""" - - -"./admin/partials/prize-form-fields.php" : -""" - -' . - __('Nagrada je bila označena kot unovčena.', 'wheel-of-fortune') . - '
| - | - | - | - | - | - |
|---|---|---|---|---|---|
| - | |||||
| - | - | - | - | - | - - | -
| - | - |
|---|---|
| - | user_email); ?> | -
| - | - 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); - ?> - | -
| - | - 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); - ?> - | -
| - | - | - | - | - | - |
|---|---|---|---|---|---|
| - | - | - | - | - ' . esc_html__('Unovčeno', 'wheel-of-fortune') : - ' ' . esc_html__('Neunovčeno', 'wheel-of-fortune'); - ?> - | -- - - - | -
' . - sprintf(__('Uporabniku ID %d je bilo uspešno dodanih %d spinov za kolo %s.', 'wheel-of-fortune'), $user_id, $spins, $selected_wheel['name']) . - '
' . - sprintf(__('Spini uporabnika ID %d za kolo %s so bili uspešno ponastavljeni na 0.', 'wheel-of-fortune'), $user_id, $selected_wheel['name']) . - '
| - | - |
|---|---|
| - | user_email); ?> | -
| - | - 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); - ?> - | -
| - | - |
| - | - | - | - | - | - |
|---|---|---|---|---|---|
| - | - | - | - | - ' . esc_html__('Unovčeno', 'wheel-of-fortune') : - ' ' . esc_html__('Neunovčeno', 'wheel-of-fortune'); - ?> - | -- - - - | -
' . __('New wheel created successfully!', 'wheel-of-fortune') . '
' . __('Please provide a name for the wheel.', 'wheel-of-fortune') . '
' . __('Wheel deleted successfully.', 'wheel-of-fortune') . '
' . __('The default wheel cannot be deleted.', 'wheel-of-fortune') . '
${l10n.you_won} ${prize.name}
`; - if (window.wof_spin_result.discount_code) { - html += `${l10n.discount_code_sent}
`; - } - resultDiv.html(html).addClass('win').fadeIn(300); - } - - // Posodobitev števca spinov - function updateSpinsCounter() { - if (spinsCounter.length) { - spinsCounter.text(wheelSpins); - } - } - - // Klik na gumb za vrtenje - spinButton.on('click', function() { - if (isSpinning || wheelSpins <= 0) return; - - isSpinning = true; - spinButton.prop('disabled', true).text(l10n.spinning); - resultDiv.hide().removeClass('win error'); - - $.ajax({ - url: wof_data.rest_url, - method: 'POST', - beforeSend: function(xhr) { - xhr.setRequestHeader('X-WP-Nonce', wof_data.nonce); - }, - data: { - wheel_id: wof_data.wheel_id, - }, - success: function(response) { - if (response.success) { - window.wof_spin_result = response.data; - wheelSpins = response.data.remaining_spins; - updateSpinsCounter(); - - const finalAngle = response.data.degree; - const totalRotation = (360 * baseRotations) + finalAngle; - - animateWheel(Date.now(), accumulatedRotation, totalRotation); - - } else { - handleError(response.data.message || l10n.error); - } - }, - error: function(xhr) { - const errorMsg = xhr.responseJSON ? (xhr.responseJSON.message || l10n.error) : l10n.error; - handleError(errorMsg); - } - }); - }); - - function handleError(message) { - resultDiv.html(`${message}
`).addClass('error').fadeIn(300); - isSpinning = false; - if(wheelSpins > 0){ - spinButton.prop('disabled', false).text(l10n.spin_button); - } - } - - // Inicializacija - function init() { - updateSpinsCounter(); - if (wheelSpins <= 0) { - spinButton.prop('disabled', true).text(l10n.no_spins_left); - } - } - - init(); -});""" - - -"./languages/wheel-of-fortune.pot" : -""" -# Copyright (C) 2023 Vaše ime -# This file is distributed under the GPL v2 or later. -msgid "" -msgstr "" -"Project-Id-Version: Kolo Sreče 1.0.0\n" -"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wheel-of-fortune\n" -"POT-Creation-Date: 2023-07-01T12:00:00+00:00\n" -"PO-Revision-Date: 2023-07-01T12:00:00+00:00\n" -"Last-Translator: FULL NAME| - Congratulations, {user_name}! - | -||||||
- You've won a prize!-- You just won a fantastic prize on our Wheel of Fortune: - -
- To redeem your prize, follow the instructions on our website or contact our support team. - -- Thank you for participating! - - |
- ||||||
|
- This is an automated message. Please do not reply to this email. - © {date} {site_name}. All rights reserved. - |
-
Uspešno ste zadeli nagrado na našem kolesu sreče.
+Nagrada: {prize_name}
+{prize_description}
+Koda za unovčitev: {redemption_code}
+Hvala za sodelovanje!
+Lep pozdrav,
{site_name}
Uspešno ste zadeli Funded Account na našem kolesu sreče!
+Podrobnosti o vašem računu:
+Za aktivacijo vašega računa sledite naslednjim korakom:
+Če potrebujete pomoč, nas kontaktirajte na info@example.com.
+Lep pozdrav,
{site_name}
Uspešno ste zadeli kupon za popust na našem kolesu sreče!
+Vaš kupon vam omogoča popust pri naslednjem nakupu.
+Koda kupona: {redemption_code}
+Za uveljavitev popusta enostavno vnesite zgornjo kodo pri zaključku nakupa.
+Kupon je veljaven 30 dni od datuma prejema.
+Lep pozdrav,
{site_name}
Uspešno ste zadeli nagrado na našem kolesu sreče.
+Nagrada: {prize_name}
+{prize_description}
+ ' . (isset($prize['funded_account_name']) ? 'Račun: {funded_account_name}
' : '') . ' + ' . (isset($prize['funded_account_value']) ? 'Vrednost: {funded_account_value}
' : '') . ' + ' . (!empty($prize['redemption_code']) ? 'Koda za unovčitev: {redemption_code}
' : '') . ' +Hvala za sodelovanje!
+Lep pozdrav,
{site_name}