true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [‚Content-Type: application/json‘],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
CURLOPT_TIMEOUT => 12,
]);
$raw = curl_exec($ch);
$err = curl_error($ch);
$code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($raw === false) return [‚ok’=>false, ‚error’=>’curl_error‘, ‚detail’=>$err];
$data = json_decode($raw, true);
if (!is_array($data)) $data = [‚raw’=>$raw];
return [‚ok’=>($code >= 200 && $code < 300), 'code'=>$code, ‚data’=>$data];
}
function tg_send_message(string $text): array {
if (TG_API_URL !== “ && TG_SECRET !== “) {
$url = TG_API_URL;
// relatívna → absolútna
if (is_string($url) && strlen($url) && $url[0] === ‚/‘) {
$scheme = (!empty($_SERVER[‚HTTPS‘]) && $_SERVER[‚HTTPS‘] !== ‚off‘) ? ‚https‘ : ‚http‘;
$host = $_SERVER[‚HTTP_HOST‘] ?? “;
$url = $scheme . ‚://‘ . $host . $url;
}
$res = http_post_json($url, [
‚secret‘ => TG_SECRET,
‚message‘ => $text,
‚text‘ => $text,
‚parse_mode‘ => ‚HTML‘,
‚disable_web_page_preview‘ => true
]);
if ($res[‚ok‘] && !empty($res[‚data‘][‚ok‘])) {
return [‚ok’=>true, ‚via’=>’wp‘, ‚resp’=>$res[‚data‘]];
}
return [‚ok’=>false, ‚via’=>’wp‘, ‚resp’=>$res];
}
if (BOT_TOKEN === “ || CHAT_ID === “) {
return [‚ok’=>false, ‚error’=>’missing_config‘, ‚detail’=>’Nastav TG_API_URL+TG_SECRET alebo BOT_TOKEN+CHAT_ID‘];
}
$url = ‚https://api.telegram.org/bot‘ . BOT_TOKEN . ‚/sendMessage‘;
$res = http_post_json($url, [
‚chat_id‘ => CHAT_ID,
‚text‘ => $text,
‚parse_mode‘ => ‚HTML‘,
‚disable_web_page_preview‘ => true
]);
if ($res[‚ok‘] && !empty($res[‚data‘][‚ok‘])) {
return [‚ok’=>true, ‚via’=>’bot‘, ‚resp’=>$res[‚data‘]];
}
return [‚ok’=>false, ‚via’=>’bot‘, ‚resp’=>$res];
}
function build_tg_message(array $v, string $title = „📅 Nová rezervácia„): string {
$esc = fn($s) => str_replace([‚&‘,‘<','>‚], [‚&‘,'<‚,‘>‘], (string)$s);
$lines = [];
$lines[] = $title;
$lines[] = „🗓️ „.$esc($v[‚date‘]).“ ⏰ „.$esc($v[‚time‘]).“„;
$lines[] = „👥 „.$esc($v[‚people‘]).“ os. • ⏳ „.$esc($v[‚dur‘]).“ min“;
$lines[] = „👤 „.$esc($v[‚name‘]);
$digits = preg_replace(‚/\D+/‘, “, (string)$v[‚phone‘]);
$lines[] = „📞 „.$esc($v[‚phone‘]).“„;
if (!empty(trim((string)$v[‚note‘]))) $lines[] = „📝 „.$esc($v[‚note‘]);
$lines[] = „🆔 Rezervácia
".$esc($v['id'])."„;
return implode(„\n“, $lines);
}
function validate_payload(string $date, string $time, int &$people, string $name, string $phone, int $durMin, string &$note): array {
if ($date === “ || $time === “ || $people <= 0 || $name === '' || $phone === '' || $durMin <= 0) {
return ['ok'=>false,’error’=>’missing_fields‘,’message’=>’Vyplň všetky povinné polia.‘];
}
// max 6 osôb (zákazník má aj možnosť „viac“ cez poznámku)
if ($people > 6) $people = 6;
// dĺžka len 30/60/90/120
if (!in_array($durMin, [30,60,90,120], true)) {
return [‚ok’=>false,’error’=>’dur_invalid‘,’message’=>’Dĺžka návštevy môže byť len 30/60/90/120 min.‘];
}
if (mb_strlen($note) > 400) $note = mb_substr($note, 0, 400);
// telefón digits 9–15
$digits = preg_replace(‚/\D+/‘, “, $phone);
if (strlen($digits) < 9 || strlen($digits) > 15) {
return [‚ok’=>false,’error’=>’phone_invalid‘,’message’=>’Telefón musí mať 9 až 15 číslic.‘];
}
$startTs = strtotime($date.‘ ‚.$time);
if (!$startTs) return [‚ok’=>false,’error’=>’invalid_datetime‘,’message’=>’Neplatný dátum alebo čas.‘];
// zatvorené dni (nedeľa/pondelok)
$day = (int)date(‚w‘, $startTs); // 0=Sun,1=Mon
if ($day === 0 || $day === 1) return [‚ok’=>false,’error’=>’closed_day‘,’message’=>’V nedeľu a pondelok máme zatvorené.‘];
// max 1 mesiac dopredu
$today0 = strtotime(date(‚Y-m-d 00:00:00‘));
$maxTs = strtotime(‚+1 month‘, $today0);
if ($startTs < $today0 || $startTs > $maxTs) return [‚ok’=>false,’error’=>’date_out_of_range‘,’message’=>’Dátum môže byť max. 1 mesiac dopredu.‘];
// čas 11:00–20:00
$hm = date(‚H:i‘, $startTs);
if ($hm < '11:00' || $hm > ’20:00′) return [‚ok’=>false,’error’=>’time_out_of_range‘,’message’=>’Rezervácie prijímame iba v čase 11:00–20:00.‘];
// iba 00 alebo 30 min
$minute = (int)date(‚i‘, $startTs);
if (!in_array($minute, [0,30], true)) return [‚ok’=>false,’error’=>’time_step_invalid‘,’message’=>’Čas musí byť po 30 minútach (napr. 18:00 alebo 18:30).‘];
return [‚ok’=>true,’startTs’=>$startTs,’digits’=>$digits];
}
/* =======================
API ROUTES (AJAX)
======================= */
if (isset($_GET[‚api‘])) {
$action = (string)($_GET[‚action‘] ?? “);
if ($action === ‚add‘) {
$date = trim((string)($_POST[‚date‘] ?? “));
$time = trim((string)($_POST[‚time‘] ?? “));
$people = (int)($_POST[‚people‘] ?? 0);
$name = trim((string)($_POST[‚name‘] ?? “));
$phone = trim((string)($_POST[‚phone‘] ?? “));
$durMin = (int)($_POST[‚dur‘] ?? 0);
$note = trim((string)($_POST[‚note‘] ?? “));
$val = validate_payload($date, $time, $people, $name, $phone, $durMin, $note);
if (!$val[‚ok‘]) json_out($val, 400);
$startTs = (int)$val[‚startTs‘];
$row = [
‚id‘ => ‚RZ-‚ . date(‚Ymd-His‘) . ‚-‚ . substr(bin2hex(random_bytes(3)),0,6),
‚created‘ => time(),
‚start‘ => $startTs,
‚date‘ => $date,
‚time‘ => $time,
‚people‘ => $people,
‚name‘ => $name,
‚phone‘ => $phone,
‚dur‘ => $durMin,
‚note‘ => $note,
‚status‘ => ‚new‘,
];
$okSave = append_jsonl($resFile, $row);
if (!$okSave) json_out([‚ok’=>false,’error’=>’save_failed‘,’message’=>’Nepodarilo sa uložiť rezerváciu.‘], 500);
$tgMsg = build_tg_message($row, „📅 Nová rezervácia„);
$tgRes = tg_send_message($tgMsg);
json_out([‚ok’=>true,’reservation’=>$row,’telegram’=>$tgRes]);
}
json_out([‚ok’=>false,’error’=>’unknown_action‘,’message’=>’Neznáma akcia.‘], 400);
}
?>
📅 Rezervácia stola
Rezervácie akceptujeme automaticky. V prípade problému alebo nedostatku miesta sa Vám ozveme.
