From e675be4cff4bbc70715d48a04cb3a7de9280b15b Mon Sep 17 00:00:00 2001 From: touffies Date: Tue, 19 Nov 2013 10:34:29 +0100 Subject: [PATCH 1/3] Email template + test email --- .../default/assets/img/email/header.jpg | Bin 0 -> 74372 bytes .../default/assets/img/email/logo.gif | Bin 0 -> 2159 bytes .../frontOffice/default/email/order.html | 123 +++++ .../default/email/password-reset.html | 21 + .../frontOffice/default/email/password.html | 21 + .../frontOffice/default/email/register.html | 42 ++ .../frontOffice/default/email/template.tpl | 485 ++++++++++++++++++ 7 files changed, 692 insertions(+) create mode 100644 templates/frontOffice/default/assets/img/email/header.jpg create mode 100644 templates/frontOffice/default/assets/img/email/logo.gif create mode 100644 templates/frontOffice/default/email/order.html create mode 100644 templates/frontOffice/default/email/password-reset.html create mode 100644 templates/frontOffice/default/email/password.html create mode 100644 templates/frontOffice/default/email/register.html create mode 100644 templates/frontOffice/default/email/template.tpl diff --git a/templates/frontOffice/default/assets/img/email/header.jpg b/templates/frontOffice/default/assets/img/email/header.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c80e165299382568fdd04c22bd649e2923dae227 GIT binary patch literal 74372 zcmb4qbxa)26E76~7I$}-!|kx*?k)!uEpCTP3&q`Cio5#(rO4q2#r1G^FWUC?m%KmT zzi&3#WHZU^%xYa&U17u(hGJ@~2hN zl2>$baCM;N=K^x^@o@2|(en6-0PRFX?078yt|Q1IpdcY5BO{^wn=nvNP|>i^(f$!G zCgyuA1{x+pd>VXwB2pS|A~s4Ae0*|7UP@Xq`VaI(WK7CTbgVQI^mP9df{22Ffrf>K zgN}|vM~qKQ_y0|Q`w{Ta5hIbCkr3$--r*r4;UWHoB2Xb9Afo)U?Vn-)myi+OA)%lm zqM`ryk8OdAfQa;Ojf9H!AI5*^h)5{!5Ri}&@lgoqQSk`*Wat=l(0KW!wXKL4Wpyn* zQ_+b@JVL*wm&^&s$?I9Cq!l-}?2;5-F_je5e6AAI3sYrMT9}w<3N&O=Qv7);!?BYId zR$`Q+?x1LD{6&~H!1MFFYID8{gmRQ7FYzpCh+T;X-Bcsfd6Q*&*$dekR+bc~NIRw!+?{hI?S^geiZvGKC9QTdm#V8d zql#S)Ei`;RQy9z=g?(oWl{DTGVgtP{pY-;cDM{m&4mp@!0a%~-3L|~x1Eac}6OXRZ9 zq6WfVw2i4SnArl_P@#>+QitYyRPCwuyB7)JLgvFQcff zbQ4qY0`y!uyjuSel>}(D%@ctuw%!YGA0>>MMjv3V-N)sFRxSyq3Mg3o=VfH;dpuCa z#CpQp)SU7bqFv^TF}?<*^PTGVC<@02#==Ddbf@qsqO4bQ;a-r8LKH?)j{!e>->;3H zqk*HUr)x3&i4wf1PxV-Si`@FXYAOcQa%z{0l{)oM3-2Rz*r`%8@zfB$&(fPcnI1hA zgN|I6JLQraL^0i<0nyhV+YR?oceRKBZF9|>2A}n7U~osIPD&;y{YlW(@;=s*BFWV6 zR4266K&%qo#;o?VCWp!M@X}e9YtzQbD@n;&EYCly4CnoSgBamRMx``m;8<57FUPIa z8+KYWUnggKc3~Wk(@k?Ge#+v@`>KNCE`KZWiT_I1?zZi=_%e2!>9hP5F|tl8`zcpO zfS=Uo@ z@-S$SU2+)6G{m1VxWIkJXh%=#j!tMA-`yzPeV#>1O7J?1|4C^PYYH*5)8z82i8Gxv?2TKklJxoa3IrwDO9c zzo!Z~;}{;XM+pSM;kn*iJ3qg_(+Kjdng7i`B8L;U<|I;=KboPg)#J~eCb&zJ*K?J%Z{QnN~PthVr~GBpSI zrvDKAP>>{K!@3InX&tmrL}N%3)?1qE4wMN)O6@wf+rPDbt?|4NMi6F(s#a=@3nt>-!$S5 zG?I!Ud=(bn2IttVm-RhS!nqjUJ8IpoHcUrodPN?roI#@N0I=gmBzWaq1i8^pq(<5T zhL%Y~6E@a)%h3_tW^JfTsfS-i^@#UlE{AvWZ7gnS7Y>QH*5pEstyeOYk9bGEgoa(D z$uBm&);*Lvr%9g2>;^%^M_-HF@B9w%jYwjRN|p8CgHhr~B{=L^hjbwcWoDBvzL$gc z%~wSFvqE{rZ9$vV`i*-BfC2Yv^f1Os)iI^xbXM{-|BT22~vL z7h?xX+oinRkE(Ads^p)kzwdA_N;`qodXQ*GhCOtKg!vw)1uTHr1ZSG$8 z5f8R<=0ZQ0=k03RH4TIbYib9=Yq3ndFeue~fhX7>Z!m;5xJ5*BrLAx}*)@sR_wOqe zj>ZQ%O;XvE?H?XJ_TM0^6+*-2ldgx2&rsMHMWSC`_p~k2&rm#(e*KPK(93f?P4Se!~Gs)t8Stm`}~d-=&9M=`o*8j%lmETtmBAl({I+0 z%VvY(bNY3x6K!!ZzOij<3}g`tf2h?cBK68hh_YR3bv1JF$qhzY^I-LEoZDqM$odO z%BknwZAaKzE!xk16Nr9cCv2vVVl)|&sSEk+yw0FU zTG*&E;SC+SpAM|2RXq{h_w39q6H`Ek8CPnvRoBsok%jMcp+|X@k+1o?VIw!fG>N3n z+;IOgwcab>dod>=kNo$tyd_GtVH2+3jBBdz6K#{p6W3i#r>lc!5q8v5XAknfP97+X z;U)gbQjkjCDA?8qNvd9ca+|BWK5kHMpN`PB=n2n&Cf)?*l-CY5W112V<;Jj!Ap5{! zFyfx0|D>52T)O$rNkm<^GOAXybW z3g$!GPOs4VLzeIjY>ugBLnd6Oz(EeI&IW}%mPGr=k@bl-)oP;~JN=#yk<^03LDN{H z*xWGYA2cLG*NTCy#QqsasY?8XBa{x1PgGH4kXO+N{s~Oqrt#s(f;XnkZzJsTH)?)@ zytbdx&IMyCC06gSh0*ENZ66xdZ$G`}eqvqOy{pf0JvxfGpA>?I=Noom%vt{Y4>Q0} zz|N~~YFA~WYV8SY0(xh$l|ocEw+QQlFu88_LT2wGr-C2^h9c<}~m5@%e;Jo3N!ViU5bYJ9W*&!Z{~V zbKJ_SL4fS3BP1`6p#%4By&QV7g2EMQ-f2nqCERaUuI0x%41)dXfdDrE!9?}1Fp}75 z9N^67f_0k@`4DqE_A^JxFT>Lx2Hg%mXo(MEVJKpQ@pI$gX*lv!+#BVykC_UB_0wL| zjtx0a24SDFdF{6(E?NTQ{f(+OJ=)3rF0Ih8R{ea%YMED&DYh&KO?Q%ID%jEWjf@I*3}wey=hpkwaE{{^@6sWKC$Y?tM5l54e~S;b zOGaafV6poiyPK)TXGg%fl}uTDUn|bP-Ol5hU%jiBOSh`xh%MQ0O9|neBQiV z%4@OLyD!+tkV)EDe;-} zqQoVs>_nb`sj4mxfA`IH@Oe62ygQ{sQ-TxxVvHx>tVX&G@!H*$lu{y+Ph5O8#j-88 z)osH=6&?n;+kGqJ$}{{-;GfTVJ&jn}>oV1>@e9dV4`+P zHcIwc17sj#;Lj+)Im)P(7zQ{-yf0#vAr5`z#>?Yoynp80v z5BSLk^4MzT#v|Pb>(M}-z&&a$MH@vS=L?sCGyQJk&$krGzzISK_9s*$$V-i3EnU_2 z##ca8RF2vKg9?v#Yn9)nMwZ$v63(wMt-c&1b5*40UfWEg{@Q_?4sUBwV0NwWvL{zHfb4*+rZk+AYx1-nw)v< zKi^B51}44@d{ounBr-0rE|a=2<2zHEWVXs8k&srw`zAD`kb3Z#CSCboG16>+z_Es+ z%ccSO<;a{qke0`zGX%>>kVasV#lv)=cBRx+seNvCp`JDmi=f`tuH#Eh731~s#jxeJ z=;oEEC4%DO?Qhmhc0h{;aq@}OkKC)`EjMkp?5=*NaFnTC4Fa{uPJvUtU+m|5Ic#^f zH66=RPx4Y%L}Yo5_xaFle#SU1VGm}9WU+*57B{|}ksSh=?OsjDLe~T4YFFgU4YO1& zBK;9sHnyz2N(UmT*o+{k2p{v+CEYJ$n~S=N~y;(Q|q9pu}c(f zEjY>9u7Gyth#d*vq2FDVFHCHRDrhRFmfSDCP^VLNTcLnZI&>K z5;=+Yr{c?m1Agm1x{Wp=+~@T9QP4xM@aC;@WTtODs$72mt17SK0P-gd)hw^}a^)yt zuz||^)!&O>J~((#qlLuIYp-IFv}{&NX2=tZU3Tn^JSYRl$L!^k&s@SKuKq<>0!JfF zU&Y)J3sWUaWfVPDLj1W1+-M?Xq%Iy&uRF{2l`%lJQa|*qIwgmC(Gev@-5=Rz%N7 zdKLs@nhsIho8hL*34>W}P>n?HRFGLqIcMxpu8**nqHar^^FdU)kcV5|E}w$LxXpsyTN4 z?Ll96aWYw=i2>2y6*ipx(SdO*9P+Ksuyu4Ug{&-G>oW=@ZT8hyfq9${G=#&US;iD2 z8-~RlI8@@;rb*z#6QP7p+$~GKA7}>mhYJRKLBJ$7GOr@q=q}rQ;OJ!TmCTQv*f-w9 zUQej2AE)bIgfzkri0RDCpzj>UX8Gs%Y_{Xh6!7DuGS5wKD-UX*sBmEc;tmnWMSP2A z`OY8<$6XWq9o-eOe~g}Hzvu`yj^vbSz;6~`m5OA;5wOLQAunk6+;)`Xl3iSbGLpX+ zgU6qK)o<5Snrif+1vK~_!-+a6Y&!>%o5!^u-_9+9wl1FHe7YVAQ`L;$0ShI{k*s+p z@~7E{+{SSJ-0bmyM2sA$46_u{(N<|drtB+ZK8d%iQ+(snHZZFDjDZ_K@O`#(CVa^L zfHDZpedD%}Xr7tdG$tMHL+2hMbGF6iCez>$;y=k>gR~=03AQ{hA;&plW7x6N!7=}a zUtvuvfmoF^g5O~IxrGgmwG|RZ8cI2a`JJdcGeFg6lPc?hp>%I$!RX@w?@Yq8YISEaahXou&O8e*@m^cb(- z_t0?=+L}q%Xbk4+CmtA_I@NH~4z;MQQkJOX^S;A+8PFTYmW!fxf7W}2qGU%Mb9J>m zFEfebNbVJ}WoAsR5q-z@42lHIXK8`DOeIw;CZc08d+3%uC^kNLD1I+mAny23S3+PV z?cTDn`EsZwbm){|_nreMgSnzw5b%DJRGoLO+lp?AA|T_Jj6 zNwQF6vG>`NFs{KghRh6$SyQCoy#zjgj|aR{zdqezop4? zX!?si`YCJ}owoPE&j2XxT}*ZjN>$&F52iO~`XwLW)%~flkG~4E~_rE+~-9pV_DqzT>L~9a%?cBvH|X#*%r0;ur|d?^~i@k$dIpKLXQ-Qm;tr4{*p!X}RTAZXZ~zu+8t}CLaLg z-xoU!jYvlAlrrKH$cFsQIlfdGmTqVNqQbBOealedU7>eKzTuYa_W2N@x$2uhEw>efiXyyG;lkfqL7+;#WyjSBkC%+GKI$Hr|8IyA+JTe68lZrk>AA{ z=P%kPANgOelb1woP#;YUN_x3ou3OTV_$fnYbF2|-?VnsL9!V0vIqI!@Ha)-FSEWR% zd;*MPE%vmV?+Rnojo|P%{|dgKukWZNONiOy>Y67@5Z>VRtPN%4o=o>Yl#qB=e;h_9 z0L_W8?o};Jv!L%D=*Zg^zd83&9di0ioEg9w1?n}i3t^e4wdT7cc*^1R3vtS6VPYdI z2RmhtHvh+4V5hb#)Nr7=Dv=5G2>N9fq4Z>$Xi<1n_BL$2zl)5ivTWw2$%7MjY@WM; z9d?Sdzs!Dsoj$GKBhmWw`Q3Op?!plef5_j%Q^0Qq95B|_C=K-x>GH$DJ>t9hivZw9 z!XGw9#o@6Q{*`$h{F0`^PXUZ}$G_X$NP zP#~b#KE{%Z!+h#(7P~kiDzdYAlave^`$kNya|U7wHe>L{b)liSHbPfoz7z{=KN7RP zL7l|f>l3_v6fpHI0qIMVf7_2^Sn)FgMGV>Vk{6wlLlK;xhOU^BIde*#%aS*LId~>s*aCn zHhlGb-G^2Os!}u3c$IHFJvU#RYKIysB z&U+$u%S$@aQyI~U$$uVA?8EE%bgW(0{HKG{;o~mOcW_2kehlM>^#|QSyyGp*k6(`0 z7<*e|eV+!t$SHG~!6dns{d8TaZBJLT0-GW4)cD5iT7K_sGZAQZvDCXnr1V((-g9-F zxr(fl85BKQJa?y&2loD`*E1yoc+PDCN~kK#It!#5Qe}Ad8dq~kUi%nN;*};L{iPQ9 zMJXqA8ppotyEj~-e-W@Ph&htUmQ1$zz~M7Jeqv))g?s#z1C2*4M-uo3UZ1M7Sxq!w0(Wm1?(KYo*Fu{+L@3KRn54^Q~_784Fhh>-kcXsU7L1J z^u6I$=7r1@Eqj|00k3b#g(2%ZVq@Do$G5G(a%ED^GYE-92m77}saSST;Xh!Znrdw8 z(-|vD=6vZ1>MY3KbmE|XV)*gBoV%l;B0cs{7vKGRPz#0YfhH{+$+c8RQ1L8xLs>unI6r0%fJD4cV@r^}uWFi=7W-j^do-gHV5;`(iaFxrvDLF$}jaL>FOU>^EXQdiam_wz^k zAqekfa)TIVfKWPK+w$4qz>KJJYSPqA=~P=ziS*fu)RI~$1B&C9o_6yw zXQ-3=KewnvU()8X1YU?ZUXVq>mg*OF%19??g0EETqp%tvcD^!Au+rYVuTpisy~3== z8MHgyS-=u(9MGK+?kwrb1WvKmKW}i-Z_0oP`;hWuZKEF@%jOK}PqjVg*mh3BqAlTB zbwam4YcA94e)=l3Q6hG^!Fo32M4-#gnR_-aX08s^*>QlXM6oi2`xP@45?h!{n@CwrBRO!-yuPC>%hDDKkf(3h+rqqUHxXjR$e)CrP7*>qH3UCESX+ zLC6&|%2L_4jZ6Xqz^Wlp#uaL0S>-DKMnr%=IElYkJ?tHdziheA4_q<}F1AjS=%hsOoc!5ype2>Ykl+pP{_c}Lm)Ng9J#pDEH(s@`b;8~+ z8bdNw-y--nzRP10{SMUsTr=Pll%Iv6`e~EoyzBvMgzwI&n4)!-?ng}92<@e*uUCas zj(3vry9F>Tapjo)Q2#;w-Svz8q2J*)z(a!DHfRs_||Hqt0sixkT)>h zY_6_Dn34}Wh4l>2C4HTR1ah_-j)}8>UtVM3TMZOZYT)Zw?E2^9Fv944$)DO;pSiCA z8mDDC&afPWQ8c(s?A#59voOhsjHJb28OiPGz5PX*6G~nTEP!H3_@&JJv<8}8ID{7g zqlvIlIeUpaV>VP>8i1Bfrtfr|jDf4tjr=ima5R1dmg5s8DN@-Nw1EygRo=-3?;m0K zL{u0I9*+#KdTAu~Oa*t#8y!tTJxJg^0vCsR?qy1q!&rIU8T&lUR!2UcyjjgCxN+~O zls6mSHzk1j_x0-qvnru=J2S_d^{f^GH|rDalM6-(H2hq*9a$>*O6VA8EE844>9Fx{ z{*{g{s$TZ$JVyc4bmr@kbAog&9wwzOq;R3w+n|cA%OvG`4TARBkCye&EXq4_?8Nq; z#2P7b<~qd+LoK|K$nwin?K{tlN1jg3Q3X!kg+xW`px|>alWu@j%eb$vcU>#}S(dQp zf@`-rd$Vh~C|mF4F7v1gUJ>lwRo&Zuv7UU3!x6`Gjqvlt<~i}|t*_{S$ghphed;P` zD(Vtq-p;>w&mLjArMZ>Z6Pk0Bs95DBQb4!S1N3%a>K9I-{C<>24~Jq2|seIB*4smG(v4|r>pro)(Y?={KER^h5#Nlv-j!wV=n=}6+bVo$-W;U^y?y&An z6K4fvwmS0mGJDNCZHsp@1_(>FbHaz(f318x77d)tvIiI3D@OF&B*eJ=xG|u_{OKP^ zJm>t{H7>iefw~*T>;1>^wsm+4#=pI5Pi-HNOKl71ci>&lPl$Zu+GnlsSzCGGG0I); zh3kUV+e>lY4ef7h*$|H72aXGql%ilH_OzHH*``y<640pRwFENGznak-P1T(X3H#~b z9H@WlE!nfc*qgo{)*uzDa4}#rv8BnKh!ngOFm_qcZFv&r_Vuy!Dp?!2(an6NDi{OZ zSd4u|Tw>h&JsPj5bG`?&a}Max!2XBcDTu%7(6x-o3YUvm)FiALgb~9cuBF7)BVzz3 z-(7r6?U2yk<*|V0jj%N`ChVr>oBzoI#fC)#76l4q}>p26>gXxS@Ap}r3nolPB@L!*o=R?LAIm#H08MTucA$Rf-`)3 zA!tlasIZ;?7a=^n0Bq#<10S+&rxHrKZuJV0>P}rGer1bQ;uCT`ph8v|YX%91I>n8E zLDW9tay9Nx@-$sS4XNTww-wDS?*{B3@S|Og`}HysZgSDDYj6vyIDux?skQYlRqwM1 zMnU4<`RYFs64PBbJAToOsCx`f6_lB{L-fs226tdLo+Ax?o0;S^&sl2O-{mhfC;)XT z3=ueCvA>FF{5|3;JTOnN4770X@0p;G7>zUr!qkuRqU6+>8IzipLn!Bx6zTk8feX2p zWdD)#imf}&{yCjHSI@R%=HEnQ-kh!0(QspzkH?}^%=1g{-2Oo5*VP=SHAGSOGBI_* zdDyz%s~MI?Ybts@BGj~4(})$tHs+y8e|&ixSaU>ed9H~Ui#_DdGxE@VpVG?ueNms< z#&S9#A4E#yvt9k#tk9ZUxrVMy8~KF@szf)prD|dPi3g-%fR`W`CqR~&*(}*?GU9&D zK@fEoPs4sfUc5$X`O}dWP zZxWT5WdBtm0YPu5bb1V)|8410fL`-@FF*1rD&;;0R%u)Rxl)6$voq^|rK*@;FC-ZA zw-XeF4^Z@s`8k4wj3?WdUgp1D^#dq+733manQ2{+^JCX4Jrg71MOYD1SN}T!$P`a? zg*#Ui+PcLpR$d5|?4z;QjT5g4=LdwnebXUP_6-b_n0eAm0H&Y0nkoh_NJLa_$tfoC z(GbhJ6Ll}jB}ftpd+F@`*83Nh&yZ+k@ey@omkNLS<5Huf@D6zu%+8#wt|KkFqF)i9 zn|Rt@ZelqlZ)I=ym@69Up6e`_{19ADWH5;%oV@*__@AlxKn&H7!XmUW#!n|bWkiX< z=>UJ_jb}Th5mYRJJ^2PhQLWgji9bZlgg!f!>jFVj2KJ9AMwSHTgPSbIAC-R| zDD0bxJSYzwwc+Sw@A55S>iqXYkmO)n^cNxL9{{E1wxjG5M{nRD)3o%Oj+cxj-|)>J z9NcK<^+2zomECD?mQn6e0(+^76yJ3H=RmA>TqiRDz>SRFvF5~8VXOU+4A-xh1FH2I z;=G-JC4TPCY8CBxwB7@Gk(K3SfWO2GzrFuer`c&q`zfzl%LV>*IakB@Rdm$Q$NOr^ zV*MV^c`CQ=IaZ`r|1(BaLeH!i9MP!YsO)l=JqFmRo+K8hud%+$Nz{>7gXl%EKXqS< z_9$8b#~mxm_6@CdZc3K`9aMb>R?0{nAEe|Uv+X#c;hb;#9mVzIeH9f`e&y@kqgNT1 zfTqbOZFOhYXhZ(o?LRe%PB!b?XFYXXDYCrMnP)}oQJ-QDcn=pm>D@g4*bs2@1#LNy zkxe6q=jJ$wWTNiyFtNe{a}j+_`bZw9zrt`50;M zkDkMmDA?#bN4cPZ??Xhx4}rD(X*Zb!mI+HJz}lkE;X^Ck3C5l_p0WCh8RrGw{z=>@cy@d44h?UkcnbEA z{aT`7X2Xs8;R#^MKy&zN?C~Wd{7^;L+ODu?Tuy(>f%uUTJH_*YK4FM-I@&|&PIM`a z$GueKir1^`lH8j5@S)LwZb;Ok{!nO2)ec5`dx7Z|&#dNMBT?x%by$Aw#E~s z8-pq>#>uu`)uh=c%6${YyHa5NNeZ$5TJ{BP-&=DDryeq%9ZGKs$WBymqz>CeOu-E| zJn3B+QsN^YJAFf?hK4pdsEEC`J~jyE;f zx!Ta2|4>3JDLn`2v3nqT@xIg7d%X`1kI5@u`IXf6k8Mbkj(&Yyft52M(Ust}p%gO0 z$DVpD>?oclcm4yKC7L3|nK-Aa)u1pV=psIht%Ej%K5O5pKh=f9-Oo9cuAb z<;(A5pSaZy#z9wHo3mXSt`ji#LhvXNoxXoaH{o5{UwF zyP+q@BL?;KH9Su_jVsLJKO7u+(QH*P#?SJwwT%7M-mKOEOl2+hyd$YDfTi^XDqD(cxF9k zT#5-BaIpVldQ8XGp3BJPGQ3M0KVHI<+#&q7sE2lJxi|RauR=aW47J&J@!f zkWiLj{A3B+vOM5eURf;LVQ)V}I?%o+w0$abee+H2Bv)=L$_tB2Y%GLzeWgqw;~fY zV<6<=S+hMHu_J3#nGuOYqQ3@a#0lZ!%}E?lqX#wdXlrfzjJa`vo>@* zm{)xRFEt!rs5{vLZ0s&gwdFhq`)=4|z7b0vdv=FEr_b^PDR}paTk+lyrx>a^dsU8U z{3~rdSbZn{*4D!!E3v^<$gx9Gm~nc`bKLgSY55lcYKrYaIbs^Wm;#lZBfX;&N<#Ia zrsIUae^G@j^7Xkm>~Y|0(Q5Q@l=o81Huy)AQRkNzn>hx1GRMCG(#jea|uJyfVI zFF&N)AB5M&uk~&DRvQo63A&IiqyI%<=9o7LBP(w2K>i@8Jk+k4TDfZ8N%E40@_D53 z=|_i|j|HXK2LqzmHn2-rsisMr$Ef2dPL74|hDlK58=?A6?sIo=M)Y3<9eKCfKOZj4 zvYuZ)*KiVdbnS!*1gLlLy$@2N8oU-R{*G*#MK?KRf@}~9Us^9BeR%J+4Xih2nt(Xo zxqqo@|A+Rz9D69HL;rYLd4s$&6hG;F^$N7O(#X|+UHO>BkwKv~ zcijRu%%zErmKx zm`nhw?j==erLUIg+GqiB!0v7tLYs@u9nLy zJR=g8a<#{J)%Q(z=^iTH#j!HF|Ct~$PAUj|itzW^;=E0{X?#aEAq}jfd}@(W)Ph3Ew=A! z!cSX1s^b!O58Si#Y}%QPsED_WSmM!el6l`r8dmNxK8p>AvxKE_|NO$1=hED6ER4VB zuDCwLZ6yL0|BGNT6FoYJgqfc25V}K7ahrE4CB|D{GjPDChG~R}o{R{byl?2kA7xgD zsRWtx{|99vfYfge_eTFtcOo8kcW_6RGI4fwSpINeJVg5~p>MnA#>We7(V(krndYk& z?dVQ1QV4MrFW2%0wx#=15l=!Vjy8>^4mY8&DmH10)ohsCLq`5*G@Kx4(Ko`GTjO%+ z1o4H@Y3@)UL|IBY6ub zziW-OuGtJeh;nO08vR*J&R@5V>6^z~%mca}68R3ZTCniGX_Duqlg7VvQ6noLM(*-i zi)H$>`?4`bDDK(-^ROF5DEm$~qz6Yh&^+w97maf!h+hwM$&qeaD8^1;bjNzB-@v$; z>+_KzGiDCaxAmWeg=hyo2@+>J$AC-xWWrdHq(FL~#8ARSn^`V%s=GyHJ=3=umGVLW zwrQP%(6I|i4E{jJbP5U!4q;Avr1H_v41Q&z3W+@@0K*P4WU>e3S~A()Gi%^c+`|KK zQ$b*JT9cQj`aqmPPYT5=wZ1HpZLL<>F7WmNvmgOAO-vSB%m#Rx?m#oO`)LO7b>uG- zxqx49L6Z?Y3B7%=iid-zWF-8~LhD2$`Z{vTRE*B{Z?Mm&xIbgFpy2_+zEZcbf|(ZH z`JvLsoJ!>`i0+@qf7t5xTr>>Q#crxu}zDuFJ^@1C#quKOD_S1=^6##QGwa4zV>$^zfJS=?c&bjj+Nu^T^ibpdVaNFSS&|%=x#O}m|L$S zvPl{svA+l*i zT;y5)0iG%Tjz8BA%R()`3k~Lo$$_7X+HG4HVBRfQ?Kj5oZl2Pqc2%js_oBo7O_F$8wXK`08oR1e{%$3|hCLr)!BP|e{!dFWf;jZD} z_Af#V^0bC`6-d&IZ|w3%wJh$yky3$H$RX)FrfZL$l`gM`cVFGl?HiQ8ZeA>}1^*|< z`i53lX6JCdRsv(;b{B}4h~Xu%m2kB?p#C+){k%p3|C@c3M7d_y>{)o+FlDjx3mJ8}fJn$5_Lz^Bpxby6 zX;17_r(p9bp01piA8dIdlZ2Ba*R~>0wgjDNW*o^I zj;ZVZhpkbElNknzU%+zf(pBAAX2IJXhmJn4H6<6Vn_R11Zd`h%%m6>py-Z!=$z8=g~yZBF80;seGXaOzYfk`vfu{D1bGUU==I<@ zIQa38qc*W8sl%3HQGi~TteZkE_Affd8Pc8nA3V|iqS|=slZ*1bF{Yao?`s_5oB0rE ztZi7OD_&g}Dmr;voyv(+?%d=u<))A7PYrsA$2HirO>CwrhXChoNVET1!2aAW_;dJ% zL78{@4f&1&n6B93F6-P-+5(x445rf~e=}_+ST&<3VbI>C+{y=|`rw)zv0v9|AJ#J4 zDEMB(rENLoCUx!(r8;bXCbkaK}!k9%z6a@|b zDn!+lccSkmPnQ-L@OvR}$~IxD$H6a11s$(aVhhQ8=dyh`!?1hPa(#7beu3Q?P<3Sm z6M)x1IofjW>1`G4V~*;_oxOyXbsBhu_HRMkPe6klF~X#*XwfYq=-I+W@A$bm)`u;H zUD8)}5*ww|?X(_Pw^wz399f4o=~Qh}j+0aWS7Q%`XlzjYDCJ3K22Cna?7M@hr{vGR zuSHit{ge-6*;Ehk0FtQ{I(MKGuvyN#OT}5cmtI`qGp1jDGL5YP-$eu5(e6OZP$`~U z1=P;k!YKr9p73{wr>ps6rQL}-izdB!A+V7Zql70M;DVrWZWGN?DF~jAvcO|sxAEcg-TN)WizqL?dhYkCS?HyHDE+SCc0;6 zXA+9Tj=dxHS?fZE09)}=DPr$BhE@5-JIjQ)c2~c-hKqkO8x#vRR~0UGFPois?-$c7 znc;INOsshcLRPw%5A2q=p%M=3{*fYat~4e;E!(ldFx@&;3*ZHLG82Vc`E}5-S_zXg zqyn6|dQT?h@3hYo>EbO#BIkAqI7YizSl2r5vLMegDWSV!WK3P|RF+eeO5Fh%o#k5R zwSXU?>iB0!IHwlEjZP+Jn3f5YPioJG;I-2iPSRZuYd>b#`CayzNKE?_SG4_y(BMcQFaX_l%`ve~%%P~5fk^0i`zTwt!d7#g*q}f~Uy@9sr0tei|tMI3E zlB&w1)eps(D4amTk2k^mXsBNZt)`Jldmcy6>xHmdMOn}9{+aD^!2u})9>?$v+3&xauL?65-D9g5pGb7Z{ub!s|HU~6I`mKeWe7dq!-P7KKbDxQ91)sS_BA98HqkPK(^j()^ zY`ZSI_o52d4Lg+oDGVZCcEL@T^-L#986plcleew^^d!nTEF?(b7cE zoahA>8wZDfhh@(BkiFpXF2lq^MtfNT%Rg0Tnya=?5y;1mK!shjb+1jtaam77vkM(g zhdA`CW(N-3Lp`_|QAj!bYeR<13_m!d4P0^K^j|g$l+W6$tZt(lw^@OR#Axmp#lH73 zGiDyb!b{HLaQKk3xhr(sulDW%;&`k_NGR50edex}7B&zch}IW}#iVG_OYN?k;vtOY zS$3@ATsDG&CbnAz!{Kh5Qro6fwUzX5*voXY#C)Qx;}#cfhUHH&&g?Da1uR{i#+h;t!Vl&PfqPeKu^B!%&&EnlD#0;@M`yZ{{)aC1 zDp>nRXtk)x#vJ&)%HEMe)w=3qb1>-goM^I6?6&Rd`l_NkS4}pi4boiXN8-4f7`%44 z$rXU}2hcp*>4G%dm-uXTpeI0A%-(5NW9}e7j3RWUQ>u-B>pJn(dgL$ zTXOWQZRuFPAnOn@W}(C$a6Wfdb@=h|5thsdRCgoA&P%j&a-K}SW8MUnhroZxpV~=u zyPaNE1QFSFfp0O+gS(Lqz=%dYJ?-4;#oF;$ldnf=fIR`>6gFRX$<5Tcx*~0(5X`?o z>P>gNxVszi5+#u#?g%bUZZ2zvIhxT`Sxx2XElO;$%x_h`C1Z%ig-8wM55{`!Py-FP zH{WWYM?}QTy(@p-Q8$OU=n*%%!PG_JRuUTqT(_7I(ac8s_vPKlC?N+MuXf>D*SaZ5 z7~&vt+&*rkvhH@_Q9oxHFvusAn8)O4|8lkZdC4z0>Xt!KQR|9m5dPNlBajG)wMAv!J z<=m;{VOEoA0Jo_Wfk(4CLAwl>F62h`SxeEO)yx4Hk7F*skFbFS4eJ*hnE3 z&fgWv!Kkq7hvp8a@8{}4QvPF(SUqUGHK#l1_URNs2r<*Ir5S;}5r^!Y!5dufW%C-G z&PW&{Ztmiaw`HoL;wjlgS$FekS2G=Z6vf_sn0z}O0pJx&BpeBaXWC4IjjkBGxn0_^ z!{YoPBru`+0q$&C7HRjCP6fh5 zq6ot$Snyufp;lOd9&pDFbJRqtVK5Z6$DO8?*PnEqBDn!jjD+m%cFt5wH78#j(&bg~ z-E>~=TfJB}D#n56{*eZ&;Vk$B%UZ6|p=FnW-7aKl`%0~e&l93R)dXBe1eXAFGV?`6 zazlJK%H~|8aAcHR-W!*wmkjd-qq2i)DnyBHK_>I4DRi>2!EvWEGbkP#Ro)uymvz_lCKfgw2MM@vv|ACR77sx@bs!skW~h9_g&TEMe%*!TByIy5amR* zBcI+>?YnegyYp1-xw_q2yea~mcX3=KiNj{Q9#0pC?ia_HNmdiB7Jv$pF{v=&$h5hw z>Qj>6c>G6dap~U|Wx$8yv{oK>aL0Y_?8fVSDBOmEI7Tk$eyVmI2&!44bsmMu%{|QK z^0ibtJy~tMyR~?&L^&CV&>fJ^dSlOWuW|PDlWkNwRkrqxr?Ur?6k7#~^FaunDAdmB zHC7ZNf4t}LqTh3SdP3CQ^KJ5!wOF z=IKODt`yrLkWM<~yvf*;QOL63Uf9{L{{Rwa3gvLVBzefP$W~fL7CkQ3+ToeEQVvsK zBXf^iZ-rVzodU6&yACUWNut)O$TMbJb)x5qRQZH_2CiBoc$ZQ{PBsk=bqh0%Atu;Y_eaAO+P7Wih-sZIXsuS;3Uk_YEEz-SvT`&c}_UwomxHNP2NM_ zcu-7lH0!6{5$5_!)Y2!&b%tS^nV`p`9}25*+o|T;trdG><2hqP9%4>wn0MXEcJ^Da zhnrF&E6zP|TrIcMO6FcAh1K@ud>Gh(b6AAgnC!`&HRoNUEdzO?Jl8COUT25+v^o4q z5bH11jGQ9>&n4+wH9SEb>x<4B0}G@Ryb&C72}oQ_}y zOT<^V=|xq~#NR8Mam$hCh%*lIVhs-dLU6fNE-{ZgI5K6%ZsGY>M%9b7tjDoj+&JNn zTZ3{lVqCR{8u2WyJBbXuKr*6IFnD}RN3mtCd{=1in)pNLbziyjV?O8UTo067Ogv0F zKh~haowLfcXNUOk{{U*H*hyRulv#!EJU`Zp!ydbDBfb9sn{WG9(rK@$;*S{r0LQP< z{@Og>a^V%a13y(7tMD)TwU4N*7v>yaeqTd7-AN>uHc2FsK$1x$33GDlND|`e;tnL7 zx#vN}8PQ0XN~mY3yvxgT8QT+zH*Yj&Ke2jq)Lwn%crMv2L;XoFb*fD@y&Ut8&C)ka zJ|n?(@%M2(J{9LhDOq?}x6$o8ACA7x49q!g z+1v>*ek9y-HYZjl;#1kH&1CvK#7tZ?BVaguS-tg^=D622$h<~Wmtak0@D|$P?)QLt zS3EPhsd&^nyksm#-s|paZM#+O*5VD%hYk}EMj1yPLGL2APD^+!SLL?QNuKFi21DrE zK}~JC8N2fG4)x^z^vi}+gm_#-mRi0@ZY8+IF(btGS*IHlBV$vh*HBSn@ch{gxrK4r zQl)7IN2~LenjRChF!o@u@xyXu2P5SmYz3QEC1SLeV*Mj zu*-JqjRlQQfro@PAzJL_e|0+7qq#$dPQ+%(ICyk>^L|VID$RGv%7W)Rh({~Hsw@VD zd9tI5VlsHSM@|v0WJU?HIWY3^XR1SW_TIF-1<~ThY;v`0%G0HBnTk45Q^4W)i@}>B zgjVUhO~Q$L2#zfn7w-a)!;X}g-#CM_%Aj2DKJHt7#)yuL^hD_TPN zu{&`afMuAm8q?IPa13V_!(zXO#XAMvUr}Gqa}R+BiDwWjRoOhRJMwC~XkrX2aRad1 zKSE9QF8M?_&1+?5BJL}SI43@3T~k8BWd;{1=HDB@d+~R}?xHhuV>Zhy*z}(lN`5ly z@d21TFo@ma=U2iHHMR`q86yf3)5JK}S`zmge=VWr^r|NE<;;s6n86rxJtEXiz~M%i z-xlRdz#-N2tX3k+%*--D#=^@zn!Ii65k^A9F??Ptl3j)nU|HUuStuTLsIiUdrC#rq zRbcx`FBHVUXFtQl0@5vqD$Z4Fl(Tq?(POxEy_)&W&5&1aTOX5mAVD!Wa zziDK}nY2yEkGx{AMfu9Y`H#hq5u(Y9VOk;7y5Dz;7OO>e#DC&iq`c>Zk>R3CuXmbR zjj}^$@ph_zRYPQwy3Il#s)}-Br`MO_A?r-;>Ovy8qd|UKt2{2d;&7M&mm69jb?nZfZ6+Sh)`mpo zcYS3Yns0FFadfUa=WxrN3Nfp0k#zV~GE0}ajKX(S-i<_A)F%W7oixiYy1L?0+3|65 z>e`@)86$j7`|askIgld;ADxKp5SbpKj=-$&g@!LOT&s<^(Gi=QhVoN25fV#G-NW7P zlCy;-E5G-HMV8pZO1eF}UxVr03L70)i7l*V{seB0(5P)yds;Z?^Zd$SGKcm+)5ZXx=*fRQshc@So{)qc7v$Gsc6 zZBVx?+>Fx(cQoHhA~6X&n%6=Cm;$JYcn}jS7~F84D?BzL3G3T24FW~VpnL+F#k;OV zXXVwV%eorifdG{!Xg!<9TDJWUGZ6`)p1xy?)&4=9VjR*fjP-?CPR%-3&cGr zf!-67==3J=?l#xO-S4~|NQO(1=UO50T0JVlX)?>f@NaQ&b#tt$lG$wBHW2CRQHxK# z6#ANLpWRkcs~mu=eBF_EcwH-|)Ok$|XppMIpgrZM=@msoO<3T%>oskk6{_Ydp)kq! z%p+VH1+dVhe-Xu>jqrPiN7!o8Aj{@LZ{nsnW7Sef+0AO^gHMG(D~z)$U;rHe55>}ldWD^k-+DJ%Do|jxrcDMG_#{h4fk;94G{2T`5!5!6s_)eF{(OxQ5S7EY{#)m zGH=(&s~vhM*_XYiE!3ukCMo<}TA?3_Ras}Y1#=ty)nl{rnHlf9D{(ku%u7GQNeJ%9 z%kIPFFXmin&HDR&FC4{nTUQ8rk*L!H>Je5ESMl&}#EJ4e8Zd5|#Y=>@ebla&jFlovZ zE4h8uJkWW&Gu*ib*=1&X+^C6Jp*0!#E`6=|~NBni+>pGnrPvCM2| zVO$Rr4(ZB9JLRLO)_b*<1)YVMv2dj9;TWtOK7@|(2Pzd zL1i`ae(@;tw}|+VlcpQu7w8exAf$-qA4UpP;&7hn%Ow>(*~iUwsvJe9nU8x;cUN47 z;~~+(akhw>9$+qHQxn2aTW+5UAwz?R%+?`60}H^&loL3>45yr+HeMAgB0NV8$MB6? zcpp#VRT-J3X}hFLQkjl8#gAEkcIPT{k!|at0VRpixTY=U=0`3^6j8AghuygxULSc> z8=m1cm&IB^rz}-l@ScY#UY)#{GS*p|(UXan@a*ove0sbhs%DgGIN!!|M%#|mYsnF` z+0J_)>%(23id1(%t|y&$75F@xrkO|TyYyD+a@{EO405Z=FKHh3b9(uYZ8x8H?;-50-YKwvt{Tk ztg+^{)YD=1-OaN@Wz@5iS(%JrQQvWsiHKPYw2RLQq1w%p94z!=8O+&sYT3wjmchGs zIsvZI`9hwO!NZ@+dB3ZT!;yUGMEi;ZFYm`kj|Q^9}z1YOHdbw(@WOrQhvD#kg^A_QCzD z=yBgwrzm(BKWp=S^MKd>&13yqu~nD_cj1x$0M&}KUzjoe(qBb8-AN>uCP^fcMI@44 z>`-wel2r*Ll0cG4BplqDN$Iwp*)Z}GVwW$xKv@mjcB`0&EJ)L=di$U?R(DC&dh)9Uqty4WCC6y za(P@4X5T*b7-te#1PijE8 z{UZ?$V_Gh$?y!BE)ppgmEn=k(>l%5nBBPqOsfPBHoz*gQ+&){;WJiUQS4!RV>>tKT zEPiGV0AmS}c5sI0By|2_mkoCP#Zerp9ij!<0$#H%ng#BT!#J+wj;bVZFfAJ zsgW6N=9{&=mfIa)$_nJ_r;|5m%N5`-rUXULNbR>+t2V8s+jbmGNJ@LJU6}ZC3TD@1 zlJMz21mT2HwOsLaAn|NjnENu@AlV%A>N5Vd+VzfZcBLhijaTId!EEn+uy}=m9%ZD& zqTx`m1~7L3FGe=qh7^7s3TG7zrvd$qH*;6vKmF^dfZ$Bn1GY!KY#CwwN z84hDrSb$#Uz3yAqeM<57rUqLliL~MK2nSH0u@+vijzbx24_App$z^~=XMy5wr#6+N z#!Ad69|NOL+oXw8Y;lGqg*hCX7V^tNzLM-%aM%~fP206xx#sDUC6D6;@MpmB{xs{l zq&l-L1k2lEGi7_aZC6-`2)%w*Te-aG>^0dKc|9{HINZ|NmqO{4A=F$j!MbvL6m)=mk>_aCUCUYejccdlEiG>iPVPe*0pYp3}r;?Z9M}LV?C1>zU zU+HiDG?!lVcn>DZWK6rP)hjf)qX!+Jf6SQ~!FKmu3z5u=PT}rkM5bNZ%!^XyxduAn z)r{F{DPJk!P&p#l?rFG>ttsv0=rW)mO{y!c46@Qn2#QF&<%T`b@}`ev-UZoIag(=C zFG`9TF;-vA-<$GCriDP9w2s8=LFtaPAZjCYoHMW}HmKh1_K~QLjeyUks+?=Mi(a0U z14eF*wrK@nxu9^!H{WN4Rj?o^^!4}^iQW%@L;%Sqsmhz^XhV;zL$}+44o*pxDZ1kLm)S#<& zmfQuUaky_d-i_9)S#X;e0Wjo_Ve}zlM9p-XGq6il*C>Hm2CC8OsTlIwh>uPD$4*|P z?1tZax+*py`pCF)qeX7eg+~wGMRp!BFW~M2hNHpKk>ePc$rf%MBWI&hOm;i1i;f?8 z)nKZJXytD1^dM=v-CaA0N30tegw;v3!=>LOnpAqMSVdcU1yoB7;&smKf5NPIc}@m@ ziBU$Q%$ZtxmV*zKbSDhYlaUt4;tRniE<}-UPLzBi-LInMQtbxNKEimBWkWW^k5VU+ z;{{+bC*+fw1Eoia#3=s&7Un+^b{0=YYT;{1bt0sRy?d^nwJ%jszQHmgZUrpxp|Ziv zMIwz_uH~@JTIH?Esi>rPs(~TNkqT>>N0?sls2+94WL#XzV`$itMRMy=A0G9_>t~5M ziv}Oz@aF?3y?3v|pbX9)*Eco^#N(Egp>Xt}e3*f}R_Y z+eX~3Y{TVLY!S|W(i(R|(z*kd=Y6TA3yESoj=mw8K)b|>GbqEDz}o%Zm=Ntc&0n$R ztCWl1@qxT85BX3uW6X7@W`mzyLQRuoBiV8`MI5V{aQfF8X{H<&-}H*0XJfp6%Y{dK zbZ=AjX~NTQN}myo_&g%}bpkFy@d_6#3hTOhR8TTSk#uroUP7Wd0D78k!ud^^DRHF?MscdmKR&44-MR|ak(A4ICb|e^q}i5HWCD!Z%Sm0n#ysX zlP;yldGsCPp5IoRl}|9SDh$7Qo~1LHB6kM+l%pJr~yIck;A!txq`EirSQ$_-*U8Sa6I3vFKI|0Jzp!>G3Fj3vs3iwj7|}%3!DpQ<5P~2-3F$ zoXEKIfy~p*0UknCQevHD4g1UaLQ-GDJ7WV&{79Bw;q#hnEtw2v2>j!kRPpN#;q;X* zyIWQ8-+Atx{{Ti-il=5w zW95!SS!%-!u1kk6F2MO9y+vC#&Pip4>%3}t1mix!C109vkh}r)m6PzyL8%rHip{HY zB50f(%*U-Sn@(zm?n$}gTo(#Skr`WH>NHLm7sV3kE>ux1k9C=MQUXO=IUbUz`-ZU` zW2lg=NM^5#4o2^MM1X5ffo<0!?=U7zdF@iLB`lpRy*#%gP8;z-w@t25R6&V5yaU}* zMh419i%rV25PZrx9#z*8n-7<~b9)C$xiidTjx{3d&y{DLEVo=}g&FXWN6onV&Xf)y z_kJ!Orxt|K9C5JFtRh!@vT@exT}q}ahgUSKXrSq{dz=v9i82Rtr@XvA1@>G$!UztI?8pd(d9%&Vrz`?A{7ATL&hU{-$GdfslyJ1 z$kSv{+y>q!8oNckY2>2`_cNPlnyKH;7Ow8fdeUP;v4+HH(cEy{DDH^#mr{Zwkl%xl z>m|hxGnZ*40kQF?#2dN`QX6D)?I7t?JVEE3;jf_=5VG@Q5n5eBpp?^{Jj2c?RXkR^ zgK@^Gcp+V9iXh32MQIXCqY2O!=vNO=poP{#KTt>_&}%nn4k-}XkYN0BZ%;@hEH&M- z4A#)pjdngGCN^W3i4qz+VV#r3)U@j)5zS@5k8s1S?)%*-*#zy33m_VLjW;tm-8S1I z3#}3&^C<4@I^cdr<-t(Dx?$VPkVP%nVv@aF8i+|-pY-myA;kaBEqKS8=7%IPdnR;(g95{{Xme`&Yf+t6}no zg&(z_Ieq1_$9@eEzmgSlvzrd)X3xX_08}ePzcJ}znruuoU^Tzl{{Y?V=uabZxKS;pG1S31c5olRGSvRVd zV;soY(U0RDU_7FuaxA#+3CLRJ=Vd#9hyZ@{eXSFpmB7(mA1aEnu_gAl|xDep^g%$sk}vu=x!7<}#?OLHC2 z(e$f%a+}0pHs}s$ftO0=qp#U?P}xw-tlP#%=XO=d?X*&cD{L-BHHJK|?! zgP^_TIl}p^ws>Yhj^mb9uA>wiv&HG0TdwK3I%z!>s~sXCFGyY@K}N!##%F{muL*UR zxC=I<)qIY{u?HsNEyxaDkw>|yka^;+lU2Bs9K2tFfphIf{qfRdjf`#ZPd#S80j*}p zPs16KuPfM`3b~og}#`j7H1>=IL|7tI9!3do($E z#Cj3gk(yzvJJRaCKpQ~Ct~&emyQkhmi=j*N0`Cf%*B+CS$`s=ld){&&h};@6XsM&S z9Ge!T_haL24<(GY`RVzpNZ=1;v<0mMEmw8dX}FW65!aPkMTrivq+hwmhme;t+h@EX zyTU2~FxH)JUk_(WIz7!8_jGl!=1#(#2BeP=-Fx0+4+@tUlkk=*1BXDYc#RE>hx}8K z%}Fi8r2ha@cO?9N9PeUUSd&f!y*i0;ry-aSz7=*y*3zwkcym7p9}5Z=Y>!AzqQWl; z6v|7&Wa6l3?LO_yyR_KaxWln1@nK{+hK#p5Tyvp0s8>P9iqhR{eic3|1mT2Mq!lxZ zQ8(Zf6sDi2eJQH3ovEQ*3UavawF510G_v^;i(SS+_EfT7WS(&C=jHcTS^;|0L^&?e z%`M)#F(o|1&jXr6nONkN*LLVbymCynjjg%OYL{ConyF=7mZP+fnOImXo{mrMsN^)z zv!i*rcRC;o83*-mv{dexlVZ~$P!zIl8;twU0xi~@Z@j*iTlQ5Iyr{_XxMOHsdouo? z0vJP1Wy%*?Dk_V(?>RzqzO)S)5!=9TdgVuk5x(`L&TYRZ;#LA$HJzT~9M*1U4?CUO zOu{!>&jQkhjQ;>mVmNas8Z_LZs@;vgN!X%tuGdd%irLuT7;ML=P}xJMOY=}x<+#~% zYDvZqFvHTj?x`JUn?HGS$13ig@7_TWi-J~Lm8Bbk#FXRY(@l$x7tV5~<=%bisam{7 z!QZU`7_1YH;FO7No4yv)h2Uy8i6IfNM=GD3oI)k31UhMH=2S@hDC{Z}H)LjF51TFY z+C1t!i-aYCQ0(YN8}goTGfTVX(maUB98JP*UvdYKI&O5ek{Fq4tY@w}O@~Vg53HP09G4uGt-5OGT!DzWOit){WgfUW1x|7bOt%9oB>I6xCYcF6 z*$qCjj%FUv8+UIa_fc2y?{K!-9wjWk>>JB2_oP)t2u3#~-X1Lg&pG{ko_CG zl{u=fbZ>(Ar=@&rmA1tN9p3PMvarUm`1oLsQDm-mB}yl>N~ zYOu&0Tnx-P@whZt=k}^t(6b;oymzLecUsqDclU{2`B`KTZnPu2Y=iv!X zN6O+fbq%VjLt$5VjLmLzBA^DY`$;USQ>I#-i8(lE>9@7xl|aOw;aUpm%i`~Hi`mdkT`lrF4sAQK1A6Wtz@0e*{bfPszP#HK*T|| znh5!U; zax2tj*0o%Q#NRx&i!Pwm{pG05uC5Z!1{@TwB1@L#wmmBHIicEYP@RD5M$JXS)J{47 z04mF|Bv|hSnn=5t4NHr|kPb!7l~?Z9Vj@F0bNOvS!j2=PT;%4IwG%Y)oOZZh#H9>p z9WMEkE|dWSG?M7&&`GXQQayq{9(TtX;&gKdLQoru60#%4&#?JVn9+GG@X655&O3N9 zZj8R9Q!*MEPJqUsx5}Fv4UZyJofHOsO}`2|41yJ5!hcu1vbR1i9~xZ4CY_+Um7pB! zB^V3?)a+x5;Ek@_rJD?C9Q^lqk&tmK7~t^;BQ(m<&3BC zjmvi&_D!6|@kS`zmbzQGfRNa}DHCWVHv#ehaJgp@T~q;pSomBt7+*_-bww8cR`* zf-iH40<^KK2*~agqS*TE)C}xDXc}*ib5m};=*SlwTbql^!toN`^|_qOMX}ZI1zbCV zLYK7otMD43LLc0t(yBIOGH1HYyoN%)b6%wAp5s=peqMJtcX?WnKl#%`ZI5w?J?^>x z02N`3g`QZ?{{UD200bwLrtMr`1D7!`Lm?V-(0$tv?l8Q^dq^U%!L>x(X za^fK*l1hY3NCow zDy%5!pCjmSzqNWS#`u3HaDJA|*Xo%2)qKb9y_4>H+8jFt@<|dXg?X(uDJACaKywR=$5NWlugyxZ2=^Lg;NxYU+mOuBa4LF8MD z#7$CZS~M`WL~wj2Wc*;tURI{r!}*tRSS-#qa%5IS8Jg{L(nl|1q{12NT{-W z*CxXZLo!sT`{T6nU!<+nt?zWK2b&DopED1CaokRao%q`I=@%Y%akr;g-Hr}FB%%2Ax$Ie8{qO}xl zjvy(x9N9QB-d4d{ zY`Go@i89doSHn|iJbw82nE|y+WjULD*DT(%UB#%R+6gAyp^DqNjJw`|urbBJ9zc9Vk)+}|fA#T3bPkpS%0xK=( z0s#K9O>6`+0JU0t>N0nWo;SxBqivaO5A~uAhFb!0r-{$5f^0Ui<>HZx5PY~{D_t__ z1b#p8A!0H<4Bl`@OKsiGqQc@tki&-L&J-Hv3wy^=fN1(U! zN^Th1X}Jb8%5#-5hAup!EW-B@EWnj1mz-#6Yd(`#DyCv#GA>1R;N9K*qC-z>d~CsT z!Ua1N+}>YMjl`uF7;-jSmfY_m3M{d^n(Mlk8Fjeg=#XZ%NSw^8#i6^TtwJ7SMQ{gC zDvBBY&h!S=9~ryRZ~CdtJlOSKDcK-Lr%E!6Xjc=7?9`fjIGMSk=}X2JP=r&?L6jn3 z^&d$pAd=$^&J$yMEe|@inIj3{^BRm!IOi*dsw55Vw|jd30KBGU;>$kfmXC=6Q8EaE z$0|zcx0`$|C7fx&rN(7yvccwOn6gR>F>iahd6y^TG7ewPpwEmh+nMf?Cz-MfZt$8b zvSXba&d49Es~kCnbFY{M{EEvt+73&csQTstpBmHAZ%VZo%nW`ce$o-jwNbo|w6#tc+J?mQZ1CySq6e1C?%~<)=x7NhWE{oXQ=XWiWk*@C18#u^Q8MWQbjlJdn049i$5@Rqg5+Sg=xb5>?gNX5oI&vDhz#TyE zi7boxIFlw#Fip|ch0nI4jMce}Wa___RzYB%5|mn5Z>e4GeUk}5)#mVX5}b?Xyn!o# zHp?$L(H%DmFv~g4CC+}OSMZBFZfUXj#rRI0_FT)yDnoC$=5s^? zeYuw@-JO)vM#Z2vSSF;h=cC2j&*lEm*jxbtZ^;K=0 zJH9g2TsynFQPLhKViPg+7gEw6z0z^8bgmP3gTvtt_(yd#UbA933YNRbD zfL!J!VTUnuWZz2XcCA5jJJvK7zL8MnyyjZAjYc5F8fPNr)Bzns-RhIIVpi- zQuLTe2g#`|oBSLen!q1YuT0j_cHs9CfpFuI3Fk zq}{JH-iq8QgGSzb4=$oN^(|z<`$alb#{}eVZzL_yhS~UzJN^E8B zCTnEQ;nko}7@Sv%ZmU?kQ43tFIW=n3e$n7lu$Nimge`NC){jcl>{bNB(8g=e&`Iu0 zwU>bL99|jN!zrHuImoQ=eV{BX4S|hD?kx@7=$AR%+)}nPAHYPWP5%J2>fsKfA9Z6| zXlUD+TlJSWgjUjIcBA2+3+Duh65sSC@@j%~LZo4mz){S?=|QmaCx(+Q;&NUJW$A1# zSbeB=MBH|BwnHKdMo+UhGD{4S3%{vH; z!i*0hZX<-0<6`n7Z!eWwGlV)#j4OTcacQ#p@`B-tX%&Y^-p0xJE(||} zO|Bk8Y-N)H{{Y=f&+vyX$0QzITe;hG%xfDr4Aeed zCt%o)IUw+f!70DwiF<8cYpH0blss)G?eWJseFgVB%Fo!Sf9e|k?H8>#Rp6g<7AY0I zjfgTOgI&OSM{V}6c82p$wV1=A=y-sa=kC$LID1D+6t!ja5qubDln7n*u2CiP=yFLe z`P5RP>f-8wB$7ykxx2M>Bv%(IoVbIFo}}d6>Z6EkL$))YRT727e{(tYR`C7kYB#?( zN}u+WpY_N6tJL<^Ax83l0Dtm3*O)~d++o4-NGg9?_g^ZISgy(hcAcRUczE_veyoSf ziYW^yX;J0g@g%7 z*sGoEXQfJ!pNH2VC`~xV{r+oKap_n;!A-&;um~-F-rI?2@H{_*!P$uU-d0=N+q?3n z{qJEs6RiVwUDr=i#8Q`S=aS^dhUf?H50e4r6%0ooefJ*BsW;$OQSdh~+q{Rnu?wH>Un z+|}I6PlM5zjK*#wV)6KiVp<;sxKFkrAGvd)?qy50hY%TctA)3n(nHot=3~voc=0)r z$BO~Aplp^t4l{?##AK70Z5*F&XAo*dcdeB9GU^{3-;~*0KI(*Ny}^=BR2cs9zQOT0 z)n)f3GgsfgOBVC0yjAC9PaMXo-?^8_yLq`Z_#PH>NO8zd4|nMXNoq}#P8%I|M7IF$ z4G~%8L1DBi0kGVPi$%}xF8mpMp^qEoIf$1(HtkA4*!X}Iudf5gujAB@mc@0LS zIKME++MtCSC8nNwJ#Q^QVafyVE9m%fcYRNnARzGjk{g5% zovKP*9t9>ik*VNaM}sevl%;N8E~P9}cw6q7rM@I;;$}!><=xT)%A<&18MuiI`+0hg zsd2op*7l+4R9V}-%iJpkT0}g7Jl)O}x>W>e1p8LG(vM})xNQsVQox`BAwMvQC$Ts~ zxpcG-%5{Du%iC}*E9hFI?b;r97(c?!+x;p*`Aea0VFMUL{ZiOgI*s zg-eZC!GiqPI8fbpy~?I$2uI6uW24P+3hdVgz0`dz^IhUqQOkob4|>O%`h+Scd*l73 zJ8m0&bu%ti99CST_Yha=pnDN*D~>?2Bg%$4xFkiLad=T#d2?KGpGDJ{n;DrCd$t?2 zdWlrb+&Qi%Fr0SFN2w>;%WqEq0IH69y}-t5Fvl?J>Ortw{!^XcbzGo|MO$kuSl)M_ zXEbeV>Lhfx0x1zSyib?vs)?jk?>W3m0G|O8ycF=9c2Q)uY6GTUKC6)R2CU78S~K;7;BY|ZkcJhS3!B> z@0(_)V!L&T)s38OR9jY}o?aA1==Z1_gkT0epsv~%z(Jxe@gI=IdB?o)sxy)50dA^k zMn}Y57j05Yigja4RJ!#8%;iT9GlX3u(2U(^+xPdTNW8eRZ4&133a{DPKz8mvO}_6^ zov96l_VV4`nh5b2Y!7$`-uRV!E#TH9Qx{(tx$EHMSm%R=Cj5>u=L$3=oIL+qJmy4M{5OicsH&~C5*GMWX@RyB_ zAlTeO=ZRc4(h8FZ2f>rMttZQJyTJ@&$+k;3URwU5g2C4u%?5;fyL1ZU z5sV4IJ4sKBLWC`GP^6WY@_1Ei?t@~nlUakGULETRx+)A!?jnA0H<#|KJVnq8wA`xm za_ue_o#!bMoZ1B;(W_)*znfB<48%ARcf26K!lEmLoz2{!aLAZ0=HWzKKZrW z!)|<^iBj%6i>lN_hNJMe$8(>fs8k_LrtAW_YRH%dD}-D@eOnQw9z!;OFlA>q)k8yr zZZ{lf4peSuEn2C+1xI({(+sm)up13mB}En%O*uBw?wNC$I~|D82buT`D;>Aa%YNv>&{tdJLhFl_kGL z;8t+(5jIOZ;<~xrQ~(m(D{XY{M7JT*Zr9u*clM#!?WE--=z~yVG zl&^qujm(!E208HsZPs{IXfZbx2BOE+E2xO{+O9CD&Q@;?#nHB(Z&?R2p^+LycTMKE zw!=50k(2QWIL;@>O#y7ly&~6AuZ-n}Pr1*3DwY$cbFGwG zJtf{(N1uyu2EY}n7}7ucyKuL*(~!3c$PV#%x5T@wESyBvzV;dk2e{&iRK67 zg=T9@EN{AJwp$Tk?zjkU(`lj@lIv_ani;u09wia6h|GI9pSNCsxjIZ&%)Mn)TtT-j zNfQ8wA<0jRB`^foacF1yc z%?aikFI4yW2Qrm0hLR=RTs?X$9bf_5CRM3QKD zdsVil`^QEzJ{DM1No+e6U=D<&D4?Ja(+(hMi3TwfJoXp1Pk;OJkRtavKjJ4RoLg$5 zmI!6iniJ#ZNc~f^%>W%tN3J@7ND9Go?B*H{%wxS~C_QcDB;5P15VN8?5bvJO?gQ$8 zO-$>Qg*L97*avddTE!qbGEUxgxPZn(UP759{|PpGmD~e`H}b7q1Nwyih#Mm>Qdtl)@Wz+fNA|FO>}w)VNKNmSb%^HL#)xGl z?PJ|nK_rWoI==Ez(3}WcKARWgaM=gPeR?!iS;_^|=6&a`(a670%t`Y)SMD+nKr1_z zkl+6H3f$sU7apz^GUGctN|z2ij!lUbj8QC%rmNck8Aveg%dIKD0*ca{`#JlQKrl~P zob=U|dG!&y&!|_%H%c5K8ijK=zVIPc9%@KjN9RrkzX9yl#wOQ!^|El`yPJcdlrpB2N^|2t&Ca z6@Q@s(p;R>HjPTJXR*u2GQ;n*^zUlyMQzznM*T&JSXaiZ>sE+_UC8$<%`&5JQMN2F)MGHvnyA(w<*L-t&YVkG#4j=OqtUhzSn)rpL5ba{C zyY0Ysf63{+k)qJ@U zZ_ijKBFwVz*no%UjwbHADqa-*3L03gwh${GSnrdh{v@haCB*0pEK;WuoR?hHWm&Nn zYN5M<~{dn^^k*q`vaE*{oyk_YPSrG{lT0Td~z@b1kBgM{j^9J52;riQX;C8hK z(-qDySiXP)XujaYS2IMf{r(w}V~K4C@}3YYd2QykhDp*romN-eq!f#$xg7;~A|vJ| zd@z~mJs+v&Kpztt=d$(S8+m2v{vv0!$XLWij0K2`jvmJinNgSaFO>AzFbyXKsGs|j zK24Q<$vGF@02e0$!{Oz)iEasDkWBb0^$j%7dO(RO_Sg=pwD3R}bcj9jNr>9ct2oV0 zCvKx!%TG)K&56%vVb0CZ^PMKh?561+j57#EHGDSFbi^k~q zPWa(aB)s^--MGsh_M(jqc`vMfCzRIMA*f?xXZQX|(aMljk?v!^Y#(7CK7||~6`k@xVBRpOeW-4AL^@TQ~C-y{MYPUvnpd`km(ZjX$)F24% z%D6z)=RCe+lcoCGUcji{HOY#j0H}PWNE&^6mUWwuD(vNGk3X^tyZ#!Yy2FAcrae~s z`)QcW$w_CVoG0;$+YTWyGUkfhuy%E^u`Vd;>w|WrIZA2i610iO@}bW1VU2;gD@d1) z#o}2rKV49lHlpz)7B1IGKdeA>R9=dmvzZG!1jVY7+YP3`{OZDX0U@a;&n9E-LYgkr z1a4u}PZM~3J3ljRB@@g!V~{$ZkP&MWANIRdNzE<^HK}UEY1&p&D&> zy&;3N3_30#^T-!+S6H`1#OsrJV_2A(m=i^o+W)1a!hcER-*#1 z{X>lqy2a?kocPrg1?PultlJ!J6++yAr(wx66KR`+rAi~;$n}CoEJJtML>roWo(qPV zNPJeff#0p_$@Q_lf>bl?R&4PJLhzUDnvn=OE{$;6on4x7O!Qp7YR|$lq3KGQOXAQd z>0^omnJo6rW1pXPMjxbqNI8lUOgmg07qUhr55pm6gMA166#>gemOR7I~(Piv13s7wmWwxcS} z8DIO3amTQ;r;b_gijh%8Yg}`YE^J=kG}bX?V7M(qXpK*y>`Pt&D&cRJ&hG*j%CYRL z;{5h#af)G^5?hNR&0#z-CdfdOo}Y-~flQ67u7`6OmT+U-mvxzb8gqfMtr2ls*|b0Z47)SZt6Hz?Nm^O3hUvA6p3j0H)D{= zivOjXzaeAD9ZAth=8i34{LJ&9*@m_CN4!<3S}Oh{i%GIS<@N`TIohloN!~eVjPto7 zo$VLaGnOUY8DsN|4hn(QR=wG_q4{S6*g}BEzwV6 zUbMPmRFSXsC*VLVt)_NBpe434aEfy+_Tev7nVd=gF8iU^a9Gh*_m@1J%PyCWSPH04 zq*u{8t$duu*JRxiyk12=1k{#;SGx2+0i#Uz;wTh9#}5c^JXn>Tn9 zwIdRgbFj2izxtnzzC6%Kpnh~2T_cf+JVZ#L_urMBkI6LGz391rTaTA#QwslRZCj&? z-u{HS+^5l=65RX2rbEvJJ6e-FQH9INt2mq*b<|z7p7$WE;LFVz5FmkM^(LNU86|Qd zRiNbeVG}O4>j6t$nU2l&QZt{k$#Fcq%bX~7edh|E2#fA2A|i`)|Lba=9EQPY-OJz* zPI{0*7?~PEed>sTMo=MDhvM8R@EpqJX2kMLhEu7Q4mr3{m%rDas=M2vvb#RscF<+u z6k`e5mT9-|lai6-cG{3()K|>;9M^~ z*iP_gq5i&7IZacXEIIgrY7O;B$i>{%4&DURiHLK=I%3qboa0>3#3|vSO=uss#z8l& zi3FWv6=^C-NYDZy2Sl;VjzokU!>{FP$UQe`FuAlKhBYJ*4SZ+NLNax&)G;gK-UXI| zjSk=T#tkb(OI>f!yD8HfaepKek<^y&lImfSb>g_4#NM?Rz@%OnfU=5`lM;;>jkf_W z&-1yVRY`hBoJ+x%IE8X7$7rn(8+dY*THPqu@Gf1#kav#%`8>znE2z=sjlk8Y%9(!%^Yr6F?IeG#&dNd4>wVMPocm44t+$cM2BsKUP zNJ2*zqJBGXUZ$Mz{e>DmK8*Vc*687^#BIE>hWSy;&^Tvq%cXl)A=&N~T2HjT)~CRG z=LfPwrO{L241?x9hXDO;W=$46i=Z<1IvNvT>;|w5&mnZEVF$JA&dVsQ$XGCm*_O&HCIER}n zx4|1L#gGHp9YK?#_+_i3Q=%kpYpd0g)#(^AAZoFk?eSuvrb!2Uo}b%5hD+Q=pXg=n zZ*BVv^&P?wO+T&UWX$rN^>j<;y{|Dw_ua++8l>i3YNYHV}O)U9~Ap zi{!_i|77IQ{+_4tD%vDYS$eH;fKsb1{^q?4g)ly4o8sQ0(EfGJgQM#mvybX*pMOo4 z%)2b81D(tErg0Ch(?fr>Z@a%F4F9Lav_NPWM(@(n1vL(XWFOIiQCQ(AYD1H6*1%E; zgrBN7j!X>SbjN;p3hJ!&8j#BUA~@}~-8n+@B%w9N1RzLSEa!CnZJ7q%+O0NychFey z_GQ!?qZ!3~!f{Ke2#p{(-Wuq~g?e`>zjnf0i&+A#2uF16h_0Jl8P`HvcT7&|s(yVl zk$B+VLi5h{nN)Hx`&bb4WAF0!!OYTOr>-vHxP|8_d3(P3Ky{l}iJoP;1Jf8FhggRSuq@4bhJUv7ewWh4<*k>JHTq?Emu2d<7l zDDX$1TH87Bx|ON^(OM%W(;-4L zU|bI~qcdcU-_*A1z_h<`fL|nw zn=idg;!j^X&P?1M`_5#hN z<>FuEr{b!wQl$+^hlurQVKM$vhA5Jz0{Na!fFluZ^kEB2>OCh$erl?&pbS>7zJam| zLv6F7EfwuRPL6a_V0k~;K{wjqH{m4#kFe>hp)31G#-R~n5Xr|5 zHxj&6g)lZKUp%ni)DV?7q8~pk?OGO=uL7QZNTtoemRPTQ7Cs*~aqXK{bZVNDe1R6x zp~ePPYl}M9vf+2NX4Uc;0FI=QQa)qbgXjK9G?!E5AT4(B=c0kB#~20;qvEM4(%Q2Q zhld0)9e+Bk+-cB&t-E9Wo0=OLgQ4@XodZ1FD79*IROm3GT56-Z-+Js97tIE|7S68dbPK>F-LV@V$o>G3voFb-o4&}iMJRp) z%>hZpA><>BOXnq0#iqoRkGZZ$j1MtL9le)BF>7zCTsg-;<`58>JSW+>J}n^J(Nzc~ zh$j`?_N_I)k7$LbQXu|k4DMm~IMq_bvZs!Prps7xwMD z-jcEFvwiIw+$Dx*q9uriXoPbzjC&6WGNLE#y#ux|AfH)If?GrPmr@AznkFB5RF_QX z;n1kF|7+(*O-F&cKQEE^Ra1q()6wGmtT8~VSi^`m5z!txNdQgF_a%{03Lm9 zIEu`;5a`3GavhhK=myKrDf_jty~>=+k|U~FrI|r8){TFm@N%14tQc$_)FQuZpoY}1 zRGD}Unv#b&;xFKXA|11JV$$U?m*?Z~!1g`HtWh@srg}7|`aPgz1Wemsgg?R+bO%W+ zhB1S~D4Gw$j8r<~h1oDG#kGyv2%dxi32eE4wg`xBmkS2JdmmmLkfr_DT@`(gpG*Sx z(SX?9l#6|>96H34+V~FxGro?nA#4Z_`9!0-#9ZL-f5wrE2DS~BnsOI5t~_)SbDleh zi~1yy{r;$GQ`Xw~T)I#w=rGjL-y5XfmJ)<kduym-PUv!PdKQu)x0V|m`zB#hgwW|`Tjk!g z&@F5UGnZe}fe}HHd5qH4XI{~`2Ot<>l1xX65=>lz5%0L6QkzBY5?HJu3FrQ4kcPor zj55tw|FF3LLMCNwS9>yS~3X!&uNfKx~dx(Ff7nr9&( z)??$cBpJ$l2RX#G-u#uuFnNQdgE^NAHsC83o6ju+@TSOqJX1W=L{ooH%s8NfHCK<~ zfZ{tiTpMcaApwi#eaj%IX?bb+Iu0+TE&!h%#d^o$w%1dsAdzY&CO?wOp(Ji5al6vi zsRFJ|Vr;f`7;#kff)1kIgl@d;Z7LVvi)tkzgxoxFa+JwW%6%SNE!c}F$ zLWTHgNOQHm^ULw?F-sv2nIMTM^@_*`^+8p9l% zZV)Q>+*rNVkO&<_8|G(Jf>>G#qE^S2*Y~PkV$R@ZA36Abo2NQ2QFJm%s%v^XX)Csj zLV1-YH14ZH%4%zAf_aHE_|nu~UcM|maiedI`vT?aoK_u_K6qX=m*v%{Lf9b&%plTU z?K#Ho)OHBbW1|lHrJ&Oy3vbu zcH}L#Vrw3(Q|BY^*L3QKFAfn+1pA63ShNH-jsyI3QhU8}!`9AGtU0~LEee^L-)FNm z+JbP%q9KRt1%)+vDhHF8A*pUx^l+8wDc@frZ;s?PR|4OSrEohnfGHZMC;V!41cFBq zFl*}(d={h%arM+)7l8Bq!4|cJxO7g$B7Hc<{g(`S6~c;)0D(3(ZZ^=bJj$Nt)_IqF zrRcDlsr(;P`!O@z9m;QX{C1|1F!+@7I&I`x?u!*X+bowlKNcOeO`z^fUZ=;-Y&pJe z@}PX_3`*R)CJ-zToU`pT4Xvy!rNGeolT%83g7tkvWcGl$t|!is#go|#^S+S zMkTVVkIW7F56{|b4rh%7*;8YZ!2NP15RlvN16NCGS`g8DxtX#C5u+MxVl$~8JxGaN z5}Yhgn}eU2Zr({bm+hBtw%7ZOd5GS;dvS7yHY z73WHy`q7mscBD61?sFO?#-?p2ka}wP#9<1CvM|AuZr;BpS_hu@tg{$02|Kq{ZR%UT2c*5Vy5v9&d60w|x~F z>a~+^dSyV$HCxS84difJ-`SQ}9_`0hr$P~d#AKqsP(0_P#JvrIx)ehRsEK$UN3|wl zav{T(5rRhx{rL5BS{}-#zzGj-FsBnDcE2gfiPGngO1QR-p`Uid@As7<0&>du!#d zxnya1JeLt0)VLe0V4Fg&NDtZN!58wHW(NTrzUG?b%NLo$XZ3kK;YI|cYb%I%Y~I7i zUeQ+R1`iW8`D6vFRmJF2aWlo)#3K@+likz37;2=S7iB;In{2H4zB*}6gOyn2;RTEC z@O8|8|A+DkCcjp#y9}~s^pPd-S`XGMuz}xGW>xJ}n5 z7|Vx*PxsoRWF}#(Pa&SRihKn{jLa`Gv<*SnOo4_|&XK3tSAZ#ivvPl|QcfIjC2hph zU(kS;3;^7gWsW9en%KyTkC)37*&^L0MgE0s(w1yZZpfC4B}YZDhatsPkBa zu$xMxdz4H>NLfRmhmb8NbkkSD%VIxGc_lxs8pNYb1YF=hJxW+o4vUEpz{7SU+&_2r zrh7pGZx2|@-P^V1$6PX7pbYZpu{(#;9X=Dz`FS|b8PF7NUWTG)VNx6WQBMbTQ<&jK z{UE7%mHC~lxMc6YfuhV9k@tr=g~`8fNQk~DMSD6VV}4P#(8kwFc&Kn&j4PtcT6^1p zVFO(TGh_$d+7vZvn9hVuk(Eq%x)UiCc4uQb_!6-|9YAvsD2)zF+&E z8^U&DAmhsJPr53U8kzRpp-g15Lp28zsim)}+3QF<@_07y^(VJ7 zUkt|hSqn>_vbfoK7)5swdeWk* zd?mh0P$Z_#>-j{duW6cl5L#PE<~ zKI={DSk_yEj;JX6J;0{%WrT|h&si5$X)D$}h4ssxqRpIPga7X<6$YsXiWRH%D*@D6l%I<4affY?IYVk0mgnrW5Ww$AiGYbJ(x4qOOv9D;)F~ z@9|zWvxIa&3=v1xRff0m5W1lr3EF{QWdUO3s3flA-B$pEb8j-cu-Mx2qbo{jg1!&? z>FvuQw^1QFKOV!~nYpp^bhjzBmP{g5^x{EbJv2>$_{<+?E}q|ZtAf3U(#4}21=a+Q zL$S0?QmB0uA62&aP?#8!i`@f6sAhJjE0m~2BvRtl%+z`WkEt+p9vJbR-)qr0?#{J& z{mB^8gTDRFs4o%wZSV&~UN&vT-u)$Jcd*GPX#88yIPBVx=V}imlZX{Apet-eZd=0BlbgL=@{w;>G->7SUxrWZ>g6^^XmzYhxoekVK70uGA`L$LMwT;!<(RZ0_d{6TE3%sT%KDc~A+ro_=;ZA5!V(+ z&v2$YzbnABrd>1n(P7^N)b??gqCXV3g)y<9q_2j?kvtB?()sz9ipggpmZ6Hw>-Gy& zEru0`xYS^!9Lz-K)p_I9yLAi|W{Oeskmfsvdf%<+3Fig(4d#+{nz0d+hlD}!|N93-OMzedUiysH$O3q+HF6e~D!IfOGN{)7M&=|toC z0xtWlPFy0hN|oMTX6Y`RNHHqtl>HUV53P6+%_~TAIb^eFNDpY|}F0|3)zffxV zk4bsbl1)tJ5Gql?r-28VVDyNTTymF%ZEXTURX7}aM!8s2q?{3#SVB6tJa;gN8VxKw zc%LT6GqQLiJF&`t}N!^cI?&3D$M=MU?_IDG^y zD5!2>>%gy<2Zjwv3>Bk{q}!UWRL+aJSbV~kJZo-hg9BHz$b;J(P8=I(K(*X{<`fpV z++oya_Gl7rVM6&VrW1PZSO)?lI6uZ^<654`X8pyK-%6$Ra&10aQA?WPdX$(=5BYjg zOu8LRIiGnJKAPJ1maC9-D(O_1Z7IWi(|F`@W6b{<@pY99-_lgVa={ZfH&Qfdt+^6# z*}CE5yfR^3uLumTuE2wtdWdiKMa>{s8Ml46Qjl)n4nN0W6nB@lea&*vy{fsQk>BmL zC26`SuK5r-w!JbtHC<}|I3^kE%9k`(qSXT+?8UPrhLJ^i9xtFm=M`a!X~K%NL*TeA zJ>1@zhZc6Ake8&s24^K`b&D?;?2E?KmkZN$m(<>7vICg{m zNz)W`+d?I;MvZky9Z8OfqG=GP6XiURi-hmHi=M^bu5}m zr+PY%Ma=z=58h;E?Mg$;=QKqgSB9gY|sh)y7U)o z!q6K#4XTHqF)BsE(dRm&>`sig5$*|m=Ob-$c@NRy^0f-NV^=x_1|E!;vf7*X8CD9c zlWmVpxG4cGH%B02Hhiz`33k%56m-g_NNtZ=i}STDXb5Xk+krL@92M6U~JY5 z%4b3Q3VU^fUAK2MDe0Jr^BN1i*pIQLQ-;aS-`PBp0B$*^h1+O)_L?2j&Xp9h*SI)| zCh=dr^1A$cncXtdtkta;{xD5V7yO`A_++%zRabx9RKQ-iJh;-fdij_jOLdcv@X2LX z-@=NSn`M#JdUykASQP=`YYN;sY1mE{>6bEC`zPB0S0k?tmRUCdi0HIyymK8A{gR4N zvDWgVm#Yj4G0p9u2g%3Bxl2~u8h;69(M%M=bzU5qC$&tYzfN;gdlK%26+# zBFx(HQwvhyUX+4g5qDu7KKhJ~1iUoB-@MA=kB`FAmnYtsyZV%q4v^J(KLH;+42J2U z>%W?PcXq!&9!fq0Rwt zje1ymCv_-1!KC6LX76A_@ngfL$nE6{n#D;@c+XD0510CpRUUY-FBc2qBDS;#=0!TE zMlBDU3Qd&t%=C)a*nQEmzG3X#1)Jkxr^c^ZD@~1tb%cWyoDM~{ZC-KrxQz7k*u$YY zNsT{+Z&_w!#5+~h=vg~lt&PE4d`g$fQ8!q{b;VQE}v~PaeQADxRx0g9Du<;OUK2R`DwT5 z>c}deZ@IKCfJjEDp&372Ui+S^u%e_gaeYL4D;^5k)xGJ)&->*&Q(G^S)yD|_LY3H` z8(kX43W%!-zmj)k#Ed-0xldQ6^7tt)xMBNGO2y(%pDJBZ>#yI*QWI1SsyPQImTxW0 z<}eAR2zfO;!57-P`Q?LJ5zVXFuu%@;xB_@CE8Fx zc>J26CNB^u1Iai^jZz^)S}8fvvkk+-nTBw6EZ1!=8d+8Pz=AYBPJwp8!-y6rrq<4_ zPVh~Lo{6{Y5i!fn>sh8$9IY##C!U!ud^gnkgp8yDy$c2O8F3tX^(fWaB{|m9&j~|V zI)#uus;USE-oF^~(N`(#oNCvfCyw=6t*Uvt#qMW14eefk%2LLL2H zH5N(0f5gKiaLaok=f$CB`C3@ZXd~ad8@XkNAMg$Sxb7M8Lkg(&j}rlPiOzdUK8W`b<9szL7GD7KxP+Ikg6F3|CP(sAC%RlbNSH zOBg>UxqVo%Iff-%J@-dL+XKmv(WB=g*dc9=(&d@&coM2zMwDPEKDHHJ_8ZHO6yfY= z2+$Klqxu)7EGL21Blbq1;YIDIVGkmsC5uBAC!^84bL_zqmXbJ0TubyH zPK@(Zo*&E%Cdh74UHl!0zs^iZd3L7O$TX>7Q6Wu}Gq?=NaeO9umu2*XfH*7ZjxY)AzQ)q5J+q~Br zYdbjQ1}#O+gYS}I171e0%kSVYc1$b3!_f(ejmSa7`;+sNL+f$b*^sUNNaOp|V+Q%u zT^eTvcwRN!N`4mFW_r&KcgBV;GP#ozd({=}ZU0PR> zZiEyI{EuR_J}gb_A_U*uljwDp155)DjkMLZ{^Z}TPLJqO-J-X5{#t)EHR?7@mwKC?KrzLl#powq<_UE*A#kU$@Eq1 zFTZShXxfKt<^K1xoHp7)j-52LqY&Mx=JcF0!XaA~+cU&l2!gIYkmBS|n_P*E z0a==2G{laAGFU7ZWL%UWGn<9x=YK=&MA1}k_>GBgPiU{x<`GBs!&V%+=4xTivK`Vz z*E7GUd{3&0vdg;!u5P9z{#3NhALqZD!glNebZuoETm8(v^4Vpu3f)zYED9oDxpMa|7;|X-4`($PoXv!# zdNOe_^W}rpgM(Z*N)YFn-?npEYtb~tT}}HRLy&b?0tm`uruI(@bA9O%x9Jg?{!|VD3(^k=41kF;`@48Xp5S^d3fLt@ zIg^Kh++Ewfp4_zm%=3RbL1zfAu;w_%c--DW-X}UhJy$~9!OFq$8bp=R3piux#IHQfXePn>qgrWw)FSZ zD_VDx#HHCs-~P%C;P%4eT>Cei|3IP;{!UBK3i@!bPK6kv&*d4d(sZt|((vDveA>tL zCNW~u3a$>JAl(R#rdOgQgCOQ`8zs8bU`te6X@nHbl4&yVd34=`oq@Jd`uYP~17SP2 zW!(kxDAyw6=+AwDdVznfEzZ=2yD?v((^+ zTnd*=e$nY=)41pkP;UCwDjwEsEq?~<*}9(P*l~LXpn3jo-O~BzO>?u`fin|U(;g~l zU7^?B`nyc-&9@bRi`MpJ2=#@^dVA3hv53jsEA?^VBfw|@BZ+CINNbmXOyrwK;_3lM z>GAFsFU3jYZoViCfRe+aVTRswa3aeLCB&%{19a!57~V|I?v`N*yOIRC8V)R<6_e(l@ zhM1(r{p_^_F6EsRW)ce)6=VpVVBX(e@OC_$5hDso-N_{hkBQ%7Qlw!+Pv5~?aT~XO z(T!4Y?a@LyvQt@q%i9V%5-c1kyHSL}W)PGU;X>-okF&j84%*Ptj;mDPAj|&h?B=Pl(mOx>T2(1=(gM`5ujIs&Q5N zAaNb*N(IMHxTr$|d&ysKO^zu!?{LvF9~U0&->9Ecmz+5^1RzqK`!m1+7{YL5@4O6n zbJcF6u2@z<7K*{v0nvE7)UtT1de_2MHg9gv=Z4xtZ%7}?u)tgWg4A$*#tk&k$ql-< zOoILReH5+9w-T9<@5}a&+M$US7kU%0<|mq4;DtF(U2Ke7;~G@&HA4*d{9cEXV@+8@ z{+3b4MK#XzeQi*0v03bWGDijb1(?uBrwBOpIQ*v-Nz(vX>#=k|fQ$}R>#>mLg~Dh5 zWSHB5NRrx*${O@$MfkwC5X@Kz7W9OuF^s9z_rG)O7U5fgu^<6a4FyoFwo+TkC$l$# zMx=y|Iw6CC?yX2a8u#UeGy4gunW2@J!ZUHA+n{tuAk>P#@^ZE#FbC9fK1(iKbmM~n zx5tJRq?_5DSO02e+<;+`^tt6Hgq!A!U(c!&Z{9;bg2~V|)@X}xSUi4a(*1Xg2+{KX zIna7|F_BP#fzeuT?b*yW%YVI;)^m}RYdL~`6VC3TFF}mePoh2VjFYL}aj`7K<6JGAABL`(uGQ&C+ zj>hBnN{#BR?9p(}&ZM@yj`UV+&wx!+$uxN?#10EXBI|EHLE-g|jG6*bdN_ zm3vxtiWu}sUHpZjP?+xMV3LxVx_$qs{E@+p&?%V4jnm+Q-ss0Z^AzV_D8zYN19l&o zi8`(n9}{No&P=ZhDdMhI{pI@=1_$Riy$m+g2sGSbwnB~aeR3LDY*e>)BCntG)-vvu z7ps}?eV0Pm_jR>@p@bCX@;weobFW4IoV%?v8^L#%#u6(iq5<>@d zFOf}nZL4B&ZOJe|6mcE=244M^t+OU(?z9?ywVj0rFGksYw%^+2#K4xQoJ;!(PyP9m z%3B|V#OmrVltrx{WH`?IAFon=o9U8|`v0z_I%&+@vMY}U2B597D?DJo`VG7l4!yn! zsU37hby15D7 z{#{S$_Ic2SGEGy-XJdZLOn8=3-@CxLP{&|82&tE&Xjf(q-nlXo5Kod$4L+I<6oL^- zaiudwGAGHQSOQb_CD}5QLn%Tfi8J;>VLfL(tKA75N!_jZq4Gil?LuDZLS7SP1H^lW zb+>j5S0%lNb=y=-)$Y3YQG43oD|S75J(ELGrrmLO?4%SnKds#bR;6+^HTKs7;6kbL zLJ4KPB~JmbnAq`bSO8+M+S)Fj(Jm%HIg$iWsAsyrfBA4Tn`~bIZ{ZcPgjyUkIj~*VAR)oRQi$#HLZ|?gKxJ z8rm%6x)p{Lik=qcVs#eNjf`@KT%z;x`v7w%`g|V3;LCY^=WJIbuBzN*@cM=Fg>C{q zF=$_Xz+lFYR8{EZ342jPrFG}CTUGG;!Nb{rRQtPGi9X~*p7lit#%Vj^zG}N2^!qPV zV^z+SzIspFsP1Sk0*f1qpWu0mqOGB3yzo9?--pgk8euf|>{i$muuturJvvO8B1&Ya z8L~#h#=_7`WT{!|CXF~M!vdR{Xb8D#hukwfhg>0yO5alb$Bv%G=(R@1mMPBL;eiK+ z>866?1bXlM8*ChbA^~I1xr+X{s@{ldx8CHW!MnFmI-8KAS=|286{lzoXHf%A3Th-$ ztY$IJb%;CiROqP*IiCa%`$cX)o$hY13URq zX>3$SbXvmRIQaRxT{plvl3p&e;uv{TgDGpZ+O*vrQ# zRAZyFqN(bVUg!tp&x-5f#>V0md0>fYSsT}Zwfgjkh*EhGd|P?Je57tP>x)6%G|wI1 z>8EY;9%yt*d`9_j2RTP~2o&sop9ax=aMAjbYsE*?`te=Ol~H2r`@i}%FFGTdA*Zd` z-f-Wi4>rbE79KIPs{QKA_c?b&H&=8&k4na5x>&nRsu<4t5->sPFOcMOXrdhXRriKl z@Nm(j`u@@EnN1z{2`|WtiWUqop*Xo-rh90a$D9gyb|=`U7nOI|-M+?vMNG_Ij= z{<~^Q2jWY1;)kiEx#b^yXTiB*ct}kUcFQUAi2JYh64@?JY))R`Cl-a4%N{*@*w)>jruFFVtlD+wZpm z=kK3%=0n+nCa7ep?e?@58;FD8&h8?qtS)wJ{U)s;@*GxKetZu4o8rFz&`qDJ-l@>m z{X8z2ld5JenVub+MwFKriM?_{pgbPAayI0+X`S@Kru%ZgQtJ1C;|;g0{4_(jJ?XQv ziEMs`&)zX)%E74rDCU1+#`OP<8JD0!=$zuD$nE(5%f-C@FD}+X`jNh}UTKw7l1kDI>9tH7 zEAMjaAI76^uQn6Us9A>-_ep~9uG^hm;r}3Z3TAg$cS(ca6m%5(Q%7aTWln7uAQz=H zBJrQ`n8DiI?}F?(W!_T$hogBcaYn8;^MuG%r4#$2f_aHN_j7{rkshoGn5x{ zxtF_@7C)$lH`Izue9|C%mlCE~xqqk`@Ig>}{y$MO?D)T+=GJEbL9O|JqsH!D6k^sk zTME5~q&*6m)ywSr=K+iwKR<0d{Y~J%*|*y`Usib}jH=bIZ;ajC-AcKZh_6sR{ln|_ zf5MjK_g}C9-rj6FpZ~McD#JewZ_$fsaKQ~xb;E3p{tsW%{%>EifGlc9u^*d^e&T-h zRacym6iIpLCdshl(nBGiPIVS`gIjGggk}o|ieI_)?aCcwupbVZ>>PjC_=!UD)$43K zrx;OQ$h1~Z@DKx~ih_zg(ji~nzoRTHU=UfFPlupaM#Fr%HD-bV_$Oqat0>9a2Mg4=^evEzK|tNY@O_P{a5h zzrWAD_r3qjXJ&SswV$=l-uvvc*0ZEOXW_yE?uf8IX`7BzszbV-cWh1R}{2*IC0-f|KV~}N+7Wtk0 zzgrbZj5qNE-5f7sE{Sc~f)F}hy}Bu$M8vg_{z(HD0yEpCTSFb{^7f2FnSEKxL2g^m zH$he9m3M%Ni`YcC_^jrCANh+XW7bsi9Et#+GDuD2quEZJRBFhZbYnE0rL5hd1v0_| zb`kdPer5T9!};v)h2Yx)^WmF&Nc4=_5BO#zYzAnARZR+G*$#(qembfAC8PBsC5jKf z6*U35O7oF;pNest`)5}Xj;=oF;V**DMXg!0fc=8+8@W6~2+zR<>g*9K4cz7#ihF`F zlguCbvt|-RDPPN+8MBE|+hUpbb_0WLqtfV^p^ks?!n3YlLoXB%j-1zXz|Ta-5|so$ zfgkIM$CST(SXg=zQ>g34CAwIhB=Xha@@Cq0vwoR{$C)jvC#YdFY_wcw2|7C~)Y_11 zhw`k1=ewntF0{86UjfO!b&*^kX2Oq5X1LZW-hw&U6+_`AVL z+8Jj|b?cJ#F$5aOx8j|zZ9nS=d#!xf)kN_;@cFyHcusbaOFAv3GM>TJVdYKF`Z@Da z)ixjAUkv;CnK&0OV>L4b>7zzs1ac(yB)zlI?N-RH%)^e=GZToxDmE_&*s2`@+or#G zm*W_n&<$TZW$drNcw1a>Lq+z(b@%FTPdqE{YZ+Er<^67V)2G|*MxkI~bJXQc0DS31 zPv}5Ls~htH>9{{I>zBu{c%AC&0j^0R45+Y;IFs~n@yKfh&*4TF$Aii?I=65Y>IxmC=o1;g)&QD`E`PM!f$@3R)5gZn%19vlu|7GPL zeo}pIZSzT=ws0uT|Hqu8FU$Ve@VM+8bp={@O62W)e)z$`18mW_vV8@xEu+n=4&uD^qj z!I_6JDlTn@S(ft-`67y~wDNbO_39ysILaT#i)Y}GR+z$Hya)3_q5{UZgq?H1nXQW7 z)R}r1R^$*@w^Jo%;9$}t%QIVtSwEn;V2IIk66e@JK#H1>XW+khs$k%2wM^MddGE-J zb{(?Jo}3hsQO%Zs_`d&|)^O=AH0N<9ZWoYpQiC&Valm!CFP&*b($8~W9i08eTLEa% zWu9JYw2BT=`+DjvR{PWvCfr%2CwfPnwM$Zx;O%2#j{;J>{p%;ob?2dSw^6oJGb#x1 z!FQ5sD8h=${l)vK1%^qW5_gu-1`k*XWr5`r!5+0pLb7Ax&N3|BSrP?O7R!(u5rGH`U54GLgh_t*KktA{0ibEZM+ zuliH{f>(aGGO97J>QT>PBx00QPY>2qQQZ1j)c;dhWR&OK#mY_xnv@XKjkO?vS7Gx3 zv%UfDFz`%+3tjWRK? zvb5&yBNhg7mJuM5a;hkjR5-WhL6ya5Z>NgBSfeoD*Q*=ZdukHy+gb1D!u-_pIVn-e zP30VhRW=D>s@;sA9ydn%5CU%YoLW#CNbMf_4ezAR_;C!_l}p|sk2_s_t3_-WS@P3-?h^z zJIy7+v8@aU(%ZjmmoJoOZIgihFtdOvZ-_l~iH#L`%>bVtRSlB2_pwPgoRmwJj(%m; zhvqkQ5_a?D=|NW}{4i_OT^yRstz1hBD)QHMO(#yhVgXOk%%!@rt|)0`IOPvh%=L|% zW772N#z!}D3xau@Z2!u0CBnd)R-*S zZg(%gTbnr3bGu0Qj9BQ_!wOxhLGtl%etWP8DHgAjKesQfs;(27JGuYj&0`iw>BlF| zmVnbA)9D$*engEgXGQR zWz1mr?lWnI!8Ofo!(vPJ@B>#6mWlyeOjDapLNnW4;ZlpG3=v6KGu2y;A+OtsSUF6H zY(pS3w$_lRz#%mzE5RBQPckuK@3kOm(Ib$3A!5(p!DY)6L1~@Ue>Cub!I{h>e&fr6 zeLsr&7Nk4Xkhnbhlm+s1Ss24gP(;9^!&o zl7B8++1!tt>w2(UW)nG}YA31@t$Xx+()Lgpt~P%trSVNV{0)5wvz<;x`n2Ciehj+KR68eg?=Rq7r&YaW4pc;)V6gE&2Nak9)L&7iGu`hgHB@o)1hBpSRI=$Xtmt7${qEgaC>;50B?b`dp}2_!1_2~a^d;{&gZW7H=ZXT zQ2VWY>I=4Z!&W;H&tj$2Cy+O(ug9I}hUGtjf8e3Vb|-7W1liBjjyP60j<3Y@B!*QPP6sWvH?*V^TUuINrDR?+he$))LOPY^%0lrKalNx+z{X6V^AZ0#IM2FTO@mR zpQOJyy&mf8Sp%5jbFt?Sy4R=eO)*kcU?pcm!~KMl&4@$jIu5pVS4!R&qfI)r^c`?g zhanelQe;NM;moCbaTe7gmt|36WDU+dRPX-$5xS1rSCx;UpOq?JXzC`z1EyF?8m!fb(v*#m}olySgQT5myr(zoeu8$wT zUpCd4ZcO{t-&kE4{*z>G=B=q-%L5p|pS-^xGUU1vI(XrUCb({dH8hQ1^21-p4G<8z z%!xYdWXvUvX1EeHm)`n5`{G@>ix{;Aa%tc!VMn!6S#@G=S_o)*j(hnZnhIP$!bibH zVT|Xmzx5>mwlFqRdKlkbCH1q>fS4nuX)xTwovrQHOwxFLL9RZcSTZlDXl$r>8D z(yaRQ$O3V#T2t)b7x6F-f*9lBbe9&>KTR?)jh&_KWi++&ls<`d;#IbL#!lIne4{jQ~B^SZ~867)Imple>0+UkW z3tdS;)aB%oA4welZHU%Jwu5U}DeqF+kIAdf^1h}9+TB0$qqm__8O|H;_^CT+02DGNmR2vQzd5>jbttf9`G}k+ z(Uki+%e+hC`CxM;7mzqWb%(({lYOg=zuA7Symd?YGU>adh8?K!g~GD*M{)LhMVdjC;jjCsTJ*Y(tLiN zhXV7O@Y1e-a6Ad8e@)!p;~GYt@oNmq9+k>o`X!IHhDZIS5!2k_y-uZb>pyucFaL}b z>`a?dJexE}yGB%oFo8dp9|CG)`a&yH7zhIRwWYK|!@|MRpB8Q;h3Jf@uQCp&tbB-D41ae@LLgb94i$w|yt zP`@Opb$kQF86m$mr6~Go^1nzCw>7n|LV3olQ<9(008Cc~l9XbfPi<*rFVRychFU9e<$r`-Fr;X@Pa$+rb zC@KG^qQVySi2M7xK^J0OGPL^UogOB58>yrSNEYC9q;+aQVY)@Zpw^x}?zberkRJ;@KnfcM<$wIbisw7va( zsw?@Q-@+G-H+#r4_2BN%FIhWGv}B*))=&HGM64?Mp4o;)wW~JE-#Oh?lig*B6)1mF z^tDKJjMl{gEfSgdQ#NVEJ#eMlG(jm##Yyz`hn}$hAr7au!2rfh_fFMPwYB1pIFMHQ zpi`xL#>6_6^rEtYucU3F+2DYhrohV)i2@R>VG3~-xhFu>N|?sYj7u7b@7>fAK&F%F zMj!jDz2ao!C8J4#(p=v|3nL%!+1);(i>JAHBi8z+D>hqB!f7RH>>FZN2vnFAl^=dAT&s1Wo(Wy{qUc z`aO#+w(!pd2tEP1x4(&!7_lD;KEIR{Fm)A07fe_EluV6B3Fw|yShneSIJr~#*)uu5 zaqg`=ddOh^4Z*lTSn&KoH&NW3k#bv*;ia->AHQJ+M>ESvyoq(0Zt?7(c|DJa`)1y& zMbY|@^rx+g#rqHUSr=oih@idLK!4qw!4s?bt;h2E`qYz2`lTWyaHctC`pf ztq-d{ituBEl|%6L5{T9>QhpOS)9O5>78PMrN#=fInVG|;<1>~@dWWZr z!9V_!1BK#%2P8A!_Nt*-VHp4T`Zr;O#lcY0@J-zLnj430N=EfSOhl*{dSZKKhYdAfVozkgiB#zyRK9I}aPW?E%B4ujb@Wr4@<4W~} zudPoaVahUG)0ld7L)-^2MI`v)dkRl|Bjh$>HtZ zspnLUAKWp<0UC-A8@6SfyP1FYx$qmArH;CO(ZkIJ#2Tjh->F0tjT9;uZj^MiOQ{;hufC59`cN<@#`cV5}P+&^qrr0LP5i{00s z-AnPb(jNzMPbeu95;6ZiqXL0bL*W}-%N7g04z0D5WzUn^YvZCO#1B=79j8J z(ZTT4MR)4@`OzH4^8#G{bBW!CbOS_W@wKSxcO|-FLi%{-qX2X@1+oh4SQqD7f75W% zTix?_qp-PXLldphi7BO^&Oy1kC1|8o+~C&YmC3JjW>}5TkW8_8+%p`# zZfnfW%j1a0~)8rXWL3IDaJs}xRuLwM*(KmD$m zsB&WCmSPDI7l0(<`T}GCHVM(f?WYHzRZ}pxt0T^ST%VSNvt+?;%c_*Zdk{t%%n;wSDra z2|vDpFVlII&rAr!JzVilB|yQF-p}W~RfpA7J7t-dFcH6RB)YvTj`P2PniLTdnY`8Y z5vU2`^X10uzjz)A@WNxgkbC9fj!CH1*5~g&o=S~xnZz72Inqb5WLK=EB&G~|FVerU zbZ zqTw~dUFj3e(p_gdin2aZ-B_IRVy&Os-PG>FHl7}zVP~tSpz;m95^a8<6T5JB z#}6bOb>FKctEnU+FP@v)3X$|ib-!HP#S42-h0W~MBn$y&8|oEgzF<0n_PJcBYoCLim@ImfXpXm?NTp7TWXzs?9{|Dv)te3`a|&B0U>+(V|{jw~1yZR0r->>`!t_MfwzWLm_?a^MsDi~sw5-MNkpy^nj*D~u~{&c9-ui(bTO ztGLqI2}cR5K6A`y_?@HjnUlsTe&gpXHJh!w&`PqCd><>;edAoWcs-4f^tm0=5l_+j zeS808ZM8S`j+=irkcjHUO-lYjwWekNr;vqBA@=ugQ=|HGU+YoZnT$F#jS;!{-tGSp z&Z|%%$>cXCJRFR816ekJi!?kV;Up#~tJ+oZ?&@1CA+Kydv0fE5XsbG8zDPHSNIKGm z0bJ&UYIY}9B0X&qZ*#kLNYlx0l=(7d3U$e#ym}V0E`={z#B|@sHPnkOj#@Ub^Gd&( z@OBhTQm1dIdK#}EI-At{FTaa2@ARBUD9%z&hUFmHWTQ}a*rQ^FkL0)0B4r_bJBc9z z41J9h;$V;!FIEm0q%Yba+XeAtew}@QkkiZUNWDjtYrv4T9~RX6&3%jDn_E7CKCe)~ z8|1_fe1j^Rhtd6S7+qYp_#F-HYaa8AGgUZuY2-q1r~{)1 z-d-r+gzo;ulP6c!=^f2uyQlF!F>B8tT+~;WAWAWm)3f1;YlKfO#fBj~n>IF4qt}pi zx>;jU)zPv-21gcsgZ zwVu1wkp0PHppZPgq@2qHLp0FQMy zhk|8ZMQ1evp7~bSCsvyeuJ}MD`uIYS0WH95GAc|Lz`AI5r)MMc4)yiIF1dim{;=g_ zwr@=Qgs?G0KGk-~bc+9sFv-qd-GojHv0D{Otwa$!m)+T;?vP~gBW>lE?dmwGydp=? zXl#G%z5XoL=^8eqW_XV!e_LGXfs{sDD}Y{v&C`ilr;tfWL$+84wHMs0ts=1%QxhE$ z4oB6Yy@aTN#Ybfx`u6JcIhL|CcE$KDbZdiP`tS!I3EanBu}w;ihC8BDH>=(Q!Yj6-ZA>6$(1 z&5y*dgl|G^IpW`p&*x~V8am~XJ4wiFu^N_a|LS31tt9nd+^dL1#E%*~e9Hsbd2Cdq z*JVV>QNf4FA+-Vm)sg*Kv8vjPyQU5N*G%*0+qS0Pr_?GKiW)F<_)K#g-yCRDuZ@V} zCILhZ%=QvpoT&ccNkz&;$aa^4Q?|FBx`^1>xsmAO(=IWf< zlwQyFGs=6n$MU;Svwc3UbhY%!6R-E-i)(#%_zSqrJ2Ssh&nL+;ioLB`%4dz0QtITi z&hX-hMJM$m2=^Z-{<>x-vO{$8VQ%T6aAi$X$Fm3quu`ur}d0^3*xK3N*HPsdz_qkr4=x$Hd(E zSwEO^@eI#~)I{QG&CQ+_IYY-{KMfxz=02wIo@R;Q$3_A1cSgpH!JKA@6UhSqs& z{rAt%eZct;+ZF1C^p;%^y5)I;{JtYz-#8%u>tnvk*%VAyCalESD=oftMBKpjS{ z1T)F)?&FxzD&5)vOc+afn;iDVwN0cZuB5@$Na;c@l#uf89<*(wpXHMJai zPoaV<+}zpB=Y;vi500Y^dfAB>x4hLfo1Ji{^-9y-thB#^F3YGf)U=}df?u^~K$JBU zuuw7DPOR5ixv%&NC~yWTTar+Bk!|tr1^E^8Dt`;dHNQ|r-jyCvgU3d80zQ%6wDh=4 zKO&KnHvD&Ts_Uc+Q>~*FWCO(0VJyA2p{LQ}B6APHTt^UDn*QvK$aK|*Cd<;59-3!_ z%}Zn-c6dt*)so3MuY_(>tlsMI%~)t@iyxJEg%{&ihFIGzil!1&o#Va|JXPX*m8&Dc zSYj10krF}g$?FmnSd;u*p-S|buVweebB13e=~Pj#l~@+m?XBk=yX(o+)JOP;yQ4X|@hv?4${cN^M}%m#jTacsMz zl#UU7*^LcPy$tQQve+T*#sCij+rAuu;Q@=f))dK@RqwD|9} ztD*Y@&E_h%$0*#A`5Qo@Z4Ft9 z1Rt(ex0B0RJ(SqnqwI=z&+6%Y*S)J~W`|iQdkXJVtShO*Ekw3z}Fa z+ec}lL-Ql7ou(3nJ0w(wvym$pW^U)a-a4$r{w+5+vrAK$QFFv_<@-JZss;S1v&177 zp2+VLt^TCCVpJ}OQ4>PHK=q$h#siMWOO84o)}2_v1u73y{H9#Gl5M`j9rAVE1(yeN z)8)C}tu-pUDq-Y1AW=VV=Q@>7i9GTjyW}9*`fr?~Gh6mS->6OrIU>H3vyIGIODNa} zitZ#7p|ncqyzyI$K&^_p-dnDoJDBRmZ1IiMZXR;{oBWV`2JD_dSaIhvbvO{6ZQZ0x z{&Igg6+1j-ZBEWAI1@iqp%^H}tlS_FC=snkbs!N!brsBiRVZpYyE_HaHh>7MT8_{|Z%Ux$JPMx%-@?161LExBmg%tM6n+`o}Ub0jH42{!~w| zMaVcxM_>A~Zb8&P(zoaUW%RCuk-#9eK%&I(Dt)76+45zq^O!_T^RUq4uNR0tnpDsd z%qxDDYS91rfNjG@GGpWSKIBORoGM$?Wf2)DM#ZE?CVDyjaS4b^aT7dqoJVS^ zG@J>!I#lKw7TSH;pqbc$IMjWJgDQA~Dg!?AxlFCke9@yT|6R81usP||(_YYmY^rrx zmwqVj)ly{gEAnu;X0@SWh|xf|*3lbhwR$M`TE^5?S0bdZ-)i8^?zGQ7mopLgi~%CI{IU#7 z*mlowm%(&=D0amp;pMl8i0M1f`(?+u3*c~8Z~0lsHUPF*$!W0mVTSFA!?`JQeY z=;yupSpDKPZ;1~t4J&cCROBi&jB2dC4V`D9)4A8b79&1?*n@XNyPz{6@OKyTA9(DX z_9Q7Poh5?J4h`)Rl)Wn`ExuA`l&Q`}w$Q$K)&2SgJ5%64$2w}%IEUM6KQcX*ZbbLd z+;)s{l@1r;dy;ncD$P7KUBj`OO~%~fM^L_dBN;DV+X0)i*2)tr zZ8~1tNxn)ByY4e<1-BS&S=X@lfnpL6k0BoDfuLaZ?2{r^ua{}Y(kAGk{vf~j0jI(= ztDNEoyMkk)$hq%;w(u)&qE z!WbjY4g^S&$iEB!ezjJmd_MJK6Lr^S?lQ|iY0cdiJ%(E`{5(r*M6y zi#dXm@-Qr_EKO;@7pDBsd)Zg)c`H>-KlPgB)2AWG!TW1MeWQ>0gt4UyHfmO_r^gG` zEwRr6N$z9ji5E)aK0QG!>PQI~eKA2>cMQ^O8O_pI4W)nl*r=CRlO)P;h?3k4oMSV* ztgdJm=W{n^pDs7s)pp||)10uJ{N{qx&CI_$sz*E$qqJ`u%(AC;p_;ZU89>G%fcU&b z*Su7=zT(pEUB3ezD=cLBqREH{?G76@tUx_TusCREfvP1CcXTN%e_l6ok#$tBNdMtc zK^Nb2#mw?GG%|Ug5qc<7o59tP)O@$?FzAQtRhjK`y5$&pI7m&M3-4uaFG=o;g7VdS z`CaNL&ZFB{9o$c;6>{Xli}u5WhF<)KiM0pX*Q}aBj_QkB7)|LY`nKW=nVVkxn3WSI zjLzr1;M~DiI5JlM-pAeKT=xrT1-g)N@Xy3^B3>idEzOtX8rLgXfl z@E7Uoz~x;-x>rWfw-ii~*9D)UQGml$yE+Q86$cK?hsy;qhOGMjB-nrP(2O*btD%_M z2(_tGT6M<(mldJaud3Dq2jBcL1rh5^BSE#R>68;x2CVyU&;vg>xTIqVBB2s0=4 z|1TQsMPWCYR5oc-9^X*6PY?RVlMh0B|1=p0=KjA0>%;6FGr@KtHqFrA>2TSjKG?)( zFkN8R6Q++(M*{$@6uNJg9}`^OH8|RWHrJ`JY@C>XF35MisJ}^B{8KIEnGV+r6Ys>! z&`$VypUpFLQyB#zs>Timr+}Y%L0)iTUxeVlrE}BD{eSH%|33X_#Ddz>4Kp$GkD6bX zt3$8Z+R@k_Hz~HyO!3s#628;h<5^yNUy?7MY4>e*0~%n9m%zn7zBsw8Qw9t&#IAeD z$J318%$jl_fAsTL+w{>}_9W5N|ZIqvM>=GwulirriRP8mz=!H?WZ1z#^36PKY~^cPQANVF*e+_n`pf7SL?Y3FAwvgbbluAh zajOxV%;^-%M**)w#}iI(QWr0-6LU1c)P=@?`zcl7N0nI#<@PE~>OSyB8MK$6M&c1+ zK7DU)&QG>T*NZOlRazY9N8^iAWl5#Lb5+b-5!3KEzqSvPiA5 z7vAFu$LT_bSe;Ehf51nbT1ChR$0kEjn`7udh{F>V@=7?x7v+3mJ20SS|V166MOQ@F*CWn&9c!8 z62+Y{`@Vp$oZ#IE`RUCK>x}{X9&>E|Xn*;2{dmj|nyaN+)Cp(1NGI2R?{VbpZ)anZ zlur!2uZi6i%Z^i`ao=kR2?pxr_A zx)bq&K=Ce#~D>?78ARjED3T-{pHQ0N&dWdmM0*+XMAcFr5IASqf|D9iAXju7uf5h2bsz1y z`A+a4n%Bn~rmNb+^)HU@%#2m)Uf;1V5bo!2J2lRHHeVHtt!0DPY~7Be9|YoX4^C?4 z?UNsa8c`}`u}-J%?pK6~WG+8qfhUh7M%pD^Lu{GpS}@xE1v_dj@<3FS`j#r zDcr(1w7x#NFD0c^2+yX1v8fKdUb6uAwT3WSsjQ@&$fNW!l*{0~2H(ZY&D&7EED9H2 zgPwCPQxEC}zO{@QYN@;(8sjwbD^Y(q{q1OMh@(kq0d9QH5S<|vh5?iI_Jr*4{1{#8 zTem1--V$3-y!hVqgAxI}9D_I*Tb^{O{>3wR^NN?ZymyZb-2%G-JiksAcp`j)45Rof zzDfY{$e`w7VzPWr-!G$CcwYwfQE0T+hxo*_Cx-Y$=0uwD$TR?dJ|fPf-Lgyj;F??b z<`wD4gfH+>K+P*OHsN!zEGDBSL!YVqigfe^&A(r@aVJf(AKqOSH@v`3;(Ia#p{f6U zkcm7BvHsWa)!h-GhO(g4*aT%F!9|C`BXA7Rnbf#8nkkchs~nT)&kc(yNhZ4Jz~^JY zo=HxE1}?9Hi%nIyR(C$Uzx;9wNek3Ul3fSBe+}Zf03lvM_JKnid1;XiBPR#lixY5B zRqkh_-zoz+KJgW%*r8vJti>vVn{7R9RPQ|5m-p;6|d`xy3-I0 znvMHpMOaVIJtO3{kCt_c848DAK_b@U+b=W`qW(vZZk}7Y&})>PyPmvQpiVVuDhYf8 zto~<&Ayk4(`7k4(SjeT;u57$DMT(VpZpG30URPuG&2zECu9m>-*UeX=C)d8^?`k)7 zX#pR29Q@#BVQzcq?J=w+5NacE#rxy7Sm&;VYh&uY!=PH{yaQxhi2h*MMuZbA4rtqJ zP3XD|m!*0;+Z8%rfJje8H*zhaB()X8wqkOI~sO0yZ2uw z`$*FXWV;NY1k#~U{|h6;yXxjF;EC);;xUZq+7{N}sQVWWQ7hRRklF&v)CnM10Xv=J z(0~S*{ml^)$VM6n4sQOgddZvlQrpsTv{(=Si)ZnINxJcJuyeseVpJTu@@eHt+SR`~z(wYo&8FugB zu(c)B$Wh>54X=ZL8bD>uZSRevmx}LoRTTY}`Zu(5N3$Xp>EV0ueRRg$_V6uYmy>cC z0^e7}7ni`umOB=(^~uV^g7cI49a-2Q-k<-}vZ?9zM;Ar2ui*+NrnNN;*#&?Y?|HpI zeNYOM)7OrlpGt#H>k+K$^#quLFk{{J&LIjr`C+4tIPvA}Jz|&LIp1>jdgSRfYf1QG zXEnOo-$n@b7f&tw!Wa<{a^-mH9gT#WtRd7bt)V-rKckT$)IPJR=(M?QK<5Bh%h%O_ zbw6eUEBR=ZErn2Hroj6xFgY#KG~%YSVL+HKRN;AE*95+-#D9QMsQx#Kbg75eANc

jvPaI4z_^=}A9_E_uMiF7b=wmodB@k;0-?ao>YKZ@o+VmRVEhwlj^kyleBT^N7o@0dH1n zU4jp$_x>Gq$U@|)Yft==pB4B$xGDR>8}Xyo z(H&eUwP5P7_6@3@OS)C2VR?{;5q0I{^D^G7f`1Ki|`AgFV-{dJzuDNuPh^MgHfN5=YNSV)3H z^y#-_bjw+F2nTKBCErakj0Eb6HTnaiCHp z*RF^og+3_qpOl>PWyX>L0Tmf*u`V59rA7>6UsbyNxV+mCsq=!?d?6@o2_xE9aobkSnIty<3~x#I7d`oq={6v=`GbYdR*s zK-u`n$k;9h?ANNbwZKx_5m}$p+fmOSpCovbw|Z+6&7t0%(=X~+^9|aYZ8^y1NBOHG z*P7H|t$un#OP7=NeEOy?#J&(5awx?((N>BIFmR`>++FJSxNbju`b0gQ zpq}r+;e0362Y&Cf{ZfOevqydseO(^M$^k~d#kjZg$c^cFqrCB}ExCl$bhP!?Kb|}& zUxIciv%Q_2Ql{|{xcZfb>DHgB&s(l)ycL-IJ=AwHjJaRIOk`AZt|np<6I`4 zH<{x8jIAWd4--TN+HL;Dy9j=8RJgK28rG7YZIt%jViMpa&@IZqo*TVh^s|?qG(j?l z>Mf_{=;O(lPo~g~!U6KM!knPm)zh0b^_@x}h1piuj9q4Xes9XBoj8BXKKrfE|NfV8 zlr*S+hy06YGYLb(uw0Cb$j4t=K}uRgU4>F1u`hn2vc<0w~i_ydl!_H{edwe$nu1y3|aV3D;u;1z|C?HvFqAsDbc z|Lk;bxm6za{PWiD>WC%+!1};tVzmEO#A2671U(3F9avU8+E0fy)#bY7#s&yFyoz@;gsFC!nDWx}g zNMKbI!cnf>`);(VNnv+(LbVI5nGt{rQ@mhUDF7#m^e8uH?5d(UKFB`+ts!P6l^?(j z6}k?NlrOI+QggVbmXpr)oy|`6r9^%*nZ~^G020$t1}Toj7cKd^?ohss*Y?dG)fsM0 zw-jCz^hPbi<~uZRr9dzRw>3e{;_|+^kCQucV5we)$ccqdad>khQX{2JEEhYwg`3x+ zfx%H|o!n(u>O15$7U$}4z#*msHy7(lF>dq^rt5v=x@6qkEVts1y`C_2#w}ZtT{)CZ zWp(#HYBSnX9n6m2|6a2jNcNPr)jztMaZ_INK&ggyx;8>u=ksP1k=K_x z574;a>#lMHy0ow&o1MV7A*#idt7!f+ZEJqb#|#&j<*j8jh6Rhb>F(v5Mwd-BRl?zW z?;b~Z+e627MnQ9KdO#+`UU|}v6qhLDw`4X%@_bWfd{Gg)n^%uuYN{*sS z``yC*JyG8|I7-c7OXvVac?$~84`$h1%I#ioV4YD-yA6fQAcWEt{zZKA}Z8<^{A`l$;%6+&}bt&L#N_4M{tt~h*p5B{TU{QCMaeJk0Yz+oh@Teg0 z`KE+?e{xmEl9{fT9rncisp!s)~e*x6F<}DiQlq21JPpyYRISpPxps7E&wLi*1L1b?*uZ zE0nhdlD#2IuE{+Qq=+EwAeQK!!4t`@G{M2N42qO6(TtYO9nf=}z!G82uV)m^U24Zh3-Vaph(Yflm^(QA8hL=VH5`IkGQN}fkk&MYH#-#!)T z><)V>wuLDo46ms{1FV%YYs6Zq$gK*zQRG?a!ItrI=V?OreAJ3G*!Bcc_ZvU$xFhvU z^A3q_J=^~$s2G`xoLwj4{F++rvCk9&t#Lcs0F)A@VxuI&-?xdzklHVe!kaz-S>6hpX+m97tcyC8f$VLlqpa^ED`*`J4E`Y zo_;E}YRpf}!jir$+TH}W-~tXW5%oMP^BaZKCX=6R%1lY(Cstn524%q#b(J=)A|%la z2UGHkkvw5py1v=t#%9N-+KOVm1vp~VjjEMwxz?N%i0~wWW}Wb`!>o7u@1uJ`iLH-( z&QVl}>~iKSQ%J+|0tZW?z&h%rgN=DVbbcWyy7;h zMu17FCue!JbU%6sF2t1$)OMoO<)Vh&4kU=8*p;xP&kYM0plgYhPW4{^*z)&BykmGw=N5vJTNQR^Y>j@;Wf^f?-2 zsAas)coI37-u3pn^3W-e1D*PO$Rj&pYjh}WawvuMwZ!`g>6;|}-;QRLFr90nzj;*! z9BK79ajdktRz$JhgJJyA2!Xh*QlE3m=urb{Z~g!7X~Feozdx|FXtrdTf4IJ4TA?pR zVUS$b?A)!=zSI=tV?FyfNZ_$=D$ z{gq;Pl&hok&APtINfdIglJ4+~7*%Y=W0hOWc9iRnuOoJ;Q88l@T0kK)9h!9&|BSvH zMPzL}y?zI?vZ1iYD%MG{a%#~r$@##12e%olIp1lX_1AAySJ$XA7gl}-2RAk*j`&42 z99B!bfmzX4eLL0v!ucO5Y|zo%fMD)WLNUusa!aLdDQslTJTE-PFl}IX+{oMXD*K8% zVTf7;x#81)>0FD|_Lfm2I>)#A@=YHRhWHc>YGwALkO4Jfs?p_d1K)Abq) zGv-o8P@9Rb@tL6It-aFG4r{?KL1FYfp{gU-RueEX-(h2S6~)Kun^9xJ+oE4KeZIj% zW3|qR=6480lsKzQ^5A-!<%`DrxWAm%9<7KuB7M%OLK275AC(daz-p} z6I&sx)Vb_LX?@T(NIQ+7JN&wU{o{7C_3(cOmkjuF-sek@MvEvs)mNSfGTy!+KP@Er z8hl&B!~Fjb*Fg_hdZ0$}ZrMOy^Ld%uA`JXRwh}(cyrS~vO3D5vFqbcSz0MzrXN+x9 zd}ix=1U8N>c=Pj;f@qfkfx|PGI#n>E#$$|^m;1)uX>cC5Y0OU-9N~^z`Jyw)&!ouZ z7O<_aSqThQ1_y0WyT_8WUzqcq92j6^sS8A5RISvC&*V##~1LaWp>fsEUOk-|Gy9r4~AtA3a$f|}5A+}!>l9}m;{8Nouucew;iSn`D_=^_LfdNHk||yo7*laf65S z;|e=r9tp5VTMj2dqrBRclONQScnhoK#r=JGFLKY5_Vo2p6aDhyn)E7+o6I2(Yb{Wg ztWgNTGxQRSIkHTSNi37A$sWmj(J*J@$#eJ&zy>|FC5@Esu`Bk?pF+V;+o&KXS2lFY zZu)+-TEyB$Km&GEE0~Oq-?Y>|bU3Su@*Cda?5(qY^`@4a(`%C+&+d=7t-3*to2Y3q z>4Xton^vqYtIjMYaxUg6mj}c0*0LR-?*;IL`T&eUpXm5sD?tXV4aC7Z9K=MF0d}>H{UJ`a=Z`TF^oF z&dL_fjy@WZuS*UrzTEfv=iBZ$i#HLwoVxO(aO^M?`-oOr2hE?+i4zuMM=P%Aw;o=P z&zcx-K2^}!sAO)66Jac!htlUy8oSpIHy^tmkus~l8eXP;q{i=?dyH|BxA~tYPPOz=puaKG$L%lyg?Yqm&)qRJ`4+wKLKu z=#_N|JnO^sTEuC4OzpkABgO2?Ph{pwjN1o8J<#HLzLnW97(HgPWwcs;tioj2eHbRr zyc&`iZjc{k4&G204-hSBR<3GZ#t?C`V!YlPxITx0i)&e+hkNN5L$vrv`v_*oQ^8hq za{?t#P5fY^*-fxryIE->WVv#@$N3hs=5}$^8L=|9=59{>%klu@)s3i&G3%2U;5Fq#=UVlMT zKtGuEn=`*IcF4%mTWQQ#MNCKK#*vj&%e==wJU`rCk5LI%rkFXJshaH(r(W9u-U-8h zTnW@H9rbbIxEgW3IX1E3qoE}13Mo-(53{G(@70H4HT}xmB+oGx0OF++p2$kZiMObK z>c96PA};v&!AeQPHq{9oHJ!Pq4`y%bytK1|B&7U>={rw0m1frUce$V+WP6o{r$XS? zu7C@)-3*4ZOl`SHr$%2T{hm8JCpQ!m%eR%c4Qag)9pooUE-7N*3dJvCQV4yILq7iG zxt(?LMlrf<&K>N_Z|No~fB^VHt9^;pW*$DqiuC48mB>c8;1EG&X>|kj&f{?ltmFZc zMX-0NPV_sNeKW_%`^4!r#JT5jQ3ut|@Lom0@5jn%vfqG=o)7L8apnbS- z1LZ)EMT9@v`1njE<*bpUy!SwoW)e5TYMLu@o&M$fz^wkgLL;ygxU2f{Wh(>@U=8inRtA|mE=s#T>qRs(u>5OQFxr2R; z2v^MM*9(-~pk?A%(6M(ZnS$*wopgBcqFDZtQ+nUXI+@tDC}C#$;saii2cs)TUhf=L z61yGxCPGoo@R^P}&l%@Gm;5*q-I_RkxLwJujKr zixl|;@Z~SxM8&{-PF*hf0u30i_P;LYd*A&nNtbT^sar-m7 zD^xtbk~QlRcf1Rl-{BF#KmfqOt-bMn&3dLE+QS=tDzW63wmaJU+|DPhkpoU^U=d5a z2Kcazt(8bjxShAYx_?!U;uOUu1?>W~$mRS76qYlok%Jm{e#q!Dmqo>@of>C~3cGWc zFcYi&>;_XBXv38zH89?-C2e?$gyCmK)nngcD*GBy1XwSH56@|4K5~IXy6vT+%=XD) zt1iN`+}}iy_hNn-j^J+Ez-OcgZH^C=b|3ztc@E&EsVB*YX=Rl^K+7-I31o~vI)v9& ziACbX4-WJbmIuGD{($!ec<-RUuMo76@ML&^u#}*JttcN`cy$ukXKTg0t^rYWxd=?k z|7O=jHr_2AB%IP-aKqLyX<1+`I9VyQo?W5B9^5-Ka$GKJVWU0y_9ONdo;Yj!99ce) zzn8LbRra{W6?ai;9N_~L+h=~w&bh&wkMh{Kj zif#b6*S4J;_d&}zA1!Oa6%PG1?X}7DyM+B*Bp2buUWI4c8akmh_RGA?^AszdE0uEE z7X?9~zRY}9-heT-3)l^GqjInkjL9mB%Jv{|*E)(#Gt>qWdg~*bI#SPl1L^012bdLZ z{kPjaYH!sz6-2Rj8-*kD=*&2HN|Q7T-b*e^{?R)Go9&=%NqazhLOa8hfP}6-kHM66FQO2=3aQkk6rmxfX z@;$-fg@|W!C2`5KAgKxX(H+8$4{@e)NQ*kr#D2Mg1hotDX2!KTTHaI;GBw2EfUz7c zV8tp~G*681RNQlXEU6s_AN=*Me#>?OM4;hj1E<(H1j||D`w#QXlRnoaX(yPk3^fDR@sI@1s%a0BfW`U zAa{MAL=kfX`_aOZ>mdN_sv4g9WzodZt-SfG^}u6J7sbM=NWDsMUtvlV$3s^ zsWnL}PY|VU6+bu(c4>Hq3Z9h6s1K}buHPB!(S`;ejXVd&FzS;21|;qIc-Ou*Dk9ix zJl!`ZTfbSr&>q;_;;}Vm=~v#HmcQ4%)o61gGQi$v(M|bEdc*W1_4g`=1(0WNo@Eko zDNCfTX1_o7r7E(v)a66v4KvnQ5prK&$)K8%nf z-4o0sGMg+c9vWWX{vutR8LoCn^N;>X3x~%hUVhBwPrFB<)t!^U>mP|%tv>i`5bqLK zlMN3w0AjP!(V*ZX+RN3(_tS5$;b5Nu03PULd$~MM{hX)P9XSKS`!Ct}m=GaM&r=@U zGzHNTQx|=$GfZUkX(Xr3LCvxF@A&MPD$R$^tBUS2qtCMXw!Km3V_2EISpNb)--d)$ zfc+cPx!4B zbXtJoW++rkQ9_V~izt>wJg+Sp6ll|`I*+W(Eud;)#IDg(P%R~$fsrj^(aCdBl#Ui$ z5L9zt8;J0cFVbBN$n15De^&#gFZ8gT=)IQ0zoYR8J?oA@3iyw=$Z7Q{ngl%&snW(0(h+&pQ(Otnb8ke*jT`LKNbtYX9q zTd19K!1ph}G@DDbESsob%K+Oe#!su)!MHz^3lf2krs8ZU?6MYzwM@kKH6g^YUL==0 zonfQ&{nnk}nup7_H>55<5{Q5qk6yJW8)#gl$>=gz$%WuVU{>0pn2>=Hp(OqTSeVfa zSOQOK+?7;N@WDZf^Y%2B223*^dbf72caGV6yyV2=R29E7LsP!Jre!0tzzh~WhZ!du zX@?c4j~iBl04mZU4Q1;J&|QBWlc$8|$Uz*^ZH_vD!X@P~u0eHT(Ac-al`XYr(70b! zSC8vklkgHxx!##@(NDsKC~9L59p8SHVR<(F9@vjS(^utOpX}&#KNC!{yqpNEjrj`S zmOpUOkoc0*l@nUpYO1bzJ8`6LEk7suRYq^Te603a&ZOF|mI1&>(ZSI$MvtHbs&5zt zs19+r&$+D|wYp#8lM2uw>GlJGPPeAp`Ewdehl!f89!uzn88`-q-xojcxjh)L+V}eIP!b0T^zfLdEAcK%|u{zaneOugY#d6`|qXt8MxpF_ng4y zafmXuk56#dad=%I?TOaWyy5IIVa1Pm!PuMYmQ(77C&6}VWNhczVo3{Z3XncI#@2ZL zZm&!2u<5nQgA_Fc)&^+^w9 zsLuUONwM08Rh^Q`%y5YHR$H81N%&2iHXR~wG)J?bOIG_QifXr!y~n%tbmTREwUY4s zx7rcUvnK=rwE^}2WY)~)x*lKS1d^s{OB z&!79`$@tHp_Q8er!G!OUC;HsG@tHI4ktIY#MgRZ*0000000000000000000000000 z00000A^8LW001`tEC2ui0EYle000L6z?*PLEEb5$~`c$ z3a)r8ReZ5%+m_5M1k$!aflaRyB?CCxVMi9OdIx=jVhVYBXoN(6h&B<5Qw0K(0uKb2 zm;{spVSZ<55QkWhLJ*BM0i;U_2N40Er>6q}0R#^M2?THuH*aVOkP@+}szwPBu(8U^ zadW<-iUp!J4+v?*#XqP8C(FTM6b<@fv0fa?>6JcpqisCg$+MXf)uxva)AOeAsbr20m z($mJ1h}e)~5i}?&wIQa^gkglw4x)NRVm@^O%VtB7gNWLASRl>M8+wJ-;kIw+Nhf{N z7`>4g3rdr7Z^$jIprRcGdLiT-(v>U|vCwXq?bK(o4V!v_fz~*v(gD&(Oxu91L?5al zMEMZXyI4RProIt*UWYr)RwvvR1|LhPap;JP0qcQFyerctu*f$2TefY_dIi$PA+UL! z?3qm9gz0IsPsD}Lk8mQ6BrxqHmDA)ygLe=tb53DF9eqmV$KMmn*`S*!?IA=*S4PPk{s=P|I*btfoK$qEIJ+D+rWVL;+L)W`mhYOw-V7Vq!64OAv%%7BL2fl+%!YE*jDSZonZ%OM5{9$06|)ghitn{YC^m zrZ(auVN4o2raZ5T5tMFEG$O$>A|6IWOLjg3TqE2Op~q%XDkx8!12&T|MZ`(}>=1*JCYz5=RBOY8ObiN#0|i)kAV)P3As${sj(Nn8yY@RoOO!6* z+^kX9%U=P$`Z?rc1w=H{x%7qu2fd8GWZx8$j@yL8MTrIni7grBg|fN&g@hhPw4~_5 zUQNMj!bp(JPqjG_=0H#)4_fLC*cuTOY(*O};}K%oIdUV!!V#^;i5e3~YzDI%EKC{e`=voF;Bp?30IP2rc!@?()wuN+)LO~^kk;5*I0@B zW`!R7*#H5XlLa_TcPese#d<@?n;3jCwZ&N}W57d%15g#SS4H3<@{<~QW+$cqtb~DB z&`cBb(w{Owpi@dX1}z8x!4&}{0tYxB5nva92rR7t4*&=aj{rm=o=*V~palXVhXm6x z0D=^XB5@`m#VT6yidf8|7PrX7E_(5cU<{)e$4JI9n(>TiOrsjtC`ACc@r`hdqa5c* z$2!{o@s4=RqaI06hYg^h27nBtAO}gvLK^arh)kp+7s*IKVn78P7()s$&`3nm;F6fk zq$W4X$xeFmlbrNGB?*ZEK28AuqqHO_SINp&f>M;J6eI>VFa;B&vIMpyWF{xDfDllC zmkR*q2WYT>VA6mBAy~i(C{WB|P5_gK?o}FOMEWi1}6}K2H?4XONQVE-E062 zPH=+?T%ZD%bZ7+tN`nR{R0IVLryx`C$5hf13NVP}21wA(OD;eI6tKWE<4MekPGAE6 z3avm!JHSkZQh)-N>_9#naDj?yfCe1^=mc)i0UBt4pEtm02&S1yan^tXD~M$aqA-F= zvLKQ};6POaiAf4*0HNAsX)zm60hrR@2G7Lg0xr;id}h)D_&lpZhgwXuRurw?Tq_7R zDM}PzRR|j>K_yi{)lr(@qb?{XS1(C{4_KfAdljoZF8~6CYM`hzu)qfvP*!km^P!hS zC=G_1OuO>*12-sWH~9+45+GKwj3g`+RNzq|kaUo06~P2Ru+xGTQ=g(;>j@^H0bZ6B zqn~ZS2g(Y93s4{fH%KWyDR2Q1(4Ydvr7UX!$$>~lb(ATH!fhK_0uq$KwYgl3>}V^S zfe&=RqVH{hHhF7Mi)H|(7Ht4#Gmu~TQUC-EJ%K?rP~Bl#;H&c8E(=Itf)Q{4wu}5I z6t>Dp43yKtxOJt5H_S>{rWeDFM8Om`0O42ylEWxYu|`eY+P{i7y)3SQ0cK3&8r%5B lIL@(-cZ_2h#Mr@O;6Mum8{;Ay`N)YJL3r87
+ + + + + + +
+ Delivery address:
+ {loop type="order_address" name="delivery_address" id=$DELIVERY_ADDRESS} + {$FIRSTNAME} {$LASTNAME}
+ {$ADDRESS1}
+ {if $ADDRESS2 != ""}{$ADDRESS2}
{/if} + {if $ADDRESS3 != ""}{$ADDRESS3}
{/if} + {$CITY}
+ {$ZIPCODE}, {loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}
+ {/loop} +
+ Billing address:
+ {loop type="order_address" name="invoice_address" id=$INVOICE_ADDRESS} + {$FIRSTNAME} {$LASTNAME}
+ {$ADDRESS1}
+ {if $ADDRESS2 != ""}{$ADDRESS2}
{/if} + {if $ADDRESS3 != ""}{$ADDRESS3}
{/if} + {$CITY}
+ {$ZIPCODE}, {loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}
+ {/loop} +
+ +
+ +

+ Order Total: {$TOTAL_TAXED_AMOUNT} {$orderCurrencySymbol} {$orderCurrencyIsoCode}
+ Order Number: {$REF}
+ Paid With: {loop name="payment-module" type="module" id=$PAYMENT_MODULE}{$TITLE}{/loop}
+ Purchase Date: {format_date date=$CREATE_DATE output="date"}
+ Delivery method: {loop name="delivery-module" type="module" id=$DELIVERY_MODULE}{$TITLE}{/loop}
+

+ + + + + + + {loop type="order_product" name="order-products" order=$ID} + {if $WAS_IN_PROMO == 1} + {assign "realPrice" $PROMO_PRICE} + {assign "realTax" $PROMO_PRICE_TAX} + {assign "realTaxedPrice" $TAXED_PROMO_PRICE} + {else} + {assign "realPrice" $PRICE} + {assign "realTax" $PRICE_TAX} + {assign "realTaxedPrice" $TAXED_PRICE} + {/if} + + + + + {/loop} + + + + + + + + + + + + +
What You PurchasedPrice in {$orderCurrencyIsoCode}
+ {$TITLE} ({$REF}) + {ifloop rel="combinations"}
+ {loop type="order_product_attribute_combination" name="combinations" order_product=$ID} + * {$ATTRIBUTE_TITLE}: {$ATTRIBUTE_AVAILABILITY_TITLE} + {/loop} + {/ifloop} +
+ {$QUANTITY} x {$realTaxedPrice} {$orderCurrencySymbol} +
Total{$TOTAL_TAXED_AMOUNT - $POSTAGE} {$orderCurrencySymbol}
Shipping:{$POSTAGE} {$orderCurrencySymbol}
Order Total{$TOTAL_TAXED_AMOUNT} {$orderCurrencySymbol}
+ {/loop} + +
+ +

Support

+ For any questions, or concerns, feel free to contact support@yourdomain.com.

+ Our contact us at:
+ Thelia V2
+ Street name of my business
+ City
+ 75000, France + +
+
+ Thanks,
+ The Thelia V2 team +{/block} diff --git a/templates/frontOffice/default/email/password-reset.html b/templates/frontOffice/default/email/password-reset.html new file mode 100644 index 000000000..0ff8c1553 --- /dev/null +++ b/templates/frontOffice/default/email/password-reset.html @@ -0,0 +1,21 @@ +{extends file="email/template.tpl"} + +{* Open in browser *} +{block name="email-browsers"}{/block} + +{* Subject *} +{block name="email-subject"}Thelia V2 password reset confirmation{/block} + +{* Title *} +{block name="email-title"}Password Reset{/block} + +{* Content *} +{block name="email-content"} + Hi there,

+ There was recently a request to change the password on your account.

+ If you requested this password change, please set a new password by following the link below:

+ __SITE__/forgot?forgot_key=5e20f225cedd08a3

+ If you don't want to change your password, just ignore this message.

+ Thanks,
+ - The Thelia V2 Team +{/block} diff --git a/templates/frontOffice/default/email/password.html b/templates/frontOffice/default/email/password.html new file mode 100644 index 000000000..ef58e0873 --- /dev/null +++ b/templates/frontOffice/default/email/password.html @@ -0,0 +1,21 @@ +{extends file="email/template.tpl"} + +{* Open in browser *} +{block name="email-browsers"}{/block} + +{* Subject *} +{block name="email-subject"}Your password for Thelia V2{/block} + +{* Title *} +{block name="email-title"}Password{/block} + +{* Content *} +{block name="email-content"} + Hi there,

+ You have requested a new password for your Thelia V2 account.

+ Your new password is:
+ __PASSWORD__

+ You can change your password in your user account by opening the "Change my password" link under your personal information.

+ Kind regards,
+ - The Thelia V2 Team +{/block} diff --git a/templates/frontOffice/default/email/register.html b/templates/frontOffice/default/email/register.html new file mode 100644 index 000000000..41b03418c --- /dev/null +++ b/templates/frontOffice/default/email/register.html @@ -0,0 +1,42 @@ +{extends file="email/template.tpl"} + +{* Open in browser *} +{block name="email-browsers"}{/block} + +{* Subject *} +{block name="email-subject"}Welcome to Thelia V2{/block} + +{* Title *} +{block name="email-title"}Welcome to Thelia V2{/block} + +{* Content *} +{block name="email-content"} + {assign var="customerId" value="1"} + + +

Congratulations! You have successfully created an account on Thelia v2 demo site. Keep this email as a reference of your account details, and helpful links.

+ +
+ +

Accessing Your Account:

+ Login at: {url path="/login"}
+ {loop type="customer" name="customer.info" id=$customerId} + Username: {$EMAIL}
+ Password: __MOTDEPASSE__
+ {/loop} +
+
+ +

Support

+ For any questions, or concerns, feel free to contact support@yourdomain.com.
+ +
+ Learn more about Thelia V2.
+ Our site: http://thelia.net/v2
+ Twitter: http://twitter.com/theliaecommerce
+ Facebook: http://www.facebook.com/theliaecommerce +
+
+ Thanks,
+ - The Thelia V2 Team +{/block} diff --git a/templates/frontOffice/default/email/template.tpl b/templates/frontOffice/default/email/template.tpl new file mode 100644 index 000000000..53eea9b00 --- /dev/null +++ b/templates/frontOffice/default/email/template.tpl @@ -0,0 +1,485 @@ +{assign var="url_site" value="{config key="url_site"}"} +{assign var="company_name" value="{config key="company_name"}"} +{if not $company_name} + {assign var="company_name" value="{intl l='Thelia V2'}"} +{/if} + + + + + +{block name="email-subject"}{/block} + + + +
+ + + + +
+ + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+ {block name="email-intro"}{intl l="Welcome to Thelia. This is a demo site built with Thelia V2 an E-Commerce solution based on Symfony 2."}{/block} + + {block name="browser"}{intl l="Email not displaying correctly?"}
{intl l="View it in your browser"}.{/block} +
+
+
+ + + + +
+ + + + +
+ {images file='../assets/img/email/logo.gif'}{$company_name}{/images} +
+
+
+ + + + +
+ + + + + + + +
+ + + + +
+ {block name="email-title"}{/block} +
+
+ + + + + + + + {* button + + + *} +
+ {images file='../assets/img/email/header.jpg'}{/images} +
+ {block name="email-content"}{/block} +
+ + + + +
+ Link Button +
+
+
+
+
+ + + + +
+ + + + + + + + {* Unsubscribe + + + *} +
+ Follow on Twitter   Friend on Facebook  +
+ {intl l="Our mailing address is:"} +
+ Street name of my business 75000 City, France +
+
+ {intl l="Copyright"} © {'Y'|date} {$company_name}, {intl l="All rights reserved."} +
+ unsubscribe from this list   update subscription preferences  +
+
+ *|IF:REWARDS|* *|HTML:REWARDS|* *|END:IF|* +
+
+
+
+
+ + \ No newline at end of file From 33e0a854f276da195c83d549bff9c9bce61c3213 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Tue, 26 Nov 2013 19:20:45 +0100 Subject: [PATCH 2/3] Implemented mail messages templates and layouts --- core/lib/Thelia/Action/Message.php | 6 + core/lib/Thelia/Action/Order.php | 32 +- .../Admin/AbstractCrudController.php | 4 +- .../Controller/Admin/MessageController.php | 57 ++- .../Admin/TranslationsController.php | 8 +- .../Compiler/RegisterRouterPass.php | 6 +- .../Core/Event/Message/MessageUpdateEvent.php | 57 ++- core/lib/Thelia/Core/Template/Loop/Module.php | 2 +- .../Thelia/Core/Template/Loop/Template.php | 2 +- .../Core/Template/Smarty/Plugins/Module.php | 2 +- .../Core/Template/Smarty/SmartyParser.php | 46 ++- .../Core/Template/TemplateDefinition.php | 25 +- .../Thelia/Core/Template/TemplateHelper.php | 10 + core/lib/Thelia/Core/Thelia.php | 16 +- .../Thelia/Form/MessageModificationForm.php | 49 ++- core/lib/Thelia/Model/Base/Message.php | 288 +++++++++++++-- core/lib/Thelia/Model/Base/MessageQuery.php | 134 ++++++- core/lib/Thelia/Model/Base/MessageVersion.php | 280 +++++++++++++-- .../Thelia/Model/Base/MessageVersionQuery.php | 134 ++++++- core/lib/Thelia/Model/Base/Product.php | 72 ++++ core/lib/Thelia/Model/Base/ProductI18n.php | 176 ++++++++- .../Thelia/Model/Base/ProductI18nQuery.php | 101 +++++- core/lib/Thelia/Model/Map/MessageTableMap.php | 60 +++- .../Model/Map/MessageVersionTableMap.php | 64 +++- .../Thelia/Model/Map/ProductI18nTableMap.php | 52 ++- core/lib/Thelia/Model/Map/ProductTableMap.php | 2 +- core/lib/Thelia/Model/Message.php | 97 ++++- core/lib/Thelia/Model/Module.php | 23 +- core/lib/Thelia/Tests/Model/Message.php | 337 ++++++++++++++++++ install/insert.sql | 1 + install/thelia.sql | 11 + local/config/schema.xml | 9 +- .../default/assets/less/thelia/forms.less | 9 +- .../backOffice/default/message-edit.html | 160 +++++++-- templates/backOffice/default/messages.html | 8 +- templates/email/default/README | 71 ++++ .../email/default/default-html-layout.tpl | 10 + .../email/default/default-text-layout.tpl | 10 + .../email/default/order_confirmation.html | 107 ++++++ .../email/default/order_confirmation.txt | 40 +++ 40 files changed, 2377 insertions(+), 201 deletions(-) create mode 100644 core/lib/Thelia/Tests/Model/Message.php create mode 100644 templates/email/default/README create mode 100644 templates/email/default/default-html-layout.tpl create mode 100644 templates/email/default/default-text-layout.tpl create mode 100644 templates/email/default/order_confirmation.html create mode 100644 templates/email/default/order_confirmation.txt diff --git a/core/lib/Thelia/Action/Message.php b/core/lib/Thelia/Action/Message.php index fa9b13db5..4b85c7ca9 100644 --- a/core/lib/Thelia/Action/Message.php +++ b/core/lib/Thelia/Action/Message.php @@ -82,9 +82,15 @@ class Message extends BaseAction implements EventSubscriberInterface ->setTitle($event->getTitle()) ->setSubject($event->getSubject()) + ->setHtmlMessage($event->getHtmlMessage()) ->setTextMessage($event->getTextMessage()) + ->setHtmlLayoutFileName($event->getHtmlLayoutFileName()) + ->setHtmlTemplateFileName($event->getHtmlTemplateFileName()) + ->setTextLayoutFileName($event->getTextLayoutFileName()) + ->setTextTemplateFileName($event->getTextTemplateFileName()) + ->save(); $event->setMessage($message); diff --git a/core/lib/Thelia/Action/Order.php b/core/lib/Thelia/Action/Order.php index 78ebb94d6..0699c14d1 100755 --- a/core/lib/Thelia/Action/Order.php +++ b/core/lib/Thelia/Action/Order.php @@ -288,8 +288,18 @@ class Order extends BaseAction implements EventSubscriberInterface */ public function sendOrderEmail(OrderEvent $event) { - $store_email = ConfigQuery::read('store_email'); - if($store_email) { + $contact_email = ConfigQuery::read('contact_email'); + + if($contact_email) { + + $message = MessageQuery::create() + ->filterByName('order_confirmation') + ->findOne(); + + if (false === $message) { + throw new \Exception("Failed to load message 'order_confirmation'."); + } + $order = $event->getOrder(); $customer = $order->getCustomer(); @@ -298,24 +308,16 @@ class Order extends BaseAction implements EventSubscriberInterface $parser->assign('order_id', $order->getId()); $parser->assign('order_ref', $order->getRef()); - $message = MessageQuery::create() - ->filterByName('order_confirmation') - ->findOne(); - $message ->setLocale($order->getLang()->getLocale()); - $subject = $parser->fetch(sprintf("string:%s", $message->getSubject())); - $htmlMessage = $parser->fetch(sprintf("string:%s", $message->getHtmlMessage())); - $textMessage = $parser->fetch(sprintf("string:%s", $message->getTextMessage())); - - $instance = \Swift_Message::newInstance($subject) + $instance = \Swift_Message::newInstance() ->addTo($customer->getEmail(), $customer->getFirstname()." ".$customer->getLastname()) - ->addFrom($store_email, ConfigQuery::read('store_name')) + ->addFrom(ConfigQuery::read('contact_email'), ConfigQuery::read('company_name')) ; - $instance - ->setBody($htmlMessage, 'text/html') - ->addPart($textMessage, 'text/plain'); + + // Build subject and body + $message->build($parser, $instance); $mail = $this->getMailer()->send($instance); } diff --git a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php index 11ed4fc50..dd6d19bcd 100644 --- a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php +++ b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php @@ -411,9 +411,9 @@ abstract class AbstractCrudController extends BaseAdminController } catch (FormValidationException $ex) { // Form cannot be validated $error_msg = $this->createStandardFormValidationErrorMessage($ex); - } catch (\Exception $ex) { + /*} catch (\Exception $ex) { // Any other error - $error_msg = $ex->getMessage(); + $error_msg = $ex->getMessage();*/ } $this->setupFormErrorContext( diff --git a/core/lib/Thelia/Controller/Admin/MessageController.php b/core/lib/Thelia/Controller/Admin/MessageController.php index 407578a08..fe8b655c7 100644 --- a/core/lib/Thelia/Controller/Admin/MessageController.php +++ b/core/lib/Thelia/Controller/Admin/MessageController.php @@ -30,6 +30,9 @@ use Thelia\Core\Event\Message\MessageCreateEvent; use Thelia\Model\MessageQuery; use Thelia\Form\MessageModificationForm; use Thelia\Form\MessageCreationForm; +use Symfony\Component\Finder\Finder; +use Thelia\Model\ConfigQuery; +use Thelia\Core\Template\TemplateHelper; /** * Manages messages sent by mail @@ -90,6 +93,10 @@ class MessageController extends AbstractCrudController ->setLocale($formData["locale"]) ->setTitle($formData['title']) ->setSubject($formData['subject']) + ->setHtmlLayoutFileName($formData['html_layout_file_name']) + ->setHtmlTemplateFileName($formData['html_template_file_name']) + ->setTextLayoutFileName($formData['text_layout_file_name']) + ->setTextTemplateFileName($formData['text_template_file_name']) ->setHtmlMessage($formData['html_message']) ->setTextMessage($formData['text_message']) ; @@ -111,14 +118,19 @@ class MessageController extends AbstractCrudController { // Prepare the data that will hydrate the form $data = array( - 'id' => $object->getId(), - 'name' => $object->getName(), - 'secured' => $object->getSecured(), - 'locale' => $object->getLocale(), - 'title' => $object->getTitle(), - 'subject' => $object->getSubject(), - 'html_message' => $object->getHtmlMessage(), - 'text_message' => $object->getTextMessage() + 'id' => $object->getId(), + 'name' => $object->getName(), + 'secured' => $object->getSecured(), + 'locale' => $object->getLocale(), + 'title' => $object->getTitle(), + 'subject' => $object->getSubject(), + 'html_message' => $object->getHtmlMessage(), + 'text_message' => $object->getTextMessage(), + + 'html_layout_file_name' => $object->getHtmlLayoutFileName(), + 'html_template_file_name' => $object->getHtmlTemplateFileName(), + 'text_layout_file_name' => $object->getTextLayoutFileName(), + 'text_template_file_name' => $object->getTextTemplateFileName(), ); // Setup the object form @@ -152,17 +164,36 @@ class MessageController extends AbstractCrudController return $this->render('messages'); } + protected function listDirectoryContent($requiredExtension) { + + $list = array(); + + $dir = TemplateHelper::getInstance()->getActiveMailTemplate()->getAbsolutePath(); + + $finder = Finder::create()->files()->in($dir)->ignoreDotFiles(true)->sortByName()->name("*.$requiredExtension"); + + foreach ($finder as $file) { + $list[] = $file->getBasename(); + } + + return $list; + } + protected function renderEditionTemplate() { - return $this->render('message-edit', array('message_id' => $this->getRequest()->get('message_id'))); + return $this->render('message-edit', array( + 'message_id' => $this->getRequest()->get('message_id'), + 'layout_list' => $this->listDirectoryContent('tpl'), + 'html_template_list' => $this->listDirectoryContent('html'), + 'text_template_list' => $this->listDirectoryContent('txt'), + )); } protected function redirectToEditionTemplate() { - $this->redirectToRoute( - "admin.configuration.messages.update", - array('message_id' => $this->getRequest()->get('message_id')) - ); + $this->redirectToRoute("admin.configuration.messages.update", array( + 'message_id' => $this->getRequest()->get('message_id') + )); } protected function redirectToListTemplate() diff --git a/core/lib/Thelia/Controller/Admin/TranslationsController.php b/core/lib/Thelia/Controller/Admin/TranslationsController.php index 04fc065b5..7bea68e6f 100644 --- a/core/lib/Thelia/Controller/Admin/TranslationsController.php +++ b/core/lib/Thelia/Controller/Admin/TranslationsController.php @@ -71,8 +71,8 @@ class TranslationsController extends BaseAdminController case 'mo' : if (null !== $module = ModuleQuery::create()->findPk($item_id)) { - $directory = THELIA_MODULE_DIR . $module->getBaseDir(); - $i18n_directory = THELIA_TEMPLATE_DIR . $module->getI18nPath(); + $directory = $module->getAbsoluteBaseDir(); + $i18n_directory = $module->getAbsoluteI18nPath(); $walkMode = TemplateHelper::WALK_MODE_PHP; } break; @@ -97,8 +97,8 @@ class TranslationsController extends BaseAdminController } if ($template) { - $directory = THELIA_TEMPLATE_DIR . $template->getPath(); - $i18n_directory = THELIA_TEMPLATE_DIR . $template->getI18nPath(); + $directory = $template->getAbsolutePath(); + $i18n_directory = $template->getAbsoluteI18nPath(); } // Load strings to translate diff --git a/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php b/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php index f92b7bf3d..845a659d2 100755 --- a/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php +++ b/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php @@ -68,12 +68,14 @@ class RegisterRouterPass implements CompilerPassInterface foreach ($modules as $module) { $moduleBaseDir = $module->getBaseDir(); - if (file_exists(THELIA_MODULE_DIR . "/" . $moduleBaseDir . "/Config/routing.xml")) { + $routingConfigFilePath = $module->getAbsoluteBaseDir() . DS . "Config" . DS . "routing.xml"; + + if (file_exists($routingConfigFilePath)) { $definition = new Definition( $container->getParameter("router.class"), array( new Reference("router.module.xmlLoader"), - $moduleBaseDir . "/Config/routing.xml", + $routingConfigFilePath, array( "cache_dir" => $container->getParameter("kernel.cache_dir"), "debug" => $container->getParameter("kernel.debug"), diff --git a/core/lib/Thelia/Core/Event/Message/MessageUpdateEvent.php b/core/lib/Thelia/Core/Event/Message/MessageUpdateEvent.php index 858a668b8..6630b7c13 100644 --- a/core/lib/Thelia/Core/Event/Message/MessageUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/Message/MessageUpdateEvent.php @@ -22,13 +22,18 @@ /*************************************************************************************/ namespace Thelia\Core\Event\Message; - use Thelia\Core\Event\Message\MessageCreateEvent; class MessageUpdateEvent extends MessageCreateEvent { protected $message_id; + protected $html_layout_file_name; + protected $html_template_file_name; + + protected $text_layout_file_name; + protected $text_template_file_name; + protected $text_message; protected $html_message; protected $subject; @@ -85,4 +90,52 @@ class MessageUpdateEvent extends MessageCreateEvent return $this; } -} + + public function getHtmlLayoutFileName() + { + return $this->html_layout_file_name; + } + + public function setHtmlLayoutFileName($html_layout_file_name) + { + $this->html_layout_file_name = $html_layout_file_name; + + return $this; + } + + public function getHtmlTemplateFileName() + { + return $this->html_template_file_name; + } + + public function setHtmlTemplateFileName($html_template_file_name) + { + $this->html_template_file_name = $html_template_file_name; + + return $this; + } + + public function getTextLayoutFileName() + { + return $this->text_layout_file_name; + } + + public function setTextLayoutFileName($text_layout_file_name) + { + $this->text_layout_file_name = $text_layout_file_name; + + return $this; + } + + public function getTextTemplateFileName() + { + return $this->text_template_file_name; + } + + public function setTextTemplateFileName($text_template_file_name) + { + $this->text_template_file_name = $text_template_file_name; + + return $this; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Loop/Module.php b/core/lib/Thelia/Core/Template/Loop/Module.php index 9815faf7e..0b10517b2 100755 --- a/core/lib/Thelia/Core/Template/Loop/Module.php +++ b/core/lib/Thelia/Core/Template/Loop/Module.php @@ -165,7 +165,7 @@ class Module extends BaseI18nLoop implements PropelSearchLoopInterface /* if not ; test if it uses admin inclusion : module_configuration.html */ if(false === $hasConfigurationInterface) { - if(file_exists( sprintf("%s/%s/AdminIncludes/%s.html", THELIA_MODULE_DIR, $module->getBaseDir(), "module_configuration"))) { + if(file_exists( sprintf("%s/AdminIncludes/%s.html", $module->getAbsoluteBaseDir(), "module_configuration"))) { $hasConfigurationInterface = true; } } diff --git a/core/lib/Thelia/Core/Template/Loop/Template.php b/core/lib/Thelia/Core/Template/Loop/Template.php index 7560926d8..c5b6a95f3 100644 --- a/core/lib/Thelia/Core/Template/Loop/Template.php +++ b/core/lib/Thelia/Core/Template/Loop/Template.php @@ -93,7 +93,7 @@ class Template extends BaseLoop implements ArraySearchLoopInterface $loopResultRow ->set("NAME" , $template->getName()) ->set("RELATIVE_PATH" , $template->getPath()) - ->set("ABSOLUTE_PATH" , THELIA_TEMPLATE_DIR . $template->getPath()) + ->set("ABSOLUTE_PATH" , $template->getAbsolutePath()) ; $loopResult->addRow($loopResultRow); diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php index 2340537db..4d1ed3060 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php @@ -54,7 +54,7 @@ class Module extends AbstractSmartyPlugin continue; } - $file = sprintf("%s/%s/AdminIncludes/%s.html", THELIA_MODULE_DIR, $module->getBaseDir(), $location); + $file = sprintf("%s/AdminIncludes/%s.html", $module->getAbsoluteBaseDir(), $location); if (file_exists($file)) { $content .= file_get_contents($file); diff --git a/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php b/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php index 53cedbede..2e52e21e0 100755 --- a/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php +++ b/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php @@ -16,6 +16,7 @@ use Thelia\Core\Template\ParserContext; use Thelia\Core\Template\TemplateDefinition; use Thelia\Model\ConfigQuery; use Thelia\Core\Template\TemplateHelper; +use Thelia\Core\Translation\Translator; /** * @@ -125,10 +126,10 @@ class SmartyParser extends Smarty implements ParserInterface $this->setTemplateDir(array()); /* add main template directory */ - $this->addTemplateDir(THELIA_TEMPLATE_DIR . $this->template, 0); + $this->addTemplateDir($templateDefinition->getAbsolutePath(), 0); /* define config directory */ - $configDirectory = THELIA_TEMPLATE_DIR . $this->template . '/configs'; + $configDirectory = $templateDefinition->getAbsoluteConfigPath(); $this->setConfigDir($configDirectory); /* add modules template directories */ @@ -165,17 +166,16 @@ class SmartyParser extends Smarty implements ParserInterface } /** - * Return a rendered template file + * Return a rendered template, either from file or ftom a string * - * @param string $realTemplateName the template name (from the template directory) + * @param string $resourceType either 'string' (rendering from a string) or 'file' (rendering a file) + * @param string $resourceContent the resource content (a text, or a template file name) * @param array $parameters an associative array of names / value pairs + * * @return string the rendered template text */ - public function render($realTemplateName, array $parameters = array()) + protected function internalRenderer($resourceType, $resourceContent, array $parameters) { - if(false === $this->templateExists($realTemplateName)) { - throw new ResourceNotFoundException(); - } // Assign the parserContext variables foreach ($this->parserContext as $var => $value) { $this->assign($var, $value); @@ -183,7 +183,35 @@ class SmartyParser extends Smarty implements ParserInterface $this->assign($parameters); - return $this->fetch(sprintf("file:%s", $realTemplateName)); + return $this->fetch(sprintf("%s:%s", $resourceType, $resourceContent)); + } + + + /** + * Return a rendered template file + * + * @param string $realTemplateName the template name (from the template directory) + * @param array $parameters an associative array of names / value pairs + * @return string the rendered template text + */ + public function render($realTemplateName, array $parameters = array()) { + + if(false === $this->templateExists($realTemplateName)) { + throw new ResourceNotFoundException(Translator::getInstance()->trans("Template file %file cannot be found.", array('%file', $realTemplateName))); + } + + return $this->internalRenderer('file', $realTemplateName, $parameters); + } + + /** + * Return a rendered template text + * + * @param string $templateText the template text + * @param array $parameters an associative array of names / value pairs + * @return string the rendered template text + */ + public function renderString($templateText, array $parameters = array()) { + return $this->internalRenderer('string', $templateText, $parameters); } /** diff --git a/core/lib/Thelia/Core/Template/TemplateDefinition.php b/core/lib/Thelia/Core/Template/TemplateDefinition.php index 7fa05c7cb..14dcdca93 100644 --- a/core/lib/Thelia/Core/Template/TemplateDefinition.php +++ b/core/lib/Thelia/Core/Template/TemplateDefinition.php @@ -28,10 +28,12 @@ class TemplateDefinition const FRONT_OFFICE = 1; const BACK_OFFICE = 2; const PDF = 3; + const EMAIL = 4; const FRONT_OFFICE_SUBDIR = 'frontOffice/'; const BACK_OFFICE_SUBDIR = 'backOffice/'; const PDF_SUBDIR = 'pdf/'; + const EMAIL_SUBDIR = 'email/'; /** * @var the template directory name (e.g. 'default') @@ -64,6 +66,9 @@ class TemplateDefinition case TemplateDefinition::PDF: $this->path = self::PDF_SUBDIR . $name; break; + case TemplateDefinition::EMAIL: + $this->path = self::EMAIL_SUBDIR . $name; + break; default: $this->path = $name; break; @@ -85,11 +90,28 @@ class TemplateDefinition return $this->getPath() . DS . 'I18n'; } + public function getAbsoluteI18nPath() { + return THELIA_TEMPLATE_DIR . $this->getI18nPath(); + } + public function getPath() { return $this->path; } + public function getAbsolutePath() { + return THELIA_TEMPLATE_DIR . $this->getPath(); + } + + public function getConfigPath() + { + return $this->getPath() . DS . 'configs'; + } + + public function getAbsoluteConfigPath() { + return THELIA_TEMPLATE_DIR . $this->getConfigPath(); + } + public function setPath($path) { $this->path = $path; @@ -106,5 +128,4 @@ class TemplateDefinition $this->type = $type; return $this; } - -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/TemplateHelper.php b/core/lib/Thelia/Core/Template/TemplateHelper.php index 3310b5f04..4f33e1a42 100644 --- a/core/lib/Thelia/Core/Template/TemplateHelper.php +++ b/core/lib/Thelia/Core/Template/TemplateHelper.php @@ -46,6 +46,16 @@ class TemplateHelper return self::$instance; } + /** + * @return TemplateDefinition + */ + public function getActiveMailTemplate() { + return new TemplateDefinition( + ConfigQuery::read('active-mail-template', 'default'), + TemplateDefinition::EMAIL + ); + } + /** * @return TemplateDefinition */ diff --git a/core/lib/Thelia/Core/Thelia.php b/core/lib/Thelia/Core/Thelia.php index 49647f4c9..e5fc0cd75 100755 --- a/core/lib/Thelia/Core/Thelia.php +++ b/core/lib/Thelia/Core/Thelia.php @@ -145,15 +145,15 @@ class Thelia extends Kernel $code = ucfirst($module->getCode()); - $loader = new XmlFileLoader($container, new FileLocator(THELIA_MODULE_DIR . "/" . $code . "/Config")); + $loader = new XmlFileLoader($container, new FileLocator($module->getAbsoluteConfigPath())); $loader->load("config.xml"); - if (is_dir($dir = THELIA_MODULE_DIR . "/" . $code . "/I18n")) { + if (is_dir($dir = $module->getAbsoluteI18nPath())) { $translationDirs[] = $dir; } /* is there a front-office template directory ? */ - $frontOfficeModuleTemplateDirectory = sprintf("%s%s%stemplates%s%s", THELIA_MODULE_DIR, $code, DS, DS, TemplateDefinition::FRONT_OFFICE_SUBDIR); + $frontOfficeModuleTemplateDirectory = sprintf("%s%stemplates%s%s", $module->getAbsoluteBaseDir(), DS, DS, TemplateDefinition::FRONT_OFFICE_SUBDIR); if (is_dir($frontOfficeModuleTemplateDirectory)) { try { $moduleFrontOfficeTemplateBrowser = new \DirectoryIterator($frontOfficeModuleTemplateDirectory); @@ -178,7 +178,7 @@ class Thelia extends Kernel } /* is there a back-office template directory ? */ - $backOfficeModuleTemplateDirectory = sprintf("%s%s%stemplates%s%s", THELIA_MODULE_DIR, $code, DS, DS, TemplateDefinition::BACK_OFFICE_SUBDIR); + $backOfficeModuleTemplateDirectory = sprintf("%s%stemplates%s%s", $module->getAbsoluteBaseDir(), DS, DS, TemplateDefinition::BACK_OFFICE_SUBDIR); if (is_dir($backOfficeModuleTemplateDirectory)) { try { $moduleBackOfficeTemplateBrowser = new \DirectoryIterator($backOfficeModuleTemplateDirectory); @@ -210,18 +210,20 @@ class Thelia extends Kernel //core translation $translationDirs[] = THELIA_ROOT . "core/lib/Thelia/Config/I18n"; + $th = TemplateHelper::getInstance(); + // admin template - if (is_dir($dir = THELIA_TEMPLATE_DIR . TemplateHelper::getInstance()->getActiveAdminTemplate()->getI18nPath())) { + if (is_dir($dir = $th->getActiveAdminTemplate()->getAbsoluteI18nPath())) { $translationDirs[] = $dir; } // front template - if (is_dir($dir = THELIA_TEMPLATE_DIR . TemplateHelper::getInstance()->getActiveFrontTemplate()->getI18nPath())) { + if (is_dir($dir = $th->getActiveFrontTemplate()->getAbsoluteI18nPath())) { $translationDirs[] = $dir; } // PDF template - if (is_dir($dir = THELIA_TEMPLATE_DIR . TemplateHelper::getInstance()->getActivePdfTemplate()->getI18nPath())) { + if (is_dir($dir = $th->getActivePdfTemplate()->getAbsoluteI18nPath())) { $translationDirs[] = $dir; } diff --git a/core/lib/Thelia/Form/MessageModificationForm.php b/core/lib/Thelia/Form/MessageModificationForm.php index c22d67bbf..231c605b8 100644 --- a/core/lib/Thelia/Form/MessageModificationForm.php +++ b/core/lib/Thelia/Form/MessageModificationForm.php @@ -34,10 +34,11 @@ class MessageModificationForm extends BaseForm ->add("id" , "hidden", array("constraints" => array(new GreaterThan(array('value' => 0))))) ->add("name" , "text" , array( "constraints" => array(new NotBlank()), - "label" => Translator::getInstance()->trans('Name *'), + "label" => Translator::getInstance()->trans('Name'), "label_attr" => array( "for" => "name" - ) + ), + "required" => true )) ->add("secured" , "text" , array( "label" => Translator::getInstance()->trans('Prevent mailing template modification or deletion, except for super-admin') @@ -45,29 +46,61 @@ class MessageModificationForm extends BaseForm ->add("locale" , "text" , array()) ->add("title" , "text" , array( "constraints" => array(new NotBlank()), - "label" => Translator::getInstance()->trans('Title *'), + "label" => Translator::getInstance()->trans('Title'), "label_attr" => array( "for" => "title" - ) + ), + "required" => true )) ->add("subject" , "text" , array( "constraints" => array(new NotBlank()), - "label" => Translator::getInstance()->trans('Message subject *'), + "label" => Translator::getInstance()->trans('Message subject'), "label_attr" => array( "for" => "subject" - ) + ), + "required" => true )) ->add("html_message" , "text" , array( "label" => Translator::getInstance()->trans('HTML Message'), "label_attr" => array( "for" => "html_message" - ) + ), + "required" => false )) ->add("text_message" , "text" , array( "label" => Translator::getInstance()->trans('Text Message'), "label_attr" => array( "for" => "text_message" - ) + ), + "required" => false + )) + ->add("html_layout_file_name" , "text" , array( + "label" => Translator::getInstance()->trans('Name of the HTML layout file'), + "label_attr" => array( + "for" => "html_layout_file_name" + ), + "required" => false + )) + ->add("html_template_file_name" , "text" , array( + "label" => Translator::getInstance()->trans('Name of the HTML template file'), + "label_attr" => array( + "for" => "html_template_file_name" + ), + "required" => false + )) + ->add("text_layout_file_name" , "text" , array( + "label" => Translator::getInstance()->trans('Name of the text layout file'), + "label_attr" => array( + "for" => "text_layout_file_name" + ), + "required" => false + )) + ->add("text_template_file_name" , "text" , array( + "label" => Translator::getInstance()->trans('Name of the text template file'), + "label_attr" => array( + "for" => "text_template_file_name" + ), + "required" => false )) ; } diff --git a/core/lib/Thelia/Model/Base/Message.php b/core/lib/Thelia/Model/Base/Message.php index fbea5b241..351aa3818 100644 --- a/core/lib/Thelia/Model/Base/Message.php +++ b/core/lib/Thelia/Model/Base/Message.php @@ -78,6 +78,30 @@ abstract class Message implements ActiveRecordInterface */ protected $secured; + /** + * The value for the text_layout_file_name field. + * @var string + */ + protected $text_layout_file_name; + + /** + * The value for the text_template_file_name field. + * @var string + */ + protected $text_template_file_name; + + /** + * The value for the html_layout_file_name field. + * @var string + */ + protected $html_layout_file_name; + + /** + * The value for the html_template_file_name field. + * @var string + */ + protected $html_template_file_name; + /** * The value for the created_at field. * @var string @@ -467,6 +491,50 @@ abstract class Message implements ActiveRecordInterface return $this->secured; } + /** + * Get the [text_layout_file_name] column value. + * + * @return string + */ + public function getTextLayoutFileName() + { + + return $this->text_layout_file_name; + } + + /** + * Get the [text_template_file_name] column value. + * + * @return string + */ + public function getTextTemplateFileName() + { + + return $this->text_template_file_name; + } + + /** + * Get the [html_layout_file_name] column value. + * + * @return string + */ + public function getHtmlLayoutFileName() + { + + return $this->html_layout_file_name; + } + + /** + * Get the [html_template_file_name] column value. + * + * @return string + */ + public function getHtmlTemplateFileName() + { + + return $this->html_template_file_name; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -612,6 +680,90 @@ abstract class Message implements ActiveRecordInterface return $this; } // setSecured() + /** + * Set the value of [text_layout_file_name] column. + * + * @param string $v new value + * @return \Thelia\Model\Message The current object (for fluent API support) + */ + public function setTextLayoutFileName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->text_layout_file_name !== $v) { + $this->text_layout_file_name = $v; + $this->modifiedColumns[] = MessageTableMap::TEXT_LAYOUT_FILE_NAME; + } + + + return $this; + } // setTextLayoutFileName() + + /** + * Set the value of [text_template_file_name] column. + * + * @param string $v new value + * @return \Thelia\Model\Message The current object (for fluent API support) + */ + public function setTextTemplateFileName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->text_template_file_name !== $v) { + $this->text_template_file_name = $v; + $this->modifiedColumns[] = MessageTableMap::TEXT_TEMPLATE_FILE_NAME; + } + + + return $this; + } // setTextTemplateFileName() + + /** + * Set the value of [html_layout_file_name] column. + * + * @param string $v new value + * @return \Thelia\Model\Message The current object (for fluent API support) + */ + public function setHtmlLayoutFileName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->html_layout_file_name !== $v) { + $this->html_layout_file_name = $v; + $this->modifiedColumns[] = MessageTableMap::HTML_LAYOUT_FILE_NAME; + } + + + return $this; + } // setHtmlLayoutFileName() + + /** + * Set the value of [html_template_file_name] column. + * + * @param string $v new value + * @return \Thelia\Model\Message The current object (for fluent API support) + */ + public function setHtmlTemplateFileName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->html_template_file_name !== $v) { + $this->html_template_file_name = $v; + $this->modifiedColumns[] = MessageTableMap::HTML_TEMPLATE_FILE_NAME; + } + + + return $this; + } // setHtmlTemplateFileName() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -767,28 +919,40 @@ abstract class Message implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : MessageTableMap::translateFieldName('Secured', TableMap::TYPE_PHPNAME, $indexType)]; $this->secured = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : MessageTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : MessageTableMap::translateFieldName('TextLayoutFileName', TableMap::TYPE_PHPNAME, $indexType)]; + $this->text_layout_file_name = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : MessageTableMap::translateFieldName('TextTemplateFileName', TableMap::TYPE_PHPNAME, $indexType)]; + $this->text_template_file_name = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : MessageTableMap::translateFieldName('HtmlLayoutFileName', TableMap::TYPE_PHPNAME, $indexType)]; + $this->html_layout_file_name = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : MessageTableMap::translateFieldName('HtmlTemplateFileName', TableMap::TYPE_PHPNAME, $indexType)]; + $this->html_template_file_name = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : MessageTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : MessageTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : MessageTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->updated_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : MessageTableMap::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : MessageTableMap::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)]; $this->version = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : MessageTableMap::translateFieldName('VersionCreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : MessageTableMap::translateFieldName('VersionCreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->version_created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : MessageTableMap::translateFieldName('VersionCreatedBy', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 11 + $startcol : MessageTableMap::translateFieldName('VersionCreatedBy', TableMap::TYPE_PHPNAME, $indexType)]; $this->version_created_by = (null !== $col) ? (string) $col : null; $this->resetModified(); @@ -798,7 +962,7 @@ abstract class Message implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 8; // 8 = MessageTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 12; // 12 = MessageTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Message object", 0, $e); @@ -1077,6 +1241,18 @@ abstract class Message implements ActiveRecordInterface if ($this->isColumnModified(MessageTableMap::SECURED)) { $modifiedColumns[':p' . $index++] = 'SECURED'; } + if ($this->isColumnModified(MessageTableMap::TEXT_LAYOUT_FILE_NAME)) { + $modifiedColumns[':p' . $index++] = 'TEXT_LAYOUT_FILE_NAME'; + } + if ($this->isColumnModified(MessageTableMap::TEXT_TEMPLATE_FILE_NAME)) { + $modifiedColumns[':p' . $index++] = 'TEXT_TEMPLATE_FILE_NAME'; + } + if ($this->isColumnModified(MessageTableMap::HTML_LAYOUT_FILE_NAME)) { + $modifiedColumns[':p' . $index++] = 'HTML_LAYOUT_FILE_NAME'; + } + if ($this->isColumnModified(MessageTableMap::HTML_TEMPLATE_FILE_NAME)) { + $modifiedColumns[':p' . $index++] = 'HTML_TEMPLATE_FILE_NAME'; + } if ($this->isColumnModified(MessageTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -1112,6 +1288,18 @@ abstract class Message implements ActiveRecordInterface case 'SECURED': $stmt->bindValue($identifier, $this->secured, PDO::PARAM_INT); break; + case 'TEXT_LAYOUT_FILE_NAME': + $stmt->bindValue($identifier, $this->text_layout_file_name, PDO::PARAM_STR); + break; + case 'TEXT_TEMPLATE_FILE_NAME': + $stmt->bindValue($identifier, $this->text_template_file_name, PDO::PARAM_STR); + break; + case 'HTML_LAYOUT_FILE_NAME': + $stmt->bindValue($identifier, $this->html_layout_file_name, PDO::PARAM_STR); + break; + case 'HTML_TEMPLATE_FILE_NAME': + $stmt->bindValue($identifier, $this->html_template_file_name, PDO::PARAM_STR); + break; case 'CREATED_AT': $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); break; @@ -1199,18 +1387,30 @@ abstract class Message implements ActiveRecordInterface return $this->getSecured(); break; case 3: - return $this->getCreatedAt(); + return $this->getTextLayoutFileName(); break; case 4: - return $this->getUpdatedAt(); + return $this->getTextTemplateFileName(); break; case 5: - return $this->getVersion(); + return $this->getHtmlLayoutFileName(); break; case 6: - return $this->getVersionCreatedAt(); + return $this->getHtmlTemplateFileName(); break; case 7: + return $this->getCreatedAt(); + break; + case 8: + return $this->getUpdatedAt(); + break; + case 9: + return $this->getVersion(); + break; + case 10: + return $this->getVersionCreatedAt(); + break; + case 11: return $this->getVersionCreatedBy(); break; default: @@ -1245,11 +1445,15 @@ abstract class Message implements ActiveRecordInterface $keys[0] => $this->getId(), $keys[1] => $this->getName(), $keys[2] => $this->getSecured(), - $keys[3] => $this->getCreatedAt(), - $keys[4] => $this->getUpdatedAt(), - $keys[5] => $this->getVersion(), - $keys[6] => $this->getVersionCreatedAt(), - $keys[7] => $this->getVersionCreatedBy(), + $keys[3] => $this->getTextLayoutFileName(), + $keys[4] => $this->getTextTemplateFileName(), + $keys[5] => $this->getHtmlLayoutFileName(), + $keys[6] => $this->getHtmlTemplateFileName(), + $keys[7] => $this->getCreatedAt(), + $keys[8] => $this->getUpdatedAt(), + $keys[9] => $this->getVersion(), + $keys[10] => $this->getVersionCreatedAt(), + $keys[11] => $this->getVersionCreatedBy(), ); $virtualColumns = $this->virtualColumns; foreach ($virtualColumns as $key => $virtualColumn) { @@ -1307,18 +1511,30 @@ abstract class Message implements ActiveRecordInterface $this->setSecured($value); break; case 3: - $this->setCreatedAt($value); + $this->setTextLayoutFileName($value); break; case 4: - $this->setUpdatedAt($value); + $this->setTextTemplateFileName($value); break; case 5: - $this->setVersion($value); + $this->setHtmlLayoutFileName($value); break; case 6: - $this->setVersionCreatedAt($value); + $this->setHtmlTemplateFileName($value); break; case 7: + $this->setCreatedAt($value); + break; + case 8: + $this->setUpdatedAt($value); + break; + case 9: + $this->setVersion($value); + break; + case 10: + $this->setVersionCreatedAt($value); + break; + case 11: $this->setVersionCreatedBy($value); break; } // switch() @@ -1348,11 +1564,15 @@ abstract class Message implements ActiveRecordInterface if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); if (array_key_exists($keys[1], $arr)) $this->setName($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setSecured($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setCreatedAt($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setUpdatedAt($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setVersion($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setVersionCreatedAt($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setVersionCreatedBy($arr[$keys[7]]); + if (array_key_exists($keys[3], $arr)) $this->setTextLayoutFileName($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setTextTemplateFileName($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setHtmlLayoutFileName($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setHtmlTemplateFileName($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setCreatedAt($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setUpdatedAt($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setVersion($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setVersionCreatedAt($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setVersionCreatedBy($arr[$keys[11]]); } /** @@ -1367,6 +1587,10 @@ abstract class Message implements ActiveRecordInterface if ($this->isColumnModified(MessageTableMap::ID)) $criteria->add(MessageTableMap::ID, $this->id); if ($this->isColumnModified(MessageTableMap::NAME)) $criteria->add(MessageTableMap::NAME, $this->name); if ($this->isColumnModified(MessageTableMap::SECURED)) $criteria->add(MessageTableMap::SECURED, $this->secured); + if ($this->isColumnModified(MessageTableMap::TEXT_LAYOUT_FILE_NAME)) $criteria->add(MessageTableMap::TEXT_LAYOUT_FILE_NAME, $this->text_layout_file_name); + if ($this->isColumnModified(MessageTableMap::TEXT_TEMPLATE_FILE_NAME)) $criteria->add(MessageTableMap::TEXT_TEMPLATE_FILE_NAME, $this->text_template_file_name); + if ($this->isColumnModified(MessageTableMap::HTML_LAYOUT_FILE_NAME)) $criteria->add(MessageTableMap::HTML_LAYOUT_FILE_NAME, $this->html_layout_file_name); + if ($this->isColumnModified(MessageTableMap::HTML_TEMPLATE_FILE_NAME)) $criteria->add(MessageTableMap::HTML_TEMPLATE_FILE_NAME, $this->html_template_file_name); if ($this->isColumnModified(MessageTableMap::CREATED_AT)) $criteria->add(MessageTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(MessageTableMap::UPDATED_AT)) $criteria->add(MessageTableMap::UPDATED_AT, $this->updated_at); if ($this->isColumnModified(MessageTableMap::VERSION)) $criteria->add(MessageTableMap::VERSION, $this->version); @@ -1437,6 +1661,10 @@ abstract class Message implements ActiveRecordInterface { $copyObj->setName($this->getName()); $copyObj->setSecured($this->getSecured()); + $copyObj->setTextLayoutFileName($this->getTextLayoutFileName()); + $copyObj->setTextTemplateFileName($this->getTextTemplateFileName()); + $copyObj->setHtmlLayoutFileName($this->getHtmlLayoutFileName()); + $copyObj->setHtmlTemplateFileName($this->getHtmlTemplateFileName()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); $copyObj->setVersion($this->getVersion()); @@ -1963,6 +2191,10 @@ abstract class Message implements ActiveRecordInterface $this->id = null; $this->name = null; $this->secured = null; + $this->text_layout_file_name = null; + $this->text_template_file_name = null; + $this->html_layout_file_name = null; + $this->html_template_file_name = null; $this->created_at = null; $this->updated_at = null; $this->version = null; @@ -2284,6 +2516,10 @@ abstract class Message implements ActiveRecordInterface $version->setId($this->getId()); $version->setName($this->getName()); $version->setSecured($this->getSecured()); + $version->setTextLayoutFileName($this->getTextLayoutFileName()); + $version->setTextTemplateFileName($this->getTextTemplateFileName()); + $version->setHtmlLayoutFileName($this->getHtmlLayoutFileName()); + $version->setHtmlTemplateFileName($this->getHtmlTemplateFileName()); $version->setCreatedAt($this->getCreatedAt()); $version->setUpdatedAt($this->getUpdatedAt()); $version->setVersion($this->getVersion()); @@ -2329,6 +2565,10 @@ abstract class Message implements ActiveRecordInterface $this->setId($version->getId()); $this->setName($version->getName()); $this->setSecured($version->getSecured()); + $this->setTextLayoutFileName($version->getTextLayoutFileName()); + $this->setTextTemplateFileName($version->getTextTemplateFileName()); + $this->setHtmlLayoutFileName($version->getHtmlLayoutFileName()); + $this->setHtmlTemplateFileName($version->getHtmlTemplateFileName()); $this->setCreatedAt($version->getCreatedAt()); $this->setUpdatedAt($version->getUpdatedAt()); $this->setVersion($version->getVersion()); diff --git a/core/lib/Thelia/Model/Base/MessageQuery.php b/core/lib/Thelia/Model/Base/MessageQuery.php index d72dc7bed..3f412191f 100644 --- a/core/lib/Thelia/Model/Base/MessageQuery.php +++ b/core/lib/Thelia/Model/Base/MessageQuery.php @@ -25,6 +25,10 @@ use Thelia\Model\Map\MessageTableMap; * @method ChildMessageQuery orderById($order = Criteria::ASC) Order by the id column * @method ChildMessageQuery orderByName($order = Criteria::ASC) Order by the name column * @method ChildMessageQuery orderBySecured($order = Criteria::ASC) Order by the secured column + * @method ChildMessageQuery orderByTextLayoutFileName($order = Criteria::ASC) Order by the text_layout_file_name column + * @method ChildMessageQuery orderByTextTemplateFileName($order = Criteria::ASC) Order by the text_template_file_name column + * @method ChildMessageQuery orderByHtmlLayoutFileName($order = Criteria::ASC) Order by the html_layout_file_name column + * @method ChildMessageQuery orderByHtmlTemplateFileName($order = Criteria::ASC) Order by the html_template_file_name column * @method ChildMessageQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildMessageQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * @method ChildMessageQuery orderByVersion($order = Criteria::ASC) Order by the version column @@ -34,6 +38,10 @@ use Thelia\Model\Map\MessageTableMap; * @method ChildMessageQuery groupById() Group by the id column * @method ChildMessageQuery groupByName() Group by the name column * @method ChildMessageQuery groupBySecured() Group by the secured column + * @method ChildMessageQuery groupByTextLayoutFileName() Group by the text_layout_file_name column + * @method ChildMessageQuery groupByTextTemplateFileName() Group by the text_template_file_name column + * @method ChildMessageQuery groupByHtmlLayoutFileName() Group by the html_layout_file_name column + * @method ChildMessageQuery groupByHtmlTemplateFileName() Group by the html_template_file_name column * @method ChildMessageQuery groupByCreatedAt() Group by the created_at column * @method ChildMessageQuery groupByUpdatedAt() Group by the updated_at column * @method ChildMessageQuery groupByVersion() Group by the version column @@ -58,6 +66,10 @@ use Thelia\Model\Map\MessageTableMap; * @method ChildMessage findOneById(int $id) Return the first ChildMessage filtered by the id column * @method ChildMessage findOneByName(string $name) Return the first ChildMessage filtered by the name column * @method ChildMessage findOneBySecured(int $secured) Return the first ChildMessage filtered by the secured column + * @method ChildMessage findOneByTextLayoutFileName(string $text_layout_file_name) Return the first ChildMessage filtered by the text_layout_file_name column + * @method ChildMessage findOneByTextTemplateFileName(string $text_template_file_name) Return the first ChildMessage filtered by the text_template_file_name column + * @method ChildMessage findOneByHtmlLayoutFileName(string $html_layout_file_name) Return the first ChildMessage filtered by the html_layout_file_name column + * @method ChildMessage findOneByHtmlTemplateFileName(string $html_template_file_name) Return the first ChildMessage filtered by the html_template_file_name column * @method ChildMessage findOneByCreatedAt(string $created_at) Return the first ChildMessage filtered by the created_at column * @method ChildMessage findOneByUpdatedAt(string $updated_at) Return the first ChildMessage filtered by the updated_at column * @method ChildMessage findOneByVersion(int $version) Return the first ChildMessage filtered by the version column @@ -67,6 +79,10 @@ use Thelia\Model\Map\MessageTableMap; * @method array findById(int $id) Return ChildMessage objects filtered by the id column * @method array findByName(string $name) Return ChildMessage objects filtered by the name column * @method array findBySecured(int $secured) Return ChildMessage objects filtered by the secured column + * @method array findByTextLayoutFileName(string $text_layout_file_name) Return ChildMessage objects filtered by the text_layout_file_name column + * @method array findByTextTemplateFileName(string $text_template_file_name) Return ChildMessage objects filtered by the text_template_file_name column + * @method array findByHtmlLayoutFileName(string $html_layout_file_name) Return ChildMessage objects filtered by the html_layout_file_name column + * @method array findByHtmlTemplateFileName(string $html_template_file_name) Return ChildMessage objects filtered by the html_template_file_name column * @method array findByCreatedAt(string $created_at) Return ChildMessage objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildMessage objects filtered by the updated_at column * @method array findByVersion(int $version) Return ChildMessage objects filtered by the version column @@ -167,7 +183,7 @@ abstract class MessageQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, NAME, SECURED, CREATED_AT, UPDATED_AT, VERSION, VERSION_CREATED_AT, VERSION_CREATED_BY FROM message WHERE ID = :p0'; + $sql = 'SELECT ID, NAME, SECURED, TEXT_LAYOUT_FILE_NAME, TEXT_TEMPLATE_FILE_NAME, HTML_LAYOUT_FILE_NAME, HTML_TEMPLATE_FILE_NAME, CREATED_AT, UPDATED_AT, VERSION, VERSION_CREATED_AT, VERSION_CREATED_BY FROM message WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -367,6 +383,122 @@ abstract class MessageQuery extends ModelCriteria return $this->addUsingAlias(MessageTableMap::SECURED, $secured, $comparison); } + /** + * Filter the query on the text_layout_file_name column + * + * Example usage: + * + * $query->filterByTextLayoutFileName('fooValue'); // WHERE text_layout_file_name = 'fooValue' + * $query->filterByTextLayoutFileName('%fooValue%'); // WHERE text_layout_file_name LIKE '%fooValue%' + * + * + * @param string $textLayoutFileName The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildMessageQuery The current query, for fluid interface + */ + public function filterByTextLayoutFileName($textLayoutFileName = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($textLayoutFileName)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $textLayoutFileName)) { + $textLayoutFileName = str_replace('*', '%', $textLayoutFileName); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(MessageTableMap::TEXT_LAYOUT_FILE_NAME, $textLayoutFileName, $comparison); + } + + /** + * Filter the query on the text_template_file_name column + * + * Example usage: + * + * $query->filterByTextTemplateFileName('fooValue'); // WHERE text_template_file_name = 'fooValue' + * $query->filterByTextTemplateFileName('%fooValue%'); // WHERE text_template_file_name LIKE '%fooValue%' + * + * + * @param string $textTemplateFileName The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildMessageQuery The current query, for fluid interface + */ + public function filterByTextTemplateFileName($textTemplateFileName = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($textTemplateFileName)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $textTemplateFileName)) { + $textTemplateFileName = str_replace('*', '%', $textTemplateFileName); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(MessageTableMap::TEXT_TEMPLATE_FILE_NAME, $textTemplateFileName, $comparison); + } + + /** + * Filter the query on the html_layout_file_name column + * + * Example usage: + * + * $query->filterByHtmlLayoutFileName('fooValue'); // WHERE html_layout_file_name = 'fooValue' + * $query->filterByHtmlLayoutFileName('%fooValue%'); // WHERE html_layout_file_name LIKE '%fooValue%' + * + * + * @param string $htmlLayoutFileName The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildMessageQuery The current query, for fluid interface + */ + public function filterByHtmlLayoutFileName($htmlLayoutFileName = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($htmlLayoutFileName)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $htmlLayoutFileName)) { + $htmlLayoutFileName = str_replace('*', '%', $htmlLayoutFileName); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(MessageTableMap::HTML_LAYOUT_FILE_NAME, $htmlLayoutFileName, $comparison); + } + + /** + * Filter the query on the html_template_file_name column + * + * Example usage: + * + * $query->filterByHtmlTemplateFileName('fooValue'); // WHERE html_template_file_name = 'fooValue' + * $query->filterByHtmlTemplateFileName('%fooValue%'); // WHERE html_template_file_name LIKE '%fooValue%' + * + * + * @param string $htmlTemplateFileName The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildMessageQuery The current query, for fluid interface + */ + public function filterByHtmlTemplateFileName($htmlTemplateFileName = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($htmlTemplateFileName)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $htmlTemplateFileName)) { + $htmlTemplateFileName = str_replace('*', '%', $htmlTemplateFileName); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(MessageTableMap::HTML_TEMPLATE_FILE_NAME, $htmlTemplateFileName, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/MessageVersion.php b/core/lib/Thelia/Model/Base/MessageVersion.php index 0c58a5bb2..6fe06658c 100644 --- a/core/lib/Thelia/Model/Base/MessageVersion.php +++ b/core/lib/Thelia/Model/Base/MessageVersion.php @@ -73,6 +73,30 @@ abstract class MessageVersion implements ActiveRecordInterface */ protected $secured; + /** + * The value for the text_layout_file_name field. + * @var string + */ + protected $text_layout_file_name; + + /** + * The value for the text_template_file_name field. + * @var string + */ + protected $text_template_file_name; + + /** + * The value for the html_layout_file_name field. + * @var string + */ + protected $html_layout_file_name; + + /** + * The value for the html_template_file_name field. + * @var string + */ + protected $html_template_file_name; + /** * The value for the created_at field. * @var string @@ -421,6 +445,50 @@ abstract class MessageVersion implements ActiveRecordInterface return $this->secured; } + /** + * Get the [text_layout_file_name] column value. + * + * @return string + */ + public function getTextLayoutFileName() + { + + return $this->text_layout_file_name; + } + + /** + * Get the [text_template_file_name] column value. + * + * @return string + */ + public function getTextTemplateFileName() + { + + return $this->text_template_file_name; + } + + /** + * Get the [html_layout_file_name] column value. + * + * @return string + */ + public function getHtmlLayoutFileName() + { + + return $this->html_layout_file_name; + } + + /** + * Get the [html_template_file_name] column value. + * + * @return string + */ + public function getHtmlTemplateFileName() + { + + return $this->html_template_file_name; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -570,6 +638,90 @@ abstract class MessageVersion implements ActiveRecordInterface return $this; } // setSecured() + /** + * Set the value of [text_layout_file_name] column. + * + * @param string $v new value + * @return \Thelia\Model\MessageVersion The current object (for fluent API support) + */ + public function setTextLayoutFileName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->text_layout_file_name !== $v) { + $this->text_layout_file_name = $v; + $this->modifiedColumns[] = MessageVersionTableMap::TEXT_LAYOUT_FILE_NAME; + } + + + return $this; + } // setTextLayoutFileName() + + /** + * Set the value of [text_template_file_name] column. + * + * @param string $v new value + * @return \Thelia\Model\MessageVersion The current object (for fluent API support) + */ + public function setTextTemplateFileName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->text_template_file_name !== $v) { + $this->text_template_file_name = $v; + $this->modifiedColumns[] = MessageVersionTableMap::TEXT_TEMPLATE_FILE_NAME; + } + + + return $this; + } // setTextTemplateFileName() + + /** + * Set the value of [html_layout_file_name] column. + * + * @param string $v new value + * @return \Thelia\Model\MessageVersion The current object (for fluent API support) + */ + public function setHtmlLayoutFileName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->html_layout_file_name !== $v) { + $this->html_layout_file_name = $v; + $this->modifiedColumns[] = MessageVersionTableMap::HTML_LAYOUT_FILE_NAME; + } + + + return $this; + } // setHtmlLayoutFileName() + + /** + * Set the value of [html_template_file_name] column. + * + * @param string $v new value + * @return \Thelia\Model\MessageVersion The current object (for fluent API support) + */ + public function setHtmlTemplateFileName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->html_template_file_name !== $v) { + $this->html_template_file_name = $v; + $this->modifiedColumns[] = MessageVersionTableMap::HTML_TEMPLATE_FILE_NAME; + } + + + return $this; + } // setHtmlTemplateFileName() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -725,28 +877,40 @@ abstract class MessageVersion implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : MessageVersionTableMap::translateFieldName('Secured', TableMap::TYPE_PHPNAME, $indexType)]; $this->secured = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : MessageVersionTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : MessageVersionTableMap::translateFieldName('TextLayoutFileName', TableMap::TYPE_PHPNAME, $indexType)]; + $this->text_layout_file_name = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : MessageVersionTableMap::translateFieldName('TextTemplateFileName', TableMap::TYPE_PHPNAME, $indexType)]; + $this->text_template_file_name = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : MessageVersionTableMap::translateFieldName('HtmlLayoutFileName', TableMap::TYPE_PHPNAME, $indexType)]; + $this->html_layout_file_name = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : MessageVersionTableMap::translateFieldName('HtmlTemplateFileName', TableMap::TYPE_PHPNAME, $indexType)]; + $this->html_template_file_name = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : MessageVersionTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : MessageVersionTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : MessageVersionTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->updated_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : MessageVersionTableMap::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : MessageVersionTableMap::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)]; $this->version = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : MessageVersionTableMap::translateFieldName('VersionCreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : MessageVersionTableMap::translateFieldName('VersionCreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->version_created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : MessageVersionTableMap::translateFieldName('VersionCreatedBy', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 11 + $startcol : MessageVersionTableMap::translateFieldName('VersionCreatedBy', TableMap::TYPE_PHPNAME, $indexType)]; $this->version_created_by = (null !== $col) ? (string) $col : null; $this->resetModified(); @@ -756,7 +920,7 @@ abstract class MessageVersion implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 8; // 8 = MessageVersionTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 12; // 12 = MessageVersionTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\MessageVersion object", 0, $e); @@ -986,6 +1150,18 @@ abstract class MessageVersion implements ActiveRecordInterface if ($this->isColumnModified(MessageVersionTableMap::SECURED)) { $modifiedColumns[':p' . $index++] = 'SECURED'; } + if ($this->isColumnModified(MessageVersionTableMap::TEXT_LAYOUT_FILE_NAME)) { + $modifiedColumns[':p' . $index++] = 'TEXT_LAYOUT_FILE_NAME'; + } + if ($this->isColumnModified(MessageVersionTableMap::TEXT_TEMPLATE_FILE_NAME)) { + $modifiedColumns[':p' . $index++] = 'TEXT_TEMPLATE_FILE_NAME'; + } + if ($this->isColumnModified(MessageVersionTableMap::HTML_LAYOUT_FILE_NAME)) { + $modifiedColumns[':p' . $index++] = 'HTML_LAYOUT_FILE_NAME'; + } + if ($this->isColumnModified(MessageVersionTableMap::HTML_TEMPLATE_FILE_NAME)) { + $modifiedColumns[':p' . $index++] = 'HTML_TEMPLATE_FILE_NAME'; + } if ($this->isColumnModified(MessageVersionTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -1021,6 +1197,18 @@ abstract class MessageVersion implements ActiveRecordInterface case 'SECURED': $stmt->bindValue($identifier, $this->secured, PDO::PARAM_INT); break; + case 'TEXT_LAYOUT_FILE_NAME': + $stmt->bindValue($identifier, $this->text_layout_file_name, PDO::PARAM_STR); + break; + case 'TEXT_TEMPLATE_FILE_NAME': + $stmt->bindValue($identifier, $this->text_template_file_name, PDO::PARAM_STR); + break; + case 'HTML_LAYOUT_FILE_NAME': + $stmt->bindValue($identifier, $this->html_layout_file_name, PDO::PARAM_STR); + break; + case 'HTML_TEMPLATE_FILE_NAME': + $stmt->bindValue($identifier, $this->html_template_file_name, PDO::PARAM_STR); + break; case 'CREATED_AT': $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); break; @@ -1101,18 +1289,30 @@ abstract class MessageVersion implements ActiveRecordInterface return $this->getSecured(); break; case 3: - return $this->getCreatedAt(); + return $this->getTextLayoutFileName(); break; case 4: - return $this->getUpdatedAt(); + return $this->getTextTemplateFileName(); break; case 5: - return $this->getVersion(); + return $this->getHtmlLayoutFileName(); break; case 6: - return $this->getVersionCreatedAt(); + return $this->getHtmlTemplateFileName(); break; case 7: + return $this->getCreatedAt(); + break; + case 8: + return $this->getUpdatedAt(); + break; + case 9: + return $this->getVersion(); + break; + case 10: + return $this->getVersionCreatedAt(); + break; + case 11: return $this->getVersionCreatedBy(); break; default: @@ -1147,11 +1347,15 @@ abstract class MessageVersion implements ActiveRecordInterface $keys[0] => $this->getId(), $keys[1] => $this->getName(), $keys[2] => $this->getSecured(), - $keys[3] => $this->getCreatedAt(), - $keys[4] => $this->getUpdatedAt(), - $keys[5] => $this->getVersion(), - $keys[6] => $this->getVersionCreatedAt(), - $keys[7] => $this->getVersionCreatedBy(), + $keys[3] => $this->getTextLayoutFileName(), + $keys[4] => $this->getTextTemplateFileName(), + $keys[5] => $this->getHtmlLayoutFileName(), + $keys[6] => $this->getHtmlTemplateFileName(), + $keys[7] => $this->getCreatedAt(), + $keys[8] => $this->getUpdatedAt(), + $keys[9] => $this->getVersion(), + $keys[10] => $this->getVersionCreatedAt(), + $keys[11] => $this->getVersionCreatedBy(), ); $virtualColumns = $this->virtualColumns; foreach ($virtualColumns as $key => $virtualColumn) { @@ -1206,18 +1410,30 @@ abstract class MessageVersion implements ActiveRecordInterface $this->setSecured($value); break; case 3: - $this->setCreatedAt($value); + $this->setTextLayoutFileName($value); break; case 4: - $this->setUpdatedAt($value); + $this->setTextTemplateFileName($value); break; case 5: - $this->setVersion($value); + $this->setHtmlLayoutFileName($value); break; case 6: - $this->setVersionCreatedAt($value); + $this->setHtmlTemplateFileName($value); break; case 7: + $this->setCreatedAt($value); + break; + case 8: + $this->setUpdatedAt($value); + break; + case 9: + $this->setVersion($value); + break; + case 10: + $this->setVersionCreatedAt($value); + break; + case 11: $this->setVersionCreatedBy($value); break; } // switch() @@ -1247,11 +1463,15 @@ abstract class MessageVersion implements ActiveRecordInterface if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); if (array_key_exists($keys[1], $arr)) $this->setName($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setSecured($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setCreatedAt($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setUpdatedAt($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setVersion($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setVersionCreatedAt($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setVersionCreatedBy($arr[$keys[7]]); + if (array_key_exists($keys[3], $arr)) $this->setTextLayoutFileName($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setTextTemplateFileName($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setHtmlLayoutFileName($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setHtmlTemplateFileName($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setCreatedAt($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setUpdatedAt($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setVersion($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setVersionCreatedAt($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setVersionCreatedBy($arr[$keys[11]]); } /** @@ -1266,6 +1486,10 @@ abstract class MessageVersion implements ActiveRecordInterface if ($this->isColumnModified(MessageVersionTableMap::ID)) $criteria->add(MessageVersionTableMap::ID, $this->id); if ($this->isColumnModified(MessageVersionTableMap::NAME)) $criteria->add(MessageVersionTableMap::NAME, $this->name); if ($this->isColumnModified(MessageVersionTableMap::SECURED)) $criteria->add(MessageVersionTableMap::SECURED, $this->secured); + if ($this->isColumnModified(MessageVersionTableMap::TEXT_LAYOUT_FILE_NAME)) $criteria->add(MessageVersionTableMap::TEXT_LAYOUT_FILE_NAME, $this->text_layout_file_name); + if ($this->isColumnModified(MessageVersionTableMap::TEXT_TEMPLATE_FILE_NAME)) $criteria->add(MessageVersionTableMap::TEXT_TEMPLATE_FILE_NAME, $this->text_template_file_name); + if ($this->isColumnModified(MessageVersionTableMap::HTML_LAYOUT_FILE_NAME)) $criteria->add(MessageVersionTableMap::HTML_LAYOUT_FILE_NAME, $this->html_layout_file_name); + if ($this->isColumnModified(MessageVersionTableMap::HTML_TEMPLATE_FILE_NAME)) $criteria->add(MessageVersionTableMap::HTML_TEMPLATE_FILE_NAME, $this->html_template_file_name); if ($this->isColumnModified(MessageVersionTableMap::CREATED_AT)) $criteria->add(MessageVersionTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(MessageVersionTableMap::UPDATED_AT)) $criteria->add(MessageVersionTableMap::UPDATED_AT, $this->updated_at); if ($this->isColumnModified(MessageVersionTableMap::VERSION)) $criteria->add(MessageVersionTableMap::VERSION, $this->version); @@ -1344,6 +1568,10 @@ abstract class MessageVersion implements ActiveRecordInterface $copyObj->setId($this->getId()); $copyObj->setName($this->getName()); $copyObj->setSecured($this->getSecured()); + $copyObj->setTextLayoutFileName($this->getTextLayoutFileName()); + $copyObj->setTextTemplateFileName($this->getTextTemplateFileName()); + $copyObj->setHtmlLayoutFileName($this->getHtmlLayoutFileName()); + $copyObj->setHtmlTemplateFileName($this->getHtmlTemplateFileName()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); $copyObj->setVersion($this->getVersion()); @@ -1435,6 +1663,10 @@ abstract class MessageVersion implements ActiveRecordInterface $this->id = null; $this->name = null; $this->secured = null; + $this->text_layout_file_name = null; + $this->text_template_file_name = null; + $this->html_layout_file_name = null; + $this->html_template_file_name = null; $this->created_at = null; $this->updated_at = null; $this->version = null; diff --git a/core/lib/Thelia/Model/Base/MessageVersionQuery.php b/core/lib/Thelia/Model/Base/MessageVersionQuery.php index 088234eb5..638ed5e5c 100644 --- a/core/lib/Thelia/Model/Base/MessageVersionQuery.php +++ b/core/lib/Thelia/Model/Base/MessageVersionQuery.php @@ -24,6 +24,10 @@ use Thelia\Model\Map\MessageVersionTableMap; * @method ChildMessageVersionQuery orderById($order = Criteria::ASC) Order by the id column * @method ChildMessageVersionQuery orderByName($order = Criteria::ASC) Order by the name column * @method ChildMessageVersionQuery orderBySecured($order = Criteria::ASC) Order by the secured column + * @method ChildMessageVersionQuery orderByTextLayoutFileName($order = Criteria::ASC) Order by the text_layout_file_name column + * @method ChildMessageVersionQuery orderByTextTemplateFileName($order = Criteria::ASC) Order by the text_template_file_name column + * @method ChildMessageVersionQuery orderByHtmlLayoutFileName($order = Criteria::ASC) Order by the html_layout_file_name column + * @method ChildMessageVersionQuery orderByHtmlTemplateFileName($order = Criteria::ASC) Order by the html_template_file_name column * @method ChildMessageVersionQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildMessageVersionQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * @method ChildMessageVersionQuery orderByVersion($order = Criteria::ASC) Order by the version column @@ -33,6 +37,10 @@ use Thelia\Model\Map\MessageVersionTableMap; * @method ChildMessageVersionQuery groupById() Group by the id column * @method ChildMessageVersionQuery groupByName() Group by the name column * @method ChildMessageVersionQuery groupBySecured() Group by the secured column + * @method ChildMessageVersionQuery groupByTextLayoutFileName() Group by the text_layout_file_name column + * @method ChildMessageVersionQuery groupByTextTemplateFileName() Group by the text_template_file_name column + * @method ChildMessageVersionQuery groupByHtmlLayoutFileName() Group by the html_layout_file_name column + * @method ChildMessageVersionQuery groupByHtmlTemplateFileName() Group by the html_template_file_name column * @method ChildMessageVersionQuery groupByCreatedAt() Group by the created_at column * @method ChildMessageVersionQuery groupByUpdatedAt() Group by the updated_at column * @method ChildMessageVersionQuery groupByVersion() Group by the version column @@ -53,6 +61,10 @@ use Thelia\Model\Map\MessageVersionTableMap; * @method ChildMessageVersion findOneById(int $id) Return the first ChildMessageVersion filtered by the id column * @method ChildMessageVersion findOneByName(string $name) Return the first ChildMessageVersion filtered by the name column * @method ChildMessageVersion findOneBySecured(int $secured) Return the first ChildMessageVersion filtered by the secured column + * @method ChildMessageVersion findOneByTextLayoutFileName(string $text_layout_file_name) Return the first ChildMessageVersion filtered by the text_layout_file_name column + * @method ChildMessageVersion findOneByTextTemplateFileName(string $text_template_file_name) Return the first ChildMessageVersion filtered by the text_template_file_name column + * @method ChildMessageVersion findOneByHtmlLayoutFileName(string $html_layout_file_name) Return the first ChildMessageVersion filtered by the html_layout_file_name column + * @method ChildMessageVersion findOneByHtmlTemplateFileName(string $html_template_file_name) Return the first ChildMessageVersion filtered by the html_template_file_name column * @method ChildMessageVersion findOneByCreatedAt(string $created_at) Return the first ChildMessageVersion filtered by the created_at column * @method ChildMessageVersion findOneByUpdatedAt(string $updated_at) Return the first ChildMessageVersion filtered by the updated_at column * @method ChildMessageVersion findOneByVersion(int $version) Return the first ChildMessageVersion filtered by the version column @@ -62,6 +74,10 @@ use Thelia\Model\Map\MessageVersionTableMap; * @method array findById(int $id) Return ChildMessageVersion objects filtered by the id column * @method array findByName(string $name) Return ChildMessageVersion objects filtered by the name column * @method array findBySecured(int $secured) Return ChildMessageVersion objects filtered by the secured column + * @method array findByTextLayoutFileName(string $text_layout_file_name) Return ChildMessageVersion objects filtered by the text_layout_file_name column + * @method array findByTextTemplateFileName(string $text_template_file_name) Return ChildMessageVersion objects filtered by the text_template_file_name column + * @method array findByHtmlLayoutFileName(string $html_layout_file_name) Return ChildMessageVersion objects filtered by the html_layout_file_name column + * @method array findByHtmlTemplateFileName(string $html_template_file_name) Return ChildMessageVersion objects filtered by the html_template_file_name column * @method array findByCreatedAt(string $created_at) Return ChildMessageVersion objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildMessageVersion objects filtered by the updated_at column * @method array findByVersion(int $version) Return ChildMessageVersion objects filtered by the version column @@ -155,7 +171,7 @@ abstract class MessageVersionQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, NAME, SECURED, CREATED_AT, UPDATED_AT, VERSION, VERSION_CREATED_AT, VERSION_CREATED_BY FROM message_version WHERE ID = :p0 AND VERSION = :p1'; + $sql = 'SELECT ID, NAME, SECURED, TEXT_LAYOUT_FILE_NAME, TEXT_TEMPLATE_FILE_NAME, HTML_LAYOUT_FILE_NAME, HTML_TEMPLATE_FILE_NAME, CREATED_AT, UPDATED_AT, VERSION, VERSION_CREATED_AT, VERSION_CREATED_BY FROM message_version WHERE ID = :p0 AND VERSION = :p1'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key[0], PDO::PARAM_INT); @@ -369,6 +385,122 @@ abstract class MessageVersionQuery extends ModelCriteria return $this->addUsingAlias(MessageVersionTableMap::SECURED, $secured, $comparison); } + /** + * Filter the query on the text_layout_file_name column + * + * Example usage: + * + * $query->filterByTextLayoutFileName('fooValue'); // WHERE text_layout_file_name = 'fooValue' + * $query->filterByTextLayoutFileName('%fooValue%'); // WHERE text_layout_file_name LIKE '%fooValue%' + * + * + * @param string $textLayoutFileName The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildMessageVersionQuery The current query, for fluid interface + */ + public function filterByTextLayoutFileName($textLayoutFileName = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($textLayoutFileName)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $textLayoutFileName)) { + $textLayoutFileName = str_replace('*', '%', $textLayoutFileName); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(MessageVersionTableMap::TEXT_LAYOUT_FILE_NAME, $textLayoutFileName, $comparison); + } + + /** + * Filter the query on the text_template_file_name column + * + * Example usage: + * + * $query->filterByTextTemplateFileName('fooValue'); // WHERE text_template_file_name = 'fooValue' + * $query->filterByTextTemplateFileName('%fooValue%'); // WHERE text_template_file_name LIKE '%fooValue%' + * + * + * @param string $textTemplateFileName The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildMessageVersionQuery The current query, for fluid interface + */ + public function filterByTextTemplateFileName($textTemplateFileName = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($textTemplateFileName)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $textTemplateFileName)) { + $textTemplateFileName = str_replace('*', '%', $textTemplateFileName); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(MessageVersionTableMap::TEXT_TEMPLATE_FILE_NAME, $textTemplateFileName, $comparison); + } + + /** + * Filter the query on the html_layout_file_name column + * + * Example usage: + * + * $query->filterByHtmlLayoutFileName('fooValue'); // WHERE html_layout_file_name = 'fooValue' + * $query->filterByHtmlLayoutFileName('%fooValue%'); // WHERE html_layout_file_name LIKE '%fooValue%' + * + * + * @param string $htmlLayoutFileName The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildMessageVersionQuery The current query, for fluid interface + */ + public function filterByHtmlLayoutFileName($htmlLayoutFileName = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($htmlLayoutFileName)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $htmlLayoutFileName)) { + $htmlLayoutFileName = str_replace('*', '%', $htmlLayoutFileName); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(MessageVersionTableMap::HTML_LAYOUT_FILE_NAME, $htmlLayoutFileName, $comparison); + } + + /** + * Filter the query on the html_template_file_name column + * + * Example usage: + * + * $query->filterByHtmlTemplateFileName('fooValue'); // WHERE html_template_file_name = 'fooValue' + * $query->filterByHtmlTemplateFileName('%fooValue%'); // WHERE html_template_file_name LIKE '%fooValue%' + * + * + * @param string $htmlTemplateFileName The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildMessageVersionQuery The current query, for fluid interface + */ + public function filterByHtmlTemplateFileName($htmlTemplateFileName = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($htmlTemplateFileName)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $htmlTemplateFileName)) { + $htmlTemplateFileName = str_replace('*', '%', $htmlTemplateFileName); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(MessageVersionTableMap::HTML_TEMPLATE_FILE_NAME, $htmlTemplateFileName, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/Product.php b/core/lib/Thelia/Model/Base/Product.php index 77824575c..e850d2acf 100644 --- a/core/lib/Thelia/Model/Base/Product.php +++ b/core/lib/Thelia/Model/Base/Product.php @@ -5866,6 +5866,78 @@ abstract class Product implements ActiveRecordInterface return $this; } + + /** + * Get the [meta_title] column value. + * + * @return string + */ + public function getMetaTitle() + { + return $this->getCurrentTranslation()->getMetaTitle(); + } + + + /** + * Set the value of [meta_title] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductI18n The current object (for fluent API support) + */ + public function setMetaTitle($v) + { $this->getCurrentTranslation()->setMetaTitle($v); + + return $this; + } + + + /** + * Get the [meta_description] column value. + * + * @return string + */ + public function getMetaDescription() + { + return $this->getCurrentTranslation()->getMetaDescription(); + } + + + /** + * Set the value of [meta_description] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductI18n The current object (for fluent API support) + */ + public function setMetaDescription($v) + { $this->getCurrentTranslation()->setMetaDescription($v); + + return $this; + } + + + /** + * Get the [meta_keyword] column value. + * + * @return string + */ + public function getMetaKeyword() + { + return $this->getCurrentTranslation()->getMetaKeyword(); + } + + + /** + * Set the value of [meta_keyword] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductI18n The current object (for fluent API support) + */ + public function setMetaKeyword($v) + { $this->getCurrentTranslation()->setMetaKeyword($v); + + return $this; + } + // versionable behavior /** diff --git a/core/lib/Thelia/Model/Base/ProductI18n.php b/core/lib/Thelia/Model/Base/ProductI18n.php index cdab7349d..a72f07c83 100644 --- a/core/lib/Thelia/Model/Base/ProductI18n.php +++ b/core/lib/Thelia/Model/Base/ProductI18n.php @@ -90,6 +90,24 @@ abstract class ProductI18n implements ActiveRecordInterface */ protected $postscriptum; + /** + * The value for the meta_title field. + * @var string + */ + protected $meta_title; + + /** + * The value for the meta_description field. + * @var string + */ + protected $meta_description; + + /** + * The value for the meta_keyword field. + * @var string + */ + protected $meta_keyword; + /** * @var Product */ @@ -440,6 +458,39 @@ abstract class ProductI18n implements ActiveRecordInterface return $this->postscriptum; } + /** + * Get the [meta_title] column value. + * + * @return string + */ + public function getMetaTitle() + { + + return $this->meta_title; + } + + /** + * Get the [meta_description] column value. + * + * @return string + */ + public function getMetaDescription() + { + + return $this->meta_description; + } + + /** + * Get the [meta_keyword] column value. + * + * @return string + */ + public function getMetaKeyword() + { + + return $this->meta_keyword; + } + /** * Set the value of [id] column. * @@ -570,6 +621,69 @@ abstract class ProductI18n implements ActiveRecordInterface return $this; } // setPostscriptum() + /** + * Set the value of [meta_title] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductI18n The current object (for fluent API support) + */ + public function setMetaTitle($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->meta_title !== $v) { + $this->meta_title = $v; + $this->modifiedColumns[] = ProductI18nTableMap::META_TITLE; + } + + + return $this; + } // setMetaTitle() + + /** + * Set the value of [meta_description] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductI18n The current object (for fluent API support) + */ + public function setMetaDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->meta_description !== $v) { + $this->meta_description = $v; + $this->modifiedColumns[] = ProductI18nTableMap::META_DESCRIPTION; + } + + + return $this; + } // setMetaDescription() + + /** + * Set the value of [meta_keyword] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductI18n The current object (for fluent API support) + */ + public function setMetaKeyword($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->meta_keyword !== $v) { + $this->meta_keyword = $v; + $this->modifiedColumns[] = ProductI18nTableMap::META_KEYWORD; + } + + + return $this; + } // setMetaKeyword() + /** * Indicates whether the columns in this object are only set to default values. * @@ -628,6 +742,15 @@ abstract class ProductI18n implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProductI18nTableMap::translateFieldName('Postscriptum', TableMap::TYPE_PHPNAME, $indexType)]; $this->postscriptum = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : ProductI18nTableMap::translateFieldName('MetaTitle', TableMap::TYPE_PHPNAME, $indexType)]; + $this->meta_title = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ProductI18nTableMap::translateFieldName('MetaDescription', TableMap::TYPE_PHPNAME, $indexType)]; + $this->meta_description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : ProductI18nTableMap::translateFieldName('MetaKeyword', TableMap::TYPE_PHPNAME, $indexType)]; + $this->meta_keyword = (null !== $col) ? (string) $col : null; $this->resetModified(); $this->setNew(false); @@ -636,7 +759,7 @@ abstract class ProductI18n implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 6; // 6 = ProductI18nTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 9; // 9 = ProductI18nTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\ProductI18n object", 0, $e); @@ -875,6 +998,15 @@ abstract class ProductI18n implements ActiveRecordInterface if ($this->isColumnModified(ProductI18nTableMap::POSTSCRIPTUM)) { $modifiedColumns[':p' . $index++] = 'POSTSCRIPTUM'; } + if ($this->isColumnModified(ProductI18nTableMap::META_TITLE)) { + $modifiedColumns[':p' . $index++] = 'META_TITLE'; + } + if ($this->isColumnModified(ProductI18nTableMap::META_DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'META_DESCRIPTION'; + } + if ($this->isColumnModified(ProductI18nTableMap::META_KEYWORD)) { + $modifiedColumns[':p' . $index++] = 'META_KEYWORD'; + } $sql = sprintf( 'INSERT INTO product_i18n (%s) VALUES (%s)', @@ -904,6 +1036,15 @@ abstract class ProductI18n implements ActiveRecordInterface case 'POSTSCRIPTUM': $stmt->bindValue($identifier, $this->postscriptum, PDO::PARAM_STR); break; + case 'META_TITLE': + $stmt->bindValue($identifier, $this->meta_title, PDO::PARAM_STR); + break; + case 'META_DESCRIPTION': + $stmt->bindValue($identifier, $this->meta_description, PDO::PARAM_STR); + break; + case 'META_KEYWORD': + $stmt->bindValue($identifier, $this->meta_keyword, PDO::PARAM_STR); + break; } } $stmt->execute(); @@ -977,6 +1118,15 @@ abstract class ProductI18n implements ActiveRecordInterface case 5: return $this->getPostscriptum(); break; + case 6: + return $this->getMetaTitle(); + break; + case 7: + return $this->getMetaDescription(); + break; + case 8: + return $this->getMetaKeyword(); + break; default: return null; break; @@ -1012,6 +1162,9 @@ abstract class ProductI18n implements ActiveRecordInterface $keys[3] => $this->getDescription(), $keys[4] => $this->getChapo(), $keys[5] => $this->getPostscriptum(), + $keys[6] => $this->getMetaTitle(), + $keys[7] => $this->getMetaDescription(), + $keys[8] => $this->getMetaKeyword(), ); $virtualColumns = $this->virtualColumns; foreach ($virtualColumns as $key => $virtualColumn) { @@ -1074,6 +1227,15 @@ abstract class ProductI18n implements ActiveRecordInterface case 5: $this->setPostscriptum($value); break; + case 6: + $this->setMetaTitle($value); + break; + case 7: + $this->setMetaDescription($value); + break; + case 8: + $this->setMetaKeyword($value); + break; } // switch() } @@ -1104,6 +1266,9 @@ abstract class ProductI18n implements ActiveRecordInterface if (array_key_exists($keys[3], $arr)) $this->setDescription($arr[$keys[3]]); if (array_key_exists($keys[4], $arr)) $this->setChapo($arr[$keys[4]]); if (array_key_exists($keys[5], $arr)) $this->setPostscriptum($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setMetaTitle($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setMetaDescription($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setMetaKeyword($arr[$keys[8]]); } /** @@ -1121,6 +1286,9 @@ abstract class ProductI18n implements ActiveRecordInterface if ($this->isColumnModified(ProductI18nTableMap::DESCRIPTION)) $criteria->add(ProductI18nTableMap::DESCRIPTION, $this->description); if ($this->isColumnModified(ProductI18nTableMap::CHAPO)) $criteria->add(ProductI18nTableMap::CHAPO, $this->chapo); if ($this->isColumnModified(ProductI18nTableMap::POSTSCRIPTUM)) $criteria->add(ProductI18nTableMap::POSTSCRIPTUM, $this->postscriptum); + if ($this->isColumnModified(ProductI18nTableMap::META_TITLE)) $criteria->add(ProductI18nTableMap::META_TITLE, $this->meta_title); + if ($this->isColumnModified(ProductI18nTableMap::META_DESCRIPTION)) $criteria->add(ProductI18nTableMap::META_DESCRIPTION, $this->meta_description); + if ($this->isColumnModified(ProductI18nTableMap::META_KEYWORD)) $criteria->add(ProductI18nTableMap::META_KEYWORD, $this->meta_keyword); return $criteria; } @@ -1197,6 +1365,9 @@ abstract class ProductI18n implements ActiveRecordInterface $copyObj->setDescription($this->getDescription()); $copyObj->setChapo($this->getChapo()); $copyObj->setPostscriptum($this->getPostscriptum()); + $copyObj->setMetaTitle($this->getMetaTitle()); + $copyObj->setMetaDescription($this->getMetaDescription()); + $copyObj->setMetaKeyword($this->getMetaKeyword()); if ($makeNew) { $copyObj->setNew(true); } @@ -1286,6 +1457,9 @@ abstract class ProductI18n implements ActiveRecordInterface $this->description = null; $this->chapo = null; $this->postscriptum = null; + $this->meta_title = null; + $this->meta_description = null; + $this->meta_keyword = null; $this->alreadyInSave = false; $this->clearAllReferences(); $this->applyDefaultValues(); diff --git a/core/lib/Thelia/Model/Base/ProductI18nQuery.php b/core/lib/Thelia/Model/Base/ProductI18nQuery.php index d64c95892..01d3af9d4 100644 --- a/core/lib/Thelia/Model/Base/ProductI18nQuery.php +++ b/core/lib/Thelia/Model/Base/ProductI18nQuery.php @@ -27,6 +27,9 @@ use Thelia\Model\Map\ProductI18nTableMap; * @method ChildProductI18nQuery orderByDescription($order = Criteria::ASC) Order by the description column * @method ChildProductI18nQuery orderByChapo($order = Criteria::ASC) Order by the chapo column * @method ChildProductI18nQuery orderByPostscriptum($order = Criteria::ASC) Order by the postscriptum column + * @method ChildProductI18nQuery orderByMetaTitle($order = Criteria::ASC) Order by the meta_title column + * @method ChildProductI18nQuery orderByMetaDescription($order = Criteria::ASC) Order by the meta_description column + * @method ChildProductI18nQuery orderByMetaKeyword($order = Criteria::ASC) Order by the meta_keyword column * * @method ChildProductI18nQuery groupById() Group by the id column * @method ChildProductI18nQuery groupByLocale() Group by the locale column @@ -34,6 +37,9 @@ use Thelia\Model\Map\ProductI18nTableMap; * @method ChildProductI18nQuery groupByDescription() Group by the description column * @method ChildProductI18nQuery groupByChapo() Group by the chapo column * @method ChildProductI18nQuery groupByPostscriptum() Group by the postscriptum column + * @method ChildProductI18nQuery groupByMetaTitle() Group by the meta_title column + * @method ChildProductI18nQuery groupByMetaDescription() Group by the meta_description column + * @method ChildProductI18nQuery groupByMetaKeyword() Group by the meta_keyword column * * @method ChildProductI18nQuery leftJoin($relation) Adds a LEFT JOIN clause to the query * @method ChildProductI18nQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query @@ -52,6 +58,9 @@ use Thelia\Model\Map\ProductI18nTableMap; * @method ChildProductI18n findOneByDescription(string $description) Return the first ChildProductI18n filtered by the description column * @method ChildProductI18n findOneByChapo(string $chapo) Return the first ChildProductI18n filtered by the chapo column * @method ChildProductI18n findOneByPostscriptum(string $postscriptum) Return the first ChildProductI18n filtered by the postscriptum column + * @method ChildProductI18n findOneByMetaTitle(string $meta_title) Return the first ChildProductI18n filtered by the meta_title column + * @method ChildProductI18n findOneByMetaDescription(string $meta_description) Return the first ChildProductI18n filtered by the meta_description column + * @method ChildProductI18n findOneByMetaKeyword(string $meta_keyword) Return the first ChildProductI18n filtered by the meta_keyword column * * @method array findById(int $id) Return ChildProductI18n objects filtered by the id column * @method array findByLocale(string $locale) Return ChildProductI18n objects filtered by the locale column @@ -59,6 +68,9 @@ use Thelia\Model\Map\ProductI18nTableMap; * @method array findByDescription(string $description) Return ChildProductI18n objects filtered by the description column * @method array findByChapo(string $chapo) Return ChildProductI18n objects filtered by the chapo column * @method array findByPostscriptum(string $postscriptum) Return ChildProductI18n objects filtered by the postscriptum column + * @method array findByMetaTitle(string $meta_title) Return ChildProductI18n objects filtered by the meta_title column + * @method array findByMetaDescription(string $meta_description) Return ChildProductI18n objects filtered by the meta_description column + * @method array findByMetaKeyword(string $meta_keyword) Return ChildProductI18n objects filtered by the meta_keyword column * */ abstract class ProductI18nQuery extends ModelCriteria @@ -147,7 +159,7 @@ abstract class ProductI18nQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, LOCALE, TITLE, DESCRIPTION, CHAPO, POSTSCRIPTUM FROM product_i18n WHERE ID = :p0 AND LOCALE = :p1'; + $sql = 'SELECT ID, LOCALE, TITLE, DESCRIPTION, CHAPO, POSTSCRIPTUM, META_TITLE, META_DESCRIPTION, META_KEYWORD FROM product_i18n WHERE ID = :p0 AND LOCALE = :p1'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key[0], PDO::PARAM_INT); @@ -436,6 +448,93 @@ abstract class ProductI18nQuery extends ModelCriteria return $this->addUsingAlias(ProductI18nTableMap::POSTSCRIPTUM, $postscriptum, $comparison); } + /** + * Filter the query on the meta_title column + * + * Example usage: + * + * $query->filterByMetaTitle('fooValue'); // WHERE meta_title = 'fooValue' + * $query->filterByMetaTitle('%fooValue%'); // WHERE meta_title LIKE '%fooValue%' + * + * + * @param string $metaTitle The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductI18nQuery The current query, for fluid interface + */ + public function filterByMetaTitle($metaTitle = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($metaTitle)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $metaTitle)) { + $metaTitle = str_replace('*', '%', $metaTitle); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductI18nTableMap::META_TITLE, $metaTitle, $comparison); + } + + /** + * Filter the query on the meta_description column + * + * Example usage: + * + * $query->filterByMetaDescription('fooValue'); // WHERE meta_description = 'fooValue' + * $query->filterByMetaDescription('%fooValue%'); // WHERE meta_description LIKE '%fooValue%' + * + * + * @param string $metaDescription The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductI18nQuery The current query, for fluid interface + */ + public function filterByMetaDescription($metaDescription = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($metaDescription)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $metaDescription)) { + $metaDescription = str_replace('*', '%', $metaDescription); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductI18nTableMap::META_DESCRIPTION, $metaDescription, $comparison); + } + + /** + * Filter the query on the meta_keyword column + * + * Example usage: + * + * $query->filterByMetaKeyword('fooValue'); // WHERE meta_keyword = 'fooValue' + * $query->filterByMetaKeyword('%fooValue%'); // WHERE meta_keyword LIKE '%fooValue%' + * + * + * @param string $metaKeyword The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductI18nQuery The current query, for fluid interface + */ + public function filterByMetaKeyword($metaKeyword = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($metaKeyword)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $metaKeyword)) { + $metaKeyword = str_replace('*', '%', $metaKeyword); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductI18nTableMap::META_KEYWORD, $metaKeyword, $comparison); + } + /** * Filter the query by a related \Thelia\Model\Product object * diff --git a/core/lib/Thelia/Model/Map/MessageTableMap.php b/core/lib/Thelia/Model/Map/MessageTableMap.php index d56b1210c..a81f022a0 100644 --- a/core/lib/Thelia/Model/Map/MessageTableMap.php +++ b/core/lib/Thelia/Model/Map/MessageTableMap.php @@ -57,7 +57,7 @@ class MessageTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 8; + const NUM_COLUMNS = 12; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class MessageTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 8; + const NUM_HYDRATE_COLUMNS = 12; /** * the column name for the ID field @@ -84,6 +84,26 @@ class MessageTableMap extends TableMap */ const SECURED = 'message.SECURED'; + /** + * the column name for the TEXT_LAYOUT_FILE_NAME field + */ + const TEXT_LAYOUT_FILE_NAME = 'message.TEXT_LAYOUT_FILE_NAME'; + + /** + * the column name for the TEXT_TEMPLATE_FILE_NAME field + */ + const TEXT_TEMPLATE_FILE_NAME = 'message.TEXT_TEMPLATE_FILE_NAME'; + + /** + * the column name for the HTML_LAYOUT_FILE_NAME field + */ + const HTML_LAYOUT_FILE_NAME = 'message.HTML_LAYOUT_FILE_NAME'; + + /** + * the column name for the HTML_TEMPLATE_FILE_NAME field + */ + const HTML_TEMPLATE_FILE_NAME = 'message.HTML_TEMPLATE_FILE_NAME'; + /** * the column name for the CREATED_AT field */ @@ -130,12 +150,12 @@ class MessageTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Name', 'Secured', 'CreatedAt', 'UpdatedAt', 'Version', 'VersionCreatedAt', 'VersionCreatedBy', ), - self::TYPE_STUDLYPHPNAME => array('id', 'name', 'secured', 'createdAt', 'updatedAt', 'version', 'versionCreatedAt', 'versionCreatedBy', ), - self::TYPE_COLNAME => array(MessageTableMap::ID, MessageTableMap::NAME, MessageTableMap::SECURED, MessageTableMap::CREATED_AT, MessageTableMap::UPDATED_AT, MessageTableMap::VERSION, MessageTableMap::VERSION_CREATED_AT, MessageTableMap::VERSION_CREATED_BY, ), - self::TYPE_RAW_COLNAME => array('ID', 'NAME', 'SECURED', 'CREATED_AT', 'UPDATED_AT', 'VERSION', 'VERSION_CREATED_AT', 'VERSION_CREATED_BY', ), - self::TYPE_FIELDNAME => array('id', 'name', 'secured', 'created_at', 'updated_at', 'version', 'version_created_at', 'version_created_by', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id', 'Name', 'Secured', 'TextLayoutFileName', 'TextTemplateFileName', 'HtmlLayoutFileName', 'HtmlTemplateFileName', 'CreatedAt', 'UpdatedAt', 'Version', 'VersionCreatedAt', 'VersionCreatedBy', ), + self::TYPE_STUDLYPHPNAME => array('id', 'name', 'secured', 'textLayoutFileName', 'textTemplateFileName', 'htmlLayoutFileName', 'htmlTemplateFileName', 'createdAt', 'updatedAt', 'version', 'versionCreatedAt', 'versionCreatedBy', ), + self::TYPE_COLNAME => array(MessageTableMap::ID, MessageTableMap::NAME, MessageTableMap::SECURED, MessageTableMap::TEXT_LAYOUT_FILE_NAME, MessageTableMap::TEXT_TEMPLATE_FILE_NAME, MessageTableMap::HTML_LAYOUT_FILE_NAME, MessageTableMap::HTML_TEMPLATE_FILE_NAME, MessageTableMap::CREATED_AT, MessageTableMap::UPDATED_AT, MessageTableMap::VERSION, MessageTableMap::VERSION_CREATED_AT, MessageTableMap::VERSION_CREATED_BY, ), + self::TYPE_RAW_COLNAME => array('ID', 'NAME', 'SECURED', 'TEXT_LAYOUT_FILE_NAME', 'TEXT_TEMPLATE_FILE_NAME', 'HTML_LAYOUT_FILE_NAME', 'HTML_TEMPLATE_FILE_NAME', 'CREATED_AT', 'UPDATED_AT', 'VERSION', 'VERSION_CREATED_AT', 'VERSION_CREATED_BY', ), + self::TYPE_FIELDNAME => array('id', 'name', 'secured', 'text_layout_file_name', 'text_template_file_name', 'html_layout_file_name', 'html_template_file_name', 'created_at', 'updated_at', 'version', 'version_created_at', 'version_created_by', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) ); /** @@ -145,12 +165,12 @@ class MessageTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Name' => 1, 'Secured' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, 'Version' => 5, 'VersionCreatedAt' => 6, 'VersionCreatedBy' => 7, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'name' => 1, 'secured' => 2, 'createdAt' => 3, 'updatedAt' => 4, 'version' => 5, 'versionCreatedAt' => 6, 'versionCreatedBy' => 7, ), - self::TYPE_COLNAME => array(MessageTableMap::ID => 0, MessageTableMap::NAME => 1, MessageTableMap::SECURED => 2, MessageTableMap::CREATED_AT => 3, MessageTableMap::UPDATED_AT => 4, MessageTableMap::VERSION => 5, MessageTableMap::VERSION_CREATED_AT => 6, MessageTableMap::VERSION_CREATED_BY => 7, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'NAME' => 1, 'SECURED' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, 'VERSION' => 5, 'VERSION_CREATED_AT' => 6, 'VERSION_CREATED_BY' => 7, ), - self::TYPE_FIELDNAME => array('id' => 0, 'name' => 1, 'secured' => 2, 'created_at' => 3, 'updated_at' => 4, 'version' => 5, 'version_created_at' => 6, 'version_created_by' => 7, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Name' => 1, 'Secured' => 2, 'TextLayoutFileName' => 3, 'TextTemplateFileName' => 4, 'HtmlLayoutFileName' => 5, 'HtmlTemplateFileName' => 6, 'CreatedAt' => 7, 'UpdatedAt' => 8, 'Version' => 9, 'VersionCreatedAt' => 10, 'VersionCreatedBy' => 11, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'name' => 1, 'secured' => 2, 'textLayoutFileName' => 3, 'textTemplateFileName' => 4, 'htmlLayoutFileName' => 5, 'htmlTemplateFileName' => 6, 'createdAt' => 7, 'updatedAt' => 8, 'version' => 9, 'versionCreatedAt' => 10, 'versionCreatedBy' => 11, ), + self::TYPE_COLNAME => array(MessageTableMap::ID => 0, MessageTableMap::NAME => 1, MessageTableMap::SECURED => 2, MessageTableMap::TEXT_LAYOUT_FILE_NAME => 3, MessageTableMap::TEXT_TEMPLATE_FILE_NAME => 4, MessageTableMap::HTML_LAYOUT_FILE_NAME => 5, MessageTableMap::HTML_TEMPLATE_FILE_NAME => 6, MessageTableMap::CREATED_AT => 7, MessageTableMap::UPDATED_AT => 8, MessageTableMap::VERSION => 9, MessageTableMap::VERSION_CREATED_AT => 10, MessageTableMap::VERSION_CREATED_BY => 11, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'NAME' => 1, 'SECURED' => 2, 'TEXT_LAYOUT_FILE_NAME' => 3, 'TEXT_TEMPLATE_FILE_NAME' => 4, 'HTML_LAYOUT_FILE_NAME' => 5, 'HTML_TEMPLATE_FILE_NAME' => 6, 'CREATED_AT' => 7, 'UPDATED_AT' => 8, 'VERSION' => 9, 'VERSION_CREATED_AT' => 10, 'VERSION_CREATED_BY' => 11, ), + self::TYPE_FIELDNAME => array('id' => 0, 'name' => 1, 'secured' => 2, 'text_layout_file_name' => 3, 'text_template_file_name' => 4, 'html_layout_file_name' => 5, 'html_template_file_name' => 6, 'created_at' => 7, 'updated_at' => 8, 'version' => 9, 'version_created_at' => 10, 'version_created_by' => 11, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) ); /** @@ -172,6 +192,10 @@ class MessageTableMap extends TableMap $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addColumn('NAME', 'Name', 'VARCHAR', true, 255, null); $this->addColumn('SECURED', 'Secured', 'TINYINT', false, null, null); + $this->addColumn('TEXT_LAYOUT_FILE_NAME', 'TextLayoutFileName', 'VARCHAR', false, 255, null); + $this->addColumn('TEXT_TEMPLATE_FILE_NAME', 'TextTemplateFileName', 'VARCHAR', false, 255, null); + $this->addColumn('HTML_LAYOUT_FILE_NAME', 'HtmlLayoutFileName', 'VARCHAR', false, 255, null); + $this->addColumn('HTML_TEMPLATE_FILE_NAME', 'HtmlTemplateFileName', 'VARCHAR', false, 255, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('VERSION', 'Version', 'INTEGER', false, null, 0); @@ -354,6 +378,10 @@ class MessageTableMap extends TableMap $criteria->addSelectColumn(MessageTableMap::ID); $criteria->addSelectColumn(MessageTableMap::NAME); $criteria->addSelectColumn(MessageTableMap::SECURED); + $criteria->addSelectColumn(MessageTableMap::TEXT_LAYOUT_FILE_NAME); + $criteria->addSelectColumn(MessageTableMap::TEXT_TEMPLATE_FILE_NAME); + $criteria->addSelectColumn(MessageTableMap::HTML_LAYOUT_FILE_NAME); + $criteria->addSelectColumn(MessageTableMap::HTML_TEMPLATE_FILE_NAME); $criteria->addSelectColumn(MessageTableMap::CREATED_AT); $criteria->addSelectColumn(MessageTableMap::UPDATED_AT); $criteria->addSelectColumn(MessageTableMap::VERSION); @@ -363,6 +391,10 @@ class MessageTableMap extends TableMap $criteria->addSelectColumn($alias . '.ID'); $criteria->addSelectColumn($alias . '.NAME'); $criteria->addSelectColumn($alias . '.SECURED'); + $criteria->addSelectColumn($alias . '.TEXT_LAYOUT_FILE_NAME'); + $criteria->addSelectColumn($alias . '.TEXT_TEMPLATE_FILE_NAME'); + $criteria->addSelectColumn($alias . '.HTML_LAYOUT_FILE_NAME'); + $criteria->addSelectColumn($alias . '.HTML_TEMPLATE_FILE_NAME'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); $criteria->addSelectColumn($alias . '.VERSION'); diff --git a/core/lib/Thelia/Model/Map/MessageVersionTableMap.php b/core/lib/Thelia/Model/Map/MessageVersionTableMap.php index db043cdc5..c4b72d126 100644 --- a/core/lib/Thelia/Model/Map/MessageVersionTableMap.php +++ b/core/lib/Thelia/Model/Map/MessageVersionTableMap.php @@ -57,7 +57,7 @@ class MessageVersionTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 8; + const NUM_COLUMNS = 12; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class MessageVersionTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 8; + const NUM_HYDRATE_COLUMNS = 12; /** * the column name for the ID field @@ -84,6 +84,26 @@ class MessageVersionTableMap extends TableMap */ const SECURED = 'message_version.SECURED'; + /** + * the column name for the TEXT_LAYOUT_FILE_NAME field + */ + const TEXT_LAYOUT_FILE_NAME = 'message_version.TEXT_LAYOUT_FILE_NAME'; + + /** + * the column name for the TEXT_TEMPLATE_FILE_NAME field + */ + const TEXT_TEMPLATE_FILE_NAME = 'message_version.TEXT_TEMPLATE_FILE_NAME'; + + /** + * the column name for the HTML_LAYOUT_FILE_NAME field + */ + const HTML_LAYOUT_FILE_NAME = 'message_version.HTML_LAYOUT_FILE_NAME'; + + /** + * the column name for the HTML_TEMPLATE_FILE_NAME field + */ + const HTML_TEMPLATE_FILE_NAME = 'message_version.HTML_TEMPLATE_FILE_NAME'; + /** * the column name for the CREATED_AT field */ @@ -121,12 +141,12 @@ class MessageVersionTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Name', 'Secured', 'CreatedAt', 'UpdatedAt', 'Version', 'VersionCreatedAt', 'VersionCreatedBy', ), - self::TYPE_STUDLYPHPNAME => array('id', 'name', 'secured', 'createdAt', 'updatedAt', 'version', 'versionCreatedAt', 'versionCreatedBy', ), - self::TYPE_COLNAME => array(MessageVersionTableMap::ID, MessageVersionTableMap::NAME, MessageVersionTableMap::SECURED, MessageVersionTableMap::CREATED_AT, MessageVersionTableMap::UPDATED_AT, MessageVersionTableMap::VERSION, MessageVersionTableMap::VERSION_CREATED_AT, MessageVersionTableMap::VERSION_CREATED_BY, ), - self::TYPE_RAW_COLNAME => array('ID', 'NAME', 'SECURED', 'CREATED_AT', 'UPDATED_AT', 'VERSION', 'VERSION_CREATED_AT', 'VERSION_CREATED_BY', ), - self::TYPE_FIELDNAME => array('id', 'name', 'secured', 'created_at', 'updated_at', 'version', 'version_created_at', 'version_created_by', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id', 'Name', 'Secured', 'TextLayoutFileName', 'TextTemplateFileName', 'HtmlLayoutFileName', 'HtmlTemplateFileName', 'CreatedAt', 'UpdatedAt', 'Version', 'VersionCreatedAt', 'VersionCreatedBy', ), + self::TYPE_STUDLYPHPNAME => array('id', 'name', 'secured', 'textLayoutFileName', 'textTemplateFileName', 'htmlLayoutFileName', 'htmlTemplateFileName', 'createdAt', 'updatedAt', 'version', 'versionCreatedAt', 'versionCreatedBy', ), + self::TYPE_COLNAME => array(MessageVersionTableMap::ID, MessageVersionTableMap::NAME, MessageVersionTableMap::SECURED, MessageVersionTableMap::TEXT_LAYOUT_FILE_NAME, MessageVersionTableMap::TEXT_TEMPLATE_FILE_NAME, MessageVersionTableMap::HTML_LAYOUT_FILE_NAME, MessageVersionTableMap::HTML_TEMPLATE_FILE_NAME, MessageVersionTableMap::CREATED_AT, MessageVersionTableMap::UPDATED_AT, MessageVersionTableMap::VERSION, MessageVersionTableMap::VERSION_CREATED_AT, MessageVersionTableMap::VERSION_CREATED_BY, ), + self::TYPE_RAW_COLNAME => array('ID', 'NAME', 'SECURED', 'TEXT_LAYOUT_FILE_NAME', 'TEXT_TEMPLATE_FILE_NAME', 'HTML_LAYOUT_FILE_NAME', 'HTML_TEMPLATE_FILE_NAME', 'CREATED_AT', 'UPDATED_AT', 'VERSION', 'VERSION_CREATED_AT', 'VERSION_CREATED_BY', ), + self::TYPE_FIELDNAME => array('id', 'name', 'secured', 'text_layout_file_name', 'text_template_file_name', 'html_layout_file_name', 'html_template_file_name', 'created_at', 'updated_at', 'version', 'version_created_at', 'version_created_by', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) ); /** @@ -136,12 +156,12 @@ class MessageVersionTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Name' => 1, 'Secured' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, 'Version' => 5, 'VersionCreatedAt' => 6, 'VersionCreatedBy' => 7, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'name' => 1, 'secured' => 2, 'createdAt' => 3, 'updatedAt' => 4, 'version' => 5, 'versionCreatedAt' => 6, 'versionCreatedBy' => 7, ), - self::TYPE_COLNAME => array(MessageVersionTableMap::ID => 0, MessageVersionTableMap::NAME => 1, MessageVersionTableMap::SECURED => 2, MessageVersionTableMap::CREATED_AT => 3, MessageVersionTableMap::UPDATED_AT => 4, MessageVersionTableMap::VERSION => 5, MessageVersionTableMap::VERSION_CREATED_AT => 6, MessageVersionTableMap::VERSION_CREATED_BY => 7, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'NAME' => 1, 'SECURED' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, 'VERSION' => 5, 'VERSION_CREATED_AT' => 6, 'VERSION_CREATED_BY' => 7, ), - self::TYPE_FIELDNAME => array('id' => 0, 'name' => 1, 'secured' => 2, 'created_at' => 3, 'updated_at' => 4, 'version' => 5, 'version_created_at' => 6, 'version_created_by' => 7, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Name' => 1, 'Secured' => 2, 'TextLayoutFileName' => 3, 'TextTemplateFileName' => 4, 'HtmlLayoutFileName' => 5, 'HtmlTemplateFileName' => 6, 'CreatedAt' => 7, 'UpdatedAt' => 8, 'Version' => 9, 'VersionCreatedAt' => 10, 'VersionCreatedBy' => 11, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'name' => 1, 'secured' => 2, 'textLayoutFileName' => 3, 'textTemplateFileName' => 4, 'htmlLayoutFileName' => 5, 'htmlTemplateFileName' => 6, 'createdAt' => 7, 'updatedAt' => 8, 'version' => 9, 'versionCreatedAt' => 10, 'versionCreatedBy' => 11, ), + self::TYPE_COLNAME => array(MessageVersionTableMap::ID => 0, MessageVersionTableMap::NAME => 1, MessageVersionTableMap::SECURED => 2, MessageVersionTableMap::TEXT_LAYOUT_FILE_NAME => 3, MessageVersionTableMap::TEXT_TEMPLATE_FILE_NAME => 4, MessageVersionTableMap::HTML_LAYOUT_FILE_NAME => 5, MessageVersionTableMap::HTML_TEMPLATE_FILE_NAME => 6, MessageVersionTableMap::CREATED_AT => 7, MessageVersionTableMap::UPDATED_AT => 8, MessageVersionTableMap::VERSION => 9, MessageVersionTableMap::VERSION_CREATED_AT => 10, MessageVersionTableMap::VERSION_CREATED_BY => 11, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'NAME' => 1, 'SECURED' => 2, 'TEXT_LAYOUT_FILE_NAME' => 3, 'TEXT_TEMPLATE_FILE_NAME' => 4, 'HTML_LAYOUT_FILE_NAME' => 5, 'HTML_TEMPLATE_FILE_NAME' => 6, 'CREATED_AT' => 7, 'UPDATED_AT' => 8, 'VERSION' => 9, 'VERSION_CREATED_AT' => 10, 'VERSION_CREATED_BY' => 11, ), + self::TYPE_FIELDNAME => array('id' => 0, 'name' => 1, 'secured' => 2, 'text_layout_file_name' => 3, 'text_template_file_name' => 4, 'html_layout_file_name' => 5, 'html_template_file_name' => 6, 'created_at' => 7, 'updated_at' => 8, 'version' => 9, 'version_created_at' => 10, 'version_created_by' => 11, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) ); /** @@ -163,6 +183,10 @@ class MessageVersionTableMap extends TableMap $this->addForeignPrimaryKey('ID', 'Id', 'INTEGER' , 'message', 'ID', true, null, null); $this->addColumn('NAME', 'Name', 'VARCHAR', true, 255, null); $this->addColumn('SECURED', 'Secured', 'TINYINT', false, null, null); + $this->addColumn('TEXT_LAYOUT_FILE_NAME', 'TextLayoutFileName', 'VARCHAR', false, 255, null); + $this->addColumn('TEXT_TEMPLATE_FILE_NAME', 'TextTemplateFileName', 'VARCHAR', false, 255, null); + $this->addColumn('HTML_LAYOUT_FILE_NAME', 'HtmlLayoutFileName', 'VARCHAR', false, 255, null); + $this->addColumn('HTML_TEMPLATE_FILE_NAME', 'HtmlTemplateFileName', 'VARCHAR', false, 255, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); $this->addPrimaryKey('VERSION', 'Version', 'INTEGER', true, null, 0); @@ -245,11 +269,11 @@ class MessageVersionTableMap extends TableMap public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) { // If the PK cannot be derived from the row, return NULL. - if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null && $row[TableMap::TYPE_NUM == $indexType ? 5 + $offset : static::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)] === null) { + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null && $row[TableMap::TYPE_NUM == $indexType ? 9 + $offset : static::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)] === null) { return null; } - return serialize(array((string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)], (string) $row[TableMap::TYPE_NUM == $indexType ? 5 + $offset : static::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)])); + return serialize(array((string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)], (string) $row[TableMap::TYPE_NUM == $indexType ? 9 + $offset : static::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)])); } /** @@ -368,6 +392,10 @@ class MessageVersionTableMap extends TableMap $criteria->addSelectColumn(MessageVersionTableMap::ID); $criteria->addSelectColumn(MessageVersionTableMap::NAME); $criteria->addSelectColumn(MessageVersionTableMap::SECURED); + $criteria->addSelectColumn(MessageVersionTableMap::TEXT_LAYOUT_FILE_NAME); + $criteria->addSelectColumn(MessageVersionTableMap::TEXT_TEMPLATE_FILE_NAME); + $criteria->addSelectColumn(MessageVersionTableMap::HTML_LAYOUT_FILE_NAME); + $criteria->addSelectColumn(MessageVersionTableMap::HTML_TEMPLATE_FILE_NAME); $criteria->addSelectColumn(MessageVersionTableMap::CREATED_AT); $criteria->addSelectColumn(MessageVersionTableMap::UPDATED_AT); $criteria->addSelectColumn(MessageVersionTableMap::VERSION); @@ -377,6 +405,10 @@ class MessageVersionTableMap extends TableMap $criteria->addSelectColumn($alias . '.ID'); $criteria->addSelectColumn($alias . '.NAME'); $criteria->addSelectColumn($alias . '.SECURED'); + $criteria->addSelectColumn($alias . '.TEXT_LAYOUT_FILE_NAME'); + $criteria->addSelectColumn($alias . '.TEXT_TEMPLATE_FILE_NAME'); + $criteria->addSelectColumn($alias . '.HTML_LAYOUT_FILE_NAME'); + $criteria->addSelectColumn($alias . '.HTML_TEMPLATE_FILE_NAME'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); $criteria->addSelectColumn($alias . '.VERSION'); diff --git a/core/lib/Thelia/Model/Map/ProductI18nTableMap.php b/core/lib/Thelia/Model/Map/ProductI18nTableMap.php index 79a01514a..e082ebccb 100644 --- a/core/lib/Thelia/Model/Map/ProductI18nTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductI18nTableMap.php @@ -57,7 +57,7 @@ class ProductI18nTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 6; + const NUM_COLUMNS = 9; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class ProductI18nTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 6; + const NUM_HYDRATE_COLUMNS = 9; /** * the column name for the ID field @@ -99,6 +99,21 @@ class ProductI18nTableMap extends TableMap */ const POSTSCRIPTUM = 'product_i18n.POSTSCRIPTUM'; + /** + * the column name for the META_TITLE field + */ + const META_TITLE = 'product_i18n.META_TITLE'; + + /** + * the column name for the META_DESCRIPTION field + */ + const META_DESCRIPTION = 'product_i18n.META_DESCRIPTION'; + + /** + * the column name for the META_KEYWORD field + */ + const META_KEYWORD = 'product_i18n.META_KEYWORD'; + /** * The default string format for model objects of the related table */ @@ -111,12 +126,12 @@ class ProductI18nTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Locale', 'Title', 'Description', 'Chapo', 'Postscriptum', ), - self::TYPE_STUDLYPHPNAME => array('id', 'locale', 'title', 'description', 'chapo', 'postscriptum', ), - self::TYPE_COLNAME => array(ProductI18nTableMap::ID, ProductI18nTableMap::LOCALE, ProductI18nTableMap::TITLE, ProductI18nTableMap::DESCRIPTION, ProductI18nTableMap::CHAPO, ProductI18nTableMap::POSTSCRIPTUM, ), - self::TYPE_RAW_COLNAME => array('ID', 'LOCALE', 'TITLE', 'DESCRIPTION', 'CHAPO', 'POSTSCRIPTUM', ), - self::TYPE_FIELDNAME => array('id', 'locale', 'title', 'description', 'chapo', 'postscriptum', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) + self::TYPE_PHPNAME => array('Id', 'Locale', 'Title', 'Description', 'Chapo', 'Postscriptum', 'MetaTitle', 'MetaDescription', 'MetaKeyword', ), + self::TYPE_STUDLYPHPNAME => array('id', 'locale', 'title', 'description', 'chapo', 'postscriptum', 'metaTitle', 'metaDescription', 'metaKeyword', ), + self::TYPE_COLNAME => array(ProductI18nTableMap::ID, ProductI18nTableMap::LOCALE, ProductI18nTableMap::TITLE, ProductI18nTableMap::DESCRIPTION, ProductI18nTableMap::CHAPO, ProductI18nTableMap::POSTSCRIPTUM, ProductI18nTableMap::META_TITLE, ProductI18nTableMap::META_DESCRIPTION, ProductI18nTableMap::META_KEYWORD, ), + self::TYPE_RAW_COLNAME => array('ID', 'LOCALE', 'TITLE', 'DESCRIPTION', 'CHAPO', 'POSTSCRIPTUM', 'META_TITLE', 'META_DESCRIPTION', 'META_KEYWORD', ), + self::TYPE_FIELDNAME => array('id', 'locale', 'title', 'description', 'chapo', 'postscriptum', 'meta_title', 'meta_description', 'meta_keyword', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) ); /** @@ -126,12 +141,12 @@ class ProductI18nTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Locale' => 1, 'Title' => 2, 'Description' => 3, 'Chapo' => 4, 'Postscriptum' => 5, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'locale' => 1, 'title' => 2, 'description' => 3, 'chapo' => 4, 'postscriptum' => 5, ), - self::TYPE_COLNAME => array(ProductI18nTableMap::ID => 0, ProductI18nTableMap::LOCALE => 1, ProductI18nTableMap::TITLE => 2, ProductI18nTableMap::DESCRIPTION => 3, ProductI18nTableMap::CHAPO => 4, ProductI18nTableMap::POSTSCRIPTUM => 5, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'LOCALE' => 1, 'TITLE' => 2, 'DESCRIPTION' => 3, 'CHAPO' => 4, 'POSTSCRIPTUM' => 5, ), - self::TYPE_FIELDNAME => array('id' => 0, 'locale' => 1, 'title' => 2, 'description' => 3, 'chapo' => 4, 'postscriptum' => 5, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Locale' => 1, 'Title' => 2, 'Description' => 3, 'Chapo' => 4, 'Postscriptum' => 5, 'MetaTitle' => 6, 'MetaDescription' => 7, 'MetaKeyword' => 8, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'locale' => 1, 'title' => 2, 'description' => 3, 'chapo' => 4, 'postscriptum' => 5, 'metaTitle' => 6, 'metaDescription' => 7, 'metaKeyword' => 8, ), + self::TYPE_COLNAME => array(ProductI18nTableMap::ID => 0, ProductI18nTableMap::LOCALE => 1, ProductI18nTableMap::TITLE => 2, ProductI18nTableMap::DESCRIPTION => 3, ProductI18nTableMap::CHAPO => 4, ProductI18nTableMap::POSTSCRIPTUM => 5, ProductI18nTableMap::META_TITLE => 6, ProductI18nTableMap::META_DESCRIPTION => 7, ProductI18nTableMap::META_KEYWORD => 8, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'LOCALE' => 1, 'TITLE' => 2, 'DESCRIPTION' => 3, 'CHAPO' => 4, 'POSTSCRIPTUM' => 5, 'META_TITLE' => 6, 'META_DESCRIPTION' => 7, 'META_KEYWORD' => 8, ), + self::TYPE_FIELDNAME => array('id' => 0, 'locale' => 1, 'title' => 2, 'description' => 3, 'chapo' => 4, 'postscriptum' => 5, 'meta_title' => 6, 'meta_description' => 7, 'meta_keyword' => 8, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) ); /** @@ -156,6 +171,9 @@ class ProductI18nTableMap extends TableMap $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); $this->addColumn('CHAPO', 'Chapo', 'LONGVARCHAR', false, null, null); $this->addColumn('POSTSCRIPTUM', 'Postscriptum', 'LONGVARCHAR', false, null, null); + $this->addColumn('META_TITLE', 'MetaTitle', 'VARCHAR', false, 255, null); + $this->addColumn('META_DESCRIPTION', 'MetaDescription', 'LONGVARCHAR', false, null, null); + $this->addColumn('META_KEYWORD', 'MetaKeyword', 'LONGVARCHAR', false, null, null); } // initialize() /** @@ -359,6 +377,9 @@ class ProductI18nTableMap extends TableMap $criteria->addSelectColumn(ProductI18nTableMap::DESCRIPTION); $criteria->addSelectColumn(ProductI18nTableMap::CHAPO); $criteria->addSelectColumn(ProductI18nTableMap::POSTSCRIPTUM); + $criteria->addSelectColumn(ProductI18nTableMap::META_TITLE); + $criteria->addSelectColumn(ProductI18nTableMap::META_DESCRIPTION); + $criteria->addSelectColumn(ProductI18nTableMap::META_KEYWORD); } else { $criteria->addSelectColumn($alias . '.ID'); $criteria->addSelectColumn($alias . '.LOCALE'); @@ -366,6 +387,9 @@ class ProductI18nTableMap extends TableMap $criteria->addSelectColumn($alias . '.DESCRIPTION'); $criteria->addSelectColumn($alias . '.CHAPO'); $criteria->addSelectColumn($alias . '.POSTSCRIPTUM'); + $criteria->addSelectColumn($alias . '.META_TITLE'); + $criteria->addSelectColumn($alias . '.META_DESCRIPTION'); + $criteria->addSelectColumn($alias . '.META_KEYWORD'); } } diff --git a/core/lib/Thelia/Model/Map/ProductTableMap.php b/core/lib/Thelia/Model/Map/ProductTableMap.php index 68a34a393..3cf8d3925 100644 --- a/core/lib/Thelia/Model/Map/ProductTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductTableMap.php @@ -230,7 +230,7 @@ class ProductTableMap extends TableMap { return array( 'timestampable' => array('create_column' => 'created_at', 'update_column' => 'updated_at', ), - 'i18n' => array('i18n_table' => '%TABLE%_i18n', 'i18n_phpname' => '%PHPNAME%I18n', 'i18n_columns' => 'title, description, chapo, postscriptum', 'locale_column' => 'locale', 'locale_length' => '5', 'default_locale' => '', 'locale_alias' => '', ), + 'i18n' => array('i18n_table' => '%TABLE%_i18n', 'i18n_phpname' => '%PHPNAME%I18n', 'i18n_columns' => 'title, description, chapo, postscriptum, meta_title, meta_description, meta_keyword', 'locale_column' => 'locale', 'locale_length' => '5', 'default_locale' => '', 'locale_alias' => '', ), 'versionable' => array('version_column' => 'version', 'version_table' => '', 'log_created_at' => 'true', 'log_created_by' => 'true', 'log_comment' => 'false', 'version_created_at_column' => 'version_created_at', 'version_created_by_column' => 'version_created_by', 'version_comment_column' => 'version_comment', ), ); } // getBehaviors() diff --git a/core/lib/Thelia/Model/Message.php b/core/lib/Thelia/Model/Message.php index 4163e6d6b..190ceff03 100755 --- a/core/lib/Thelia/Model/Message.php +++ b/core/lib/Thelia/Model/Message.php @@ -6,6 +6,8 @@ use Thelia\Model\Base\Message as BaseMessage; use Propel\Runtime\Connection\ConnectionInterface; use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\Message\MessageEvent; +use Thelia\Core\Template\ParserInterface; +use Thelia\Core\Template\TemplateHelper; class Message extends BaseMessage { @@ -64,4 +66,97 @@ class Message extends BaseMessage { { $this->dispatchEvent(TheliaEvents::AFTER_DELETEMESSAGE, new MessageEvent($this)); } -} + + /** + * Calculate the message body, given the HTML entered in the back-office, the message layout, and the message template + */ + protected function getMessageBody($parser, $message, $layout, $template) { + + $body = false; + + $mail_template_path = TemplateHelper::getInstance()->getActiveMailTemplate()->getAbsolutePath() . DS; + + // Try to get the body from template file, if a file is defined + if (! empty($template)) { + try { + + $body = $parser->render($mail_template_path . $template); + } catch (ResourceNotFoundException $ex) { + // Ignore this. + } + } + + // We did not get it ? Use the message entered in the back-office + if ($body === false) { + $body = $parser->renderString($message); + } + + // Do we have a layout ? + if (! empty($layout)) { + + // Populate the message body variable + $parser->assign('message_body', $body); + + // Render the layout file + $body = $parser->render($mail_template_path . $layout); + } + + return $body; + } + + /** + * Get the HTML message body + */ + public function getHtmlMessageBody(ParserInterface $parser) { + + return $this->getMessageBody( + $parser, + $this->getHtmlMessage(), + $this->getHtmlLayoutFileName(), + $this->getHtmlTemplateFileName() + ); + } + + /** + * Get the TEXT message body + */ + public function getTextMessageBody(ParserInterface $parser) { + + return $this->getMessageBody( + $parser, + $this->getTextMessage(), + $this->getTextLayoutFileName(), + $this->getTextTemplateFileName() + ); + } + + /** + * Add a subject and a body (TEXT, HTML or both, depending on the message + * configuration. + */ + public function buildMessage($parser, \Swift_Message $messageInstance) { + + $subject = $parser->fetch(sprintf("string:%s", $this->getSubject())); + $htmlMessage = $this->getHtmlMessageBody($parser); + $textMessage = $this->getTextMessageBody($parser); + + $messageInstance->setSubject($subject); + + // If we do not have an HTML message + if (empty($htmlMessage)) { + // Message body is the text message + $messageInstance->setBody($textMessage, 'text/plain'); + } + else { + // The main body is the HTML messahe + $messageInstance->setBody($htmlMessage, 'text/html'); + + // Use the text as a message part, if we have one. + if (! empty($textMessage)) { + $messageInstance->addPart($textMessage, 'text/plain'); + } + } + + return $messageInstance; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Model/Module.php b/core/lib/Thelia/Model/Module.php index b2518169d..3d45746cc 100755 --- a/core/lib/Thelia/Model/Module.php +++ b/core/lib/Thelia/Model/Module.php @@ -22,6 +22,13 @@ class Module extends BaseModule return ucfirst($this->getCode()); } + /** + * @return the module's base directory path, relative to THELIA_MODULE_DIR + */ + public function getAbsoluteBaseDir() { + return THELIA_MODULE_DIR . $this->getBaseDir(); + } + /** * @return the module's config directory path, relative to THELIA_MODULE_DIR */ @@ -29,10 +36,24 @@ class Module extends BaseModule return $this->getBaseDir() . DS . "Config"; } + /** + * @return the module's config absolute directory path + */ + public function getAbsoluteConfigPath() { + return THELIA_MODULE_DIR . $this->getConfigPath(); + } + /** * @return the module's i18N directory path, relative to THELIA_MODULE_DIR */ public function getI18nPath() { return $this->getBaseDir() . DS . "I18n"; } -} + + /** + * @return the module's i18N absolute directory path + */ + public function getAbsoluteI18nPath() { + return THELIA_MODULE_DIR . $this->getI18nPath(); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tests/Model/Message.php b/core/lib/Thelia/Tests/Model/Message.php new file mode 100644 index 000000000..1b7cd5716 --- /dev/null +++ b/core/lib/Thelia/Tests/Model/Message.php @@ -0,0 +1,337 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Model; + + +use Thelia\Model\ConfigQuery; +use Symfony\Component\Filesystem\Filesystem; +use Thelia\Model\Message; +use Thelia\Core\Template\Smarty\SmartyParser; +use Thelia\Core\Template\ParserContext; +use Thelia\Core\Template\TemplateHelper; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; +use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\HttpFoundation\Session\Session; + +/** + * Class CustomerTest + * @package Thelia\Tests\Action + * @author Etienne Roudeix + */ +class MessageTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ContainerBuilder $container + */ + protected $container, $parser; + + private $backup_mail_template = 'undefined'; + + public function setUp() + { + $this->backup_mail_template = ConfigQuery::read('active-mail-template', 'default'); + + ConfigQuery::write('active-mail-template', 'test'); + + @mkdir(TemplateHelper::getInstance()->getActiveMailTemplate()->getAbsolutePath(), 0777, true); + + $container = new ContainerBuilder(); + + $session = new Session(new MockArraySessionStorage()); + $request = new Request(); + $dispatcher = $this->getMock("Symfony\Component\EventDispatcher\EventDispatcherInterface"); + + $request->setSession($session); + + /* + * public function __construct( + Request $request, EventDispatcherInterface $dispatcher, ParserContext $parserContext, + $env = "prod", $debug = false) + + */ + $container->set("event_dispatcher", $dispatcher); + $container->set('request', $request); + + $this->parser = new SmartyParser($request, $dispatcher, new ParserContext($request), 'dev', true); + $this->parser->setTemplate(TemplateHelper::getInstance()->getActiveMailTemplate()); + + $container->set('thelia.parser', $this->parser); + + $this->container = $container; + } + + /** + * Create message with HTML and TEXT body from message HTMl and TEXT fields + */ + public function testMessageWithTextAndHtmlBody() + { + $message = new Message(); + + $message->setLocale('fr_FR'); + + $message->setSubject("The subject"); + $message->setHtmlMessage("The HTML content"); + $message->setTextMessage("The TEXT content"); + + $instance = \Swift_Message::newInstance(); + + $message->buildMessage($this->parser, $instance); + + $this->assertEquals("The subject", $instance->getSubject()); + $this->assertEquals("The HTML content", $instance->getBody()); + $this->assertEquals("The TEXT content", $instance->getChildren()[0]->getBody()); + } + + /** + * Create message with TEXT body only from message HTMl and TEXT fields + */ + public function testMessageWithTextOnlyBody() + { + $message = new Message(); + + $message->setLocale('fr_FR'); + + $message->setSubject("The subject"); + $message->setTextMessage("The TEXT content"); + + $instance = \Swift_Message::newInstance(); + + $message->buildMessage($this->parser, $instance); + + $this->assertEquals("The subject", $instance->getSubject()); + $this->assertEquals("The TEXT content", $instance->getBody()); + $this->assertEquals(0, count($instance->getChildren())); + } + + /** + * Create message with HTML and TEXT body from message HTMl and TEXT fields + * using a text and a html layout + */ + public function testMessageWithTextAndHtmlBodyAndTextAndHtmlLayout() + { + $message = new Message(); + + $message->setLocale('fr_FR'); + + $message->setSubject("The subject"); + $message->setTextMessage("The TEXT content"); + $message->setHtmlMessage("The HTML content"); + + $message->setHtmlLayoutFileName('layout.html.tpl'); + $message->setTextLayoutFileName('layout.text.tpl'); + + $path = TemplateHelper::getInstance()->getActiveMailTemplate()->getAbsolutePath(); + + file_put_contents($path.DS.'layout.html.tpl', 'HTML Layout: {$message_body nofilter}'); + file_put_contents($path.DS.'layout.text.tpl', 'TEXT Layout: {$message_body nofilter}'); + + $instance = \Swift_Message::newInstance(); + + $message->buildMessage($this->parser, $instance); + + $this->assertEquals("The subject", $instance->getSubject()); + $this->assertEquals("HTML Layout: The HTML content", $instance->getBody()); + $this->assertEquals("TEXT Layout: The TEXT content", $instance->getChildren()[0]->getBody()); + } + + /** + * Create message with TEXT only body from message HTMl and TEXT fields + * using a text only layout + */ + public function testMessageWithTextOnlyBodyAndTextOnlyLayout() + { + $message = new Message(); + + $message->setLocale('fr_FR'); + + $message->setSubject("The subject"); + $message->setTextMessage("The & content"); + + $message->setTextLayoutFileName('layout3.text.tpl'); + + $path = TemplateHelper::getInstance()->getActiveMailTemplate()->getAbsolutePath(); + + file_put_contents($path.DS.'layout3.text.tpl', 'TEXT Layout 3: {$message_body nofilter} :-) <>'); + + $instance = \Swift_Message::newInstance(); + + $message->buildMessage($this->parser, $instance); + + $this->assertEquals("The subject", $instance->getSubject()); + $this->assertEquals("TEXT Layout 3: The & content :-) <>", $instance->getBody()); + $this->assertEquals(0, count($instance->getChildren())); + } + + /** + * Create message with TEXT and HTML body from message HTMl and TEXT fields + * using a text only layout + */ + public function testMessageWithTextAndHtmlBodyAndTextOnlyLayout() + { + $message = new Message(); + + $message->setLocale('fr_FR'); + + $message->setSubject("The subject"); + $message->setTextMessage("The & content"); + $message->setHtmlMessage("The & content"); + + $message->setTextLayoutFileName('layout3.text.tpl'); + + $path = TemplateHelper::getInstance()->getActiveMailTemplate()->getAbsolutePath(); + + file_put_contents($path.DS.'layout3.text.tpl', 'TEXT Layout 3: {$message_body nofilter} :-) <>'); + + $instance = \Swift_Message::newInstance(); + + $message->buildMessage($this->parser, $instance); + + $this->assertEquals("The subject", $instance->getSubject()); + $this->assertEquals("The & content", $instance->getBody()); + $this->assertEquals("TEXT Layout 3: The & content :-) <>", $instance->getChildren()[0]->getBody()); + } + + /** + * Create message with HTML and TEXT body from template HTMl and TEXT fields + * using a text and a html layout + */ + public function testMessageWithTextAndHtmlBodyAndTextAndHtmlLayoutAndTextAndHtmlTemplate() + { + $message = new Message(); + + $message->setLocale('fr_FR'); + + $message->setSubject("The subject"); + $message->setTextMessage("The TEXT content"); + $message->setHtmlMessage("The HTML content"); + + $message->setTextTemplateFileName('template4-text.txt'); + $message->setHtmlTemplateFileName('template4-html.html'); + + $message->setHtmlLayoutFileName('layout4.html.tpl'); + $message->setTextLayoutFileName('layout4.text.tpl'); + + $path = TemplateHelper::getInstance()->getActiveMailTemplate()->getAbsolutePath(); + + $this->parser->assign('myvar', 'my-value'); + + file_put_contents($path.DS.'layout4.html.tpl', 'HTML Layout 4: {$message_body nofilter}'); + file_put_contents($path.DS.'layout4.text.tpl', 'TEXT Layout 4: {$message_body nofilter}'); + + file_put_contents($path.DS.'template4-html.html', 'HTML