Canlı · durum OK
Dokümantasyon · OW Agenda v1.3.1

OW Agenda
Dokümantasyon

Randevu aralıklarını boş yere kimseye kaptırmayan WordPress randevu sistemi.

v1.3.1GPL-2.0-or-laterDokümantasyon

OW Agenda — Dokümantasyon

Online randevu alma ve günlük ajanda, WordPress içinde, aboneliksiz. Yazar: OptionWeb — Julien Daniel Eklenti sayfası: https://optionweb.dev/tr/addons/ow-agenda/ Lisans: GPL-2.0-or-later Bu belgenin kapsadığı sürüm: 1.3.1


İçindekiler

  1. Genel bakış
  2. Kurulum
  3. Hızlı başlangıç
  4. Rezervasyon akışı
  5. E-posta ile çift doğrulama
  6. Taleplerin onaylanması
  7. Ajanda sayfası
  8. Müşteri rehberi
  9. Seans davetleri
  10. E-postalar ve takvim dosyası (ICS)
  11. Hatırlatmalar ve zamanlanmış görev
  12. Anti-spam ve hız sınırları
  13. GDPR
  14. Shortcode'lar
  15. REST API
  16. Ayarlar referansı
  17. Saklanan veriler
  18. Uluslararasılaştırma
  19. Kaldırma
  20. Sorun giderme
  21. SSS
  22. Changelog

Genel bakış

OW Agenda, WordPress'e eksiksiz bir randevu sistemi ekler: ziyaretçinin önce gününü, sonra saatini seçtiği herkese açık bir sayfa ve girişle korunan, telefondan kullanılmak üzere tasarlanmış, günü yönettiğiniz bir «Ajanda» sayfası.

Her şey sitenin içinde kalır. Dış servis yok, üçüncü taraf API yok, abonelik yok: aralıklar sizin sunucunuz tarafından hesaplanır, randevular sizin MySQL tablolarınızda yaşar, e-postalar wp_mail() ile gider.

Pakette gelenler (hepsi ücretsiz, GPL-2):

  • Online rezervasyon: gün seçimi, aralık seçimi, kısa form, GDPR onay kutusu
  • E-posta ile çift onay: bir talep, ancak bir doğrulama bağlantısına tıklandıktan sonra gerçek olur — botlar ajandaya asla ulaşamaz
  • Manuel onay (önerilen) veya otomatik onay; bildirim e-postasının içinde doğrudan Onayla / Reddet düğmeleri (HMAC imzalı bağlantılar, giriş gerektirmez)
  • Mobil öncelikli «Ajanda» sayfası: günün görünümü, bekleyen talepler, elle eklenen telefon randevuları, aralık bloklama, yeniden planlama, yapıldı / gelmedi durumları
  • Müşteri rehberi: arama, oluşturma, düzenleme, silme; onaylanan randevulardan otomatik olarak beslenir
  • Seans davetleri: gizli bir bağlantı, mevcut bir müşterinin seansının tarihini, sizin belirlediğiniz bir hizmet ve süre üzerinden seçmesini sağlar
  • ICS ekli özenli HTML e-postalar (tek hareketle telefonun takvimine ekleme), bir gün önce otomatik hatırlatma, müşterinin online iptali
  • Geçmiş randevuların otomatik anonimleştirilmesi, hiç doğrulanmamış taleplerin temizlenmesi
  • owag/v1 ad alanı altında eksiksiz REST API

Bilerek yapmadıkları:

  • Online ödeme yok: OW Agenda randevuyu alır, kapora tahsil etmez (ihtiyacınız buysa WooCommerce kullanın)
  • Tek bir ajanda: çoklu uzman veya çoklu kaynak yönetimi yok; eklenti bir programı, sitenin programını tarif eder
  • Çift yönlü senkronizasyon yok (Google Takvim veya Outlook ile): müşterinin takvimi ICS dosyasıyla güncellenir (tek yön), sizin kişisel müsaitsizlikleriniz blokaj olarak girilir
  • Ziyaretçi tarafında hizmet kataloğu yok: herkese açık rezervasyon tek bir hizmet üzerinedir (adı ve süresi ayarlanabilir); diğer hizmetler seans davetlerinden geçer
  • Tekrarlayan randevu yok, görüntülü görüşme yok, bekleme odası yok

Bu liste bir mimari tercihtir, gizlenmiş bir yol haritası değil: aralığı asla şaşırmayan basit bir ajanda, kimsenin dokunmaya cesaret edemediği bir dev makineden iyidir.


Kurulum

.zip dosyasından

  1. ow-agenda-1.3.1.zip dosyasını https://optionweb.dev/tr/addons/ow-agenda/ adresinden indirin
  2. Eklentiler → Yeni Ekle → Eklenti Yükle
  3. Dosyayı seçin, Şimdi Kur'a, ardından Etkinleştir'e tıklayın

FTP ile

Arşivi açın ve ow-agenda klasörünü /wp-content/plugins/ içine bırakın, ardından eklentiyi Eklentiler ekranından etkinleştirin.

Gereksinimler

  • WordPress 6.3 veya üzeri
  • PHP 7.4 veya üzeri (8.1+ önerilir)
  • MySQL 5.7+ / MariaDB 10.2+ — eşzamanlı rezervasyonları sıraya sokmak için GET_LOCK() / RELEASE_LOCK() fonksiyonları kullanılır
  • Çalışan bir e-posta gönderimi. Eklentinin tek gerçek bağımlılığı budur: tüm akış (doğrulama, onay, hatırlatma, iptal) e-postadan geçer. Paylaşımlı bir hostingde, ajandayı yayına almadan önce bir SMTP eklentisi kurun.

Kurulanlar

Etkinleştirmede OW Agenda üç tablo oluşturur:

Tabloİçerik
{prefix}_owag_appointmentsAjandadaki tüm kayıtlar: web görüşmeleri, bir davetten doğan seanslar, elle girilen randevular, aralık blokajları
{prefix}_owag_invites«seansınızın tarihini seçin» gizli bağlantıları
{prefix}_owag_customersMüşteri rehberi

…ve yalnızca ilk seferde yayımlanmış iki sayfa:

  • «Randevu al»[ow_agenda] shortcode'unu içerir
  • «Ajanda»[ow_agenda_admin] shortcode'unu içerir

Kimlikleri owag_page_booking ve owag_page_admin seçeneklerinde saklanır; owag_pages_created bayrağı, devre dışı bırakıp yeniden etkinleştirmenin kopya sayfa oluşturmamasını garanti eder. Bu sayfaları yeniden adlandırabilir, bir menüye taşıyabilir, kalıcı bağlantılarını değiştirebilirsiniz: eklenti onları ID'lerinden izler.

Etkinleştirme ayrıca şunları ekler:

  • yönetici rolüne owag_manage yetkisi — ajandayı ve yönetim REST rotalarını açan, manage_options değil, bu yetkidir;
  • owag_settings seçeneğine varsayılan ayarlar;
  • saatlik zamanlanmış görev owag_hourly_event (ilk çalıştırma, etkinleştirmeden 5 dakika sonra).

Bir HMAC gizli anahtarı (owag_admin_secret, 64 karakter, otomatik yüklenmez) ilk yönetici bildiriminde üretilir: e-postalardaki Onayla / Reddet düğmelerini imzalayan odur.

Erişimi başka birine vermek

Ajanda sayfası, owag_manage yetkisine sahip her giriş yapmış kullanıcı tarafından görülebilir. Sitenin anahtarlarını vermeden bir asistana ajandayı açmak için:

// À exécuter une fois (mu-plugin, ou plugin de gestion des rôles).
$role = get_role( 'editor' );
if ( $role ) { $role->add_cap( 'owag_manage' ); }

Hızlı başlangıç

Etkinleştirmenin ardından OW Agenda menüsüne gidin (yönetim panelinin ana menüsü). Ayarlar ekranı tek bir sayfaya sığar; beş dakika yeterlidir.

1. Çalışma saatleri

Haftanın her günü için bir aralık (09:00 → 18:00) ve öğle arası veriyorsanız ikinci bir aralık (14:00 → 18:30) girin. Boş bırakılan bir gün, kapalı bir gündür. Varsayılan: pazartesiden cumaya 09:00–18:00; cumartesi ve pazar kapalı.

Saatler sitenin saat diliminde yorumlanır (Ayarlar → Genel → Zaman dilimi). Rezervasyonu açmadan önce bunu doğrulayın: tüm tarihler yerel saatle saklanır.

2. Online rezerve edilebilir hizmet

  • Görüşmenin adı — ziyaretçinin bileşenin başlığında gördüğü şey («Görüşme», «İlk randevu», «Değerlendirme»…)
  • Görüşme süresi — varsayılan 60 dakika. Ajandada bloke edilen süre budur.
  • Aralık adımı — önerilen iki saat arasındaki fark (varsayılan 30 dakika). 60 dakikalık bir süre ve 30 dakikalık bir adımla 9:00, 9:30, 10:00… önerirsiniz; 9:30'a alınan ilk randevu 9:00 ve 10:00'u listeden çıkarır.
  • İki randevu arasındaki tampon — her aday aralığın iki yanına eklenen nefes alma dakikaları (varsayılan 0).

3. Süreler

  • Minimum rezervasyon süresi — varsayılan 24 saat: bir ziyaretçi bir saat sonrasına randevu alamaz.
  • Rezervasyon ufku — varsayılan 60 gün: ötesinde hiçbir şey önerilmez.
  • Müşterinin online iptali — randevudan en geç 24 saat öncesine kadar; bu süre geçtikten sonra iptal sayfası telefon etmeye yönlendirir.

4. Onay ve e-postalar

  • Taleplerin onaylanması: manuel onay (önerilir) veya otomatik onay.
  • E-posta ile çift doğrulama: işaretli bırakın. Eklentinin en iyi bot koruması budur.
  • Yönetici bildirimlerinin gönderileceği adres: sizin adresiniz. Varsayılan olarak sitenin yönetim e-postası.

Kaydedin, ardından «Randevu al» sayfasını açın: bileşen önümüzdeki 14 günü ve boş aralıklarınızı gösterir. Yayındasınız.

5. Telefonda ajanda

«Ajanda» sayfasını telefonunuzda açın, giriş yapın, ardından **«Ana ekrana ekle»**yi kullanın. Eklenti bir uygulama manifestosu yayımlar: sayfa o andan itibaren tarayıcı çubuğu olmadan, tam ekran, bir uygulama gibi açılır.


Rezervasyon akışı

Ziyaretçi tarafında rezervasyon sayfası bağımsız bir bileşendir (framework kullanmayan JavaScript, 10 KB'ın altında) ve owag/v1/public/* herkese açık endpoint'leriyle konuşur.

Adım 1 — gün

Yüklenmede bileşen, bugünden itibaren 14 günlük uygunluğu ister ve tıklanabilir bir gün şeridi gösterir. Boş aralığı olmayan bir gün soluklaştırılır ve tıklanamaz. «Sonraki tarihleri gör» düğmesi sonraki 14 günü yükler; yapılandırılan ufka kadar, gerektiği sayıda.

Bileşendeki tarihler tarayıcının yerel saatiyle kurulur, asla UTC ile değil. Bu, 1.3.0'da yapılan bir düzeltmedir: daha önce, UTC'nin doğusundaki bir ziyaretçi sayfayı gece yarısından kısa süre sonra açtığında listeyi bir gün önceden başlar görüyor ve bir günlük uygunluğu kaybediyordu.

Adım 2 — saat

Bir güne tıklamak /public/slots çağrısını yapar ve boş başlangıç saatlerini gösterir. Bir aralık ancak tüm şu koşullar sağlandığında önerilir:

  1. ilgili günün bir çalışma aralığına düşüyorsa;
  2. randevunun tamamı (başlangıç + süre) kapanıştan önce bitiyorsa;
  3. şimdi + minimum süre değerinden sonra başlıyorsa;
  4. gün rezervasyon ufkunun içindeyse;
  5. tampon dahil hiçbir aktif kayıtla çakışmıyorsa — ve «aktif kayıt», onaylanmış randevuları, bekleyen talepleri, blokajları, elle girilen telefon randevularını ve aralığını hâlâ tutan, henüz doğrulanmamış talepleri kapsar.

Önemli nokta budur: ajandayı meşgul eden her şey online aralığı kapatır. Telefonda alınıp ajandaya not edilen bir randevu, sitede önerilen aralıklardan anında kaybolur.

Adım 3 — form

Üçü zorunlu dört alan: ad (en az 2 karakter), telefon (en az 8 rakam), e-posta (doğrulanır), serbest mesaj. Varsayılan olarak işaretli olmayan bir GDPR onay kutusu zorunludur.

Form ayrıca ziyaretçinin göremediği iki alan taşır — bir bot tuzağı ve sayfanın açılış zaman damgası —; bunlar Anti-spam bölümünde anlatılıyor.

Adım 4 — yanıt

Yapılandırmanıza göre üç sonuç:

YapılandırmaOluşan durumGösterilen mesaj
E-posta ile çift doğrulama açık (varsayılan)unverified«Son bir adım: az önce size bir e-posta gönderildi…»
Doğrulama kapalı + manuel onaypending«Talebiniz alındı!»
Doğrulama kapalı + otomatik onayconfirmed«Randevunuz onaylandı!»

Aralık, liste gösterildikten sonra ama form gönderilmeden önce alınmışsa, ziyaretçi açık bir mesaj alır (owag_slot_taken, HTTP 409) ve gün listesi otomatik olarak yeniden yüklenir. İki ziyaretçi aynı aralığı alamaz: kritik bölüm, veritabanınıza ve tablo önekinize özgü adlandırılmış bir MySQL kilidiyle sıraya sokulur; bu, paylaşımlı bir hostingde bile geçerlidir.


E-posta ile çift doğrulama

OW Agenda'yı kılık değiştirmiş bir iletişim formundan ayıran özellik budur.

E-posta ile çift doğrulama açıkken (email_verify ayarı, varsayılan olarak açık):

  1. Talep unverified durumuyla kaydedilir. Yöneticiye bildirim gitmez. Randevu, işlenecek bir talep olarak görünmez.
  2. Ziyaretçi, içinde bir doğrulama düğmesi bulunan «Son bir adım…» e-postasını alır.
  3. Aralık 45 dakika tutulur. Bu sürenin sonunda doğrulama gelmezse aralık herkes için yeniden uygun hâle gelir — yani bir bot gününüzü donduramaz.
  4. Düğmeye tıklamak, randevunun özetini ve «Talebimi onaylıyorum» düğmesini gösteren bağımsız bir sayfa (?owag_verify=<uid>) açar. Doğrulama yalnızca tıklamayla gönderilir: e-postalardaki URL'leri ziyaret eden antivirüsler ve bağlantı tarayıcıları hiçbir şeyi doğrulamaz.
  5. Talep bunun ardından pending (manuel onay) veya confirmed (otomatik onay) olur, müşteri ilgili e-postayı alır ve yönetici bildirimi ancak o zaman gönderilir.
  6. Hiç doğrulanmamış talepler, saatlik görev tarafından 48 saat sonra silinir. Geride ne bir iz ne de kişisel bir veri bırakırlar.

Gönderimle tıklama arasında aralık başkası tarafından alınmışsa (45 dakikalık pencere geçmişse), doğrulama açık bir hata döndürür ve talep iptal edilir — dolu bir aralıkta asla hayalet randevu oluşmaz.

Pratik sonuç: geçersiz bir e-posta adresi hiçbir randevu üretmez. Uydurma numaraları geri aramakla vakit kaybetmezsiniz. Bedeli, müşteri için fazladan bir tıklamadır; deneyim, vazgeçme oranının bu sayede önlenen sahte randevu oranından çok daha düşük olduğunu gösteriyor.

Bir seans davetinden gelen rezervasyonlar bu adımı atlar: müşteri, aldığı gizli bağlantıya tıklayarak e-postasını okuduğunu zaten kanıtlamıştır.


Taleplerin onaylanması

Manuel onay (önerilir)

Varsayılan ayar: auto_confirm = 0. Doğrulanmış bir talep pending durumuyla gelir. Siz bir şey yapana kadar müşteriye hiçbir söz verilmez — ama aralık şimdiden bloke edilmiştir, kimse sizi geçemez.

«Onay bekliyor: <müşteri> — » başlıklı, eksiksiz özeti (hizmet, tarih, ad, telefon, e-posta, müşterinin mesajı) ve iki düğmeyi içeren bir e-posta alırsınız:

  • Randevuyu onayla — camgöbeği
  • Reddet — kırmızı çerçeveli

E-postadaki düğmeler: HMAC imzalı bağlantılar

Bu düğmeler hiçbir giriş istemez. Sitenize üç parametreyle işaret ederler: owag_admin_action (confirm veya refuse), uid (randevunun rastgele kimliği) ve sig; yani sitenin gizli anahtarıyla (owag_admin_secret) hesaplanan uid|action değerinin HMAC-SHA256 imzası.

  • İmza, en küçük ayrıntı gösterilmeden önce doğrulanır: kurcalanmış bir bağlantı «Geçersiz bağlantı» dışında hiçbir şey göstermez.
  • Karşılaştırma hash_equals() ile yapılır — yanıt süresinden bilgi sızmaz.
  • Sayfa bir özet ve bir düğme gösterir; işlem yalnızca tıklamayla yürütülür. Yani bir bağlantı tarayıcısı sizin yerinize hiçbir şeyi onaylamaz.
  • Zaten işlenmiş bir talep, bir hata yerine «Zaten işlendi (durum: …)» döndürür.

Onaylamak, takvim dosyasıyla birlikte onay e-postasını otomatik olarak müşteriye gönderir. Reddetmek iptal e-postasını gönderir. Her iki durumda da siz telefonunuzu cebinize koymadan ajanda güncellenmiş olur.

Bu bağlantılar, randevu beklemede olduğu sürece geçerli kalır. owag_admin_secret seçeneğini silerseniz (kısmi veritabanı geri yükleme, elle temizlik), gönderilmiş tüm bağlantılar çalışmayı bırakır: yeni bir gizli anahtar üretilir ve eski imzalar artık eşleşmez. Bu durumda Ajanda sayfasını kullanın.

Otomatik onay

auto_confirm = 1 ayarı. Boş bir aralık anında onaylanır: müşteri takvim dosyasıyla onayını alır, siz «Yeni randevu» bildirimini alırsınız. Her açık aralığın kabul edilebilir olduğu işler için uygundur.

Bu iki ayar çift doğrulamayla birleşir: otomatik onayda bile, email_verify açıksa talep önce unverified durumundan geçer.


Ajanda sayfası

«Ajanda» sayfası ([ow_agenda_admin]) her günkü araçtır. Önce telefon için tasarlanmıştır: geniş düğmeler, tek sütun, yatay kaydırılacak tablo yok; elbette bir bilgisayar ekranında da aynı derecede iyi çalışır.

Korumalıdır: giriş yapmamış bir ziyaretçi bir giriş bağlantısı görür, owag_manage yetkisi olmadan giriş yapmış bir kullanıcı «Erişim ekibe ayrılmıştır» mesajını görür. Sayfa noindex,nofollow işaretlidir: Google'a asla düşmez.

Ajanda sekmesi — günün görünümü

İçinde bulunulan gün, kayıt kayıt; saat, süre, etiket, durum ve kaynak (site, davet, elle giriş) ile birlikte. Günler arası gezinme ve Bugün düğmesi. Her randevunun üzerinde:

  • Ayrıntılar — müşterinin iletişim bilgileri, rezervasyon sırasında bıraktığı mesaj ve hiçbir e-posta gönderilmeden kaydedilen bir dahili not alanı (müşteri tarafından asla görülmez)
  • Onayla ✓ — hâlâ bekleyen bir talep için; onay e-postası gider
  • Yapıldı / Gelmedi (no-show) — randevu sonu durumları
  • Ertele — yeni tarih, yeni saat, gerekirse değiştirilmiş süre. Eklenti müşterinin e-postayla bilgilendirilmesi gerekip gerekmediğini sorar; evet derseniz müşteri güncel bir onay ve telefonunda hâlihazırda bulunan etkinliği düzelten bir takvim dosyası alır
  • Randevuyu iptal et — burada da müşteriyi bilgilendirip bilgilendirmeme seçeneğiyle
  • Blokajı kaldır — bloke edilmiş bir aralık için

Bir işlem çakışma yarattığında (dolu bir aralığa erteleme), eklenti uyarır ve onay ister: zorlayabilirsiniz. Bu sizin programınız, ne yaptığınızı biliyorsunuz — koruma yalnızca ziyaretçiler için engelleyicidir.

Randevu veya blokaj eklemek

«Randevu ekle» düğmesi, iki işe yarayan tek bir form açar:

  • Randevu — müşteri sizi aradı. Ad, telefon, e-posta (isteğe bağlı), hizmet, tarih, saat, süre, dahili notlar. Bir e-posta adresi girer ve ilgili seçeneği işaretlerseniz, müşteri online rezervasyon yapmış gibi takvim dosyasıyla onayını alır. Randevu ayrıca müşteri rehberini de besler.
  • Blokaj (izin, mola…) — bir gerekçe, bir tarih, bir saat, bir süre. E-posta yok, müşteri kaydı yok, ama aralık online rezervasyondan anında kaybolur. Bir haftalık izin, bir eğitim ya da rezerve edilmesini istemediğiniz öğle aralığı böyle konur.

Bekleyenler sekmesi

Kararınızı bekleyen doğrulanmış taleplerin listesi, tüm günler bir arada (geçmiş randevular hariç). Satır başına iki düğme: Onayla ve Reddet. Sabah ilk açılacak ekran budur.

İpucu: ajanda bir uygulama olarak

Ajanda sayfasında eklenti, sitenin adı, simgesi ve tema rengiyle bir web uygulaması manifestosu (?owag_manifest=1) bildirir. Hem Android'de hem iOS'ta tarayıcı menüsü o zaman «Ana ekrana ekle» seçeneğini sunar: bir simge, tam ekran bir açılış ve bir daha asla URL yazma zorunluluğu.


Müşteri rehberi

Ajanda sayfasının üçüncü sekmesi, bilerek asgari tutulmuş hafif bir rehberdir: ad, telefon, e-posta, serbest notlar.

  • Kendiliğinden dolar. Bir randevu onaylandığı anda (doğrulanmış online rezervasyon, davetli seans, elle giriş), müşteri önce e-postasından, sonra telefonundan mevcut bir kartla eşleştirilir. Kart yoksa oluşturulur; varsa yalnızca boş alanlar tamamlanır — eklenti elle girdiğiniz hiçbir şeyin üzerine yazmaz.
  • Arama: ad, telefon veya e-posta üzerinden (en fazla 200 kart gösterilir).
  • Elle oluşturma ve düzenleme; geçmiş, tercihler ve dikkat edilecekler için bir not alanıyla.
  • Kart başına iki kısayol: Yeni randevu (elle giriş formunu ön doldurur) ve Seans için davet et (daveti ön doldurur).
  • Bir kartın silinmesi: geçmiş randevular ajandada kalır, yalnızca rehberdeki kart kaybolur.

Bu rehber bir CRM değildir ve öyle olma iddiasında da değildir. Tek bir soruya cevap verir: «Saat 14'teki hanım kimdi?»


Seans davetleri

Kullanım durumu: mevcut bir müşterinin bir seans hakkı var — bir takip, bir rötuş, başka bir yerde satılmış bir hizmet — ve tarihini herkese açık rezervasyondan geçmeden, sizin belirlediğiniz bir hizmet ve süre üzerinden seçmesini istiyorsunuz.

Davetler sekmesinden:

  1. Müşterinin adını, seansın başlığını (zorunlu), süresini (15 ila 720 dakika) ve isterseniz e-postasını ve telefonunu girin.
  2. Bağlantının geçerlilik süresini seçin: varsayılan 60 gün, 1 ile 365 arasında.
  3. İsterseniz «Bağlantıyı müşteriye e-postayla gönder» kutusunu işaretleyin — müşteri, başlığı, süreyi, son geçerlilik tarihini ve bir düğmeyi içeren «Seansınızın tarihini seçin» e-postasını alır.
  4. Aksi hâlde bağlantıyı kopyalayıp SMS, WhatsApp ya da telefonun yerel paylaşım düğmesiyle gönderin.

Bağlantı, gizli bir jetonla (?owag_invite=<token>, kriptografik bir üreticiden çıkan 32 onaltılık karakter) rezervasyon sayfanıza işaret eder. Bileşen o zaman standart görüşmeyi değil, seansın başlığını ve süresini gösterir. Müşteri aynı kısa formu doldurur.

Bir davet bağlantısını yöneten kurallar:

  • Tek kullanımlık. Seans rezerve edildikten sonra bağlantı «Bu bağlantı zaten kullanılmış» yanıtını verir (HTTP 410). Aynı jetonla iki eşzamanlı açılış iki seans oluşturamaz: jetonun tüketilmesi, aralığın rezervasyonuyla aynı kilit altında yapılır.
  • Tarihli. Süre dolduktan sonra bağlantı, sizinle yeniden iletişime geçmeye yönlendirir (HTTP 410).
  • Çift onaysız. Müşteri bu bağlantıyı, sizin kontrol ettiğiniz bir kanaldan zaten aldı: seans doğrudan confirmed olarak, onay ve takvim dosyasıyla oluşturulur.
  • İptalde geri kazanılır. Seans iptal edilirse (sizin ya da müşterinin tarafından), davet serbest bırakılır: bağlantı yeniden etkinleşir ve davet, açık davetler listesinde yeniden görünür. Bu, 1.3.0'da yapılan bir düzeltmedir — daha önce bir iptal bağlantıyı kalıcı olarak öldürüyordu ve yenisini oluşturmak gerekiyordu.
  • Geri alınabilir. Bir daveti listeden silmek bağlantıyı anında devre dışı bırakır.

E-postalar ve takvim dosyası (ICS)

İşlemsel e-postalar

Tüm mesajlar HTML'dir ve Gmail ile Outlook uyumlu, tablo tabanlı bir düzen kullanır: açık zemin üzerinde beyaz kart, başlıkta sitenin adı, camgöbeği çizgili özet kutusu, hap biçimli düğmeler. wp_mail() ile gönderilirler, dolayısıyla SMTP yapılandırmanıza ve alışılmış WordPress filtrelerine uyarlar.

E-postaAlıcıTetikleyici
Talep doğrulamaMüşteriÇift doğrulama açıkken yapılan web rezervasyonu
Talep alındıMüşteriDoğrulanmış talep, kararınızı bekliyor
Randevu onaylandıMüşteriOnay (manuel, otomatik, yönetici girişi, erteleme) — ICS ekiyle
Randevu iptal edildiMüşteriMüşterinin iptali, yöneticinin reddi veya iptali — iptal ICS ekiyle
HatırlatmaMüşteriOtomatik olarak, randevudan 12 ila 36 saat önce
Seansınızın tarihini seçinMüşteriE-posta gönderimi seçilerek bir davet oluşturulması
Onay bekliyor: …YöneticiBekleyen yeni doğrulanmış talep — Onayla / Reddet düğmeleriyle
Yeni randevu: …YöneticiOnaylanmış yeni randevu (otomatik onay, davet)
Müşteri iptali: …YöneticiMüşteri kendi e-postasından iptal etti

Yönetici bildirim adresi notify_email ayarıdır (varsayılan olarak sitenin yönetim e-postası). Müşteri e-postaları yalnızca adres geçerliyse gider ve bir aralık blokajı için asla gönderilmez.

Onay ve iptal e-postaları müşteriye, gerçekte yapılandırılmış ön bildirim saatiyle birlikte online iptal edebileceğini hatırlatır.

ICS eki

Onaylara eklenen .ics dosyası, bir e-postayı müşterinin telefonunda gerçekten var olan bir randevuya dönüştüren şeydir: eke tek bir dokunuş, ve etkinlik kendi hatırlatmasıyla birlikte takvimindedir.

Dosya RFC 5545 uyumludur ve takvim istemcilerinin (Google, Outlook, Apple) güncellemeleri doğru işlemesi için gerekenleri içerir:

  • oluşturmada ve her saat revizyonunda METHOD:REQUEST, iptalde METHOD:CANCEL;
  • randevunun kimliğinden ve sitenin alan adından türetilen kararlı bir UID — bir revizyonun ikinci bir etkinlik yaratmak yerine mevcut etkinliğin yerini almasını sağlayan budur;
  • son değişiklik tarihinden, mutlak bir ana indirgenerek türetilen artan bir SEQUENCE: kış saatine geçiş revizyon numarasını geriye alamaz (ve iptal, aynı saniye içinde olmuş bir revizyondan büyük kalmak için 1 ekler);
  • ORGANIZER (sizin bildirim adresiniz) ve ATTENDEE (müşteri);
  • UTC olarak DTSTART / DTEND, STATUS:CONFIRMED veya STATUS:CANCELLED;
  • satırların 75 baytta katlanması, hiçbir UTF-8 karakteri bölünmeden.

Onaylanmış bir randevunun ertelenmesi böylece müşteride hâlihazırda bulunan etkinliği düzelten yeni bir dosya gönderir; bir iptal ise onu silen bir dosya gönderir. Bu, 1.3.0'da yapılan bir düzeltmedir: daha önce eski saat müşterinin takviminde kalıyordu.

Dosya, WordPress'in dosya API'si üzerinden sunucunun geçici dizinine yazılır — asla herkese açık olarak sunulan wp-content/uploads/ içine değil — ve gönderim biter bitmez, gönderim başarısız olsa bile silinir. Müşterinin adını ve e-postasını taşır: diskte gereğinden bir saniye fazla durmasının anlamı yoktur.


Hatırlatmalar ve zamanlanmış görev

Tek bir zamanlanmış görev, owag_hourly_event, her saat çalıştırılır. Üç iş yapar.

1. Bir gün önceki hatırlatma

Hatırlatma, randevu 12 ila 36 saat içinde başlıyorsa gönderilir. Bu sabit bir saat penceresi değildir ve bu bilinçlidir: WP-Cron yalnızca bir sayfa ziyaretinde tetiklenir. Akşamları trafiği olmayan bir site, ertesi günün hatırlatmalarını kalıcı olarak kaybediyordu. Kayan bir pencereyle hatırlatma ilk uygun çalıştırmada gider ve gecikmeyi kapatır.

Koşullar: randevu onaylanmış, e-posta adresi girilmiş, bir blokaj değil ve hatırlatma daha önce gönderilmemiş.

Her hatırlatma, gönderimden önce atomik olarak rezerve edilir (reminder_sent bayrağı üzerinde koşullu bir UPDATE): çakışan iki cron çalıştırması aynı mesajı iki kez gönderemez. Gönderim başarısız olursa rezervasyon geri verilir ve hatırlatma bir sonraki çalıştırmada yeniden denenir. Ayrıca kısa bir kilit (10 dakika), iki eşzamanlı geçişin aynı listeyi dolaşmasını engeller.

Bir randevuyu ertelemek bayrağı sıfırlar: müşteri yeni saat için de hatırlatma alır.

2. Doğrulanmamış taleplerin temizlenmesi

48 saatten uzun süredir unverified kalan talepler silinir. (Aralıkları ise zaten 45 dakika sonra yeniden uygun hâle getirilmişti.)

3. GDPR anonimleştirmesi

GDPR bölümüne bakın.

Güvenlik ağı

Bir WP-Cron etkinliği kaybolabilir: veritabanı optimizasyonu, kısmi geri yükleme, temizlik eklentisi, cron seçeneğinin sıfırlanması. OW Agenda her yüklemede görevin programlanmış olduğunu doğrular ve değilse yeniden programlar. Hatırlatmalar, temizlik ve saklama sessizce duramaz.

Gerçek bir sistem cron'u kullanmak

WP-Cron trafiğe bağlıdır. Az ziyaret edilen bir sitede sistem cron'unu tercih edin:

// wp-config.php
define( 'DISABLE_WP_CRON', true );
# crontab -e — toutes les 15 minutes
*/15 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null

Anti-spam ve hız sınırları

Rezervasyon doğası gereği herkese açıktır: hesap yok, giriş yok, nonce imkânı yok. Bu yüzden beş bağımsız koruma daha en baştan devreye girer.

1. Bot tuzağı (honeypot)

Form, ekran dışında duran, insan için görünmez ama bir bot için iştah açıcı bir metin alanı içerir. Alan mevcut ve boş olmalıdır. Doldurulmuş bir alan — ya da doğrudan API'ye gönderim yapıldığını ele veren eksik bir alan — kullanılabilir hiçbir ayrıntı vermeden kuru bir ret döndürür (HTTP 403).

2. Doldurma süresi

Sayfa, görüntülenme zaman damgasını iletir. Yüklemeden 4 saniyeden az süre sonra gelen bir gönderim reddedilir. Burada da eksik ya da bozuk bir zaman damgası bir rettir: 1.3.0'da bu iki alan zorunlu hâle geldi — bunları atlamak kontrolü düpedüz devre dışı bırakıyordu.

3. Adres başına saatlik kota

Kapsam başına saatte 5 rezervasyon. IPv4'te kapsam adresin kendisidir; IPv6'da /64 önekidir — bir saldırganın orada 2⁶⁴ adresi vardır, adresin tamamını saymak hiçbir şeyi sınırlamazdı.

Sayaç, yalnızca formun doğrulanmasından sonra artırılır: e-postasını üst üste üç kez yanlış yazan bir ziyaretçi artık boşuna bir saat engellenmez.

4. Doğrulanmamış talepler için günlük üst sınır

Aynı gün içinde en fazla 3 e-posta doğrulaması bekleyen talep bir aralığı tutabilir. Bu üst sınır olmadan, birkaç gönderim bir tarihin bütün aralıklarını dondurmaya yetiyordu. Sınırın ötesinde ziyaretçi, daha sonra yeniden denemeye ya da başka bir gün seçmeye davet edilir (HTTP 429).

5. Rezervasyon kilidi

Bir aralığın rezervasyonu ve bir davetin tüketilmesi, adı veritabanınızdan ve tablo önekinizden türetilen adlandırılmış bir MySQL kilidiyle sıraya sokulmuş kritik bir bölümde yapılır (böylece aynı paylaşımlı hostingdeki iki site birbirini kilitlemez). Kilit 5 saniye içinde alınamazsa istek, çifte randevu yerine açık bir HTTP 503 döndürür.

Bu kilit, 1.3.0'dan beri, çıplak bir SELECT üzerine kurulu bir transaction'ın yerini alıyor: REPEATABLE READ altında bu hiçbir satır kilidi koymuyordu ve eşzamanlı iki ziyaretçi aynı saati rezerve edebiliyordu.

Ve çift doğrulama

En etkili katman budur: yukarıdakilerin hepsini aşsa bile bir bot ne ajandanıza ne de gelen kutunuza ulaşır, çünkü yönetici bildirimi ancak e-postayla alınan bir bağlantıya tıklandıktan sonra gönderilir. Bkz. E-posta ile çift doğrulama.


GDPR

Bir randevu ajandası, potansiyel sağlık verilerini, iletişim bilgilerini ve geçmiş kayıtlarını işler. Varsayılan ayarlar bilinçli olarak muhafazakârdır.

Rıza

Onay kutusu, herkese açık formda zorunludur ve varsayılan olarak işaretli değildir: «İletişim bilgilerimin randevumun yönetimi için kullanılmasını kabul ediyorum.» Rızası olmayan bir rezervasyon yalnızca tarayıcı tarafında değil, sunucu tarafında da reddedilir.

Veri minimizasyonu

  • Veritabanında hiçbir IP adresi saklanmaz. Saatlik kota, anahtarı ağ kapsamının bir özetinden oluşan ve bir saat sonra temizlenen geçici bir sayaç (transient) kullanır.
  • Eklenti hiçbir user agent saklamaz, hiçbir izleyici ya da çerez bırakmaz.
  • Hiçbir veri üçüncü bir servise gönderilmez: CDN yok, dış çağrı yok, telemetri yok.
  • Hiç doğrulanmamış talepler 48 saat sonra silinir — arkalarında hiçbir veri bırakmazlar.
  • İptal edilen randevular artık ajanda API'sinden dönmez: gereksiz kişisel veriler dolaşımda olmaz.

Otomatik anonimleştirme

retention_months ayarı, varsayılan 24 ay. Her saat, bu süreden daha uzun zaman önce tamamlanmış randevular yerinde anonimleştirilir: ad «Anonimleştirildi» ile değiştirilir, telefon ve e-posta boşaltılır, müşterinin mesajı ve dahili notlar silinir. Satır kalır; bu da hiçbir kişisel veri saklamadan faaliyetin istatistiksel geçmişini (kaç randevu, ne zaman, hangi hizmet için) korur.

Otomatik anonimleştirmeyi kapatmak için 0 yazın — sonuçlarını bilerek.

Not: anonimleştirme, e-posta adresi taşıyan randevuları hedefler. E-postası olmadan elle girilmiş bir randevu (yalnızca ad ve telefon) otomatik temizlikten etkilenmez; saklama politikanız gerektiriyorsa onu elle silin.

Erişim hakkı ve silme hakkı

Eklenti, WordPress'in yerleşik dışa aktarıcı/silicilerini bağlamaz (bunlar kullanıcı hesapları üzerinde çalışır, oysa müşterilerin hesabı yoktur). Bir talebi işlemek için:

  • Erişim — kişiyi müşteri rehberinde arayın (ad, telefon veya e-posta) ve randevularını ajandada gözden geçirin. Veritabanı yöneticileri ayrıca {prefix}_owag_appointments ve {prefix}_owag_customers tablolarını customer_email / email sütunu üzerinden doğrudan sorgulayabilir.
  • Silme — rehberdeki kartı silin, ardından ilgili randevuları iptal edin ya da anonimleştirilmeye bırakın. Anında silme, veritabanında customer_email üzerinden yapılır.
-- Effacement manuel des données personnelles d'une personne (adaptez le préfixe).
UPDATE wp_owag_appointments
   SET customer_name = 'Anonymisé', customer_phone = '', customer_email = '',
       customer_msg = NULL, admin_notes = NULL
 WHERE customer_email = 'personne@example.com';

DELETE FROM wp_owag_customers WHERE email = 'personne@example.com';

İşleme faaliyetleri kaydı

Kaydınız için: amaç randevu yönetimi; hukuki dayanak rıza (online rezervasyon) ya da sözleşmenin ifası / sözleşme öncesi önlemler (telefonla alınan randevu); kategoriler kimlik, iletişim bilgileri, mesajın içeriği, dahili notlar; süre varsayılan 24 ay, ardından anonimleştirme; alıcılar hostinginiz ve e-posta gönderim servisiniz dışında hiçbir alt işleyen yok.


Shortcode'lar

[ow_agenda] — ziyaretçi rezervasyonu

Herkese açık bir sayfaya yerleştirin. Hiçbir özniteliği yoktur: hizmet, süre ve saatler ayarlardan gelir. Shortcode kendi stil dosyasını ve betiğini yükler (toplamda 12 KB'ın altında, bağımlılıksız) ve API'ye yapılan ilk çağrıdan sonra dolan bir kapsayıcı üretir.

[ow_agenda]

?owag_invite=<token> URL parametresini yorumlayan shortcode budur: aynı sayfa hem standart görüşmeye hem de davetli seanslara hizmet eder.

[ow_agenda_admin] — yönetim sayfası

Ayrı bir sayfaya yerleştirin. Hiçbir özniteliği yoktur. Erişimi shortcode'un kendisi yönetir:

  • giriş yapmamış ziyaretçi → sayfaya geri döndüren bir giriş bağlantısı;
  • owag_manage yetkisi olmadan giriş yapmış → kısıtlı erişim mesajı;
  • yetkiyle giriş yapmış → tam arayüz (ajanda, bekleyenler, müşteriler, davetler).
[ow_agenda_admin]

Her iki sayfa da etkinleştirmede bu shortcode'larla otomatik oluşturulur. Sildiyseniz bir sayfa oluşturup shortcode'u yapıştırmanız yeterlidir — bu durumda e-postalardaki bağlantıların ve manifestonun doğru yeri göstermesi için owag_page_admin (ya da owag_page_booking) seçeneğini güncellemeyi unutmayın.

Bağımsız sayfalar

Sitenin herhangi bir sayfasında yakalanan dört URL parametresi, temanın dışında sunulan bağımsız sayfalar üretir (asgari render, noindex,nofollow):

URLRolü
?owag_verify=<uid>Talebin müşteri tarafından doğrulanması (çift onay)
?owag_cancel=<uid>Müşterinin online iptali
?owag_admin_action=confirm|refuse&uid=…&sig=…Yönetici e-postasından onay / ret
?owag_manifest=1Ajanda sayfasının uygulama manifestosu

Bu sayfalar yüklemede asla bir işlem yürütmez: bir özet ve bir düğme gösterirler. Hiçbir bot, hiçbir e-posta antivirüsü, hiçbir tarayıcı prefetch'i bir insanın yerine randevuyu onaylayamaz ya da iptal edemez.


REST API

Tüm endpoint'ler owag/v1 ad alanı altında, alışılmış REST kökünde yaşar (https://example.com/wp-json/owag/v1/…).

Herkese açık endpoint'ler

Kimlik doğrulaması yok: bunlar rezervasyon bileşeninin ve e-postayla alınan bağlantıların rotalarıdır. Güvenlikleri rastgele jetonlara (kriptografik bir üreticiden gelen 32 onaltılık karakter), HMAC imzalarına ve Anti-spam bölümünde anlatılan korumalara dayanır.

YöntemYolParametrelerRolü
GET/public/daysfrom (Y-m-d, varsayılan: bugün), token (davet, isteğe bağlı)label, duration ve days döndürür: from tarihinden itibaren 14 gün, her biri boş aralık sayısıyla
GET/public/slotsdate (Y-m-d, zorunlu), tokenslots döndürür: boş başlangıç saatleri (HH:MM)
POST/public/bookdate, time, name, phone, email, message, consent, website (tuzak), ts (zaman damgası), tokenTalebi oluşturur; status ve gösterilecek mesajı döndürür
POST/public/verifyuidunverified bir talebi doğrular
POST/public/canceluidÖn bildirim süresi içinde kalmak kaydıyla pending veya confirmed bir randevuyu iptal eder
POST/public/admin-actionuid, action (confirm|refuse), sigYönetici e-postasından onaylar veya reddeder (HMAC imzası)

Rezervasyon örneği:

curl -X POST https://example.com/wp-json/owag/v1/public/book \
  -H 'Content-Type: application/json' \
  -d '{
    "date": "2026-09-15",
    "time": "14:30",
    "name": "Marie Dupont",
    "phone": "0470 12 34 56",
    "email": "marie@example.com",
    "message": "Première visite",
    "consent": 1,
    "website": "",
    "ts": 1757942400
  }'
{
  "ok": true,
  "status": "unverified",
  "message": "Un dernier geste : un e-mail vient de vous être envoyé…"
}

Yönetim endpoint'leri

Hepsi owag_manage yetkisini ve geçerli bir WordPress REST nonce'unu (X-WP-Nonce başlığı) gerektirir.

YöntemYolParametrelerRolü
GET/admin/agendafrom, to (Y-m-d)events (istenen aralık, iptaller hariç) ve pending (bekleyen tüm gelecek talepler)
POST/admin/appointmentkind (manual|block|consult|seance), date, time, duration (5–720 dk), label, name, phone, email, notes, force, send_emailElle bir randevu ya da bir blokaj oluşturur
POST/admin/appointment/{id}status (pending|confirmed|cancelled|done|noshow), name, phone, email, label, notes, date, time, duration, force, silentGünceller, erteler, durumu değiştirir. silent=1 tüm e-posta gönderimini kapatır
GET/admin/customersq (arama)Rehber (en fazla 200 kart)
POST/admin/customersname (zorunlu), phone, email, notesBir kart oluşturur
POST/admin/customers/{id}aynısıBir kartı günceller
DELETE/admin/customers/{id}Bir kartı siler
GET/admin/invitesAçık davetler (hiç kullanılmamış ya da serbest bırakılmış, süresi dolmamış)
POST/admin/invitesname (zorunlu), label (zorunlu), duration (15–720), days_valid (1–365, varsayılan 60), email, phone, send_emailBir davet oluşturur; url ve email_sent döndürür
DELETE/admin/invites/{id}Bir daveti siler
GET/admin/settingsGeçerli ayarlar
POST/admin/settingsJSON gövde (bkz. Ayarlar referansı)Ayarları kaydeder

Her rota erişim kontrolünü açıkça bildirir; yetki, en küçük işlem yürütülmeden önce doğrulanır.

Hata kodları

Hatalar, okunabilir bir kod ve bir HTTP durumu taşıyan standart WP_Error nesneleridir.

KodHTTPAnlamı
owag_spam403Bot tuzağı doldurulmuş ya da zaman damgası eksik / çok yeni
owag_rate429Bu adres için saatlik kota doldu
owag_day_full429Bu tarihte doğrulama bekleyen çok fazla talep var
owag_busy503Rezervasyon kilidi alınamadı — birazdan tekrar deneyin
owag_slot_taken409Aralık bu arada alındı
owag_overlap409Çakışma tespit edildi (yönetici) — force ile yeniden gönderin
owag_invite_invalid404Bilinmeyen davet jetonu
owag_invite_used410Davet zaten kullanılmış
owag_invite_expired410Davetin süresi dolmuş
owag_too_late403Online iptal, ön bildirim süresinin dışında
owag_bad_sig403Geçersiz HMAC imzası
owag_not_found404Randevu ya da kart bulunamadı
owag_name, owag_phone, owag_email, owag_consent400Geçersiz alan ya da eksik rıza
owag_bad_input, owag_bad_date400Geçersiz tarih, saat ya da giriş
owag_noop400Boş güncelleme isteği
owag_insert500Veritabanına yazma başarısız

Geliştirici kancaları

1.3.1'de OW Agenda ne bir filtre ne de herkese açık bir action sunar: belgelenecek bir uzantı API'si yoktur ve aşağıdakilerin hiçbiri tahmin edilmek zorunda değildir. Kullanılabilir tek kanca, kendi bakım işinizi bağlayabileceğiniz owag_hourly_event zamanlanmış etkinliğidir:

add_action( 'owag_hourly_event', function () {
    // Votre traitement horaire, exécuté juste après celui du plugin.
} );

Geri kalan her şey için entegrasyon noktası REST API'dir: arayüzün yaptığı şeyi tam olarak sunar, ne eksik ne fazla.


Ayarlar referansı

Tüm ayarlar tek bir seçeneğe, owag_settings içine sığar. PHP'de okuma ve yazma:

$s = owag_settings();          // réglages effectifs (défauts + enregistrés)
$duree = (int) $s['consult_duration'];

update_option( 'owag_settings', array_merge( owag_settings(), [
    'consult_duration' => 45,
    'buffer'           => 10,
] ) );

Varsayılan değerler

[
    // Horaires : clé = 1 (lundi) … 7 (dimanche), valeur = liste de plages [début, fin]
    'hours' => [
        '1' => [ [ '09:00', '18:00' ] ],
        '2' => [ [ '09:00', '18:00' ] ],
        '3' => [ [ '09:00', '18:00' ] ],
        '4' => [ [ '09:00', '18:00' ] ],
        '5' => [ [ '09:00', '18:00' ] ],
        '6' => [],   // samedi fermé
        '7' => [],   // dimanche fermé
    ],
    'slot_step'           => 30,   // granularité des créneaux proposés (minutes)
    'consult_duration'    => 60,   // durée d'une consultation (minutes)
    'buffer'              => 0,    // battement autour de chaque rendez-vous (minutes)
    'min_notice_hours'    => 24,   // délai minimum avant réservation
    'max_advance_days'    => 60,   // horizon maximum de réservation
    'auto_confirm'        => 0,    // 0 = validation manuelle, 1 = confirmation automatique
    'email_verify'        => 1,    // double vérification par e-mail
    'cancel_notice_hours' => 24,   // préavis d'annulation en ligne par le client
    'notify_email'        => get_option( 'admin_email' ),
    'retention_months'    => 24,   // anonymisation des RDV passés (0 = jamais)
    'consult_label'       => 'Consultation',
]

Ayrıntılar

AyarTürArayüzdeki sınırlarEtkisi
hoursdiziGün başına 1 veya 2 aralıkİki aralık öğle arasına imkân verir. Bir aralık, yalnızca başlangıç ve bitiş geçerliyse ve başlangıç < bitiş ise dikkate alınır. Boş bir gün = kapalı
slot_steptamsayı5 → 120 dkÖnerilen saatler arasındaki mesafe. Ne kadar ince olursa liste o kadar uzar
consult_durationtamsayı15 → 480 dkBir web görüşmesi için ajandada ayrılan süre
buffertamsayı0 → 120 dkAday aralığın iki yanına uygulanan tampon
min_notice_hourstamsayı0 → 168 saŞimdi + bu süre öncesinde hiçbir şey önerilmez
max_advance_daystamsayı7 → 365 günÖtesinde hiçbir aralığın önerilmediği ufuk
auto_confirm0 / 1Manuel onay ya da anında onay
email_verify0 / 1E-posta ile çift onay (açık bırakın)
cancel_notice_hourstamsayı0 → 168 saBu sürenin ötesinde online iptal, telefon etmeye davet eden bir mesajla reddedilir
notify_emaile-postaYönetici bildirimlerinin alıcısı; ICS dosyalarında ORGANIZER olarak da kullanılır
retention_monthstamsayı0 → 120 ayTamamlanmış randevuların anonimleştirilmesi; 0 devre dışı bırakır
consult_labelmetinRezervasyon bileşeninde gösterilen başlık

Yapılandırılamayan iki sabit bilinmeye değer, çünkü çift onayın davranışını belirlerler: doğrulanmamış bir talebin aralığı 45 dakika tutulur ve talep 48 saat sonra silinir.

REST API üzerinden kayıt aynı anahtarları JSON olarak kabul eder; tam sayılar en az sıfıra çekilir, bildirim adresi yalnızca geçerliyse kabul edilir ve her çalışma aralığı sunucu tarafında yeniden doğrulanır.


Saklanan veriler

Üç tablo, hepsi kurulumunuzun önekiyle. Tarihler sitenin yerel saatiyle yazılmış DATETIME değerleridir, asla UTC değil — sorguları okunabilir, saat karşılaştırmalarını da basit kılan budur.

{prefix}_owag_appointments

SütunTürNotlar
idBIGINTBirincil anahtar
uidCHAR(32)Benzersiz herkese açık jeton (onaltılık, kriptografik üretici). Doğrulama, iptal ve yönetici işlemi bağlantılarının anahtarı ve ICS UID'i olarak kullanılır
kindVARCHAR(16)consult, seance, manual, block
service_labelVARCHAR(120)Gösterilen başlık
customer_name, customer_phone, customer_emailVARCHARİletişim bilgileri
customer_msgTEXTMüşterinin bıraktığı mesaj
admin_notesTEXTDahili notlar, müşteriye asla gönderilmez
start_dt, end_dtDATETIMEAralığın sınırları (start_dt üzerinde indeksli)
statusVARCHAR(16)unverified, pending, confirmed, cancelled, done, noshow
sourceVARCHAR(16)web, invite, admin
invite_idBIGINTVarsa kaynak davet
reminder_sentTINYINTHatırlatma bayrağı (erteleme durumunda 0'a döner)
created_at, updated_atDATETIMEupdated_at, ICS revizyon numarasını besler

{prefix}_owag_invites

id, token (CHAR(32), benzersiz), müşterinin iletişim bilgileri, service_label, duration_min, expires_at, appointment_id (bağlantı tüketildiğinde doldurulur, randevu iptal edilirse NULL'a döner), created_at.

{prefix}_owag_customers

id, name, phone, email, notes, created_at, updated_at. name ve email üzerinde indeks.

Yapılandırmayı tek bir seçenek taşır (owag_settings); diğerleri tekniktir: owag_admin_secret (HMAC gizli anahtarı), owag_db_version, owag_pages_created, owag_page_booking, owag_page_admin.


Uluslararasılaştırma

Arayüzün tamamı çevrilebilir: yönetim ayarları, rezervasyon bileşeni, Ajanda sayfası, bağımsız sayfalar, API mesajları ve e-posta şablonları. Kaynak dil İngilizce'dir; eklenti ow-agenda çeviri alanını ve /languages yolunu bildirir.

Paket languages/ow-agenda.pot şablonunu içerir. Arayüzün özgün ifadelerinden üretilmiş eksiksiz bir Fransızca çeviri de birlikte gelir.

Bir çeviriyi elle kurmak

.po dosyasını derleyin ve .mo dosyasını WordPress'in çeviriler klasörüne bırakın:

msgfmt ow-agenda-fr_FR.po -o ow-agenda-fr_FR.mo
# puis : wp-content/languages/plugins/ow-agenda-fr_FR.mo

WordPress kataloğu ilk çevrilmiş metinde yükler; elle hiçbir çağrı gerekmez.

Çevirmenler için iki tuzak

  • JavaScript'e gönderilen metinler numaralandırılmış yer tutucular (%1$s, %2$s) kullanır, asla çıplak bir %s değil: betiklerin içindeki küçük biçimlendirici yalnızca bunları anlar. Numaralandırılmamış bir yer tutucu olduğu gibi ekrana yazılırdı.
  • İki metin, cümle değil PHP tarih biçimidir: l, F j, Y \a\t g:i a ve l j F Y \a\t H:i. Bunları biçim olarak çevirin (jetonları yeniden sıralayın, düz harfleri ters eğik çizgiyle kaçırın). Fransızca l j F Y \à H\hi kullanır.

Kaldırma

Eklentiyi devre dışı bırakmak yalnızca tek bir şey yapar: saatlik zamanlanmış görevi kaldırır. Verileriniz, ayarlarınız ve sayfalarınız olduğu gibi kalır ve yeniden etkinleştirmede her şey kaldığı yerden devam eder.

Eklentiyi WordPress'ten silmek ise tam kaldırmayı çalıştırır:

  • üç tablonun silinmesi (owag_appointments, owag_invites, owag_customers);
  • owag_settings, owag_admin_secret, owag_db_version, owag_pages_created, owag_page_booking, owag_page_admin seçeneklerinin silinmesi;
  • zamanlanmış görevin silinmesi;
  • owag_manage yetkisinin yönetici rolünden kaldırılması.

Etkinleştirmede oluşturulan iki sayfa silinmez — üzerlerinde çalışılmış, menüye konmuş, dizine eklenmiş olabilirler. Artık istemiyorsanız onları çöp kutusuna taşımak size kalmıştır.

Tabloların silinmesi geri alınamaz. Randevu geçmişinin sizin için bir değeri varsa önce veritabanınızı dışa aktarın.


Sorun giderme

Rezervasyon sayfasında hiç aralık görünmüyor

Listeyi sırayla gözden geçirin:

  1. Günün saatleri girilmiş mi? Boş bir gün, kapalı bir gündür.
  2. Minimum süre (varsayılan 24 saat) bugünü ve yarının bir kısmını zorunlu olarak gizler.
  3. Süre aralığa sığıyor mu? 09:00–12:00 aralığı ve 240 dakikalık bir süreyle hiçbir aralık var olamaz.
  4. Ufuk: max_advance_days ötesindeki günler asla önerilmez.
  5. Tampon: yoğun bir programda geniş bir tampon her şeyi kapatabilir.
  6. Bir blokaj belki günü kaplıyordur. Ajanda sayfasını ilgili günde açın.
  7. Sitenin saat dilimi (Ayarlar → Genel): yanlış ayarlanmış bir saat dilimi tüm hesapları kaydırır.

E-postalar gelmiyor

Bu neredeyse her zaman teslim edilebilirlik sorunudur, eklenti değil.

  1. Randevunun Ajanda sayfasında gerçekten var olduğunu doğrulayın: oradaysa eklenti işini yapmıştır.
  2. Bir SMTP eklentisi kurun (Fluent SMTP, WP Mail SMTP…). PHP'nin mail() fonksiyonu, alıcı sunucuların büyük çoğunluğu tarafından reddedilir.
  3. Alan adınızın SPF, DKIM ve DMARC kayıtlarını doğrulayın.
  4. OW Agenda → Yönetici bildirimlerinin gönderileceği adres alanındaki adresi test edin: geçersiz bir adres bildirimleri sessizce engeller.

Bir gün önceki hatırlatma gitmedi

Hatırlatma WP-Cron'a, o da trafiğe bağlıdır. Az ziyaret edilen bir sitede gerçek bir sistem cron'una geçin (bkz. Hatırlatmalar ve zamanlanmış görev). Ayrıca randevunun gerçekten onaylanmış olduğunu, bir e-posta adresi taşıdığını ve bir blokaj olmadığını doğrulayın.

Ajanda sayfası «Erişim ekibe ayrılmıştır» diyor

Giriş yapmış kullanıcının owag_manage yetkisi yok. Bu yetki etkinleştirmede yöneticilere verilir; diğer roller için bkz. Kurulum.

E-postadaki «Onayla» düğmesi «Geçersiz bağlantı» gösteriyor

Üç olası neden: bağlantı e-posta istemcisi tarafından kısaltılmıştır (URL'nin tamamını kopyalamayı deneyin), randevu zaten işlenmiştir (mesaj bunu belirtir) ya da sitenin HMAC gizli anahtarı yeniden üretilmiştir. Son durumda Ajanda sayfasını kullanın: eski bağlantılar, tasarım gereği artık doğrulanamaz.

İki randevu aynı aralıkta bulunuyor

1.3.0'dan beri bu, online rezervasyonla imkânsızdır. Buna karşılık yönetici, Ajanda sayfasından bir çakışmayı zorlayabilir (eklenti bunu bildirir ve onay ister): önce bunun bilinçli bir zorlama olmadığını doğrulayın. Ayrıca veritabanınızın GET_LOCK() desteklediğini doğrulayın — sıra dışı bir hosting bu durumda çift kayıt yerine rezervasyonda 503 hataları döndürürdü.

«Randevu al» ve «Ajanda» sayfaları oluşturulmadı

Bunlar yalnızca bir kez, ilk etkinleştirmede oluşturulur. Sildiyseniz, [ow_agenda] ve [ow_agenda_admin] shortcode'larıyla iki sayfa oluşturun, ardından e-postalardaki bağlantıların doğru kalması için owag_page_booking ve owag_page_admin seçeneklerini bu sayfalara yönlendirin:

update_option( 'owag_page_booking', 42 );  // ID de votre page de réservation
update_option( 'owag_page_admin', 43 );    // ID de votre page Agenda

Takvim dosyası eklenmiyor

Dosya, WordPress'in dosya API'si üzerinden sunucunun geçici dizinine yazılır. Bu dizin yazılabilir değilse (kota, izinler, kilitli hosting), e-posta başarısız olmak yerine ek olmadan gider. Yazma izinlerini ve disk alanını kontrol edin.

Saatler bir saat kaymış

Ayarlar → Genel → Zaman dilimi. Sabit bir UTC farkı yerine bir şehir seçin (Europe/Brussels): yaz saatine geçişi yalnızca adlandırılmış bir saat dilimi yönetir.


SSS

OW Agenda gerçekten ücretsiz mi? Evet. GPL-2.0-or-later, https://optionweb.dev/tr/addons/ow-agenda/ adresinden .zip olarak indirilebilir. Pro sürüm yok, lisans anahtarı yok, kilitli özellik yok, açılacak hesap yok, randevu kotası yok.

Online aralıklar telefonla alınan randevuları hesaba katıyor mu? Evet. Ajandadaki her kayıt — web rezervasyonu, elle girilen randevu, davetli seans, blokaj — kendi zaman dilimini online rezervasyona kapatır.

Müşterinin hesap açması gerekiyor mu? Hayır. Hesap yok, parola yok. Müşterinin tüm işlemleri (doğrulama, iptal) e-postayla alınan gizli bağlantılardan geçer.

Birden çok uzman ya da birden çok oda yönetilebilir mi? Hayır. OW Agenda tek bir programı tarif eder. Bağımsız iki ajanda için iki site gerekir (ya da bir multisite ağının iki sitesi).

Google Takvim ile senkronize oluyor mu? Müşteri açısından önemli olan yönde: evet. Her onay, etkinliği Google Takvim, Outlook ya da iPhone takviminde ekleyen — ve güncelleyen, silen — standart bir takvim dosyası taşır. Buna karşılık eklenti sizin dış takvimlerinizi okumaz: kişisel müsaitsizlikleriniz blokaj olarak girilir.

Rezervasyonda kapora alınabilir mi? Hayır, bu eklentinin bilinçli olarak kapsam dışında bıraktığı bir şey.

Online olarak kaç hizmet sunulabilir? Yalnızca bir tane; adını ve süresini siz seçersiniz. Diğer hizmetler, başlığı ve süreyi duruma göre belirlemenizi sağlayan seans davetlerinden geçer. Bu tercih bilinçlidir: herkese açık bir sayfadaki hizmet menüsü, hedefini şaşırmış talepleri çoğaltır.

Multisite üzerinde çalışıyor mu? Evet. Ağdaki her sitenin kendi tabloları, kendi ayarları ve kendi ajandası olur.

Eklenti siteyi yavaşlatır mı? Hayır. İlgili iki sayfa dışında hiçbir betik yüklenmez; rezervasyon bileşeni jQuery ve framework olmadan 12 KB'ın altındadır. Periyodik iş tek bir saatlik göreve sığar.

Bir müşteri e-postasını hiç doğrulamazsa ne olur? Aralığı 45 dakika sonra yeniden uygun hâle gelir ve talebi 48 saat sonra silinir. Bundan hiç haberiniz olmaz.

Destek nerede?


Changelog

1.3.1

Uyumluluk

  • İşlem, doğrulama ve iptal için kullanılan bağımsız sayfalar artık CSS ve JavaScript'lerini satır içinde yazdırmıyor: ikisi de artık WordPress'in enqueue API'si tarafından kaydedilip sunulan dosyalar. Değişken iki düğme rengi CSS özel özellikleri üzerinden geçiyor ve betik wp_localize_script() ile yapılandırılıyor.
  • Çeviri katalogları artık pakete gömülmüyor: yalnızca languages/ow-agenda.pot teslim ediliyor, Fransızca ise translate.wordpress.org tarafından beslenen WordPress.org dil paketleriyle dağıtılıyor.
  • Minimum WordPress sürümü 6.3'e geri döndü: pakette artık hiçbir şey 6.7'de gelen gömülü çeviri keşfine bağlı değil.

REST API

  • Her yönetim rotası artık permission_callback değerini array_merge() ile paylaşmak yerine açıkça bildiriyor. Yetki kontrolü zaten uygulanıyordu; artık statik analiz için de görünür durumda.

Davranışta hiçbir değişiklik yok.

1.3.0

Uluslararasılaştırma

  • Eklenti tamamen çevrilebilir hâle geldi (ow-agenda alanı, kaynak dil İngilizce): ayarlar, herkese açık sayfalar, API mesajları, e-postalar ve JavaScript arayüzü.
  • languages/ow-agenda.pot şablonu teslim edildi ve eksiksiz bir Fransızca çeviri hazırlandı.

Güvenlik

  • Randevuların herkese açık kimlikleri ve davet jetonları artık bir kriptografik üreticiyle (random_bytes()) üretiliyor. Bu jetonlar, iptal, doğrulama ve davet bağlantılarının tek kimlik doğrulamasıdır.
  • Bot tuzağı ve zaman damgası zorunlu hâle geldi: bunları atlamak anti-spam kontrollerini devre dışı bırakıyordu.
  • Saatlik kota IPv6'da /64 önekine göre toplanıyor ve günlük bir üst sınır doğrulanmamış talepleri sınırlıyor — bir ziyaretçi artık bir günün tüm aralıklarını tutamaz.
  • Kota yalnızca formun doğrulanmasından sonra düşülüyor: bir yazım hatası artık meşru bir ziyaretçiyi bir saat boyunca engellemiyor.

Güvenilirlik

  • Aynı aralık için eşzamanlı rezervasyonlar adlandırılmış bir MySQL kilidiyle sıraya sokuluyor. Önceki transaction hiçbir satır kilidi koymuyordu: iki ziyaretçi aynı saati rezerve edebiliyordu.
  • Bir gün önceki hatırlatma 12 ila 36 saatlik kayan bir pencere kullanıyor ve gecikmesini kapatıyor; her gönderim atomik olarak rezerve ediliyor, iki cron çalıştırması artık aynı hatırlatmayı iki kez gönderemiyor.
  • Saatlik görev kaybolursa kendini otomatik olarak yeniden programlıyor: hatırlatmalar, temizlik ve anonimleştirme artık sessizce duramaz.
  • Bir randevunun ertelenmesi müşterinin takvimini günceller (SEQUENCE, METHOD:REQUEST, organizatör ve katılımcı); iptal ise etkinliği silen bir METHOD:CANCEL gönderir.
  • Bileşendeki tarihler UTC ile değil yerel saatle hesaplanıyor: UTC'nin doğusundaki ziyaretçiler için artık kaybolan bir gün yok.
  • Bir davetten doğan randevunun iptali daveti serbest bırakıyor; davet yeniden kullanılabilir hâle geliyor.
  • İptal edilen randevular ve süresi dolmuş doğrulanmamış talepler artık ajandaya döndürülmüyor: yanıtlarda daha az kişisel veri, artık hayalet randevu yok.

1.2.1

  • Plugin Check uyumluluğu: çıktıların kaçırılması, girdilerin temizlenmesi, ayarlarda nonce, readme.
  • Kaldırma işlemi artık müşteri rehberi tablosunu ve HMAC gizli anahtarını da siliyor.

1.2.0

  • Tüm bildirimler için HTML e-postalar (kart düzeni, sitenin vurgu rengi).
  • Yönetici e-postasında Onayla / Reddet düğmeleri (HMAC imzalı bağlantılar).
  • Müşteri rehberi: arama, oluşturma, düzenleme, silme, yeni bir randevuya ve bir davete kısayollar.

1.1.0

  • Botlara karşı e-posta ile çift doğrulama (aralık 45 dakika tutulur, 48 saat sonra temizlenir).

1.0.0

  • İlk sürüm: online rezervasyon, mobil öncelikli yönetim ajandası, seans davetleri, takvim dosyalı e-postalar ve bir gün önceki hatırlatma.

OptionWeb tarafından tasarlandı — Julien Daniel, Châtelet, Belçika.