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:/proc/self/root/usr/local/lsws/add-ons/webcachemgr/src/
Upload File :
Current File : //proc/self/root/usr/local/lsws/add-ons/webcachemgr/src/WPCaller.php
<?php

/** *********************************************
 * LiteSpeed Web Server Cache Manager
 *
 * @author    Michael Alegre
 * @copyright 2018-2025 LiteSpeed Technologies, Inc.
 * *******************************************
 */

namespace Lsc\Wp;

use Lsc\Wp\Context\Context;
use Lsc\Wp\WpWrapper\PluginUpgrader;
use Lsc\Wp\WpWrapper\WpConstants;
use Lsc\Wp\WpWrapper\WpFuncs;
use Lsc\Wp\WpWrapper\Wpdb;
use Lsc\Wp\WpWrapper\WpQuery;
use Lsc\Wp\WpWrapper\WpTextdomainRegistry;

/**
 * Calls WP internal functions in SHORTINIT mode.
 */
class WPCaller
{

    /**
     * @var string
     */
    const LSCWP_PLUGIN = 'litespeed-cache/litespeed-cache.php';

    /**
     * @var string
     */
    const LSCWP_HTTP_HOST_TEST = 'litespeed_something_is_wrong';

    /**
     * @var null|WPCaller
     */
    private static $instance = null;

    /**
     * @var WPInstall
     */
    private $currInstall;

    /**
     * @since 1.13.4.4
     * @var string
     */
    private $advancedCacheFile;

    /**
     * @var bool
     */
    private $loadLscwp;

    /**
     * @var string
     */
    private $pluginEntry;

    /**
     * @since 1.13
     * @var null|string
     */
    private $installedLscwpVer = null;

    /**
     * @var string[]
     */
    private $outputResult = array();

    /**
     * @var string
     */
    private $massIncr = '';

    /**
     *
     * @param WPInstall $curInstall
     * @param bool      $loadLscwp
     *
     * @throws LSCMException  Thrown indirectly by $this->init() call.
     */
    private function __construct( WPInstall $curInstall, $loadLscwp )
    {
        $this->currInstall = $curInstall;
        $this->loadLscwp   = $loadLscwp;

        $this->init();
    }

    /**
     *
     * @since 1.13.4.4
     *
     * @throws LSCMException  Thrown indirectly by $this->initWp() call.
     */
    private function init()
    {
        $this->advancedCacheFile =
            "{$this->currInstall->getPath()}/wp-content/advanced-cache.php";

        $this->initWp();
    }

    /**
     *
     * @param WPInstall $currInstall
     * @param bool      $loadLscwp
     *
     * @return WPCaller
     *
     * @throws LSCMException  Thrown indirectly by "new self()" call.
     */
    public static function getInstance(
        WPInstall $currInstall,
                  $loadLscwp = true )
    {
        if ( self::$instance == null
                || self::$instance->currInstall !== $currInstall ) {

            self::$instance = new self($currInstall, $loadLscwp);
        }

        return self::$instance;
    }

    /**
     *
     * @param int    $errno   Not used at this time.
     * @param string $errstr
     *
     * @return bool
     *
     * @noinspection PhpUnusedParameterInspection
     */
    public static function warning_handler( $errno, $errstr )
    {
        $strs = array(
            'ini_set() has been disabled for security reasons',
            'Constant FS_METHOD already defined'
        );

        if ( in_array($errstr, $strs) ) {
            /**
             * Throw this warning out.
             */
            return true;
        }

        return false;
    }

    /**
     * Deprecated 03/12/19 as this function is no longer used.
     *
     * Prevents database table options not in the $allowedOptions list
     * from having their value updated by others during execution.
     *
     * Run when WP function apply_filters('pre_update_option', ...) is called
     * in WP function update_option().
     *
     * @deprecated
     *
     * @param mixed  $value      New option value.
     * @param string $option     Option name in db.
     * @param mixed  $old_value  Old option value.
     *
     * @return mixed
     */
    public static function lock_database( $value, $option, $old_value )
    {
        $allowedOptions = array(
            'litespeed-cache-conf',
            '_transient_lscwp_whm_install',
            'active_plugins',
            '_transient_doing_cron',
            '_site_transient_update_plugins',
            'uninstall_plugins'
        );

        if ( in_array($option, $allowedOptions) ) {
            return $value;
        }
        else {
            return $old_value;
        }
    }

    /**
     * Redefine disabled PHP global/core functions that no longer exist
     * (PHP 8+).
     *
     * @since 1.13.10
     */
    private static function redefineDisabledFunctions()
    {
        if ( Util::betterVersionCompare(phpversion(), '8.0', '>=') ) {
            include_once(__DIR__ . '/RedefineGlobalFuncs.php');
        }
    }

    /**
     *
     * @return string[]
     */
    public function getOutputResult()
    {
        return $this->outputResult;
    }

    /**
     * Adds key value pair to $this->outputResult to be grabbed later in
     * the $output variable of the UserCommand::issue() exec call.
     *
     * @param string $key
     * @param mixed  $value
     */
    private function outputResult( $key, $value )
    {
        $this->outputResult[$key] = $value;
    }

    /**
     *
     * @deprecated 1.9  Use Logger::getLogMsgQueue() to get these messages as
     *     LogEntry objects.
     *
     * @return string[]
     *
     * @throws LSCMException  Thrown indirectly by Logger::getLogMsgQueue()
     *     call.
     */
    public function getDebugMsgs()
    {
        $debugMsgs = array();

        $msgQueue = Logger::getLogMsgQueue();

        foreach ( $msgQueue as $logEntry ) {
            $label       = Logger::getLvlDescr($logEntry->getLvl());
            $debugMsgs[] = "[$label] {$logEntry->getMsg()}";
        }

        return $debugMsgs;
    }

    /**
     * @deprecated 1.9  Deprecated 07/30/19. Use
     *     Logger::getUiMsgs(Logger::UI_ERR) to get these messages.
     *
     * @return string[]
     *
     * @throws LSCMException  Thrown indirectly by Logger::getUiMsgs() call.
     */
    public function getErrMsgs()
    {
        return Logger::getUiMsgs(Logger::UI_ERR);
    }

    /**
     *
     * @deprecated 1.9  Deprecated 07/30/19. Use
     *     Logger::getUiMsgs(Logger::UI_SUCC) to get these messages.
     *
     * @return string[]
     *
     * @throws LSCMException  Thrown indirectly by Logger::getUiMsgs() call.
     */
    public function getSuccMsgs()
    {
        return Logger::getUiMsgs(Logger::UI_SUCC);
    }

    /**
     *
     * WP Variables $table_prefix
     *
     * @global string $table_prefix
     *
     * @return string
     */
    private function getSiteURL()
    {
        global $table_prefix;

        $siteURL = WpFuncs::getOption('siteurl');

        if ( !$siteURL ) {
            return '';
        }

        if ( strpos($siteURL, self::LSCWP_HTTP_HOST_TEST) !== false ) {
            /**
             * User is setting WP_SITEURL using fake $_SERVER['HTTP_HOST'].
             * Get siteurl value from DB directly.
             */
            return WpFuncs::getVar(
                "SELECT option_value FROM {$table_prefix}options "
                    . "WHERE option_name = 'siteurl'"
            );
        }

        return $siteURL;
    }

    /**
     *
     * @since 1.17.0.3
     *
     * @param string $advCacheFileContents
     *
     * @return bool
     */
    private static function advancedCacheFileBelongsToLscwp(
        $advCacheFileContents
    )
    {
        if ( self::advancedCacheFileHasLscacheDefine($advCacheFileContents) ) {
            return true;
        }

        if ( self::advancedCacheFileHasPlaceholderMsg($advCacheFileContents) ) {
            return true;
        }

        return false;
    }


    /**
     *
     * @since 1.13.4.3
     *
     * @return bool
     */
    private function generic3rdPartyAdvCachePluginExists()
    {
        if ( Util::betterVersionCompare($this->installedLscwpVer, '3.0.4', '>=') ) {

            if ( file_exists($this->advancedCacheFile) ) {

                $advCacheFileContents =
                    file_get_contents($this->advancedCacheFile);

                if ( $advCacheFileContents !== '' ) {
                    /**
                     * Old LSCWP advanced-cache.php file is no longer used in
                     * these versions but is also never cleaned up. As a result,
                     * any existing advanced-cache.php files need to have their
                     * contents checked to avoid detecting an old LSCWP
                     * advanced-cache.php file as a generic 3rd-party
                     * advanced-cache plugin.
                     */
                    return !self::advancedCacheFileBelongsToLscwp(
                        $advCacheFileContents
                    );
                }
            }
        }
        elseif ( !defined('LSCACHE_ADV_CACHE')
                || WpConstants::getWpConstant('LSCACHE_ADV_CACHE') !== true ) {

            return true;
        }

        return false;
    }

    /**
     *
     * @since 1.13.8  Added optional parameter $output.
     *
     * @param WPInstall $install
     * @param bool      $output
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by Logger::uiError() call.
     * @throws LSCMException  Thrown indirectly by $install->addUserFlagFile()
     *     call.
     * @throws LSCMException  Thrown indirectly by $install->addUserFlagFile()
     *     call.
     * @throws LSCMException  Thrown indirectly by Logger::notice() call.
     * @throws LSCMException  Thrown indirectly by Logger::notice() call.
     */
    private function checkStatus( WPInstall $install, $output = false )
    {
        if ( $output ) {

            if ( ($siteUrl = $this->getSiteURL()) === '' ) {
                Logger::uiError(
                    'Could not retrieve siteURL to match against known '
                        . 'docroots.'
                );
                $install->addUserFlagFile();

                return (WPInstall::ST_ERR_SITEURL | WPInstall::ST_FLAGGED);
            }

            $this->outputResult('SITEURL', $siteUrl);
        }

        $status = 0;

        /**
         * Check if plugin files exist first, as status in db could be stale if
         * LSCWP was removed manually.
         */
        if ( file_exists($this->pluginEntry)
                && WpFuncs::isPluginActive(self::LSCWP_PLUGIN) ) {

            $status |= WPInstall::ST_PLUGIN_ACTIVE;

            //TODO: Get rid of ST_LSC_ADVCACHE_DEFINED status or replace with
            //      new "is caching enabled" define check.

            if ( $this->generic3rdPartyAdvCachePluginExists() ) {
                $status |= WPInstall::ST_FLAGGED;
            }
            else {
                $status |= WPInstall::ST_LSC_ADVCACHE_DEFINED;
            }
        }
        else {
            $status |= WPInstall::ST_PLUGIN_INACTIVE;
        }

        if ( $install->hasFlagFile() ) {
            $status |= WPInstall::ST_FLAGGED;
        }

        if ( $status & WPInstall::ST_FLAGGED ) {

            if ( $install->addUserFlagFile() ) {
                Logger::notice('Install is flagged');
            }
            else {
                Logger::notice('Install is not flagged');
            }
        }

        return $status;
    }

    /**
     *
     * @param bool $output
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->checkStatus() call.
     */
    public function updateStatus( $output = false )
    {
        $status = $this->checkStatus($this->currInstall, $output);
        $this->currInstall->setStatus($status);

        if ( $output ) {
            $this->outputResult('STATUS', $status);
        }

        if ( $status & WPInstall::ST_ERR_SITEURL ) {
            return UserCommand::EXIT_FAIL;
        }

        return UserCommand::EXIT_SUCC;
    }

    /**
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->updateStatus() call.
     */
    private function getCurrStatus()
    {
        $this->updateStatus();

        return $this->currInstall->getStatus();
    }

    /**
     * Check if any known cache plugins that do not use an advanced-cache.php
     * file are active for this WordPress installation. If any of these plugins
     * are found, that plugin's slug is returned.
     *
     * @since 1.9.1
     *
     * @return string  Empty string or detected active cache plugin slug.
     */
    private function checkForKnownNonAdvCachePlugins()
    {
        $knownPlugins = array(
            'wp-fastest-cache' => 'wp-fastest-cache/wpFastestCache.php'
        );


        foreach ( $knownPlugins as $slug => $plugin ) {
            /**
             * Check if plugin files exist first, as status in db could be
             * stale if plugin files were removed manually.
             */
            $pluginExistsAndIsActive = (
                file_exists(
                    WpConstants::getWpConstant('WP_PLUGIN_DIR') . "/$plugin"
                )
                &&
                WpFuncs::isPluginActive($plugin)
            );

            if ( $pluginExistsAndIsActive) {
                return $slug;
            }
        }

        return '';
    }

    /**
     *
     * @param bool $isMassAction
     * @param bool $isNewInstall
     *
     * @return bool
     *
     * @throws LSCMException  Thrown indirectly by $this->getCurrStatus() call.
     * @throws LSCMException  Thrown indirectly by
     *     $this->currInstall->addUserFlagFile() call.
     * @throws LSCMException  Thrown indirectly by  Logger::uiSuccess() call.
     * @throws LSCMException  Thrown indirectly by Logger::notice() call.
     * @throws LSCMException  Thrown indirectly by
     *     $this->currInstall->addUserFlagFile() call.
     * @throws LSCMException  Thrown indirectly by Logger::uiError() call.
     * @throws LSCMException  Thrown indirectly by Logger::notice() call.
     * @throws LSCMException  Thrown indirectly by  Logger::uiSuccess() call.
     * @throws LSCMException  Thrown indirectly by Logger::notice() call.
     * @throws LSCMException  Thrown indirectly by
     *     $this->currInstall->addUserFlagFile() call.
     * @throws LSCMException  Thrown indirectly by Logger::uiError() call.
     * @throws LSCMException  Thrown indirectly by Logger::notice() call.
     */
    private function canEnable( $isMassAction, $isNewInstall )
    {
        $status = $this->getCurrStatus();

        if ( $status & WPInstall::ST_PLUGIN_INACTIVE ) {

            if ( !$isNewInstall && $isMassAction ) {
                $this->currInstall->addUserFlagFile();

                Logger::uiSuccess(
                    'LSCWP Detected As Manually Disabled - Flag Set'
                );
                Logger::notice(
                    'Ignore - Previously disabled, flag it from mass operation'
                );

                return false;
            }

            $thirdPartyCachePluginSlug =
                $this->checkForKnownNonAdvCachePlugins();

            if ( $thirdPartyCachePluginSlug != '' ) {
                $this->currInstall->addUserFlagFile();

                Logger::uiError(
                    'Cannot Enable LSCWP - Detected another active cache '
                        . "plugin \"$thirdPartyCachePluginSlug\". Flag set."
                );

                Logger::notice(
                    'Ignore - Detected another active cache plugin '
                        . "\"$thirdPartyCachePluginSlug\". Flagged."
                );

                return false;
            }
        }
        elseif ( !$isNewInstall ) {
            /**
             * already active
             */
            if ( $status & WPInstall::ST_LSC_ADVCACHE_DEFINED ) {
                Logger::uiSuccess('LSCWP Already Enabled - No Action Taken');
                Logger::notice('Ignore - Already enabled');
            }
            else {
                $this->currInstall->addUserFlagFile();

                Logger::uiError(
                    'LSCWP Already Enabled But Not Caching - Detected another '
                        . 'active cache plugin. Please visit the WordPress '
                        . 'Dashboard for further instructions.'
                );
                Logger::notice(
                    'Ignore - Existing install but advanced cache not set'
                );
            }

            return false;
        }

        return true;
    }

    /**
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->canEnable() call.
     * @throws LSCMException  Thrown indirectly by $this->enable_lscwp() call.
     * @throws LSCMException  Thrown indirectly by
     *     $this->directEnableNewInstall() call.
     */
    public function directEnable()
    {
        $isNewInstall = !file_exists($this->pluginEntry);

        if ( !$this->canEnable(false, $isNewInstall) ) {
            $this->outputResult('STATUS', $this->currInstall->getStatus());
            return UserCommand::EXIT_FAIL;
        }

        if ( !$isNewInstall ) {
            $status = $this->enable_lscwp();
        }
        else {
            $status = $this->directEnableNewInstall();
        }

        $this->outputResult('STATUS', $status);
        return UserCommand::EXIT_SUCC;
    }

    /**
     *
     * @return int
     *
     * @throws LSCMException  Thrown when unable to extract downloaded LSCWP
     *     files.
     * @throws LSCMException  Thrown indirectly by $this->downloadLSCWPZip()
     *     call.
     * @throws LSCMException  Thrown indirectly by $this->enable_lscwp() call.
     * @throws LSCMException  Thrown indirectly by
     *     $this->removeLscwpPluginFiles() call.
     */
    private function directEnableNewInstall()
    {
        $pluginDir = WpConstants::getWpConstant('WP_PLUGIN_DIR');

        $lscwpZip = "$pluginDir/litespeed-cache.latest-stable.zip";

        $this->downloadLSCWPZip($lscwpZip);

        WpFuncs::WpFilesystem();

        $unzipRet = WpFuncs::unzipFile($lscwpZip, $pluginDir);
        unlink($lscwpZip);

        if ( $unzipRet !== true ) {
            throw new LSCMException(
                "Unable to extract downloaded LSCWP files.",
                LSCMException::E_NON_FATAL
            );
        }

        $this->currInstall->addNewLscwpFlagFile();

        $customIni = Context::LOCAL_PLUGIN_DIR . '/'
            . PluginVersion::LSCWP_DEFAULTS_INI_FILE_NAME;

        if ( file_exists($customIni) ) {
            copy(
                $customIni,
                "$pluginDir/litespeed-cache/data/"
                    . PluginVersion::LSCWP_DEFAULTS_INI_FILE_NAME
            );
        }

        $this->installedLscwpVer = $this->getPluginVersionFromFile();

        $status = $this->enable_lscwp();

        if ( $status & WPInstall::ST_PLUGIN_INACTIVE) {
            $this->removeLscwpPluginFiles();
        }
        else {
            $this->updateTranslationFiles();
        }

        return $status;
    }

    /**
     *
     * @param string $lscwpZip
     *
     * @return null
     *
     * @throws LSCMException  Thrown when LSCWP download operation fails.
     */
    private function downloadLscwpZip( $lscwpZip )
    {
        $pluginDir = WpConstants::getWpConstant('WP_PLUGIN_DIR');
        $url = 'https://downloads.wordpress.org/plugin/'
            . 'litespeed-cache.latest-stable.zip';

        exec(
            "wget -q --tries=1 --no-check-certificate $url -P $pluginDir",
            $output1,
            $return_var1
        );

        if ( $return_var1 === 0 && file_exists($lscwpZip) ) {
            return;
        }

        /**
         * Fall back to curl in case wget is disabled for user.
         */
        exec(
            "cd $pluginDir && curl -O -s --retry 1 --insecure $url",
            $output2,
            $return_var2
        );

        if ( $return_var2 === 0 && file_exists($lscwpZip) ) {
            return;
        }

        throw new LSCMException(
            "Failed to download LSCWP with wget exit status $return_var1 and "
                . "curl exit status $return_var2.",
            LSCMException::E_NON_FATAL
        );
    }

    /**
     *
     * @param array $extraArgs  Not used at this time.
     * @param bool  $massOp     True when called from massEnable().
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by PluginVersion::getInstance()
     *     call.
     * @throws LSCMException  Thrown indirectly by
     *     PluginVersion::getInstance()->prepareUserInstall() call.
     * @throws LSCMException  Thrown indirectly by $this->canEnable() call.
     * @throws LSCMException  Thrown indirectly by $this->enable_lscwp() call.
     * @throws LSCMException  Thrown indirectly by
     *     $this->removeLscwpPluginFiles() call.
     *
     * @noinspection PhpUnusedParameterInspection
     */
    public function enable( array $extraArgs, $massOp = false )
    {
        $isNewInstall = PluginVersion::getInstance()->prepareUserInstall(
            WpConstants::getWpConstant('WP_PLUGIN_DIR')
        );

        if ( $isNewInstall ) {
            $this->installedLscwpVer = $this->getPluginVersionFromFile();
            $this->currInstall->addNewLscwpFlagFile();
        }

        if ( !$this->canEnable($massOp, $isNewInstall) ) {
            $status = $this->currInstall->getStatus();
            $ret    = UserCommand::EXIT_FAIL;
        }
        else {
            $status = $this->enable_lscwp();
            $ret    = UserCommand::EXIT_SUCC;
        }

        if ( $isNewInstall ) {

            if ( $status & WPInstall::ST_PLUGIN_INACTIVE ) {
                $this->removeLscwpPluginFiles();
            }
            else {
                $this->updateTranslationFiles();
            }
        }

        $this->outputResult('STATUS', $this->currInstall->getStatus());
        return $ret;
    }

    /**
     *
     * @param string[] $extraArgs
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->enable() call.
     */
    public function massEnable( array $extraArgs )
    {
        $ret = $this->enable($extraArgs, true);

        if ( $this->massIncr != '' ) {
            $this->outputResult('MASS_INCR', $this->massIncr);
        }

        return $ret;
    }

    /**
     *
     * @param bool $isMassAction
     *
     * @return bool
     *
     * @throws LSCMException  Thrown indirectly by $this->getCurrStatus() call.
     * @throws LSCMException  Thrown indirectly by Logger::notice() call.
     * @throws LSCMException  Thrown indirectly by Logger::uiSuccess() call.
     * @throws LSCMException  Thrown indirectly by
     *     $this->currInstall->addUserFlagFile() call.
     * @throws LSCMException  Thrown indirectly by Logger::uiSuccess() call.
     * @throws LSCMException  Thrown indirectly by Logger::notice() call.
     * @throws LSCMException  Thrown indirectly by
     *     $this->currInstall->addUserFlagFile() call.
     * @throws LSCMException  Thrown indirectly by Logger::uiSuccess() call.
     */
    private function canDisable( $isMassAction )
    {
        $status = $this->getCurrStatus();

        if ( $status & WPInstall::ST_PLUGIN_INACTIVE ) {
            Logger::notice('Ignore - Already disabled');
            Logger::uiSuccess(
                'LiteSpeed Cache Already Disabled - No Action Taken'
            );

            return false;
        }

        if ( $isMassAction ) {

            if ( !($status & WPInstall::ST_LSC_ADVCACHE_DEFINED) ) {
                $this->currInstall->addUserFlagFile();

                Logger::uiSuccess(
                    'LSCWP Detected As Manually Enabled But Not Caching - Flag '
                        . 'Set. If desired, this installation can be disabled '
                        . 'from the Manage Cache Installations screen.'
                );
                Logger::notice(
                    'Ignore for mass disable - Installed manually as advanced '
                        . 'cache not set.'
                );

                return false;
            }

            if ( WpFuncs::isPluginActiveForNetwork(self::LSCWP_PLUGIN) ) {
                $this->currInstall->addUserFlagFile();

                Logger::uiSuccess(
                    'LiteSpeed Cache Detected As Network Activated - Flag Set '
                        . '& No Action Taken'
                );

                return false;
            }
        }

        return true;
    }

    /**
     *
     * @param string[] $extraArgs  Not used at this time.
     * @param bool     $massOp     True when called from MassDisable().
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->canDisable() call.
     * @throws LSCMException  Thrown indirectly by $this->performDisable() call.
     * @throws LSCMException  Thrown indirectly by Logger::uiSuccess() call.
     *
     * @noinspection PhpUnusedParameterInspection
     */
    public function disable( array $extraArgs, $massOp = false )
    {
        if ( !$this->canDisable($massOp) ) {
            $ret = UserCommand::EXIT_FAIL;
        }
        else {

            if ( $this->performDisable(true) & WPInstall::ST_PLUGIN_ACTIVE ) {
                $ret = UserCommand::EXIT_FAIL;
            }
            else {
                Logger::uiSuccess('LiteSpeed Cache Disabled');
                $this->massIncr = 'SUCC';
                $ret            = UserCommand::EXIT_SUCC;
            }
        }

        $this->outputResult('STATUS', $this->currInstall->getStatus());

        return $ret;
    }

    /**
     *
     * @param string[] $extraArgs
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->disable() call.
     */
    public function massDisable( array $extraArgs )
    {
        $ret = $this->disable($extraArgs, true);

        if ( $this->massIncr != '' ) {
            $this->outputResult('MASS_INCR', $this->massIncr);
        }

        return $ret;
    }

    /**
     * Includes LSCWP files needed to properly disable the LSCWP plugin.
     *
     * @since 1.13  Removed param $lscwpVer.
     */
    private function includeDisableRequiredFiles()
    {
        $dir = WpConstants::getWpConstant('WP_PLUGIN_DIR') . '/litespeed-cache';

        if ( Util::betterVersionCompare($this->installedLscwpVer, '3.0', '>=') ) {
            require_once "$dir/src/admin.cls.php";
        }
        elseif ( Util::betterVersionCompare($this->installedLscwpVer, '1.1.2.2', '>') ) {
            require_once "$dir/admin/litespeed-cache-admin.class.php";
        }
        else {
            require_once "$dir/admin/class-litespeed-cache-admin.php";
        }

        if ( Util::betterVersionCompare($this->installedLscwpVer, '1.1.0', '<')
                && Util::betterVersionCompare($this->installedLscwpVer, '1.0.6', '>') ) {

            require_once "$dir/admin/class-litespeed-cache-admin-rules.php";
        }
    }

    /**
     *
     * @param bool $uninstall
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->disable_lscwp() call.
     */
    private function performDisable( $uninstall )
    {
        $this->includeDisableRequiredFiles();
        return $this->disable_lscwp($uninstall);
    }

    /**
     *
     * @param string[] $fromVersions
     * @param string   $toVersion
     * @param bool     $massOp        Not used at this time.
     *
     * @return bool
     *
     * @noinspection PhpUnusedParameterInspection
     */
    private function canUpgrade( array $fromVersions, $toVersion, $massOp )
    {
        if ( !file_exists($this->pluginEntry) ) {
            return false;
        }

        if ( $toVersion == $this->installedLscwpVer ) {
            return false;
        }

        foreach ( $fromVersions as $fromVer ) {
            $fromVerParts      = explode('.', $fromVer);
            $installedVerParts = explode('.', $this->installedLscwpVer);

            $i = 0;

            while ( isset($fromVerParts[$i]) ) {
                $fromVerPart = $fromVerParts[$i];

                if ( $fromVerPart == 'x' ) {
                    return true;
                }

                if ( !isset($installedVerParts[$i])
                        || $installedVerParts[$i] != $fromVerPart ) {

                    continue 2;
                }

                $i++;
            }

            if ( !isset($installedVerParts[$i]) ) {
                return true;
            }
        }

        return false;
    }

    /**
     *
     * @param string[] $extraArgs
     * @param bool     $massOp
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->updateStatus() call.
     * @throws LSCMException  Thrown indirectly by $this->upgrade_lscwp() call.
     */
    public function upgrade( array $extraArgs, $massOp = false )
    {
        $toVersion = $extraArgs[1];

        $canUpgrade = $this->canUpgrade(
            explode(',', $extraArgs[0]),
            $toVersion,
            $massOp
        );

        if ( !$canUpgrade ) {
            $this->updateStatus(true);
            return UserCommand::EXIT_FAIL;
        }
        else {
            $this->upgrade_lscwp($toVersion);
            return UserCommand::EXIT_SUCC;
        }
    }

    /**
     *
     * @param string[] $extraArgs
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->upgrade() call.
     */
    public function massUpgrade( array $extraArgs )
    {
        $ret = $this->upgrade($extraArgs, true);

        if ( $this->massIncr != '' ) {
            $this->outputResult('MASS_INCR', $this->massIncr);
        }

        return $ret;
    }

    /**
     *
     * @param bool $uninstall
     */
    private function deactivate_lscwp( $uninstall )
    {
        WpFuncs::deactivatePlugins(self::LSCWP_PLUGIN);

        if ( $uninstall ) {
            //Todo: add some msg about having removed plugin files?
            WpFuncs::deletePlugins(array( self::LSCWP_PLUGIN ));
        }
    }

    /**
     *
     * @param bool $uninstall
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->getCurrStatus() call.
     */
    private function disable_lscwp( $uninstall )
    {
        if ( WpConstants::getWpConstant('MULTISITE') ) {
            $blogs =
                Wpdb::getCol("SELECT blog_id FROM " . Wpdb::getBlogs() . ';');

            foreach ( $blogs as $id ) {
                WpFuncs::switchToBlog($id);

                $this->deactivate_lscwp($uninstall);

                WpFuncs::restoreCurrentBlog();
            }
        }
        else {
            $this->deactivate_lscwp($uninstall);
        }

        return $this->getCurrStatus();
    }

    /**
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->getCurrStatus() call.
     * @throws LSCMException  Thrown indirectly by $this->performDisable() call.
     * @throws LSCMException  Thrown indirectly by Logger::uiError() call.
     * @throws LSCMException  Thrown indirectly by
     *     $this->currInstall->addUserFlagFile() call.
     * @throws LSCMException  Thrown indirectly by Logger::uiError() call.
     * @throws LSCMException  Thrown indirectly by Logger::uiSuccess() call.
     */
    private function enable_lscwp()
    {
        /**
         * Should not check directly, can error on success due to object cache.
         */
        WpFuncs::activatePlugin(self::LSCWP_PLUGIN);

        $status = $this->getCurrStatus();

        if ( !($status & WPInstall::ST_LSC_ADVCACHE_DEFINED) ) {
            $status = $this->performDisable(true);

            Logger::uiError(
                'Detected '
                    . "{$this->currInstall->getPath()}/wp-content/advanced-cache.php "
                    . 'as belonging to another cache plugin. Please deactivate '
                    . 'the related cache plugin and try again. You may also '
                    . 'try manually installing through the WordPress Dashboard '
                    . 'and following the instructions given.'
            );

            $this->massIncr = 'FAIL';
        }
        elseif ( $status & WPInstall::ST_PLUGIN_ACTIVE ) {

            if (
                    !is_writable($this->currInstall->getWpConfigFile())
                    &&
                    (
                        !defined('WP_CACHE')
                        ||
                        WpConstants::getWpConstant('WP_CACHE') !== true
                    )
            ) {

                /**
                 * LSCACHE_ADV_CACHE is incorrectly defined true at this point.
                 * Detected status must be manually corrected.
                 */
                $status &= ~WPInstall::ST_LSC_ADVCACHE_DEFINED;
                $this->currInstall->setStatus($status);

                $this->currInstall->addUserFlagFile();
                $status = $this->currInstall->getStatus();

                Logger::uiError(
                    'LSCWP Enabled But Not Caching - Please visit the '
                        . 'WordPress Dashboard for further instructions.'
                );
            }
            else {
                Logger::uiSuccess('LSCWP Enabled');
            }

            $this->massIncr = 'SUCC';
        }

        return $status;
    }

    /**
     *
     * @param string $ver
     * @param bool   $runHooks
     *
     * @throws LSCMException  Thrown when LSCWP plugin version upgrade fails.
     */
    private function upgrade_lscwp( $ver, $runHooks = true )
    {
        /**
         * Label the following $upgraderWrapper output (Cannot be buffered).
         */
        echo "[UPGRADE]\n";

        $upgraderWrapper = new PluginUpgrader;

        $upgraderWrapper->init();
        $upgraderWrapper->upgradeStrings();

        $lscwpPackageURL =
            "https://downloads.wordpress.org/plugin/litespeed-cache.$ver.zip";

        if ( $runHooks ) {
            WpFuncs::addFilter(
                'upgrader_pre_install',
                array(
                    $upgraderWrapper->getWpPluginUpgraderObject(),
                    'deactivate_plugin_before_upgrade'
                ),
                10,
                2
            );

            WpFuncs::addFilter(
                'upgrader_clear_destination',
                array(
                    $upgraderWrapper->getWpPluginUpgraderObject(),
                    'delete_old_plugin'
                ),
                10,
                4
            );
        }

        $upgraderWrapper->run(
            array(
                'package'           => $lscwpPackageURL,
                'destination'       =>
                    WpConstants::getWpConstant('WP_PLUGIN_DIR'),
                'clear_destination' => true,
                'clear_working'     => true,
                'hook_extra'        => array(
                    'plugin' => $this->pluginEntry,
                    'type'   => 'plugin',
                    'action' => 'update',
                )
            )
        );

        /**
         * Start new messages on a new line
         */
        echo "\n";

        if ( $runHooks ) {
            /**
             * Cleanup our hooks, in case something else does an upgrade on
             * this connection.
             */
            WpFuncs::removeFilter(
                'upgrader_pre_install',
                array(
                    $upgraderWrapper->getWpPluginUpgraderObject(),
                    'deactivate_plugin_before_upgrade'
                )
            );

            WpFuncs::removeFilter(
                'upgrader_clear_destination',
                array(
                    $upgraderWrapper->getWpPluginUpgraderObject(),
                    'delete_old_plugin'
                )
            );
        }

        if ( !$upgraderWrapper->getResult()
                || WpFuncs::isWpError($upgraderWrapper->getResult()) ) {

            throw new LSCMException(
                "Failed to upgrade to v$ver.",
                LSCMException::E_NON_FATAL
            );
        }

        $this->updateTranslationFiles();

        /**
         * Force refresh of plugin update information
         */
        WpFuncs::wpCleanPluginsCache();
    }

    /**
     * Gets LSCWP version from the litespeed-cache.php file.
     *
     * @return string
     */
    private function getPluginVersionFromFile()
    {
        $lscwp_data = WpFuncs::getPluginData($this->pluginEntry, false, false);

        return $lscwp_data['Version'];
    }

    /**
     * Checks for local plugin translation files and copies them to the plugin
     * languages directory if able. This function will also attempt to inform
     * the root user when a locale's translation should be retrieved or removed.
     */
    public function updateTranslationFiles()
    {
        $locale = WpFuncs::getLocale();

        if ( $locale == 'en_US' ) {
            return;
        }

        $localTranslationDir = Context::LOCAL_PLUGIN_DIR
            . "/$this->installedLscwpVer/translations";

        $moFileName = "litespeed-cache-$locale.mo";
        $poFileName = "litespeed-cache-$locale.po";
        $localMoFile = "$localTranslationDir/$moFileName";
        $localPoFile = "$localTranslationDir/$poFileName";
        $zipFile = "$localTranslationDir/$locale.zip";
        $translationFlag = "$localTranslationDir/"
            . PluginVersion::TRANSLATION_CHECK_FLAG_BASE . "_$locale";

        $langDir =
            $this->currInstall->getPath() . '/wp-content/languages/plugins';

        if ( !file_exists($langDir) ) {
            mkdir($langDir, 0755);
        }

        if ( file_exists($localMoFile) && file_exists($localPoFile) ) {
            copy($localMoFile, "$langDir/$moFileName");
            copy($localPoFile, "$langDir/$poFileName");
        }
        elseif ( file_exists($zipFile) ) {
            WpFuncs::WpFilesystem();

            if ( WpFuncs::unzipFile($zipFile, $langDir) !== true ) {
                $this->outputResult(
                    'BAD_TRANSLATION',
                    "$locale $this->installedLscwpVer"
                );
            }
        }
        elseif ( !file_exists($translationFlag)
                || (time() - filemtime($translationFlag)) > 86400  ) {

            $this->outputResult(
                'GET_TRANSLATION',
                "$locale $this->installedLscwpVer"
            );
        }
    }

    /**
     *
     * @since 1.13.4.4
     * @since 1.17.0.3  Added required parameter $advCacheFileContents.
     *
     * @param string $advCacheFileContents
     *
     * @return bool
     */
    private static function advancedCacheFileHasLscacheDefine(
        $advCacheFileContents
    )
    {
        $definePosition = strpos($advCacheFileContents, 'LSCACHE_ADV_CACHE');

        return ($definePosition !== false);
    }

    /**
     * Check if advanced-cache.php file contains LSCWP placeholder text. This
     * file with generic placeholder text was re-added by LSCWP for improved
     * compatibility with WordPress versions lower than v5.3.
     *
     * @since 1.17.0.3
     *
     * @param string $advCacheFileContent
     *
     * @return bool
     */
    private static function advancedCacheFileHasPlaceholderMsg(
        $advCacheFileContent
    )
    {
        $definePosition = strpos(
            $advCacheFileContent,
            'A compatibility placeholder for WordPress < v5.3'
        );

        return ($definePosition !== false);
    }

    private function includeLSCWPAdvancedCacheFile()
    {
        if ( file_exists($this->advancedCacheFile) ) {

            $advCacheFileContents =
                file_get_contents($this->advancedCacheFile);

            if (
                    $advCacheFileContents !== ''
                    &&
                    $this->advancedCacheFileHasLscacheDefine(
                        $advCacheFileContents
                    )
            ) {
                include_once $this->advancedCacheFile;
            }
        }
    }

    /**
     *
     * @throws LSCMException  Thrown indirectly by
     *     $this->currInstall->removePluginFiles() call.
     */
    public function removeLscwpPluginFiles()
    {
        $this->currInstall->removePluginFiles(dirname($this->pluginEntry));
    }

    /**
     *
     * @param string[] $extraArgs
     * @param bool     $massOp     Not used at this time.
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by
     *     DashNotifier::prepareUserInstall() call.
     * @throws LSCMException  Thrown indirectly by DashNotifier::doNotify()
     *     call.
     * @throws LSCMException  Thrown indirectly by Logger::uiSuccess() call.
     * @throws LSCMException  Thrown indirectly by Logger::uiError() call.
     *
     * @noinspection PhpUnusedParameterInspection
     */
    public function dashNotify( array $extraArgs, $massOp = false )
    {
        if ( DashNotifier::canNotify($this->currInstall->getPath()) ) {
            DashNotifier::prepareUserInstall();

            if ( DashNotifier::doNotify(base64_decode($extraArgs[0])) ) {
                Logger::uiSuccess('Notified Successfully');
                $this->massIncr = 'SUCC';

                return UserCommand::EXIT_SUCC;
            }

            Logger::uiError('Failed to Notify');
            $this->massIncr = 'FAIL';
        }
        else {
            $this->massIncr = 'BYPASS';
        }

        return UserCommand::EXIT_FAIL;
    }

    /**
     *
     * @param string[] $extraArgs
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->dashNotify() call.
     */
    public function massDashNotify( array $extraArgs )
    {
        $ret = $this->dashNotify($extraArgs, true);

        if ( $this->massIncr != '' ) {
            $this->outputResult('MASS_INCR', $this->massIncr);
        }

        return $ret;
    }

    /**
     *
     * @param string[] $extraArgs  Unused for now.
     * @param bool     $massOp     Unused for now.
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by Logger::uiSuccess() call.
     *
     * @noinspection PhpUnusedParameterInspection
     */
    public function dashDisable( array $extraArgs, $massOp = false )
    {
        if ( WpConstants::getWpConstant('MULTISITE') ) {
            $blogs =
                Wpdb::getCol('SELECT blog_id FROM ' . Wpdb::getBlogs() . ';');

            foreach ( $blogs as $id ) {
                WpFuncs::switchToBlog($id);

                DashNotifier::deactivate(true);

                WpFuncs::restoreCurrentBlog();
            }
        }
        else {
            DashNotifier::deactivate(true);
        }

        if ( WpFuncs::isPluginActive(DashNotifier::DASH_PLUGIN) ) {
            $this->massIncr = 'FAIL';
            return UserCommand::EXIT_FAIL;
        }

        Logger::uiSuccess('Dash Notifier Disabled');
        $this->massIncr = 'SUCC';

        return UserCommand::EXIT_SUCC;
    }

    /**
     *
     * @param string[] $extraArgs
     *
     * @return int
     *
     * @throws LSCMException  Thrown indirectly by $this->dashDisable() call.
     */
    public function massDashDisable( array $extraArgs )
    {
        $ret = $this->dashDisable($extraArgs, true);

        if ( $this->massIncr != '' ) {
            $this->outputResult('MASS_INCR', $this->massIncr);
        }

        return $ret;
    }

    /**
     *
     * @since 1.12
     *
     * @param bool $setOutputResult
     *
     * @return string
     */
    public function getQuicCloudAPIKey( $setOutputResult = false )
    {
        $key = WpFuncs::applyFilters('litespeed_conf', 'api_key', null);

        if ( $key == 'api_key' || $key == null ) {
            $key = '';
        }

        if ( $setOutputResult ) {
            $this->outputResult('API_KEY', $key);
        }

        return $key;
    }

    /**
     * Set global server and environment variables.
     *
     * @since 1.9.8
     *
     * @param string $key
     * @param mixed  $val
     */
    private function setEnvVar( $key, $val )
    {
        $_SERVER[$key] = $val;
        putenv("$key=$val");
    }

    /**
     * Checks if the current WordPress installation is a multisite install and
     * does some preload setup if so.
     *
     * Patterns and multisite check logic based on WordPress function
     * is_multisite().
     *
     * @since 1.9.8
     *
     * @return bool
     *
     * @throws LSCMException  Thrown when DOMAIN_CURRENT_SITE is not found with
     *     MULTISITE defined.
     * @throws LSCMException  Thrown when PATH_CURRENT_SITE is not found with
     *     MULTISITE defined.
     */
    private function isMultisite()
    {
        $config_content =
            file_get_contents($this->currInstall->getWpConfigFile());

        $isMultiSite = (
            preg_match(
                '/define\(\s*[\'"]MULTISITE[\'"]\s*,[^;]*;/',
                $config_content,
                $m1
            )
            &&
            preg_match(
                '/define\(\s*[\'"]MULTISITE[\'"]\s*,\s*true\s*\)\s*;/',
                $m1[0]
            )
        )
        ||
        (
            preg_match(
                '/define\(\s*[\'"]SUBDOMAIN_INSTALL[\'"]\s*,[^;]*;/',
                $config_content
            )
            ||
            preg_match(
                '/define\(\s*[\'"]VHOST[\'"]\s*,[^;]*;/',
                $config_content
            )
            ||
            preg_match(
                '/define\(\s*[\'"]SUNRISE[\'"]\s*,[^;]*;/',
                $config_content
            )
        );

        if ( !$isMultiSite ) {
            return false;
        }

        $domainCurrentSiteFound = preg_match(
            '/define\(\s*[\'"]DOMAIN_CURRENT_SITE[\'"]\s*,'
                . '\s*[\'"](.+)[\'"]\s*\)\s*;/',
            $config_content,
            $m2
        );

        if ( !$domainCurrentSiteFound ) {
            throw new LSCMException(
                'Cannot find DOMAIN_CURRENT_SITE with MULTISITE defined.'
            );
        }

        $this->currInstall->setServerName($m2[1]);

        $pathCurrentSiteFound = preg_match(
            '/define\(\s*[\'"]PATH_CURRENT_SITE[\'"]\s*,'
                . '\s*[\'"](.+)[\'"]\s*\)\s*;/',
            $config_content,
            $m3
        );

        if ( !$pathCurrentSiteFound ) {
            throw new LSCMException(
                'Cannot find PATH_CURRENT_SITE with MULTISITE defined.'
            );
        }

        $this->setEnvVar('REQUEST_URI', $m3[1]);

        Util::define_wrapper('WP_NETWORK_ADMIN', true);

        return true;
    }

    /**
     *
     * WP Variables: $wpdb, $shortcode_tags
     *
     * @global \wpdb $wpdb
     * @global array $shortcode_tags
     *
     * @throws LSCMException  Thrown when detected WordPress version is lower
     *     then 4.0.
     * @throws LSCMException  Thrown when unable to find a required WordPress
     *     include file.
     * @throws LSCMException  Thrown indirectly by $this->isMultisite() call.
     *
     * @noinspection PhpUndefinedClassInspection
     */
    private function initWp()
    {
        /**
         * Declared global variables for use in included files.
         *
         * @noinspection PhpUnusedLocalVariableInspection
         */
        global $wpdb, $shortcode_tags;

        error_reporting(E_ALL);

        /**
         * Attempt to override any WordPress memory limits.
         */
        Util::define_wrapper('WP_MEMORY_LIMIT', '512M');
        Util::define_wrapper('WP_MAX_MEMORY_LIMIT', '512M');

        /**
         * Only load core WordPress functionality.
         */
        Util::define_wrapper('SHORTINIT', true);

        $wpPath = $this->currInstall->getPath();

        /**
         * Set WP version data global variables, including $wp_version.
         */
        include_once "$wpPath/wp-includes/version.php";

        /** @noinspection PhpUndefinedVariableInspection  $wp_version is defined
         *     and made available in previous version.php include
         */
        if ( Util::betterVersionCompare($wp_version, '4.0', '<') ) {
            throw new LSCMException(
                "Detected WordPress version as $wp_version. Version 4.0 '
                    . 'required at minimum."
            );
        }

        /**
         * Set needed server variables.
         */
        $_SERVER['SCRIPT_FILENAME'] = "$wpPath/wp-admin/plugins.php";

        if ( ! $this->isMultisite() ) {
            $this->setEnvVar('REQUEST_URI', '');
        }

        /**
         * Set for LSCWP v1.1.5.1+ plugin logic.
         */
        if ( $docRoot = $this->currInstall->getDocRoot() ) {

            /**
             * For enable/disable.
             */
            $this->setEnvVar('DOCUMENT_ROOT', $docRoot);
        }

        $serverName = $this->currInstall->getServerName();

        if ( empty($serverName) ) {
            $serverName = self::LSCWP_HTTP_HOST_TEST;
        }

        /**
         * For security plugins.
         */
        $this->setEnvVar('HTTP_HOST', $serverName);

        /**
         * Version specific includes may fail on RC releases.
         */

        $includeFiles = array(
            '/wp-load.php',
            '/wp-includes/default-constants.php',
            '/wp-includes/formatting.php',
            '/wp-includes/meta.php',
            '/wp-includes/l10n.php',
            '/wp-includes/class-wp-walker.php',
            '/wp-includes/capabilities.php'
        );

        if ( Util::betterVersionCompare($wp_version, '4.4.0', '>=') ) {
            $includeFiles[] = '/wp-includes/class-wp-roles.php';
            $includeFiles[] = '/wp-includes/class-wp-role.php';
            $includeFiles[] = '/wp-includes/class-wp-user.php';
            $includeFiles[] = '/wp-includes/rest-api.php';
            $includeFiles[] = '/wp-includes/class-wp-http-encoding.php';
            $includeFiles[] = '/wp-includes/class-wp-http-proxy.php';
            $includeFiles[] = '/wp-includes/class-wp-http-response.php';
            $includeFiles[] = '/wp-includes/class-wp-http-curl.php';
            $includeFiles[] = '/wp-includes/class-wp-http-cookie.php';
        }

        $includeFiles[] = '/wp-includes/query.php';
        $includeFiles[] = '/wp-includes/theme.php';
        $includeFiles[] = '/wp-includes/class-wp-theme.php';
        $includeFiles[] = '/wp-includes/user.php';
        $includeFiles[] = '/wp-includes/general-template.php';
        $includeFiles[] = '/wp-includes/link-template.php';
        $includeFiles[] = '/wp-includes/post.php';
        $includeFiles[] = '/wp-includes/kses.php';
        $includeFiles[] = '/wp-includes/cron.php';
        $includeFiles[] = '/wp-includes/update.php';
        $includeFiles[] = '/wp-includes/shortcodes.php';
        $includeFiles[] = '/wp-includes/http.php';

        if ( Util::betterVersionCompare($wp_version, '5.9.0', '>=') ) {
            $includeFiles[] = '/wp-includes/class-wp-http.php';
        }
        else {
            $includeFiles[] = '/wp-includes/class-http.php';
        }


        if ( Util::betterVersionCompare($wp_version, '4.6.0', '>=') ) {
            $includeFiles[] = '/wp-includes/class-wp-http-requests-response.php';
        }

        if ( Util::betterVersionCompare($wp_version, '4.7.0', '>=') ) {
            $includeFiles[] = '/wp-includes/class-wp-http-requests-hooks.php';

            /**
             * Content contained in /wp-includes/query.php for earlier versions.
             */
            $includeFiles[] = '/wp-includes/class-wp-query.php';
        }

        if ( Util::betterVersionCompare($wp_version, '5.0.0', '>=') ) {
            $includeFiles[] = '/wp-includes/blocks.php';
            $includeFiles[] = '/wp-includes/class-wp-block-parser.php';
        }

        if ( Util::betterVersionCompare($wp_version, '6.1.0', '>=') ) {
            $includeFiles[] = '/wp-includes/class-wp-textdomain-registry.php';
        }

        $includeFiles[] = '/wp-includes/ms-functions.php';
        $includeFiles[] = '/wp-includes/ms-deprecated.php';
        $includeFiles[] = '/wp-includes/pluggable.php';
        $includeFiles[] = '/wp-admin/includes/plugin.php';
        $includeFiles[] = '/wp-admin/includes/file.php';
        $includeFiles[] = '/wp-admin/includes/class-wp-upgrader.php';
        $includeFiles[] = '/wp-admin/includes/misc.php';
        $includeFiles[] = '/wp-admin/includes/template.php';

        if ( Util::betterVersionCompare($wp_version, '6.5.0', '>=') ) {
            $includeFiles[] = '/wp-includes/class-wp-plugin-dependencies.php';
        }

        set_error_handler('\Lsc\Wp\WPCaller::warning_handler');

        /**
         * Force WP to use PHP I/O file handling.
         */
        Util::define_wrapper('FS_METHOD', 'direct');

        /**
         * Trigger an early return from WP Rocket advanced-cache.php to prevent
         * WP Rocket from serving a cached copy and killing the process. This
         * occurs when calling an action from our control panel plugins and is
         * fixed by more closely matching the environment of a direct cli call.
         */
        unset($_SERVER['REQUEST_METHOD']);

        self::redefineDisabledFunctions();

        foreach ( $includeFiles as $file ) {
            $file = $wpPath . $file;

            if ( !file_exists($file) ) {
                throw new LSCMException(
                    "Could not include missing file $file."
                );
            }

            include_once $file;
        }

        restore_error_handler();

        /**
         * Needs to be defined after including files.
         */
        Util::define_wrapper('WP_ADMIN', true);

        /**
         * Define common WP constants and set 'wp_plugin_paths' array.
         */
        WpFuncs::wpPluginDirectoryConstants();

        /**
         * Do not load other plugins.
         */
        $GLOBALS['wp_plugin_paths'] = array();

        WpFuncs::wpCookieConstants();

        /**
         * Create global wp_query (WordPress) object entry. Needed during
         * LSCWP uninstall.
         */
        $wpQueryWrapper = new WpQuery();

        $GLOBALS['wp_the_query'] = $wpQueryWrapper->getWpWpQueryObject();
        $GLOBALS['wp_query']     = $GLOBALS['wp_the_query'];

        if ( Util::betterVersionCompare($wp_version, '6.1.0', '>=') ) {
            $wpTextdomainRegistryWrapper = new WpTextdomainRegistry();

            $GLOBALS['wp_textdomain_registry'] =
                $wpTextdomainRegistryWrapper->getWpWpTextdomainRegistryObject();
        }

        $this->pluginEntry = WpConstants::getWpConstant('WP_PLUGIN_DIR')
            . '/' . self::LSCWP_PLUGIN;

        if ( $this->loadLscwp && file_exists($this->pluginEntry) ) {
            include $this->pluginEntry;

            $this->installedLscwpVer = $this->getPluginVersionFromFile();

            if ( Util::betterVersionCompare($this->installedLscwpVer, '3.0.4', '<') ) {
                $this->includeLSCWPAdvancedCacheFile();
            }
        }
    }

}