Compare commits
1 Commits
master
...
email-temp
| Author | SHA1 | Date |
|---|---|---|
|
|
e11fa6fa5b |
|
|
@ -0,0 +1,87 @@
|
|||
name: Deploy to Production Server
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set SSH key permissions
|
||||
shell: bash
|
||||
run: |
|
||||
# Izpis trenutne delovne mape in seznama datotek
|
||||
pwd
|
||||
ls -la
|
||||
|
||||
# Uporabimo SSH ključ iz skrivnosti
|
||||
mkdir -p ~/.ssh
|
||||
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa_gitea
|
||||
chmod 600 ~/.ssh/id_rsa_gitea
|
||||
echo "SSH ključ ustvarjen iz skrivnosti"
|
||||
|
||||
- name: Install rsync
|
||||
shell: bash
|
||||
continue-on-error: true
|
||||
run: |
|
||||
# Najprej preverimo, ali je rsync že nameščen
|
||||
if command -v rsync &> /dev/null; then
|
||||
echo "rsync je že nameščen, verzija:"
|
||||
rsync --version | head -n 1
|
||||
else
|
||||
# Če rsync ni nameščen, ga poskušamo namestiti
|
||||
echo "rsync ni nameščen, poskušam namestiti..."
|
||||
if command -v apt-get &> /dev/null; then
|
||||
echo "Poskušam namestiti rsync z apt-get..."
|
||||
sudo apt-get update && sudo apt-get install -y rsync || echo "Ni mogoče namestiti rsync z apt-get"
|
||||
elif command -v yum &> /dev/null; then
|
||||
echo "Poskušam namestiti rsync z yum..."
|
||||
sudo yum install -y rsync || echo "Ni mogoče namestiti rsync z yum"
|
||||
else
|
||||
echo "Ni mogoče namestiti rsync - manjka paketni upravljalnik"
|
||||
fi
|
||||
|
||||
# Ponovno preverimo, ali je namestitev uspela
|
||||
if command -v rsync &> /dev/null; then
|
||||
echo "rsync je uspešno nameščen, verzija:"
|
||||
rsync --version | head -n 1
|
||||
else
|
||||
echo "rsync ni uspešno nameščen, uporabili bomo tar"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Vedno vrnemo uspešno kodo za izhod, da korak ne bo označen kot neuspešen
|
||||
exit 0
|
||||
|
||||
- name: Deploy to production server
|
||||
shell: bash
|
||||
run: |
|
||||
SSH_KEY="~/.ssh/id_rsa_gitea"
|
||||
|
||||
echo "Uporabljam SSH ključ: $SSH_KEY"
|
||||
|
||||
# Testiranje SSH povezave
|
||||
ssh -p 5050 -i "$SSH_KEY" -o StrictHostKeyChecking=no forexana@152.89.234.215 "echo 'SSH povezava uspešna'"
|
||||
|
||||
# Izbrišemo obstoječo vsebino v mapi vtičnika v produkcijskem okolju
|
||||
ssh -p 5050 -i "$SSH_KEY" -o StrictHostKeyChecking=no forexana@152.89.234.215 "rm -rf public_html/wp-content/plugins/custom_wheel\ 2/*"
|
||||
|
||||
# Poskusimo najprej z rsync, če je nameščen
|
||||
if command -v rsync &> /dev/null; then
|
||||
echo "Prenašanje datotek z rsync..."
|
||||
rsync -avz -e "ssh -p 5050 -i $SSH_KEY -o StrictHostKeyChecking=no" --exclude=".git" --exclude=".gitea" --exclude="id_rsa_gitea*" ./ forexana@152.89.234.215:public_html/wp-content/plugins/custom_wheel\ 2/
|
||||
else
|
||||
# Alternativna metoda prenosa z uporabo tar preko SSH
|
||||
echo "Prenašanje datotek s tar preko SSH..."
|
||||
tar czf - --exclude=".git" --exclude=".gitea" --exclude="id_rsa_gitea*" ./ | ssh -p 5050 -i "$SSH_KEY" -o StrictHostKeyChecking=no forexana@152.89.234.215 "tar xzf - -C public_html/wp-content/plugins/custom_wheel\ 2/"
|
||||
fi
|
||||
|
||||
# Nastavimo pravilna dovoljenja
|
||||
ssh -p 5050 -i "$SSH_KEY" -o StrictHostKeyChecking=no forexana@152.89.234.215 "chmod -R 755 public_html/wp-content/plugins/custom_wheel\ 2/"
|
||||
|
||||
echo "Production deployment completed successfully!"
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
name: Deploy to Test Server
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set SSH key permissions
|
||||
shell: bash
|
||||
run: |
|
||||
# Izpis trenutne delovne mape in seznama datotek
|
||||
pwd
|
||||
ls -la
|
||||
ls -la .gitea/runner/ || echo "Mapa runner ne obstaja"
|
||||
|
||||
# Poskusimo najti SSH ključ
|
||||
find . -name "id_rsa_gitea*" -type f
|
||||
|
||||
# Uporabimo SSH ključ v bazi repozitorija
|
||||
if [ -f ".gitea/runner/id_rsa_gitea" ]; then
|
||||
chmod 600 .gitea/runner/id_rsa_gitea
|
||||
echo "SSH ključ najden in nastavljen"
|
||||
else
|
||||
echo "SSH ključ ni bil najden na pričakovani lokaciji!"
|
||||
# Ustvarimo SSH ključ iz kodiranega besedila
|
||||
mkdir -p ~/.ssh
|
||||
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa_gitea
|
||||
chmod 600 ~/.ssh/id_rsa_gitea
|
||||
echo "SSH ključ ustvarjen iz skrivnosti"
|
||||
fi
|
||||
|
||||
- name: Install rsync
|
||||
shell: bash
|
||||
continue-on-error: true
|
||||
run: |
|
||||
# Najprej preverimo, ali je rsync že nameščen
|
||||
if command -v rsync &> /dev/null; then
|
||||
echo "rsync je že nameščen, verzija:"
|
||||
rsync --version | head -n 1
|
||||
else
|
||||
# Če rsync ni nameščen, ga poskušamo namestiti
|
||||
echo "rsync ni nameščen, poskušam namestiti..."
|
||||
if command -v apt-get &> /dev/null; then
|
||||
echo "Poskušam namestiti rsync z apt-get..."
|
||||
sudo apt-get update && sudo apt-get install -y rsync || echo "Ni mogoče namestiti rsync z apt-get"
|
||||
elif command -v yum &> /dev/null; then
|
||||
echo "Poskušam namestiti rsync z yum..."
|
||||
sudo yum install -y rsync || echo "Ni mogoče namestiti rsync z yum"
|
||||
else
|
||||
echo "Ni mogoče namestiti rsync - manjka paketni upravljalnik"
|
||||
fi
|
||||
|
||||
# Ponovno preverimo, ali je namestitev uspela
|
||||
if command -v rsync &> /dev/null; then
|
||||
echo "rsync je uspešno nameščen, verzija:"
|
||||
rsync --version | head -n 1
|
||||
else
|
||||
echo "rsync ni uspešno nameščen, uporabili bomo tar"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Vedno vrnemo uspešno kodo za izhod, da korak ne bo označen kot neuspešen
|
||||
exit 0
|
||||
|
||||
- name: Deploy to test server
|
||||
shell: bash
|
||||
run: |
|
||||
# Najprej preverimo SSH povezavo
|
||||
if [ -f ".gitea/runner/id_rsa_gitea" ]; then
|
||||
SSH_KEY=".gitea/runner/id_rsa_gitea"
|
||||
else
|
||||
SSH_KEY="~/.ssh/id_rsa_gitea"
|
||||
fi
|
||||
|
||||
echo "Uporabljam SSH ključ: $SSH_KEY"
|
||||
|
||||
# Testiranje SSH povezave
|
||||
ssh -p 5050 -i "$SSH_KEY" -o StrictHostKeyChecking=no forexana@152.89.234.215 "echo 'SSH povezava uspešna'"
|
||||
|
||||
# Izbrišemo obstoječo vsebino v mapi vtičnika
|
||||
ssh -p 5050 -i "$SSH_KEY" -o StrictHostKeyChecking=no forexana@152.89.234.215 "rm -rf test.forexanalysis.com/wp-content/plugins/custom_wheel\ 2/*"
|
||||
|
||||
# Poskusimo najprej z rsync, če je nameščen
|
||||
if command -v rsync &> /dev/null; then
|
||||
echo "Prenašanje datotek z rsync..."
|
||||
rsync -avz -e "ssh -p 5050 -i $SSH_KEY -o StrictHostKeyChecking=no" --exclude=".git" --exclude=".gitea" --exclude="id_rsa_gitea*" ./ forexana@152.89.234.215:test.forexanalysis.com/wp-content/plugins/custom_wheel\ 2/
|
||||
else
|
||||
# Alternativna metoda prenosa z uporabo tar preko SSH
|
||||
echo "Prenašanje datotek s tar preko SSH..."
|
||||
tar czf - --exclude=".git" --exclude=".gitea" --exclude="id_rsa_gitea*" ./ | ssh -p 5050 -i "$SSH_KEY" -o StrictHostKeyChecking=no forexana@152.89.234.215 "tar xzf - -C test.forexanalysis.com/wp-content/plugins/custom_wheel\ 2/"
|
||||
fi
|
||||
|
||||
# Nastavimo pravilna dovoljenja
|
||||
ssh -p 5050 -i "$SSH_KEY" -o StrictHostKeyChecking=no forexana@152.89.234.215 "chmod -R 755 test.forexanalysis.com/wp-content/plugins/custom_wheel\ 2/"
|
||||
|
||||
echo "Deployment completed successfully!"
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
name: Deploy to Development and Production
|
||||
|
||||
# 1. EN trigger, ki se sproži ob potisku na OBE veji
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- master
|
||||
|
||||
# 2. EN jobs blok
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# Ta korak se vedno izvede
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Preveri, ali je rsync nameščen, sicer ga namesti
|
||||
- name: Ensure rsync is installed
|
||||
run: |
|
||||
if ! command -v rsync >/dev/null; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y rsync
|
||||
fi
|
||||
|
||||
# Ta korak se vedno izvede - priprava SSH ključa
|
||||
- name: Setup SSH
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
|
||||
# 3. KORAK ZA DEVELOP: Izvede se samo, če je veja 'develop'
|
||||
- name: Deploy to Development Server
|
||||
if: gitea.ref_name == 'develop'
|
||||
run: |
|
||||
echo "🚀 Deploying to Development..."
|
||||
rsync -avz --delete \
|
||||
--exclude=".git/" \
|
||||
--exclude=".gitea/" \
|
||||
--exclude=".gitignore" \
|
||||
-e "ssh -p ${{ secrets.SSH_PORT }} -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no" \
|
||||
./ \
|
||||
${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.TARGET_DIR }}
|
||||
|
||||
# 4. KORAK ZA MASTER: Izvede se samo, če je veja 'master'
|
||||
- name: Deploy to Production Server
|
||||
if: gitea.ref_name == 'master'
|
||||
run: |
|
||||
echo "🚀 Deploying to Production..."
|
||||
rsync -avz --delete \
|
||||
--exclude=".git/" \
|
||||
--exclude=".gitea/" \
|
||||
--exclude=".gitignore" \
|
||||
-e "ssh -p ${{ secrets.SSH_PORT }} -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no" \
|
||||
./ \
|
||||
${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.TARGET_MASTER_DIR }}
|
||||
|
|
@ -41,5 +41,4 @@ vendor/
|
|||
*.tar
|
||||
*.bak
|
||||
*.swp
|
||||
*.tmp
|
||||
code_export.txt
|
||||
*.tmp
|
||||
856
README.md
856
README.md
|
|
@ -1,154 +1,748 @@
|
|||
# Wheel of Fortune za WooCommerce (Kolo Sreče)
|
||||
# Wheel of Fortune Plugin
|
||||
|
||||
**Wheel of Fortune** je napreden WordPress/WooCommerce vtičnik, ki omogoča gamifikacijo spletne trgovine. Kupcem omogoča, da z nakupom določenih izdelkov pridobijo "vrtljaje" (spins) in zavrtijo kolo sreče za priboritev nagrad (popusti, kuponi, fizična darila ali sporočila).
|
||||
Test posodobitve za preverjanje Gitea workflow.
|
||||
|
||||
Vtičnik podpira več različnih koles, napredno upravljanje verjetnosti, samodejno ustvarjanje WooCommerce kuponov, pošiljanje e-poštnih obvestil (SMTP) in dnevne nagrade (Cron job).
|
||||
# Wheel of Fortune - WordPress Plugin
|
||||
|
||||
## 🚀 Glavne funkcionalnosti
|
||||
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.
|
||||
|
||||
* **Več koles:** Ustvarite lahko neomejeno število različnih koles za različne priložnosti.
|
||||
* **Povezava z WooCommerce:** Določite, kateri izdelki prinašajo vrtljaje in koliko.
|
||||
* **Napredne nagrade:**
|
||||
* Avtomatsko ustvarjanje kuponov za popuste (odstotni popust).
|
||||
* Fizične nagrade.
|
||||
* "Poskusi znova" (Try Again) polja.
|
||||
* Nastavljanje verjetnosti dobitka (uteženo).
|
||||
* **Uporabniški račun:** Beleženje zgodovine vrtljajev in preostalih vrtljajev za vsakega uporabnika.
|
||||
* **Dnevni vrtljaji:** Možnost nastavitve, da vsak uporabnik prejme 1 brezplačen vrtljaj vsakih 24 ur.
|
||||
* **E-poštna obvestila:** Integriran SMTP klient za zanesljivo pošiljanje obvestil o nagradah.
|
||||
* **Diagnostika:** Orodje za testiranje generiranja kuponov in pošiljanja e-pošte.
|
||||
## 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
|
||||
|
||||
## 📂 Struktura map in datotek
|
||||
## Namestitev
|
||||
|
||||
Spodaj je podroben opis vseh datotek v projektu in njihov namen.
|
||||
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
|
||||
|
||||
### root (koren mape)
|
||||
* **`wheel-of-fortune.php`**:
|
||||
* Glavna datoteka vtičnika.
|
||||
* Inicializira vtičnik, registrira 'hooks' (akcije in filtre).
|
||||
* Ustvari in posodablja podatkovne baze (`dbDelta`).
|
||||
* Registrira REST API endpoint (`/wp-json/wheel-of-fortune/v1/spin`) za varno izvedbo vrtljaja.
|
||||
* Obravnava logiko dodeljevanja spinov ob zaključku WooCommerce naročila (`woocommerce_order_status_completed`).
|
||||
* Vsebuje logiko za pošiljanje e-pošte in generiranje SVG kolesa.
|
||||
## Uporaba
|
||||
|
||||
### `/admin` (Administracija)
|
||||
Vsebuje logiko za backend vmesnik v WP Adminu.
|
||||
### Osnovna uporaba
|
||||
|
||||
* **`coupon-test.php`**:
|
||||
* Diagnostično orodje. Preizkusi 4 različne metode ustvarjanja WooCommerce kuponov (API, programsko, DB insert), da najde tisto, ki deluje na strežniku, in jo shrani kot privzeto.
|
||||
* **`wheels-page.php`**:
|
||||
* Prikazuje seznam vseh ustvarjenih koles.
|
||||
* Omogoča dodajanje novih koles in brisanje obstoječih.
|
||||
* **`edit-wheel-page.php`**:
|
||||
* Glavni urejevalnik za posamezno kolo.
|
||||
* Upravljanje nagrad (CRUD): dodajanje, urejanje, verjetnosti, barve, template e-pošte.
|
||||
* Povezovanje WooCommerce izdelkov s tem kolesom (koliko spinov prinese izdelek).
|
||||
* **`settings-page.php`**:
|
||||
* Globalne nastavitve: SMTP podatki, Cron nastavitve za dnevne spine, "cooldown" čas.
|
||||
* Vsebuje orodja za ročno dodajanje spinov in testiranje e-pošte.
|
||||
* **`stats-page.php`**:
|
||||
* Analitika: Kdo je vrtel, kaj je zadel, kdaj.
|
||||
* Filtriranje uporabnikov glede na preostale spine.
|
||||
* **`users-page.php`**:
|
||||
* Pregled uporabnikov in njihovih spinov.
|
||||
* Možnost ročnega resetiranja ali dodajanja spinov specifičnemu uporabniku.
|
||||
* **`partials/prize-form-fields.php`**:
|
||||
* HTML delček (partial) za obrazec nagrade, ki se uporablja pri dodajanju in urejanju, da se koda ne podvaja.
|
||||
* **`js/admin.js`**:
|
||||
* jQuery skripte za admin vmesnik (odpiranje modalov, AJAX klici za shranjevanje nagrad, testiranje e-pošte).
|
||||
* **`js/wheel.js`** (Admin preview):
|
||||
* Skripta za animacijo kolesa v predogledu v administraciji.
|
||||
Vstavite kratko kodo `[wheel_of_fortune]` na katerokoli stran ali prispevek, kjer želite prikazati kolo sreče.
|
||||
|
||||
### `/assets` (Sredstva)
|
||||
Datoteke, ki se nalagajo na frontend-u (in delno v adminu za stilizacijo).
|
||||
### Parametri kratke kode
|
||||
|
||||
* **`css/admin.css`**:
|
||||
* Stili za WP Admin (kartice, tabele, gumbi, postavitev urejevalnika).
|
||||
* **`css/wheel.css`**:
|
||||
* CSS za izgled kolesa na spletni strani.
|
||||
* Vsebuje animacije (utripanje lučk), senčenje (SVG filtri) in odzivnost (responsive design) za mobilne naprave.
|
||||
* **`js/wheel.js`**:
|
||||
* **Glavna frontend logika.**
|
||||
* Komunicira z REST API-jem za pridobitev rezultata vrtljaja (rezultat se določi na strežniku, ne v brskalniku zaradi varnosti).
|
||||
* Izvaja animacijo vrtenja (easing functions) in prikaže "popup" z rezultatom.
|
||||
Kratka koda sprejme naslednje parametre:
|
||||
|
||||
### `/languages`
|
||||
* **`wheel-of-fortune.pot`**:
|
||||
* Predloga za prevajanje vtičnika v druge jezike (npr. v slovenščino).
|
||||
- `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)
|
||||
|
||||
### `/public`
|
||||
* **`shortcode-template.php`**:
|
||||
* HTML predloga, ki se izpiše, ko na stran vstavite `[wheel_of_fortune]`. Vsebuje kontejner za SVG kolo in gumb za vrtenje.
|
||||
#### Primeri
|
||||
|
||||
### `/templates`
|
||||
* **`wheel.php`**:
|
||||
* Alternativna ali starejša PHP predloga za generiranje SVG strukture (gradienti, filtri).
|
||||
* **`emails/default-prize-email.html`**:
|
||||
* HTML predloga za e-poštno sporočilo, ki ga prejme uporabnik ob zadetku. Vsebuje "placeholders" kot so `{user_name}`, `{prize_name}`, itd.
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ Podatkovna baza
|
||||
|
||||
Vtičnik ustvari naslednje tabele v bazi:
|
||||
1. `wp_wof_wheels`: Seznam koles.
|
||||
2. `wp_wheel_prizes`: Nagrade povezane s kolesi (verjetnost, tip nagrade).
|
||||
3. `wp_wheel_spins`: Stanje spinov za vsakega uporabnika (ločeno po kolesih).
|
||||
4. `wp_wheel_log`: Zgodovina vseh vrtljajev (log).
|
||||
5. `wp_wheel_of_fortune_products`: Povezovalna tabela med WC izdelki in kolesi.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Navodila za uporabo
|
||||
|
||||
### 1. Namestitev in Aktivacija
|
||||
1. Naložite mapo `wheel-of-fortune` v mapo `wp-content/plugins/` ali namestite preko ZIP datoteke v WP Adminu.
|
||||
2. Aktivirajte vtičnik. Ob aktivaciji se bodo ustvarile potrebne tabele.
|
||||
|
||||
### 2. Ustvarjanje Kolesa
|
||||
1. Pojdite na **Wheels of Fortune > Wheels**.
|
||||
2. Vnesite ime kolesa in kliknite "Add New Wheel".
|
||||
3. Kliknite na ime kolesa ali "Edit" za urejanje.
|
||||
|
||||
### 3. Dodajanje Nagrad (Prizes)
|
||||
V urejevalniku kolesa:
|
||||
1. Kliknite "Add New Prize".
|
||||
2. Izpolnite podatke:
|
||||
* **Probability:** Verjetnost med 0 in 1 (npr. 0.1 je 10%). *Pomembno: Vsota vseh verjetnosti naj bo 1.*
|
||||
* **Is Discount?:** Če označite, vpišite odstotek. Sistem bo avtomatsko generiral unikatno kodo kupona.
|
||||
* **Is Try Again?:** Če uporabnik ne zadene ničesar, a lahko vrti ponovno.
|
||||
3. Shranite nagrado.
|
||||
|
||||
### 4. Povezava z Izdelki (Kako do spinov?)
|
||||
Na isti strani urejanja kolesa (spodaj):
|
||||
1. V sekciji "Produkti & spini" izberite WooCommerce izdelek.
|
||||
2. Določite "Število spinov na nakup" (npr. 1).
|
||||
3. Kliknite "Dodaj". Ko kupec kupi ta izdelek (status naročila: Completed/Processing), bo prejel spine.
|
||||
|
||||
### 5. Prikaz na spletni strani
|
||||
Na katerokoli stran ali prispevek dodajte shortcode:
|
||||
```
|
||||
[wheel_of_fortune id="1"]
|
||||
[wheel_of_fortune]
|
||||
[wheel_of_fortune size="large" theme="dark"]
|
||||
[wheel_of_fortune size="medium" theme="light" scale="scale-80"]
|
||||
```
|
||||
*Zamenjajte `1` z ID-jem vašega kolesa.*
|
||||
|
||||
### 6. Nastavitve SMTP in Dnevni Spin
|
||||
Pojdite na **Wheels of Fortune > Settings**:
|
||||
* **SMTP:** Vnesite podatke vašega mail strežnika za zanesljivo dostavo nagrad.
|
||||
* **Daily Spin:** Izberite kolo, ki se uporablja za dnevne nagrade. Uporabniki bodo avtomatsko prejeli 1 spin vsakih 24h za to kolo.
|
||||
* **Coupon Test:** Če se kuponi ne generirajo, zaženite "Testiraj ustvarjanje kuponov" in shranite delujočo metodo.
|
||||
## 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
|
||||
|
||||
## ⚠️ Pomembna opozorila
|
||||
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.
|
||||
|
||||
* **DEBUG mode:** V datoteki `wheel-of-fortune.php` je konstanta `WHEEL_OF_FORTUNE_DEBUG` nastavljena na `true`. Za produkcijo jo nastavite na `false`, da ne polnite `debug.log` datoteke.
|
||||
* **Varnost:** Vtičnik uporablja "Nonce" preverjanje za vse AJAX in REST klice, zato je varen pred CSRF napadi.
|
||||
* **Login:** Kolo se prikaže samo prijavljenim uporabnikom. Neprijavljeni vidijo obvestilo za prijavo.
|
||||
## 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.
|
||||
|
||||
**Avtor:** Mark Poljansek
|
||||
**Verzija:** 1.0.1
|
||||
## 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,569 @@
|
|||
<?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']) : '';
|
||||
|
||||
// Dodaj nova polja
|
||||
$email_template_id = isset($_POST['email_template_id']) ? intval($_POST['email_template_id']) : 0;
|
||||
$funded_account_name = isset($_POST['funded_account_name']) ? sanitize_text_field($_POST['funded_account_name']) : null;
|
||||
$funded_account_value = isset($_POST['funded_account_value']) ? floatval($_POST['funded_account_value']) : null;
|
||||
|
||||
if (!empty($name) && $wheel_id > 0) {
|
||||
$result = $wpdb->insert(
|
||||
$prizes_table,
|
||||
[
|
||||
'wheel_id' => $wheel_id,
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'probability' => $probability,
|
||||
'is_active' => $is_active,
|
||||
'redemption_code' => $redemption_code,
|
||||
'is_discount' => $is_discount,
|
||||
'discount_value' => $discount_value,
|
||||
'email_subject' => $email_subject,
|
||||
'email_template' => $email_template,
|
||||
|
||||
// Dodaj nova polja
|
||||
'email_template_id' => $email_template_id,
|
||||
'funded_account_name' => $funded_account_name,
|
||||
'funded_account_value' => $funded_account_value
|
||||
],
|
||||
['%d', '%s', '%s', '%f', '%d', '%s', '%d', '%f', '%s', '%s', '%d', '%s', '%f']
|
||||
);
|
||||
|
||||
if ($result !== false) {
|
||||
echo '<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']) : '';
|
||||
|
||||
// Dodaj nova polja
|
||||
$email_template_id = isset($_POST['email_template_id']) ? intval($_POST['email_template_id']) : 0;
|
||||
$funded_account_name = isset($_POST['funded_account_name']) ? sanitize_text_field($_POST['funded_account_name']) : null;
|
||||
$funded_account_value = isset($_POST['funded_account_value']) ? floatval($_POST['funded_account_value']) : null;
|
||||
|
||||
if (!empty($name) && $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,
|
||||
|
||||
// Dodaj nova polja
|
||||
'email_template_id' => $email_template_id,
|
||||
'funded_account_name' => $funded_account_name,
|
||||
'funded_account_value' => $funded_account_value
|
||||
],
|
||||
['id' => $prize_id],
|
||||
['%d', '%s', '%s', '%f', '%d', '%s', '%d', '%f', '%s', '%s', '%d', '%s', '%f'],
|
||||
['%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>
|
||||
|
||||
<!-- DODAJ NOVA POLJA ZA FUNDED ACCOUNT -->
|
||||
<tr><th scope="row"><label for="edit-funded-account-name"><?php _e('Funded Account Name', 'wheel-of-fortune'); ?></label></th><td><input type="text" id="edit-funded-account-name" name="funded_account_name" class="regular-text"><p class="description"><?php _e('e.g., Funded7 $50k. Used for the {funded_account_name} tag.', 'wheel-of-fortune'); ?></p></td></tr>
|
||||
<tr><th scope="row"><label for="edit-funded-account-value"><?php _e('Funded Account Value', 'wheel-of-fortune'); ?></label></th><td><input type="number" id="edit-funded-account-value" name="funded_account_value" step="any" min="0"><p class="description"><?php _e('e.g., 50000. Used for the {funded_account_value} tag.', 'wheel-of-fortune'); ?></p></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>
|
||||
|
||||
<!-- SPREMENI SEKCIJO ZA EMAIL -->
|
||||
<tr>
|
||||
<th scope="row"><label for="edit-prize-email-template-id"><?php _e('Email Content', 'wheel-of-fortune'); ?></label></th>
|
||||
<td>
|
||||
<select id="edit-prize-email-template-id" name="email_template_id">
|
||||
<option value="0"><?php _e('-- Custom Email --', 'wheel-of-fortune'); ?></option>
|
||||
<?php
|
||||
global $wpdb;
|
||||
$email_templates = $wpdb->get_results("SELECT id, name FROM {$wpdb->prefix}wheel_email_templates ORDER BY name ASC", ARRAY_A);
|
||||
foreach ($email_templates as $template) : ?>
|
||||
<option value="<?php echo esc_attr($template['id']); ?>"><?php echo esc_html($template['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<p class="description"><?php _e('Choose a pre-written template or select "Custom Email" to write your own below.', 'wheel-of-fortune'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="custom-email-fields-edit"><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. Only used if "Custom Email" is selected.', 'wheel-of-fortune'); ?></p></td></tr>
|
||||
<tr class="custom-email-fields-edit"><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>, <code>{prize_description}</code>, <code>{redemption_code}</code>, <code>{site_name}</code>, <code>{site_url}</code>, <code>{date}</code>, <code>{time}</code>, <strong><code>{funded_account_name}</code></strong>, <strong><code>{funded_account_value}</code></strong></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>
|
||||
</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>
|
||||
|
||||
// Funkcija za prikaz/skrivanje polj za e-pošto po meri
|
||||
function handleEmailSourceChange() {
|
||||
// Za formo za dodajanje
|
||||
if ($('#prize_email_template_id').val() == '0') {
|
||||
$('.custom-email-fields').show();
|
||||
} else {
|
||||
$('.custom-email-fields').hide();
|
||||
}
|
||||
|
||||
// Za modalno okno za urejanje
|
||||
if ($('#edit-prize-email-template-id').val() == '0') {
|
||||
$('.custom-email-fields-edit').show();
|
||||
} else {
|
||||
$('.custom-email-fields-edit').hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Poveži event handler
|
||||
$('body').on('change', '#prize_email_template_id, #edit-prize-email-template-id', handleEmailSourceChange);
|
||||
|
||||
// Sproži ob nalaganju strani za formo za dodajanje
|
||||
handleEmailSourceChange();
|
||||
|
||||
$('.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);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Modalno okno za urejanje nagrad
|
||||
var modal = $('#edit-prize-modal');
|
||||
var closeBtn = modal.find('.close');
|
||||
|
||||
$('.add-new-prize').on('click', function() {
|
||||
$('html, body').animate({
|
||||
scrollTop: $('.wheel-card:contains("Add New Prize")').offset().top
|
||||
}, 500);
|
||||
});
|
||||
|
||||
closeBtn.on('click', function() {
|
||||
modal.hide();
|
||||
});
|
||||
|
||||
$(window).on('click', function(e) {
|
||||
if (e.target === modal[0]) {
|
||||
modal.hide();
|
||||
}
|
||||
});
|
||||
|
||||
$('.edit-prize').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var prizeId = $(this).data('id');
|
||||
|
||||
// AJAX klic za pridobitev podatkov o nagradi
|
||||
$.post(ajaxurl, {
|
||||
action: 'wheel_get_prize_details',
|
||||
prize_id: prizeId,
|
||||
_ajax_nonce: '<?php echo wp_create_nonce('wheel_admin_nonce'); ?>'
|
||||
}, function(response) {
|
||||
if (response.success) {
|
||||
var prize = response.data;
|
||||
|
||||
// Napolni obrazec
|
||||
$('#edit-prize-id').val(prize.id);
|
||||
$('#edit-wheel-id').val(prize.wheel_id);
|
||||
$('#edit-prize-name').val(prize.name);
|
||||
$('#edit-prize-description').val(prize.description);
|
||||
$('#edit-prize-probability').val(prize.probability);
|
||||
$('#edit-prize-is-active').prop('checked', prize.is_active == 1);
|
||||
$('#edit-prize-redemption-code').val(prize.redemption_code);
|
||||
$('#edit-prize-is-discount').prop('checked', prize.is_discount == 1);
|
||||
$('#edit-prize-discount-value').val(prize.discount_value);
|
||||
$('#edit-prize-email-subject').val(prize.email_subject);
|
||||
$('#edit-prize-email-template').val(prize.email_template);
|
||||
|
||||
// Napolni nova polja
|
||||
$('#edit-funded-account-name').val(prize.funded_account_name);
|
||||
$('#edit-funded-account-value').val(prize.funded_account_value);
|
||||
$('#edit-prize-email-template-id').val(prize.email_template_id);
|
||||
|
||||
// Sproži spremembo, da se pravilno prikažejo/skrijejo polja
|
||||
$('#edit-prize-email-template-id').trigger('change');
|
||||
|
||||
modal.show();
|
||||
} else {
|
||||
alert(response.data.message || 'Napaka pri pridobivanju podatkov o nagradi.');
|
||||
}
|
||||
}).fail(function() {
|
||||
alert('Napaka pri komunikaciji s strežnikom.');
|
||||
});
|
||||
});
|
||||
|
||||
$('.delete-prize').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (!confirm('Ali res želiš izbrisati to nagrado?')) return;
|
||||
|
||||
var row = $(this).closest('tr');
|
||||
var prizeId = $(this).data('id');
|
||||
|
||||
$.post(ajaxurl, {
|
||||
action: 'wheel_delete_prize',
|
||||
prize_id: prizeId,
|
||||
_ajax_nonce: '<?php echo wp_create_nonce('wheel_admin_nonce'); ?>'
|
||||
}, function(response) {
|
||||
if (response.success) {
|
||||
row.fadeOut(300, function() { $(this).remove(); });
|
||||
} else {
|
||||
alert(response.data.message || 'Napaka pri brisanju nagrade.');
|
||||
}
|
||||
}).fail(function() {
|
||||
alert('Napaka pri komunikaciji s strežnikom.');
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -20,7 +20,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||
$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']) : '';
|
||||
$is_try_again = isset($_POST['prize_is_try_again']) ? 1 : 0;
|
||||
|
||||
// Dodaj nova polja
|
||||
$email_template_id = isset($_POST['email_template_id']) ? intval($_POST['email_template_id']) : 0;
|
||||
$funded_account_name = isset($_POST['funded_account_name']) ? sanitize_text_field($_POST['funded_account_name']) : null;
|
||||
$funded_account_value = isset($_POST['funded_account_value']) ? floatval($_POST['funded_account_value']) : null;
|
||||
|
||||
if (!empty($name) && $wheel_id > 0) {
|
||||
$result = $wpdb->insert(
|
||||
|
|
@ -36,9 +40,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||
'discount_value' => $discount_value,
|
||||
'email_subject' => $email_subject,
|
||||
'email_template' => $email_template,
|
||||
'is_try_again' => $is_try_again
|
||||
|
||||
// Dodaj nova polja
|
||||
'email_template_id' => $email_template_id,
|
||||
'funded_account_name' => $funded_account_name,
|
||||
'funded_account_value' => $funded_account_value
|
||||
],
|
||||
['%d', '%s', '%s', '%f', '%d', '%s', '%d', '%f', '%s', '%s', '%d']
|
||||
['%d', '%s', '%s', '%f', '%d', '%s', '%d', '%f', '%s', '%s', '%d', '%s', '%f']
|
||||
);
|
||||
|
||||
if ($result !== false) {
|
||||
|
|
@ -64,7 +72,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||
$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']) : '';
|
||||
$is_try_again = isset($_POST['prize_is_try_again']) ? 1 : 0;
|
||||
|
||||
// Dodaj nova polja
|
||||
$email_template_id = isset($_POST['email_template_id']) ? intval($_POST['email_template_id']) : 0;
|
||||
$funded_account_name = isset($_POST['funded_account_name']) ? sanitize_text_field($_POST['funded_account_name']) : null;
|
||||
$funded_account_value = isset($_POST['funded_account_value']) ? floatval($_POST['funded_account_value']) : null;
|
||||
|
||||
if (!empty($name) && $prize_id > 0 && $wheel_id > 0) {
|
||||
$result = $wpdb->update(
|
||||
|
|
@ -80,10 +92,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||
'discount_value' => $discount_value,
|
||||
'email_subject' => $email_subject,
|
||||
'email_template' => $email_template,
|
||||
'is_try_again' => $is_try_again
|
||||
|
||||
// Dodaj nova polja
|
||||
'email_template_id' => $email_template_id,
|
||||
'funded_account_name' => $funded_account_name,
|
||||
'funded_account_value' => $funded_account_value
|
||||
],
|
||||
['id' => $prize_id],
|
||||
['%d', '%s', '%s', '%f', '%d', '%s', '%d', '%f', '%s', '%s', '%d'],
|
||||
['%d', '%s', '%s', '%f', '%d', '%s', '%d', '%f', '%s', '%s', '%d', '%s', '%f'],
|
||||
['%d']
|
||||
);
|
||||
|
||||
|
|
@ -235,17 +251,6 @@ if (class_exists('WooCommerce')) {
|
|||
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<!-- Gumb za migracijo is_try_again stolpca -->
|
||||
<div class="notice notice-info">
|
||||
<p><strong><?php _e('Database Migration', 'wheel-of-fortune'); ?>:</strong>
|
||||
<?php _e('If you encounter "Unknown column is_try_again" error, click the button below to add the missing column to the database.', 'wheel-of-fortune'); ?>
|
||||
<button id="migrate-try-again-btn" class="button button-secondary" style="margin-left: 10px;">
|
||||
<?php _e('Add is_try_again Column', 'wheel-of-fortune'); ?>
|
||||
</button>
|
||||
<span id="migrate-result" style="margin-left: 10px;"></span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="wheel-card">
|
||||
<h2><?php echo esc_html__('Prizes for this Wheel', 'wheel-of-fortune'); ?></h2>
|
||||
|
||||
|
|
@ -371,103 +376,37 @@ if (class_exists('WooCommerce')) {
|
|||
<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>
|
||||
|
||||
<!-- DODAJ NOVA POLJA ZA FUNDED ACCOUNT -->
|
||||
<tr><th scope="row"><label for="edit-funded-account-name"><?php _e('Funded Account Name', 'wheel-of-fortune'); ?></label></th><td><input type="text" id="edit-funded-account-name" name="funded_account_name" class="regular-text"><p class="description"><?php _e('e.g., Funded7 $50k. Used for the {funded_account_name} tag.', 'wheel-of-fortune'); ?></p></td></tr>
|
||||
<tr><th scope="row"><label for="edit-funded-account-value"><?php _e('Funded Account Value', 'wheel-of-fortune'); ?></label></th><td><input type="number" id="edit-funded-account-value" name="funded_account_value" step="any" min="0"><p class="description"><?php _e('e.g., 50000. Used for the {funded_account_value} tag.', 'wheel-of-fortune'); ?></p></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>
|
||||
|
||||
<!-- SPREMENI SEKCIJO ZA EMAIL -->
|
||||
<tr>
|
||||
<th scope="row"><label for="edit-prize-email-template-id"><?php _e('Email Content', 'wheel-of-fortune'); ?></label></th>
|
||||
<td>
|
||||
<select id="edit-prize-email-template-id" name="email_template_id">
|
||||
<option value="0"><?php _e('-- Custom Email --', 'wheel-of-fortune'); ?></option>
|
||||
<?php
|
||||
global $wpdb;
|
||||
$email_templates = $wpdb->get_results("SELECT id, name FROM {$wpdb->prefix}wheel_email_templates ORDER BY name ASC", ARRAY_A);
|
||||
foreach ($email_templates as $template) : ?>
|
||||
<option value="<?php echo esc_attr($template['id']); ?>"><?php echo esc_html($template['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<p class="description"><?php _e('Choose a pre-written template or select "Custom Email" to write your own below.', 'wheel-of-fortune'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="custom-email-fields-edit"><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. Only used if "Custom Email" is selected.', 'wheel-of-fortune'); ?></p></td></tr>
|
||||
<tr class="custom-email-fields-edit"><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>, <code>{prize_description}</code>, <code>{redemption_code}</code>, <code>{site_name}</code>, <code>{site_url}</code>, <code>{date}</code>, <code>{time}</code>, <strong><code>{funded_account_name}</code></strong>, <strong><code>{funded_account_value}</code></strong></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-is-try-again"><?php _e('Is Try Again?', 'wheel-of-fortune'); ?></label></th><td><input type="checkbox" id="edit-prize-is-try-again" name="prize_is_try_again" value="1"><p class="description"><?php _e('Check if the prize is a try again.', '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>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
// Gumb za migracijo is_try_again stolpca
|
||||
$('#migrate-try-again-btn').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const button = $(this);
|
||||
const resultSpan = $('#migrate-result');
|
||||
|
||||
button.prop('disabled', true).text('<?php _e('Running migration...', 'wheel-of-fortune'); ?>');
|
||||
resultSpan.html('');
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'wheel_migrate_try_again',
|
||||
_ajax_nonce: '<?php echo wp_create_nonce('wheel_admin_nonce'); ?>'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
resultSpan.html('<span style="color: green;">✓ ' + response.data.message + '</span>');
|
||||
button.text('<?php _e('Migration Completed', 'wheel-of-fortune'); ?>').addClass('button-primary');
|
||||
} else {
|
||||
resultSpan.html('<span style="color: red;">✗ ' + (response.data.message || '<?php _e('Migration failed', 'wheel-of-fortune'); ?>') + '</span>');
|
||||
button.prop('disabled', false).text('<?php _e('Add is_try_again Column', 'wheel-of-fortune'); ?>');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
resultSpan.html('<span style="color: red;">✗ <?php _e('Network error occurred', 'wheel-of-fortune'); ?></span>');
|
||||
button.prop('disabled', false).text('<?php _e('Add is_try_again Column', 'wheel-of-fortune'); ?>');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
<?php
|
||||
/**
|
||||
* Admin page for managing email templates
|
||||
*/
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
// Handle form submissions
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||
if ($_POST['action'] === 'add_template' && check_admin_referer('wheel_email_templates_nonce')) {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'wheel_email_templates';
|
||||
|
||||
$name = isset($_POST['template_name']) ? sanitize_text_field($_POST['template_name']) : '';
|
||||
$subject = isset($_POST['template_subject']) ? sanitize_text_field($_POST['template_subject']) : '';
|
||||
$template_body = isset($_POST['template_body']) ? wp_kses_post($_POST['template_body']) : '';
|
||||
|
||||
if (!empty($name) && !empty($subject) && !empty($template_body)) {
|
||||
$result = $wpdb->insert(
|
||||
$table_name,
|
||||
[
|
||||
'name' => $name,
|
||||
'subject' => $subject,
|
||||
'template_body' => $template_body,
|
||||
],
|
||||
['%s', '%s', '%s']
|
||||
);
|
||||
|
||||
if ($result !== false) {
|
||||
echo '<div class="notice notice-success is-dismissible"><p>' . __('Email template added successfully!', 'wheel-of-fortune') . '</p></div>';
|
||||
} else {
|
||||
echo '<div class="notice notice-error is-dismissible"><p>' . __('Error adding email template. 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_template' && check_admin_referer('wheel_email_templates_nonce')) {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'wheel_email_templates';
|
||||
|
||||
$template_id = isset($_POST['template_id']) ? intval($_POST['template_id']) : 0;
|
||||
$name = isset($_POST['template_name']) ? sanitize_text_field($_POST['template_name']) : '';
|
||||
$subject = isset($_POST['template_subject']) ? sanitize_text_field($_POST['template_subject']) : '';
|
||||
$template_body = isset($_POST['template_body']) ? wp_kses_post($_POST['template_body']) : '';
|
||||
|
||||
if (!empty($name) && !empty($subject) && !empty($template_body) && $template_id > 0) {
|
||||
$result = $wpdb->update(
|
||||
$table_name,
|
||||
[
|
||||
'name' => $name,
|
||||
'subject' => $subject,
|
||||
'template_body' => $template_body,
|
||||
],
|
||||
['id' => $template_id],
|
||||
['%s', '%s', '%s'],
|
||||
['%d']
|
||||
);
|
||||
|
||||
if ($result !== false) {
|
||||
echo '<div class="notice notice-success is-dismissible"><p>' . __('Email template updated successfully!', 'wheel-of-fortune') . '</p></div>';
|
||||
} else {
|
||||
echo '<div class="notice notice-error is-dismissible"><p>' . __('Error updating email template. 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'] === 'delete_template' && check_admin_referer('wheel_email_templates_nonce')) {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'wheel_email_templates';
|
||||
|
||||
$template_id = isset($_POST['template_id']) ? intval($_POST['template_id']) : 0;
|
||||
|
||||
if ($template_id > 0) {
|
||||
$result = $wpdb->delete($table_name, ['id' => $template_id], ['%d']);
|
||||
|
||||
if ($result !== false) {
|
||||
echo '<div class="notice notice-success is-dismissible"><p>' . __('Email template deleted successfully!', 'wheel-of-fortune') . '</p></div>';
|
||||
} else {
|
||||
echo '<div class="notice notice-error is-dismissible"><p>' . __('Error deleting email template. Please try again.', 'wheel-of-fortune') . '</p></div>';
|
||||
}
|
||||
} else {
|
||||
echo '<div class="notice notice-error is-dismissible"><p>' . __('Invalid template ID.', 'wheel-of-fortune') . '</p></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get all email templates
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'wheel_email_templates';
|
||||
$templates = $wpdb->get_results("SELECT * FROM $table_name ORDER BY name ASC", ARRAY_A);
|
||||
|
||||
?>
|
||||
|
||||
<div class="wrap wheel-admin-page">
|
||||
<h1><?php echo esc_html__('Email Templates', 'wheel-of-fortune'); ?></h1>
|
||||
|
||||
<div class="wheel-card">
|
||||
<h2><?php echo esc_html__('All Email Templates', 'wheel-of-fortune'); ?></h2>
|
||||
|
||||
<p><button class="button button-primary add-new-template"><?php _e('Add New Template', 'wheel-of-fortune'); ?></button></p>
|
||||
|
||||
<table class="wheel-templates-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('Subject', 'wheel-of-fortune'); ?></th>
|
||||
<th><?php _e('Actions', 'wheel-of-fortune'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($templates)): ?>
|
||||
<tr><td colspan="4"><?php _e('No email templates found. Add your first template using the button above.', 'wheel-of-fortune'); ?></td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($templates as $template): ?>
|
||||
<tr>
|
||||
<td><?php echo esc_html($template['id']); ?></td>
|
||||
<td><?php echo esc_html($template['name']); ?></td>
|
||||
<td><?php echo esc_html($template['subject']); ?></td>
|
||||
<td>
|
||||
<button class="button edit-template" data-id="<?php echo esc_attr($template['id']); ?>"><?php _e('Edit', 'wheel-of-fortune'); ?></button>
|
||||
<button class="button delete-template" data-id="<?php echo esc_attr($template['id']); ?>"><?php _e('Delete', 'wheel-of-fortune'); ?></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="wheel-card" id="add-template-section">
|
||||
<h2><?php echo esc_html__('Add New Email Template', 'wheel-of-fortune'); ?></h2>
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('wheel_email_templates_nonce'); ?>
|
||||
<input type="hidden" name="action" value="add_template">
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><label for="template_name"><?php _e('Template Name', 'wheel-of-fortune'); ?></label></th>
|
||||
<td><input type="text" id="template_name" name="template_name" class="regular-text" required></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="template_subject"><?php _e('Email Subject', 'wheel-of-fortune'); ?></label></th>
|
||||
<td><input type="text" id="template_subject" name="template_subject" class="large-text" required></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="template_body"><?php _e('Email Body', 'wheel-of-fortune'); ?></label></th>
|
||||
<td>
|
||||
<textarea id="template_body" name="template_body" rows="10" class="large-text code" required></textarea>
|
||||
<p class="description"><?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>, <strong><code>{funded_account_name}</code></strong>, <strong><code>{funded_account_value}</code></strong></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p class="submit"><input type="submit" class="button button-primary" value="<?php esc_attr_e('Add Template', 'wheel-of-fortune'); ?>"></p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Template Modal -->
|
||||
<div id="edit-template-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);">
|
||||
<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 Email Template', 'wheel-of-fortune'); ?></h2>
|
||||
<form id="edit-template-form" method="post" action="">
|
||||
<?php wp_nonce_field('wheel_email_templates_nonce'); ?>
|
||||
<input type="hidden" name="action" value="edit_template">
|
||||
<input type="hidden" id="edit-template-id" name="template_id" value="">
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row"><label for="edit-template-name"><?php _e('Template Name', 'wheel-of-fortune'); ?></label></th>
|
||||
<td><input type="text" id="edit-template-name" name="template_name" class="regular-text" required></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="edit-template-subject"><?php _e('Email Subject', 'wheel-of-fortune'); ?></label></th>
|
||||
<td><input type="text" id="edit-template-subject" name="template_subject" class="large-text" required></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="edit-template-body"><?php _e('Email Body', 'wheel-of-fortune'); ?></label></th>
|
||||
<td>
|
||||
<textarea id="edit-template-body" name="template_body" rows="10" class="large-text code" required></textarea>
|
||||
<p class="description"><?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>, <strong><code>{funded_account_name}</code></strong>, <strong><code>{funded_account_value}</code></strong></li>
|
||||
</ul>
|
||||
</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($) {
|
||||
// Modalno okno za urejanje predlog
|
||||
var modal = $('#edit-template-modal');
|
||||
var closeBtn = modal.find('.close');
|
||||
|
||||
$('.add-new-template').on('click', function() {
|
||||
$('html, body').animate({
|
||||
scrollTop: $('#add-template-section').offset().top
|
||||
}, 500);
|
||||
});
|
||||
|
||||
closeBtn.on('click', function() {
|
||||
modal.hide();
|
||||
});
|
||||
|
||||
$(window).on('click', function(e) {
|
||||
if (e.target === modal[0]) {
|
||||
modal.hide();
|
||||
}
|
||||
});
|
||||
|
||||
$('.edit-template').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var templateId = $(this).data('id');
|
||||
|
||||
// AJAX klic za pridobitev podatkov o predlogi
|
||||
$.post(ajaxurl, {
|
||||
action: 'wheel_get_template_details',
|
||||
template_id: templateId,
|
||||
_ajax_nonce: '<?php echo wp_create_nonce('wheel_admin_nonce'); ?>'
|
||||
}, function(response) {
|
||||
if (response.success) {
|
||||
var template = response.data;
|
||||
|
||||
// Napolni obrazec
|
||||
$('#edit-template-id').val(template.id);
|
||||
$('#edit-template-name').val(template.name);
|
||||
$('#edit-template-subject').val(template.subject);
|
||||
$('#edit-template-body').val(template.template_body);
|
||||
|
||||
modal.show();
|
||||
} else {
|
||||
alert(response.data.message || 'Napaka pri pridobivanju podatkov o predlogi.');
|
||||
}
|
||||
}).fail(function() {
|
||||
alert('Napaka pri komunikaciji s strežnikom.');
|
||||
});
|
||||
});
|
||||
|
||||
$('.delete-template').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (!confirm('Ali res želiš izbrisati to predlogo?')) return;
|
||||
|
||||
var row = $(this).closest('tr');
|
||||
var templateId = $(this).data('id');
|
||||
|
||||
// Ustvari obrazec za POST zahtevo
|
||||
var form = $('<form method="post"></form>');
|
||||
form.append('<input type="hidden" name="action" value="delete_template">');
|
||||
form.append('<input type="hidden" name="template_id" value="' + templateId + '">');
|
||||
form.append('<?php echo wp_nonce_field('wheel_email_templates_nonce', '_wpnonce', true, false); ?>');
|
||||
|
||||
// Dodaj obrazec na stran in ga pošlji
|
||||
$('body').append(form);
|
||||
form.submit();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -6,6 +6,29 @@ jQuery(document).ready(function($) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Funkcija za prikaz/skrivanje polj za e-pošto po meri
|
||||
function handleEmailSourceChange() {
|
||||
// Za formo za dodajanje
|
||||
if ($('#prize_email_template_id').val() == '0') {
|
||||
$('.custom-email-fields').show();
|
||||
} else {
|
||||
$('.custom-email-fields').hide();
|
||||
}
|
||||
|
||||
// Za modalno okno za urejanje
|
||||
if ($('#edit-prize-email-template-id').val() == '0') {
|
||||
$('.custom-email-fields-edit').show();
|
||||
} else {
|
||||
$('.custom-email-fields-edit').hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Poveži event handler za spremembo izbire predloge
|
||||
$('body').on('change', '#prize_email_template_id, #edit-prize-email-template-id', handleEmailSourceChange);
|
||||
|
||||
// Sproži ob nalaganju strani za formo za dodajanje
|
||||
handleEmailSourceChange();
|
||||
|
||||
// Tab navigation
|
||||
$('.nav-tab').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
|
@ -71,7 +94,14 @@ jQuery(document).ready(function($) {
|
|||
$('#edit-prize-discount-value').val(prize.discount_value);
|
||||
$('#edit-prize-email-subject').val(prize.email_subject);
|
||||
$('#edit-prize-email-template').val(prize.email_template);
|
||||
$('#edit-prize-is-try-again').prop('checked', parseInt(prize.is_try_again, 10));
|
||||
|
||||
// Napolni nova polja
|
||||
$('#edit-funded-account-name').val(prize.funded_account_name);
|
||||
$('#edit-funded-account-value').val(prize.funded_account_value);
|
||||
$('#edit-prize-email-template-id').val(prize.email_template_id);
|
||||
|
||||
// Sproži spremembo, da se pravilno prikažejo/skrijejo polja
|
||||
$('#edit-prize-email-template-id').trigger('change');
|
||||
|
||||
modal.show();
|
||||
} else {
|
||||
|
|
@ -101,7 +131,11 @@ jQuery(document).ready(function($) {
|
|||
discount_value: $('#edit-prize-discount-value').val(),
|
||||
email_subject: $('#edit-prize-email-subject').val(),
|
||||
email_template: $('#edit-prize-email-template').val(),
|
||||
is_try_again: $('#edit-prize-is-try-again').is(':checked') ? 1 : 0,
|
||||
|
||||
// Dodaj nova polja
|
||||
email_template_id: $('#edit-prize-email-template-id').val(),
|
||||
funded_account_name: $('#edit-funded-account-name').val(),
|
||||
funded_account_value: $('#edit-funded-account-value').val()
|
||||
};
|
||||
|
||||
// Debug: preveri wheel_id
|
||||
|
|
@ -284,4 +318,53 @@ jQuery(document).ready(function($) {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Upravljanje z wheel_product elementi (preneseno iz edit-wheel-page.php)
|
||||
$('.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: wheel_admin_nonce._ajax_nonce
|
||||
}, 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: wheel_admin_nonce._ajax_nonce
|
||||
}, function(response) {
|
||||
if (response.success) {
|
||||
td.text(val);
|
||||
} else {
|
||||
alert(response.data || 'Napaka pri shranjevanju.');
|
||||
td.text(current);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
td.text(current);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -3,6 +3,10 @@
|
|||
* Reusable form fields for adding/editing prizes
|
||||
*/
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
// Pridobi predloge (potrebno na strani, ki vključuje to datoteko)
|
||||
global $wpdb;
|
||||
$email_templates = $wpdb->get_results("SELECT id, name FROM {$wpdb->prefix}wheel_email_templates ORDER BY name ASC", ARRAY_A);
|
||||
?>
|
||||
<tr>
|
||||
<th scope="row"><label for="prize_name"><?php _e('Prize Name', 'wheel-of-fortune'); ?></label></th>
|
||||
|
|
@ -28,6 +32,23 @@ if (!defined('ABSPATH')) exit;
|
|||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- DODAJ NOVA POLJA ZA FUNDED ACCOUNT -->
|
||||
<tr>
|
||||
<th scope="row"><label for="funded_account_name"><?php _e('Funded Account Name', 'wheel-of-fortune'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" id="funded_account_name" name="funded_account_name" class="regular-text">
|
||||
<p class="description"><?php _e('e.g., Funded7 $50k. Used for the {funded_account_name} tag.', 'wheel-of-fortune'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="funded_account_value"><?php _e('Funded Account Value', 'wheel-of-fortune'); ?></label></th>
|
||||
<td>
|
||||
<input type="number" id="funded_account_value" name="funded_account_value" step="any" min="0">
|
||||
<p class="description"><?php _e('e.g., 50000. Used for the {funded_account_value} tag.', 'wheel-of-fortune'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row"><label for="prize_redemption_code"><?php _e('Redemption Code', 'wheel-of-fortune'); ?></label></th>
|
||||
<td>
|
||||
|
|
@ -35,24 +56,42 @@ if (!defined('ABSPATH')) exit;
|
|||
<p class="description"><?php _e('Optional code for the user to redeem the prize.', 'wheel-of-fortune'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- SPREMENJENA EMAIL SEKCIJA -->
|
||||
<tr>
|
||||
<th scope="row"><label for="prize_email_subject"><?php _e('Email Subject', 'wheel-of-fortune'); ?></label></th>
|
||||
<th scope="row"><label for="prize_email_template_id"><?php _e('Email Content', 'wheel-of-fortune'); ?></label></th>
|
||||
<td>
|
||||
<select id="prize_email_template_id" name="email_template_id">
|
||||
<option value="0"><?php _e('-- Custom Email --', 'wheel-of-fortune'); ?></option>
|
||||
<?php foreach ($email_templates as $template) : ?>
|
||||
<option value="<?php echo esc_attr($template['id']); ?>"><?php echo esc_html($template['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<p class="description"><?php _e('Choose a pre-written template or select "Custom Email" to write your own below.', 'wheel-of-fortune'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tbody class="custom-email-fields">
|
||||
<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>
|
||||
<p class="description"><?php _e('Subject for this prize\'s email. Only used if "Custom Email" is selected.', '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 class="description"><?php _e('Content for this prize\'s email. Only used if "Custom Email" is selected.', '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>
|
||||
<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>, <strong><code>{funded_account_name}</code></strong>, <strong><code>{funded_account_value}</code></strong></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<tr>
|
||||
<th scope="row"><label for="prize_is_discount"><?php _e('Je discount?', 'wheel-of-fortune'); ?></label></th>
|
||||
<td>
|
||||
|
|
@ -66,11 +105,4 @@ if (!defined('ABSPATH')) exit;
|
|||
<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>
|
||||
<tr>
|
||||
<th scope="row"><label for="prize_is_try_again"><?php _e('Try Again?', 'wheel-of-fortune'); ?></label></th>
|
||||
<td>
|
||||
<input type="checkbox" id="prize_is_try_again" name="prize_is_try_again" value="1">
|
||||
<p class="description"><?php _e('Označi, če je ta nagrada "Try Again" (ponovni poskus).', 'wheel-of-fortune'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -8,8 +8,6 @@ if (!defined('ABSPATH')) {
|
|||
exit;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
|
||||
// Preveri, če ima uporabnik pravice za dostop
|
||||
if (!current_user_can('manage_options')) {
|
||||
return;
|
||||
|
|
@ -69,10 +67,6 @@ if (isset($_POST['wheel_save_settings']) && check_admin_referer('wheel_settings_
|
|||
}
|
||||
update_option('wheel_spin_products', $spin_products);
|
||||
|
||||
// Dnevni spin - shrani izbrano kolo
|
||||
$daily_spin_wheel_id = isset($_POST['wof_daily_spin_wheel_id']) ? intval($_POST['wof_daily_spin_wheel_id']) : '';
|
||||
update_option('wof_daily_spin_wheel_id', $daily_spin_wheel_id);
|
||||
|
||||
// Prikaži sporočilo o uspehu
|
||||
add_settings_error('wheel_settings', 'settings_updated', __('Nastavitve so bile uspešno shranjene.', 'wheel-of-fortune'), 'updated');
|
||||
}
|
||||
|
|
@ -85,11 +79,6 @@ $max_spins = get_option('wheel_max_spins', 0);
|
|||
$send_emails = get_option('wheel_send_emails', false);
|
||||
$spin_products = get_option('wheel_spin_products', array());
|
||||
|
||||
// Pridobi vsa kolesa za dropdown
|
||||
$wheels_table = $wpdb->prefix . 'wof_wheels';
|
||||
$wheels = $wpdb->get_results("SELECT * FROM $wheels_table ORDER BY id ASC", ARRAY_A);
|
||||
$daily_spin_wheel_id = get_option('wof_daily_spin_wheel_id', '');
|
||||
|
||||
// Prikaži sporočila o napakah/uspehu
|
||||
settings_errors('wheel_settings');
|
||||
?>
|
||||
|
|
@ -129,20 +118,6 @@ settings_errors('wheel_settings');
|
|||
<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>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="wof_daily_spin_wheel_id"><?php echo esc_html__('Kolo za dnevni spin', 'wheel-of-fortune'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<select id="wof_daily_spin_wheel_id" name="wof_daily_spin_wheel_id">
|
||||
<option value=""><?php echo esc_html__('Izberi kolo', 'wheel-of-fortune'); ?></option>
|
||||
<?php foreach ($wheels as $wheel): ?>
|
||||
<option value="<?php echo esc_attr($wheel['id']); ?>" <?php selected($daily_spin_wheel_id, $wheel['id']); ?>><?php echo esc_html($wheel['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<p class="description"><?php echo esc_html__('Vsi registrirani uporabniki bodo vsakih 24 ur prejeli 1 spin na izbranem kolesu.', '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>
|
||||
|
|
|
|||
|
|
@ -81,41 +81,6 @@ if (isset($_POST['mark_redeemed']) && isset($_POST['prize_id'])) {
|
|||
'</p></div>';
|
||||
}
|
||||
|
||||
// Ponastavi spine na 0 za vse uporabnike na izbranem kolesu
|
||||
if (isset($_POST['reset_all_spins_wheel']) && isset($_POST['wheel_id'])) {
|
||||
check_admin_referer('reset_spins_wheel_nonce', 'reset_spins_wheel_nonce');
|
||||
|
||||
$wheel_id = intval($_POST['wheel_id']);
|
||||
|
||||
// Preveri, če kolo obstaja
|
||||
$wheel_exists = $wpdb->get_var($wpdb->prepare("SELECT id FROM $wheels_table WHERE id = %d", $wheel_id));
|
||||
|
||||
if ($wheel_exists) {
|
||||
// Ponastavi spine na 0 za vse uporabnike na tem kolesu
|
||||
$result = $wpdb->update(
|
||||
$spins_table,
|
||||
array('spins_available' => 0),
|
||||
array('wheel_id' => $wheel_id),
|
||||
array('%d'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
if ($result !== false) {
|
||||
echo '<div class="notice notice-success is-dismissible"><p>' .
|
||||
sprintf(__('Vsi spini za kolo ID %d so bili uspešno ponastavljeni na 0.', 'wheel-of-fortune'), $wheel_id) .
|
||||
'</p></div>';
|
||||
} else {
|
||||
echo '<div class="notice notice-error is-dismissible"><p>' .
|
||||
__('Prišlo je do napake pri ponastavitvi spinov.', 'wheel-of-fortune') .
|
||||
'</p></div>';
|
||||
}
|
||||
} else {
|
||||
echo '<div class="notice notice-error is-dismissible"><p>' .
|
||||
__('Izbrano kolo ne obstaja.', 'wheel-of-fortune') .
|
||||
'</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// Izberi uporabnika za podrobnosti
|
||||
$selected_user_id = isset($_GET['user_id']) ? intval($_GET['user_id']) : 0;
|
||||
|
||||
|
|
@ -141,22 +106,6 @@ if ($selected_user_id > 0) {
|
|||
<div class="wrap">
|
||||
<h1><?php echo esc_html__('Statistika Kolesa Sreče', 'wheel-of-fortune'); ?></h1>
|
||||
|
||||
<!-- Gumb za ponastavitev spinov za izbrano kolo -->
|
||||
<div class="notice notice-warning" style="margin: 20px 0;">
|
||||
<p>
|
||||
<strong><?php echo esc_html__('Ponastavitev spinov', 'wheel-of-fortune'); ?>:</strong>
|
||||
<?php echo esc_html__('To dejanje bo ponastavilo vse spine na 0 za vse uporabnike na izbranem kolesu. To dejanje ni mogoče razveljaviti.', 'wheel-of-fortune'); ?>
|
||||
<form method="post" style="display: inline-block; margin-left: 10px;">
|
||||
<?php wp_nonce_field('reset_spins_wheel_nonce', 'reset_spins_wheel_nonce'); ?>
|
||||
<input type="hidden" name="wheel_id" value="<?php echo esc_attr($selected_wheel_id); ?>">
|
||||
<button type="submit" name="reset_all_spins_wheel" class="button button-secondary"
|
||||
onclick="return confirm('<?php echo esc_js(__('Ste prepričani, da želite ponastaviti vse spine na 0 za vse uporabnike na tem kolesu? To dejanje ni mogoče razveljaviti.', 'wheel-of-fortune')); ?>')">
|
||||
<?php echo esc_html__('Ponastavi vse spine na 0 za to kolo', 'wheel-of-fortune'); ?>
|
||||
</button>
|
||||
</form>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Izbira kolesa -->
|
||||
<div class="tablenav top">
|
||||
<div class="alignleft actions">
|
||||
|
|
@ -183,45 +132,9 @@ if ($selected_user_id > 0) {
|
|||
<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>
|
||||
|
||||
<!-- Filtriranje uporabnikov -->
|
||||
<div class="user-filters" style="margin: 20px 0; padding: 15px; background: #f9f9f9; border: 1px solid #ddd; border-radius: 5px;">
|
||||
<h4><?php echo esc_html__('Filtriranje uporabnikov', 'wheel-of-fortune'); ?></h4>
|
||||
<div style="display: flex; gap: 15px; align-items: center; flex-wrap: wrap;">
|
||||
<div>
|
||||
<label for="filter-spins"><?php echo esc_html__('Preostali spini:', 'wheel-of-fortune'); ?></label>
|
||||
<select id="filter-spins" style="margin-left: 5px;">
|
||||
<option value=""><?php echo esc_html__('Vsi', 'wheel-of-fortune'); ?></option>
|
||||
<option value="0"><?php echo esc_html__('0 spinov (porabili)', 'wheel-of-fortune'); ?></option>
|
||||
<option value="1"><?php echo esc_html__('1 spin', 'wheel-of-fortune'); ?></option>
|
||||
<option value="2"><?php echo esc_html__('2 spina', 'wheel-of-fortune'); ?></option>
|
||||
<option value="3"><?php echo esc_html__('3 spini', 'wheel-of-fortune'); ?></option>
|
||||
<option value="4"><?php echo esc_html__('4 spini', 'wheel-of-fortune'); ?></option>
|
||||
<option value="5"><?php echo esc_html__('5+ spinov', 'wheel-of-fortune'); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="filter-total-spins"><?php echo esc_html__('Skupno spinov:', 'wheel-of-fortune'); ?></label>
|
||||
<select id="filter-total-spins" style="margin-left: 5px;">
|
||||
<option value=""><?php echo esc_html__('Vsi', 'wheel-of-fortune'); ?></option>
|
||||
<option value="0"><?php echo esc_html__('0', 'wheel-of-fortune'); ?></option>
|
||||
<option value="1"><?php echo esc_html__('1', 'wheel-of-fortune'); ?></option>
|
||||
<option value="2-5"><?php echo esc_html__('2-5', 'wheel-of-fortune'); ?></option>
|
||||
<option value="6-10"><?php echo esc_html__('6-10', 'wheel-of-fortune'); ?></option>
|
||||
<option value="11+"><?php echo esc_html__('11+', 'wheel-of-fortune'); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" onclick="filterUsers()" class="button button-primary"><?php echo esc_html__('Potrdi filtriranje', 'wheel-of-fortune'); ?></button>
|
||||
<button type="button" onclick="clearFilters()" class="button" style="margin-left: 10px;"><?php echo esc_html__('Počisti filtre', 'wheel-of-fortune'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filter-results" style="margin-top: 10px; font-weight: bold; color: #0073aa;"></div>
|
||||
</div>
|
||||
|
||||
<table class="wp-list-table widefat fixed striped" id="users-table">
|
||||
<table class="wp-list-table widefat fixed striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><?php echo esc_html__('ID', 'wheel-of-fortune'); ?></th>
|
||||
|
|
@ -341,200 +254,4 @@ if ($selected_user_id > 0) {
|
|||
<p><?php echo esc_html__('Uporabnik ni bil najden.', 'wheel-of-fortune'); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Funkcija za filtriranje uporabnikov
|
||||
function filterUsers() {
|
||||
const filterSpins = document.getElementById('filter-spins').value;
|
||||
const filterTotalSpins = document.getElementById('filter-total-spins').value;
|
||||
const table = document.getElementById('users-table');
|
||||
const tbody = table.getElementsByTagName('tbody')[0];
|
||||
|
||||
if (!tbody) {
|
||||
console.error('Tabela ni najdena');
|
||||
return;
|
||||
}
|
||||
|
||||
const rows = tbody.getElementsByTagName('tr');
|
||||
let visibleCount = 0;
|
||||
|
||||
console.log('Filtriranje uporabnikov:', { filterSpins, filterTotalSpins, totalRows: rows.length });
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const row = rows[i];
|
||||
const cells = row.getElementsByTagName('td');
|
||||
|
||||
if (cells.length < 4) {
|
||||
console.log('Preskočena vrstica (premalo stolpcev):', cells.length);
|
||||
continue; // Preskoči header vrstice ali vrstice brez dovolj stolpcev
|
||||
}
|
||||
|
||||
// Debug: prikaži vsebino vseh stolpcev
|
||||
console.log(`Vrstica ${i} stolpci:`, {
|
||||
stolpec0: cells[0] ? cells[0].textContent.trim() : 'N/A',
|
||||
stolpec1: cells[1] ? cells[1].textContent.trim() : 'N/A',
|
||||
stolpec2: cells[2] ? cells[2].textContent.trim() : 'N/A',
|
||||
stolpec3: cells[3] ? cells[3].textContent.trim() : 'N/A',
|
||||
stolpec4: cells[4] ? cells[4].textContent.trim() : 'N/A',
|
||||
stolpec5: cells[5] ? cells[5].textContent.trim() : 'N/A'
|
||||
});
|
||||
|
||||
const currentSpins = parseInt(cells[3].textContent.trim()) || 0; // Preostali spini (4. stolpec)
|
||||
const totalSpins = parseInt(cells[2].textContent.trim()) || 0; // Skupno št. spinov (3. stolpec)
|
||||
|
||||
console.log(`Vrstica ${i}: currentSpins=${currentSpins}, totalSpins=${totalSpins}`);
|
||||
|
||||
let showRow = true;
|
||||
|
||||
// Filtriranje po preostalih spinih
|
||||
if (filterSpins !== '') {
|
||||
if (filterSpins === '0') {
|
||||
showRow = showRow && (currentSpins === 0);
|
||||
} else if (filterSpins === '1') {
|
||||
showRow = showRow && (currentSpins === 1);
|
||||
} else if (filterSpins === '2') {
|
||||
showRow = showRow && (currentSpins === 2);
|
||||
} else if (filterSpins === '3') {
|
||||
showRow = showRow && (currentSpins === 3);
|
||||
} else if (filterSpins === '4') {
|
||||
showRow = showRow && (currentSpins === 4);
|
||||
} else if (filterSpins === '5') {
|
||||
showRow = showRow && (currentSpins >= 5);
|
||||
}
|
||||
}
|
||||
|
||||
// Filtriranje po skupnem številu spinov
|
||||
if (filterTotalSpins !== '') {
|
||||
if (filterTotalSpins === '0') {
|
||||
showRow = showRow && (totalSpins === 0);
|
||||
} else if (filterTotalSpins === '1') {
|
||||
showRow = showRow && (totalSpins === 1);
|
||||
} else if (filterTotalSpins === '2-5') {
|
||||
showRow = showRow && (totalSpins >= 2 && totalSpins <= 5);
|
||||
} else if (filterTotalSpins === '6-10') {
|
||||
showRow = showRow && (totalSpins >= 6 && totalSpins <= 10);
|
||||
} else if (filterTotalSpins === '11+') {
|
||||
showRow = showRow && (totalSpins >= 11);
|
||||
}
|
||||
}
|
||||
|
||||
// Prikaži/skrij vrstico
|
||||
if (showRow) {
|
||||
row.style.display = '';
|
||||
visibleCount++;
|
||||
console.log(`Prikazana vrstica ${i}`);
|
||||
} else {
|
||||
row.style.display = 'none';
|
||||
console.log(`Skrita vrstica ${i}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Filtriranje končano: ${visibleCount} od ${rows.length} vrstic prikazanih`);
|
||||
|
||||
// Posodobi števec rezultatov
|
||||
updateFilterResults(visibleCount, rows.length);
|
||||
}
|
||||
|
||||
function clearFilters() {
|
||||
document.getElementById('filter-spins').value = '';
|
||||
document.getElementById('filter-total-spins').value = '';
|
||||
filterUsers();
|
||||
}
|
||||
|
||||
function updateFilterResults(visible, total) {
|
||||
const resultsDiv = document.getElementById('filter-results');
|
||||
if (visible === total) {
|
||||
resultsDiv.innerHTML = '<?php echo esc_js(__('Prikazani vsi uporabniki:', 'wheel-of-fortune')); ?> ' + total;
|
||||
} else {
|
||||
resultsDiv.innerHTML = '<?php echo esc_js(__('Prikazano:', 'wheel-of-fortune')); ?> ' + visible + ' <?php echo esc_js(__('od', 'wheel-of-fortune')); ?> ' + total + ' <?php echo esc_js(__('uporabnikov', 'wheel-of-fortune')); ?>';
|
||||
}
|
||||
}
|
||||
|
||||
// Testna funkcija za preverjanje strukture tabele
|
||||
function testTableStructure() {
|
||||
const table = document.getElementById('users-table');
|
||||
if (!table) {
|
||||
console.log('Tabela ni najdena!');
|
||||
return;
|
||||
}
|
||||
|
||||
const tbody = table.getElementsByTagName('tbody')[0];
|
||||
if (!tbody) {
|
||||
console.log('Tbody ni najden!');
|
||||
return;
|
||||
}
|
||||
|
||||
const rows = tbody.getElementsByTagName('tr');
|
||||
console.log(`Najdenih ${rows.length} vrstic v tabeli`);
|
||||
|
||||
if (rows.length > 0) {
|
||||
const firstRow = rows[0];
|
||||
const cells = firstRow.getElementsByTagName('td');
|
||||
console.log(`Prva vrstica ima ${cells.length} stolpcev`);
|
||||
|
||||
for (let i = 0; i < cells.length; i++) {
|
||||
console.log(`Stolpec ${i}: "${cells[i].textContent.trim()}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializiraj števec rezultatov ob nalaganju strani
|
||||
jQuery(document).ready(function($) {
|
||||
// Gumb za ponastavitev spinov preko AJAX
|
||||
$('button[name="reset_all_spins_wheel"]').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const button = $(this);
|
||||
const originalText = button.text();
|
||||
const wheelId = $('input[name="wheel_id"]').val();
|
||||
|
||||
if (!confirm('<?php echo esc_js(__('Ste prepričani, da želite ponastaviti vse spine na 0 za vse uporabnike na tem kolesu? To dejanje ni mogoče razveljaviti.', 'wheel-of-fortune')); ?>')) {
|
||||
return;
|
||||
}
|
||||
|
||||
button.prop('disabled', true).text('<?php echo esc_js(__('Ponastavljam spine...', 'wheel-of-fortune')); ?>');
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'wheel_reset_spins_wheel',
|
||||
wheel_id: wheelId,
|
||||
_ajax_nonce: '<?php echo wp_create_nonce('wheel_admin_nonce'); ?>'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
// Prikaži uspešno sporočilo
|
||||
$('<div class="notice notice-success is-dismissible"><p>' + response.data.message + '</p></div>')
|
||||
.insertAfter('h1')
|
||||
.delay(3000)
|
||||
.fadeOut();
|
||||
|
||||
// Osveži stran po 2 sekundah
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 2000);
|
||||
} else {
|
||||
alert(response.data.message || '<?php echo esc_js(__('Prišlo je do napake.', 'wheel-of-fortune')); ?>');
|
||||
button.prop('disabled', false).text(originalText);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('<?php echo esc_js(__('Prišlo je do napake pri komunikaciji s strežnikom.', 'wheel-of-fortune')); ?>');
|
||||
button.prop('disabled', false).text(originalText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Posodobi števec rezultatov ob nalaganju strani
|
||||
const table = document.getElementById('users-table');
|
||||
if (table) {
|
||||
const rows = table.getElementsByTagName('tbody')[0].getElementsByTagName('tr');
|
||||
updateFilterResults(rows.length, rows.length);
|
||||
|
||||
// Testiraj strukturo tabele
|
||||
testTableStructure();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
@ -128,12 +128,12 @@
|
|||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
/* Simple solid fills for segment color classes */
|
||||
.wheel-segment-red { fill: #ff3131; }
|
||||
.wheel-segment-green { fill: #7ed957; }
|
||||
.wheel-segment-purple { fill: #8c52ff; }
|
||||
.wheel-segment-orange { fill: #ff914d; }
|
||||
.wheel-segment-blue { fill: #1da3e7; }
|
||||
/* 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 {
|
||||
|
|
@ -301,7 +301,7 @@
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 20px auto 0 auto;
|
||||
padding: 0 40px !important;
|
||||
padding: 0 40px;
|
||||
background: linear-gradient(135deg, #ff00c4, #00dfe9);
|
||||
color: #fff;
|
||||
border: none;
|
||||
|
|
@ -316,15 +316,7 @@
|
|||
height: 56px;
|
||||
min-width: 140px;
|
||||
letter-spacing: 2px;
|
||||
line-height: normal !important;
|
||||
text-shadow: 0 2px 8px #000, 0 0 10px #0cf101;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
/* Prevent accidental <br> tags inside the button from breaking centering */
|
||||
.wheel-button br {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Button hover effect */
|
||||
|
|
@ -639,4 +631,4 @@
|
|||
|
||||
.wheel-container.scale-50 {
|
||||
transform: scale(0.5);
|
||||
}
|
||||
}
|
||||
|
|
@ -67,13 +67,7 @@ jQuery(document).ready(function($) {
|
|||
|
||||
// Prikaz nagrade
|
||||
function showPrizePopup(prize) {
|
||||
var isTryAgain = window.wof_spin_result.is_try_again === 1 || prize.is_try_again === 1;
|
||||
var html = '';
|
||||
if (isTryAgain) {
|
||||
html = '<p><strong>' + prize.name + '</strong></p>';
|
||||
} else {
|
||||
html = '<h3>' + l10n.congratulations + '</h3><p>' + l10n.you_won + ' <strong>' + prize.name + '</strong></p>';
|
||||
}
|
||||
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>';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,58 +1,26 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Nastavitev imena izhodne datoteke
|
||||
# Set the output file
|
||||
OUTPUT_FILE="code_export.txt"
|
||||
|
||||
# Odstrani izhodno datoteko, če že obstaja, da začnemo s čisto datoteko
|
||||
# Remove the output file if it exists
|
||||
if [ -f "$OUTPUT_FILE" ]; then
|
||||
rm "$OUTPUT_FILE"
|
||||
fi
|
||||
|
||||
# Poišči vse datoteke, razen skritih datotek in določenih map (npr. node_modules).
|
||||
# Dodane so izjeme za slike, videoposnetke, PDF-je, arhive in druge binarne datoteke
|
||||
# neposredno v ukaz 'find' za boljšo zmogljivost.
|
||||
find . -type f \
|
||||
-not -path "*/\.*" \
|
||||
-not -path "*node_modules*" \
|
||||
-not -path "*vendor*" \
|
||||
-not -path "*dist*" \
|
||||
-not -path "*build*" \
|
||||
-not -path "*/images/*" \
|
||||
-not -iname "*.jpg" -not -iname "*.jpeg" \
|
||||
-not -iname "*.png" -not -iname "*.gif" \
|
||||
-not -iname "*.bmp" -not -iname "*.tiff" \
|
||||
-not -iname "*.svg" -not -iname "*.ico" \
|
||||
-not -iname "*.webp" \
|
||||
-not -iname "*.mp4" -not -iname "*.mov" \
|
||||
-not -iname "*.avi" -not -iname "*.mkv" \
|
||||
-not -iname "*.webm" \
|
||||
-not -iname "*.mp3" -not -iname "*.wav" \
|
||||
-not -iname "*.ogg" -not -iname "*.flac" \
|
||||
-not -iname "*.pdf" \
|
||||
-not -iname "*.zip" \
|
||||
-not -iname "*.tar" \
|
||||
-not -iname "*.gz" \
|
||||
-not -iname "*.bz2" \
|
||||
-not -iname "*.rar" \
|
||||
-not -iname "*.7z" \
|
||||
-not -iname "*.doc" -not -iname "*.docx" \
|
||||
-not -iname "*.xls" -not -iname "*.xlsx" \
|
||||
-not -iname "*.ppt" -not -iname "*.pptx" \
|
||||
-not -iname "*.eot" -not -iname "*.ttf" \
|
||||
-not -iname "*.woff" -not -iname "*.woff2" \
|
||||
| sort | while read -r file; do
|
||||
|
||||
# Preskoči samo izhodno datoteko in to skripto
|
||||
# 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
|
||||
|
||||
# Dodatna varnostna preverba: preskoči slikovne datoteke po MIME tipu
|
||||
if file --mime-type -b "$file" | grep -qiE '^(image)/'; then
|
||||
# Skip binary files and the output file itself
|
||||
if file "$file" | grep -q "binary"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Dodaj ime datoteke in njeno vsebino v izhodno datoteko
|
||||
# Add the filename and content to the output file
|
||||
echo "\"$file\" : " >> "$OUTPUT_FILE"
|
||||
echo "\"\"\"" >> "$OUTPUT_FILE"
|
||||
cat "$file" >> "$OUTPUT_FILE"
|
||||
|
|
@ -61,4 +29,4 @@ find . -type f \
|
|||
echo "" >> "$OUTPUT_FILE"
|
||||
done
|
||||
|
||||
echo "Izvoz kode končan. Vsebina je shranjena v datoteko $OUTPUT_FILE"
|
||||
echo "Code export completed. Output saved to $OUTPUT_FILE"
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
-- Dodajanje privzetih email predlog
|
||||
-- To datoteko lahko uvozimo ročno v phpMyAdmin ali uporabimo za references
|
||||
|
||||
-- Predloga 1: Standardna čestitka
|
||||
INSERT INTO `wp_wheel_email_templates` (`name`, `subject`, `template_body`) VALUES
|
||||
('Standardna čestitka', 'Čestitamo za vašo nagrado!',
|
||||
'<h2>Čestitamo, {user_name}!</h2>
|
||||
<p>Uspešno ste zadeli nagrado na našem kolesu sreče.</p>
|
||||
<p><strong>Nagrada:</strong> {prize_name}</p>
|
||||
<p>{prize_description}</p>
|
||||
<p><strong>Koda za unovčitev:</strong> {redemption_code}</p>
|
||||
<p>Hvala za sodelovanje!</p>
|
||||
<p>Lep pozdrav,<br>{site_name}</p>');
|
||||
|
||||
-- Predloga 2: Funded Account obvestilo
|
||||
INSERT INTO `wp_wheel_email_templates` (`name`, `subject`, `template_body`) VALUES
|
||||
('Funded Account obvestilo', 'Čestitamo! Zadeli ste Funded Account!',
|
||||
'<h2>Čestitamo, {user_name}!</h2>
|
||||
<p>Uspešno ste zadeli <strong>Funded Account</strong> na našem kolesu sreče!</p>
|
||||
<p>Podrobnosti o vašem računu:</p>
|
||||
<ul>
|
||||
<li><strong>Tip računa:</strong> {funded_account_name}</li>
|
||||
<li><strong>Vrednost računa:</strong> {funded_account_value}</li>
|
||||
<li><strong>Koda za unovčitev:</strong> {redemption_code}</li>
|
||||
</ul>
|
||||
<p>Za aktivacijo vašega računa sledite naslednjim korakom:</p>
|
||||
<ol>
|
||||
<li>Prijavite se v svoj uporabniški račun</li>
|
||||
<li>Pojdite na stran "Moji računi"</li>
|
||||
<li>Kliknite na "Aktiviraj nov račun"</li>
|
||||
<li>Vnesite kodo za unovčitev</li>
|
||||
</ol>
|
||||
<p>Če potrebujete pomoč, nas kontaktirajte na info@example.com.</p>
|
||||
<p>Lep pozdrav,<br>{site_name}</p>');
|
||||
|
||||
-- Predloga 3: Kupon za popust
|
||||
INSERT INTO `wp_wheel_email_templates` (`name`, `subject`, `template_body`) VALUES
|
||||
('Kupon za popust', 'Vaš kupon za popust je pripravljen!',
|
||||
'<h2>Čestitamo, {user_name}!</h2>
|
||||
<p>Uspešno ste zadeli <strong>kupon za popust</strong> na našem kolesu sreče!</p>
|
||||
<p>Vaš kupon vam omogoča popust pri naslednjem nakupu.</p>
|
||||
<p><strong>Koda kupona:</strong> {redemption_code}</p>
|
||||
<p>Za uveljavitev popusta enostavno vnesite zgornjo kodo pri zaključku nakupa.</p>
|
||||
<p>Kupon je veljaven 30 dni od datuma prejema.</p>
|
||||
<p>Lep pozdrav,<br>{site_name}</p>');
|
||||
|
|
@ -25,6 +25,17 @@
|
|||
<td style="font-weight: bold;">Description:</td>
|
||||
<td>{prize_description}</td>
|
||||
</tr>
|
||||
<!-- FUNDED ACCOUNT FIELDS - prikaži samo če obstajajo -->
|
||||
<!-- BEGIN FUNDED ACCOUNT -->
|
||||
<tr>
|
||||
<td style="font-weight: bold;">Account Type:</td>
|
||||
<td><strong>{funded_account_name}</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-weight: bold;">Account Value:</td>
|
||||
<td><strong>{funded_account_value}</strong></td>
|
||||
</tr>
|
||||
<!-- END FUNDED ACCOUNT -->
|
||||
<tr>
|
||||
<td style="font-weight: bold;">Redemption code:</td>
|
||||
<td><strong>{redemption_code}</strong></td>
|
||||
|
|
|
|||
|
|
@ -105,12 +105,6 @@ class WheelOfFortune {
|
|||
add_action('plugins_loaded', array($this, 'load_textdomain'));
|
||||
register_activation_hook(WHEEL_OF_FORTUNE_PLUGIN_FILE, array($this, 'activate'));
|
||||
register_deactivation_hook(WHEEL_OF_FORTUNE_PLUGIN_FILE, array($this, 'deactivate'));
|
||||
|
||||
// --- CRON: filter in akcija vedno aktivna ---
|
||||
add_filter('cron_schedules', array($this, 'add_custom_cron_schedules'));
|
||||
add_action('wof_daily_spin_event', array($this, 'execute_daily_spin_cron'));
|
||||
// ------------------------------------------
|
||||
|
||||
add_action('admin_menu', array($this, 'admin_menu'));
|
||||
add_action('rest_api_init', array($this, 'register_rest_routes'));
|
||||
add_shortcode('wheel_of_fortune', array($this, 'shortcode'));
|
||||
|
|
@ -131,10 +125,9 @@ class WheelOfFortune {
|
|||
add_action('wp_ajax_wheel_get_product', array($this, 'ajax_get_product'));
|
||||
add_action('wp_ajax_wheel_test_email', array($this, 'ajax_test_email'));
|
||||
add_action('wp_ajax_wheel_get_prizes', array($this, 'ajax_get_prizes'));
|
||||
add_action('wp_ajax_ajax_update_wheel_product_spins', array($this, 'ajax_update_wheel_product_spins'));
|
||||
add_action('wp_ajax_wof_delete_wheel_product', array($this, 'ajax_delete_wheel_product'));
|
||||
add_action('wp_ajax_wheel_migrate_try_again', array($this, 'ajax_migrate_try_again'));
|
||||
add_action('wp_ajax_wheel_reset_spins_wheel', array($this, 'ajax_reset_spins_wheel'));
|
||||
add_action('wp_ajax_wof_update_wheel_product_spins', array($this, 'ajax_update_wheel_product_spins'));
|
||||
add_action('wp_ajax_wheel_get_template_details', array($this, 'ajax_get_template_details'));
|
||||
|
||||
// Vključi testno skripto za kupone
|
||||
if (is_admin()) {
|
||||
|
|
@ -234,22 +227,35 @@ class WheelOfFortune {
|
|||
}
|
||||
|
||||
public function activate() {
|
||||
error_log("Wheel of Fortune: Aktivacija plugina...");
|
||||
$this->create_database_tables();
|
||||
$this->run_migration();
|
||||
$this->set_default_options();
|
||||
$this->add_default_prizes();
|
||||
|
||||
// Dodaj cron opravilo za dnevne spine
|
||||
if (!wp_next_scheduled('wheel_daily_spins_cron')) {
|
||||
wp_schedule_event(time(), 'wheel_daily', 'wheel_daily_spins_cron');
|
||||
// Debug: Preveri, ali se tabela za kolesa ustvari
|
||||
global $wpdb;
|
||||
$wheels_table = $wpdb->prefix . 'wof_wheels';
|
||||
$wheel_products_table = $wpdb->prefix . 'wheel_of_fortune_products';
|
||||
|
||||
$wheels_exists = $wpdb->get_var("SHOW TABLES LIKE '$wheels_table'") == $wheels_table;
|
||||
$products_exists = $wpdb->get_var("SHOW TABLES LIKE '$wheel_products_table'") == $wheel_products_table;
|
||||
|
||||
error_log("=== ACTIVATION DEBUG ===");
|
||||
error_log("Wheels table exists: " . ($wheels_exists ? 'YES' : 'NO'));
|
||||
error_log("Products table exists: " . ($products_exists ? 'YES' : 'NO'));
|
||||
|
||||
if (!$wheels_exists) {
|
||||
error_log('Wheel of Fortune: Wheels table was not created properly during activation.');
|
||||
} else {
|
||||
error_log('Wheel of Fortune: Wheels table created successfully.');
|
||||
}
|
||||
|
||||
// Izvedi migracijo za is_try_again stolpec
|
||||
$this->migrate_add_is_try_again_column();
|
||||
flush_rewrite_rules();
|
||||
error_log("Wheel of Fortune: Aktivacija končana.");
|
||||
}
|
||||
|
||||
public function deactivate() {
|
||||
wp_clear_scheduled_hook('wof_daily_spin_event');
|
||||
error_log("Wheel of Fortune: Cron job 'wof_daily_spin_event' cleared.");
|
||||
flush_rewrite_rules();
|
||||
}
|
||||
|
||||
|
|
@ -259,54 +265,23 @@ class WheelOfFortune {
|
|||
|
||||
private function create_database_tables() {
|
||||
global $wpdb;
|
||||
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
||||
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
|
||||
// Ustvari tabelo za kolesa
|
||||
$wheels_table = $wpdb->prefix . 'wof_wheels';
|
||||
$wheel_products_table = $wpdb->prefix . 'wheel_of_fortune_products';
|
||||
|
||||
// Debug informacije za tabelo
|
||||
error_log("=== TABLE DEBUG ===");
|
||||
error_log("Wheels table: " . $wheels_table);
|
||||
error_log("Products table: " . $wheel_products_table);
|
||||
|
||||
// Preveri, ali tabela obstaja
|
||||
$wheels_table_exists = $wpdb->get_var("SHOW TABLES LIKE '$wheels_table'") == $wheels_table;
|
||||
error_log("Wheels table exists: " . ($wheels_table_exists ? 'YES' : 'NO'));
|
||||
|
||||
$products_table_exists = $wpdb->get_var("SHOW TABLES LIKE '$wheel_products_table'") == $wheel_products_table;
|
||||
error_log("Products table exists: " . ($products_table_exists ? 'YES' : 'NO'));
|
||||
|
||||
if ($wheels_table_exists) {
|
||||
$wheels_table_structure = $wpdb->get_results("DESCRIBE $wheels_table");
|
||||
error_log("Wheels table structure: " . print_r($wheels_table_structure, true));
|
||||
}
|
||||
|
||||
if ($products_table_exists) {
|
||||
$products_table_structure = $wpdb->get_results("DESCRIBE $wheel_products_table");
|
||||
error_log("Products table structure: " . print_r($products_table_structure, true));
|
||||
}
|
||||
|
||||
$sql_wheels = "CREATE TABLE $wheels_table (
|
||||
// Tabela za spine uporabnikov
|
||||
$table_spins = $wpdb->prefix . 'wheel_spins';
|
||||
$sql_spins = "CREATE TABLE $table_spins (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
name varchar(255) NOT NULL,
|
||||
slug varchar(100) NOT NULL,
|
||||
created_at datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
||||
user_id bigint(20) NOT NULL,
|
||||
wheel_id mediumint(9) NOT NULL DEFAULT 1,
|
||||
spins_available int(11) NOT NULL DEFAULT 0,
|
||||
last_spin_date datetime DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY slug (slug)
|
||||
UNIQUE KEY user_wheel (user_id,wheel_id)
|
||||
) $charset_collate;";
|
||||
|
||||
$sql_products = "CREATE TABLE $wheel_products_table (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
wheel_id mediumint(9) NOT NULL,
|
||||
product_id bigint(20) NOT NULL,
|
||||
spins_per_purchase int(11) NOT NULL DEFAULT 1,
|
||||
created_at datetime DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY wheel_product (wheel_id, product_id)
|
||||
) $charset_collate;";
|
||||
|
||||
// --- 2. Posodobljena tabela za nagrade ---
|
||||
// Tabela za nagrade
|
||||
$table_prizes = $wpdb->prefix . 'wheel_prizes';
|
||||
$sql_prizes = "CREATE TABLE $table_prizes (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
|
|
@ -316,31 +291,24 @@ class WheelOfFortune {
|
|||
probability float NOT NULL,
|
||||
is_active tinyint(1) NOT NULL DEFAULT 1,
|
||||
image_url varchar(255) DEFAULT '',
|
||||
|
||||
-- STARA POLJA ZA EMAIL --
|
||||
email_subject varchar(255) DEFAULT '',
|
||||
email_template text DEFAULT '',
|
||||
|
||||
-- NOVA POLJA --
|
||||
email_template_id mediumint(9) NOT NULL DEFAULT 0, -- 0 pomeni custom email
|
||||
funded_account_name varchar(255) DEFAULT NULL,
|
||||
funded_account_value decimal(12,2) DEFAULT NULL,
|
||||
|
||||
redemption_code varchar(100) DEFAULT '',
|
||||
is_discount tinyint(1) NOT NULL DEFAULT 0,
|
||||
discount_value float DEFAULT 0,
|
||||
is_try_again tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (id),
|
||||
KEY wheel_id (wheel_id)
|
||||
) $charset_collate;";
|
||||
|
||||
// --- 3. Posodobljena tabela za spine (NOVO - spini po kolesih) ---
|
||||
$table_spins = $wpdb->prefix . 'wheel_spins';
|
||||
$sql_spins = "CREATE TABLE $table_spins (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
user_id bigint(20) NOT NULL,
|
||||
wheel_id mediumint(9) NOT NULL DEFAULT 1,
|
||||
spins_available int(11) NOT NULL DEFAULT 0,
|
||||
last_spin_date datetime DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY user_wheel (user_id, wheel_id),
|
||||
KEY user_id (user_id),
|
||||
KEY wheel_id (wheel_id)
|
||||
) $charset_collate;";
|
||||
|
||||
// --- 4. Posodobljena tabela za log (NOVO - log po kolesih) ---
|
||||
// Tabela za dnevnik vrtljajev
|
||||
$table_log = $wpdb->prefix . 'wheel_log';
|
||||
$sql_log = "CREATE TABLE $table_log (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
|
|
@ -349,60 +317,62 @@ class WheelOfFortune {
|
|||
prize_id mediumint(9) NOT NULL,
|
||||
spin_date datetime NOT NULL,
|
||||
redeemed tinyint(1) NOT NULL DEFAULT 0,
|
||||
redemption_code varchar(100) DEFAULT '',
|
||||
PRIMARY KEY (id),
|
||||
KEY user_id (user_id),
|
||||
KEY wheel_id (wheel_id),
|
||||
KEY prize_id (prize_id)
|
||||
) $charset_collate;";
|
||||
|
||||
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
||||
dbDelta($sql_wheels); // Dodajanje nove tabele
|
||||
dbDelta($sql_products);
|
||||
dbDelta($sql_prizes);
|
||||
// Tabela za kolesa
|
||||
$table_wheels = $wpdb->prefix . 'wof_wheels';
|
||||
$sql_wheels = "CREATE TABLE $table_wheels (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
name varchar(255) NOT NULL,
|
||||
description text DEFAULT '',
|
||||
is_active tinyint(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (id)
|
||||
) $charset_collate;";
|
||||
|
||||
// Tabela za izdelke, ki podeljujejo spine
|
||||
$table_products = $wpdb->prefix . 'wheel_of_fortune_products';
|
||||
$sql_products = "CREATE TABLE $table_products (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
wheel_id mediumint(9) NOT NULL DEFAULT 1,
|
||||
product_id bigint(20) NOT NULL,
|
||||
spins_per_purchase int(11) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY wheel_product (wheel_id,product_id)
|
||||
) $charset_collate;";
|
||||
|
||||
// --- DODAJ NOVO TABELO ZA EMAIL PREDLOGE ---
|
||||
$table_email_templates = $wpdb->prefix . 'wheel_email_templates';
|
||||
$sql_email_templates = "CREATE TABLE $table_email_templates (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
name varchar(255) NOT NULL,
|
||||
subject varchar(255) NOT NULL,
|
||||
template_body text NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) $charset_collate;";
|
||||
|
||||
dbDelta($sql_spins);
|
||||
dbDelta($sql_prizes);
|
||||
dbDelta($sql_log);
|
||||
dbDelta($sql_wheels);
|
||||
dbDelta($sql_products);
|
||||
dbDelta($sql_email_templates);
|
||||
|
||||
// Debug: preveri, ali so se tabele ustvarile
|
||||
$wheels_after = $wpdb->get_var("SHOW TABLES LIKE '$wheels_table'") == $wheels_table;
|
||||
$products_after = $wpdb->get_var("SHOW TABLES LIKE '$wheel_products_table'") == $wheel_products_table;
|
||||
|
||||
error_log("After dbDelta - Wheels table exists: " . ($wheels_after ? 'YES' : 'NO'));
|
||||
error_log("After dbDelta - Products table exists: " . ($products_after ? 'YES' : 'NO'));
|
||||
|
||||
if (!$wheels_after) {
|
||||
error_log("Wheel of Fortune: Tabela $wheels_table se ni ustvarila!");
|
||||
} else {
|
||||
error_log("Wheel of Fortune: Tabela $wheels_table uspešno ustvarjena.");
|
||||
}
|
||||
|
||||
if (!$products_after) {
|
||||
error_log("Wheel of Fortune: Tabela $wheel_products_table se ni ustvarila!");
|
||||
} else {
|
||||
error_log("Wheel of Fortune: Tabela $wheel_products_table uspešno ustvarjena.");
|
||||
}
|
||||
|
||||
// Migracija: dodaj stolpec is_try_again v obstoječe tabele
|
||||
$this->migrate_add_is_try_again_column();
|
||||
}
|
||||
|
||||
private function migrate_add_is_try_again_column() {
|
||||
global $wpdb;
|
||||
$table_prizes = $wpdb->prefix . 'wheel_prizes';
|
||||
|
||||
// Preveri, če stolpec is_try_again že obstaja
|
||||
$column_exists = $wpdb->get_results("SHOW COLUMNS FROM $table_prizes LIKE 'is_try_again'");
|
||||
|
||||
if (empty($column_exists)) {
|
||||
// Dodaj stolpec is_try_again
|
||||
$result = $wpdb->query("ALTER TABLE $table_prizes ADD COLUMN is_try_again tinyint(1) NOT NULL DEFAULT 0");
|
||||
if ($result !== false) {
|
||||
error_log("Wheel of Fortune: Stolpec is_try_again uspešno dodan v tabelo $table_prizes");
|
||||
} else {
|
||||
error_log("Wheel of Fortune: Napaka pri dodajanju stolpca is_try_again v tabelo $table_prizes");
|
||||
}
|
||||
} else {
|
||||
error_log("Wheel of Fortune: Stolpec is_try_again že obstaja v tabeli $table_prizes");
|
||||
// Dodaj privzeto kolo, če še ne obstaja
|
||||
$existing_wheel = $wpdb->get_var("SELECT COUNT(*) FROM $table_wheels");
|
||||
if (!$existing_wheel) {
|
||||
$wpdb->insert(
|
||||
$table_wheels,
|
||||
[
|
||||
'name' => __('Default Wheel', 'wheel-of-fortune'),
|
||||
'description' => __('Default wheel of fortune', 'wheel-of-fortune'),
|
||||
'is_active' => 1
|
||||
],
|
||||
['%s', '%s', '%d']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -537,43 +507,51 @@ class WheelOfFortune {
|
|||
|
||||
public function admin_menu() {
|
||||
add_menu_page(
|
||||
__('Wheels of Fortune', 'wheel-of-fortune'),
|
||||
__('Wheels', 'wheel-of-fortune'),
|
||||
'Kolo Sreče',
|
||||
'Kolo Sreče',
|
||||
'manage_options',
|
||||
'wof-wheels', // slug
|
||||
array($this, 'wheels_page'), // callback
|
||||
'wheel-of-fortune',
|
||||
array($this, 'wheels_page'),
|
||||
'dashicons-marker',
|
||||
30
|
||||
);
|
||||
|
||||
// Stran za urejanje posameznega kolesa (skrita iz glavnega menija, dostopna preko linkov)
|
||||
add_submenu_page(
|
||||
'wof-wheels', // parent slug
|
||||
__('Edit Wheel', 'wheel-of-fortune'),
|
||||
__('Edit Wheel', 'wheel-of-fortune'),
|
||||
'wheel-of-fortune',
|
||||
__('Wheels', 'wheel-of-fortune'),
|
||||
__('Wheels', 'wheel-of-fortune'),
|
||||
'manage_options',
|
||||
'wof-edit-wheel',
|
||||
array($this, 'edit_wheel_page')
|
||||
'wheel-of-fortune',
|
||||
array($this, 'wheels_page')
|
||||
);
|
||||
|
||||
// Dodam podstran za nastavitve
|
||||
|
||||
add_submenu_page(
|
||||
'wof-wheels',
|
||||
__('Settings', 'wheel-of-fortune'),
|
||||
__('Settings', 'wheel-of-fortune'),
|
||||
'wheel-of-fortune',
|
||||
__('Statistics', 'wheel-of-fortune'),
|
||||
__('Statistics', 'wheel-of-fortune'),
|
||||
'manage_options',
|
||||
'wof-settings',
|
||||
array($this, 'settings_page')
|
||||
'wheel-stats',
|
||||
array($this, 'stats_page')
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'wheel-of-fortune',
|
||||
__('Users', 'wheel-of-fortune'),
|
||||
__('Users', 'wheel-of-fortune'),
|
||||
'manage_options',
|
||||
'wheel-users',
|
||||
array($this, 'users_page')
|
||||
);
|
||||
|
||||
// Dodaj novo stran za email predloge
|
||||
add_submenu_page(
|
||||
'wheel-of-fortune',
|
||||
__('Email Templates', 'wheel-of-fortune'),
|
||||
__('Email Templates', 'wheel-of-fortune'),
|
||||
'manage_options',
|
||||
'wheel-email-templates',
|
||||
array($this, 'email_templates_page')
|
||||
);
|
||||
|
||||
// Statistika in uporabniki
|
||||
add_submenu_page('wof-wheels', __('Statistics', 'wheel-of-fortune'), __('Statistics', 'wheel-of-fortune'), 'manage_options', 'wof-stats', array($this, 'stats_page'));
|
||||
add_submenu_page('wof-wheels', __('Users & Spins', 'wheel-of-fortune'), __('Users & Spins', 'wheel-of-fortune'), 'manage_options', 'wof-users', array($this, 'users_page'));
|
||||
}
|
||||
|
||||
// Dodam funkcijo za prikaz strani z nastavitvami
|
||||
public function settings_page() {
|
||||
require_once WHEEL_OF_FORTUNE_PLUGIN_DIR . 'admin/settings-page.php';
|
||||
}
|
||||
|
||||
public function wheels_page() {
|
||||
|
|
@ -598,6 +576,10 @@ class WheelOfFortune {
|
|||
include WHEEL_OF_FORTUNE_PLUGIN_DIR . 'admin/users-page.php';
|
||||
}
|
||||
|
||||
public function email_templates_page() {
|
||||
require_once WHEEL_OF_FORTUNE_PLUGIN_DIR . 'admin/email-templates-page.php';
|
||||
}
|
||||
|
||||
public function register_rest_routes() {
|
||||
register_rest_route('wheel-of-fortune/v1', '/spin', array('methods' => 'POST', 'callback' => array($this, 'process_wheel_spin'), 'permission_callback' => 'is_user_logged_in'));
|
||||
register_rest_route('wheel-of-fortune/v1', '/test', array('methods' => 'GET', 'callback' => function() { return new WP_REST_Response(['success' => true, 'message' => 'REST API endpoint is working correctly.'], 200); }, 'permission_callback' => '__return_true'));
|
||||
|
|
@ -655,18 +637,11 @@ class WheelOfFortune {
|
|||
}
|
||||
}
|
||||
|
||||
// Pošlji email samo, če ni "try again" nagrada
|
||||
if (get_option('wheel_send_emails', true) && (!isset($prize['is_try_again']) || $prize['is_try_again'] != 1)) {
|
||||
if (get_option('wheel_send_emails', true)) {
|
||||
$this->send_prize_email($user_id, $prize);
|
||||
}
|
||||
|
||||
$response_data = [
|
||||
'prize' => $prize,
|
||||
'degree' => $degree,
|
||||
'remaining_spins' => $new_spins,
|
||||
'discount_code' => $redemption_code,
|
||||
'is_try_again' => isset($prize['is_try_again']) ? (int)$prize['is_try_again'] : 0
|
||||
];
|
||||
$response_data = [ 'prize' => $prize, 'degree' => $degree, 'remaining_spins' => $new_spins, 'discount_code' => $redemption_code ];
|
||||
|
||||
return new WP_REST_Response(['success' => true, 'data' => $response_data], 200);
|
||||
}
|
||||
|
|
@ -871,8 +846,7 @@ class WheelOfFortune {
|
|||
$text_paths = '';
|
||||
|
||||
// Generate segments and text paths
|
||||
// Updated segment color palette
|
||||
$segment_colors = ['#ff3131', '#7ed957', '#8c52ff', '#ff914d', '#1da3e7'];
|
||||
$segment_colors = ['#00dfe9', '#ff00c4', '#0cf101'];
|
||||
for ($i = 0; $i < $num_prizes; $i++) {
|
||||
$prize = $prizes[$i];
|
||||
$start_angle = $i * $angle;
|
||||
|
|
@ -960,36 +934,34 @@ class WheelOfFortune {
|
|||
}
|
||||
|
||||
public function ajax_save_prize() {
|
||||
check_ajax_referer('wheel_admin_nonce', '_ajax_nonce');
|
||||
check_ajax_referer('wheel_of_fortune_admin', 'nonce');
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error(['message' => __('You do not have permission to perform this action.', 'wheel-of-fortune')]);
|
||||
wp_send_json_error(__('Nimate dovoljenja za to dejanje.', 'wheel-of-fortune'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Dodamo wheel_id
|
||||
$wheel_id = isset($_POST['wheel_id']) ? intval($_POST['wheel_id']) : 0;
|
||||
$prize_id = isset($_POST['prize_id']) ? intval($_POST['prize_id']) : 0;
|
||||
$wheel_id = isset($_POST['wheel_id']) ? intval($_POST['wheel_id']) : 1;
|
||||
$name = isset($_POST['name']) ? sanitize_text_field($_POST['name']) : '';
|
||||
$description = isset($_POST['description']) ? sanitize_textarea_field($_POST['description']) : '';
|
||||
$description = isset($_POST['description']) ? wp_kses_post($_POST['description']) : '';
|
||||
$probability = isset($_POST['probability']) ? floatval($_POST['probability']) : 0;
|
||||
$is_active = isset($_POST['is_active']) ? intval($_POST['is_active']) : 0;
|
||||
$redemption_code = isset($_POST['redemption_code']) ? sanitize_text_field($_POST['redemption_code']) : '';
|
||||
$is_discount = isset($_POST['is_discount']) ? intval($_POST['is_discount']) : 0;
|
||||
$is_active = isset($_POST['is_active']) ? 1 : 0;
|
||||
$image_url = isset($_POST['image_url']) ? esc_url_raw($_POST['image_url']) : '';
|
||||
$email_subject = isset($_POST['email_subject']) ? sanitize_text_field($_POST['email_subject']) : '';
|
||||
$email_template = isset($_POST['email_template']) ? wp_kses_post($_POST['email_template']) : '';
|
||||
$redemption_code = isset($_POST['redemption_code']) ? sanitize_text_field($_POST['redemption_code']) : '';
|
||||
$is_discount = isset($_POST['is_discount']) ? 1 : 0;
|
||||
$discount_value = isset($_POST['discount_value']) ? floatval($_POST['discount_value']) : 0;
|
||||
$is_try_again = isset($_POST['is_try_again']) ? intval($_POST['is_try_again']) : 0;
|
||||
|
||||
// Dodaj nova polja
|
||||
$email_template_id = isset($_POST['email_template_id']) ? intval($_POST['email_template_id']) : 0;
|
||||
$funded_account_name = isset($_POST['funded_account_name']) ? sanitize_text_field($_POST['funded_account_name']) : null;
|
||||
$funded_account_value = isset($_POST['funded_account_value']) ? floatval($_POST['funded_account_value']) : null;
|
||||
|
||||
if (empty($name)) {
|
||||
wp_send_json_error(['message' => __('Prize name is required.', 'wheel-of-fortune')]);
|
||||
}
|
||||
|
||||
if ($wheel_id === 0) {
|
||||
wp_send_json_error(['message' => __('Wheel ID is missing.', 'wheel-of-fortune')]);
|
||||
}
|
||||
|
||||
if ($probability < 0 || $probability > 1) {
|
||||
wp_send_json_error(['message' => __('Probability must be between 0 and 1.', 'wheel-of-fortune')]);
|
||||
wp_send_json_error(__('Ime nagrade je obvezno.', 'wheel-of-fortune'));
|
||||
return;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
|
|
@ -1001,27 +973,37 @@ class WheelOfFortune {
|
|||
'description' => $description,
|
||||
'probability' => $probability,
|
||||
'is_active' => $is_active,
|
||||
'redemption_code' => $redemption_code,
|
||||
'is_discount' => $is_discount,
|
||||
'image_url' => $image_url,
|
||||
'email_subject' => $email_subject,
|
||||
'email_template' => $email_template,
|
||||
'redemption_code' => $redemption_code,
|
||||
'is_discount' => $is_discount,
|
||||
'discount_value' => $discount_value,
|
||||
'is_try_again' => $is_try_again,
|
||||
|
||||
// Dodaj nova polja
|
||||
'email_template_id' => $email_template_id,
|
||||
'funded_account_name' => $funded_account_name,
|
||||
'funded_account_value' => $funded_account_value
|
||||
];
|
||||
|
||||
$format = ['%d', '%s', '%s', '%f', '%d', '%s', '%d', '%s', '%s', '%f', '%d'];
|
||||
$format = ['%d', '%s', '%s', '%f', '%d', '%s', '%s', '%s', '%s', '%d', '%f', '%d', '%s', '%f'];
|
||||
|
||||
if ($prize_id > 0) {
|
||||
// Posodobi obstoječo nagrado
|
||||
$result = $wpdb->update($table_name, $data, ['id' => $prize_id], $format, ['%d']);
|
||||
} else {
|
||||
// Dodaj novo nagrado
|
||||
$result = $wpdb->insert($table_name, $data, $format);
|
||||
$prize_id = $wpdb->insert_id;
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
wp_send_json_error(['message' => $wpdb->last_error]);
|
||||
if ($result !== false) {
|
||||
wp_send_json_success([
|
||||
'id' => $prize_id,
|
||||
'message' => __('Nagrada uspešno shranjena.', 'wheel-of-fortune')
|
||||
]);
|
||||
} else {
|
||||
wp_send_json_success(['message' => __('Prize saved successfully!', 'wheel-of-fortune'), 'prize_id' => $prize_id]);
|
||||
wp_send_json_error(__('Napaka pri shranjevanju nagrade.', 'wheel-of-fortune'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1314,8 +1296,7 @@ class WheelOfFortune {
|
|||
update_post_meta($coupon_id, 'usage_limit_per_user', '1');
|
||||
update_post_meta($coupon_id, 'customer_email', array($user->user_email));
|
||||
update_post_meta($coupon_id, 'description', __('Wheel of Fortune', 'wheel-of-fortune'));
|
||||
// Nastavi veljavnost 10 dni
|
||||
update_post_meta($coupon_id, 'date_expires', strtotime('+10 days'));
|
||||
|
||||
return $coupon_id;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
|
|
@ -1343,9 +1324,12 @@ class WheelOfFortune {
|
|||
$coupon->set_usage_limit(1);
|
||||
$coupon->set_usage_limit_per_user(1);
|
||||
$coupon->set_email_restrictions(array($user->user_email));
|
||||
// Nastavi veljavnost 10 dni
|
||||
$coupon->set_date_expires(strtotime('+10 days'));
|
||||
|
||||
// Dodatna nastavitev
|
||||
$coupon->set_date_expires(strtotime('+30 days'));
|
||||
|
||||
$coupon_id = $coupon->save();
|
||||
|
||||
// Preveri, ali je kupon res ustvarjen
|
||||
if ($coupon_id) {
|
||||
$verification_id = wc_get_coupon_id_by_code($code);
|
||||
|
|
@ -1362,6 +1346,7 @@ class WheelOfFortune {
|
|||
// Metoda 4: Neposredno vstavljanje v podatkovno bazo
|
||||
try {
|
||||
global $wpdb;
|
||||
|
||||
// Ustvari nov post tipa shop_coupon
|
||||
$wpdb->insert(
|
||||
$wpdb->posts,
|
||||
|
|
@ -1376,7 +1361,9 @@ class WheelOfFortune {
|
|||
'post_date_gmt' => current_time('mysql', 1)
|
||||
)
|
||||
);
|
||||
|
||||
$coupon_id = $wpdb->insert_id;
|
||||
|
||||
if ($coupon_id) {
|
||||
// Dodaj meta podatke za kupon
|
||||
$meta_data = array(
|
||||
|
|
@ -1386,10 +1373,9 @@ class WheelOfFortune {
|
|||
'usage_limit' => '1',
|
||||
'usage_limit_per_user' => '1',
|
||||
'customer_email' => serialize(array($user->user_email)),
|
||||
'description' => __('Wheel of Fortune', 'wheel-of-fortune'),
|
||||
// Nastavi veljavnost 10 dni
|
||||
'date_expires' => strtotime('+10 days')
|
||||
'description' => __('Wheel of Fortune', 'wheel-of-fortune')
|
||||
);
|
||||
|
||||
foreach ($meta_data as $meta_key => $meta_value) {
|
||||
$wpdb->insert(
|
||||
$wpdb->postmeta,
|
||||
|
|
@ -1400,6 +1386,7 @@ class WheelOfFortune {
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $coupon_id;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
|
|
@ -1420,9 +1407,8 @@ class WheelOfFortune {
|
|||
$coupon->set_usage_limit(1);
|
||||
$coupon->set_usage_limit_per_user(1);
|
||||
$coupon->set_email_restrictions(array($user->user_email));
|
||||
// Nastavi veljavnost 10 dni
|
||||
$coupon->set_date_expires(strtotime('+10 days'));
|
||||
$coupon_id = $coupon->save();
|
||||
|
||||
if ($coupon_id) {
|
||||
return $coupon_id;
|
||||
}
|
||||
|
|
@ -1443,98 +1429,93 @@ class WheelOfFortune {
|
|||
* @param array $prize The prize details array.
|
||||
*/
|
||||
public function send_prize_email($user_id, $prize) {
|
||||
// Ne pošlji emaila, če je nagrada "try again"
|
||||
if (isset($prize['is_try_again']) && $prize['is_try_again'] == 1) {
|
||||
wheel_of_fortune_debug_log("send_prize_email: Email ni poslan za 'try again' nagrado: {$prize['name']}");
|
||||
return;
|
||||
if (!$user_id || !is_array($prize)) {
|
||||
wheel_of_fortune_debug_log("send_prize_email: Invalid parameters");
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = get_userdata($user_id);
|
||||
if (!$user) {
|
||||
wheel_of_fortune_debug_log("send_prize_email: Uporabnik z ID {$user_id} ni bil najden.");
|
||||
return;
|
||||
wheel_of_fortune_debug_log("send_prize_email: User not found - ID: $user_id");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Določi vsebino emaila - uporabi specifično predlogo za nagrado, če obstaja, sicer splošno
|
||||
$subject = !empty($prize['email_subject'])
|
||||
? $prize['email_subject']
|
||||
: sprintf(__('Congratulations! You won a prize on the Wheel of Fortune - %s', 'wheel-of-fortune'), get_bloginfo('name'));
|
||||
|
||||
$body = !empty($prize['email_template'])
|
||||
? $prize['email_template']
|
||||
: file_get_contents(WHEEL_OF_FORTUNE_PLUGIN_DIR . 'templates/emails/default-prize-email.html');
|
||||
|
||||
// PREVERI, ALI NAGRADA UPORABLJA PREDLOGO
|
||||
if (!empty($prize['email_template_id'])) {
|
||||
global $wpdb;
|
||||
$template_table = $wpdb->prefix . 'wheel_email_templates';
|
||||
$email_template_data = $wpdb->get_row($wpdb->prepare("SELECT * FROM $template_table WHERE id = %d", $prize['email_template_id']), ARRAY_A);
|
||||
|
||||
if ($email_template_data) {
|
||||
$prize['email_subject'] = $email_template_data['subject'];
|
||||
$prize['email_template'] = $email_template_data['template_body'];
|
||||
}
|
||||
}
|
||||
|
||||
// Določi vsebino emaila
|
||||
$email_subject = !empty($prize['email_subject']) ? $prize['email_subject'] : sprintf(__('Congratulations on your prize: %s', 'wheel-of-fortune'), $prize['name']);
|
||||
$email_content = !empty($prize['email_template']) ? $prize['email_template'] : $this->get_default_email_template($prize);
|
||||
|
||||
// Pripravi nadomestne oznake (placeholders)
|
||||
$replacements = [
|
||||
'{user_name}' => $user->display_name,
|
||||
'{user_email}' => $user->user_email,
|
||||
'{prize_name}' => $prize['name'],
|
||||
'{prize_description}' => $prize['description'],
|
||||
'{redemption_code}' => !empty($prize['redemption_code']) ? $prize['redemption_code'] : __('N/A', 'wheel-of-fortune'),
|
||||
'{site_name}' => get_bloginfo('name'),
|
||||
'{site_url}' => home_url(),
|
||||
'{date}' => date_i18n(get_option('date_format')),
|
||||
'{time}' => date_i18n(get_option('time_format')),
|
||||
];
|
||||
'{user_name}' => $user->display_name,
|
||||
'{user_email}' => $user->user_email,
|
||||
'{prize_name}' => $prize['name'],
|
||||
'{prize_description}' => $prize['description'],
|
||||
'{redemption_code}' => !empty($prize['redemption_code']) ? $prize['redemption_code'] : __('N/A', 'wheel-of-fortune'),
|
||||
|
||||
// DODAJ NOVE OZNAČEVALCE
|
||||
'{funded_account_name}' => $prize['funded_account_name'] ?? '',
|
||||
'{funded_account_value}' => isset($prize['funded_account_value']) ? number_format_i18n($prize['funded_account_value'], 0) : '',
|
||||
|
||||
// Zamenjaj oznake v vsebini in zadevi
|
||||
$final_subject = str_replace(array_keys($replacements), array_values($replacements), $subject);
|
||||
$final_body = str_replace(array_keys($replacements), array_values($replacements), $body);
|
||||
|
||||
// Pridobi nastavitve pošiljatelja
|
||||
$from_name = get_option('wheel_email_from_name', get_bloginfo('name'));
|
||||
$from_email = get_option('wheel_email_from_email', get_bloginfo('admin_email'));
|
||||
|
||||
$headers = [
|
||||
'Content-Type: text/html; charset=UTF-8',
|
||||
'From: ' . $from_name . ' <' . $from_email . '>'
|
||||
'{site_name}' => get_bloginfo('name'),
|
||||
'{site_url}' => home_url(),
|
||||
'{date}' => date_i18n(get_option('date_format')),
|
||||
'{time}' => date_i18n(get_option('time_format')),
|
||||
];
|
||||
|
||||
// Preveri, ali je omogočen SMTP
|
||||
if (get_option('wheel_smtp_enabled', false)) {
|
||||
// Pošlji preko SMTP z uporabo PHPMailer
|
||||
require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
|
||||
require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
|
||||
require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
|
||||
|
||||
$mail = new PHPMailer\PHPMailer\PHPMailer(true);
|
||||
try {
|
||||
$mail->isSMTP();
|
||||
$mail->Host = get_option('wheel_smtp_host');
|
||||
$mail->SMTPAuth = !empty(get_option('wheel_smtp_username'));
|
||||
$mail->Username = get_option('wheel_smtp_username');
|
||||
$mail->Password = get_option('wheel_smtp_password');
|
||||
$mail->Port = get_option('wheel_smtp_port', 587);
|
||||
|
||||
$smtp_encryption = get_option('wheel_smtp_encryption', 'tls');
|
||||
if ($smtp_encryption === 'ssl') {
|
||||
$mail->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS;
|
||||
} elseif ($smtp_encryption === 'tls') {
|
||||
$mail->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
|
||||
}
|
||||
|
||||
$mail->setFrom($from_email, $from_name);
|
||||
$mail->addAddress($user->user_email, $user->display_name);
|
||||
|
||||
$mail->isHTML(true);
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->Subject = $final_subject;
|
||||
$mail->Body = $final_body;
|
||||
$mail->AltBody = wp_strip_all_tags($final_body);
|
||||
|
||||
$mail->send();
|
||||
wheel_of_fortune_debug_log("Email uspešno poslan preko SMTP na {$user->user_email}.");
|
||||
|
||||
} catch (Exception $e) {
|
||||
wheel_of_fortune_debug_log("Napaka pri pošiljanju emaila preko SMTP: {$mail->ErrorInfo}");
|
||||
}
|
||||
// Zamenjaj vse oznake
|
||||
$email_subject = str_replace(array_keys($replacements), array_values($replacements), $email_subject);
|
||||
$email_content = str_replace(array_keys($replacements), array_values($replacements), $email_content);
|
||||
|
||||
// Dodaj HTML wrapper, če ga že ni
|
||||
if (strpos($email_content, '<html') === false) {
|
||||
$email_content = $this->get_email_html_wrapper($email_content);
|
||||
}
|
||||
|
||||
// Nastavi naslov za pošiljanje
|
||||
$admin_email = get_option('admin_email');
|
||||
$site_name = get_bloginfo('name');
|
||||
|
||||
$headers = [];
|
||||
$headers[] = 'Content-Type: text/html; charset=UTF-8';
|
||||
$headers[] = "From: {$site_name} <{$admin_email}>";
|
||||
|
||||
// Pošlji email
|
||||
$mail_sent = wp_mail($user->user_email, $email_subject, $email_content, $headers);
|
||||
|
||||
if ($mail_sent) {
|
||||
wheel_of_fortune_debug_log("Email sent to user {$user->user_email} for prize {$prize['name']}");
|
||||
|
||||
// Shrani log
|
||||
global $wpdb;
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'wheel_email_log',
|
||||
[
|
||||
'user_id' => $user_id,
|
||||
'prize_id' => $prize['id'],
|
||||
'email' => $user->user_email,
|
||||
'subject' => $email_subject,
|
||||
'content' => $email_content,
|
||||
'sent_date' => current_time('mysql')
|
||||
],
|
||||
['%d', '%d', '%s', '%s', '%s', '%s']
|
||||
);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// Pošlji preko standardne wp_mail() funkcije
|
||||
if (wp_mail($user->user_email, $final_subject, $final_body, $headers)) {
|
||||
wheel_of_fortune_debug_log("Email uspešno poslan preko wp_mail() na {$user->user_email}.");
|
||||
} else {
|
||||
wheel_of_fortune_debug_log("Napaka pri pošiljanju emaila preko wp_mail().");
|
||||
}
|
||||
wheel_of_fortune_debug_log("Failed to send email to user {$user->user_email} for prize {$prize['name']}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1570,123 +1551,119 @@ class WheelOfFortune {
|
|||
}
|
||||
|
||||
public function ajax_delete_wheel_product() {
|
||||
check_ajax_referer('wof_delete_wheel_product', '_ajax_nonce');
|
||||
|
||||
check_ajax_referer('wof_delete_wheel_product');
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error(['message' => __('You do not have permission to perform this action.', 'wheel-of-fortune')]);
|
||||
wp_send_json_error(__('Nimaš dovoljenja.', 'wheel-of-fortune'));
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
|
||||
|
||||
if (!$id) {
|
||||
wp_send_json_error(['message' => __('Invalid ID.', 'wheel-of-fortune')]);
|
||||
}
|
||||
// Debug informacije
|
||||
error_log("=== AJAX DELETE WHEEL PRODUCT DEBUG ===");
|
||||
error_log("POST data: " . print_r($_POST, true));
|
||||
error_log("ID to delete: " . $id);
|
||||
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'wheel_of_fortune_products';
|
||||
|
||||
$result = $wpdb->delete($table_name, ['id' => $id]);
|
||||
|
||||
if ($result !== false) {
|
||||
wp_send_json_success(['message' => __('Product deleted successfully.', 'wheel-of-fortune')]);
|
||||
} else {
|
||||
wp_send_json_error(['message' => __('Failed to delete product.', 'wheel-of-fortune')]);
|
||||
}
|
||||
}
|
||||
|
||||
public function ajax_migrate_try_again() {
|
||||
check_ajax_referer('wheel_admin_nonce', '_ajax_nonce');
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error(['message' => __('You do not have permission to perform this action.', 'wheel-of-fortune')]);
|
||||
}
|
||||
|
||||
$this->migrate_add_is_try_again_column();
|
||||
|
||||
wp_send_json_success(['message' => __('Migration completed successfully. The is_try_again column has been added to the database.', 'wheel-of-fortune')]);
|
||||
}
|
||||
|
||||
public function ajax_reset_spins_wheel() {
|
||||
check_ajax_referer('wheel_admin_nonce', '_ajax_nonce');
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error(['message' => __('You do not have permission to perform this action.', 'wheel-of-fortune')]);
|
||||
}
|
||||
|
||||
$wheel_id = isset($_POST['wheel_id']) ? intval($_POST['wheel_id']) : 0;
|
||||
|
||||
if (!$wheel_id) {
|
||||
wp_send_json_error(['message' => __('Wheel ID is required.', 'wheel-of-fortune')]);
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$wheels_table = $wpdb->prefix . 'wof_wheels';
|
||||
$spins_table = $wpdb->prefix . 'wheel_spins';
|
||||
|
||||
// Preveri, če kolo obstaja
|
||||
$wheel_exists = $wpdb->get_var($wpdb->prepare("SELECT id FROM $wheels_table WHERE id = %d", $wheel_id));
|
||||
|
||||
if (!$wheel_exists) {
|
||||
wp_send_json_error(['message' => __('Selected wheel does not exist.', 'wheel-of-fortune')]);
|
||||
}
|
||||
|
||||
// Ponastavi spine na 0 za vse uporabnike na tem kolesu
|
||||
$result = $wpdb->update(
|
||||
$spins_table,
|
||||
array('spins_available' => 0),
|
||||
array('wheel_id' => $wheel_id),
|
||||
array('%d'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
if ($result !== false) {
|
||||
wp_send_json_success([
|
||||
'message' => sprintf(__('All spins for wheel ID %d have been successfully reset to 0.', 'wheel-of-fortune'), $wheel_id),
|
||||
'affected_users' => $result
|
||||
]);
|
||||
} else {
|
||||
wp_send_json_error(['message' => __('An error occurred while resetting spins.', 'wheel-of-fortune')]);
|
||||
}
|
||||
}
|
||||
|
||||
// --- NOVE METODE ZA CRON ---
|
||||
public function add_custom_cron_schedules($schedules) {
|
||||
// Lahko pustiš custom interval, če ga uporabljaš še kje drugje, sicer ni potreben
|
||||
// $schedules['every_2_minutes'] = array(
|
||||
// 'interval' => 120,
|
||||
// 'display' => __('Every 2 minutes', 'wheel-of-fortune')
|
||||
// );
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
public function execute_daily_spin_cron() {
|
||||
wheel_of_fortune_debug_log('CRON: "wof_daily_spin_event" triggered.');
|
||||
$wheel_id = get_option('wof_daily_spin_wheel_id');
|
||||
if (empty($wheel_id)) {
|
||||
wheel_of_fortune_debug_log('CRON: No wheel selected for daily spin. Aborting.');
|
||||
return;
|
||||
}
|
||||
$users = get_users(array('fields' => 'ID'));
|
||||
wheel_of_fortune_debug_log('CRON: Found ' . count($users) . ' users to process for wheel ID ' . $wheel_id);
|
||||
foreach ($users as $user_id) {
|
||||
$last_given_meta_key = '_wof_daily_spin_last_given_' . $wheel_id;
|
||||
$last_given_timestamp = get_user_meta($user_id, $last_given_meta_key, true);
|
||||
// Sprememba: 24 ur (23*HOUR_IN_SECONDS)
|
||||
if (empty($last_given_timestamp) || (time() - $last_given_timestamp > 23 * HOUR_IN_SECONDS)) {
|
||||
$ok = wheel_of_fortune_add_spins($user_id, 1, $wheel_id);
|
||||
if ($ok) {
|
||||
update_user_meta($user_id, $last_given_meta_key, time());
|
||||
wheel_of_fortune_debug_log("CRON: Assigned spin to user $user_id for wheel $wheel_id. Result: " . var_export($ok, true));
|
||||
} else {
|
||||
wheel_of_fortune_debug_log("CRON: Failed to assign spin to user $user_id for wheel $wheel_id.");
|
||||
}
|
||||
} else {
|
||||
wheel_of_fortune_debug_log("CRON: User $user_id already received a spin recently. Skipping.");
|
||||
if ($id > 0) {
|
||||
$table = $wpdb->prefix . 'wheel_of_fortune_products';
|
||||
error_log("Table: " . $table);
|
||||
|
||||
$result = $wpdb->delete($table, ['id' => $id], ['%d']);
|
||||
error_log("Delete result: " . $result);
|
||||
error_log("Last SQL query: " . $wpdb->last_query);
|
||||
error_log("Last SQL error: " . $wpdb->last_error);
|
||||
|
||||
if ($result !== false) {
|
||||
wp_send_json_success();
|
||||
}
|
||||
}
|
||||
wp_send_json_error(__('Napaka pri brisanju.', 'wheel-of-fortune'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Vrne privzeto email predlogo za nagrado
|
||||
*
|
||||
* @param array $prize Podatki o nagradi
|
||||
* @return string HTML vsebina email predloge
|
||||
*/
|
||||
private function get_default_email_template($prize) {
|
||||
$template_path = WHEEL_OF_FORTUNE_PLUGIN_DIR . 'templates/emails/default-prize-email.html';
|
||||
|
||||
if (file_exists($template_path)) {
|
||||
return file_get_contents($template_path);
|
||||
} else {
|
||||
// Če datoteka ne obstaja, vrni osnovno HTML predlogo
|
||||
return '
|
||||
<h2>Čestitamo, {user_name}!</h2>
|
||||
<p>Uspešno ste zadeli nagrado na našem kolesu sreče.</p>
|
||||
<p><strong>Nagrada:</strong> {prize_name}</p>
|
||||
<p>{prize_description}</p>
|
||||
' . (isset($prize['funded_account_name']) ? '<p><strong>Račun:</strong> {funded_account_name}</p>' : '') . '
|
||||
' . (isset($prize['funded_account_value']) ? '<p><strong>Vrednost:</strong> {funded_account_value}</p>' : '') . '
|
||||
' . (!empty($prize['redemption_code']) ? '<p><strong>Koda za unovčitev:</strong> {redemption_code}</p>' : '') . '
|
||||
<p>Hvala za sodelovanje!</p>
|
||||
<p>Lep pozdrav,<br>{site_name}</p>
|
||||
';
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
/**
|
||||
* Ovije vsebino emaila v HTML wrapper
|
||||
*
|
||||
* @param string $content Vsebina emaila
|
||||
* @return string Vsebina z HTML wrapperjem
|
||||
*/
|
||||
private function get_email_html_wrapper($content) {
|
||||
return '
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Kolo sreče - Nagrada</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; }
|
||||
h1, h2 { color: #0066cc; }
|
||||
.footer { margin-top: 30px; font-size: 12px; color: #666; border-top: 1px solid #eee; padding-top: 10px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
' . $content . '
|
||||
</div>
|
||||
<div class="footer">
|
||||
<p>© ' . date('Y') . ' ' . get_bloginfo('name') . ' - Vsi pravice pridržane.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler za pridobivanje podatkov o email predlogi
|
||||
*/
|
||||
public function ajax_get_template_details() {
|
||||
check_ajax_referer('wheel_admin_nonce', '_ajax_nonce');
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error(['message' => __('You do not have permission to perform this action.', 'wheel-of-fortune')]);
|
||||
}
|
||||
|
||||
$template_id = isset($_POST['template_id']) ? intval($_POST['template_id']) : 0;
|
||||
|
||||
if (!$template_id) {
|
||||
wp_send_json_error(['message' => __('Template ID was not provided.', 'wheel-of-fortune')]);
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'wheel_email_templates';
|
||||
|
||||
$template = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $template_id), ARRAY_A);
|
||||
|
||||
if (!$template) {
|
||||
wp_send_json_error(['message' => __('Template not found.', 'wheel-of-fortune')]);
|
||||
}
|
||||
|
||||
wp_send_json_success($template);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize plugin
|
||||
|
|
|
|||
Loading…
Reference in New Issue