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` sh-3ll

HOME


sh-3ll 1.0
DIR:/home/ami/.trash/dup-installer/ctrls/
Upload File :
Current File : /home/ami/.trash/dup-installer/ctrls/ctrl.s2.dbtest.php
<?php
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
/** IDE HELPERS */
/* @var $GLOBALS['DUPX_AC'] DUPX_ArchiveConfig */

/**
 * Lightweight abstraction layer for testing the connectivity of a database request
 *
 * Standard: PSR-2
 *
 * @package SC\DUPX\DBTest
 * @link http://www.php-fig.org/psr/psr-2/
 *
 */

class DUPX_DBTestIn
{
	//Create, Rename, Empty, Skip
	public $dbaction;
	public $dbhost;
	public $dbname;
	public $dbuser;
	public $dbpass;
	public $dbport;
	public $dbcollatefb;
}

class DUPX_DBTestOut extends DUPX_CTRL_Out
{
	public function __construct()
	{
		parent::__construct();
	}
}

class DUPX_DBTest
{
	public $databases		 = array();
	public $tblPerms;
	public $reqs			 = array();
	public $notices			 = array();
	public $reqsPass		 = false;
	public $noticesPass		 = false;
	public $in;
	public $ac;
	public $collationStatus = array();
    public $collationReplaceList = array();
	public $lastError;
	//JSON | PHP
	public $responseMode	 = 'JSON';
	//TEST | LIVE
	public $runMode			 = 'TEST';
	//TEXT | HTML
	public $displayMode		 = 'TEXT';
	//PRIVATE
	private $out;
	private $dbh;
	private $permsChecked  = false;
	private $newDBMade	   = false;


	public function __construct(DUPX_DBTestIn $input)
	{
		$default_msg	 = 'This test passed without any issues';
		$this->in		 = $input;
		$this->out		 = new DUPX_DBTestOut();
		$this->tblPerms	 = array('all' => -1, 'create' => -1, 'insert' => -1, 'update' => -1, 'delete' => -1, 'select' => -1, 'drop' => -1);
		$this->ac = DUPX_ArchiveConfig::getInstance();

		//REQUIRMENTS
		//Pass States: skipped = -1		failed = 0		passed = 1   warned = 2
		$this->reqs[5]	 = array('title' => "Create Database User", 'info' => "{$default_msg}", 'pass' => -1);
		$this->reqs[10]	 = array('title' => "Host Connection", 'info' => "{$default_msg}", 'pass' => -1);
		$this->reqs[20]	 = array('title' => "Database Version", 'info' => "{$default_msg}", 'pass' => -1);
		$this->reqs[30]	 = array('title' => "Database Create New Tests", 'info' => "{$default_msg}", 'pass' => -1);
		$this->reqs[40]	 = array('title' => "Privileges: User Visibility", 'info' => "{$default_msg}", 'pass' => -1);
		$this->reqs[50]	 = array('title' => "Manual Table Check", 'info' => "{$default_msg}", 'pass' => -1);
		$this->reqs[60]	 = array('title' => "Privileges: User Resources", 'info' => "{$default_msg}", 'pass' => -1);
		$this->reqs[70]	 = array('title' => "Check Collation Capability", 'info' => "{$default_msg}", 'pass' => -1);
		$this->reqs[80]	 = array('title' => "Database GTID mode", 'info' => "{$default_msg}", 'pass' => -1);
		//NOTICES
		$this->notices[10]	 = array('title' => "Table Case Sensitivity", 'info' => "{$default_msg}", 'pass' => -1);
		$this->notices[20]	 = array('title' => "Source Database Triggers", 'info' => "{$default_msg}", 'pass' => -1);
       }

	public function run()
	{
		//Requirments
        $this->runBasic();

		$this->buildStateSummary();
		$this->buildDisplaySummary();
		$this->out->payload = $this;
		foreach ($this->out->payload->in as $key=>$val) {
			$this->out->payload->in->$key = htmlentities($val);
		}
		$this->out->getProcessTime();

		//Return PHP or JSON result
		if ($this->responseMode == 'PHP') {
			$result = $this->out;
			return $result;
		} elseif ($this->responseMode == 'JSON') {
			$result = DupLiteSnapJsonU::wp_json_encode($this->out);
			return $result;
		} else {
			die('Please specific the responseMode property');
		}

	}

	private function runBasic()
	{
		//REQUIRMENTS:
		//[10]	 = "Verify Host Connection"
		//[20]	 = "Check Server Version"
		//[30]	 = "Create New Database Tests"
		//[40]	 = "Confirm Database Visibility"
		//[50]	 = "Manual Table Check"
		//[60]	 = "Test User Table Privileges"


		$this->r10All($this->reqs[10]);
		$this->r20All($this->reqs[20]);

		switch ($this->in->dbaction) {
			case "create" :
				$this->r30Basic($this->reqs[30]);
				$this->r40Basic($this->reqs[40]);
				break;
			case "empty" :
				$this->r40Basic($this->reqs[40]);
				break;
			case "rename":
				$this->r40Basic($this->reqs[40]);
				break;
			case "manual":
				$this->r40Basic($this->reqs[40]);
				$this->r50All($this->reqs[50]);
				break;
		}

		$this->r60All($this->reqs[60]);

		//NOTICES
		$this->n10All($this->notices[10]);
		$this->n20All($this->notices[20]);
		$this->r70All($this->reqs[70]);
		$this->r80All($this->reqs[80]);
		$this->basicCleanup();
	}

    /**
     * Verify Host Connection
     *
     * @return null
     */
    private function r10All(&$test)
    {
        try {

            if ($this->isFailedState($test)) {
                return;
            }

            //Host check
            $parsed_host_info = DUPX_DB::parseDBHost($this->in->dbhost);
            $parsed_host      = $parsed_host_info[0];
            $isInvalidHost    = $parsed_host == 'http' || $parsed_host == "https";

            if ($isInvalidHost) {
                $fixed_host = DupLiteSnapLibIOU::untrailingslashit(str_replace($parsed_host."://","",$this->in->dbhost));
                $test['pass'] = 0;
                $test['info'] = "<b>[".htmlentities($this->in->dbhost)."]</b> is not a valid input. Try using <b>[$fixed_host]</b> instead.";
                return;
            }

            $this->dbh = DUPX_DB::connect($this->in->dbhost, $this->in->dbuser, $this->in->dbpass, null);
            if ($this->dbh) {
                $test['pass'] = 1;
                $test['info'] = "The user <b>[".htmlentities($this->in->dbuser)."]</b> successfully connected to the database server on host <b>[".htmlentities($this->in->dbhost)."]</b>.";
            } else {
                $msg          = "Unable to connect the user <b>[".htmlentities($this->in->dbuser)."]</b> to the host <b>[".htmlentities($this->in->dbhost)."]</b>";
                $test['pass'] = 0;
                $test['info'] = (mysqli_connect_error()) ? "{$msg}. The server error response was: <i>".htmlentities(mysqli_connect_error()).'</i>' : "{$msg}. Please contact your hosting provider or server administrator.";
            }
        }
        catch (Exception $ex) {
            $test['pass'] = 0;
            $test['info'] = "Unable to connect the user <b>[".htmlentities($this->in->dbuser)."]</b> to the host <b>[".htmlentities($this->in->dbhost)."]</b>.<br/>".$this->formatError($ex);
        }
    }

	/**
	 * Check Server Version
	 *
	 * @return null
	 */
	private function r20All(&$test)
	{
		try {

			if ($this->isFailedState($test)) {
				return;
			}

			$db_version		 = DUPX_DB::getVersion($this->dbh);
			$db_version_pass = version_compare('5.0.0', $db_version) <= 0;

			if ($db_version_pass) {
				$test['pass']	 = 1;
				$test['info']	 = "This test passes with a current database version of <b>[".htmlentities($db_version)."]</b>";
			} else {
				$test['pass']	 = 0;
				$test['info']	 = "The current database version is <b>[".htmlentities($db_version)."]</b> which is below the required version of 5.0.0  "
					."Please work with your server admin or hosting provider to update the database server.";
			}

		} catch (Exception $ex) {
			$test['pass']	 = 0;
			$test['info']	 = "Unable to properly check the database server version number.<br/>" . $this->formatError($ex);
		}
	}

	/**
	 * Create New Database Basic Test
	 * Use selects: 'Create New Database for basic
	 *
	 * @return null
	 */
	private function r30Basic(&$test)
	{
		try {

			if ($this->isFailedState($test)) {
				return;
			}

			//DATABASE EXISTS
			$db_found = mysqli_select_db($this->dbh, $this->in->dbname);
			if ($db_found) {
				$test['pass']	 = 0;
				$test['info']	 = "DATABASE CREATION FAILURE: A database named <b>[".htmlentities($this->in->dbname)."]</b> already exists.<br/><br/>"
							."Please continue with the following options:<br/>"
							."- Choose a different database name or remove this one.<br/>"
							."- Change the action drop-down to an option like \"Connect and Remove All Data\".<br/>";
				return;
			}

			//CREATE & DROP DB
			$result		 = mysqli_query($this->dbh, "CREATE DATABASE IF NOT EXISTS `".mysqli_real_escape_string($this->dbh, $this->in->dbname)."`");
			$db_found	 = mysqli_select_db($this->dbh, mysqli_real_escape_string($this->dbh, $this->in->dbname));

			if (!$db_found) {
				$test['pass']	 = 0;
				$test['info']	 = sprintf(ERR_DBCONNECT_CREATE, htmlentities($this->in->dbname));
				$test['info'] .= "\nError Message: ".mysqli_error($this->dbh);
			} else {
				$this->newDBMade = true;
				$test['pass']	= 1;
				$test['info'] = "Database <b>[".htmlentities($this->in->dbname)."]</b> was successfully created and dropped.  The user has enough privileges to create a new database with the "
							. "'Basic' option enabled.";
			}
		} catch (Exception $ex) {
			$test['pass']	 = 0;
			$test['info']	 = "Error creating database <b>[".htmlentities($this->in->dbname)."]</b>.<br/>" . $this->formatError($ex);
		}
	}

	/**
	 * Confirm Database Visibility for Basic
	 *
	 * @return null
	 */
	private function r40Basic(&$test)
	{
		try {

			if ($this->isFailedState($test)) {
				return;
			}

			//Show Databases by the host account, otherwise a timeout
			//to issue the 'Show Databases' query may occur on some hosts
			$host_user = substr_replace($this->in->dbuser, '', strpos($this->in->dbuser, '_'));
			$this->databases = DUPX_DB::getDatabases($this->dbh, $host_user);

			$db_found = mysqli_select_db($this->dbh, $this->in->dbname);
			if (!$db_found) {
				$test['pass'] = 0;
				$test['info'] = "The user '<b>[".htmlentities($this->in->dbuser)."]</b>' is unable to see the database named '<b>[".htmlentities($this->in->dbname)."]</b>'.  "
					. "Be sure the database name already exists and check that the database user has access to the database.  "
                                        . "If you want to create a new database choose the action 'Create New Database'.";
			} else {
				$test['pass'] = 1;
				$test['info'] = "The database user <b>[".htmlentities($this->in->dbuser)."]</b> has visible access to see the database named <b>[".htmlentities($this->in->dbname)."]</b>";
			}

		} catch (Exception $ex) {
			$test['pass'] = 0;
			$test['info'] = "The user '<b>[".htmlentities($this->in->dbuser)."]</b>' is unable to see the database named '<b>[".htmlentities($this->in->dbname)."]</b>'.  "
				. "Be sure the database name already exists and check that the database user has access to the database.  "
                                . "If you want to create a new database choose the action 'Create New Database'<br/>" . $this->formatError($ex);
		}
	}

	/**
	 * Manual Table Check
	 *
	 * User chooses "Manual SQL Execution"
	 * Core WP has 12 tables. Check to make sure at least 10 are present
	 * otherwise present an error message
	 *
	 * @return null
	 */
	private function r50All(&$test)
	{
		try {

			if ($this->isFailedState($test)) {
				return;
			}

			$tblcount = DUPX_DB::countTables($this->dbh, htmlentities($this->in->dbname));

			if ($tblcount < 10) {
				$test['pass']	 = 0;
				$test['info']	 = sprintf(ERR_DBMANUAL, htmlentities($this->in->dbname), htmlentities($tblcount));
			} else {
				$test['pass']	 = 1;
				$test['info']	 = "This test passes.  A WordPress database looks to be setup.";
			}

		} catch (Exception $ex) {
			$test['pass']	 = 0;
			$test['info']	 = "The database user <b>[".htmlentities($this->in->dbuser)."]</b> has visible access to see the database named <b>[".htmlentities($this->in->dbname)."]</b> .<br/>" . $this->formatError($ex);
		}
	}

	/**
	 * Test User Table privileges
	 *
	 * @return null
	 */
	private function r60All(&$test)
	{
		try {

			if ($this->isFailedState($test)) {
				return;
			}

			$this->checkTablePerms();

			if ($this->tblPerms['all']) {
				$test['pass']	 = 1;
				$test['info']	 = "The user <b>[".htmlentities($this->in->dbuser)."]</b> has the correct privileges on the database <b>[".htmlentities($this->in->dbname)."]</b>";
			} else {
				$list		 = array();
				$test['pass']	 = 0;
				foreach ($this->tblPerms as $key => $val) {
					if ($key != 'all') {
						if ($val == false) array_push($list, $key);
					}
				}
				$list		 = implode(',', $list);
				$test['info']	 = "The user <b>[".htmlentities($this->in->dbuser)."]</b> is missing the privileges <b>[".htmlentities($list)."]</b> on the database <b>[".htmlentities($this->in->dbname)."]</b>";
			}

		} catch (Exception $ex) {
			$test['pass']	 = 0;
			$test['info']	 = "Failure in attempt to read the users table priveleges.<br/>" . $this->formatError($ex);
		}
	}

	/**
	 * Check Collation Capability
	 *
	 * @return null
	 */
	private function r70All(&$test)
	{
		try {
			if ($this->isFailedState($test)) {
				return;
			}

			$this->collationStatus = DUPX_DB::getCollationStatus($this->dbh, $this->ac->dbInfo->collationList);

            $collation_arr = array(
                'utf8mb4_unicode_520_ci',
                'utf8mb4_unicode_520',
                'utf8mb4_unicode_ci',
                'utf8mb4',
                'utf8_unicode_520_ci',
                'utf8_unicode_520',
                'utf8_unicode_ci',
                'utf8',
            );
			$invalid = 0;
			$collation_arr_max = count($collation_arr);
			$invalid_match = 0;

			foreach($this->collationStatus as $key => $val) {
				if ($this->collationStatus[$key]['found'] == 0) {
				    if($this->in->dbcollatefb){
				        $not_supported_col = $this->collationStatus[$key]['name'];
                        for($i = 0; $i < $collation_arr_max; $i++) {
							$col_status = DUPX_DB::getCollationStatus($this->dbh, array($collation_arr[$i]));
							$cur_col_is_supported = $col_status[0]['found'];
							if($cur_col_is_supported){
								$this->collationReplaceList[] = array(
									'search'    => $not_supported_col,
									'replace'   => $collation_arr[$i]
								);
								++$invalid_match;
								break;
							}
						}
						$invalid = 1;
                    	break;
                    } else {
                        $invalid = 1;
                        break;
                    }
				}
			}

			if($invalid_match > 0) {
				$invalid = -1;
			}

			if ($invalid === 1) {
				$test['pass']	 = 0;
				$test['info']	 = "Please check the 'Legacy' checkbox in the options section and then click the 'Retry Test' link.<br/>"
								 . "<small>Details: The database where the package was created has a collation that is not supported on this server.  This issue happens "
								 . "when a site is moved from an older version of MySQL to a newer version of MySQL. The recommended fix is to update MySQL on this server to support "
								 . "the collation that is failing below.  If that is not an option for your host then continue by clicking the 'Legacy' checkbox above.  For more "
								 . "details about this issue and other details regarding this issue see the FAQ link below. </small>";
			} else if($invalid === -1) {
                $test['pass']	 = 1;
                $test['info']	 = "There is at least one collation that is not supported, however a replacement collation is possible.  Please continue by clicking the next button and the "
								 . "installer will attempt to use a legacy/fallback collation type to create the database table.  For more details about this issue see the FAQ link below.";
            } else {
				$test['pass']	 = 1;
				$test['info']	 = "Collation test passed! This database supports the required table collations.";
			}

		} catch (Exception $ex) {
			//Return '1' to allow user to continue
			$test['pass']	 = 1;
			$test['info']	 = "Failure in attempt to check collation capability status.<br/>" . $this->formatError($ex);
		}

	}

	/**
	 * Check GTID mode
	 *
	 * @return null
	 */
	private function r80All(&$test)
	{
		try {
			if ($this->isFailedState($test)) {
				return;
			}

			$gtid_mode_enabled = false;
			$query  = "SELECT @@GLOBAL.GTID_MODE";
			$result = mysqli_query($this->dbh, $query);

			if ($result = mysqli_query($this->dbh, $query)) {
				if ($row = mysqli_fetch_array($result, MYSQLI_NUM)) {
					if ('ON' == $row[0] || 'on' == $row[0])
						$gtid_mode_enabled = true;
				}
			}

			// $gtid_mode_enabled = true;
			if ($gtid_mode_enabled) {
				$test['pass'] = 2;
				$test['info'] = "Your database server have GTID mode is on, It might make a trouble in Database installation.<br/>"
								 . "<small>Details: You might face the error something like Statement violates GTID consistency. "
								 . "You should ask hosting provider to make off GTID off. "
								 . "You can make off GTID mode as decribed in the <a href='https://dev.mysql.com/doc/refman/5.7/en/replication-mode-change-online-disable-gtids.html' target='_blank'>https://dev.mysql.com/doc/refman/5.7/en/replication-mode-change-online-disable-gtids.html</a>"
								 . "</small>";
			} else {
				$test['pass'] = 1;
				$test['info'] = "The installer has not detected GTID mode.";
			}
		} catch (Exception $ex) {			
			//Return '1' to allow user to continue
			$test['pass'] = 1;
			$test['info'] = "Failure in attempt to check GTID mode status.<br/>" . $this->formatError($ex);
		}
	}

	/**
	 * Table Case Compatibility
	 *
	 * Failure occurs when:
	 *		BuildServer = lower_case_table_names=1		&&
	 *		BuildServer = HasATableUpperCase			&&
	 *		InstallServer = lower_case_table_names=0
	 *
	 * @return null
	 */
	private function n10All(&$test)
	{
		try {

			if ($this->isFailedState($test)) {
				return;
			}

			$localhostLowerCaseTables = DUPX_DB::getVariable($this->dbh, 'lower_case_table_names');
			$localhostLowerCaseTables = (empty($localhostLowerCaseTables) && DUPX_U::isWindows()) ? 0 : $localhostLowerCaseTables;

			if (isset($this->ac->dbInfo->isTablesUpperCase) && $this->ac->dbInfo->isTablesUpperCase && $this->ac->dbInfo->varLowerCaseTables == 1 && $localhostLowerCaseTables == 0) {
				$test['pass']	 = 0;
				$test['info']	 = "An upper case table name was found in the database SQL script and the server variable lower_case_table_names is set  "
					. "to <b>[".htmlentities($localhostLowerCaseTables)."]</b>.  When both of these conditions are met it can lead to issues with creating tables with upper case characters.  "
					. "<br/><b>Options</b>:<br/> "
					. " - On this server have the host company set the lower_case_table_names value to 1 or 2 in the my.cnf file.<br/>"
					. " - On the build server set the lower_case_table_names value to 2 restart server and build package.<br/>"
					. " - Optionally continue the install with data creation issues on upper case tables names.<br/>";
			} else {
				$test['pass']	 = 1;
				$test['info']	 = "No table casing issues detected. This servers variable setting for lower_case_table_names is [{$localhostLowerCaseTables}]";
			}

		} catch (Exception $ex) {
			//Return '1' to allow user to continue
			$test['pass']	 = 1;
			$test['info']	 = "Failure in attempt to read the upper case table status.<br/>" . $this->formatError($ex);
		}
	}

    /**
     * Show source site trigger creates
     *
     * @return null
     */
    private function n20All(&$test)
    {
        if ($this->isFailedState($test)) {
            return;
        }

        $triggers = (array)$this->ac->dbInfo->triggerList;
        if (count($triggers) > 0) {
            $test['pass'] = 0;
            $test['info'] = "";

            foreach ($triggers as $trigger) {
                $test['info'] .= $trigger->create."\n\n";;
            }

        } else {
            $test['pass'] = 1;
            $test['info'] = "Source site did not contain triggers.";
        }
    }

	/**
	 * Input has UTF8 data
	 *
	 * @return null
	 */
	private function n30All(&$test)
	{
		try {

			if ($this->isFailedState($test)) {
				return;
			}

			//WARNNG: Input has utf8 data
			$dbConnItems = array($this->in->dbhost, $this->in->dbuser, $this->in->dbname, $this->in->dbpass);
			$dbUTF8_tst	 = false;
			foreach ($dbConnItems as $value) {
				if (DUPX_U::isNonASCII($value)) {
					$dbUTF8_tst = true;
					break;
				}
			}

			if (!$dbConn && $dbUTF8_tst) {
				$test['pass']	 = 0;
				$test['info']	 = ERR_TESTDB_UTF8;

			} else {
				$test['pass']	 = 1;
				$test['info']	 = "Connection string is using all non-UTF8 characters and should be safe.";
			}

		} catch (Exception $ex) {
			//Return '1' to allow user to continue
			$test['pass']	 = 1;
			$test['info']	 = "Failure in attempt to read input has utf8 data status.<br/>" . $this->formatError($ex);
		}
	}

	/**
	 * Runs a series of CREATE, INSERT, SELECT, UPDATE, DELETE and DROP statements
	 * on a temporary test table to find out the state of the users privileges
	 *
	 * @return null
	 */
	private function checkTablePerms()
	{

		if ($this->permsChecked) {
			return;
		}

		mysqli_select_db($this->dbh, mysqli_real_escape_string($this->dbh, $this->in->dbname));
		$tmp_table	 = '__dpro_temp_'.rand(1000, 9999).'_'.date("ymdHis");
		$qry_create	 = @mysqli_query($this->dbh, "CREATE TABLE `".mysqli_real_escape_string($this->dbh, $tmp_table)."` (
						`id` int(11) NOT NULL AUTO_INCREMENT,
						`text` text NOT NULL,
						PRIMARY KEY (`id`))");

		$this->tblPerms['create'] = ($qry_create) ? 1 : 0;

		if ($qry_create) {
			$qry_insert	 = @mysqli_query($this->dbh, "INSERT INTO `".mysqli_real_escape_string($this->dbh, $tmp_table)."` (`text`) VALUES ('Duplicator Test: Please Remove this Table')");
			$qry_insert	 = @mysqli_query($this->dbh, "INSERT INTO `".mysqli_real_escape_string($this->dbh, $tmp_table)."` (`text`) VALUES ('TEXT-1')");
			$qry_select	 = @mysqli_query($this->dbh, "SELECT COUNT(*) FROM `".mysqli_real_escape_string($this->dbh, $tmp_table)."`");
			$qry_update	 = @mysqli_query($this->dbh, "UPDATE `".mysqli_real_escape_string($this->dbh, $tmp_table)."` SET text = 'TEXT-2' WHERE text = 'TEXT-1'");
			$qry_delete	 = @mysqli_query($this->dbh, "DELETE FROM `".mysqli_real_escape_string($this->dbh, $tmp_table)."` WHERE text = 'TEXT-2'");
			$qry_drop	 = @mysqli_query($this->dbh, "DROP TABLE IF EXISTS `".mysqli_real_escape_string($this->dbh, $tmp_table)."`;");

			$this->tblPerms['insert']	 = ($qry_insert) ? 1 : 0;
			$this->tblPerms['select']	 = ($qry_select) ? 1 : 0;
			$this->tblPerms['update']	 = ($qry_update) ? 1 : 0;
			$this->tblPerms['delete']	 = ($qry_delete) ? 1 : 0;
			$this->tblPerms['drop']	 = ($qry_drop) ? 1 : 0;
		}

		$this->tblPerms['all'] = $this->tblPerms['create'] && $this->tblPerms['insert'] && $this->tblPerms['select'] &&
			$this->tblPerms['update'] && $this->tblPerms['delete'] && $this->tblPerms['drop'];

		$this->permsChecked = true;
	}

        /**
	 * Return the sql_mode set for the database
	 *
	 * @return null
	 */
	private function checkSQLMode()
	{
		if ($this->sqlmodeChecked) {
			return;
		}

        $qry_sqlmode	 = @mysqli_query($this->dbh, "SELECT @@GLOBAL.sql_mode as mode");
        if($qry_sqlmode){
            $sql_mode_array = mysqli_fetch_assoc($qry_sqlmode);

            if($sql_mode_array !== false) {
                $this->sql_modes = $sql_mode_array['mode'];
            } else {
                $this->sql_modes ="query failed <br/>".htmlentities(@mysqli_error($this->dbh));
            }

        }else{
           $this->sql_modes ="query failed <br/>".htmlentities(@mysqli_error($this->dbh));
        }

		$this->sqlmodeChecked = true;
        return $this->sql_modes;
	}

    /**
	 * Test if '0000-00-00' date query fails or not
	 *
	 * @return null
	 */
	private function testDateInsert()
	{
		if ($this->dateInsertChecked) {
			return;
		}

		mysqli_select_db($this->dbh, $this->in->dbname);

		$tmp_table	 = '__dpro_temp_'.rand(1000, 9999).'_'.date("ymdHis");
		$tmp_table	 = mysqli_real_escape_string($dbh, $tmp_table);

		$qry_create	 = @mysqli_query($this->dbh, "CREATE TABLE `{$tmp_table}` (
						`datetimefield` datetime NOT NULL,
						`datefield` date NOT NULL)");

		if ($qry_create) {
            $qry_date    = @mysqli_query($this->dbh, "INSERT INTO `".$tmp_table."` (`datetimefield`,`datefield`) VALUES ('0000-00-00 00:00:00','0000-00-00')");

            if($qry_date) {
                 $this->queryDateInserted = true;
            }
		}

		$this->dateInsertChecked = true;

        return $this->queryDateInserted;
	}

	/**
	 * Cleans up basic setup items when test mode is enabled
	 *
	 * @return null
	 */
	private function basicCleanup()
	{
		//TEST MODE ONLY
		if ($this->runMode == 'TEST') {

			//DELETE DB
			if ($this->newDBMade && $this->in->dbaction == 'create') {
				$result	= mysqli_query($this->dbh, "DROP DATABASE IF EXISTS `".mysqli_real_escape_string($this->dbh, $this->in->dbname)."`");
				if (!$result) {
					$this->reqs[30][pass] = 0;
					$this->reqs[30][info] = "The database <b>[".htmlentities($this->in->dbname)."]</b> was successfully created. However removing the database was not successful with the following response.<br/>"
								."Response Message: <i>".htmlentities(mysqli_error($this->dbh))."</i>.  This database may need to be removed manually.";
				}
			}
		}
	}

	/**
	 * Checks if any previous test has failed.  If so then prevent the current test
	 * from running
	 *
	 * @return null
	 */
	private function isFailedState(&$test)
	{
		foreach ($this->reqs as $key => $value) {
			if ($this->reqs[$key]['pass'] == 0) {
				$test['pass']	 = -1;
				$test['info']	 = 'This test has been skipped because a higher-level requirement failed. Please resolve previous failed tests.';
				return true;
			}
		}
		return false;
	}

	/**
	 * Gathers all the test data and builds a summary result
	 *
	 * @return null
	 */
	private function buildStateSummary()
	{
		$req_status		 = 1;
		$notice_status	 = -1;
		$last_error		 = 'Unable to determine error response';
		foreach ($this->reqs as $key => $value) {
			if ($this->reqs[$key]['pass'] == 0) {
				$req_status	 = 0;
				$last_error	 = $this->reqs[$key]['info'];
				break;
			}
		}

		if (1 == $req_status) {
			foreach ($this->reqs as $key => $value) {
				if ($this->reqs[$key]['pass'] == 2) {
					$req_status = 2;
					break;
				}
			}	
		}

		//Only show notice summary if a test was ran
		foreach ($this->notices as $key => $value) {
			if ($this->notices[$key]['pass'] == 0) {
				$notice_status = 0;
				break;
			} elseif ($this->notices[$key]['pass'] == 1) {
				$notice_status = 1;
			}
		}

		$this->lastError	 = $last_error;
		$this->reqsPass		 = $req_status;
		$this->noticesPass	 = $notice_status;
	}

	/**
	 * Converts all test info messages to either TEXT or HTML format
	 *
	 * @return null
	 */
	private function buildDisplaySummary()
	{
		if ($this->displayMode == 'TEXT') {
			//TODO: Format for text
		} else {
			//TODO: Format for html
		}
	}

	private function formatError(Exception $ex)
	{
		return "Message: " . htmlentities($ex->getMessage()) . "<br/>Line: " . htmlentities($ex->getFile()) . ':' . htmlentities($ex->getLine());
	}
}