PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/home/helphum.com/www/wp-content/plugins/optinmonster/
Upload File :
Current File : /home/helphum.com/www/wp-content/plugins/optinmonster/optin-monster-wp-api.php
<?php
/**
 * Plugin Name: OptinMonster
 * Plugin URI:  https://optinmonster.com
 * Description: OptinMonster is the best WordPress popup builder plugin that helps you grow your email newsletter list and sales with email popups, exit intent popups, floating bars and more!
 * Author:      OptinMonster Popup Builder Team
 * Author URI:  https://optinmonster.com
 * Version:     2.13.7
 * Text Domain: optin-monster-api
 * Domain Path: languages
 *
 * WC requires at least: 3.2
 * WC tested up to:      7.7
 * Requires at least:    4.7
 * Requires PHP:         5.3
 * Tested up to:         6.3
 *
 * @package OMAPI
 *
 * OptinMonster is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * any later version.
 *
 * OptinMonster is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with OptinMonster. If not, see <https://www.gnu.org/licenses/>.
 */

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

// Autoload the class files.
spl_autoload_register( 'OMAPI::autoload' );

// Store base file location.
define( 'OMAPI_FILE', __FILE__ );

/**
 * Main plugin class.
 *
 * @since 1.0.0
 *
 * @package OMAPI
 * @author  Thomas Griffin
 */
#[\AllowDynamicProperties]
class OMAPI {

	/**
	 * Holds the class object.
	 *
	 * @since 1.0.0
	 *
	 * @var object
	 */
	public static $instance;

	/**
	 * Plugin version, used for cache-busting of style and script file references.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	public $version = '2.13.7';

	/**
	 * The name of the plugin.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	public $plugin_name = 'OptinMonster';

	/**
	 * Unique plugin slug identifier.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	public $plugin_slug = 'optinmonster';

	/**
	 * Plugin file.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	public $file = __FILE__;

	/**
	 * The assets base URL for this plugin.
	 *
	 * @var string
	 */
	public $url;

	/**
	 * Defines the properties that can be autoloaded from classes.
	 *
	 * @since 2.11.2
	 *
	 * @var array
	 */
	protected static $class_map = array(
		'ajax'          => 'OMAPI_Ajax',
		'blocks'        => 'OMAPI_Blocks',
		'type'          => 'OMAPI_Type',
		'output'        => 'OMAPI_Output',
		'shortcode'     => 'OMAPI_Shortcode',
		'revenue'       => 'OMAPI_RevenueAttribution',
		'woocommerce'   => 'OMAPI_WooCommerce',
		// @since 2.9.0
		'wpforms'       => 'OMAPI_WPForms',
		'elementor'     => 'OMAPI_Elementor',
		'mailpoet'      => 'OMAPI_MailPoet',
		'edd'           => 'OMAPI_EasyDigitalDownloads',
		'memberpress'   => 'OMAPI_MemberPress',
		'rest_api'      => 'OMAPI_RestApi',
		'actions'       => 'OMAPI_Actions',
		'menu'          => 'OMAPI_Menu',
		'save'          => 'OMAPI_Save',
		'refresh'       => 'OMAPI_Refresh',
		'validate'      => 'OMAPI_Validate',
		'welcome'       => 'OMAPI_Welcome',
		'promos'        => 'OMAPI_Promos',
		'review'        => 'OMAPI_Review',
		'sites'         => 'OMAPI_Sites',
		'notifications' => 'OMAPI_Notifications',
		'classicEditor' => 'OMAPI_ClassicEditor',
		// @since 2.10.0
		'wordfence'     => 'OMAPI_Wordfence',
		'urls'          => 'OMAPI_Urls',
	);

	/**
	 * Primary class constructor.
	 *
	 * @since 1.0.0
	 */
	public function __construct() {

		// Load the plugin textdomain.
		add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );

		// Load the plugin widgets.
		add_action( 'widgets_init', array( $this, 'widgets' ) );

		// Define Constants.
		add_action( 'init', array( $this, 'define_constants' ) );

		// Load the plugin.
		add_action( 'init', array( $this, 'init' ) );

		// Hide the unrelated admin notices.
		add_action( 'admin_print_scripts', array( $this, 'hide_unrelated_admin_notices' ) );

		// PHP version check.
		add_action( 'admin_init', array( $this, 'check_php_version' ) );

		// Filter the WooCommerce category/tag REST API responses.
		add_filter( 'woocommerce_rest_prepare_product_cat', 'OMAPI_WooCommerce::add_category_base_to_api_response' );
		add_filter( 'woocommerce_rest_prepare_product_tag', 'OMAPI_WooCommerce::add_tag_base_to_api_response' );
	}

	/**
	 * Loads the plugin textdomain for translation.
	 *
	 * @since 1.0.0
	 */
	public function load_plugin_textdomain() {
		$domain = 'optin-monster-api';
		// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
		$locale = apply_filters( 'plugin_locale', get_locale(), $domain );

		load_textdomain( $domain, WP_LANG_DIR . '/' . $domain . '/' . $domain . '-' . $locale . '.mo' );
		load_plugin_textdomain( $domain, false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );

	}

	/**
	 * Registers the OptinMonster widgets.
	 *
	 * @since 1.0.0
	 */
	public function widgets() {

		// To do: add widgets.
		register_widget( 'OMAPI_Widget' );

	}

	/**
	 * Set the OM constants.
	 *
	 * @since 2.0.2
	 */
	public function define_constants() {
		$this->url = plugin_dir_url( __FILE__ );

		do_action( 'optin_monster_before_define_constants', $this );

		// Define necessary plugin constants.
		if ( ! defined( 'OPTINMONSTER_APP_URL' ) ) {
			define( 'OPTINMONSTER_APP_URL', 'https://app.optinmonster.com' );
		}

		if ( ! defined( 'OPTINMONSTER_URL' ) ) {
			define( 'OPTINMONSTER_URL', 'https://optinmonster.com' );
		}

		if ( ! defined( 'OPTINMONSTER_API_URL' ) ) {
			define( 'OPTINMONSTER_API_URL', 'https://api.omwpapi.com' );
		}

		if ( ! defined( 'OPTINMONSTER_CDN_URL' ) ) {
			define(
				'OPTINMONSTER_CDN_URL',
				is_admin()
					? 'https://a.omwpapi.com'
				: 'https://a.omappapi.com'
			);
		}

		if ( ! defined( 'OPTINMONSTER_VUE_ASSETS_URL' ) ) {
			define( 'OPTINMONSTER_VUE_ASSETS_URL', OPTINMONSTER_CDN_URL . '/app/wp-plugin/build' );
		}

		if ( ! defined( 'OPTINMONSTER_VUE_ASSETS_PATH' ) ) {
			define( 'OPTINMONSTER_VUE_ASSETS_PATH', '' );
		}

		if ( ! defined( 'OPTINMONSTER_APIJS_URL' ) ) {
			define( 'OPTINMONSTER_APIJS_URL', OPTINMONSTER_CDN_URL . '/app/js/api.min.js' );
		}

		if ( ! defined( 'OPTINMONSTER_SHAREABLE_LINK' ) ) {
			define( 'OPTINMONSTER_SHAREABLE_LINK', 'https://app.monstercampaigns.com' );
		}
	}

	/**
	 * Loads the plugin into WordPress.
	 *
	 * @since 1.0.0
	 */
	public function init() {

		// Load our global option.
		$this->load_option();

		// Load global components.
		$this->load_global();

		add_action( 'rest_api_init', array( $this, 'load_rest' ) );

		// Load admin only components.
		if ( is_admin() ) {
			$this->load_admin();
		}

		// Run hook once OptinMonster has been fully loaded.
		do_action( 'optin_monster_api_loaded' );
	}

	/**
	 * Sets our options if not found in the DB.
	 *
	 * @since 1.0.0
	 */
	public function load_option() {

		// Check/set the plugin options.
		$option = get_option( 'optin_monster_api' );
		if ( empty( $option ) ) {
			$option = self::default_options();
			update_option( 'optin_monster_api', $option );
		}

		$review           = get_option( 'omapi_review' );
		$review_installed = ! empty( $review['time'] ) && is_numeric( $review['time'] );
		$review_dismissed = ! empty( $review['dismissed'] );

		if ( ! $review_installed ) {
			$review = array(
				'time'      => time(),
				'dismissed' => $review_dismissed,
			);
			update_option( 'omapi_review', $review );
		}

		// Check/set the installation date.
		if ( empty( $option['installed'] ) ) {

			// If the review was dismissed, we know the plugin was installed at least a day
			// before the notice was shown and dismissed. Otherwise, the review timestamp
			// should be pretty close to the install date.
			$option['installed'] = $review_dismissed ? $review['time'] - DAY_IN_SECONDS : $review['time'];

			// Store the plugin install date.
			update_option( 'optin_monster_api', $option );
		}
	}

	/**
	 * Loads all global related classes into scope.
	 *
	 * @since 1.0.0
	 */
	public function load_global() {

		// Register global components.
		$this->ajax        = new OMAPI_Ajax();
		$this->blocks      = new OMAPI_Blocks();
		$this->type        = new OMAPI_Type();
		$this->output      = new OMAPI_Output();
		$this->shortcode   = new OMAPI_Shortcode();
		$this->woocommerce = new OMAPI_WooCommerce();
		$this->wpforms     = new OMAPI_WPForms();
		$this->elementor   = new OMAPI_Elementor();
		$this->edd         = new OMAPI_EasyDigitalDownloads();
		$this->memberpress = new OMAPI_MemberPress();

		if ( defined( 'DOING_CRON' ) && DOING_CRON && ! $this->actions ) {
			$this->actions = new OMAPI_Actions();
		}

		// Fire a hook to say that the global classes are loaded.
		do_action( 'optin_monster_api_global_loaded' );

	}

	/**
	 * Loads all REST API related classes into scope.
	 *
	 * @since 1.8.0
	 */
	public function load_rest() {

		// Register global components.
		$this->actions       = new OMAPI_Actions();
		$this->rest_api      = new OMAPI_RestApi();
		$this->notifications = new OMAPI_Notifications();

		// Fire a hook to say that the global classes are loaded.
		do_action( 'optin_monster_api_rest_loaded' );
	}

	/**
	 * Loads all admin related classes into scope.
	 *
	 * @since 1.0.0
	 */
	public function load_admin() {

		// Register admin components.
		$this->actions       = new OMAPI_Actions();
		$this->menu          = new OMAPI_Menu();
		$this->validate      = new OMAPI_Validate();
		$this->welcome       = new OMAPI_Welcome();
		$this->promos        = new OMAPI_Promos();
		$this->notifications = new OMAPI_Notifications();
		// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
		$this->classicEditor = new OMAPI_ClassicEditor();
		$this->wordfence     = new OMAPI_Wordfence();

		// Fire a hook to say that the admin classes are loaded.
		do_action( 'optin_monster_api_admin_loaded' );

	}

	/**
	 * Internal method that returns a optin based on ID.
	 *
	 * @since 1.0.0
	 *
	 * @param int $id     The optin ID used to retrieve a optin.
	 * @return array|bool Array of optin data or false if none found.
	 */
	public function get_optin( $id ) {
		$optin = get_post( absint( $id ) );
		return $this->add_campaign_properties( $optin );
	}

	/**
	 * Internal method that returns a optin based on slug.
	 *
	 * @since 1.0.0
	 *
	 * @param string $slug The optin slug used to retrieve a optin.
	 * @return array|bool  Array of optin data or false if none found.
	 */
	public function get_optin_by_slug( $slug ) {
		$optin = get_page_by_path( sanitize_text_field( $slug ), OBJECT, OMAPI_Type::SLUG );
		return $this->add_campaign_properties( $optin );
	}

	/**
	 * Get all data for given campaign (optin).
	 *
	 * @since  1.9.10
	 *
	 * @param  WP_Post $campaign The campaign post object.
	 *
	 * @return array
	 */
	public function collect_campaign_data( $campaign ) {
		$campaign = $this->validate_is_campaign_type( $campaign );
		if ( empty( $campaign ) ) {
			return array(
				'id'        => '',
				'post'      => $campaign,
				'type'      => '',
				'inline'    => false,
				'post_meta' => array(),
			);
		}

		$meta = array();
		$keys = get_post_meta( $campaign->ID );

		if ( ! empty( $keys ) ) {
			foreach ( $keys as $key => $x ) {
				$val = get_post_meta( $campaign->ID, $key, true );
				switch ( $key ) {
					case '_omapi_never':
					case '_omapi_only':
						$val = OMAPI_Utils::unique_array( $val );
						break;
					case '_omapi_taxonomies':
						$val = ! empty( $val )
							? array_map( array( 'OMAPI_Utils', 'unique_array' ), $val )
							: array();
						break;
				}
				$meta[ $key ] = $val;
			}
		}

		$type = get_post_meta( $campaign->ID, '_omapi_type', true );

		return array(
			'id'        => $campaign->post_name,
			'post'      => $campaign,
			'type'      => $type,
			'inline'    => OMAPI_Utils::is_inline_type( $type ),
			'post_meta' => $meta,
		);
	}

	/**
	 * Internal method that returns all optins created on the site.
	 *
	 * @since 1.0.0
	 *
	 * @param array $args Array of args to modify the query for retreiving optins.
	 * @return array|bool Array of optin data or false if none found.
	 */
	public function get_optins( $args = array() ) {

		$optins = get_posts(
			wp_parse_args(
				$args,
				array(
					'no_found_rows'          => true,
					'nopaging'               => true,
					'post_type'              => OMAPI_Type::SLUG,
					'posts_per_page'         => -1,
					'update_post_term_cache' => false,
				)
			)
		);

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

		$optins = array_map( array( $this, 'add_campaign_properties' ), $optins );

		// Return the optin data.
		return $optins;
	}

	/**
	 * Add campaign-type and enabled status to post object properties.
	 *
	 * @since 2.6.8
	 *
	 * @param WP_Post $post Optin post object.
	 */
	public function add_campaign_properties( $post ) {
		$post = $this->validate_is_campaign_type( $post );
		if ( ! empty( $post->ID ) ) {
			$post->campaign_type = get_post_meta( $post->ID, '_omapi_type', true );
			$post->enabled       = ! ! get_post_meta( $post->ID, '_omapi_enabled', true );
		}

		return $post;

	}

	/**
	 * Validates post object to ensure our optin post-type.
	 *
	 * @since 2.12.2
	 *
	 * @param  WP_Post $post The post object to check.
	 *
	 * @return WP_Post|null   Null if post-type doesn't match.
	 */
	public function validate_is_campaign_type( $post ) {
		if ( ! empty( $post->post_type ) && OMAPI_Type::SLUG !== $post->post_type ) {
			$post = null;
		}

		return $post;
	}

	/**
	 * Returns all local campaigns. Cached.
	 *
	 * @since 2.2.0
	 *
	 * @return array|bool Array of optin data or false if none found.
	 */
	public function get_campaigns() {
		static $campaigns = null;
		if ( null === $campaigns ) {
			$campaigns = $this->get_optins();
		}

		return $campaigns;
	}

	/**
	 * Returns the main option for the plugin.
	 *
	 * @since 1.0.0
	 *
	 * @param  string $key      The option value to get for given key.
	 * @param  string $subkey   The option value to get for given key and sub-key.
	 * @param  mixed  $fallback The fallback value.
	 *
	 * @return mixed            The main option array for the plugin, or requsted value.
	 */
	public function get_option( $key = '', $subkey = '', $fallback = false ) {

		$option = get_option( 'optin_monster_api' );

		if ( ! empty( $key ) ) {
			if ( ! isset( $option[ $key ] ) ) {
				return $fallback;
			}

			if ( ! empty( $subkey ) ) {
				return isset( $option[ $key ], $option[ $key ][ $subkey ] )
					? $option[ $key ][ $subkey ]
					: $fallback;
			}

			return $option[ $key ];
		}

		return $option;
	}

	/**
	 * Returns the API credentials for OptinMonster.
	 *
	 * @since 1.0.0
	 *
	 * @return array|bool $creds The user's API creds for OptinMonster.
	 */
	public function get_api_credentials() {

		// Prepare variables.
		$option = $this->get_option();
		$key    = false;
		$user   = false;
		$apikey = false;

		// Attempt to grab the new API Key.
		if ( empty( $option['api']['apikey'] ) ) {
			if ( defined( 'OPTINMONSTER_REST_API_LICENSE_KEY' ) ) {
				$apikey = OPTINMONSTER_REST_API_LICENSE_KEY;
			}
		} else {
			$apikey = $option['api']['apikey'];
		}

		// Attempt to grab the Legacy API key and API user.
		if ( empty( $option['api']['key'] ) ) {
			if ( defined( 'OPTINMONSTER_API_LICENSE_KEY' ) ) {
				$key = OPTINMONSTER_API_LICENSE_KEY;
			}
		} else {
			$key = $option['api']['key'];
		}

		if ( empty( $option['api']['user'] ) ) {
			if ( defined( 'OPTINMONSTER_API_USER' ) ) {
				$user = OPTINMONSTER_API_USER;
			}
		} else {
			$user = $option['api']['user'];
		}

		// Check if we have any of the authentication data.
		if ( ! $apikey ) {
			// Do we at least have Legacy API Key and User.
			if ( ! $key || ! $user ) {
				return false;
			}
		}

		// Return the API credentials.
		return apply_filters(
			'optin_monster_api_creds',
			array(
				'key'    => $key,
				'user'   => $user,
				'apikey' => $apikey,
			)
		);

	}

	/**
	 * Returns the API credentials for OptinMonster.
	 *
	 * @since 1.9.2
	 *
	 * @return string The API url to use for embedding on the page.
	 */
	public function get_api_url() {
		return OMAPI_Urls::om_api();
	}

	/**
	 * Check if the  main WooCommerce class is active.
	 *
	 * @since 1.1.9
	 *
	 * @deprecated 2.8.0 Use `OMAPI_WooCommerce::is_active` instead.
	 *
	 * @return bool
	 */
	public static function is_woocommerce_active() {
		_deprecated_function( __FUNCTION__, '2.8.0', 'OMAPI_WooCommerce::is_active' );

		return OMAPI_WooCommerce::is_active();
	}

	/**
	 * Return the WooCommerce versions string.
	 *
	 * @since 1.6.5
	 *
	 * @return string
	 */
	public static function woocommerce_version() {
		return OMAPI_WooCommerce::version();
	}

	/**
	 * Determines if the passed version string passes the operator compare
	 * against the currently installed version of WooCommerce.
	 *
	 * Defaults to checking if the current WooCommerce version is greater than
	 * the passed version.
	 *
	 * @since 1.7.0
	 *
	 * @param string $version  The version to check.
	 * @param string $operator The operator to use for comparison.
	 *
	 * @return string
	 */
	public static function woocommerce_version_compare( $version = '', $operator = '>=' ) {
		return OMAPI_WooCommerce::version_compare( $version, $operator );
	}

	/**
	 * Check to see if Mailpoet is active.
	 *
	 * @since 1.2.3
	 *
	 * @return bool
	 */
	public static function is_mailpoet_active() {
		return OMAPI_MailPoet::is_active();
	}

	/**
	 * Returns possible API key error flag.
	 *
	 * @since 1.0.0
	 *
	 * @return bool True if there are API key errors, false otherwise.
	 */
	public function get_api_key_errors() {
		$option = $this->get_option();
		return isset( $option['is_expired'] ) && $option['is_expired'] || isset( $option['is_disabled'] ) && $option['is_disabled'] || isset( $option['is_invalid'] ) && $option['is_invalid'];
	}

	/**
	 * Get and include a view file for output.
	 *
	 * @since  1.9.0
	 *
	 * @param  string $file The view file.
	 * @param  mixed  $data Arbitrary data to be made available to the view file.
	 *
	 * @return void
	 */
	public function output_view( $file, $data = array() ) {
		// Potentially use validate_file() (WP function) if we end up needing sub-directories later.
		require dirname( $this->file ) . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . basename( $file );
	}

	/**
	 * Get view file output content.
	 *
	 * @since 2.3.0
	 *
	 * @param  string $file The view file.
	 * @param  mixed  $data Arbitrary data to be made available to the view file.
	 *
	 * @return string The view html content.
	 */
	public function get_view_contents( $file, $data = array() ) {
		ob_start();
		$this->output_view( $file, $data );
		return ob_get_clean();
	}

	/**
	 * Get and include a view file with css and minify the output.
	 *
	 * @since 2.3.0
	 *
	 * @param  string $file The view file.
	 * @param  mixed  $data Arbitrary data to be made available to the view file.
	 *
	 * @return string
	 */
	public function get_min_css_view_contents( $file, $data = array() ) {
		$contents = $this->get_view_contents( $file, $data );
		return str_replace( array( "\n", "\r", "\t" ), '', $contents );
	}

	/**
	 * Get and include a view file with css and minify the output.
	 *
	 * @since  1.9.0
	 *
	 * @param  string $file The view file.
	 * @param  mixed  $data Arbitrary data to be made available to the view file.
	 *
	 * @return void
	 */
	public function output_min_css( $file, $data = array() ) {
		echo wp_kses(
			$this->get_min_css_view_contents( $file, $data ),
			array(
				'style' => array(
					'type' => array(),
				),
			)
		);
	}

	/**
	 * Return the level of the OM user.
	 *
	 * @since  2.0.0
	 *
	 * @return string  The level.
	 */
	public function get_level() {
		return $this->get_option( 'currentLevel', '', '' );
	}

	/**
	 * Check if the OM user has a custom plan.
	 *
	 * @since  2.0.0
	 *
	 * @return string  The level.
	 */
	public function is_custom_plan() {
		return 'vbp_custom' === $this->get_option( 'plan' );
	}

	/**
	 * Check if the OM user's plan is upgradeable.
	 *
	 * @since 2.4.0
	 *
	 * @return boolean Whether OM user's plan is upgradeable.
	 */
	public function can_upgrade() {
		$level = $this->get_level();

		// If plan upgradeable... (e.g. not top tier).
		return $level && ! in_array(
			$level,
			array(
				'vbp_agency',
				'vbp_team',
				'vbp_growth',
			),
			true
		) ? $level : false;
	}

	/**
	 * Check if the user can see upgrade prompts.
	 *
	 * @since 2.11.0
	 *
	 * @return boolean Whether upgrades can be shown.
	 */
	public function can_show_upgrade() {
		return $this->can_upgrade() || ! $this->get_level();
	}

	/**
	 * Whether user is a lite user.
	 *
	 * @since 2.11.0
	 *
	 * @return boolean Whether user is a lite user.
	 */
	public function is_lite_user() {
		return 'vbp_free' === $this->get_level();
	}

	/**
	 * Check if the OM user is allowed MonsterLinks.
	 *
	 * @since  2.6.6
	 *
	 * @param  string $rule_type The rule type to check.
	 *
	 * @return boolean Whether OM user is allowed MonsterLinks.
	 */
	public function has_rule_type( $rule_type ) {
		$data = OMAPI_Api::fetch_me_cached();

		// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
		return ! empty( $data->ruleTypes ) && in_array( $rule_type, (array) $data->ruleTypes, true );
	}

	/**
	 * Loads the default plugin options.
	 *
	 * @since 1.0.0
	 *
	 * @return array Array of default plugin options.
	 */
	public static function default_options() {

		$options = array(
			'api'                => array(),
			'is_expired'         => false,
			'is_disabled'        => false,
			'is_invalid'         => false,
			'installed'          => time(),
			'connected'          => '',
			'beta'               => false,
			'auto_updates'       => '',
			'usage_tracking'     => false,
			'hide_announcements' => false,
			'welcome'            => array(
				'status' => 'none',
			),
		);

		return apply_filters( 'optin_monster_api_default_options', $options );
	}

	/**
	 * PRS-0 compliant autoloader.
	 *
	 * @since 1.0.0
	 *
	 * @param string $classname The classname to check with the autoloader.
	 */
	public static function autoload( $classname ) {

		// Return early if not the proper classname.
		if ( 'OMAPI' !== mb_substr( $classname, 0, 5, 'UTF-8' ) ) {
			return;
		}

		// Check if the file exists. If so, load the file.
		$filename = dirname( __FILE__ ) . DIRECTORY_SEPARATOR . str_replace( '_', DIRECTORY_SEPARATOR, $classname ) . '.php';
		if ( file_exists( $filename ) ) {
			require $filename;
		}

	}

	/**
	 * Gets all site IDs associated with this site
	 *
	 * @since 1.9.10
	 *
	 * @return array
	 */
	public function get_site_ids() {
		$option = $this->get_option();
		return ! empty( $option['siteIds'] ) ? (array) $option['siteIds'] : array();
	}

	/**
	 * Gets the site ID associated with this site
	 *
	 * @since 1.9.10
	 *
	 * @return string
	 */
	public function get_site_id() {
		$option = $this->get_option();
		return ! empty( $option['siteId'] ) ? (string) $option['siteId'] : '';
	}

	/**
	 * Gets the revenue attribution settings associated with the
	 * account that has registered this site.
	 *
	 * @since 2.6.13
	 *
	 * @return array
	 */
	public function get_revenue_attribution() {
		$option = $this->get_option();
		return ! empty( $option['revenueAttribution'] ) ? (array) $option['revenueAttribution'] : array();
	}

	/**
	 * Checks if given (or current) page is an optinmonster admin page.
	 *
	 * @since 2.10.0
	 *
	 * @param string $page Page to check. Falls back to $_REQUEST['page'].
	 *
	 * @return boolean Whether given (or current) page is an optinmonster admin page.
	 */
	public function is_om_page( $page = null ) {
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		if ( empty( $page ) && ! empty( $_REQUEST['page'] ) ) {
			$page = sanitize_key( wp_unslash( $_REQUEST['page'] ) );
		}
		// phpcs:enable WordPress.Security.NonceVerification.Recommended

		return ! empty( $page ) && preg_match( '/optin-monster-/', $page );
	}

	/**
	 * Hides unrelated admin notices.
	 *
	 * @since 1.9.7
	 */
	public function hide_unrelated_admin_notices() {
		// Bail if we're not on a OptinMonster screen.
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( ! $this->is_om_page() ) {
			return;
		}

		global $wp_filter;

		$notices_type = array(
			'user_admin_notices',
			'admin_notices',
			'all_admin_notices',
		);

		foreach ( $notices_type as $type ) {
			if ( empty( $wp_filter[ $type ]->callbacks ) || ! is_array( $wp_filter[ $type ]->callbacks ) ) {
				continue;
			}

			foreach ( $wp_filter[ $type ]->callbacks as $priority => $hooks ) {
				foreach ( $hooks as $name => $arr ) {
					if ( is_object( $arr['function'] ) && $arr['function'] instanceof Closure ) {
						unset( $wp_filter[ $type ]->callbacks[ $priority ][ $name ] );
						continue;
					}

					$class = ! empty( $arr['function'][0] ) && is_object( $arr['function'][0] ) ? strtolower( get_class( $arr['function'][0] ) ) : '';

					if ( ! empty( $class ) && preg_match( '/^(?:omapi|am_notification)/', $class ) ) {
						continue;
					}

					if ( ! empty( $name ) && ! preg_match( '/^(?:omapi|am_notification)/', $name ) ) {
						unset( $wp_filter[ $type ]->callbacks[ $priority ][ $name ] );
					}
				}
			}
		}
	}

	/**
	 * Checks PHP version.
	 *
	 * @return void
	 */
	public function check_php_version() {

		// Display for PHP below 5.6.
		if ( version_compare( PHP_VERSION, '5.5', '>=' ) ) {
			return;
		}

		// Display for admins only.
		if ( ! is_super_admin() ) {
			return;
		}

		// Display on Dashboard page only.
		if ( isset( $GLOBALS['pagenow'] ) && 'index.php' !== $GLOBALS['pagenow'] ) {
			return;
		}

		// Do not double up on WPForms notice.
		if ( function_exists( 'wpforms_check_php_version' ) ) {
			return;
		}

		// Display the notice, finally.
		echo '<div id="message" class="notice notice-error">' .
		'<p>' .
		sprintf(
			wp_kses(
				/* translators: %1$s - OptinMonster API plugin name; %2$s - optinmonster.com URL to a related doc. */
				__( 'Your site is running an outdated version of PHP that is no longer supported and may cause issues with the %1$s plugin. <a href="%2$s" target="_blank" rel="noopener noreferrer">Read more</a> for additional information.', 'optin-monster-api' ),
				array(
					'a' => array(
						'href'   => array(),
						'target' => array(),
						'rel'    => array(),
					),
				)
			),
			'<strong>OptinMonster API</strong>',
			'https://optinmonster.com/docs/supported-php-version/'
		) .
		'<br><br><em>' .
		wp_kses(
			__( '<strong>Please Note:</strong> Support for PHP 5.5 will be discontinued in 2020. After this, if no further action is taken, OptinMonster functionality will be disabled.', 'optin-monster-api' ),
			array(
				'strong' => array(),
				'em'     => array(),
			)
		) .
		'</em></p>' .
		'</div>';
	}

	/**
	 * Get the asset version for enqueued assets.
	 *
	 * @since  1.9.10
	 *
	 * @return mixed
	 */
	public function asset_version() {
		if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
			return time();
		}

		if ( defined( 'OPTINMONSTER_ENV' ) && 'dev' === strtolower( OPTINMONSTER_ENV ) ) {
			return time();
		}

		$beta_version = $this->beta_version( 'U' );

		return $beta_version ? $beta_version : $this->version;
	}

	/**
	 * Check if beta is enabled.
	 *
	 * @since  2.0.0
	 *
	 * @return bool
	 */
	public function beta_enabled() {
		$option = $this->get_option();

		return apply_filters( 'optin_monster_beta_enabled', ! empty( $option['beta'] ) );
	}

	/**
	 * Get beta version.
	 *
	 * @since  2.0.0
	 *
	 * @param string $format The php date format.
	 *
	 * @return bool
	 */
	public function beta_version( $format = 'd M Y H:i:s' ) {
		static $timestamp = null;

		$version = false;
		if ( ! $this->beta_enabled() ) {
			return $version;
		}

		if ( null === $timestamp ) {
			$file = plugin_dir_path( __FILE__ ) . '.betaversion';
			if ( file_exists( $file ) ) {
				ob_start();
				include plugin_dir_path( __FILE__ ) . '.betaversion';
				$timestamp = ob_get_clean();
			}
		}

		if ( ! empty( $timestamp ) ) {
			$version = gmdate( $format, (int) $timestamp );
		}

		return $version;
	}

	/**
	 * The access capability required for access to OptinMonster pages/settings.
	 *
	 * @since  2.0.0
	 *
	 * @param  string|null $slug The menu slug. Null by default.
	 *
	 * @return string The access capability.
	 */
	public function access_capability( $slug = null ) {
		return apply_filters( 'optin_monster_api_menu_cap', 'manage_options', $slug );
	}

	/**
	 * Check if user has access capability required for access to OptinMonster pages/settings.
	 *
	 * @since  2.0.0
	 *
	 * @param  string|null $slug The menu slug. Null by default.
	 *
	 * @return bool Whether user has access.
	 */
	public function can_access( $slug = null ) {
		return current_user_can( $this->access_capability( $slug ) );
	}

	/**
	 * Get app url, with proper query args set to ensure going to correct account, and setting return
	 * query arg to come back (if relevant on the destination page).
	 *
	 * @since  2.0.0
	 *
	 * @param  string $path The path on the app.
	 * @param  string $return_url Url to return. Will default to wp_get_referer().
	 *
	 * @return string        The app url.
	 */
	public function app_url( $path, $return_url = '' ) {
		return OMAPI_Urls::om_app( $path, $return_url );
	}

	/**
	 * Returns the singleton instance of the class.
	 *
	 * @since 1.0.0
	 *
	 * @return OMAPI
	 */
	public static function get_instance() {
		if ( ! isset( self::$instance ) && ! ( self::$instance instanceof OMAPI ) ) {
			self::$instance = new OMAPI();
		}

		return self::$instance;
	}

	/**
	 * Magic getter for our object.
	 *
	 * @since 2.11.2
	 *
	 * @param string $property The property to retrieve.
	 *
	 * @return mixed
	 */
	public function __get( $property ) {
		if ( ! empty( self::$class_map[ $property ] ) ) {
			$this->$property = new self::$class_map[ $property ]();
		}

		return $this->$property;
	}

}

register_activation_hook( __FILE__, 'optin_monster_api_activation_hook' );
/**
 * Fired when the plugin is activated.
 *
 * @since 1.0.0
 *
 * @global int $wp_version      The version of WordPress for this install.
 * @global object $wpdb         The WordPress database object.
 * @param boolean $network_wide True if WPMU superadmin uses "Network Activate" action, false otherwise.
 */
function optin_monster_api_activation_hook( $network_wide ) {

	global $wp_version;
	if ( version_compare( $wp_version, '4.7.0', '<' ) && ! defined( 'OPTINMONSTER_FORCE_ACTIVATION' ) ) {
		deactivate_plugins( plugin_basename( __FILE__ ) );
		wp_die(
			wp_kses_post(
				sprintf(
					/* translators: %s) admin url */
					__( 'Sorry, but your version of WordPress does not meet OptinMonster\'s required version of <strong>4.7.0</strong> to run properly. The plugin has been deactivated. <a href="%s">Click here to return to the Dashboard</a>.', 'optin-monster-api' ),
					esc_url( admin_url() )
				)
			)
		);
	}

	$instance = OMAPI::get_instance();

	global $wpdb;
	if ( is_multisite() && $network_wide ) {
		$site_list = $wpdb->get_results( "SELECT * FROM $wpdb->blogs ORDER BY blog_id" );
		foreach ( (array) $site_list as $site ) {
			switch_to_blog( $site->blog_id );

			// Set default option.
			$instance->load_option();

			restore_current_blog();
		}
	} else {
		// Set default option.
		$instance->load_option();
	}

	// If we don't have api credentials, set up the redirect on plugin activation.
	if ( ! $instance->get_api_credentials() ) {
		$options                      = $instance->get_option();
		$options['welcome']['status'] = 'none';
		update_option( 'optin_monster_api', $options );
	}

	// Abort so we only set the transient for single site installs.
	// phpcs:ignore WordPress.Security.NonceVerification.Recommended
	if ( isset( $_GET['activate-multi'] ) || is_network_admin() ) {
		return;
	}

	// Add transient to trigger redirect to the Welcome screen.
	set_transient( 'optin_monster_api_activation_redirect', true, 30 );
}

register_uninstall_hook( __FILE__, 'optin_monster_api_uninstall_hook' );
/**
 * Fired when the plugin is uninstalled.
 *
 * @since 1.0.0
 *
 * @global object $wpdb The WordPress database object.
 */
function optin_monster_api_uninstall_hook() {

	$instance = OMAPI::get_instance();

	global $wpdb;
	if ( is_multisite() ) {
		$site_list = $wpdb->get_results( "SELECT * FROM $wpdb->blogs ORDER BY blog_id" );
		foreach ( (array) $site_list as $site ) {
			switch_to_blog( $site->blog_id );
			delete_option( 'optin_monster_api' );
			restore_current_blog();
		}
	} else {
		delete_option( 'optin_monster_api' );
	}

}

// Load the plugin.
$optin_monster_api = OMAPI::get_instance();

// Conditionally load the template tag.
if ( ! function_exists( 'optin_monster' ) ) {
	/**
	 * Primary template tag for outputting OptinMonster optins in templates.
	 *
	 * @since 1.0.0
	 *
	 * @param int    $id     The ID of the optin to load.
	 * @param string $type   The type of field to query.
	 * @param array  $args   Associative array of args to be passed.
	 * @param bool   $return Flag to echo or return the optin HTML.
	 */
	function optin_monster( $id, $type = 'id', $args = array(), $return = false ) {

		// If we have args, build them into a shortcode format.
		$args_string = '';
		if ( ! empty( $args ) ) {
			foreach ( (array) $args as $key => $value ) {
				$args_string .= ' ' . $key . '="' . $value . '"';
			}
		}

		// Build the shortcode.
		$shortcode = ! empty( $args_string ) ? '[optin-monster ' . $type . '="' . $id . '"' . $args_string . ']' : '[optin-monster ' . $type . '="' . $id . '"]';

		// Return or echo the shortcode output.
		if ( $return ) {
			return do_shortcode( $shortcode );
		} else {
			echo do_shortcode( $shortcode );
		}

	}
}

// Backwards compat for the v1 template tag.
if ( ! function_exists( 'optin_monster_tag' ) ) {
	/**
	 * Primary template tag for outputting OptinMonster optins in templates (v1).
	 *
	 * @since 1.0.0
	 *
	 * @param int  $id     The post name of the optin to load.
	 * @param bool $return Flag to echo or return the optin HTML.
	 */
	function optin_monster_tag( $id, $return = false ) {

		// Return the v2 template tag.
		return optin_monster( $id, 'slug', array(), $return );

	}
}