Prvi commit: Začetna verzija vtičnika Wheel of Fortune
This commit is contained in:
commit
0d28b08727
|
|
@ -0,0 +1,40 @@
|
|||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# IDE files
|
||||
.idea/
|
||||
.vscode/
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
# WordPress specific files
|
||||
*.log
|
||||
wp-config.php
|
||||
wp-content/advanced-cache.php
|
||||
wp-content/backup-*/
|
||||
wp-content/backups/
|
||||
wp-content/blogs.dir/
|
||||
wp-content/cache/
|
||||
wp-content/upgrade/
|
||||
wp-content/uploads/
|
||||
wp-content/wp-cache-config.php
|
||||
|
||||
# Node modules
|
||||
node_modules/
|
||||
|
||||
# Composer
|
||||
vendor/
|
||||
|
||||
# Others
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.tar
|
||||
*.bak
|
||||
*.swp
|
||||
*.tmp
|
||||
|
|
@ -0,0 +1,744 @@
|
|||
# Wheel of Fortune - WordPress Plugin
|
||||
|
||||
Vtičnik "Kolo Sreče" (Wheel of Fortune) omogoča uporabnikom vrtenje kolesa za nagrade. Povezan je z WooCommerce za dodeljevanje spinov ob nakupu izdelkov.
|
||||
|
||||
## Funkcionalnosti
|
||||
|
||||
- Prikaz interaktivnega kolesa sreče preko kratke kode [wheel_of_fortune]
|
||||
- Povezava z WooCommerce za dodeljevanje spinov ob nakupu izdelkov
|
||||
- Upravljanje z nagradami, verjetnostmi in barvami
|
||||
- Statistika vrtljajev in zadetkov
|
||||
|
||||
## Namestitev
|
||||
|
||||
1. Prenesite datoteke vtičnika v mapo `/wp-content/plugins/wheel-of-fortune/`
|
||||
2. Aktivirajte vtičnik preko menija 'Vtičniki' v WordPress skrbniški plošči
|
||||
3. Nastavite vtičnik preko menija 'Kolo sreče' v skrbniški plošči
|
||||
|
||||
## Uporaba
|
||||
|
||||
### Osnovna uporaba
|
||||
|
||||
Vstavite kratko kodo `[wheel_of_fortune]` na katerokoli stran ali prispevek, kjer želite prikazati kolo sreče.
|
||||
|
||||
### Parametri kratke kode
|
||||
|
||||
Kratka koda sprejme naslednje parametre:
|
||||
|
||||
- `size`: Velikost kolesa (možnosti: `small`, `medium`, `large`, privzeto: `medium`)
|
||||
- `theme`: Tema kolesa (možnosti: `light`, `dark`, privzeto: `light`)
|
||||
- `scale`: Dodatno prilagajanje velikosti (možnosti: `scale-90`, `scale-80`, `scale-70`, `scale-60`, `scale-50`, privzeto: prazen)
|
||||
|
||||
#### Primeri
|
||||
|
||||
```
|
||||
[wheel_of_fortune]
|
||||
[wheel_of_fortune size="large" theme="dark"]
|
||||
[wheel_of_fortune size="medium" theme="light" scale="scale-80"]
|
||||
```
|
||||
|
||||
## Vsebina
|
||||
1. [Namen vtičnika](#namen-vtičnika)
|
||||
2. [Ključne funkcionalnosti](#ključne-funkcionalnosti)
|
||||
3. [Tehnični opis](#tehnični-opis)
|
||||
4. [Logika delovanja](#logika-delovanja)
|
||||
5. [Administratorske nastavitve](#administratorske-nastavitve)
|
||||
6. [Kratka koda](#kratka-koda)
|
||||
7. [Varnost in integracije](#varnost-in-integracije)
|
||||
8. [Možne razširitve](#možne-razširitve)
|
||||
9. [Implementacija kolesa](#implementacija-kolesa)
|
||||
10. [Namestitev in uporaba](#namestitev-in-uporaba)
|
||||
|
||||
## Namen vtičnika
|
||||
|
||||
Vtičnik »Kolo Sreče« omogoča obiskovalcem spletne strani, da zavrtijo interaktivno kolo in prejmejo naključno nagrado. Vrtljaji so vezani na nakupe določenih izdelkov in uporabniške račune, kar omogoča gamificirano izkušnjo zvestobe in nagrajevanja.
|
||||
|
||||
## Ključne funkcionalnosti
|
||||
|
||||
- 🎯 Naključni izbor nagrade ob vrtenju kolesa
|
||||
- 🔐 Vezava spinov (vrtljajev) na uporabniški račun
|
||||
- 🛒 Samodejna dodelitev spinov ob nakupu določenih izdelkov
|
||||
- 🧠 Nastavljive nagrade in verjetnosti zadetkov
|
||||
- 📊 Spremljanje števila preostalih spinov
|
||||
- 🎛️ Kratka koda za vključitev kolesa kjerkoli v WordPress vsebino
|
||||
- 📬 Email obvestila ob zadetkih (opcijsko)
|
||||
- 📈 Administratorska statistika: število zadetkov, porabljenih spinov ipd.
|
||||
|
||||
## Tehnični opis
|
||||
|
||||
### Arhitektura
|
||||
- WordPress Plugin: zgrajen po WordPress standardih (object-oriented, namespacing, varnostni hooki)
|
||||
- Frontend: JavaScript za animacijo kolesa, AJAX za komunikacijo z backendom
|
||||
- Backend: PHP (WP REST API), povezano z WP uporabniki in WooCommerce naročili
|
||||
- Baza podatkov: uporaba wp_usermeta, lastne tabele wp_wheel_spins in wp_wheel_prizes
|
||||
|
||||
### Tabele podatkovne baze
|
||||
|
||||
#### wp_wheel_spins
|
||||
|
||||
| Polje | Tip | Opis |
|
||||
|-------|-----|------|
|
||||
| id | INT | Primarni ključ |
|
||||
| user_id | INT | ID uporabnika (WordPress) |
|
||||
| spins_available | INT | Število razpoložljivih spinov |
|
||||
| last_spin_date | DATETIME | Datum zadnjega vrtenja |
|
||||
|
||||
#### wp_wheel_prizes
|
||||
|
||||
| Polje | Tip | Opis |
|
||||
|-------|-----|------|
|
||||
| id | INT | Primarni ključ |
|
||||
| name | VARCHAR(255) | Ime nagrade |
|
||||
| description | TEXT | Opis nagrade |
|
||||
| probability | FLOAT | Verjetnost zadetka (0-1) |
|
||||
| color | VARCHAR(20) | Barva segmenta (HEX ali RGB) |
|
||||
| is_active | TINYINT | Ali je nagrada aktivna |
|
||||
| image_url | VARCHAR(255) | URL do slike nagrade (opcijsko) |
|
||||
|
||||
#### wp_wheel_log
|
||||
|
||||
| Polje | Tip | Opis |
|
||||
|-------|-----|------|
|
||||
| id | INT | Primarni ključ |
|
||||
| user_id | INT | ID uporabnika |
|
||||
| prize_id | INT | ID zadete nagrade |
|
||||
| spin_date | DATETIME | Datum in čas vrtenja |
|
||||
| redeemed | TINYINT | Ali je nagrada unovčena |
|
||||
|
||||
## Logika delovanja
|
||||
|
||||
### Podeljevanje spinov
|
||||
|
||||
Ob zaključenem nakupu določenega izdelka (npr. ID = 123), WooCommerce hook (woocommerce_order_status_completed) sproži funkcijo za dodelitev spinov.
|
||||
|
||||
```php
|
||||
function assign_spins_on_purchase($order_id) {
|
||||
$order = wc_get_order($order_id);
|
||||
foreach ($order->get_items() as $item) {
|
||||
$product_id = $item->get_product_id();
|
||||
$spin_products = get_option('wheel_spin_products', array());
|
||||
|
||||
if (array_key_exists($product_id, $spin_products)) {
|
||||
$user_id = $order->get_user_id();
|
||||
$current_spins = get_user_meta($user_id, '_wheel_spins', true) ?: 0;
|
||||
$new_spins = $current_spins + $spin_products[$product_id];
|
||||
update_user_meta($user_id, '_wheel_spins', $new_spins);
|
||||
|
||||
// Posodobi tudi v tabeli wp_wheel_spins
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'wheel_spins';
|
||||
|
||||
$existing = $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT id FROM $table_name WHERE user_id = %d",
|
||||
$user_id
|
||||
));
|
||||
|
||||
if ($existing) {
|
||||
$wpdb->update(
|
||||
$table_name,
|
||||
array('spins_available' => $new_spins),
|
||||
array('user_id' => $user_id)
|
||||
);
|
||||
} else {
|
||||
$wpdb->insert(
|
||||
$table_name,
|
||||
array(
|
||||
'user_id' => $user_id,
|
||||
'spins_available' => $new_spins,
|
||||
'last_spin_date' => current_time('mysql')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action('woocommerce_order_status_completed', 'assign_spins_on_purchase');
|
||||
```
|
||||
|
||||
### Vrtenje kolesa
|
||||
|
||||
1. Uporabnik klikne gumb "Zavrti"
|
||||
2. JS animira kolo (CSS transformacija)
|
||||
3. Medtem AJAX zahteva iz strežnika rezultat
|
||||
4. PHP backend izbere nagrado glede na verjetnosti
|
||||
5. Backend zabeleži zadetek, zmanjša število spinov
|
||||
|
||||
```php
|
||||
// REST API endpoint za vrtenje kolesa
|
||||
function spin_wheel_endpoint() {
|
||||
register_rest_route('wheel-of-fortune/v1', '/spin', array(
|
||||
'methods' => 'POST',
|
||||
'callback' => 'process_wheel_spin',
|
||||
'permission_callback' => function() {
|
||||
return is_user_logged_in();
|
||||
}
|
||||
));
|
||||
}
|
||||
add_action('rest_api_init', 'spin_wheel_endpoint');
|
||||
|
||||
function process_wheel_spin($request) {
|
||||
$user_id = get_current_user_id();
|
||||
$spins = get_user_meta($user_id, '_wheel_spins', true) ?: 0;
|
||||
|
||||
if ($spins <= 0) {
|
||||
return new WP_Error('no_spins', 'Nimate več razpoložljivih vrtljajev', array('status' => 403));
|
||||
}
|
||||
|
||||
// Preveri časovni interval med vrtljaji
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'wheel_spins';
|
||||
$last_spin = $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT last_spin_date FROM $table_name WHERE user_id = %d",
|
||||
$user_id
|
||||
));
|
||||
|
||||
$cooldown_minutes = get_option('wheel_cooldown_minutes', 0);
|
||||
if ($cooldown_minutes > 0 && $last_spin) {
|
||||
$time_diff = (strtotime(current_time('mysql')) - strtotime($last_spin)) / 60;
|
||||
if ($time_diff < $cooldown_minutes) {
|
||||
return new WP_Error(
|
||||
'cooldown',
|
||||
sprintf('Počakajte še %d minut pred naslednjim vrtenjem', ceil($cooldown_minutes - $time_diff)),
|
||||
array('status' => 403)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Izberi nagrado glede na verjetnosti
|
||||
$prize = select_random_prize($prizes);
|
||||
|
||||
// Posodobi število spinov
|
||||
update_user_meta($user_id, '_wheel_spins', $spins - 1);
|
||||
|
||||
// Posodobi tabelo wp_wheel_spins
|
||||
$wpdb->update(
|
||||
$table_name,
|
||||
array(
|
||||
'spins_available' => $spins - 1,
|
||||
'last_spin_date' => current_time('mysql')
|
||||
),
|
||||
array('user_id' => $user_id)
|
||||
);
|
||||
|
||||
// Zabeleži zadetek
|
||||
$log_table = $wpdb->prefix . 'wheel_log';
|
||||
$wpdb->insert(
|
||||
$log_table,
|
||||
array(
|
||||
'user_id' => $user_id,
|
||||
'prize_id' => $prize['id'],
|
||||
'spin_date' => current_time('mysql'),
|
||||
'redeemed' => 0
|
||||
)
|
||||
);
|
||||
|
||||
// Pošlji email obvestilo (če je vključeno)
|
||||
if (get_option('wheel_send_emails', false)) {
|
||||
send_prize_email($user_id, $prize);
|
||||
}
|
||||
|
||||
return array(
|
||||
'success' => true,
|
||||
'prize' => $prize,
|
||||
'remaining_spins' => $spins - 1,
|
||||
'degree' => calculate_prize_degree($prize['id'], $prizes)
|
||||
);
|
||||
}
|
||||
|
||||
function calculate_prize_degree($prize_id, $prizes) {
|
||||
// Izračunaj stopinje za animacijo kolesa
|
||||
$prize_index = 0;
|
||||
foreach ($prizes as $index => $prize) {
|
||||
if ($prize['id'] == $prize_id) {
|
||||
$prize_index = $index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$segment_size = 360 / count($prizes);
|
||||
$degree = 360 - ($prize_index * $segment_size + $segment_size / 2);
|
||||
// Dodaj naključno odstopanje znotraj segmenta
|
||||
$degree += mt_rand(-($segment_size / 4), $segment_size / 4);
|
||||
// Dodaj še nekaj obratov
|
||||
$degree += 360 * 5;
|
||||
|
||||
return $degree;
|
||||
}
|
||||
```
|
||||
|
||||
## Administratorske nastavitve
|
||||
|
||||
- 📦 Seznam izdelkov, ki podeljujejo spin (ID + št. spinov)
|
||||
- 🎁 Nastavitev nagrad (ime, opis, slika, verjetnost, barva)
|
||||
- 🗳️ Max. spinov na uporabnika
|
||||
- 🕒 Časovna omejitev (1 spin na X minut)
|
||||
- 🔧 Reset spinov / bonus kampanje
|
||||
- 📧 Nastavitve email obvestil
|
||||
|
||||
```php
|
||||
function wheel_admin_menu() {
|
||||
add_menu_page(
|
||||
'Kolo Sreče',
|
||||
'Kolo Sreče',
|
||||
'manage_options',
|
||||
'wheel-of-fortune',
|
||||
'wheel_settings_page',
|
||||
'dashicons-marker',
|
||||
30
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'wheel-of-fortune',
|
||||
'Nastavitve',
|
||||
'Nastavitve',
|
||||
'manage_options',
|
||||
'wheel-of-fortune',
|
||||
'wheel_settings_page'
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'wheel-of-fortune',
|
||||
'Nagrade',
|
||||
'Nagrade',
|
||||
'manage_options',
|
||||
'wheel-prizes',
|
||||
'wheel_prizes_page'
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'wheel-of-fortune',
|
||||
'Statistika',
|
||||
'Statistika',
|
||||
'manage_options',
|
||||
'wheel-stats',
|
||||
'wheel_stats_page'
|
||||
);
|
||||
}
|
||||
add_action('admin_menu', 'wheel_admin_menu');
|
||||
```
|
||||
|
||||
## Kratka koda
|
||||
|
||||
Kolo lahko prikažemo kjerkoli s pomočjo:
|
||||
|
||||
```
|
||||
[wheel_of_fortune]
|
||||
```
|
||||
|
||||
Možne opcije:
|
||||
|
||||
```
|
||||
[wheel_of_fortune size="large" theme="dark"]
|
||||
```
|
||||
|
||||
Implementacija kratke kode:
|
||||
|
||||
```php
|
||||
function wheel_shortcode($atts) {
|
||||
$atts = shortcode_atts(array(
|
||||
'size' => 'medium', // small, medium, large
|
||||
'theme' => 'light', // light, dark
|
||||
), $atts);
|
||||
|
||||
// Preveri, če je uporabnik prijavljen
|
||||
if (!is_user_logged_in()) {
|
||||
return '<div class="wheel-login-required">Za sodelovanje v nagradni igri se morate <a href="' . wp_login_url(get_permalink()) . '">prijaviti</a>.</div>';
|
||||
}
|
||||
|
||||
// Preveri, če ima uporabnik na voljo spine
|
||||
$user_id = get_current_user_id();
|
||||
$spins = get_user_meta($user_id, '_wheel_spins', true) ?: 0;
|
||||
|
||||
if ($spins <= 0) {
|
||||
return '<div class="wheel-no-spins">Trenutno nimate razpoložljivih vrtljajev. Kupite izdelke za pridobitev novih vrtljajev.</div>';
|
||||
}
|
||||
|
||||
// Naloži potrebne skripte in stile
|
||||
wp_enqueue_style('wheel-of-fortune-css', plugin_dir_url(__FILE__) . 'assets/css/wheel.css');
|
||||
wp_enqueue_script('wheel-of-fortune-js', plugin_dir_url(__FILE__) . 'assets/js/wheel.js', array('jquery'), '1.0', true);
|
||||
|
||||
wp_localize_script('wheel-of-fortune-js', 'wheelSettings', array(
|
||||
'ajaxUrl' => rest_url('wheel-of-fortune/v1/spin'),
|
||||
'nonce' => wp_create_nonce('wp_rest'),
|
||||
'prizes' => get_wheel_prizes(),
|
||||
'remainingSpins' => $spins
|
||||
));
|
||||
|
||||
// Vrni HTML za kolo
|
||||
ob_start();
|
||||
include plugin_dir_path(__FILE__) . 'templates/wheel.php';
|
||||
return ob_get_clean();
|
||||
}
|
||||
add_shortcode('wheel_of_fortune', 'wheel_shortcode');
|
||||
```
|
||||
|
||||
## Varnost in integracije
|
||||
|
||||
- CSRF zaščita za AJAX klice (WordPress nonce)
|
||||
- Preverjanje uporabniške prijave
|
||||
- Integracija z WooCommerce
|
||||
- Možna integracija z emailing sistemom (npr. MailPoet, Sendinblue)
|
||||
- Preverjanje vlog in pravic uporabnikov
|
||||
- Sanitizacija vnosov in validacija podatkov
|
||||
|
||||
## Možne razširitve
|
||||
|
||||
- 🎟️ Shranjevanje zgodovine zadetkov (WP tabelo wp_wheel_log)
|
||||
- 🏆 Leaderboard: največ zadetkov / spinov
|
||||
- 🔗 Integracija z zvestobnim sistemom (CLIP)
|
||||
- 📱 Mobilna verzija (PWA)
|
||||
- 🔔 Push obvestila za bonus spin
|
||||
- 📊 Napredna analitika in poročila
|
||||
- 🌐 Večjezična podpora
|
||||
|
||||
## Implementacija kolesa
|
||||
|
||||
Glede na priloženo sliko, bo kolo implementirano kot interaktivna SVG ali Canvas komponenta z naslednjimi lastnostmi:
|
||||
|
||||
### Struktura kolesa
|
||||
- Kolo je razdeljeno na več segmentov (8-12)
|
||||
- Vsak segment ima svojo barvo (modra, rdeča, siva)
|
||||
- Segmenti vsebujejo besedilo z nagrado
|
||||
- Kazalec na vrhu označuje zmagovalni segment
|
||||
|
||||
### CSS in JS implementacija
|
||||
|
||||
```css
|
||||
.wheel-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.wheel {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
transform-origin: center;
|
||||
transition: transform 5s cubic-bezier(0.17, 0.67, 0.83, 0.67);
|
||||
}
|
||||
|
||||
.wheel-pointer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.wheel-segment {
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.wheel-segment-blue {
|
||||
fill: #5DADE2;
|
||||
}
|
||||
|
||||
.wheel-segment-red {
|
||||
fill: #E74C3C;
|
||||
}
|
||||
|
||||
.wheel-segment-gray {
|
||||
fill: #D5D8DC;
|
||||
}
|
||||
|
||||
.wheel-text {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
fill: white;
|
||||
text-anchor: middle;
|
||||
}
|
||||
|
||||
.wheel-button {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
padding: 10px 20px;
|
||||
background-color: #E74C3C;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wheel-button:disabled {
|
||||
background-color: #D5D8DC;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wheel-spins-counter {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.wheel-result {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wheel-result.win {
|
||||
background-color: #D5F5E3;
|
||||
border: 1px solid #2ECC71;
|
||||
}
|
||||
```
|
||||
|
||||
```javascript
|
||||
jQuery(document).ready(function($) {
|
||||
var wheel = $('.wheel');
|
||||
var button = $('.wheel-button');
|
||||
var result = $('.wheel-result');
|
||||
var spinning = false;
|
||||
|
||||
button.on('click', function() {
|
||||
if (spinning) return;
|
||||
|
||||
spinning = true;
|
||||
button.prop('disabled', true);
|
||||
result.hide();
|
||||
|
||||
$.ajax({
|
||||
url: wheelSettings.ajaxUrl,
|
||||
method: 'POST',
|
||||
beforeSend: function(xhr) {
|
||||
xhr.setRequestHeader('X-WP-Nonce', wheelSettings.nonce);
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
// Animiraj kolo
|
||||
wheel.css({
|
||||
'transform': 'rotate(' + response.degree + 'deg)'
|
||||
});
|
||||
|
||||
// Posodobi števec spinov
|
||||
$('.wheel-spins-counter span').text(response.remaining_spins);
|
||||
|
||||
// Prikaži rezultat po končani animaciji
|
||||
setTimeout(function() {
|
||||
result.html('<h3>Čestitamo!</h3><p>Zadeli ste: ' + response.prize.name + '</p>');
|
||||
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('<p>' + errorMsg + '</p>');
|
||||
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 = '<svg viewBox="0 0 500 500" class="wheel">';
|
||||
|
||||
// Center point
|
||||
$cx = 250;
|
||||
$cy = 250;
|
||||
$radius = 240;
|
||||
|
||||
// Generate segments
|
||||
for ($i = 0; $i < $num_prizes; $i++) {
|
||||
$prize = $prizes[$i];
|
||||
$start_angle = $i * $angle;
|
||||
$end_angle = ($i + 1) * $angle;
|
||||
|
||||
$start_rad = deg2rad($start_angle);
|
||||
$end_rad = deg2rad($end_angle);
|
||||
|
||||
$x1 = $cx + $radius * cos($start_rad);
|
||||
$y1 = $cy + $radius * sin($start_rad);
|
||||
$x2 = $cx + $radius * cos($end_rad);
|
||||
$y2 = $cy + $radius * sin($end_rad);
|
||||
|
||||
// Determine if the arc should be drawn as a large arc
|
||||
$large_arc = $end_angle - $start_angle > 180 ? 1 : 0;
|
||||
|
||||
// Create the path for the segment
|
||||
$path = "M{$cx},{$cy} L{$x1},{$y1} A{$radius},{$radius} 0 {$large_arc},1 {$x2},{$y2} Z";
|
||||
|
||||
// Determine the color class
|
||||
$color_class = '';
|
||||
switch ($prize['color']) {
|
||||
case 'blue':
|
||||
$color_class = 'wheel-segment-blue';
|
||||
break;
|
||||
case 'red':
|
||||
$color_class = 'wheel-segment-red';
|
||||
break;
|
||||
default:
|
||||
$color_class = 'wheel-segment-gray';
|
||||
}
|
||||
|
||||
$svg .= "<path d='{$path}' class='wheel-segment {$color_class}' />";
|
||||
|
||||
// Add text to the segment
|
||||
$text_angle = $start_angle + ($angle / 2);
|
||||
$text_rad = deg2rad($text_angle);
|
||||
$text_x = $cx + ($radius * 0.75) * cos($text_rad);
|
||||
$text_y = $cy + ($radius * 0.75) * sin($text_rad);
|
||||
|
||||
// Rotate text to be readable
|
||||
$text_rotate = $text_angle;
|
||||
if ($text_angle > 90 && $text_angle < 270) {
|
||||
$text_rotate += 180;
|
||||
}
|
||||
|
||||
$svg .= "<text x='{$text_x}' y='{$text_y}' class='wheel-text' transform='rotate({$text_rotate}, {$text_x}, {$text_y})'>{$prize['name']}</text>";
|
||||
}
|
||||
|
||||
// Add center circle
|
||||
$svg .= "<circle cx='{$cx}' cy='{$cy}' r='50' fill='white' />";
|
||||
|
||||
$svg .= '</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
|
||||
|
|
@ -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');
|
||||
|
|
@ -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'); ?>">← <?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>
|
||||
|
|
@ -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.');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
/**
|
||||
* Kolo Sreče - CSS za administratorski vmesnik
|
||||
*/
|
||||
|
||||
/* Splošni stil administratorske strani */
|
||||
.wheel-admin-page {
|
||||
max-width: 1200px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.wheel-admin-page h1 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.wheel-admin-page .nav-tab-wrapper {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Kartice */
|
||||
.wheel-card {
|
||||
background: #fff;
|
||||
border: 1px solid #ccd0d4;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.04);
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.wheel-card h2 {
|
||||
margin-top: 0;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
/* Tabela z nagradami */
|
||||
.wheel-prizes-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.wheel-prizes-table th,
|
||||
.wheel-prizes-table td {
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.wheel-prizes-table th {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.wheel-prizes-table tr:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
/* Barve nagrad */
|
||||
.wheel-color-preview {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.wheel-color-blue {
|
||||
background-color: #5DADE2;
|
||||
}
|
||||
|
||||
.wheel-color-red {
|
||||
background-color: #E74C3C;
|
||||
}
|
||||
|
||||
.wheel-color-gray {
|
||||
background-color: #D5D8DC;
|
||||
}
|
||||
|
||||
/* Obrazci */
|
||||
.wheel-form-table {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.wheel-form-table th {
|
||||
width: 200px;
|
||||
padding: 15px 10px 15px 0;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.wheel-form-table td {
|
||||
padding: 15px 10px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.wheel-form-table input[type="text"],
|
||||
.wheel-form-table input[type="number"],
|
||||
.wheel-form-table select,
|
||||
.wheel-form-table textarea {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.wheel-form-table .description {
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
margin-top: 5px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Gumbi */
|
||||
.wheel-button-primary {
|
||||
background: #0073aa;
|
||||
border-color: #0073aa;
|
||||
color: #fff;
|
||||
padding: 5px 15px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wheel-button-secondary {
|
||||
background: #f7f7f7;
|
||||
border-color: #ccc;
|
||||
color: #555;
|
||||
padding: 5px 15px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wheel-button-delete {
|
||||
background: #d63638;
|
||||
border-color: #d63638;
|
||||
color: #fff;
|
||||
padding: 5px 15px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Statistika */
|
||||
.wheel-stats-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -10px;
|
||||
}
|
||||
|
||||
.wheel-stats-box {
|
||||
background: #fff;
|
||||
border: 1px solid #ccd0d4;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.04);
|
||||
padding: 20px;
|
||||
margin: 10px;
|
||||
flex: 1 0 calc(33.333% - 20px);
|
||||
min-width: 250px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wheel-stats-box h3 {
|
||||
margin-top: 0;
|
||||
color: #23282d;
|
||||
}
|
||||
|
||||
.wheel-stats-number {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
color: #0073aa;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
/* Predogled kolesa */
|
||||
.wheel-preview-container {
|
||||
max-width: 300px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
/* Odzivnost */
|
||||
@media screen and (max-width: 782px) {
|
||||
.wheel-form-table th {
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.wheel-form-table td {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.wheel-stats-box {
|
||||
flex: 1 0 calc(50% - 20px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.wheel-stats-box {
|
||||
flex: 1 0 calc(100% - 20px);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,634 @@
|
|||
/**
|
||||
* Wheel of Fortune - CSS for wheel styling
|
||||
* Modern game-show aesthetic with 3D effects and lighting
|
||||
*/
|
||||
|
||||
/* Main container */
|
||||
.wheel-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
border-radius: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Dark theme */
|
||||
.wheel-container.theme-dark {
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
border-radius: 0 !important;
|
||||
padding: 0 !important;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* Wheel sizes */
|
||||
.wheel-container.size-small {
|
||||
max-width: 300px;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.wheel-container.size-medium {
|
||||
max-width: 650px;
|
||||
}
|
||||
|
||||
.wheel-container.size-large {
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
/* Wheel wrapper with lighting effects */
|
||||
.wheel-wrapper {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
max-width: 700px;
|
||||
filter: drop-shadow(0 0 15px rgba(0, 200, 255, 0.3));
|
||||
padding-top: 80px;
|
||||
transition: transform 0.05s ease-out;
|
||||
}
|
||||
|
||||
/* Outer ring lighting effect - POENOSTAVLJENO */
|
||||
.wheel-wrapper::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -5%;
|
||||
width: 110%;
|
||||
height: 110%;
|
||||
border-radius: 50%;
|
||||
/* Manj kompleksen gradient */
|
||||
background: radial-gradient(
|
||||
circle at center,
|
||||
rgba(0, 150, 200, 0.1) 0%,
|
||||
rgba(0, 0, 0, 0) 70%
|
||||
);
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Wheel */
|
||||
.wheel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transform-origin: center;
|
||||
transition: none; /* POMEMBNO: ne uporabljamo CSS tranzicije, saj jo upravlja JS */
|
||||
display: block;
|
||||
will-change: transform;
|
||||
/* Enostavnejši shadow, ki ga podpirajo vse naprave */
|
||||
filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.25));
|
||||
border: 4px solid #222;
|
||||
box-shadow: 0 0 10px 2px rgba(0, 223, 233, 0.5), 0 2px 8px rgba(0,0,0,0.3);
|
||||
border-radius: 50%;
|
||||
background: #111;
|
||||
}
|
||||
|
||||
/* Wheel frame - BREZ SVG FILTRA */
|
||||
.wheel-frame {
|
||||
fill: #0a4d6e;
|
||||
stroke: #0a7bb5;
|
||||
stroke-width: 8;
|
||||
}
|
||||
|
||||
/* LED lighting on wheel frame - BREZ SVG FILTRA */
|
||||
.wheel-light-track {
|
||||
fill: none;
|
||||
stroke: #00c8ff;
|
||||
stroke-width: 6;
|
||||
stroke-dasharray: 3, 8;
|
||||
animation: lightTrackAnimation 5s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes lightTrackAnimation {
|
||||
0% {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
100% {
|
||||
stroke-dashoffset: 100;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fast light track animation for spinning */
|
||||
@keyframes fastLightTrackAnimation {
|
||||
0% {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
100% {
|
||||
stroke-dashoffset: 200;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wheel segment - BREZ SVG FILTRA */
|
||||
.wheel-segment {
|
||||
stroke: #fff;
|
||||
stroke-width: 1px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
/* Simple gradients for cross-browser compatibility */
|
||||
.wheel-segment-yellow { fill: #ffdd00; }
|
||||
.wheel-segment-green { fill: #88ff00; }
|
||||
.wheel-segment-red { fill: #ff5500; }
|
||||
.wheel-segment-pink { fill: #ff44aa; }
|
||||
.wheel-segment-blue { fill: #00ccff; }
|
||||
|
||||
/* Divider between segments */
|
||||
.wheel-divider {
|
||||
stroke: rgba(255, 255, 255, 0.5);
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
/* Pegs on the wheel */
|
||||
.wheel-peg {
|
||||
fill: #e0e0e0;
|
||||
stroke: #666;
|
||||
stroke-width: 1px;
|
||||
/* Enostavnejši shadow namesto glow filtra */
|
||||
filter: drop-shadow(0 1px 2px rgba(0,0,0,0.5));
|
||||
}
|
||||
|
||||
@keyframes pegPulse {
|
||||
from {
|
||||
fill: #e0e0e0;
|
||||
filter: url(#pegGlow);
|
||||
}
|
||||
to {
|
||||
fill: #ffffff;
|
||||
filter: url(#pegGlow) drop-shadow(0 0 3px rgba(255, 255, 255, 0.8));
|
||||
}
|
||||
}
|
||||
|
||||
/* Faster peg pulse for spinning */
|
||||
@keyframes fastPegPulse {
|
||||
0% {
|
||||
fill: #e0e0e0;
|
||||
filter: url(#pegGlow);
|
||||
}
|
||||
50% {
|
||||
fill: #ffffff;
|
||||
filter: url(#pegGlow) drop-shadow(0 0 5px rgba(255, 255, 255, 0.9));
|
||||
}
|
||||
100% {
|
||||
fill: #e0e0e0;
|
||||
filter: url(#pegGlow);
|
||||
}
|
||||
}
|
||||
|
||||
/* Text on wheel - BREZ SVG FILTRA */
|
||||
.wheel-text {
|
||||
font-family: 'Arial Rounded MT Bold', 'Arial', sans-serif;
|
||||
font-size: 24px;
|
||||
font-weight: 900;
|
||||
fill: #ffffff;
|
||||
stroke: #000000;
|
||||
stroke-width: 0.5px;
|
||||
paint-order: stroke fill;
|
||||
letter-spacing: 1px;
|
||||
pointer-events: none;
|
||||
text-anchor: middle;
|
||||
/* Enostavnejša senca, ki deluje povsod */
|
||||
text-shadow: 1px 1px 3px rgba(0,0,0,0.7);
|
||||
text-overflow: ellipsis;
|
||||
max-width: 70px;
|
||||
}
|
||||
|
||||
/* Center hub - BREZ SVG FILTRA */
|
||||
.wheel-hub-outer {
|
||||
fill: #0a4d6e;
|
||||
stroke: #0a7bb5;
|
||||
stroke-width: 4;
|
||||
}
|
||||
|
||||
.wheel-hub-inner {
|
||||
fill: #999;
|
||||
}
|
||||
|
||||
.wheel-hub-button {
|
||||
fill: #330066;
|
||||
}
|
||||
|
||||
/* Hub text - BREZ SVG FILTRA */
|
||||
.wheel-hub-text {
|
||||
font-family: 'Arial Rounded MT Bold', 'Arial', sans-serif;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
fill: #ff00aa;
|
||||
text-anchor: middle;
|
||||
/* Enostavnejša senca namesto glow filtra */
|
||||
text-shadow: 0 0 10px #ff00aa;
|
||||
}
|
||||
|
||||
/* Pointer - BREZ SVG FILTRA */
|
||||
.wheel-pointer {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 60px;
|
||||
height: 70px;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.4));
|
||||
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Pointer active state - BREZ SVG FILTRA */
|
||||
.wheel-pointer.active {
|
||||
filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.8));
|
||||
animation: pointerPulse 1s infinite alternate;
|
||||
}
|
||||
|
||||
/* Pointer bounce effect when hitting a peg */
|
||||
.wheel-pointer.bounce {
|
||||
animation: pointerBounce 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes pointerPulse {
|
||||
from {
|
||||
opacity: 0.8;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pointerBounce {
|
||||
0% {
|
||||
transform: translateX(-50%) rotate(0deg);
|
||||
}
|
||||
25% {
|
||||
transform: translateX(-50%) rotate(-5deg);
|
||||
}
|
||||
75% {
|
||||
transform: translateX(-50%) rotate(5deg);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(-50%) rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
.wheel-pointer svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Pointer parts */
|
||||
.pointer-mount {
|
||||
fill: #c0c0c0;
|
||||
stroke: #a0a0a0;
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
.pointer-arm {
|
||||
fill: #a0a0a0;
|
||||
stroke: #808080;
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
.pointer-tip {
|
||||
fill: #ff0066;
|
||||
stroke: #cc0055;
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
/* Wheel button with improved styling */
|
||||
.wheel-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 20px auto 0 auto;
|
||||
padding: 0 40px;
|
||||
background: linear-gradient(135deg, #ff00c4, #00dfe9);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 24px;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 3px 10px #00dfe9;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 56px;
|
||||
min-width: 140px;
|
||||
letter-spacing: 2px;
|
||||
text-shadow: 0 2px 8px #000, 0 0 10px #0cf101;
|
||||
}
|
||||
|
||||
/* Button hover effect */
|
||||
.wheel-button:hover {
|
||||
transform: translateY(-2px) scale(1.04);
|
||||
box-shadow: 0 7px 30px #ff00c4, 0 0 30px #00dfe9;
|
||||
background: linear-gradient(135deg, #00dfe9, #ff00c4);
|
||||
}
|
||||
|
||||
/* Button active effect */
|
||||
.wheel-button:active {
|
||||
transform: translateY(1px) scale(0.98);
|
||||
box-shadow: 0 3px 10px #00dfe9;
|
||||
}
|
||||
|
||||
/* Button disabled state */
|
||||
.wheel-button:disabled {
|
||||
background: linear-gradient(135deg, #aa6699, #774466);
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* Button ripple effect */
|
||||
.wheel-button::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
opacity: 0;
|
||||
border-radius: 100%;
|
||||
transform: scale(1, 1) translate(-50%, -50%);
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
.wheel-button:focus:not(:active)::after {
|
||||
animation: ripple 1s ease-out;
|
||||
}
|
||||
|
||||
@keyframes ripple {
|
||||
0% {
|
||||
transform: scale(0, 0);
|
||||
opacity: 0.5;
|
||||
}
|
||||
20% {
|
||||
transform: scale(25, 25);
|
||||
opacity: 0.3;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: scale(40, 40);
|
||||
}
|
||||
}
|
||||
|
||||
/* Spins counter */
|
||||
.wheel-spins-counter {
|
||||
text-align: center;
|
||||
margin: 18px 0 0 0;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
text-shadow: 0 2px 8px #000, 0 0 10px #0cf101, 0 0 20px #00dfe9;
|
||||
letter-spacing: 1px;
|
||||
background: rgba(0,0,0,0.35);
|
||||
border-radius: 10px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
/* Result display */
|
||||
.wheel-result {
|
||||
display: none;
|
||||
text-align: center;
|
||||
margin: 20px 0;
|
||||
padding: 15px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
||||
color: white;
|
||||
animation: resultGlow 2s infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes resultGlow {
|
||||
from {
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
to {
|
||||
box-shadow: 0 5px 25px rgba(255, 0, 170, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.wheel-result.win {
|
||||
background: rgba(255, 0, 170, 0.2);
|
||||
}
|
||||
|
||||
.wheel-result h3 {
|
||||
font-size: 24px;
|
||||
margin: 0 0 10px 0;
|
||||
color: #ffffff;
|
||||
text-shadow: 0 0 10px rgba(255, 0, 170, 0.8);
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.wheel-result p {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.wheel-result strong {
|
||||
color: #ffcc00;
|
||||
font-size: 1.2em;
|
||||
text-shadow: 0 0 5px rgba(255, 204, 0, 0.8);
|
||||
}
|
||||
|
||||
/* Login required message */
|
||||
.wheel-login-required,
|
||||
.wheel-no-spins {
|
||||
text-align: center;
|
||||
margin: 20px 0;
|
||||
padding: 20px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.wheel-login-required a {
|
||||
color: #00c8ff;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
transition: all 0.3s ease;
|
||||
text-shadow: 0 0 5px rgba(0, 200, 255, 0.5);
|
||||
}
|
||||
|
||||
.wheel-login-required a:hover {
|
||||
color: #33d6ff;
|
||||
text-shadow: 0 0 10px rgba(0, 200, 255, 0.8);
|
||||
}
|
||||
|
||||
/* Error message */
|
||||
.wheel-error {
|
||||
text-align: center;
|
||||
margin: 20px 0;
|
||||
padding: 15px;
|
||||
background: rgba(255, 0, 0, 0.2);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Posodobljene medijske poizvedbe za manjše zaslone */
|
||||
@media (max-width: 768px) {
|
||||
.wheel-text {
|
||||
font-size: 10px;
|
||||
max-width: 60px;
|
||||
}
|
||||
|
||||
.wheel-container.size-large {
|
||||
max-width: 500px;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.wheel-hub-text {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.wheel-pointer {
|
||||
width: 50px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.wheel-wrapper {
|
||||
padding-top: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.wheel-container {
|
||||
padding: 20px 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.wheel-text {
|
||||
font-size: 8px;
|
||||
max-width: 50px;
|
||||
}
|
||||
|
||||
.wheel-container.size-medium,
|
||||
.wheel-container.size-small {
|
||||
max-width: 320px;
|
||||
transform: scale(0.85);
|
||||
}
|
||||
|
||||
.wheel-hub-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.wheel-button {
|
||||
padding: 8px 25px;
|
||||
font-size: 16px;
|
||||
margin: 15px auto;
|
||||
}
|
||||
|
||||
.wheel-pointer {
|
||||
width: 40px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.wheel-wrapper {
|
||||
padding-top: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.wheel-container {
|
||||
transform: scale(0.8);
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.wheel-text {
|
||||
font-size: 7px;
|
||||
max-width: 40px;
|
||||
}
|
||||
|
||||
.wheel-container.size-medium,
|
||||
.wheel-container.size-small,
|
||||
.wheel-container.size-large {
|
||||
max-width: 280px;
|
||||
transform: scale(0.75);
|
||||
}
|
||||
|
||||
.wheel-hub-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.wheel-button {
|
||||
padding: 7px 20px;
|
||||
font-size: 14px;
|
||||
margin: 10px auto;
|
||||
}
|
||||
|
||||
.wheel-pointer {
|
||||
width: 35px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.wheel-wrapper {
|
||||
padding-top: 25px;
|
||||
}
|
||||
|
||||
.wheel-result h3 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.wheel-result p {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dodana nova medijska poizvedba za zelo majhne zaslone */
|
||||
@media (max-width: 360px) {
|
||||
.wheel-container {
|
||||
transform: scale(0.7);
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.wheel-container.size-medium,
|
||||
.wheel-container.size-small,
|
||||
.wheel-container.size-large {
|
||||
max-width: 240px;
|
||||
transform: scale(0.65);
|
||||
}
|
||||
|
||||
.wheel-text {
|
||||
font-size: 6px;
|
||||
max-width: 30px;
|
||||
}
|
||||
|
||||
.wheel-hub-text {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.wheel-pointer {
|
||||
width: 30px;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.wheel-wrapper {
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dodana možnost za ročno prilagajanje velikosti */
|
||||
.wheel-container.scale-90 {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.wheel-container.scale-80 {
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
.wheel-container.scale-70 {
|
||||
transform: scale(0.7);
|
||||
}
|
||||
|
||||
.wheel-container.scale-60 {
|
||||
transform: scale(0.6);
|
||||
}
|
||||
|
||||
.wheel-container.scale-50 {
|
||||
transform: scale(0.5);
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
/**
|
||||
* Wheel of Fortune - JavaScript for wheel functionality
|
||||
* Robust, smooth animation using requestAnimationFrame and easing functions.
|
||||
*/
|
||||
jQuery(document).ready(function($) {
|
||||
// Preveri, ali so podatki na voljo
|
||||
if (typeof wof_data === 'undefined') {
|
||||
console.error('WOF Data is missing.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Elementi
|
||||
var wheelContainer = $('.wheel-container');
|
||||
var wheelElement = wheelContainer.find('.wheel');
|
||||
var spinButton = wheelContainer.find('.wheel-button');
|
||||
var resultDiv = wheelContainer.find('.wheel-result');
|
||||
var spinsCounter = wheelContainer.find('.wheel-spins-counter span');
|
||||
|
||||
// Stanje
|
||||
var isSpinning = false;
|
||||
var accumulatedRotation = 0;
|
||||
var wheelSpins = wof_data.spins_left;
|
||||
var l10n = wof_data.l10n;
|
||||
|
||||
// Nastavitve animacije
|
||||
var spinDuration = 8000;
|
||||
var baseRotations = 5;
|
||||
|
||||
// Funkcija za animacijo
|
||||
function easeOutCubic(t) {
|
||||
return 1 - Math.pow(1 - t, 3);
|
||||
}
|
||||
|
||||
function animateWheel(startTime, startRotation, totalRotation) {
|
||||
var currentTime = Date.now();
|
||||
var elapsedTime = currentTime - startTime;
|
||||
|
||||
if (elapsedTime >= spinDuration) {
|
||||
wheelElement.css('transform', 'rotate(' + (startRotation + totalRotation) + 'deg)');
|
||||
accumulatedRotation = (startRotation + totalRotation);
|
||||
finishSpin();
|
||||
return;
|
||||
}
|
||||
|
||||
var timeProgress = elapsedTime / spinDuration;
|
||||
var rotationProgress = easeOutCubic(timeProgress);
|
||||
var currentRotation = startRotation + (totalRotation * rotationProgress);
|
||||
wheelElement.css('transform', 'rotate(' + currentRotation + 'deg)');
|
||||
|
||||
requestAnimationFrame(function() {
|
||||
animateWheel(startTime, startRotation, totalRotation);
|
||||
});
|
||||
}
|
||||
|
||||
// Obdelava po koncu vrtenja
|
||||
function finishSpin() {
|
||||
var prize = window.wof_spin_result.prize;
|
||||
showPrizePopup(prize);
|
||||
isSpinning = false;
|
||||
|
||||
if (wheelSpins > 0) {
|
||||
spinButton.prop('disabled', false).text(l10n.spin_button);
|
||||
} else {
|
||||
spinButton.prop('disabled', true).text(l10n.no_spins_left);
|
||||
}
|
||||
}
|
||||
|
||||
// Prikaz nagrade
|
||||
function showPrizePopup(prize) {
|
||||
var html = '<h3>' + l10n.congratulations + '</h3><p>' + l10n.you_won + ' <strong>' + prize.name + '</strong></p>';
|
||||
if (window.wof_spin_result.discount_code) {
|
||||
html += '<p>' + l10n.discount_code_sent + '</p>';
|
||||
}
|
||||
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();
|
||||
|
||||
var targetAngle = response.data.degree;
|
||||
var fullSpinsRotation = baseRotations * 360;
|
||||
var currentAngle = accumulatedRotation % 360;
|
||||
|
||||
var rotationToTarget = targetAngle - currentAngle;
|
||||
if (rotationToTarget < 0) {
|
||||
rotationToTarget += 360;
|
||||
}
|
||||
|
||||
var totalRotationAmount = fullSpinsRotation + rotationToTarget;
|
||||
|
||||
animateWheel(Date.now(), accumulatedRotation, totalRotationAmount);
|
||||
|
||||
} else {
|
||||
handleError(response.data.message || l10n.error);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
var errorMsg = xhr.responseJSON ? (xhr.responseJSON.message || l10n.error) : l10n.error;
|
||||
handleError(errorMsg);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function handleError(message) {
|
||||
resultDiv.html('<p>' + message + '</p>').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();
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Set the output file
|
||||
OUTPUT_FILE="code_export.txt"
|
||||
|
||||
# Remove the output file if it exists
|
||||
if [ -f "$OUTPUT_FILE" ]; then
|
||||
rm "$OUTPUT_FILE"
|
||||
fi
|
||||
|
||||
# Find all files except hidden files and directories
|
||||
find . -type f -not -path "*/\.*" -not -path "*node_modules*" -not -path "*vendor*" | sort | while read -r file; do
|
||||
# Skip the output file itself and this script
|
||||
if [[ "$file" == "./$OUTPUT_FILE" || "$file" == "./export_code.sh" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Skip binary files and the output file itself
|
||||
if file "$file" | grep -q "binary"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Add the filename and content to the output file
|
||||
echo "\"$file\" : " >> "$OUTPUT_FILE"
|
||||
echo "\"\"\"" >> "$OUTPUT_FILE"
|
||||
cat "$file" >> "$OUTPUT_FILE"
|
||||
echo "\"\"\"" >> "$OUTPUT_FILE"
|
||||
echo "" >> "$OUTPUT_FILE"
|
||||
echo "" >> "$OUTPUT_FILE"
|
||||
done
|
||||
|
||||
echo "Code export completed. Output saved to $OUTPUT_FILE"
|
||||
|
|
@ -0,0 +1,625 @@
|
|||
# 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 <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: WP-CLI 2.7.1\n"
|
||||
"X-Domain: wheel-of-fortune\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Kolo Sreče"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://example.com/kolo-srece"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "WordPress vtičnik za interaktivno kolo sreče z nagradami"
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Vaše ime"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://example.com"
|
||||
msgstr ""
|
||||
|
||||
#: wheel-of-fortune.php:199
|
||||
msgid "Nimate več razpoložljivih vrtljajev"
|
||||
msgstr ""
|
||||
|
||||
#: wheel-of-fortune.php:214
|
||||
msgid "Počakajte še %d minut pred naslednjim vrtenjem"
|
||||
msgstr ""
|
||||
|
||||
#: wheel-of-fortune.php:304
|
||||
msgid "Čestitamo! Zadeli ste nagrado na kolesu sreče - %s"
|
||||
msgstr ""
|
||||
|
||||
#: wheel-of-fortune.php:307
|
||||
msgid ""
|
||||
"Pozdravljeni %s,\n"
|
||||
"\n"
|
||||
"Čestitamo! Pravkar ste zadeli nagrado na našem kolesu sreče:\n"
|
||||
"\n"
|
||||
"%s - %s\n"
|
||||
"\n"
|
||||
"Za unovčenje nagrade se obrnite na našo podporo ali sledite navodilom na naši spletni strani.\n"
|
||||
"\n"
|
||||
"Lep pozdrav,\n"
|
||||
"Ekipa %s"
|
||||
msgstr ""
|
||||
|
||||
#: wheel-of-fortune.php:372
|
||||
msgid "Za sodelovanje v nagradni igri se morate <a href=\"%s\">prijaviti</a>."
|
||||
msgstr ""
|
||||
|
||||
#: wheel-of-fortune.php:383
|
||||
msgid "Trenutno nimate razpoložljivih vrtljajev. Kupite izdelke za pridobitev novih vrtljajev."
|
||||
msgstr ""
|
||||
|
||||
#: templates/wheel.php:37
|
||||
msgid "Preostali vrtljaji:"
|
||||
msgstr ""
|
||||
|
||||
#: templates/wheel.php:41
|
||||
msgid "Zavrti kolo"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:37
|
||||
msgid "Nastavitve so bile uspešno shranjene."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:53
|
||||
msgid "Kolo Sreče - Nastavitve"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:56
|
||||
msgid "Splošne nastavitve"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:57
|
||||
msgid "Izdelki"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:58
|
||||
msgid "Predogled"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:71
|
||||
msgid "Časovna omejitev (minute)"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:75
|
||||
msgid "Število minut, ki mora preteči med dvema vrtljajema. Vrednost 0 pomeni brez omejitve."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:80
|
||||
msgid "Maksimalno število spinov"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:84
|
||||
msgid "Maksimalno število spinov, ki jih lahko ima uporabnik. Vrednost 0 pomeni brez omejitve."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:89
|
||||
msgid "Email obvestila"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:93
|
||||
msgid "Pošlji email obvestilo ob zadetku nagrade"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:103
|
||||
msgid "Upravljanje s spini"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:108
|
||||
msgid "Dodeli spine uporabnikom"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:111
|
||||
msgid "Uporabite spodnji obrazec za dodelitev spinov izbranim uporabnikom."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:114
|
||||
msgid "Išči uporabnike..."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:116
|
||||
msgid "Izberi uporabnika"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:118
|
||||
msgid "Število spinov"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:119
|
||||
msgid "Dodaj spine"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:125
|
||||
msgid "Ponastavi vse spine"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:128
|
||||
msgid "Ponastavi vse spine"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:129
|
||||
msgid "Ta akcija bo ponastavila število spinov za vse uporabnike na 0. Tega ni mogoče razveljaviti!"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:139
|
||||
msgid "Izdelki, ki podeljujejo spine"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:141
|
||||
msgid "Nastavite izdelke, ki bodo ob nakupu podelili določeno število spinov."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:146
|
||||
msgid "ID izdelka"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:147
|
||||
msgid "Ime izdelka"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:148
|
||||
msgid "Število spinov"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:149
|
||||
msgid "Akcije"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:155
|
||||
msgid "Ni nastavljenih izdelkov."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:169
|
||||
msgid "Odstrani"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:178
|
||||
msgid "ID izdelka"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:182
|
||||
msgid "Število spinov"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:185
|
||||
msgid "Dodaj izdelek"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:197
|
||||
msgid "Predogled kolesa"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:209
|
||||
msgid "To je predogled kolesa, ki ga bodo videli uporabniki. Za spreminjanje nagrad pojdite na stran \"Nagrade\"."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:215
|
||||
msgid "Shrani nastavitve"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:233
|
||||
msgid "Izdelek ni najden"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:236
|
||||
msgid "Napaka pri iskanju izdelka"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:249
|
||||
msgid "Vnesite veljaven ID izdelka in število spinov"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:256
|
||||
msgid "Odstrani"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:276
|
||||
msgid "Ni nastavljenih izdelkov."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:283
|
||||
msgid "Ali ste prepričani, da želite ponastaviti vse spine za vse uporabnike? Tega ni mogoče razveljaviti!"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:292
|
||||
msgid "Vsi spini so bili uspešno ponastavljeni."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:294
|
||||
msgid "Napaka pri ponastavljanju spinov:"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:297
|
||||
msgid "Prišlo je do napake pri komunikaciji s strežnikom."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:320
|
||||
msgid "Izberi uporabnika"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:337
|
||||
msgid "Izberite uporabnika in vnesite število spinov"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:352
|
||||
msgid "Spini so bili uspešno dodani."
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:354
|
||||
msgid "Napaka pri dodajanju spinov:"
|
||||
msgstr ""
|
||||
|
||||
#: admin/settings-page.php:357
|
||||
msgid "Prišlo je do napake pri komunikaciji s strežnikom."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:36
|
||||
msgid "Ime nagrade je obvezno."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:38
|
||||
msgid "Verjetnost mora biti med 0 in 1."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:54
|
||||
msgid "Nagrada je bila uspešno dodana."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:80
|
||||
msgid "Ime nagrade je obvezno."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:82
|
||||
msgid "Verjetnost mora biti med 0 in 1."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:98
|
||||
msgid "Nagrada je bila uspešno posodobljena."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:117
|
||||
msgid "Nagrada je bila uspešno izbrisana."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:134
|
||||
msgid "Kolo Sreče - Nagrade"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:139
|
||||
msgid "Seznam nagrad"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:143
|
||||
msgid "Opozorilo: Skupna verjetnost vseh nagrad presega 1 (100%). Priporočamo, da prilagodite verjetnosti tako, da bo skupna vsota enaka 1."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:144
|
||||
msgid "Trenutna skupna verjetnost:"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:147
|
||||
msgid "Opozorilo: Skupna verjetnost vseh nagrad je manjša od 1 (100%). Priporočamo, da prilagodite verjetnosti tako, da bo skupna vsota enaka 1."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:148
|
||||
msgid "Trenutna skupna verjetnost:"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:156
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:157
|
||||
msgid "Ime"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:158
|
||||
msgid "Opis"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:159
|
||||
msgid "Verjetnost"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:160
|
||||
msgid "Barva"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:161
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:162
|
||||
msgid "Akcije"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:168
|
||||
msgid "Ni nagrad. Dodajte prvo nagrado spodaj."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:179
|
||||
msgid "Aktivna"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:179
|
||||
msgid "Neaktivna"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:182
|
||||
msgid "Uredi"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:183
|
||||
msgid "Izbriši"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:194
|
||||
msgid "Dodaj novo nagrado"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:203
|
||||
msgid "Ime nagrade"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:210
|
||||
msgid "Opis"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:217
|
||||
msgid "Verjetnost"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:221
|
||||
msgid "Vnesite vrednost med 0 in 1 (npr. 0.1 za 10% verjetnost)."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:226
|
||||
msgid "Barva"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:230
|
||||
msgid "Modra"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:231
|
||||
msgid "Rdeča"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:232
|
||||
msgid "Siva"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:239
|
||||
msgid "Nagrada je aktivna"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:247
|
||||
msgid "Dodaj nagrado"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:258
|
||||
msgid "Uredi nagrado"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:267
|
||||
msgid "Ime nagrade"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:274
|
||||
msgid "Opis"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:281
|
||||
msgid "Verjetnost"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:285
|
||||
msgid "Vnesite vrednost med 0 in 1 (npr. 0.1 za 10% verjetnost)."
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:290
|
||||
msgid "Barva"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:294
|
||||
msgid "Modra"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:295
|
||||
msgid "Rdeča"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:296
|
||||
msgid "Siva"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:303
|
||||
msgid "Nagrada je aktivna"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:311
|
||||
msgid "Shrani spremembe"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:335
|
||||
msgid "Aktivna"
|
||||
msgstr ""
|
||||
|
||||
#: admin/prizes-page.php:345
|
||||
msgid "Ali ste prepričani, da želite izbrisati to nagrado?"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:134
|
||||
msgid "Kolo Sreče - Statistika"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:138
|
||||
msgid "Skupno število vrtljajev"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:143
|
||||
msgid "Uporabniki z vrtljaji"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:148
|
||||
msgid "Preostali vrtljaji"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:155
|
||||
msgid "Nagrade po kategorijah"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:160
|
||||
msgid "Nagrada"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:161
|
||||
msgid "Barva"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:162
|
||||
msgid "Število zadetkov"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:168
|
||||
msgid "Ni podatkov."
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:186
|
||||
msgid "Vrtljaji po dnevih (zadnjih 30 dni)"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:189
|
||||
msgid "Ni podatkov za prikaz."
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:225
|
||||
msgid "Uporabniki z največ vrtljaji"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:230
|
||||
msgid "Uporabnik"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:231
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:232
|
||||
msgid "Število vrtljajev"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:238
|
||||
msgid "Ni podatkov."
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:255
|
||||
msgid "Uporabniki z največ preostalimi vrtljaji"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:260
|
||||
msgid "Uporabnik"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:261
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:262
|
||||
msgid "Preostali vrtljaji"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:268
|
||||
msgid "Ni podatkov."
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:285
|
||||
msgid "Zadnjih 10 vrtljajev"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:290
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:291
|
||||
msgid "Uporabnik"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:292
|
||||
msgid "Nagrada"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:293
|
||||
msgid "Datum"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:294
|
||||
msgid "Unovčeno"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:300
|
||||
msgid "Ni podatkov."
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:310
|
||||
msgid "Da"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:312
|
||||
msgid "Ne"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:325
|
||||
msgid "Izvoz podatkov"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:327
|
||||
msgid "Izvozite podatke o vrtljajih in nagradah za nadaljnjo analizo."
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:336
|
||||
msgid "Vsi vrtljaji"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:342
|
||||
msgid "Nagrade in zadetki"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:348
|
||||
msgid "Uporabniki in vrtljaji"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:353
|
||||
msgid "Od datuma:"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:358
|
||||
msgid "Do datuma:"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:363
|
||||
msgid "Format:"
|
||||
msgstr ""
|
||||
|
||||
#: admin/stats-page.php:372
|
||||
msgid "Izvozi podatke"
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
/**
|
||||
* Template for the Wheel of Fortune shortcode.
|
||||
*
|
||||
* This template is included from the shortcode function and has access to:
|
||||
* @var int $wheel_id
|
||||
* @var array $prizes
|
||||
* @var int $spins_left
|
||||
*/
|
||||
if (!defined('ABSPATH')) exit;
|
||||
?>
|
||||
|
||||
<div class="wheel-container">
|
||||
<div class="wheel-wrapper">
|
||||
<div class="wheel-svg">
|
||||
<?php echo $this->generate_wheel_svg($prizes); ?>
|
||||
</div>
|
||||
<div class="wheel-pointer">
|
||||
<!-- SVG za puščico je lahko tukaj ali v CSS kot background-image -->
|
||||
<svg width="60" height="70" viewBox="0 0 60 70" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M30 70L58.286 17.5H1.714L30 70Z" fill="#D9D9D9"/><path d="M30 70L58.286 17.5H1.714L30 70Z" stroke="black" stroke-width="2"/><circle cx="30" cy="15" r="15" fill="#C4C4C4" stroke="black" stroke-width="2"/></svg>
|
||||
</div>
|
||||
<div class="wheel-button-container">
|
||||
<button class="wheel-button" <?php echo ($spins_left <= 0) ? 'disabled' : ''; ?>>
|
||||
<?php echo ($spins_left > 0) ? esc_html($l10n['spin_button']) : esc_html($l10n['no_spins_left']); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wheel-info">
|
||||
<div class="wheel-spins-counter">
|
||||
<?php _e('Spins left:', 'wheel-of-fortune'); ?> <span><?php echo esc_html($spins_left); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wheel-result" style="display: none;"></div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Congratulations on your win!</title>
|
||||
</head>
|
||||
<body style="font-family: Arial, sans-serif; margin: 20px; padding: 0; background-color: #f4f4f4;">
|
||||
<table align="center" border="0" cellpadding="0" cellspacing="0" width="600" style="border-collapse: collapse; background-color: #ffffff; border: 1px solid #dddddd;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#70bbd9" style="padding: 40px 0 30px 0; color: #ffffff; font-size: 28px; font-weight: bold;">
|
||||
Congratulations, {user_name}!
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor="#ffffff" style="padding: 40px 30px 40px 30px;">
|
||||
<h1 style="color: #333333;">You've won a prize!</h1>
|
||||
<p style="color: #555555; font-size: 16px;">
|
||||
You just won a fantastic prize on our Wheel of Fortune:
|
||||
</p>
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="margin-top: 20px;">
|
||||
<tr>
|
||||
<td width="150" style="font-weight: bold;">Prize:</td>
|
||||
<td>{prize_name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-weight: bold;">Description:</td>
|
||||
<td>{prize_description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-weight: bold;">Redemption code:</td>
|
||||
<td><strong>{redemption_code}</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p style="color: #555555; font-size: 16px; margin-top: 30px;">
|
||||
To redeem your prize, follow the instructions on our website or contact our support team.
|
||||
</p>
|
||||
<p style="color: #555555; font-size: 16px;">
|
||||
Thank you for participating!
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor="#eeeeee" style="padding: 30px 30px 30px 30px; text-align: center; color: #888888; font-size: 12px;">
|
||||
This is an automated message. Please do not reply to this email.<br/>
|
||||
© {date} <a href="{site_url}" style="color: #888888;">{site_name}</a>. All rights reserved.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
<?php
|
||||
/**
|
||||
* Template for displaying the wheel of fortune
|
||||
*
|
||||
* @var array $atts Shortcode attributes
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Get number of available spins for this specific wheel
|
||||
$user_id = get_current_user_id();
|
||||
$wheel_id = isset($template_vars['wheel_id']) ? $template_vars['wheel_id'] : 1;
|
||||
global $wpdb;
|
||||
$spins_table = $wpdb->prefix . 'wheel_spins';
|
||||
$spins = $wpdb->get_var($wpdb->prepare("SELECT spins_available FROM $spins_table WHERE user_id = %d AND wheel_id = %d", $user_id, $wheel_id));
|
||||
$spins = $spins === null ? 0 : (int) $spins;
|
||||
|
||||
// Get prizes for the specific wheel
|
||||
$wheel = wheel_of_fortune();
|
||||
$prizes = $wheel->get_wheel_prizes($wheel_id);
|
||||
|
||||
// Set classes for size, theme and scale
|
||||
$container_classes = array(
|
||||
'wheel-container',
|
||||
'wheel-of-fortune-container',
|
||||
'size-' . $atts['size'],
|
||||
'theme-' . $atts['theme']
|
||||
);
|
||||
|
||||
// Add scale class if provided
|
||||
if (!empty($atts['scale'])) {
|
||||
$container_classes[] = $atts['scale'];
|
||||
}
|
||||
|
||||
// Generate unique ID for this wheel
|
||||
$wheel_id_html = 'wheel-of-fortune-' . uniqid();
|
||||
|
||||
?>
|
||||
<div id="<?php echo esc_attr($wheel_id_html); ?>" class="<?php echo esc_attr(implode(' ', $container_classes)); ?>">
|
||||
<!-- SVG Filters and Gradients for 3D effects -->
|
||||
<svg width="0" height="0" style="position: absolute;">
|
||||
<!-- Gradients for wheel segments -->
|
||||
<linearGradient id="gradientYellow" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#ffdd00" />
|
||||
<stop offset="100%" stop-color="#ffaa00" />
|
||||
</linearGradient>
|
||||
<linearGradient id="gradientGreen" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#88ff00" />
|
||||
<stop offset="100%" stop-color="#44cc00" />
|
||||
</linearGradient>
|
||||
<linearGradient id="gradientRed" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#ff5500" />
|
||||
<stop offset="100%" stop-color="#cc3300" />
|
||||
</linearGradient>
|
||||
<linearGradient id="gradientPink" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#ff44aa" />
|
||||
<stop offset="100%" stop-color="#cc2288" />
|
||||
</linearGradient>
|
||||
<linearGradient id="gradientBlue" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#00ccff" />
|
||||
<stop offset="100%" stop-color="#0088cc" />
|
||||
</linearGradient>
|
||||
|
||||
<!-- Hub gradients -->
|
||||
<radialGradient id="hubGradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
|
||||
<stop offset="0%" stop-color="#dddddd" />
|
||||
<stop offset="70%" stop-color="#999999" />
|
||||
<stop offset="100%" stop-color="#666666" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="buttonGradient" cx="50%" cy="30%" r="70%" fx="50%" fy="30%">
|
||||
<stop offset="0%" stop-color="#330066" />
|
||||
<stop offset="100%" stop-color="#220044" />
|
||||
</radialGradient>
|
||||
|
||||
<!-- Chrome effect for pegs -->
|
||||
<linearGradient id="chromeGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#ffffff" />
|
||||
<stop offset="25%" stop-color="#f0f0f0" />
|
||||
<stop offset="50%" stop-color="#d0d0d0" />
|
||||
<stop offset="75%" stop-color="#a0a0a0" />
|
||||
<stop offset="100%" stop-color="#808080" />
|
||||
</linearGradient>
|
||||
|
||||
<!-- Pointer gradients -->
|
||||
<linearGradient id="pointerGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#e0e0e0" />
|
||||
<stop offset="50%" stop-color="#b0b0b0" />
|
||||
<stop offset="100%" stop-color="#707070" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="pointerShineGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#ffffff" />
|
||||
<stop offset="100%" stop-color="rgba(255,255,255,0)" />
|
||||
</linearGradient>
|
||||
|
||||
<!-- Filters for 3D effects -->
|
||||
<filter id="bevel" x="-10%" y="-10%" width="120%" height="120%">
|
||||
<feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur"/>
|
||||
<feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>
|
||||
<feSpecularLighting in="blur" surfaceScale="5" specularConstant="1" specularExponent="20" lighting-color="#ffffff" result="specOut">
|
||||
<fePointLight x="-5000" y="-10000" z="20000"/>
|
||||
</feSpecularLighting>
|
||||
<feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut2"/>
|
||||
<feComposite in="SourceGraphic" in2="specOut2" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="litPaint"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="offsetBlur"/>
|
||||
<feMergeNode in="litPaint"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<filter id="innerShadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/>
|
||||
<feOffset in="blur" dx="3" dy="3" result="offsetBlur"/>
|
||||
<feComposite in="offsetBlur" in2="SourceAlpha" operator="in" result="innerShadow"/>
|
||||
<feComposite in="SourceGraphic" in2="innerShadow" operator="over"/>
|
||||
</filter>
|
||||
|
||||
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"/>
|
||||
<feComposite in="blur" in2="SourceGraphic" operator="over"/>
|
||||
</filter>
|
||||
|
||||
<filter id="neonGlow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"/>
|
||||
<feComposite in="blur" in2="SourceGraphic" operator="over"/>
|
||||
</filter>
|
||||
|
||||
<filter id="neonGlowBright" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur"/>
|
||||
<feComposite in="blur" in2="SourceGraphic" operator="over"/>
|
||||
</filter>
|
||||
|
||||
<filter id="pegGlow" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="2" result="blur"/>
|
||||
<feComposite in="blur" in2="SourceGraphic" operator="over"/>
|
||||
</filter>
|
||||
|
||||
<filter id="textShadow" x="-10%" y="-10%" width="120%" height="120%">
|
||||
<feDropShadow dx="1" dy="1" stdDeviation="1" flood-color="#000000" flood-opacity="0.7"/>
|
||||
</filter>
|
||||
|
||||
<filter id="innerGlow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur"/>
|
||||
<feComposite in="blur" in2="SourceGraphic" operator="atop"/>
|
||||
</filter>
|
||||
|
||||
<filter id="buttonGlow" x="-30%" y="-30%" width="160%" height="160%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"/>
|
||||
<feComposite in="blur" in2="SourceGraphic" operator="over"/>
|
||||
</filter>
|
||||
|
||||
<filter id="chromeEffect" x="-30%" y="-30%" width="160%" height="160%">
|
||||
<feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur"/>
|
||||
<feSpecularLighting in="blur" surfaceScale="5" specularConstant="1" specularExponent="20" lighting-color="#ffffff" result="specOut">
|
||||
<fePointLight x="-5000" y="-10000" z="20000"/>
|
||||
</feSpecularLighting>
|
||||
<feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut2"/>
|
||||
<feComposite in="SourceGraphic" in2="specOut2" operator="arithmetic" k1="0" k2="1" k3="1" k4="0"/>
|
||||
</filter>
|
||||
|
||||
<filter id="pointerShadow" x="-30%" y="-30%" width="160%" height="160%">
|
||||
<feDropShadow dx="2" dy="4" stdDeviation="3" flood-color="#000000" flood-opacity="0.5"/>
|
||||
</filter>
|
||||
</svg>
|
||||
|
||||
<!-- Wheel Pointer (Arrow) -->
|
||||
<div class="wheel-pointer">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 100">
|
||||
<!-- Base/Mount -->
|
||||
<rect x="15" y="0" width="50" height="15" rx="5" ry="5" fill="url(#pointerGradient)" filter="url(#bevel)" />
|
||||
|
||||
<!-- Arrow body -->
|
||||
<path d="M25,10 L25,50 L15,50 L40,85 L65,50 L55,50 L55,10 Z"
|
||||
fill="url(#pointerGradient)"
|
||||
stroke="#505050"
|
||||
stroke-width="2"
|
||||
filter="url(#pointerShadow)" />
|
||||
|
||||
<!-- Highlight on arrow (3D effect) -->
|
||||
<path d="M30,15 L30,45 L20,45 L40,75 L60,45 L50,45 L50,15 Z"
|
||||
fill="url(#pointerShineGradient)"
|
||||
opacity="0.3" />
|
||||
|
||||
<!-- Center bolt -->
|
||||
<circle cx="40" cy="25" r="5" fill="url(#chromeGradient)" filter="url(#chromeEffect)" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="wheel-wrapper">
|
||||
<?php
|
||||
if (!empty($prizes)) {
|
||||
echo $wheel->generate_wheel_svg($prizes);
|
||||
} else {
|
||||
echo '<div class="wheel-error">' . esc_html__('Error loading the wheel. No prizes available.', 'wheel-of-fortune') . '</div>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="wheel-spins-counter">
|
||||
<?php echo esc_html__('Remaining spins:', 'wheel-of-fortune'); ?> <span><?php echo esc_html($spins); ?></span>
|
||||
</div>
|
||||
|
||||
<button class="wheel-button" <?php echo ($spins <= 0) ? 'disabled' : ''; ?>>
|
||||
<?php echo esc_html__('SPIN', 'wheel-of-fortune'); ?>
|
||||
</button>
|
||||
|
||||
<div class="wheel-result"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
// Additional initialization for this specific wheel
|
||||
jQuery(document).ready(function($) {
|
||||
if (typeof wheel_params !== 'undefined') {
|
||||
console.log('Wheel of Fortune initialized: <?php echo esc_js($wheel_id_html); ?>');
|
||||
} else {
|
||||
console.error('Wheel of Fortune: wheel_params is not defined. Check if the plugin is properly loaded.');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue