OW Agenda — Документација
Онлајн закажување термини и секојдневната агенда, во WordPress, без претплата. Автор: OptionWeb — Julien Daniel Страница на додатокот: https://optionweb.dev/mk/addons/ow-agenda/ Лиценца: GPL-2.0-or-later Верзија покриена со овој документ: 1.3.1
Содржина
- Преглед
- Инсталација
- Брз почеток
- Текот на резервацијата
- Двојната потврда по е-пошта
- Одобрувањето на барањата
- Страницата Агенда
- Именикот на клиенти
- Поканите за сеанса
- Е-пошти и календарска датотека (ICS)
- Потсетници и закажана задача
- Анти-спам и ограничувања на брзината
- GDPR
- Shortcode-ови
- REST API
- Референца на поставките
- Зачувани податоци
- Интернационализација
- Деинсталација
- Решавање проблеми
- ЧПП
- Changelog
Преглед
OW Agenda му додава на WordPress целосен систем за термини: јавна страница на која посетителот го избира својот ден, а потоа и часот, и страница «Агенда» заштитена со најава, замислена да се користи од телефон, на која вие го водите денот.
Сè останува во сајтот. Без надворешен сервис, без API од трета страна, без претплата:
термините ги пресметува вашиот сервер, состаноците живеат во вашите MySQL табели,
е-поштата тргнува преку wp_mail().
Што е испорачано (сè е бесплатно, GPL-2):
- Онлајн резервација: избор на ден, избор на термин, краток формулар, поле за GDPR согласност
- Двојна потврда по е-пошта: барањето станува вистинско дури по клик на линкот за потврда — ботовите никогаш не стигнуваат до агендата
- Рачно одобрување (препорачано) или автоматска потврда, со копчиња Потврди / Одбиј директно во известувањето по е-пошта (линкови потпишани со HMAC, без најава)
- Mobile-first страница «Агенда»: преглед на денот, барања на чекање, термини земени по телефон и внесени рачно, блокирање термини, презакажување, статуси завршено / не се појави
- Именик на клиенти: пребарување, создавање, уредување, бришење; се полни автоматски од потврдените термини
- Покани за сеанса: приватен линк му овозможува на постоен клиент сам да го избере датумот на својата сеанса, за услуга и времетраење што вие ги одредувате
- Уредни HTML е-пошти со ICS прилог (додавање во календарот на телефонот со еден потег), автоматски потсетник претходниот ден, онлајн откажување од страна на клиентот
- Автоматска анонимизација на минатите термини, чистење на барањата што никогаш не биле потврдени
- Целосна REST API под namespace
owag/v1
Што намерно не прави:
- Без онлајн плаќање: OW Agenda го закажува терминот, не наплаќа капар (користете WooCommerce ако тоа ви треба)
- Само една агенда: без управување со повеќе практичари или повеќе ресурси; додатокот опишува еден распоред, оној на сајтот
- Без двонасочна синхронизација со Google Calendar или Outlook: календарот на клиентот се ажурира преку ICS датотека (еднонасочно), а вашата лична недостапност се внесува како блокади
- Без каталог на услуги од страна на посетителот: јавната резервација се однесува на една единствена услуга (со подесив назив и времетраење); останатите услуги одат преку поканите за сеанса
- Без повторливи термини, без видеоконференции, без чекална
Овој список е архитектонски избор, а не скриен roadmap: едноставна агенда што никогаш не греши со терминот вреди повеќе од сложена машинерија што никој не смее да ја допре.
Инсталација
Од .zip
- Преземете
ow-agenda-1.3.1.zipод https://optionweb.dev/mk/addons/ow-agenda/ - Plugins → Add New → Upload Plugin
- Изберете ја датотеката, кликнете Install Now, потоа Activate
Преку FTP
Отпакувајте ја архивата и ставете ја папката ow-agenda во /wp-content/plugins/,
потоа активирајте го додатокот од Plugins.
Предуслови
- WordPress 6.3 или понов
- PHP 7.4 или понов (8.1+ препорачано)
- MySQL 5.7+ / MariaDB 10.2+ — функциите
GET_LOCK()/RELEASE_LOCK()се користат за серијализирање на истовремените резервации - Испраќање на е-пошта што функционира. Тоа е единствената вистинска зависност на додатокот: целиот тек (потврда, одобрување, потсетник, откажување) минува низ е-поштата. На споделен хостинг, инсталирајте SMTP додаток пред да ја пуштите агендата во живо.
Што се инсталира
При активирање, OW Agenda создава три табели:
| Табела | Содржина |
|---|---|
{prefix}_owag_appointments | Сите настани од агендата: веб консултации, сеанси произлезени од покана, термини внесени рачно, блокирани термини |
{prefix}_owag_invites | Приватните линкови «изберете го датумот на вашата сеанса» |
{prefix}_owag_customers | Именикот на клиенти |
…и, само првиот пат, две објавени страници:
- «Закажи термин» — ја содржи shortcode
[ow_agenda] - «Агенда» — ја содржи shortcode
[ow_agenda_admin]
Нивните идентификатори се памтат во опциите owag_page_booking и owag_page_admin;
знаменцето owag_pages_created гарантира дека деактивирање проследено со повторно
активирање нема да создаде дупликати. Можете да ги преименувате овие страници, да ги
преместите во мени, да го смените нивниот permalink: додатокот ги следи преку нивниот ID.
Активирањето додава и:
- capability
owag_manageна улогата administrator — таа, а неmanage_options, ја отвора агендата и административните REST рути; - стандардните поставки во опцијата
owag_settings; - часовната закажана задача
owag_hourly_event(првото извршување е 5 минути по активирањето).
HMAC тајна (owag_admin_secret, 64 знаци, не се вчитува автоматски) се генерира при
првото известување до администраторот: таа ги потпишува копчињата Потврди / Одбиј во
е-поштите.
Давање пристап на некој друг
Страницата Агенда е видлива за секој најавен корисник што има owag_manage. За да ѝ ја
отворите агендата на асистентка без да ѝ ги дадете клучевите од сајтот:
// À exécuter une fois (mu-plugin, ou plugin de gestion des rôles).
$role = get_role( 'editor' );
if ( $role ) { $role->add_cap( 'owag_manage' ); }
Брз почеток
По активирањето, отворете OW Agenda (главно мени на администрацијата). Екранот со поставки собира на една страница; пет минути се доволни.
1. Работното време
За секој ден од неделата, внесете еден интервал (09:00 → 18:00) и, ако правите пауза
на пладне, втор интервал (14:00 → 18:30). Ден оставен празен е затворен ден.
Стандардно: од понеделник до петок, 09:00–18:00; сабота и недела затворено.
Работното време се толкува во временската зона на сајтот (Settings → General → Timezone). Проверете ја пред да ја отворите резервацијата: сите датуми се чуваат во локално време.
2. Услугата што се резервира онлајн
- Назив на консултацијата — она што посетителот го гледа како наслов на виџетот («Консултација», «Прв термин», «Проценка»…)
- Времетраење на консултацијата — 60 минути стандардно. Токму тоа времетраење се блокира во агендата.
- Чекор на термините — растојанието меѓу два понудени часа (30 минути стандардно). Со времетраење од 60 и чекор од 30, нудите 9:00, 9:30, 10:00… а првиот термин земен во 9:30 ги брише 9:00 и 10:00 од списокот.
- Пауза меѓу два термина — минути за здив додадени од двете страни на секој кандидат-термин (0 стандардно).
3. Роковите
- Минимална најава за резервација — 24 ч стандардно: посетителот не може да резервира за за еден час.
- Хоризонт на резервација — 60 дена стандардно: подалеку од тоа, ништо повеќе не се нуди.
- Онлајн откажување од клиентот — до 24 ч пред терминот; по тој рок, страницата за откажување поканува да ви се јават.
4. Одобрувањето и е-поштите
- Потврда на барањата: рачно одобрување (препорачано) или автоматска потврда.
- Двојна потврда по е-пошта: оставете ја штиклирана. Тоа е најдобрата анти-бот заштита во додатокот.
- Административните известувања се праќаат на: вашата адреса. Стандардно, административната е-пошта на сајтот.
Зачувајте, потоа отворете ја страницата «Закажи термин»: виџетот ги прикажува следните 14 дена и вашите слободни термини. Во живо сте.
5. Агендата на телефон
Отворете ја страницата «Агенда» на вашиот телефон, најавете се, потоа употребете «Додај на почетен екран». Додатокот објавува манифест за апликација: страницата тогаш се отвора на цел екран, без лента на прелистувачот, како апликација.
Текот на резервацијата
Од страна на посетителот, страницата за резервација е самостојна компонента (JavaScript
без framework, помалку од 10 KB) што разговара со јавните endpoint-и owag/v1/public/*.
Чекор 1 — денот
При вчитување, виџетот ја бара достапноста за 14 дена од денес и прикажува лента од денови на кои може да се кликне. Ден без слободен термин е засивен и не може да се кликне. Копчето «Види ги следните датуми» ги вчитува следните 14 дена, онолку пати колку што е потребно до конфигурираниот хоризонт.
Датумите во виџетот се градат во локалното време на прелистувачот, никогаш во UTC. Тоа е поправка од 1.3.0: претходно, посетител источно од UTC што ја отвораше страницата кратко по полноќ го гледаше списокот како почнува претходниот ден и губеше цел ден достапност.
Чекор 2 — часот
Кликот на ден го повикува /public/slots и ги прикажува слободните почетни часови.
Термин се нуди кога сите овие услови се исполнети:
- паѓа во интервал од работното време на тој ден;
- целиот термин (почеток + времетраење) собира пред затворањето;
- почнува по сега + минималната најава;
- денот е во рамките на хоризонтот на резервација;
- не се преклопува со ниту еден активен настан, вклучувајќи ја и паузата — а „активен настан“ ги опфаќа потврдените термини, барањата на чекање, блокадите, термините земени по телефон и внесени рачно, и уште непотврдените барања што сè уште го задржуваат својот термин.
Тоа е важната точка: сè што ја зафаќа агендата го затвора онлајн терминот. Термин земен по телефон и запишан во агендата веднаш исчезнува од термините понудени на сајтот.
Чекор 3 — формуларот
Четири полиња, од кои три задолжителни: име (најмалку 2 знаци), телефон (најмалку 8 цифри), е-пошта (валидирана), слободна порака. Задолжително е и поле за GDPR согласност, кое не е штиклирано однапред.
Формуларот носи со себе и две полиња невидливи за посетителот — замка за ботови и временски печат од отворањето на страницата — опишани во делот Анти-спам.
Чекор 4 — одговорот
Според вашата конфигурација, три исходи:
| Конфигурација | Создаден статус | Прикажана порака |
|---|---|---|
| Двојна потврда по е-пошта активна (стандардно) | unverified | «Уште еден потег: штотуку ви е испратена е-пошта…» |
| Потврдата исклучена + рачно одобрување | pending | «Вашето барање е примено!» |
| Потврдата исклучена + автоматска потврда | confirmed | «Вашиот термин е потврден!» |
Ако терминот бил зафатен помеѓу прикажувањето на списокот и испраќањето на формуларот,
посетителот добива јасна порака (owag_slot_taken, HTTP 409) и списокот на денови се
превчитува автоматски. Двајца посетители не можат да го добијат истиот термин:
критичната секција е серијализирана со именувано MySQL заклучување, специфично за
вашата база и за вашиот префикс на табели, што важи и на споделен хостинг.
Двојната потврда по е-пошта
Тоа е функцијата што го одделува OW Agenda од преправен контакт формулар.
Кога Двојна потврда по е-пошта е активна (поставка email_verify, вклучена
стандардно):
- Барањето се запишува со статус
unverified. Администраторот не добива известување. Терминот не се појавува како барање за обработка. - Посетителот добива е-пошта «Уште еден потег…» со копче за потврда.
- Терминот е задржан 45 минути. По тој рок без потврда, тој повторно станува достапен за сите — значи бот не може да ви го замрзне денот.
- Кликот на копчето отвора самостојна страница (
?owag_verify=<uid>) што го прикажува резимето на терминот и копче «Го потврдувам моето барање». Потврдата тргнува само на клик: антивирусите и скенерите на линкови што ги посетуваат URL-адресите од е-поштите не потврдуваат ништо. - Барањето тогаш станува
pending(рачно одобрување) илиconfirmed(автоматска потврда), клиентот ја добива соодветната е-пошта, и дури тогаш тргнува известувањето до администраторот. - Барањата што никогаш не биле потврдени се бришат по 48 ч од часовната задача. Тие не оставаат ниту трага ниту лични податоци.
Ако, помеѓу испраќањето и кликот, терминот го зел некој друг (прозорецот од 45 минути е поминат), потврдата враќа јасна грешка и барањето се откажува — никогаш фантомски термин врз веќе зафатено место.
Практична последица: невалидна адреса за е-пошта не создава никаков термин. Повеќе не губите време да враќате повици на лажни броеви. Цената е еден дополнителен клик за клиентот; искуството покажува дека стапката на откажување е далеку помала од стапката на лажни термини што таа ја спречува.
Резервациите произлезени од покана за сеанса го прескокнуваат овој чекор: клиентот веќе докажал дека си ја чита поштата кликајќи на приватниот линк што го добил.
Одобрувањето на барањата
Рачно одобрување (препорачано)
Стандардна поставка: auto_confirm = 0. Потврдено барање пристигнува со статус
pending. На клиентот ништо не му е ветено додека вие не сте направиле ништо — но
терминот е веќе блокиран, никој не може да ве престигне.
Добивате е-пошта «За потврда: <клиент> — <датум>» со целосно резиме (услуга, датум, име, телефон, е-пошта, порака од клиентот) и две копчиња:
- Потврди го терминот — цијан
- Одбиј — со црвена контура
Копчињата во е-поштата: линкови потпишани со HMAC
Овие копчиња не бараат никаква најава. Тие водат кон вашиот сајт со три параметри:
owag_admin_action (confirm или refuse), uid (случајниот идентификатор на
терминот) и sig, потпис HMAC-SHA256 на uid|action пресметан со приватната тајна
на сајтот (owag_admin_secret).
- Потписот се проверува пред да се прикаже и најмалиот детал: манипулиран линк не прикажува ништо друго освен «Невалиден линк».
- Споредбата користи
hash_equals()— без истекување на информации преку времето на одговор. - Страницата прикажува резиме и копче; дејството се извршува само на клик. Значи скенер на линкови не потврдува ништо наместо вас.
- Веќе обработено барање враќа «Веќе обработено (статус: …)» наместо грешка.
Потврдувањето автоматски ја испраќа е-поштата за потврда до клиентот, со календарската датотека. Одбивањето ја испраќа е-поштата за откажување. Во двата случаја, агендата е ажурирана пред да сте го оставиле телефонот.
Овие линкови остануваат валидни сè додека терминот е на чекање. Ако ја избришете опцијата
owag_admin_secret(делумно враќање на базата, рачно чистење), сите веќе испратени линкови престануваат да работат: се генерира нова тајна и старите потписи повеќе не се совпаѓаат. Тогаш работете преку страницата Агенда.
Автоматска потврда
Поставка auto_confirm = 1. Слободен термин се потврдува веднаш: клиентот ја добива
својата потврда со календарската датотека, вие добивате известување «Нов термин».
Резервирано за дејности каде што секој отворен термин е прифатлив термин.
Двете поставки се комбинираат со двојната потврда: дури и при автоматска потврда,
барањето прво минува низ unverified ако email_verify е активна.
Страницата Агенда
Страницата «Агенда» ([ow_agenda_admin]) е алатката за секој ден. Таа е замислена
прво за телефон: широки копчиња, една колона, без табела што се лизга хоризонтално, а
се разбира работи подеднакво добро и на компјутерски екран.
Заштитена е: ненајавен посетител гледа линк за најава, најавен корисник без capability
owag_manage гледа «Пристапот е резервиран за тимот». Страницата е noindex,nofollow:
никогаш нема да заврши во Google.
Јазиче Агенда — прегледот на денот
Тековниот ден, настан по настан, со часот, времетраењето, називот, статусот и потеклото (сајт, покана, рачен внес). Навигација од ден на ден, копче Денес. На секој термин:
- Детали — контакт податоци на клиентот, порака оставена при резервацијата, и блок со внатрешни белешки (никогаш видливи за клиентот) што се зачувуваат без да се испрати ниту една е-пошта
- Потврди ✓ — за барање што е сè уште на чекање; е-поштата за потврда тргнува
- Завршено / Не се појави (no-show) — статуси на крајот од терминот
- Помести — нов датум, нов час, евентуално изменето времетраење. Додатокот ве прашува дали клиентот треба да биде известен по е-пошта; ако да, тој добива ажурирана потврда и календарска датотека што го поправа настанот што веќе е на неговиот телефон
- Откажи го терминот — повторно со избор дали да го известите клиентот или не
- Избриши ја блокадата — за блокиран термин
Кога некое дејство создава преклопување (преместување врз зафатен термин), додатокот предупредува и бара потврда: можете да форсирате. Тоа е вашиот распоред, вие знаете што правите — заштитата е блокирачка само за посетителите.
Додавање термин или блокада
Копчето «Додај термин» отвора единствен образец што служи за две употреби:
- Термин — клиентот ви се јавил. Име, телефон, е-пошта (изборно), услуга, датум, час, времетраење, внатрешни белешки. Ако внесете адреса за е-пошта и ја штиклирате опцијата, клиентот ја добива потврдата со својата календарска датотека, како да резервирал онлајн. Терминот го полни и именикот на клиенти.
- Блокада (одмор, пауза…) — причина, датум, час, времетраење. Без е-пошта, без картон на клиент, но терминот веднаш исчезнува од онлајн резервацијата. Така се внесува недела одмор, обука, или пладневниот термин што не сакате да биде резервиран.
Јазиче На чекање
Списокот на потврдени барања што ја чекаат вашата одлука, за сите денови заедно (веќе поминатите термини се исклучени). Две копчиња по ред: Потврди и Одбиј. Тоа е првиот екран што се отвора наутро.
Совет: агендата како апликација
На страницата Агенда, додатокот објавува манифест за веб апликација (?owag_manifest=1)
со името на сајтот, иконата на сајтот и бојата на темата. И на Android и на iOS, менито
на прелистувачот тогаш нуди «Додај на почетен екран»: добивате икона, отворање на цел
екран, и никогаш повеќе да ја куцате URL-адресата.
Именикот на клиенти
Третото јазиче на страницата Агенда е лесен именик, намерно минимален: име, телефон, е-пошта, слободни белешки.
- Се полни сам. Штом еден термин е потврден (проверена онлајн резервација, сеанса по покана, рачен внес), клиентот се поврзува со постоен картон преку неговата е-пошта, а потоа преку неговиот телефон. Ако не постои, картонот се создава; ако постои, се дополнуваат само празните полиња — додатокот никогаш не го препишува тоа што сте го внеле рачно.
- Пребарување по име, телефон или е-пошта (максимум 200 прикажани картони).
- Рачно создавање и уредување, со поле за белешки за историјата, преференциите, мерките на претпазливост.
- Две кратенки по картон: Нов термин (го пополнува однапред образецот за рачен внес) и Покани на сеанса (ја пополнува однапред поканата).
- Бришење на картон: минатите термини остануваат во агендата, исчезнува само картонот од именикот.
Овој именик не е CRM и не се преправа дека е. Тој одговара на едно прашање: „Која беше, всушност, госпоѓата во 14 ч?“
Поканите за сеанса
Случајот на употреба: постоен клиент има право на сеанса — контрола, корекција, услуга продадена на друго место — и вие сакате тој сам да го избере својот датум без да минува низ јавната резервација, за услуга и времетраење што вие ги одредувате.
Од јазичето Покани:
- Внесете го името на клиентот, називот на сеансата (задолжителни), нејзиното времетраење (15 до 720 минути) и, ако сакате, неговата е-пошта и телефон.
- Изберете ја важноста на линкот: 60 дена стандардно, од 1 до 365.
- Штиклирајте по потреба «Испрати му го линкот на клиентот по е-пошта» — клиентот добива е-пошта «Изберете го датумот на вашата сеанса» со називот, времетраењето, датумот на истекување и копче.
- Инаку, копирајте го линкот и испратете го преку SMS, WhatsApp, или преку нативното копче за споделување на телефонот.
Линкот води кон вашата страница за резервација со приватен токен
(?owag_invite=<token>, 32 хексадецимални знаци извлечени од криптографски генератор).
Виџетот тогаш го прикажува називот и времетраењето на сеансата, а не на стандардната
консултација. Клиентот го пополнува истиот краток формулар.
Правила што управуваат со еден линк за покана:
- Еднократна употреба. Штом сеансата е резервирана, линкот одговара «Овој линк веќе е искористен» (HTTP 410). Две истовремени отворања со ист токен не можат да создадат две сеанси: трошењето на токенот се одвива под истото заклучување како и резервацијата на терминот.
- Со рок. По истекувањето, линкот поканува повторно да ве контактираат (HTTP 410).
- Без двојна потврда. Клиентот веќе го добил овој линк преку канал што вие го
контролирате: сеансата се создава директно како
confirmed, со потврда и календарска датотека. - Рециклиран при откажување. Ако сеансата се откаже (од вас или од клиентот), поканата се ослободува: линкот повторно станува активен и поканата повторно се појавува во списокот на отворени покани. Тоа е поправка од 1.3.0 — претходно, откажувањето го убиваше линкот засекогаш и мораше да се прави нов.
- Отповиклив. Бришењето на покана од списокот го деактивира линкот веднаш.
Е-пошти и календарска датотека (ICS)
Трансакциските е-пошти
Сите пораки се во HTML, со распоред во табели компатибилен со Gmail и Outlook: бела
картичка на светла позадина, име на сајтот во заглавието, резиме во рамка со цијан раб,
копчиња во облик на пилула. Се испраќаат преку wp_mail(), значи ја почитуваат вашата
SMTP конфигурација и вообичаените WordPress филтри.
| Е-пошта | Примач | Активирач |
|---|---|---|
| Потврда на барањето | Клиент | Веб резервација кога двојната потврда е активна |
| Барањето е примено | Клиент | Потврдено барање, ја чека вашата одлука |
| Терминот е потврден | Клиент | Потврда (рачна, автоматска, админ внес, преместување) — со ICS прилог |
| Терминот е откажан | Клиент | Откажување од клиентот, одбивање или откажување од администраторот — со ICS прилог за откажување |
| Потсетник | Клиент | Автоматски, помеѓу 12 и 36 ч пред терминот |
| Изберете го датумот на вашата сеанса | Клиент | Создавање покана со испраќање по е-пошта |
| За потврда: … | Админ | Ново потврдено барање на чекање — со копчињата Потврди / Одбиј |
| Нов термин: … | Админ | Нов потврден термин (автоматска потврда, покана) |
| Откажување од клиент: … | Админ | Клиентот самиот откажал преку својата е-пошта |
Адресата за административни известувања е поставката notify_email (стандардно
административната е-пошта на сајтот). Е-поштите до клиентот тргнуваат само ако адресата е
валидна, и никогаш за блокиран термин.
Е-поштите за потврда и за откажување му потсетуваат на клиентот дека може да откаже онлајн, со бројот на часови најава што е навистина конфигуриран.
ICS прилогот
Датотеката .ics прикачена на потврдите е она што ја претвора една е-пошта во термин
навистина присутен во телефонот на клиентот: еден потег на прилогот, и настанот е во
неговиот календар, со свој сопствен потсетник.
Датотеката е усогласена со RFC 5545 и содржи сè што е потребно за календарските клиенти (Google, Outlook, Apple) правилно да ги обработат ажурирањата:
METHOD:REQUESTпри создавање и при секоја измена на распоредот,METHOD:CANCELпри откажување;- стабилен
UIDизведен од идентификаторот на терминот и од доменот на сајтот — токму тој ѝ овозможува на една измена да го замени постоечкиот настан наместо да создаде втор; - растечки
SEQUENCEизведен од датумот на последната измена, сведен на апсолутен момент: преминот на зимско време не може да го врати назад бројот на ревизијата (а откажувањето додава 1, за да остане повисоко од измена настаната во истата секунда); ORGANIZER(вашата адреса за известувања) иATTENDEE(клиентот);DTSTART/DTENDво UTC,STATUS:CONFIRMEDилиSTATUS:CANCELLED;- превиткување на редовите на 75 бајти без никогаш да се пресече UTF-8 знак.
Преместувањето на потврден термин значи испраќање на нова датотека што го поправа настанот што веќе е кај клиентот; откажувањето испраќа датотека што го брише. Тоа е поправка од 1.3.0: претходно старото време остануваше во календарот на клиентот.
Датотеката се запишува во привремениот директориум на серверот — никогаш во
wp-content/uploads/, кој се служи јавно — преку WordPress API за датотеки, и се
брише веднаш штом испраќањето заврши, вклучително и ако испраќањето не успее. Таа го носи
името и е-поштата на клиентот: нема што да прави на дискот ниту секунда подолго од
потребното.
Потсетници и закажана задача
Една единствена закажана задача, owag_hourly_event, што се извршува на секој час. Таа
прави три работи.
1. Потсетникот од претходниот ден
Потсетникот тргнува кога терминот почнува за 12 до 36 часа. Тоа не е фиксен часовен прозорец, и тоа е намерно: WP-Cron се активира само при посета на страница. Сајт без сообраќај навечер ги губеше засекогаш потсетниците за следниот ден. Со подвижен прозорец, потсетникот тргнува при првото достапно извршување и го надоместува задоцнувањето.
Услови: потврден термин, внесена адреса за е-пошта, не е блокада, и потсетникот не е веќе испратен.
Секој потсетник е атомски резервиран пред испраќањето (условен UPDATE врз
знаменцето reminder_sent): две извршувања на cron што се преклопуваат не можат двапати
да ја испратат истата порака. Ако испраќањето не успее, резервацијата се враќа и
потсетникот ќе биде обиден повторно при следното извршување. Кратко заклучување (10
минути) дополнително спречува две истовремени поминувања да го поминат истиот список.
Преместувањето на термин го враќа знаменцето на нула: клиентот навистина добива потсетник за новото време.
2. Чистењето на непотврдените барања
Барањата што останале unverified повеќе од 48 часа се бришат. (Нивниот термин, пак,
беше веќе ослободен по 45 минути.)
3. GDPR анонимизацијата
Видете го делот GDPR.
Заштитната мрежа
WP-Cron настан може да исчезне: оптимизација на базата, делумно враќање, додаток за
чистење, ресетирање на опцијата cron. OW Agenda при секое вчитување проверува дали
задачата е добро закажана и ја презакажува ако не е. Потсетниците, чистењето и
задржувањето не можат да запрат тивко.
Користење на вистински системски cron
WP-Cron зависи од сообраќајот. На слабо посетен сајт, подобро е системски cron:
// 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
Анти-спам и ограничувања на брзината
Резервацијата е јавна по природа: без сметка, без најава, без можен nonce. Затоа пет независни заштити работат однапред.
1. Замката за ботови (honeypot)
Формуларот содржи текстуално поле надвор од екранот, невидливо за човек и примамливо за бот. Полето мора да биде присутно и празно. Пополнето поле — или отсутно, што издава директно испраќање до API — враќа суво одбивање (HTTP 403), без искористливи детали.
2. Времето на пополнување
Страницата го пренесува временскиот печат од своето прикажување. Испраќање пристигнато помалку од 4 секунди по вчитувањето се одбива. И тука, отсутен или неисправен временски печат значи одбивање: во 1.3.0, овие две полиња станаа задолжителни — нивното изоставување едноставно ја исклучуваше контролата.
3. Часовната квота по адреса
5 резервации на час и по опсег. Кај IPv4, опсегот е адресата; кај IPv6, тоа е префиксот /64 — таму напаѓачот располага со 2⁶⁴ адреси, броењето на целата адреса не би ограничило ништо.
Бројачот се зголемува само по валидацијата на формуларот: посетител што трипати по ред ја погрешил е-поштата повеќе не е блокиран еден час за ништо.
4. Дневната горна граница на непотврдени барања
Најмногу 3 барања што чекаат потврда по е-пошта можат да задржат термин во ист ден. Без оваа граница, неколку испраќања беа доволни за да ги замрзнат сите термини на еден датум. Над неа, посетителот добива покана да проба подоцна или да избере друг ден (HTTP 429).
5. Заклучувањето на резервацијата
Резервирањето на термин и трошењето на покана се одвиваат во критична секција серијализирана со именувано MySQL заклучување, чие име е изведено од вашата база и од вашиот префикс на табели (значи два сајта на ист споделен хостинг не се блокираат меѓусебно). Ако заклучувањето не се добие за 5 секунди, барањето враќа јасен HTTP 503 наместо двоен термин.
Ова заклучување ја заменува, од 1.3.0, трансакцијата што се потпираше на гол SELECT:
под REPEATABLE READ, тој не поставува никакво заклучување на редот, и двајца истовремени
посетители можеа да го резервираат истото време.
А двојната потврда
Тоа е најефикасниот слој: дури и ако помине сè претходно, бот никогаш не стигнува до вашата агенда ниту до вашето сандаче, бидејќи известувањето до администраторот се испраќа само по клик на линк примен по е-пошта. Видете Двојната потврда по е-пошта.
GDPR
Агендата за термини ракува со потенцијални здравствени податоци, со контакт податоци и со историјати. Стандардните поставки се намерно конзервативни.
Согласност
Полето за согласност е задолжително и не е штиклирано однапред на јавниот формулар: «Се согласувам моите контакт податоци да се користат за управување со мојот термин.» Резервација без согласност се одбива на страна на серверот, не само во прелистувачот.
Минимизација
- Ниту една IP адреса не се чува во базата. Часовната квота користи привремен бројач (transient) чиј клуч е отпечаток од мрежниот опсег, избришан по еден час.
- Никаков user agent, никаков tracker, никакво колаче поставено од додатокот.
- Ниту еден податок не се испраќа до сервис од трета страна: без CDN, без надворешен повик, без телеметрија.
- Барањата што никогаш не биле потврдени се бришат по 48 часа — тие не оставаат никакви податоци зад себе.
- Откажаните термини повеќе не се враќаат од API на агендата: непотребните лични податоци не циркулираат.
Автоматска анонимизација
Поставка retention_months, 24 месеци стандардно. На секој час, завршените
термини постари од тој рок се анонимизираат на самото место: името се заменува со
«Анонимизирано», телефонот и е-поштата се празнат, пораката од клиентот и внатрешните
белешки се бришат. Редот останува, што ја зачувува статистичката историја на дејноста
(колку термини, кога, за која услуга) без да се чува ниту еден личен податок.
Ставете 0 за да ја исклучите автоматската анонимизација — со целосна свест за тоа.
Забелешка: анонимизацијата ги цели термините што носат адреса за е-пошта. Термин внесен рачно без е-пошта (само име и телефон) не е зафатен од автоматското чистење; избришете го рачно ако вашата политика на задржување го бара тоа.
Право на пристап и право на бришење
Додатокот не ги приклучува нативните WordPress извозници/бришачи (тие работат врз кориснички сметки, а клиентите немаат такви). За да обработите барање:
- Пристап — побарајте ја личноста во именикот на клиенти (име, телефон или е-пошта) и
поминете ги нејзините термини во агендата. Администраторите на базата можат и директно
да ги пребараат
{prefix}_owag_appointmentsи{prefix}_owag_customersпо колонатаcustomer_email/email. - Бришење — избришете го картонот од именикот, потоа откажете ги или оставете да се
анонимизираат соодветните термини. Итно бришење се прави во базата по
customer_email.
-- 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';
Регистар на обработки
За вашиот регистар: цел управување со термини; правен основ согласност (онлајн резервација) или извршување на договор / преддоговорни мерки (термин земен по телефон); категории идентитет, контакт податоци, содржина на пораката, внатрешни белешки; времетраење 24 месеци стандардно, потоа анонимизација; примачи ниту еден обработувач освен вашиот хостинг провајдер и вашата служба за испраќање е-пошта.
Shortcode-ови
[ow_agenda] — резервацијата за посетители
Се става на јавна страница. Без атрибути: услугата, времетраењето и работното време доаѓаат од поставките. Shortcode-от ги вчитува својот стилски лист и својата скрипта (вкупно под 12 KB, без зависности) и исцртува контејнер што се пополнува по првиот повик до API.
[ow_agenda]
Токму овој shortcode го толкува URL параметарот ?owag_invite=<token>: истата страница ја
служи и стандардната консултација и сеансите по покана.
[ow_agenda_admin] — страницата за управување
Се става на посветена страница. Без атрибути. Shortcode-от сам го управува пристапот:
- ненајавен посетител → линк за најава што враќа на страницата;
- најавен без capability
owag_manage→ порака за ограничен пристап; - најавен со capability → целосниот интерфејс (агенда, на чекање, клиенти, покани).
[ow_agenda_admin]
Двете страници се создаваат автоматски при активирањето со овие shortcode-ови. Ако сте ги
избришале, доволно е да создадете страница и да го залепите shortcode-от во неа — тогаш не
заборавајте да ја ажурирате опцијата owag_page_admin (или owag_page_booking) за
линковите во е-поштите и манифестот да покажуваат на вистинското место.
Самостојните страници
Четири URL параметри, пресретнати на која било страница од сајтот, произведуваат самостојни
страници што се служат надвор од темата (минимално исцртување, noindex,nofollow):
| URL | Улога |
|---|---|
?owag_verify=<uid> | Потврда на барањето од клиентот (двојна потврда) |
?owag_cancel=<uid> | Онлајн откажување од клиентот |
?owag_admin_action=confirm|refuse&uid=…&sig=… | Потврда / одбивање од административната е-пошта |
?owag_manifest=1 | Манифест за апликација на страницата Агенда |
Овие страници никогаш не извршуваат дејство при вчитување: тие прикажуваат резиме и копче. Ниту еден бот, ниту еден антивирус за пошта, ниту еден prefetch на прелистувач не може да потврди или откаже термин наместо човек.
REST API
Сите endpoint-и живеат под namespace owag/v1, на вообичаениот REST корен
(https://example.com/wp-json/owag/v1/…).
Јавни endpoint-и
Без автентикација: тоа се рутите на виџетот за резервација и на линковите примени по е-пошта. Нивната безбедност се потпира на случајни токени (32 хексадецимални знаци од криптографски генератор), на HMAC потписи, и на заштитите опишани во Анти-спам.
| Метод | Патека | Параметри | Улога |
|---|---|---|---|
GET | /public/days | from (Y-m-d, стандардно: денес), token (покана, изборно) | Враќа label, duration и days: 14 дена од from, секој со својот број слободни термини |
GET | /public/slots | date (Y-m-d, задолжително), token | Враќа slots: слободните почетни часови (HH:MM) |
POST | /public/book | date, time, name, phone, email, message, consent, website (замка), ts (временски печат), token | Го создава барањето; враќа status и порака за прикажување |
POST | /public/verify | uid | Потврдува барање со статус unverified |
POST | /public/cancel | uid | Откажува термин pending или confirmed, во рамките на рокот на најава |
POST | /public/admin-action | uid, action (confirm|refuse), sig | Потврдува или одбива од административната е-пошта (HMAC потпис) |
Пример за резервација:
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é…"
}
Административни endpoint-и
Сите бараат capability owag_manage и валиден WordPress REST nonce
(заглавие X-WP-Nonce).
| Метод | Патека | Параметри | Улога |
|---|---|---|---|
GET | /admin/agenda | from, to (Y-m-d) | events (бараниот опсег, без откажаните) и pending (сите претстојни барања на чекање) |
POST | /admin/appointment | kind (manual|block|consult|seance), date, time, duration (5–720 мин), label, name, phone, email, notes, force, send_email | Создава рачен термин или блокада |
POST | /admin/appointment/{id} | status (pending|confirmed|cancelled|done|noshow), name, phone, email, label, notes, date, time, duration, force, silent | Ажурира, поместува, менува статус. silent=1 го спречува секое испраќање на е-пошта |
GET | /admin/customers | q (пребарување) | Именикот (максимум 200 картони) |
POST | /admin/customers | name (задолжително), phone, email, notes | Создава картон |
POST | /admin/customers/{id} | исто | Ажурира картон |
DELETE | /admin/customers/{id} | — | Брише картон |
GET | /admin/invites | — | Отворените покани (никогаш искористени или ослободени, неистечени) |
POST | /admin/invites | name (задолжително), label (задолжително), duration (15–720), days_valid (1–365, стандардно 60), email, phone, send_email | Создава покана; враќа url и email_sent |
DELETE | /admin/invites/{id} | — | Брише покана |
GET | /admin/settings | — | Ефективните поставки |
POST | /admin/settings | JSON тело (видете Референца на поставките) | Ги зачувува поставките |
Секоја рута експлицитно ја декларира својата контрола на пристап; capability се проверува пред извршувањето на која било обработка.
Кодови на грешки
Грешките се стандардни WP_Error, со читлив код и HTTP статус.
| Код | HTTP | Значење |
|---|---|---|
owag_spam | 403 | Замката за ботови е пополнета, или временскиот печат недостасува / е премногу свеж |
owag_rate | 429 | Часовната квота е достигната за оваа адреса |
owag_day_full | 429 | Премногу барања што чекаат потврда на овој датум |
owag_busy | 503 | Заклучувањето за резервација не е добиено — обидете се повторно за миг |
owag_slot_taken | 409 | Терминот во меѓувреме е зафатен |
owag_overlap | 409 | Откриено преклопување (админ) — испратете повторно со force |
owag_invite_invalid | 404 | Непознат токен на покана |
owag_invite_used | 410 | Поканата е веќе искористена |
owag_invite_expired | 410 | Поканата истекла |
owag_too_late | 403 | Онлајн откажување надвор од рокот на најава |
owag_bad_sig | 403 | Невалиден HMAC потпис |
owag_not_found | 404 | Терминот или картонот не е пронајден |
owag_name, owag_phone, owag_email, owag_consent | 400 | Невалидно поле или недостасува согласност |
owag_bad_input, owag_bad_date | 400 | Невалиден датум, час или внес |
owag_noop | 400 | Празно барање за ажурирање |
owag_insert | 500 | Неуспешно запишување во базата |
Куки за програмери
Во 1.3.1, OW Agenda не изложува ниту филтер ниту јавен action: нема API за
проширување за документирање, и ништо од тоа што следува не треба да се погодува. Единствената
употреблива кука е закажаниот настан owag_hourly_event, на кој можете да го закачите
своето сопствено одржување:
add_action( 'owag_hourly_event', function () {
// Votre traitement horaire, exécuté juste après celui du plugin.
} );
За сè останато, REST API е точката за интеграција: таа изложува точно она што го прави интерфејсот, ни повеќе ни помалку.
Референца на поставките
Сите поставки собираат во една единствена опција, owag_settings. Читање и запишување
во PHP:
$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,
] ) );
Стандардни вредности
[
// 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',
]
Детали
| Поставка | Тип | Граници во интерфејсот | Ефект |
|---|---|---|---|
hours | низа | 1 или 2 интервали дневно | Два интервали овозможуваат пладневна пауза. Интервал се прифаќа само ако почетокот и крајот се валидни и ако почеток < крај. Празен ден = затворено |
slot_step | цел број | 5 → 120 мин | Растојание меѓу понудените часови. Колку е поситно, толку е подолг списокот |
consult_duration | цел број | 15 → 480 мин | Времетраење резервирано во агендата за веб консултација |
buffer | цел број | 0 → 120 мин | Пауза применета од двете страни на кандидат-терминот |
min_notice_hours | цел број | 0 → 168 ч | Ништо не се нуди пред сега + овој рок |
max_advance_days | цел број | 7 → 365 д | Хоризонт над кој повеќе не се нуди ниту еден термин |
auto_confirm | 0 / 1 | — | Рачно одобрување или моментална потврда |
email_verify | 0 / 1 | — | Двојна потврда по е-пошта (да се остави активна) |
cancel_notice_hours | цел број | 0 → 168 ч | По него, онлајн откажувањето се одбива со порака што поканува да се јави |
notify_email | е-пошта | — | Примач на административните известувања; служи и како ORGANIZER во ICS датотеките |
retention_months | цел број | 0 → 120 месеци | Анонимизација на завршените термини; 0 исклучува |
consult_label | текст | — | Наслов прикажан на виџетот за резервација |
Две неконфигурабилни константи вреди да се знаат, бидејќи тие го управуваат однесувањето на двојната потврда: терминот на непотврдено барање се задржува 45 минути, а барањето се брише по 48 часа.
Зачувувањето преку REST API ги прифаќа истите клучеви во JSON; целите броеви се сведуваат на минимум нула, адресата за известување се прифаќа само ако е валидна, а секој временски интервал се ревалидира на страна на серверот.
Зачувани податоци
Три табели, сите со префиксот на вашата инсталација. Датумите се DATETIME во локално
време на сајтот, никогаш во UTC — токму тоа ги прави барањата читливи, а споредбите на
времиња тривијални.
{prefix}_owag_appointments
| Колона | Тип | Белешки |
|---|---|---|
id | BIGINT | Примарен клуч |
uid | CHAR(32) | Уникатен јавен токен (хексадецимален, криптографски генератор). Служи како клуч на линковите за потврда, откажување и административно дејство, и како ICS UID |
kind | VARCHAR(16) | consult, seance, manual, block |
service_label | VARCHAR(120) | Прикажан назив |
customer_name, customer_phone, customer_email | VARCHAR | Контакт податоци |
customer_msg | TEXT | Порака оставена од клиентот |
admin_notes | TEXT | Внатрешни белешки, никогаш испратени до клиентот |
start_dt, end_dt | DATETIME | Граници на терминот (индексирани по start_dt) |
status | VARCHAR(16) | unverified, pending, confirmed, cancelled, done, noshow |
source | VARCHAR(16) | web, invite, admin |
invite_id | BIGINT | Изворната покана, ако ја има |
reminder_sent | TINYINT | Знаменце за потсетник (се враќа на 0 при преместување) |
created_at, updated_at | DATETIME | updated_at го храни бројот на ICS ревизијата |
{prefix}_owag_invites
id, token (CHAR(32), уникатен), контакт податоци на клиентот, service_label,
duration_min, expires_at, appointment_id (се пополнува кога линкот е искористен, се
враќа на NULL ако терминот се откаже), created_at.
{prefix}_owag_customers
id, name, phone, email, notes, created_at, updated_at. Индекс на name и
email.
Само една опција ја носи конфигурацијата (owag_settings); останатите се технички:
owag_admin_secret (HMAC тајна), owag_db_version, owag_pages_created,
owag_page_booking, owag_page_admin.
Интернационализација
Целиот интерфејс може да се преведе: административните поставки, виџетот за резервација,
страницата Агенда, самостојните страници, пораките на API и шаблоните за е-пошта. Изворниот
јазик е англискиот; додатокот го декларира доменот за превод ow-agenda и патеката
/languages.
Пакетот го испорачува шаблонот languages/ow-agenda.pot. Обезбеден е целосен француски
превод, изработен од оригиналната формулација на интерфејсот.
Рачно инсталирање превод
Компајлирајте го .po и ставете го .mo во папката со преводи на WordPress:
msgfmt ow-agenda-fr_FR.po -o ow-agenda-fr_FR.mo
# puis : wp-content/languages/plugins/ow-agenda-fr_FR.mo
WordPress го вчитува каталогот при првиот преведен текст; не е потребен никаков рачен повик.
Две стапици за преведувачите
- Текстовите наменети за JavaScript користат нумерирани ознаки
(
%1$s,%2$s) и никогаш гол%s: малиот форматер вграден во скриптите ги разбира само тие. Ненумерирана ознака би се прикажала буквално. - Два текста се PHP формати за датум, не реченици:
l, F j, Y \a\t g:i aиl j F Y \a\t H:i. Преведете ги како формати (преуредување на токените, escape на буквалните букви со обратна коса црта). Францускиот користиl j F Y \à H\hi.
Деинсталација
Деактивирањето на додатокот прави само едно: ја брише часовната закажана задача. Вашите податоци, вашите поставки и вашите страници остануваат недопрени, и сè продолжува при повторното активирање.
Бришењето на додатокот од WordPress ја извршува целосната деинсталација:
- бришење на трите табели (
owag_appointments,owag_invites,owag_customers); - бришење на опциите
owag_settings,owag_admin_secret,owag_db_version,owag_pages_created,owag_page_booking,owag_page_admin; - бришење на закажаната задача;
- одземање на capability
owag_manageод улогата administrator.
Двете страници создадени при активирањето не се бришат — тие можеби се преработени, ставени во мени, индексирани. На вас е да ги фрлите во корпата ако повеќе не ги сакате.
Бришењето на табелите е неповратно. Извезете ја вашата база претходно ако историјата на термините има вредност за вас.
Решавање проблеми
Ниту еден термин не се појавува на страницата за резервација
Поминете го списокот по редослед:
- Дали е внесено работното време за тој ден? Празен ден е затворен ден.
- Минималната најава (24 ч стандардно) нужно ги крие денес и дел од утре.
- Дали времетраењето собира во интервалот? Со интервал 09:00–12:00 и времетраење од 240 минути, не може да постои ниту еден термин.
- Хоризонтот: деновите над
max_advance_daysникогаш не се нудат. - Паузата: широка пауза врз натоварен распоред може сè да затвори.
- Некоја блокада можеби го покрива денот. Отворете ја страницата Агенда на тој ден.
- Временската зона на сајтот (Settings → General): погрешно поставена зона ги поместува сите пресметки.
Е-поштите не пристигнуваат
Тоа речиси секогаш е испорачливоста, а не додатокот.
- Проверете дали терминот навистина постои на страницата Агенда: ако е таму, додатокот си ја завршил работата.
- Инсталирајте SMTP додаток (Fluent SMTP, WP Mail SMTP…). Функцијата
mail()на PHP се одбива од огромното мнозинство приемни сервери. - Проверете ги SPF, DKIM и DMARC за вашиот домен.
- Тестирајте ја адресата во OW Agenda → Административните известувања се праќаат на: невалидна адреса тивко ги блокира известувањата.
Потсетникот од претходниот ден не тргнал
Потсетникот зависи од WP-Cron, кој зависи од сообраќајот. На слабо посетен сајт, префрлете се на вистински системски cron (видете Потсетници и закажана задача). Проверете исто така дали терминот е навистина потврден, дали носи адреса за е-пошта и дали не е блокада.
Страницата Агенда прикажува «Пристапот е резервиран за тимот»
Најавениот корисник ја нема capability owag_manage. Таа им се дава на администраторите
при активирањето; за другите улоги, видете Инсталација.
Копчето «Потврди» во е-поштата прикажува «Невалиден линк»
Три можни причини: линкот е скратен од клиентот за пошта (обидете се да ја копирате целата URL-адреса), терминот е веќе обработен (пораката го прецизира тоа), или HMAC тајната на сајтот е регенерирана. Во последниот случај, работете преку страницата Агенда: старите линкови повеќе не можат да се потврдат, по конструкција.
Два термина се наоѓаат на исто место
Од 1.3.0, тоа е невозможно преку онлајн резервацијата. Меѓутоа, администраторот може да
форсира преклопување од страницата Агенда (додатокот го сигнализира тоа и бара потврда):
прво проверете дали не станува збор за намерно форсирање. Проверете и дали вашата база
навистина поддржува GET_LOCK() — егзотичен хостинг тогаш би враќал грешки 503 при
резервацијата наместо дупликати.
Страниците «Закажи термин» и «Агенда» не се создадени
Тие се создаваат само еднаш, при првото активирање. Ако сте ги избришале, создадете две
страници со shortcode-овите [ow_agenda] и [ow_agenda_admin], потоа насочете ги кон нив
опциите owag_page_booking и owag_page_admin за да останат точни линковите во е-поштите:
update_option( 'owag_page_booking', 42 ); // ID de votre page de réservation
update_option( 'owag_page_admin', 43 ); // ID de votre page Agenda
Календарската датотека не е прикачена
Датотеката се запишува во привремениот директориум на серверот преку WordPress API за датотеки. Ако тој директориум не е достапен за запишување (квота, дозволи, заклучен хостинг), е-поштата тргнува без прилог наместо да падне. Проверете ги дозволите за запишување и просторот на дискот.
Времињата се поместени за еден час
Settings → General → Timezone. Изберете град (Europe/Skopje) наместо фиксен UTC
поместок: само именувана зона го управува преминот на летно време.
ЧПП
Дали OW Agenda е навистина бесплатен?
Да. GPL-2.0-or-later, може да се преземе како .zip од
https://optionweb.dev/mk/addons/ow-agenda/. Без Pro верзија, без лиценцен клуч, без
заклучена функција, без сметка за отворање, без квота на термини.
Дали онлајн термините ги земаат предвид термините земени по телефон? Да. Секој настан од агендата — веб резервација, термин внесен рачно, сеанса по покана, блокада — го прави својот временски период недостапен за онлајн резервација.
Мора ли клиентот да создаде сметка? Не. Без сметка, без лозинка. Сите дејства на клиентот (потврда, откажување) минуваат низ приватни линкови примени по е-пошта.
Може ли да се управуваат повеќе практичари или повеќе простории? Не. OW Agenda опишува само еден распоред. За два независни распореди, потребни се два сајта (или два сајта од multisite мрежа).
Дали се синхронизира со Google Calendar? Во смисла што е важна за клиентот: да. Секоја потврда носи стандардна календарска датотека што го додава — и го ажурира, и го брише — настанот во Google Calendar, Outlook или календарот на iPhone. Меѓутоа, додатокот не ги чита вашите надворешни календари: вашата лична недостапност се внесува како блокади.
Може ли да се наплати капар при резервацијата? Не, тоа е надвор од свесно поставениот опфат на додатокот.
Колку услуги може да се понудат онлајн? Само една, чиј назив и времетраење вие ги избирате. Останатите услуги одат преку поканите за сеанса, кои ви дозволуваат да го определите називот и времетраењето од случај до случај. Овој избор е намерен: мени со услуги на јавна страница ги умножува лошо насочените барања.
Дали работи на multisite? Да. Секој сајт од мрежата има свои табели, свои поставки и своја агенда.
Дали додатокот го забавува сајтот? Не. Никаква скрипта не се вчитува надвор од двете засегнати страници; виџетот за резервација тежи под 12 KB, без jQuery и без framework. Периодичната работа собира во една часовна задача.
Што се случува ако клиент никогаш не ја потврди својата е-пошта? Неговиот термин станува достапен по 45 минути, а неговото барање се брише по 48 часа. Вие никогаш не слушате за тоа.
Каде да се најде поддршка?
- Портал за поддршка: https://optionweb.dev/mk/addons/support/
- Е-пошта: support@optionweb.dev
- Документација: https://optionweb.dev/mk/addons/ow-agenda/
Changelog
1.3.1
Усогласеност
- Самостојните страници за дејство, за потврда и за откажување повеќе не го печатат својот
CSS ниту својот JavaScript инлајн: и двете сега се регистрирани датотеки што се служат
преку WordPress enqueue API. Двете променливи бои на копчињата минуваат низ прилагодени
CSS својства, а скриптата се конфигурира преку
wp_localize_script(). - Каталозите со преводи повеќе не се вградени: се испорачува само
languages/ow-agenda.pot, а францускиот се дистрибуира преку јазичните пакети на WordPress.org што се хранат од translate.wordpress.org. - Минималната верзија на WordPress се враќа на 6.3: ништо во пакетот повеќе не зависи од откривањето на вградените преводи воведено во 6.7.
REST API
- Секоја административна рута сега го декларира својот
permission_callbackексплицитно наместо да го дели прекуarray_merge(). Контролата на capability и претходно се применуваше; сега е видлива за статичка анализа.
Без промена во однесувањето.
1.3.0
Интернационализација
- Додатокот е целосно преводлив (домен
ow-agenda, англискиот како изворен јазик): поставки, јавни страници, пораки на API, е-пошти и JavaScript интерфејс. - Испорачан шаблон
languages/ow-agenda.potи целосен француски превод.
Безбедност
- Јавните идентификатори на термините и токените на поканите се генерираат со
криптографски генератор (
random_bytes()). Тие токени се единствената автентикација на линковите за откажување, потврда и покана. - Замката за ботови и временскиот печат станаа задолжителни: нивното изоставување ги исклучуваше анти-спам контролите.
- Часовната квота се агрегира по /64 префикс кај IPv6, а дневна горна граница ги ограничува непотврдените барања — посетител повеќе не може да ги задржи сите термини на еден ден.
- Квотата се одбива дури по валидацијата на формуларот: печатна грешка повеќе не блокира легитимен посетител цел час.
Сигурност
- Истовремените резервации на ист термин се серијализираат со именувано MySQL заклучување. Претходната трансакција не поставуваше никакво заклучување на редот: двајца посетители можеа да го резервираат истото време.
- Потсетникот од претходниот ден користи подвижен прозорец од 12 до 36 ч и го надоместува своето задоцнување; секое испраќање е атомски резервирано, две извршувања на cron повеќе не можат двапати да го испратат истиот потсетник.
- Часовната задача се презакажува автоматски ако исчезне: потсетниците, чистењето и анонимизацијата повеќе не можат да запрат тивко.
- Преместувањето на термин го ажурира календарот на клиентот (
SEQUENCE,METHOD:REQUEST, организатор и учесник); откажувањето испраќаMETHOD:CANCELшто го брише настанот. - Датумите во виџетот се пресметуваат во локално време, а не во UTC: нема повеќе изгубен ден за посетителите источно од UTC.
- Откажувањето на термин произлезен од покана ја ослободува поканата, која повторно станува употреблива.
- Откажаните термини и истечените непотврдени барања повеќе не се враќаат во агендата: помалку лични податоци во одговорите, нема повеќе фантомски термини.
1.2.1
- Усогласеност со Plugin Check: escape на излезите, чистење на влезовите, nonce на поставките, readme.
- Деинсталацијата ја брише и табелата на именикот на клиенти и HMAC тајната.
1.2.0
- HTML е-пошти (распоред во картичка, акцентна боја на сајтот) за сите известувања.
- Копчиња Потврди / Одбиј во административната е-пошта (линкови потпишани со HMAC).
- Именик на клиенти: пребарување, создавање, уредување, бришење, кратенки кон нов термин и кон покана.
1.1.0
- Двојна потврда по е-пошта против ботовите (терминот се задржува 45 минути, чистење по 48 часа).
1.0.0
- Првична верзија: онлајн резервација, mobile-first административна агенда, покани за сеанса, е-пошти со календарска датотека и потсетник од претходниот ден.
Создадено од OptionWeb — Julien Daniel, Châtelet, Белгија.