From 0661f5dd3feb096fa257359bdaf8dd6e4a53c55b Mon Sep 17 00:00:00 2001 From: lubiana Date: Sat, 22 Jun 2024 22:20:51 +0200 Subject: [PATCH 001/100] more-deployment --- .forgejo/workflows/release.yml | 7 +++++-- deploy/prepare-deploy.sh | 10 +--------- public/static/img/slice-of-pizza.png | Bin 0 -> 22501 bytes templates/base.html.twig | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) create mode 100644 public/static/img/slice-of-pizza.png diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index 9602add..a1c6c78 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -16,5 +16,8 @@ jobs: git clone --branch $GITHUB_REF_NAME https://${TOKEN}@${GIT_SERVER}/${REPO}.git . git fetch git checkout ${{ github.head_ref }} - - name: list - run: ls + - name: prepare deploy + run: sh ./deploy/prepare-deploy.sh + + + diff --git a/deploy/prepare-deploy.sh b/deploy/prepare-deploy.sh index c0ad1ed..53f4e46 100644 --- a/deploy/prepare-deploy.sh +++ b/deploy/prepare-deploy.sh @@ -17,14 +17,6 @@ done rm ./bin/phpunit APP_ENV=prod composer install --no-dev -a -mkdir -p ~/.ssh/ -# Print the SSH key, replacing newline characters with actual new lines -echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa -# Set appropriate permissions for the SSH key -chmod 600 ~/.ssh/id_rsa -# Add the remote host's key to the known_hosts file to avoid authenticity confirmation -ssh-keyscan -H $HOST >> ~/.ssh/known_hosts -# SCP files to the remote host -rsync -avz --delete public/ ${USERNAME}@${HOST}:${TARGETDIR} + diff --git a/public/static/img/slice-of-pizza.png b/public/static/img/slice-of-pizza.png new file mode 100644 index 0000000000000000000000000000000000000000..300e7e73f58771df77ac33d9f349463cd4b095f7 GIT binary patch literal 22501 zcmX`T1zgn6^FMxcNq2Wkqk<>hNOyOLfV2nF2$B*WDcvoKbR6A{fb`KNaCFD-#ryOB ze|;z@w>vvCJM)~`*;yks)D&>BsjxvH5U!GAt)Z6bhwW4S6CdVoN9-A{jzlDP4xfge(O${BcSyV!X`EZuEE5D0|V;e(@xwWX^q zuZz2V`r#WY5QqV!BrB!kow2{daJ$fFipNOhqgof3?|6#r4^KA_CP7HQzJ`;nIhGL#OD>CEmp`>&_?95De z`|gmQv@X6drR>wF=(%s38I0(4rnq_Yq!(;kbj*jYgJONDs<}v&i!9u@OT_6bhdTP- z!wko1kq_E7g1jHdll0__Gy6$&=Lw87jgSaVN@~Qf(R3FG+%X-M$*ZgpZME!WgIsC3m|7R}w>#4vkL17N>h*>eqCs6DfNf zXJMtbd)ES)ms_ePuJtnmB!2Xu>6E&WZ~Wqn*ddK2SsY~^ny<)<+4C|$!-ayLA0}oESEAL4>D5G|c4^79Qt6soiJE#Dq>fCISj+~lokcqnSfwC}~6jwd7 zUNkSIe&@({>U3-4z-Oq4WA@K+ab4+48-8DqEfQHW(=lBcO668O%o} zD`@S{;d3#fF_^Q@Jh|_XlFsw)EE(QkA8<=F`nN+wtg}Y3gOozSO_-mp{&}F8aR`iQ zCy;}p3k0u6Q){AiW*L4}boI1F>IOjhHUfRk{$`=TKBx8CqP2Vf+WXAoAxxgJE)0{@ zO-8o2?7A#Eb|UsPeO`^1;6?SXim$0Iuo$6HBmn5{#bx&Z-Lyx>o@i8t`lgSM_3&@8 ze3A`e*kwx`zSAY`piLYpNLv@e-PxI9eKVn#>YFkB|&tCxVmpEzZ2+|2df~ zJSy(HJ|=R|xg@se9;3*h zaKldMnNQxY*v{sGdsDGAR*@plXACy_G;;&bdrTAk?FEVL(HNKmYMllLZ1eO*BF!uN zxqp`XS*xh-1hv!tYBC4 zdTUq7h1}?Y%sGHUCw>vjM=egsX@4l#WMw+6Eo-3?S%$D#$M{5D1l<|vxNz=MHsr4l zCHk=oD%hbhto{cbbdhGbCsgD5AvHInHZcPEKNTkEv2R*S!#V(O);y!_e*+~ALM?k! z_Vn1e^kjbc@=^`f+g)l7q0nh_DniKvIlohAVhXO+E;cpKdGPeQKV3)oYWO z6dd{!d1WH--Ua&rI&ZEiy8AC1=>R4~X{|zwi~Y&>`QjS`r`w1Bxkrw?6CK)Mgp`{s7{4)6GMFnU|%Jv1Uj=X#)UCInY!h?ryHRFV1g9p{#nK zvi(@z@13i4`q4+cD}}R{vlP~4jOYP{T=3_wUfeJAn1XNpF_ghzQQd(-Tb^x^?d8Hj zb1Ud|j6hNH7ukjvWY;rwxc-k`10%99l)?nkAgrq=Jn7`{F2{DkAiEj0juF7!(UfgF znDX}+sP)Ic!Gp5tfqF{>yWuyl34OpxnHL$`ioF!pTzYvog<5~wFZm9wW+ABszmfTs z%d0Z{u-&c$IZo6PDPgA+)-j@a{!ELgeup7(mv97FMavLL1pA<~lInwhq{j)bt{Fb+ zlh$G=aSV$GQ-)Oi;We7U_SML)6y7?N&cnMca4D7zK09$rzb%lDHTtMO;#2wbbbR3hK|DvChH&v)(N@LUas0Lg zdMUJD83$8GuJQ4-1{?{%E%z!daoU%L7S!V=+AtodjN{-G)>MXsN$FPPORf`r7=i0x zl~!RBBm*zQTP>`!)|aJY6xPF*6?&UO3op+f6=ujO-bWzkm^SDZUPvSuq@ZlyKBQ%W77m$oOtn@hlVcTcLa=HWCTJ7j4Sn!T>VF+kZts7X&k_6 z9c?z8_9{LXu^*u=3W<+jom(BBU(LiYllHI&5k=FH~D9%&B5we$0*$=w(?(m(nBoc^HDc4hC^0JH?-KgZcOxgBjtL^4v*i7Ms;GDU2q}{f++(5x_Xm zSdAXhJp2;-@8a;1cFRCZ8$@C=O?nW>B|wjSaQ3tbF`^+$Tz*+1SHr+AA8l1$r>z zCYJ}+^@h<6Z3Tc{*Mf6CxlQcQ?W-pZ_v#E_cK+>j_f#c{lC;7O0`T^0%|j9cJ^KHQ zxOb|bpUXT(uBvrs{vi`4&5{SIFqyd#By6Ok-h0(c@rU12GIWgmw2@T&g8Ik^q{o|G zV-TSa;=4%e0;D*87l)kU&`NDZAU<;vcp z-ns32inO)j2Bzw;wg-#TMUH3U1%u$=oUFc=fTL)w5$ZPDEfm419UK2jnqs#vnL>*k z1a5N5?&xz$>H36$F_S7`7!i%{ccUHxz4R4HK01&57`X#Ei3b|DwQ)F-AceN&0Lz5u8U3vu2x z%c>&2_gjC~?gDh*x>ap77Pi~+LnWJ;L~;9Cu6?FnZA+; z-Z~DzecD7j*Xk>obvAI6~a2H!F$_(zjIy#-iWV={%4O z{0$f6_O2+CdM%%p-k4pF$4NF>xLo-q?xupaa=3X=+_&@IV!k0Cz!?AqUxtO<&24)f zh`QFOQ=QWUft&2=O84Ua#~Re8I8h<$(X&FG$_uF<;nH_^c1HjA-$NCD+)N52f@zSfLEAvV|17{wM2Y(mJu($6jlgYl;HB z1==ys0kelqt3Mie7pOmMCPCF$qaG_R03+fha7R<%9Q4Z)$6!V4KE zL?zhR7=SnbJh=v~g|0+MOivRhF~(Zu3CeD!ij>`bYKU_r(dL!X(HiVY)zajQlTD0L z)~VC7R1p)Izz2dpOz**m=cS6J6uL4I!~bFWtrI6tt{o$cYo@FBlHJIO4Z zsfsI9Yl2zQNxxwEd?Epa5@R8%RvD>Z&@O~f{g zGvbV-TFIyie07d3nu(W={tazbur$LwW#oaz-ic}&Qqo0a-NE}MyIliKuJ1KsdS6Ca zP|cWgm~iH}7KnoKQl?&f6QJ9`jxEwt@Gw@)t#$tvxK{9ZHsH=?8lv$olVpdN&r9mEbs`~&?3Fu(ie{v64BPSJCfZN=4rVogfjlN=$8u5@Qnoc zDf1>AgSyB;g!jxkd;D>;seA6h~Rv=oOnf|8YzZqIsYqCKSlCC1Nij``gJ zluG!lj@q?*asth}`zw|jSobnw=6Wf|)^Um&6{FXv4opmK z5&SCuq-{D%`;aW%SaOEonP{sTZifk?_`ZFHKaVO4_0EK}#ci>^;y>F*W_aH7rCBAU zzvI=)MJZ#Yw#+XBg?&!?D!X9!+53;oCr@pN^IJ%v#1)p1b}uXxYsV^OjRLyam{nlN*L^QWu< zA$Qc=`*fkNGI+7>wJO+YURK1Qp4BT0MhOS^qXTh%M zy!}S1u$cP7R6E-qrALGx)OvpZ%^y2`d8|Cavjg7hK!t?+W`G0kxi`q#VodBEjA)V* zK32>iJLGPxgFn)2^fV_<>F=TEF_h&D8@#1qQNd0HW#BnL;yDList?`;q!>u4u`#gR#;#P#5k)N~mdLi1kdQ>hSAdks^8* z&V0Y@|6w-QesDuK<=ATWLfqnpJ{R2qBGepo}@%!efcR^ptjE)^cmJyySnlV)Nl$ zmWK~NjF#(YQ*|$8?e0(kWeJ@Y4CYJl{)EB=iazFjt9Bg11k=-QwSVxf;kUhzsQVRo z!}^Mtwh0f^p4raog=f>7J5I#!VU}fhYW(i~uLNpq6@OIG)rM$|R%XOQ$El>~1HTO15erAnG&f+A7Mo9g=)lCLlNY~c| zAYQ5?LyNWnN9r4}ulu$Ai|I*Z_ytqlfQi*R0t^YiH3>Z5`-b;E3y2`0e`EtRdawbv z#XB~;tSKj%yWUhCD$1DI3Gnd6NEb=?J}2^6K<(N51FQO7pJf#*+IHPptW~cArNLvDyMgvh6;yK`)^=AKar5Qnwv4nIS z`?>9qj3e&EF?7W)Xjo_QdA#9@-RE?S*`RQNIVOHvy)4e(C(rP^_jhQmd=dPGgw&)Z z&|HGX-CcT-we!DaLkj^xC-d|6@0|eWi!~k}9`->C;qOT4a@%B~zr;M2ArL#8O7frH zWE7!X^k^T^4}k`ecrsZJ&%UeJU)Hnn9pk@+kR7;n&fhFfI^M!>&+uuEvEh-o-W9)q z)2geK?XRr$tyh30jzTi>qv*rl;U)%hzcbIoGYWktvl+;sNF8d=ErroQ{4cSCLfd1F zOZ~+Nu;Chk-4}<0B|!&T23~S&JJ9feqmq;iAj5e?J=3innlf-l>)S^g8P0;s{@`r1 zUYy6+^bLEbY8xS;wCIHSI`POPUJ3RGIQ8;yaWD9W&(^s`BuF)jY2fDFOylT1YdJNf zmzXy<0Qn=l63LMNAyS>X<`jG;$i1TbYcA-{0o zIFZ?zbs$Fv7wLx4%E28bo%qLHC!WsTbT=4%Z>TGqS`H*M%=DoKl$RS$4?e0aKBrGK`xxzN1{y?GnqM zla-n_Ofx&Tfy_)QZ43#w!q(LtR8t*7iObW>hrD-u-5{NmKtu{)y&5FenZc5!;E zPP~NQ69^qt_Q#d{&Tz?wIaW<%p;E-TKX1f|jB@+uWkM<2!+Ho{dmMcRhL$S!Kcp*iSNwni+1vV z7X%Z-HAW49lWgC`(Gb3#G^)X6!bI#S6bjuLrn@zluhIjqi)|Hx7OleB6zir(I3Y)((2^Dcc z;$&zYljNqYZT2;RmW%c^xI>|@0*WYsPVNjOn z8p#KjB%oBu(wq8;YF2+MLE_oZ%VU*TOs6R1O9j5BoA%Tqi2BZOox9egS3C5Lw|Bw8dO7yx4b7PL8$=NexyI2IHHe(GSq zg~VLDsGW_Mr_{H}OzhiIh!{+T9PTw7qL_qZxc9hMNt=FfdIZ43%)(+v^w z!w~4b`sw1EpfH0!*~Yi~FN;16^A-8Yy$fQ;%4F=L?xqUl@5u!Y%_kvOzZWnwu}EUO zF&C@DU7ii>0rU3lcWZqX8y;HC&Yym>;j0E>9Bw$lDTI4zf;$hLncp-81a;_CGUuR_ z+=dr&-#pkdnHRoKX@a!0`OEWGy+W=ko%vhA8Jy;ko_e`Bqf@a6dER79@u09*Z|fqj z$W8JPw`O+@?831e=|}O`!^slQ3M_1;TEp90op-1G@m0^bb-gN#rSyP<9ye3A%1MZn zcHEH1+NqI4W=1l`b(|W8#Rh$tcQJxxm*r2+u76a`?GrU6>&@e3%Q|rpMK=*QxfM4l zUURLT+b^EF_Ls@u7x!WIKDTGzcBVNHEK);NHR?E`$3D&~SqZ6%#KrvX`2w`jz*(6oHjy?i=4iI-^Rvspkl3J3GARjS zGHml77m<%xUX9C!UWTWUOsl@ry9;|>j*_yeAN^wIifj0N?7sZC%4S=B)|E}F_-8SR z1vH7W2Ok_1hel~aiPzax^^$KHMS=~MH{mEuev_7%0(i-U3m7U7u9{RbBi0yU%0+%-}OUEX+yzZa>EF@!^aB#gP z@MpC4iy23g9x4dBa1fm@-UgC*^;DOb^oBwNR-rCT+eX_v_}ilgoHGVUAQc9I7zF%w zeLCC7>gWx!vc_`tw4+I<5}PnINYc&MIUF$)?Q|8I{QC@4@6PJX9P>t#xl>fLs8BzZ zC7)jncyy+ye>b}_r{azx+M=;sCJaq-vB`arQ#!}G|0w0(9oKnOOzmOc*5o>VX4aFr z4~`IEv$l#9H72`U+y-N^+?`QYr3F$SX~9K_Sbr>D#`*eV47_}$@9;?i>k$h$zejSx zF-H%4nh`YWif5|sk+zf{GjE@5n$Hci(XH`FJJcdbdQ+cqzK#^%19$&nZ3aC*G{fS)!~<`DwD+;VLUnQ@-CqsN|+ydV(K5UIw30^?-fndA69Oj{W5 z;PYhF0bP)QUFVI7xZ>hy;{YEhy7?8yi7s5UB|68iIWuOj(hpqsJ5Rt)TDHM#bWwQg z;FBZIF&d~{>5R~#9fFrV_z!hy9W1v#;jdw~4h|Dwt4*YRwk@#^?p-a&11a`xIdk0@ z!bSbK9y_xZh-wN?r-Lq$ONI;gO(8su^iaBmb=dwNPGycvJ?fvm2zMoK4TDDOPdKbb?~663_HJaHzM!rbGO3yxmg*7BZ~2h>WR*98y;F zQi*kuefunfC*<-zG>%2r#opZw@pHL3=dB#|R%y@kPpRis+})nx*m<6btx*N>f&HVu6>nz6onE2AI*`xP3kn9E6~wXoLh*jrh66;~Tm z59^k}{+@(S9&QMDnG8+w^NGL4LmGk0d8Un%Cw}5Xe)WUw6%jWwr}oDkU6@Ra-g}Ji z1^JhBD|*1nO0Vqd77FxQCe$93$Ppn4d{{kIg@}zu&!#FZ)Gt-Uc^H1h0{OZ9ZHfwr z&oB>QG7cyxA|Sqdaim<_*pJO;&5YYNQa5xmE^L)_?zLqv7@zFB%e576pnRC=)c}!mNG_@L?zYXvx12j_%PXT?zc>WTmMh7J z_|umkjx(*FYng&TCcnH{;~VR3mK^?#u_v*8P_IHS(zsG5y!iin0h-=YTo?DwK7SjY zdqtajTpW;ZCJfBGau;o@dgK(CY!1o}Z>id%4)9w^+@b@+lksrBVUkFn*| z&7gAHSFUBGu2-0w@N2cn71=ti=S3$>!o+BjW=H*IjK=AxyL8k@id@e9Vw_Osd5#!A zv+?_{z9)fNSW$2iWo~~A2NR+`{lRZMr7gIbk;ov)QcsllGAs%OYvPe_LuS;0d2k$N z^Xk7VlvW)6<{V2QBh+PW7?dKSwZs!b+8~>OWJW^OX=Vxq-J0_B?&<-3v&29&W^*)U zAfeF);?^-6LapD=)-`b#z@}EX3)D_xa@09jF0)Ao97%dI zyDx#zs6KAXwELp~xIzJC{5cg%G{21%&@`%ss%SY(Ktg&6C9r#_S${|0PATv9)mdnK zU1G{?h1}o?Xr^(4m`dVfD=FgS-C@M3%++5F_oOd%liO?2TzaK)uS^-|SHOyFJw&IB zaKXYE=)pbfkq}&zjRgS?5+!mt$;?6O*0}ouWO1Jh44(D4MDlQ&*_Qde{Vyyi zys)VTffR=^l#Weh9F)&13srt2Yxou#GwvN{GTqlyRjWxhA#~W4CzQ@KfhAa*(Jb7? z{G$SZumTxkOmOHJ@8ZZj{zJapdL0lpA@j?Ivy zU01LI4i+W)<*p|*kKf~BtzV(52l$}vR?Vhr_7DcQUwBE83OUHIrBPv(8*rm=m0ytd zf^VfTVjKNkg(TGgm82exCMBv5e+u3cHK>g)CYH8J3O$)WfgkG5X{L3BO)>&?OVK7d z>9E|;#g0Ckn`eIAoA=XxX+-$@IvOh&M3CzbkbqxMO_sN zZSW+1h3!|(|Ah-p99&J1&BRTBX6pZIzyy%z#U1sLFP+4$obfa4+L$f9u0XR955J9QME zZNldV`s%%fx=W213ol5n$#-}B$04zw-t_}9=a(^FqW`uCnZuXyA8%T5vZE`9G~^~w zk}BVS4V-w*ZKW>sKgd0wYyeF85?vPtaQ+T8^W)kv&(2vUgK^&NK>?Ix;vPoK65d(7 z+49xcZ@VPr3l9jy``jGu+0Cfi^A5_on+)|y><&u3&N9w`*{8_no&L3#rUn31^=mv$ zbzD=x#uVtaH#}e-G|!gxvDNI;=Wy2W!=d5Vl=F?=(KUW_M9Igl{6Dmof&Ch7_m#JW&e#6#V)Yef* ztaSn#X3CA)gm-6QR1L80Jje3fI!eS6Q?rFCYgfvK)wcbBavZM!{FKN>qdTWvH|QkS z|DmXw8A<@_heYg0(mU@%Rf&3xK;+4?q}z!i zUUza%!2!UQBb|xA7fho2o6272nE2VR(PLGiaf8%%cCTOWe1Z$avR-1#6#-u7FNoEd za;ugg))Yrl0h>r&qlFQByWwYw)!*Q)Mw148euB>*XPN7%C-J_OOEQ(Ui~pwCOlKrp zy1qO@m8pM%Fq>3ZXooughL8poC&Vt(2Q43f`+kMm&o`ablDxr?HomB5qdMafBBlBX zTKpewt^)lSG7(T6C!{prOzCAv)U!dU!>_o$QX0Ou`@ZQqO;x$__EwSC@dyGK&>9e$ z@#i-Z2}neII)0@ zB_ElvzWMv3q>S~=Tdc9uOs4fO)O%b)x>P#??Rn6he3%SNFlkU%eC#2d`>q^tr-VS} zhV=?mmBe(U##c|;`RbXJ_8RwOp2N@VHT~{ICNowAh$a~4iooG2p#5rS65 zU;DaT&@x9>fMP;CE4Y;^N{wF%dc(B5>zOKH&?|Nx4R44oJ=%Jl%Fv;%-Tc6rQ|xHO zU?G!XAj}fzDvHswN2s>Hh70s^iJ*NK&q2lUV?XZ8#8ge;>W~IsU$OmuQt`Kmzgud% z`>+v6L_sysk-}7xlL911bb@HufmNYZlf9pM(A@d7zAu;e3&Sm+1r2Q}u@MVi&6h+J zS$VuNr`q-8x5TKARk2U^j1MFwdBEsrfm^;;pU*w2S3dNbMOMOMI=Enw)UtI(l?+QS z1kzGK$-~&~6iUN|1>UU{E6)md-B}@;@(L)Z?&P`;66n!Dbuk=TORUN!;`&F(E4pHT zyxcEbvFUjh@_S_<@)yVNQ5H_3HvZK=jBdV${n3d_$54ID*)Vg_Pg5exNGt_rHu%`Q zFHq5KW1?-vzZp&N1R8QWdXC)%e^y4Oqo^WuPXa4Tmo>)$yE9HKy5u}$fjbQUYWM>v zBph4qJTs^4i%Fv&klZ@N=Z@-2RC{}oqZe~b}P2q?$NlaF|M`++{eKJ%_75uac9!%jx1*hl3YfB zNhbAEF_Mm85TYMYxDTFX1Wrleu8~A<$ic_O@xq_eagOt0PzsPVX0->mYZbR__6aQ$ z53sAyj7A3qPsH6=gli$<`7~KZE~*qJvS#M7BnV6xf`>V#S1{s2Cgj%PpnO+S zThD^2mRC(|f&PEFZvxo`u?SMrp6J1Mz7MkfcP(4q^- zdu^Sk_=lJGN;(a^P|4XL{I>g z1rN+ zXGJEx4UkHR3>W>m`)U7Mu*1RTz35&|JR2t8aJT4b^5^uLG`F9~8ge1LU5D?egxEx> z(Mp<+^14)Es+k5>P8(jx6(F4i&x=Kz6B)Q@j1ts>u%S^8d5;a>5C`T?we@@E;biwMRd0xCJ*m>o@&CjM9 zvMqgdcV?c%mZ|c2@$HlFVPivUBVsU*g3PCzio%odV5$F>yrY)H24afw1Mc@Qug6=H zWz%i2EEymf5)hfoJIVc?$k||r^3`hw8DV8rp+@@w)PnzQ46B0uw)>H}K`+*%??rz0 zLGY|6SuWQG1^*N^6`-9|U1sKCC(_1jNc;oK>jCr#Mav=C5q_P(I4#zS=jz<5u+KIT zl81aGX?x)Q?#QQ{c3h;MRw%q0S>tWbnthOhe;=^+;_x8WkdDG36RRJPw&_l&dYpcR z$=E~!VtivY{vvywilFH&P`#4I9IGed*Ze@YVRitP^NOf8A*at>26GopGJf^I#jSR}a`_@3-#RjC-pb-m5rMitY0MCJ>iX;N)tF{@cJ zU=18D;ILsQvnuvfLj7iev;nUO%YZMG z52ies#YjQpNrc7Wx#SA?E4?KK$#QXnAuu|-v)FbZxf14KlPQM26Z}KW`OA9;V*UXL zne`;^@-t>QL5*hJGB)Go_d%jI%36Kw2~Oa+zTYuM^_vicUtrzE`-C##0){JUAw`$m zt8-~$jN${C&s0<1C#ydI0Qd2v3ZEM3NcJz^`#&8W;Yh~Y!>L@6FR=^Lle~TFmgfu5 zI`yRvrAIEB>-zOL$<&hoGx1Y!Ks9_QPV{cFdw_HMjRK+yvW85)&%LuAuTifj#T*M> z%;ucj0;?QE?koT?48Ra!Y;F+U?!1S4Su;IIvloVb7xLZSU5HTxqtoMs z5culrgxKVS2MlvAb179)4@4ySH}g*U>t-9^^+lT9U`8XH%@+@J^oeAcqgo+&)eZ4u zshFRBd0s5?LeE3zuzkQ!d;K0_8Eh)VthVy!Aw{_OhDnBHAIp=p_x#HLA!)F%FNd^L{cPZweN7)I}2dg22|2JWuUoscz(E?)2|PR-kWNqebthAcVCSh&##sj2SNe#ZmoiQ-q_MS3W<;hdbKSJ ztWRH(-d6x%L7~l!{C6NN{o~c>#7+f>CBDlPWB&r+%eqVrNGg|k-HF<R!&zW{A~sjl>yV(?Sit~Wi{k|6`EvLPmifU)l?MUcxqxVHP5%RvP#-p+9EC*aFEJ}V2i(qUxgBc38HaxZ5To4f zxb=wXU5lXEO7leZEG9q%d53r6jo*imNnwyiC7Et`7F0jpLeqOUq>QABLWW;AI4-)a z6j|0T+C+6iK96R#9c6aCNhb|T9Is{1{=wDO_mbpX`IccG^|*^b!bJ2~Ul-I7xuT}K zD2=&gZ7h=}%&o){z0qu|}82 z>~J8+C=VU$>J3qu#Es}KRt8Guu+OPofIbB$zF%h(U9|xaquW9}SdX>oB{>KA&J6vC zY5r_gt8$o=pUqOI@wG_(whYW8mHBDP&7)dI8FL4lMH%9`A&~_7=0ezs3xldU*V|kz zT7)ImUdaDg6b;k5L1Uy{OEb>~RXA~k~u zbB}Xx!IE7X(HjM|rPSQ)3Mar~wVEzAAmxMP{@aTA?}!sWgn0XYe7p|l3tjw2lC}?y zbP#5``MA4t{{`6I+3H)oRJTvW!K2xazAMk*hFUVYSK1tpDq3FIfh`5P18tNcaxiEr zx_jH%S&IfQ;|Xmy4Y02ye`-%3O_I`qYy#!r^ICoAyUz#~FSht*#er6;bZU$DYKedQ z8^!9cMlI$0uqC5PnE;?%!rZ6-OweM@H5IZEX?v)g8t>+hULE`q@B z%xU_VgjfpAbPKHTEeSy?4_lmN4-9I+_#(m6ZS2o3V8|-s%co39jnp6HJ#v?gTy>Pm z?4aC6pj`iLukW@@^*iHZy|QZ*f`!dGVB@u~**|b7B{eV_6nV{nD^Tg2NTMu3qFism z{wT9U5aS1wn?@l-P{xFJu8qL*`xPLYpy!8;>Jtbc*kfY%1d=O5uJFED*m48_L97&y z^g21C*{u~p^WV@=pwlP)He|rW#Q{dpR5v$7K#2nH2!nT(?GJkO7K&BtUVmEBxd&hd*4+#=5YJ z|AcjX>7rH0x(@DeYy`OIl_63;fvE4g8mU7AuE<&+*X6x)C;aLieasz>#z|&(L1g=R zwfDadfDJtjrTDvehh+g=be-oh16R_s1CAkU&Kh^>a88vdCuWH&N`Pdy0Wi+624=29 zZD;Vq6G{MJCKL4_1ZT4rrkyHGFcCMHwtxXJNenO2+@Cx- z@^lN24SmeW`1KQlH1*gfKJLUC;6DkUSZ`;8cRlES^I0&s6VV%HrK?GgU&gI3d z5l>P82M_^C*nmLHYqc(8Xo<$qRp4=|uF<*#i7n%jI`#$9y6g+7>$VD;H2bSY&yVme zaA+wVH;9s*X=q@ac4^YoDtcy0$>Bve?x|#{C_3qO@-3ca*$}p5uaf;(YtEc^XESgk zc!M_~Nix`WMBB*{+^On5%9c*~O#paQ6x97eRO2GkI#0O``KfYg%~?gbmI+)5k16wh z!w0s$Yz$ixCBA2gTIcFJf`*t#>Kc#wrV1Q(k_nTc$kw@v%J_T#6G2mS13Wy!+#WQQ ze826L@)zr=MA@qYQ*hcSbi-{hka*%6mm7pDJsNN(ASb>J?(1h~B!#fA=YT~;9AzFZt?C9PS`;He- zbJnd%ekRtRs&@R5aoH*#^i?)K?ky0e;G!xA21xIO@BPTUrywz!+D_q3p%F6%IF1bI zX=@Jy5KL`jKmjo(i{R%+gm6)L?qw&OM;5v3S9MAn`2-W?8&hBF7UX*kk>1IQiJ4;n zv8wl-EdI5cMOKbKfy-%T=TyhN=VibGK*$#$6mKHU(wPMCBY*eP)SXS~?B~~Bo6PQN z698{AyQTnSM`xvNl>oH@_eJ?!GEJt)@UioC$;#Ci1BKX{(EzZUcb(Dcr-|PxXtSy4qR`p1N z7Sz`rV^?^VcfgCtEEf9@^aM$9*P}=|T^~b~Y6yKv_zz^y^4+&Ckbo1MgdS*EsIk;s z>Zom{Jkx?m_32`WnCZ>4KQ3pqU01-{!#AJ*t1QuAxp@LHEeLCVQ;Kz zlkPfCL10}%MSDbMyYn(KNek^snSJQ2lKBc+J?QT~8crK=r z2fU)}+rXA0AJ-qVR=(}vR)vauNM6cPN<$)dWYW759(Y>gsm>D4PY`IFgW7Jn{^!D(19_Z%Qwvgydcd_1r@d z1Z<5@RG@PIqLJxK{~j;CiQoD}I}#%g^pv35)u4($FaA*DoIXql?2+}KiBsnlh?i(` zkg-MzbDE}m@q9~6VncRTRv_R{EKiR-*_gVC{<=sJf>&AIx|RVXgjtd|ffFr)hHVa5 zNC4WiR3Eaa8E1`VKef(bCk*sYIsm~!(?Iu{^2HXA38%UddQwgWyw!x5*zyJ)^X(h~ z@_bnVywqZ{13QS4e0RT*d?Wl^BstTYNRnay=Yjy|5%cb1%{&AXiU$}(11$|2$KM-~ zRZ(oI$~dc7HUo>UM^1uB^c28hC%XU=uXgu+6enC}?nImkGR*$vr{-h5KG>7kCAly9 zUzBDO1Ngvldn!EhmStgG#9yLlsNz<)uEl zmkDqimNK}80j><3F#h|HYj^)a{HPpIl3x-N^gvIN2k2$2H~i+pvwa2>G%%qbfH%(5 zky@uCiUpwSHnMml`qE$hI{o)){@PHr_)Vr-c+8LuU^v=d?jOcX86-;2-9o~Y4@ocR z3|=6SETd1phyMw^{r}>yk^~?hn{30g2uJ^nMQ%os${7WRXN~&Yhc@7A_Kg3z_M8P; z`&8%?>V_ev?j-R}Tr>+>w-g3zR<4x~FXE;Q*RQ z;reUFuTb@m!G7iBR3d=Vg*(OnyjqT&STF5oT`vR_aY&X;DUtXGivKTMI{`NEezdkG z0J~%%T^}e&J?g*bo}&#``O*pJ{_tbuN_G z+Rq21Cedxq{cLS~!OcX?>Pu6}lbEj$aC)KGe zv6Na@_Ajpi&Zmz{_;fP6eHu-s?+Qq#3bEW%bl4QWPc@o<`eeqDLU4^|RXrdNQdx?~ zSz8-wrCF3ZoYuHX?`>pV*^*k-s)YtBD?J}N*l>CO->4qPE%?RbLh~a-^S_(r^|8xs zzcIETY*eJTno5cV-^!8PKaw-+#G7;@t07{FGIy)Mt&pPob+hf!%GyXIY|;v&&>NIW z?`XL~(h2O=dAwN4=#Xg};;J4K?ztro1!58 ziEbCh_i{wW%+4S>;6>`ZLK3J$s86O#)gzOWEk@{VPq*%7g6&7Mu#ZOHH2h)kJiUDc_a9zJ=7>SUt_g&raJd@|V|2{qzAAXyL< z!GH;_eh{Ak!-7AVPA_b@$E&v9zf1qCH#@#FvqMlSexJ-}IiH?7LDr@I^TJu$*N5&1oY~BvlZiv6#$K)5i^s#se4>?E-x$}S^76cv+D-++pT*Q67 zh|6ikz1yX0tr{^I)HmLm8cn-)EaioWYf-<4u{X)wgah)NB(U~1-%_}0c@9mS6vte= zWQW^rfEnRvDr1jc&Wy918pitth4MywvjV4qrkr6*$?91SUEu5}V9i`4hE+eCWBSJb z*TR*@L%n|g8EfAnDP$YVs2e3~$gT`yDN0I_%#9+(ay6E+%pjS_7P?6jHDgP%6*XeG z$~s1a>|{hTTcl0lYCiO}oq8zYvNLCoH(ok-@ zXW>vw&~q<@kVT+y%-^G_9nP`pFLJX(M75_Ez6@F2Y&0g@9!Q)XX0`di0Y>_-+pWc4 z1r-)kE{Kl>#`OX@a_eYopthfk$~K0g@-{ z&YM3qSyKXTX4+Pi7C3Z&qB-Jw#)km=LPXTj}- z_EC6ha;s528iU28bf$r{Okbko6=q|Aecigo<6iUU8i?I?!ZuE=5+00LxKreucY9+>*7+c5|UlU0R;^qk$B~Mz&b-RG}LTDk)i(a>+e>q z*p_dWwZWP{wtHo^C1xG%*kSE&OZ19a3xVG(&4Co>#`g5*G%-|!uc$EKmbtb(QnvLE z_P(i1rLBEau1U+HoE`jl$$ogX2aS{OVa7UdZ`M}hYv%U0k4md;XScy_8D;DAL$dk< zGqvB*CaUf&Wi559CjF9U8xxx(W1sH|eW2E~Gte34CG@5krCY%5dHa`dC7tt?CZ39U z3c`ID>diA?Hb%)DHzM1a9pP)eHfdXzYtvBK5q!pcSK#c4MM-2F2G#IA$A4^vR!Y8n zs9#zU;udHX-rmSqB+_99*keCQc@1wVh=;E{4d@1NM=V-1_5pV)<)uTT4_ z0JH{U=U1Uj^PkvO+WnC1cRx%2+_rkOz5fX34UFYi=DlO%{O-{c*!iqp<-Ozg?RqL}ZXG5&`Wa(XAzGG(;Tpr~ z9;r0{=C906sPB*Fa4cJRunHm}F*M)i)9rwSkPKGS{n0H8m2}u@+G+=Cb+-og0GVVM zSQRD5fkHHf0(R%;#nBwB`=ue}5{6z#7WUQ4r>xWM%>^&krZZ1)SMv)A)Zj`hPVq|s zgaNwxoiwKcAlJ6p_H8!3%UqK)%B{;Lh_f)_?7Ncbq4*`~{3DW(a+#h1Gn5&b$o!t! z%A@F&m>~bgT$HTsQEoX}ylFR!r-F{?o+_DX4U|bV-@Y`N$W=92^`;*rcwh&pO%UbA zfeRVugC`vdfz-MkZ)|&_LNQ3|KT*d499?@z+GDUbJ(S6>c`quU%LgHny16AnM4dzZR20Oiu_}cCN>oxbbp?&RDJ-MD2c1=e_8l#CgAq2 z*A3_SpR8>nKT=Oi-Y01w-7YCY`b}Qy^NNz1dkATckG7fIpVK}uN$0#IS}cu^|FQw; z41-qe<7o5>x;>>9>3^EBi+2iRCv~8V0>jnc3XTg)ckloS`_!yG9)}HVOw>)ewhhK{ ze-2_R%Ct59Uo59_8~{Sf5&wxr5Vp;DlMz zZre!xWXZ@(TuvxYr^_~-#n$;AG7X9SNAar^aubg!0A5PBCkvpKpBHzOP=fVjz3FlF zsF{1%mZia`92AJxRS<8jY^Lj@@!v%ARO)8iIv04#_Wm}~(>h`0C%CFXDMbM^KCBOY zD0CW4^9Ad)JMT|xNaT|oZ;=+F_9OO1bh^Vb@WiZbpV8{!{+P>n9vHfmW61YNf(hUC z@js$c2sFf!1ztjvDs`a+M8nkf!n^MU@kG8qM}go{z!kiUCe6|UCPCNVPA}hE(tON1 zibHx}e7K7?Fo_{A-3LmQo4jKI}uCh5_KlD;HBMPs4O4vrEdU{3*wv@W0nfNO}m9x$d z?7RS3kyKJ-?s=lI7xcMrxZK%!T-RJiz*aQo#OCKJjNXLXZ68dU1E6)bFgiMBfWbE- zYj|2IdVlhMWBBZsSr{j+KKzsi&Vktv*>fx5by4Ke>O*9W)a8U&4~$(DaDgk&4ID-^ z;1L1?sF(h)JLanCOZW#K9O>huO6mmY?uN1MnpD;KJ-2QsLg2a&{t&mizlOjd@5Fi} zyF!k2>WHJ@?|f7*YwUFaA=)h@7B1-5@nYc<1D~4|b(HR6UVIgZxj#p(c=-kduiRbJ zF(I_xy0s!+u^^3;_z`*&=dD%6kSA!kiGTxAP(2MUikJ5@=s{QL`yliC6A3%+GEuXc zR!WTjw-^YBhqA5d3QgZ+IRUSevnnHTi%+uR4ufu?c?^Qs-FAN>e7>SXG)6QuDc4&f zQd$0TaF6{apr1^#7_QT~dirNoLfjED@z9t!uWV0@g5Q4AmZW2kqY%IX+|QlT^34ye zqK}6h#BTF5QM+2GL-{Q58*yDQjD?FBk4)@{bj2Wt&!ZtD@G{CMbg7}8Jq)@+syzTe zQ~CH#Js5-T{h2IM9j}m;kUeDIfS1VzZqHV?&bTV`FJq79%>MFUTT9jj*E4u z04i$1K@o|$B_&nRU-sZnZ6JADuxIh2Spfy56<~x+eF3LT*pd4#ERL|koCPlanM>Sq zu1X%mhAC4RckLVOLG*dx7;O^O8e#!LFp`yrZ1lkH$91_e8C_@ni~%^;TWP^uDwPK( z6TKE>>7r}rVk`%*i2o~4S?t@IPEG&>PaS&7(M>=;HzcbQ+`jCCO8zj+{LLVY<#4x- zA+s-ig6zpZ*!cEM-;+&b6efwV*IO@Y^qq?tL%%_46bt~*0Th4>emb7L<2Y5MKgQGS z4QW$IuX9rDKWT!Nqa`>d0Ss#H%O}A508@%k=j1oixz;I9ub*rLCeuMdV2~}DffZ%{ zJ(uC)RGPcu)?zluybh82GtEi~utg5AWew%>Cd9Bnji3P2H{bAyScvZUZ$#e2=L%|V zF>+>Y9L1Mm&>e5wxYaCH?W@)(f|FM4trD5V=cWoQ@_!yWLqPTpJq8NYNmF2>wF7u zE+fOiaI;^RykL+5op9qd&&g#Q09mmhG3P42(@KfvX2nBzo#-3&JASlHvG-Tj#5oHx z1**U}IBjeS_kp^f4AvU?A6+)ZgEFD+d$@Sah<+4)tr)7-uRatV@b^~}yC@7IabaQ( zZ|hvz``UCO@JNR};9j?runj4xzosKjBwCwH+!vVi(L$;y{+;brfjAj(x9b2cm|stW zm4BEm26>1yP!xFq^RYG1xu{-w;$7EW&pdfg_*p?Ry>fAiWgnig&=Hu{*4iEz%A-5T z1aLT)Ack{Dx#YW+`)A&9)5?0Pqrc483fx$D8R363@l6D4&wDvX?cjoJY<)RtsJyop zmGO?yC5cBxyrA9Hgnf0CRGM_T5TLn^UIk4uFtCTPJ~nc9;j#loLd;{lmL50}=6C>1 z@D6{EbPqMzY=xdJKur-;HXH3EYa7h}m8i&hyn6<)*ncS`=ov?<+_CB|`uI%Ke1%%m zUMiY!DME#OU@usKNonZlSdp?1zJc=|W|5aOnHWf|GwjLoMPJUmWqee&(*UT8K~J!y zo-9M(CsKQmNgq#A*l3_yZ1gz<#ca33<7|MJ9&|KEy(1)TY3>eMzBaGvmae&6Z5ph) zF&NB8O}9M$-5C3YyT*p0`{*#j8K1ADoJPLYXkfMP4WL^xKLpN20zcv}Yq)1qGC_S4 zkKz)T5uIeVN{201sN?5&Z~!J~bJCH71;DL482r{-aTnCb!2(NS)YIvmxcm>C&#`vfCh4=g3{J? z*DU6mO=Pm|7yok0t=5d@YP>SoEIwq#jTv!U+aE=ddNsOze=(}X-W z89^!oe7IftdD|j7!UbK?+JcP?be_c?D2gw({c?6>vu1bhy-sJ)4p{nLw&T@K7MgRj zXs9;Zwv(3sJ7|#h#Pk6wtkNi++;B4j9Ep2)X1h01e$~|#W*ay^<_ZiAyYX;A!qN&x<|G3zEWzD0u<9Kvrn5V}1o}nlU^zCGE+>s;!!WYWlib-J2WrUO+O-aT|yg8`L?Ym~1 zbwzXrT)kJ32*gfs^&ZGF^5oB4_rWjC$(cjtI3}g>_f)r|3Iw-P*wUM4KP4@tWLUl+ zf!6+S-_EzJ(P7>>*Iib;*w*Stt=OTTnF}NE3AZcd6>vm1;LU+Ym18vn1XoaRFEhp^ zc8LE}L(3Jbn=DklqB8%vQGMvWrF|@uy5p`M2=Yh%hS8yI-k5yYRgAMPdo8P>=-2HM z?c%y%!6u#KK%q-RvW2PzOLJ>F9oBTUgF3O^F?}J9o%R7>ua#O}UXTEzD_E{y4yRa| zoh11HCdu5X9Q*m6Zmo(BiOi9Fqml+*5_o|4?fTJNUBS+5S$*VmX(j@RUpE9`3e_0B z?k%HzO_XYzsA~9kSl+|(C-1Z&p(ga1ui1_Av&aTaSETu~$cIOj7^*OMe;-B!Jf()U z4TCJxT0d{E?7vs40fCF=g?h&7hTXs*Q!E40XH2huqpQQYE=UMsXLtDIuFu;=$Lb=0 zv6dJ(H?dYQ^H2=QMBo3k36^sMTfoki{}$&A7d^LYeL;J)Gz3A`O)s8K@gkbf^expt zt68@9z;{xBjjn;faHc?xGBCZ?^3R-1+whMzACiS2Vw#E0yAQp~A}%|fqG?a~S8aQB zMVlz#Vr>@Mqh$&vN0cxNy+V {% block title %}Welcome!{% endblock %} - + From 7f2eb7ec65beb9424129c4fbbd4b5c441888eea3 Mon Sep 17 00:00:00 2001 From: lubiana Date: Sun, 23 Jun 2024 08:27:17 +0200 Subject: [PATCH 002/100] update fpm config --- deploy/Dockerfile | 2 -- deploy/etc/php83/php-fpm.d/www.conf | 6 +++++- deploy/prepare-deploy.sh | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) delete mode 100644 deploy/Dockerfile mode change 100644 => 100755 deploy/prepare-deploy.sh diff --git a/deploy/Dockerfile b/deploy/Dockerfile deleted file mode 100644 index 47bc55b..0000000 --- a/deploy/Dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -FROM git.php.fail/lubiana/container/php:8.3 as phpbuild - diff --git a/deploy/etc/php83/php-fpm.d/www.conf b/deploy/etc/php83/php-fpm.d/www.conf index 113b8c2..edf975a 100644 --- a/deploy/etc/php83/php-fpm.d/www.conf +++ b/deploy/etc/php83/php-fpm.d/www.conf @@ -7,4 +7,8 @@ pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 -pm.max_spare_servers = 3 \ No newline at end of file +pm.max_spare_servers = 3 +env[APP_ENV]=$APP_ENV +env[APP_SECRET]=$APP_SECRET +error_log = /var/log/php-fpm.log +catch_workers_output = yes \ No newline at end of file diff --git a/deploy/prepare-deploy.sh b/deploy/prepare-deploy.sh old mode 100644 new mode 100755 index 53f4e46..d8c92fa --- a/deploy/prepare-deploy.sh +++ b/deploy/prepare-deploy.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -TARGETDIR='futtern-app' +TARGETDIR='deploy/futtern-app' if [ -d $TARGETDIR ]; then rm -rf $TARGETDIR @@ -8,7 +8,7 @@ fi mkdir $TARGETDIR cd $TARGETDIR || return -pathsToCopy="public bin config migrations src templates composer.json composer.lock symfony.lock .env etc" +pathsToCopy="public bin config migrations src templates composer.json composer.lock symfony.lock .env" for path in $pathsToCopy do From 38a2de58589ec00585166920a9a6ebc51b6f9be7 Mon Sep 17 00:00:00 2001 From: lubiana Date: Sun, 23 Jun 2024 08:49:44 +0200 Subject: [PATCH 003/100] add unit files --- deploy/etc/php83/php-fpm.d/www.conf | 7 ++- .../systemd/container-futtern-caddy.service | 43 +++++++++++++++++ deploy/systemd/container-futtern-php.service | 46 +++++++++++++++++++ deploy/systemd/pod-futtern.service | 42 +++++++++++++++++ deploy/update.sh | 8 ++++ 5 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 deploy/systemd/container-futtern-caddy.service create mode 100644 deploy/systemd/container-futtern-php.service create mode 100644 deploy/systemd/pod-futtern.service create mode 100644 deploy/update.sh diff --git a/deploy/etc/php83/php-fpm.d/www.conf b/deploy/etc/php83/php-fpm.d/www.conf index edf975a..e5a895d 100644 --- a/deploy/etc/php83/php-fpm.d/www.conf +++ b/deploy/etc/php83/php-fpm.d/www.conf @@ -1,7 +1,7 @@ [www] -user = nobody -group = nobody +user = root +group = root listen = 9001 pm = dynamic pm.max_children = 5 @@ -10,5 +10,4 @@ pm.min_spare_servers = 1 pm.max_spare_servers = 3 env[APP_ENV]=$APP_ENV env[APP_SECRET]=$APP_SECRET -error_log = /var/log/php-fpm.log -catch_workers_output = yes \ No newline at end of file +catch_workers_output = yes diff --git a/deploy/systemd/container-futtern-caddy.service b/deploy/systemd/container-futtern-caddy.service new file mode 100644 index 0000000..2c7e3f6 --- /dev/null +++ b/deploy/systemd/container-futtern-caddy.service @@ -0,0 +1,43 @@ +# container-futtern-caddy.service +# autogenerated by Podman 4.3.1 +# Sun Jun 23 05:33:51 UTC 2024 + +[Unit] +Description=Podman container-futtern-caddy.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-futtern.service +After=pod-futtern.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-futtern.pod-id \ + --sdnotify=conmon \ + --replace \ + -d \ + --name futtern-caddy \ + --volume /home/c3h-futtern/etc/caddy/Caddyfile:/etc/caddy/Caddyfile \ + --volume /home/c3h-futtern/futtern-app:/var/www/html \ + --volume caddy_data:/data docker.io/caddy/caddy:alpine +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/deploy/systemd/container-futtern-php.service b/deploy/systemd/container-futtern-php.service new file mode 100644 index 0000000..cec0498 --- /dev/null +++ b/deploy/systemd/container-futtern-php.service @@ -0,0 +1,46 @@ +# container-futtern-php.service +# autogenerated by Podman 4.3.1 +# Sun Jun 23 05:33:51 UTC 2024 + +[Unit] +Description=Podman container-futtern-php.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-futtern.service +After=pod-futtern.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-futtern.pod-id \ + --sdnotify=conmon \ + --replace \ + -d \ + --name futtern-php \ + --volume /home/c3h-futtern/etc/php83/php-fpm.d/www.conf:/etc/php83/php-fpm.d/www.conf \ + --volume /home/c3h-futtern/futtern-app:/var/www/html \ + --volume /home/c3h-futtern/var:/var/www/html/var \ + --env APP_ENV=prod \ + --env APP_SECRET=UwUtHiSisNotSecurePlZcHanGeMe \ + git.php.fail/lubiana/container/php:8.3-fpm +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/deploy/systemd/pod-futtern.service b/deploy/systemd/pod-futtern.service new file mode 100644 index 0000000..3189e8c --- /dev/null +++ b/deploy/systemd/pod-futtern.service @@ -0,0 +1,42 @@ +# pod-futtern.service +# autogenerated by Podman 4.3.1 +# Sun Jun 23 05:33:51 UTC 2024 + +[Unit] +Description=Podman pod-futtern.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=/run/user/1006/containers +Wants=container-futtern-caddy.service container-futtern-php.service +Before=container-futtern-caddy.service container-futtern-php.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStartPre=/bin/rm \ + -f %t/pod-futtern.pid %t/pod-futtern.pod-id +ExecStartPre=/usr/bin/podman pod create \ + --infra-conmon-pidfile %t/pod-futtern.pid \ + --pod-id-file %t/pod-futtern.pod-id \ + --exit-policy=stop \ + --label io.containers.autoupdate=registry \ + --name futtern \ + -p 8087:8087 \ + --replace +ExecStart=/usr/bin/podman pod start \ + --pod-id-file %t/pod-futtern.pod-id +ExecStop=/usr/bin/podman pod stop \ + --ignore \ + --pod-id-file %t/pod-futtern.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-futtern.pod-id +PIDFile=%t/pod-futtern.pid +Type=forking + +[Install] +WantedBy=default.target diff --git a/deploy/update.sh b/deploy/update.sh new file mode 100644 index 0000000..4d7548a --- /dev/null +++ b/deploy/update.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +systemctl --user stop pod-futtern +systemctl --user start pod-futtern +sleep 2 +podman exec -it futtern-php /var/www/html/bin/console cache:clear +podman exec -it futtern-php /var/www/html/bin/console cache:warmup +echo 'yes' | podman exec -it futtern-php /var/www/html/bin/console doctrine:migrations:migrate From 14bb4a15421fcac9c07c43a6ea6cc9468c389896 Mon Sep 17 00:00:00 2001 From: lubiana Date: Sun, 23 Jun 2024 09:21:20 +0200 Subject: [PATCH 004/100] update deployment paths --- .gitignore | 2 +- deploy/install.sh | 31 ------------------- deploy/prepare-deploy.sh | 2 +- .../systemd/container-futtern-caddy.service | 4 +-- deploy/systemd/container-futtern-php.service | 6 ++-- deploy/systemd/pod-futtern.service | 2 +- 6 files changed, 8 insertions(+), 39 deletions(-) delete mode 100755 deploy/install.sh diff --git a/.gitignore b/.gitignore index 62752be..feabc44 100644 --- a/.gitignore +++ b/.gitignore @@ -20,5 +20,5 @@ ###< phpunit/phpunit ### .idea/ -/deploy/futtern-app/ /deploy/var/ +/deploy/app/ diff --git a/deploy/install.sh b/deploy/install.sh deleted file mode 100755 index d4b64b7..0000000 --- a/deploy/install.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env sh - -if [ ! -d "var" ]; then - mkdir var -fi -podman pod stop futtern -podman pod rm futtern - -podman pod create \ - --label "io.containers.autoupdate=registry" \ - --name futtern \ - -p 8087:8087 - -podman run -d \ - --pod futtern \ - --name futtern-php \ - --volume $(pwd)/etc/php83/php-fpm.d/www.conf:/etc/php83/php-fpm.d/www.conf \ - --volume $(pwd)/futtern-app:/var/www/html \ - --volume $(pwd)/var:/var/www/html/var \ - --env 'APP_ENV=prod' \ - git.php.fail/lubiana/container/php:8.3-fpm - -podman run -d \ - --pod futtern \ - --name futtern-caddy \ - --volume $(pwd)/etc/caddy/Caddyfile:/etc/caddy/Caddyfile \ - --volume $(pwd)/futtern-app:/var/www/html \ - --volume caddy_data:/data \ - docker.io/caddy/caddy:alpine - -echo 'yes' | podman exec -it futtern-php /var/www/html/bin/console doctrine:migrations:migrate diff --git a/deploy/prepare-deploy.sh b/deploy/prepare-deploy.sh index d8c92fa..5bb412a 100755 --- a/deploy/prepare-deploy.sh +++ b/deploy/prepare-deploy.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -TARGETDIR='deploy/futtern-app' +TARGETDIR='deploy/app' if [ -d $TARGETDIR ]; then rm -rf $TARGETDIR diff --git a/deploy/systemd/container-futtern-caddy.service b/deploy/systemd/container-futtern-caddy.service index 2c7e3f6..1067128 100644 --- a/deploy/systemd/container-futtern-caddy.service +++ b/deploy/systemd/container-futtern-caddy.service @@ -26,8 +26,8 @@ ExecStart=/usr/bin/podman run \ --replace \ -d \ --name futtern-caddy \ - --volume /home/c3h-futtern/etc/caddy/Caddyfile:/etc/caddy/Caddyfile \ - --volume /home/c3h-futtern/futtern-app:/var/www/html \ + --volume %h/futtern/etc/caddy/Caddyfile:/etc/caddy/Caddyfile \ + --volume %h/futtern/app:/var/www/html \ --volume caddy_data:/data docker.io/caddy/caddy:alpine ExecStop=/usr/bin/podman stop \ --ignore -t 10 \ diff --git a/deploy/systemd/container-futtern-php.service b/deploy/systemd/container-futtern-php.service index cec0498..e6f139c 100644 --- a/deploy/systemd/container-futtern-php.service +++ b/deploy/systemd/container-futtern-php.service @@ -26,9 +26,9 @@ ExecStart=/usr/bin/podman run \ --replace \ -d \ --name futtern-php \ - --volume /home/c3h-futtern/etc/php83/php-fpm.d/www.conf:/etc/php83/php-fpm.d/www.conf \ - --volume /home/c3h-futtern/futtern-app:/var/www/html \ - --volume /home/c3h-futtern/var:/var/www/html/var \ + --volume %h/futtern/etc/php83/php-fpm.d/www.conf:/etc/php83/php-fpm.d/www.conf \ + --volume %h/futtern/app:/var/www/html \ + --volume %h/futtern/app/var:/var/www/html/var \ --env APP_ENV=prod \ --env APP_SECRET=UwUtHiSisNotSecurePlZcHanGeMe \ git.php.fail/lubiana/container/php:8.3-fpm diff --git a/deploy/systemd/pod-futtern.service b/deploy/systemd/pod-futtern.service index 3189e8c..10a8fb0 100644 --- a/deploy/systemd/pod-futtern.service +++ b/deploy/systemd/pod-futtern.service @@ -7,7 +7,7 @@ Description=Podman pod-futtern.service Documentation=man:podman-generate-systemd(1) Wants=network-online.target After=network-online.target -RequiresMountsFor=/run/user/1006/containers +RequiresMountsFor=/run/user/%U/containers Wants=container-futtern-caddy.service container-futtern-php.service Before=container-futtern-caddy.service container-futtern-php.service From b6e0ef44f4b33baa187fee1e5757c44bd121dac7 Mon Sep 17 00:00:00 2001 From: lubiana Date: Sun, 23 Jun 2024 11:58:18 +0200 Subject: [PATCH 005/100] write release workflow file --- .forgejo/workflows/release.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index a1c6c78..72b4710 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -18,6 +18,27 @@ jobs: git checkout ${{ github.head_ref }} - name: prepare deploy run: sh ./deploy/prepare-deploy.sh + - name: deploy + env: + HOST: 'web.server.c3h' + USERNAME: 'c3h-futtern' + TARGETDIR: '/home/c3h-futtern/futtern' + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + run: | + mkdir -p ~/.ssh/ + # Print the SSH key, replacing newline characters with actual new lines + echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa + # Set appropriate permissions for the SSH key + chmod 600 ~/.ssh/id_rsa + # Add the remote host's key to the known_hosts file to avoid authenticity confirmation + ssh-keyscan -H $HOST >> ~/.ssh/known_hosts + # stop services + ssh ${USERNAME}@${HOST} systemctl --user stop pod-futtern + # SCP files to the remote host + rsync -avz --delete deploy/ ${USERNAME}@${HOST}:${TARGETDIR} --exclude=var + # run update script + ssh ${USERNAME}@${HOST} /home/c3h-futtern/futtern/update.sh + - + From 57b4e330281db40bc9d76f7e8221a77937b1c225 Mon Sep 17 00:00:00 2001 From: lubiana Date: Mon, 24 Jun 2024 21:19:11 +0200 Subject: [PATCH 006/100] fix paths in prepare deploy and add local deploy script --- deploy/local-deploy.sh | 6 ++++++ deploy/prepare-deploy.sh | 3 ++- deploy/update.sh | 0 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100755 deploy/local-deploy.sh mode change 100644 => 100755 deploy/update.sh diff --git a/deploy/local-deploy.sh b/deploy/local-deploy.sh new file mode 100755 index 0000000..77189ad --- /dev/null +++ b/deploy/local-deploy.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +. ./deploy/prepare-deploy.sh +ssh leitstelle-futtern 'systemctl --user stop pod-futtern' +rsync -avz --delete deploy/ leitstelle-futtern:futtern --exclude=var +ssh leitstelle-futtern '/home/c3h-futtern/futtern/update.sh' diff --git a/deploy/prepare-deploy.sh b/deploy/prepare-deploy.sh index 5bb412a..6a80baa 100755 --- a/deploy/prepare-deploy.sh +++ b/deploy/prepare-deploy.sh @@ -17,6 +17,7 @@ done rm ./bin/phpunit APP_ENV=prod composer install --no-dev -a +rm -rf ./var/cache - +cd - diff --git a/deploy/update.sh b/deploy/update.sh old mode 100644 new mode 100755 From 45029e0a4c1d12f18acadcdda1edd533e2bc8925 Mon Sep 17 00:00:00 2001 From: lubiana Date: Wed, 26 Jun 2024 20:12:27 +0200 Subject: [PATCH 007/100] add option to select previous menuitems --- composer.json | 2 +- composer.lock | 167 +++++++++--------- migrations/Version20240626175246.php | 73 ++++++++ .../MigrateOrderitemsMenuitemsCommand.php | 66 +++++++ src/Controller/OrderItemController.php | 22 ++- src/Entity/FoodVendor.php | 35 ++++ src/Entity/MenuItem.php | 55 ++++++ src/Entity/OrderItem.php | 18 +- src/Repository/MenuItemRepository.php | 43 +++++ templates/food_vendor/show.html.twig | 4 - templates/order_item/new.html.twig | 19 ++ 11 files changed, 410 insertions(+), 94 deletions(-) create mode 100644 migrations/Version20240626175246.php create mode 100644 src/Command/MigrateOrderitemsMenuitemsCommand.php create mode 100644 src/Entity/MenuItem.php create mode 100644 src/Repository/MenuItemRepository.php diff --git a/composer.json b/composer.json index 9a7f726..a48327c 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "php": ">=8.3", "ext-ctype": "*", "ext-iconv": "*", - "doctrine/dbal": "^3", + "doctrine/dbal": "^4", "doctrine/doctrine-bundle": "^2.12", "doctrine/doctrine-migrations-bundle": "^3.3", "doctrine/orm": "^3.2", diff --git a/composer.lock b/composer.lock index 7e1d029..02edf36 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5aec19bda25c7cc358299be1a1d67cef", + "content-hash": "ab475528135d157af8dae9e8b967be1a", "packages": [ { "name": "doctrine/cache", @@ -187,47 +187,42 @@ }, { "name": "doctrine/dbal", - "version": "3.8.5", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "0e3536ba088a749985c8801105b6b3ac6c1280b6" + "reference": "50fda19f80724b55ff770bb4ff352407008e63c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/0e3536ba088a749985c8801105b6b3ac6c1280b6", - "reference": "0e3536ba088a749985c8801105b6b3ac6c1280b6", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/50fda19f80724b55ff770bb4ff352407008e63c5", + "reference": "50fda19f80724b55ff770bb4ff352407008e63c5", "shasum": "" }, "require": { - "composer-runtime-api": "^2", - "doctrine/cache": "^1.11|^2.0", "doctrine/deprecations": "^0.5.3|^1", - "doctrine/event-manager": "^1|^2", - "php": "^7.4 || ^8.0", + "php": "^8.1", "psr/cache": "^1|^2|^3", "psr/log": "^1|^2|^3" }, "require-dev": { "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", - "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.11.1", + "jetbrains/phpstorm-stubs": "2023.2", + "phpstan/phpstan": "1.11.5", + "phpstan/phpstan-phpunit": "1.4.0", "phpstan/phpstan-strict-rules": "^1.6", - "phpunit/phpunit": "9.6.19", - "psalm/plugin-phpunit": "0.18.4", + "phpunit/phpunit": "10.5.22", + "psalm/plugin-phpunit": "0.19.0", "slevomat/coding-standard": "8.13.1", - "squizlabs/php_codesniffer": "3.9.2", - "symfony/cache": "^5.4|^6.0|^7.0", - "symfony/console": "^4.4|^5.4|^6.0|^7.0", - "vimeo/psalm": "4.30.0" + "squizlabs/php_codesniffer": "3.10.1", + "symfony/cache": "^6.3.8|^7.0", + "symfony/console": "^5.4|^6.3|^7.0", + "vimeo/psalm": "5.24.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." }, - "bin": [ - "bin/doctrine-dbal" - ], "type": "library", "autoload": { "psr-4": { @@ -280,7 +275,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.8.5" + "source": "https://github.com/doctrine/dbal/tree/4.0.4" }, "funding": [ { @@ -296,7 +291,7 @@ "type": "tidelift" } ], - "time": "2024-06-08T17:49:56+00:00" + "time": "2024-06-19T11:57:23+00:00" }, { "name": "doctrine/deprecations", @@ -1078,16 +1073,16 @@ }, { "name": "doctrine/persistence", - "version": "3.3.2", + "version": "3.3.3", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "477da35bd0255e032826f440b94b3e37f2d56f42" + "reference": "b337726451f5d530df338fc7f68dee8781b49779" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/477da35bd0255e032826f440b94b3e37f2d56f42", - "reference": "477da35bd0255e032826f440b94b3e37f2d56f42", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/b337726451f5d530df338fc7f68dee8781b49779", + "reference": "b337726451f5d530df338fc7f68dee8781b49779", "shasum": "" }, "require": { @@ -1099,15 +1094,14 @@ "doctrine/common": "<2.10" }, "require-dev": { - "composer/package-versions-deprecated": "^1.11", - "doctrine/coding-standard": "^11", + "doctrine/coding-standard": "^12", "doctrine/common": "^3.0", - "phpstan/phpstan": "1.9.4", + "phpstan/phpstan": "1.11.1", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", "phpunit/phpunit": "^8.5 || ^9.5", "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.3.0" + "vimeo/psalm": "4.30.0 || 5.24.0" }, "type": "library", "autoload": { @@ -1156,7 +1150,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.3.2" + "source": "https://github.com/doctrine/persistence/tree/3.3.3" }, "funding": [ { @@ -1172,7 +1166,7 @@ "type": "tidelift" } ], - "time": "2024-03-12T14:54:36+00:00" + "time": "2024-06-20T10:14:30+00:00" }, { "name": "doctrine/sql-formatter", @@ -3103,16 +3097,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a", + "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a", "shasum": "" }, "require": { @@ -3161,7 +3155,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0" }, "funding": [ { @@ -3177,20 +3171,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "07094a28851a49107f3ab4f9120ca2975a64b6e1" + "reference": "e76343c631b453088e2260ac41dfebe21954de81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/07094a28851a49107f3ab4f9120ca2975a64b6e1", - "reference": "07094a28851a49107f3ab4f9120ca2975a64b6e1", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/e76343c631b453088e2260ac41dfebe21954de81", + "reference": "e76343c631b453088e2260ac41dfebe21954de81", "shasum": "" }, "require": { @@ -3245,7 +3239,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.30.0" }, "funding": [ { @@ -3261,20 +3255,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:12:16+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb", + "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb", "shasum": "" }, "require": { @@ -3326,7 +3320,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0" }, "funding": [ { @@ -3342,20 +3336,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", "shasum": "" }, "require": { @@ -3406,7 +3400,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" }, "funding": [ { @@ -3422,25 +3416,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-06-19T12:30:46+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "86fcae159633351e5fd145d1c47de6c528f8caff" + "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/86fcae159633351e5fd145d1c47de6c528f8caff", - "reference": "86fcae159633351e5fd145d1c47de6c528f8caff", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9", + "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-php80": "^1.14" + "php": ">=7.1" }, "type": "library", "extra": { @@ -3483,7 +3476,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.30.0" }, "funding": [ { @@ -3499,20 +3492,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-06-19T12:35:24+00:00" }, { "name": "symfony/polyfill-uuid", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "3abdd21b0ceaa3000ee950097bc3cf9efc137853" + "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/3abdd21b0ceaa3000ee950097bc3cf9efc137853", - "reference": "3abdd21b0ceaa3000ee950097bc3cf9efc137853", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/2ba1f33797470debcda07fe9dce20a0003df18e9", + "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9", "shasum": "" }, "require": { @@ -3562,7 +3555,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.30.0" }, "funding": [ { @@ -3578,7 +3571,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/property-access", @@ -5580,16 +5573,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.4", + "version": "1.11.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "9100a76ce8015b9aa7125b9171ae3a76887b6c82" + "reference": "490f0ae1c92b082f154681d7849aee776a7c1443" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9100a76ce8015b9aa7125b9171ae3a76887b6c82", - "reference": "9100a76ce8015b9aa7125b9171ae3a76887b6c82", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/490f0ae1c92b082f154681d7849aee776a7c1443", + "reference": "490f0ae1c92b082f154681d7849aee776a7c1443", "shasum": "" }, "require": { @@ -5634,7 +5627,7 @@ "type": "github" } ], - "time": "2024-06-06T12:19:22+00:00" + "time": "2024-06-17T15:10:54+00:00" }, { "name": "phpunit/php-code-coverage", @@ -6060,16 +6053,16 @@ }, { "name": "rector/rector", - "version": "1.1.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "556509e2dcf527369892b7d411379c4a02f31859" + "reference": "c930cdb21294f10955ddfc31b720971e8333943d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/556509e2dcf527369892b7d411379c4a02f31859", - "reference": "556509e2dcf527369892b7d411379c4a02f31859", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/c930cdb21294f10955ddfc31b720971e8333943d", + "reference": "c930cdb21294f10955ddfc31b720971e8333943d", "shasum": "" }, "require": { @@ -6107,7 +6100,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/1.1.0" + "source": "https://github.com/rectorphp/rector/tree/1.1.1" }, "funding": [ { @@ -6115,7 +6108,7 @@ "type": "github" } ], - "time": "2024-05-18T09:40:27+00:00" + "time": "2024-06-21T07:51:17+00:00" }, { "name": "sebastian/cli-parser", @@ -7704,16 +7697,16 @@ }, { "name": "symplify/easy-coding-standard", - "version": "12.2.1", + "version": "12.3.0", "source": { "type": "git", "url": "https://github.com/easy-coding-standard/easy-coding-standard.git", - "reference": "095fe591b2e51fd84edd21b8c9be74402eadc50e" + "reference": "f919574aa566b4d00fd06700ca61168aafef66e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/easy-coding-standard/easy-coding-standard/zipball/095fe591b2e51fd84edd21b8c9be74402eadc50e", - "reference": "095fe591b2e51fd84edd21b8c9be74402eadc50e", + "url": "https://api.github.com/repos/easy-coding-standard/easy-coding-standard/zipball/f919574aa566b4d00fd06700ca61168aafef66e1", + "reference": "f919574aa566b4d00fd06700ca61168aafef66e1", "shasum": "" }, "require": { @@ -7749,7 +7742,7 @@ ], "support": { "issues": "https://github.com/easy-coding-standard/easy-coding-standard/issues", - "source": "https://github.com/easy-coding-standard/easy-coding-standard/tree/12.2.1" + "source": "https://github.com/easy-coding-standard/easy-coding-standard/tree/12.3.0" }, "funding": [ { @@ -7761,7 +7754,7 @@ "type": "github" } ], - "time": "2024-06-02T01:25:21+00:00" + "time": "2024-06-18T07:35:59+00:00" }, { "name": "theseer/tokenizer", diff --git a/migrations/Version20240626175246.php b/migrations/Version20240626175246.php new file mode 100644 index 0000000..7c43d78 --- /dev/null +++ b/migrations/Version20240626175246.php @@ -0,0 +1,73 @@ +addSql('CREATE TABLE menu_item (id BLOB NOT NULL, name VARCHAR(255) NOT NULL, food_vendor_id BLOB NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_D754D5506EF983E8 FOREIGN KEY (food_vendor_id) REFERENCES food_vendor (id) NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('CREATE INDEX IDX_D754D5506EF983E8 ON menu_item (food_vendor_id)'); + $this->addSql('CREATE TEMPORARY TABLE __temp__food_order AS SELECT id, food_vendor_id, closed_at FROM food_order'); + $this->addSql('DROP TABLE food_order'); + $this->addSql('CREATE TABLE food_order (id BLOB NOT NULL, food_vendor_id BLOB NOT NULL, closed_at DATETIME DEFAULT NULL, PRIMARY KEY(id), CONSTRAINT FK_44856726EF983E8 FOREIGN KEY (food_vendor_id) REFERENCES food_vendor (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO food_order (id, food_vendor_id, closed_at) SELECT id, food_vendor_id, closed_at FROM __temp__food_order'); + $this->addSql('DROP TABLE __temp__food_order'); + $this->addSql('CREATE INDEX IDX_44856726EF983E8 ON food_order (food_vendor_id)'); + $this->addSql('CREATE TEMPORARY TABLE __temp__food_vendor AS SELECT id, name FROM food_vendor'); + $this->addSql('DROP TABLE food_vendor'); + $this->addSql('CREATE TABLE food_vendor (id BLOB NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('INSERT INTO food_vendor (id, name) SELECT id, name FROM __temp__food_vendor'); + $this->addSql('DROP TABLE __temp__food_vendor'); + $this->addSql('CREATE TEMPORARY TABLE __temp__order_item AS SELECT id, food_order_id, name, extras FROM order_item'); + $this->addSql('DROP TABLE order_item'); + $this->addSql('CREATE TABLE order_item (id BLOB NOT NULL, food_order_id BLOB DEFAULT NULL, name VARCHAR(255) NOT NULL, extras VARCHAR(255) DEFAULT NULL, menu_item_id BLOB DEFAULT NULL, PRIMARY KEY(id), CONSTRAINT FK_52EA1F09A5D24A7A FOREIGN KEY (food_order_id) REFERENCES food_order (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_52EA1F099AB44FE0 FOREIGN KEY (menu_item_id) REFERENCES menu_item (id) NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO order_item (id, food_order_id, name, extras) SELECT id, food_order_id, name, extras FROM __temp__order_item'); + $this->addSql('DROP TABLE __temp__order_item'); + $this->addSql('CREATE INDEX IDX_52EA1F09A5D24A7A ON order_item (food_order_id)'); + $this->addSql('CREATE INDEX IDX_52EA1F099AB44FE0 ON order_item (menu_item_id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP TABLE menu_item'); + $this->addSql('CREATE TEMPORARY TABLE __temp__food_order AS SELECT id, closed_at, food_vendor_id FROM food_order'); + $this->addSql('DROP TABLE food_order'); + $this->addSql('CREATE TABLE food_order (id BLOB NOT NULL --(DC2Type:ulid) + , closed_at DATETIME DEFAULT NULL --(DC2Type:datetime_immutable) + , food_vendor_id BLOB NOT NULL --(DC2Type:ulid) + , PRIMARY KEY(id), CONSTRAINT FK_44856726EF983E8 FOREIGN KEY (food_vendor_id) REFERENCES food_vendor (id) NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO food_order (id, closed_at, food_vendor_id) SELECT id, closed_at, food_vendor_id FROM __temp__food_order'); + $this->addSql('DROP TABLE __temp__food_order'); + $this->addSql('CREATE INDEX IDX_44856726EF983E8 ON food_order (food_vendor_id)'); + $this->addSql('CREATE TEMPORARY TABLE __temp__food_vendor AS SELECT id, name FROM food_vendor'); + $this->addSql('DROP TABLE food_vendor'); + $this->addSql('CREATE TABLE food_vendor (id BLOB NOT NULL --(DC2Type:ulid) + , name VARCHAR(50) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('INSERT INTO food_vendor (id, name) SELECT id, name FROM __temp__food_vendor'); + $this->addSql('DROP TABLE __temp__food_vendor'); + $this->addSql('CREATE TEMPORARY TABLE __temp__order_item AS SELECT id, name, extras, food_order_id FROM order_item'); + $this->addSql('DROP TABLE order_item'); + $this->addSql('CREATE TABLE order_item (id BLOB NOT NULL --(DC2Type:ulid) + , name VARCHAR(255) NOT NULL, extras VARCHAR(255) DEFAULT NULL, food_order_id BLOB NOT NULL --(DC2Type:ulid) + , PRIMARY KEY(id), CONSTRAINT FK_52EA1F09A5D24A7A FOREIGN KEY (food_order_id) REFERENCES food_order (id) NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO order_item (id, name, extras, food_order_id) SELECT id, name, extras, food_order_id FROM __temp__order_item'); + $this->addSql('DROP TABLE __temp__order_item'); + $this->addSql('CREATE INDEX IDX_52EA1F09A5D24A7A ON order_item (food_order_id)'); + } +} diff --git a/src/Command/MigrateOrderitemsMenuitemsCommand.php b/src/Command/MigrateOrderitemsMenuitemsCommand.php new file mode 100644 index 0000000..101d354 --- /dev/null +++ b/src/Command/MigrateOrderitemsMenuitemsCommand.php @@ -0,0 +1,66 @@ +orderItemRepository->findAll(); + + foreach ($orderItems as $orderItem) { + + $menuItem = $this->menuItemRepository->findOneBy([ + 'name' => $orderItem->getName(), + 'foodVendor' => $orderItem->getFoodOrder() + ->getFoodVendor(), + ]); + + if ($menuItem === null) { + $menuItem = new MenuItem; + $menuItem->setName($orderItem->getName()); + $menuItem->setFoodVendor($orderItem->getFoodOrder()->getFoodVendor()); + $this->entityManager->persist($menuItem); + $this->entityManager->flush(); + $output->writeln(sprintf('Menu item %s added', $menuItem->getName())); + } + $orderItem->setMenuItem($menuItem); + $this->entityManager->persist($orderItem); + } + + $this->entityManager->flush(); + $io->success('You have a new command! Now make it your own! Pass --help to see your options.'); + + return Command::SUCCESS; + } +} diff --git a/src/Controller/OrderItemController.php b/src/Controller/OrderItemController.php index 5f819ef..512d0d7 100644 --- a/src/Controller/OrderItemController.php +++ b/src/Controller/OrderItemController.php @@ -3,8 +3,10 @@ namespace App\Controller; use App\Entity\FoodOrder; +use App\Entity\MenuItem; use App\Entity\OrderItem; use App\Form\OrderItemType; +use App\Repository\MenuItemRepository; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; @@ -15,18 +17,32 @@ use Symfony\Component\Routing\Attribute\Route; final class OrderItemController extends AbstractController { #[Route('/new/{foodOrder}', name: 'app_order_item_new', methods: ['GET', 'POST'])] - public function new(Request $request, FoodOrder $foodOrder, EntityManagerInterface $entityManager): Response + public function new(Request $request, FoodOrder $foodOrder, EntityManagerInterface $entityManager, MenuItemRepository $menuItemRepository): Response { if ($foodOrder->isClosed()) { return $this->redirectToRoute('app_food_order_show', [ 'id' => $foodOrder->getId(), ], Response::HTTP_SEE_OTHER); } + $orderItem = new OrderItem; $form = $this->createForm(OrderItemType::class, $orderItem); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { + $menuItem = $menuItemRepository->findOneBy([ + 'name' => $orderItem->getName(), + 'foodVendor' => $foodOrder->getFoodVendor(), + ]); + + if ($menuItem === null) { + $menuItem = new MenuItem; + $menuItem->setName($orderItem->getName()); + $menuItem->setFoodVendor($foodOrder->getFoodVendor()); + $entityManager->persist($menuItem); + } + + $orderItem->setMenuItem($menuItem); $orderItem->setFoodOrder($foodOrder); $entityManager->persist($orderItem); $entityManager->flush(); @@ -35,11 +51,15 @@ final class OrderItemController extends AbstractController 'id' => $foodOrder->getId(), ], Response::HTTP_SEE_OTHER); } + $menuItems = $menuItemRepository->findBy([ + 'foodVendor' => $foodOrder->getFoodVendor(), + ]); return $this->render('order_item/new.html.twig', [ 'order_item' => $orderItem, 'food_order' => $foodOrder, 'form' => $form, + 'menuItems' => $menuItems, ]); } diff --git a/src/Entity/FoodVendor.php b/src/Entity/FoodVendor.php index 67a8018..5c4a610 100644 --- a/src/Entity/FoodVendor.php +++ b/src/Entity/FoodVendor.php @@ -28,9 +28,16 @@ class FoodVendor #[ORM\OneToMany(targetEntity: FoodOrder::class, mappedBy: 'foodVendor', orphanRemoval: true)] private Collection $foodOrders; + /** + * @var Collection + */ + #[ORM\OneToMany(targetEntity: MenuItem::class, mappedBy: 'foodVendor', orphanRemoval: true)] + private Collection $menuItems; + public function __construct() { $this->foodOrders = new ArrayCollection; + $this->menuItems = new ArrayCollection; } public function getId(): Ulid|null @@ -77,4 +84,32 @@ class FoodVendor return $this; } + + /** + * @return Collection + */ + public function getMenuItems(): Collection + { + return $this->menuItems; + } + + public function addMenuItem(MenuItem $menuItem): static + { + if (! $this->menuItems->contains($menuItem)) { + $this->menuItems->add($menuItem); + $menuItem->setFoodVendor($this); + } + + return $this; + } + + public function removeMenuItem(MenuItem $menuItem): static + { + // set the owning side to null (unless already changed) + if ($this->menuItems->removeElement($menuItem) && $menuItem->getFoodVendor() === $this) { + $menuItem->setFoodVendor(null); + } + + return $this; + } } diff --git a/src/Entity/MenuItem.php b/src/Entity/MenuItem.php new file mode 100644 index 0000000..0f13ec9 --- /dev/null +++ b/src/Entity/MenuItem.php @@ -0,0 +1,55 @@ +id; + } + + public function getName(): string|null + { + return $this->name; + } + + public function setName(string $name): static + { + $this->name = $name; + + return $this; + } + + public function getFoodVendor(): FoodVendor|null + { + return $this->foodVendor; + } + + public function setFoodVendor(FoodVendor|null $foodVendor): static + { + $this->foodVendor = $foodVendor; + + return $this; + } +} diff --git a/src/Entity/OrderItem.php b/src/Entity/OrderItem.php index 4bff23a..eb98fb3 100644 --- a/src/Entity/OrderItem.php +++ b/src/Entity/OrderItem.php @@ -24,9 +24,13 @@ class OrderItem private string|null $extras = null; #[ORM\ManyToOne(inversedBy: 'orderItems')] - #[ORM\JoinColumn(nullable: false)] + #[ORM\JoinColumn(nullable: true)] private FoodOrder|null $foodOrder = null; + #[ORM\ManyToOne] + #[ORM\JoinColumn(nullable: true)] + private MenuItem|null $menuItem = null; + public function getId(): Ulid|null { return $this->id; @@ -67,4 +71,16 @@ class OrderItem return $this; } + + public function getMenuItem(): MenuItem|null + { + return $this->menuItem; + } + + public function setMenuItem(MenuItem|null $menuItem): static + { + $this->menuItem = $menuItem; + + return $this; + } } diff --git a/src/Repository/MenuItemRepository.php b/src/Repository/MenuItemRepository.php new file mode 100644 index 0000000..dbcb4f2 --- /dev/null +++ b/src/Repository/MenuItemRepository.php @@ -0,0 +1,43 @@ + + */ +final class MenuItemRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, MenuItem::class); + } + + // /** + // * @return MenuItem[] Returns an array of MenuItem objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('m') + // ->andWhere('m.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('m.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?MenuItem + // { + // return $this->createQueryBuilder('m') + // ->andWhere('m.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} diff --git a/templates/food_vendor/show.html.twig b/templates/food_vendor/show.html.twig index a14b226..a1a5803 100644 --- a/templates/food_vendor/show.html.twig +++ b/templates/food_vendor/show.html.twig @@ -7,10 +7,6 @@ - - - - diff --git a/templates/order_item/new.html.twig b/templates/order_item/new.html.twig index bd4ac99..5b90051 100644 --- a/templates/order_item/new.html.twig +++ b/templates/order_item/new.html.twig @@ -7,5 +7,24 @@ {{ include('order_item/_form.html.twig') }} +
+ click a button to select a given menuitem +
+
+ {% for menuItem in menuItems %} + + {% endfor %} +
+ +
+ back to list + + {% endblock %} From 5ff1832dee0759c0f05d13a94243a12e637ed21b Mon Sep 17 00:00:00 2001 From: lubiana Date: Wed, 26 Jun 2024 20:31:27 +0200 Subject: [PATCH 008/100] make orderitem menuitem non nullable --- migrations/Version20240626182031.php | 43 ++++++++++++++++++++ src/Controller/OrderItemController.php | 1 + src/Entity/OrderItem.php | 2 +- tests/Controller/OrderItemControllerTest.php | 12 +++++- 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 migrations/Version20240626182031.php diff --git a/migrations/Version20240626182031.php b/migrations/Version20240626182031.php new file mode 100644 index 0000000..8f74202 --- /dev/null +++ b/migrations/Version20240626182031.php @@ -0,0 +1,43 @@ +addSql('CREATE TEMPORARY TABLE __temp__order_item AS SELECT id, food_order_id, name, extras, menu_item_id FROM order_item'); + $this->addSql('DROP TABLE order_item'); + $this->addSql('CREATE TABLE order_item (id BLOB NOT NULL, food_order_id BLOB DEFAULT NULL, name VARCHAR(255) NOT NULL, extras VARCHAR(255) DEFAULT NULL, menu_item_id BLOB NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_52EA1F09A5D24A7A FOREIGN KEY (food_order_id) REFERENCES food_order (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_52EA1F099AB44FE0 FOREIGN KEY (menu_item_id) REFERENCES menu_item (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO order_item (id, food_order_id, name, extras, menu_item_id) SELECT id, food_order_id, name, extras, menu_item_id FROM __temp__order_item'); + $this->addSql('DROP TABLE __temp__order_item'); + $this->addSql('CREATE INDEX IDX_52EA1F099AB44FE0 ON order_item (menu_item_id)'); + $this->addSql('CREATE INDEX IDX_52EA1F09A5D24A7A ON order_item (food_order_id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE TEMPORARY TABLE __temp__order_item AS SELECT id, name, extras, food_order_id, menu_item_id FROM order_item'); + $this->addSql('DROP TABLE order_item'); + $this->addSql('CREATE TABLE order_item (id BLOB NOT NULL, name VARCHAR(255) NOT NULL, extras VARCHAR(255) DEFAULT NULL, food_order_id BLOB DEFAULT NULL, menu_item_id BLOB DEFAULT NULL, PRIMARY KEY(id), CONSTRAINT FK_52EA1F09A5D24A7A FOREIGN KEY (food_order_id) REFERENCES food_order (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_52EA1F099AB44FE0 FOREIGN KEY (menu_item_id) REFERENCES menu_item (id) NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO order_item (id, name, extras, food_order_id, menu_item_id) SELECT id, name, extras, food_order_id, menu_item_id FROM __temp__order_item'); + $this->addSql('DROP TABLE __temp__order_item'); + $this->addSql('CREATE INDEX IDX_52EA1F09A5D24A7A ON order_item (food_order_id)'); + $this->addSql('CREATE INDEX IDX_52EA1F099AB44FE0 ON order_item (menu_item_id)'); + } +} diff --git a/src/Controller/OrderItemController.php b/src/Controller/OrderItemController.php index 512d0d7..6f615a8 100644 --- a/src/Controller/OrderItemController.php +++ b/src/Controller/OrderItemController.php @@ -76,6 +76,7 @@ final class OrderItemController extends AbstractController $newOrderItem->setFoodOrder($orderItem->getFoodOrder()); $newOrderItem->setName($orderItem->getName()); $newOrderItem->setExtras($orderItem->getExtras()); + $newOrderItem->setMenuItem($orderItem->getMenuItem()); $entityManager->persist($newOrderItem); $entityManager->flush(); diff --git a/src/Entity/OrderItem.php b/src/Entity/OrderItem.php index eb98fb3..1429a5d 100644 --- a/src/Entity/OrderItem.php +++ b/src/Entity/OrderItem.php @@ -28,7 +28,7 @@ class OrderItem private FoodOrder|null $foodOrder = null; #[ORM\ManyToOne] - #[ORM\JoinColumn(nullable: true)] + #[ORM\JoinColumn(nullable: false)] private MenuItem|null $menuItem = null; public function getId(): Ulid|null diff --git a/tests/Controller/OrderItemControllerTest.php b/tests/Controller/OrderItemControllerTest.php index c8762df..f090f27 100644 --- a/tests/Controller/OrderItemControllerTest.php +++ b/tests/Controller/OrderItemControllerTest.php @@ -4,6 +4,7 @@ namespace App\Tests\Controller; use App\Entity\FoodOrder; use App\Entity\FoodVendor; +use App\Entity\MenuItem; use App\Entity\OrderItem; use App\Tests\DbWebTest; use Override; @@ -14,6 +15,7 @@ final class OrderItemControllerTest extends DbWebTest { public FoodVendor $vendor; public FoodOrder $order; + public Menuitem $menuItem; private string $path = '/order/item/'; #[Override] @@ -28,6 +30,11 @@ final class OrderItemControllerTest extends DbWebTest $this->order->setFoodVendor($this->vendor); $this->manager->persist($this->order); + + $this->menuItem = new MenuItem(); + $this->menuItem->setName('Testing'); + $this->menuItem->setFoodVendor($this->vendor); + $this->manager->persist($this->menuItem); $this->manager->flush(); } @@ -53,8 +60,10 @@ final class OrderItemControllerTest extends DbWebTest public function testRemove(): void { $fixture = new OrderItem; - $fixture->setName('Value'); + $fixture->setName('Testing'); $fixture->setExtras('Value'); + $fixture->setMenuItem($this->menuItem); + $fixture->setFoodOrder($this->order); $this->manager->persist($fixture); @@ -72,6 +81,7 @@ final class OrderItemControllerTest extends DbWebTest $orderItem->setName('My Title'); $orderItem->setExtras('My Title'); $orderItem->setFoodOrder($this->order); + $orderItem->setMenuItem($this->menuItem); $this->manager->persist($orderItem); $this->manager->flush(); From 83e1ae3204b3f6103544dda13b3ec1bc5f8953c0 Mon Sep 17 00:00:00 2001 From: Continuous Integration Date: Wed, 26 Jun 2024 18:32:46 +0000 Subject: [PATCH 009/100] Continuous Integration Fixes --- tests/Controller/OrderItemControllerTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Controller/OrderItemControllerTest.php b/tests/Controller/OrderItemControllerTest.php index f090f27..a7b0fb8 100644 --- a/tests/Controller/OrderItemControllerTest.php +++ b/tests/Controller/OrderItemControllerTest.php @@ -31,9 +31,10 @@ final class OrderItemControllerTest extends DbWebTest $this->manager->persist($this->order); - $this->menuItem = new MenuItem(); + $this->menuItem = new MenuItem; $this->menuItem->setName('Testing'); $this->menuItem->setFoodVendor($this->vendor); + $this->manager->persist($this->menuItem); $this->manager->flush(); } From 01354fa70c36a70d5a503139e32531bb8410be3b Mon Sep 17 00:00:00 2001 From: lubiana Date: Wed, 26 Jun 2024 20:49:00 +0200 Subject: [PATCH 010/100] remove vendor id from list --- templates/food_vendor/index.html.twig | 2 -- 1 file changed, 2 deletions(-) diff --git a/templates/food_vendor/index.html.twig b/templates/food_vendor/index.html.twig index 1cb1701..7754082 100644 --- a/templates/food_vendor/index.html.twig +++ b/templates/food_vendor/index.html.twig @@ -8,7 +8,6 @@
Id{{ food_vendor.id }}
Name {{ food_vendor.name }}
- @@ -16,7 +15,6 @@ {% for food_vendor in food_vendors %} - \ No newline at end of file diff --git a/templates/food_vendor/_form.html.twig b/templates/food_vendor/_form.html.twig index bf20b98..e0ed7ee 100644 --- a/templates/food_vendor/_form.html.twig +++ b/templates/food_vendor/_form.html.twig @@ -1,4 +1,4 @@ -{{ form_start(form) }} - {{ form_widget(form) }} - +{{ form_start(form, {'attr': {'class': 'mb-3'}}) }} + {{ form_widget(form, {'attr': {'class': 'form-control'}}) }} + {{ form_end(form) }} diff --git a/templates/food_vendor/edit.html.twig b/templates/food_vendor/edit.html.twig index 3adde61..83e4bd3 100644 --- a/templates/food_vendor/edit.html.twig +++ b/templates/food_vendor/edit.html.twig @@ -3,9 +3,11 @@ {% block title %}Edit FoodVendor{% endblock %} {% block body %} -

Edit FoodVendor

+

Edit FoodVendor

- {{ include('food_vendor/_form.html.twig', {'button_label': 'Update'}) }} +
+ {{ include('food_vendor/_form.html.twig', {'button_label': 'Update'}) }} +
- back to list + back to list {% endblock %} diff --git a/templates/food_vendor/index.html.twig b/templates/food_vendor/index.html.twig index 7754082..8857c40 100644 --- a/templates/food_vendor/index.html.twig +++ b/templates/food_vendor/index.html.twig @@ -3,10 +3,10 @@ {% block title %}FoodVendor index{% endblock %} {% block body %} -

FoodVendor index

+

FoodVendor index

-
Id Name actions
{{ food_vendor.id }} {{ food_vendor.name }} show From 634f13d968790b4dc331d9ee02ec0c4d7f1cff1c Mon Sep 17 00:00:00 2001 From: lubiana Date: Thu, 27 Jun 2024 16:57:15 +0200 Subject: [PATCH 011/100] reset database for each test, test menuitem creation --- tests/Controller/OrderItemControllerTest.php | 24 ++++++++++++++++++++ tests/DbWebTest.php | 7 +----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/tests/Controller/OrderItemControllerTest.php b/tests/Controller/OrderItemControllerTest.php index a7b0fb8..a5f6da2 100644 --- a/tests/Controller/OrderItemControllerTest.php +++ b/tests/Controller/OrderItemControllerTest.php @@ -6,6 +6,7 @@ use App\Entity\FoodOrder; use App\Entity\FoodVendor; use App\Entity\MenuItem; use App\Entity\OrderItem; +use App\Repository\MenuItemRepository; use App\Tests\DbWebTest; use Override; @@ -16,6 +17,7 @@ final class OrderItemControllerTest extends DbWebTest public FoodVendor $vendor; public FoodOrder $order; public Menuitem $menuItem; + public MenuItemRepository $menuItemRepository; private string $path = '/order/item/'; #[Override] @@ -37,6 +39,7 @@ final class OrderItemControllerTest extends DbWebTest $this->manager->persist($this->menuItem); $this->manager->flush(); + $this->menuItemRepository = static::getContainer()->get(MenuItemRepository::class); } public function testNew(): void @@ -56,6 +59,27 @@ final class OrderItemControllerTest extends DbWebTest self::assertResponseRedirects(sprintf('/food/order/%s', $this->order->getId())); self::assertSame(1, $this->repository->count([])); + self::assertSame(1, $this->menuItemRepository->count([])); + } + + public function testNewCreateMenuItem(): void + { + $this->client->request( + 'GET', + sprintf('%snew/%s', $this->path, $this->order->getId()) + ); + + self::assertResponseStatusCodeSame(200); + + $this->client->submitForm('Save', [ + 'order_item[name]' => 'Testing-1', + 'order_item[extras]' => 'Testing-1', + ]); + + self::assertResponseRedirects(sprintf('/food/order/%s', $this->order->getId())); + + self::assertSame(1, $this->repository->count([])); + self::assertSame(2, $this->menuItemRepository->count([])); } public function testRemove(): void diff --git a/tests/DbWebTest.php b/tests/DbWebTest.php index cbcf5c9..c2491c6 100644 --- a/tests/DbWebTest.php +++ b/tests/DbWebTest.php @@ -25,13 +25,8 @@ abstract class DbWebTest extends WebTestCase $schemaTool = new SchemaTool($this->manager); $metadata = $this->manager->getMetadataFactory() ->getAllMetadata(); + $schemaTool->dropDatabase(); $schemaTool->updateSchema($metadata); - $this->repository = $this->manager->getRepository($this->getEntityClass()); - foreach ($this->repository->findAll() as $object) { - $this->manager->remove($object); - } - - $this->manager->flush(); } } From b479fbf5ed752ed9bfccf5c078b89293b73364c8 Mon Sep 17 00:00:00 2001 From: lubiana Date: Thu, 27 Jun 2024 17:14:59 +0200 Subject: [PATCH 012/100] #21 add planned closing time to food order --- src/Entity/FoodOrder.php | 7 +++++-- src/Form/FoodOrderType.php | 3 +++ src/Repository/FoodOrderRepository.php | 2 +- tests/Controller/OrderItemControllerTest.php | 1 + tests/DbWebTest.php | 1 + 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Entity/FoodOrder.php b/src/Entity/FoodOrder.php index 847542b..72a9530 100644 --- a/src/Entity/FoodOrder.php +++ b/src/Entity/FoodOrder.php @@ -3,6 +3,7 @@ namespace App\Entity; use App\Repository\FoodOrderRepository; +use DateInterval; use DateTimeImmutable; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -36,6 +37,7 @@ class FoodOrder public function __construct() { $this->orderItems = new ArrayCollection; + $this->open(); } public function getId(): Ulid|null @@ -62,7 +64,7 @@ class FoodOrder public function isClosed(): bool { - return $this->closedAt instanceof DateTimeImmutable; + return $this->closedAt instanceof DateTimeImmutable && $this->closedAt->getTimestamp() <= (new DateTimeImmutable)->getTimestamp(); } public function close(): static @@ -72,7 +74,8 @@ class FoodOrder public function open(): static { - return $this->setClosedAt(null); + $this->closedAt = (new DateTimeImmutable)->add(new DateInterval('PT1H')); + return $this; } public function getFoodVendor(): FoodVendor|null diff --git a/src/Form/FoodOrderType.php b/src/Form/FoodOrderType.php index bfe9dc4..b0f177b 100644 --- a/src/Form/FoodOrderType.php +++ b/src/Form/FoodOrderType.php @@ -21,6 +21,9 @@ final class FoodOrderType extends AbstractType 'class' => FoodVendor::class, 'choice_label' => 'name', ]) + ->add(child: 'closedAt', options: [ + 'label' => 'closes at', + ]) ; if ($action !== null) { $builder->setAction($action); diff --git a/src/Repository/FoodOrderRepository.php b/src/Repository/FoodOrderRepository.php index 4438819..aea76d5 100644 --- a/src/Repository/FoodOrderRepository.php +++ b/src/Repository/FoodOrderRepository.php @@ -27,7 +27,7 @@ final class FoodOrderRepository extends ServiceEntityRepository /** * @return FoodOrder[] */ - public function findLatestEntries(int $limit = 10): array + public function findLatestEntries(int $limit = 5): array { $qb = $this->createQueryBuilder('alias'); diff --git a/tests/Controller/OrderItemControllerTest.php b/tests/Controller/OrderItemControllerTest.php index a5f6da2..706d1c1 100644 --- a/tests/Controller/OrderItemControllerTest.php +++ b/tests/Controller/OrderItemControllerTest.php @@ -39,6 +39,7 @@ final class OrderItemControllerTest extends DbWebTest $this->manager->persist($this->menuItem); $this->manager->flush(); + $this->menuItemRepository = static::getContainer()->get(MenuItemRepository::class); } diff --git a/tests/DbWebTest.php b/tests/DbWebTest.php index c2491c6..18ef24a 100644 --- a/tests/DbWebTest.php +++ b/tests/DbWebTest.php @@ -27,6 +27,7 @@ abstract class DbWebTest extends WebTestCase ->getAllMetadata(); $schemaTool->dropDatabase(); $schemaTool->updateSchema($metadata); + $this->repository = $this->manager->getRepository($this->getEntityClass()); } } From 9d81464fd84c471836158413eb9d39c861eae26d Mon Sep 17 00:00:00 2001 From: lubiana Date: Thu, 27 Jun 2024 17:43:14 +0200 Subject: [PATCH 013/100] #20 add username form --- src/Controller/HomeController.php | 18 +++++++++++++++++- src/Form/UserNameFormType.php | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/Form/UserNameFormType.php diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php index a9bd31e..991729e 100644 --- a/src/Controller/HomeController.php +++ b/src/Controller/HomeController.php @@ -2,16 +2,32 @@ namespace App\Controller; +use App\Form\UserNameFormType; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -final class HomeController +final class HomeController extends AbstractController { + public const string DEFAULT_USERNAME = 'nobody'; #[Route('/', name: 'home')] public function home(UrlGeneratorInterface $router): Response { return new RedirectResponse($router->generate('app_food_order_index')); } + + public function usernameForm(Request $request): Response + { + $username = $request->cookies->get('username', self::DEFAULT_USERNAME); + $form = $this->createForm(UsernameFormType::class); + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $username = $form->getData()['username'] ?? self::DEFAULT_USERNAME; + if ($username === '') {} + + } + } } diff --git a/src/Form/UserNameFormType.php b/src/Form/UserNameFormType.php new file mode 100644 index 0000000..63cb607 --- /dev/null +++ b/src/Form/UserNameFormType.php @@ -0,0 +1,24 @@ +add('username') + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + // Configure your form options here + ]); + } +} From 511f12f10faf1407cef0ce9dd724933aed453d18 Mon Sep 17 00:00:00 2001 From: lubiana Date: Thu, 27 Jun 2024 23:33:32 +0200 Subject: [PATCH 014/100] !20 add username to order and item --- migrations/Version20240627212849.php | 44 ++++++++++++++++++++++++ src/Controller/HomeController.php | 22 +++++++++--- src/Entity/FoodOrder.php | 17 +++++++++ src/Entity/OrderItem.php | 17 +++++++++ src/Form/OrderItemType.php | 4 ++- src/Form/UserNameFormType.php | 11 ++++-- templates/base.html.twig | 36 +++++++++++-------- templates/food_order/index.html.twig | 1 + templates/food_order/show.html.twig | 6 ++++ templates/food_order/table_row.html.twig | 1 + templates/order_item/new.html.twig | 3 +- templates/username.html.twig | 9 +++++ 12 files changed, 147 insertions(+), 24 deletions(-) create mode 100644 migrations/Version20240627212849.php create mode 100644 templates/username.html.twig diff --git a/migrations/Version20240627212849.php b/migrations/Version20240627212849.php new file mode 100644 index 0000000..2a5650b --- /dev/null +++ b/migrations/Version20240627212849.php @@ -0,0 +1,44 @@ +addSql('ALTER TABLE food_order ADD COLUMN created_by VARCHAR(255) DEFAULT \'nobody\' NOT NULL'); + $this->addSql('ALTER TABLE order_item ADD COLUMN created_by VARCHAR(255) DEFAULT \'nobody\' NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE TEMPORARY TABLE __temp__food_order AS SELECT id, closed_at, food_vendor_id FROM food_order'); + $this->addSql('DROP TABLE food_order'); + $this->addSql('CREATE TABLE food_order (id BLOB NOT NULL, closed_at DATETIME DEFAULT NULL, food_vendor_id BLOB NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_44856726EF983E8 FOREIGN KEY (food_vendor_id) REFERENCES food_vendor (id) NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO food_order (id, closed_at, food_vendor_id) SELECT id, closed_at, food_vendor_id FROM __temp__food_order'); + $this->addSql('DROP TABLE __temp__food_order'); + $this->addSql('CREATE INDEX IDX_44856726EF983E8 ON food_order (food_vendor_id)'); + $this->addSql('CREATE TEMPORARY TABLE __temp__order_item AS SELECT id, name, extras, food_order_id, menu_item_id FROM order_item'); + $this->addSql('DROP TABLE order_item'); + $this->addSql('CREATE TABLE order_item (id BLOB NOT NULL, name VARCHAR(255) NOT NULL, extras VARCHAR(255) DEFAULT NULL, food_order_id BLOB DEFAULT NULL, menu_item_id BLOB NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_52EA1F09A5D24A7A FOREIGN KEY (food_order_id) REFERENCES food_order (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_52EA1F099AB44FE0 FOREIGN KEY (menu_item_id) REFERENCES menu_item (id) NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO order_item (id, name, extras, food_order_id, menu_item_id) SELECT id, name, extras, food_order_id, menu_item_id FROM __temp__order_item'); + $this->addSql('DROP TABLE __temp__order_item'); + $this->addSql('CREATE INDEX IDX_52EA1F09A5D24A7A ON order_item (food_order_id)'); + $this->addSql('CREATE INDEX IDX_52EA1F099AB44FE0 ON order_item (menu_item_id)'); + } +} diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php index 991729e..46c90c7 100644 --- a/src/Controller/HomeController.php +++ b/src/Controller/HomeController.php @@ -4,6 +4,7 @@ namespace App\Controller; use App\Form\UserNameFormType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -13,21 +14,34 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; final class HomeController extends AbstractController { public const string DEFAULT_USERNAME = 'nobody'; + #[Route('/', name: 'home')] public function home(UrlGeneratorInterface $router): Response { return new RedirectResponse($router->generate('app_food_order_index')); } - public function usernameForm(Request $request): Response + #[Route('/username', name: 'username')] + public function usernameForm(Request $request, UrlGeneratorInterface $router): Response { - $username = $request->cookies->get('username', self::DEFAULT_USERNAME); $form = $this->createForm(UsernameFormType::class); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $username = $form->getData()['username'] ?? self::DEFAULT_USERNAME; - if ($username === '') {} - + $response = new RedirectResponse($router->generate('app_food_order_index')); + if ($username === self::DEFAULT_USERNAME || $username === '') { + $response->headers->clearCookie('username'); + return $response; + } + $response->headers->setCookie(new Cookie('username', $username)); + return $response; } + $username = $request->cookies->get('username', self::DEFAULT_USERNAME); + $form->setData([ + 'username' => $username, + ]); + return $this->render('username.html.twig', [ + 'form' => $form, + ]); } } diff --git a/src/Entity/FoodOrder.php b/src/Entity/FoodOrder.php index 72a9530..40d7db8 100644 --- a/src/Entity/FoodOrder.php +++ b/src/Entity/FoodOrder.php @@ -34,6 +34,11 @@ class FoodOrder #[ORM\OneToMany(targetEntity: OrderItem::class, mappedBy: 'foodOrder', orphanRemoval: true)] private Collection $orderItems; + #[ORM\Column(length: 255, options: [ + 'default' => 'nobody', + ])] + private string|null $createdBy = 'nobody'; + public function __construct() { $this->orderItems = new ArrayCollection; @@ -117,4 +122,16 @@ class FoodOrder return $this; } + + public function getCreatedBy(): string|null + { + return $this->createdBy; + } + + public function setCreatedBy(string $createdBy): static + { + $this->createdBy = $createdBy; + + return $this; + } } diff --git a/src/Entity/OrderItem.php b/src/Entity/OrderItem.php index 1429a5d..cc7abd4 100644 --- a/src/Entity/OrderItem.php +++ b/src/Entity/OrderItem.php @@ -31,6 +31,11 @@ class OrderItem #[ORM\JoinColumn(nullable: false)] private MenuItem|null $menuItem = null; + #[ORM\Column(length: 255, options: [ + 'default' => 'nobody', + ])] + private string|null $createdBy = 'nobody'; + public function getId(): Ulid|null { return $this->id; @@ -83,4 +88,16 @@ class OrderItem return $this; } + + public function getCreatedBy(): string|null + { + return $this->createdBy; + } + + public function setCreatedBy(string $createdBy): static + { + $this->createdBy = $createdBy; + + return $this; + } } diff --git a/src/Form/OrderItemType.php b/src/Form/OrderItemType.php index 4716baf..2cd7f32 100644 --- a/src/Form/OrderItemType.php +++ b/src/Form/OrderItemType.php @@ -14,7 +14,9 @@ final class OrderItemType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options): void { $builder - ->add('name') + ->add(child: 'name', options: [ + 'data' => $options['name'] ?? '', + ]) ->add('extras') ; } diff --git a/src/Form/UserNameFormType.php b/src/Form/UserNameFormType.php index 63cb607..6d2a011 100644 --- a/src/Form/UserNameFormType.php +++ b/src/Form/UserNameFormType.php @@ -1,20 +1,25 @@ -add('username') + ->add(child: 'username', options: [ + 'required' => false, + ]) ; } + #[Override] public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ diff --git a/templates/base.html.twig b/templates/base.html.twig index 1918768..a286536 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -4,23 +4,29 @@ {% block title %}Welcome!{% endblock %} - + + -
- - -
-
- {% block body %}{% endblock %} -
+
+

Hello {{ app.request.cookies.get('username', 'nobody') }} - change name

+ +
+
+ {% block body %}{% endblock %} +
+ diff --git a/templates/food_order/index.html.twig b/templates/food_order/index.html.twig index 1a80bb5..e0aaf6c 100644 --- a/templates/food_order/index.html.twig +++ b/templates/food_order/index.html.twig @@ -8,6 +8,7 @@ + diff --git a/templates/food_order/show.html.twig b/templates/food_order/show.html.twig index 556de6a..ddf36c3 100644 --- a/templates/food_order/show.html.twig +++ b/templates/food_order/show.html.twig @@ -11,6 +11,10 @@ + + + + @@ -32,6 +36,7 @@
CreatedBy Vendor CreatedAt ClosedAtVendor {{ food_order.foodVendor.name }}
Created By{{ food_order.createdBy }}
CreatedAt {{ food_order.createdAt ? food_order.createdAt|date('Y-m-d H:i:s') : '' }}
+ @@ -40,6 +45,7 @@ {% for item in food_order.orderItems %} + + diff --git a/templates/order_item/new.html.twig b/templates/order_item/new.html.twig index 5b90051..53aff8d 100644 --- a/templates/order_item/new.html.twig +++ b/templates/order_item/new.html.twig @@ -12,7 +12,7 @@
{% for menuItem in menuItems %} - + {{ menuItem.name }} {% endfor %}
@@ -23,6 +23,7 @@ + {% block javascripts %} + {% block importmap %}{{ importmap('app') }}{% endblock %} + {% endblock %}
From 5cb66c5012635b1fc026e3cca8c8c9a728a229f0 Mon Sep 17 00:00:00 2001 From: lubiana Date: Wed, 18 Jun 2025 20:12:17 +0200 Subject: [PATCH 085/100] booty --- assets/app.js | 15 +- assets/javascript/emoji-footprint.js | 19 + assets/javascript/modes.js | 136 +++++ assets/javascript/numberInputs.js | 55 ++ assets/javascript/radioState.js | 35 ++ assets/javascript/theme.js | 18 + assets/styles/app.css | 182 +++++- assets/styles/emoji-footprint.css | 30 + assets/styles/modes.css | 565 ++++++++++++++++++ config/packages/twig.php | 19 +- templates/_form.html.twig | 6 +- templates/base.html.twig | 56 +- templates/food_order/edit.html.twig | 8 +- templates/food_order/index.html.twig | 25 +- templates/food_order/new.html.twig | 4 +- templates/food_order/show.html.twig | 32 +- templates/food_order/table_row.html.twig | 2 +- templates/food_vendor/_form.html.twig | 6 +- templates/food_vendor/edit.html.twig | 8 +- templates/food_vendor/index.html.twig | 14 +- templates/food_vendor/new.html.twig | 8 +- templates/food_vendor/show.html.twig | 21 +- templates/menu_item/_delete_form.html.twig | 2 +- templates/menu_item/_form.html.twig | 6 +- templates/menu_item/edit.html.twig | 10 +- templates/menu_item/index.html.twig | 14 +- templates/menu_item/new.html.twig | 8 +- templates/menu_item/show.html.twig | 18 +- templates/order_item/_form.html.twig | 6 +- templates/order_item/edit.html.twig | 8 +- templates/order_item/new.html.twig | 16 +- templates/username.html.twig | 8 +- .../Controller/FoodOrderControllerTest.php | 6 +- .../Controller/FoodVendorControllerTest.php | 2 +- 34 files changed, 1236 insertions(+), 132 deletions(-) create mode 100644 assets/javascript/emoji-footprint.js create mode 100644 assets/javascript/modes.js create mode 100644 assets/javascript/numberInputs.js create mode 100644 assets/javascript/radioState.js create mode 100644 assets/javascript/theme.js create mode 100644 assets/styles/emoji-footprint.css create mode 100644 assets/styles/modes.css diff --git a/assets/app.js b/assets/app.js index 321cea2..88672ac 100644 --- a/assets/app.js +++ b/assets/app.js @@ -4,6 +4,19 @@ * This file will be included onto the page via the importmap() Twig function, * which should already be in your base.html.twig. */ +import 'bootstrap/dist/css/bootstrap.min.css'; import './styles/app.css'; +import './styles/modes.css'; +import './styles/emoji-footprint.css'; -import './javascript/htmx.js'; \ No newline at end of file +// Import modules +import './javascript/theme.js'; +import './javascript/emoji-footprint.js'; +import './javascript/modes.js'; +import './javascript/htmx.js'; +import 'bootstrap'; +import { initRadioState } from './javascript/radioState.js'; + +document.addEventListener('DOMContentLoaded', () => { + initRadioState(); +}); \ No newline at end of file diff --git a/assets/javascript/emoji-footprint.js b/assets/javascript/emoji-footprint.js new file mode 100644 index 0000000..238377b --- /dev/null +++ b/assets/javascript/emoji-footprint.js @@ -0,0 +1,19 @@ +// Sparkle effect on mouse move +document.addEventListener('mousemove', function (e) { + const emojis = ['✨', '💖', '🌟', '💅', '🦄', '🎉', '🌈']; + const sparkle = document.createElement('div'); + sparkle.className = 'emoji-footprint'; + sparkle.textContent = emojis[Math.floor(Math.random() * emojis.length)]; + sparkle.style.left = e.pageX + 'px'; + sparkle.style.top = e.pageY + 'px'; + document.body.appendChild(sparkle); + + setTimeout(() => { + sparkle.remove(); + }, 1000); +}); + +export function initEmojiFootprint() { + // The sparkle effect is already initialized when this module is imported + // This function can be used if we need to control when the effect starts +} \ No newline at end of file diff --git a/assets/javascript/modes.js b/assets/javascript/modes.js new file mode 100644 index 0000000..a288f32 --- /dev/null +++ b/assets/javascript/modes.js @@ -0,0 +1,136 @@ +// Bonkers mode functionality +function setEmojiLevelClass(mode) { + document.body.classList.remove('emoji-normal', 'emoji-enhanced', 'emoji-bonkers'); + if (mode === 'bonkers') { + document.body.classList.add('emoji-bonkers'); + } else if (mode === 'enhanced') { + document.body.classList.add('emoji-enhanced'); + } else { + document.body.classList.add('emoji-normal'); + } +} + +function initBonkersMode() { + // Check if we're in bonkers mode + const currentMode = document.documentElement.getAttribute('data-website-mode'); + setEmojiLevelClass(currentMode); + + if (currentMode === 'bonkers') { + // Apply bonkers mode immediately + document.body.classList.add('bonkers-mode'); + + // Start the fabulous effects + createExtraSparkles(); + createSlayEffects(); + + console.log('🌈✨ Bonkers mode activated! ✨🌈'); + } else { + // Remove bonkers mode if it was active + document.body.classList.remove('bonkers-mode'); + } +} + +// Function to create extra sparkles during bonkers mode +function createExtraSparkles() { + const currentMode = document.documentElement.getAttribute('data-website-mode'); + if (currentMode !== 'bonkers') return; + + const extraEmojis = [ + '💃', '🕺', + '🍑', '💦', '😏', '😈', '👅', '💋', '🥵', '😳', '🤤', '😍', '🥴', + '💕', '💖', '💗', '💘', '💝', '💞', '💟', '💌', '💏', '💑', + '🍆', '🥒', '🍌', '💦', '👀', '😉', '😌', '😍', '🥰', '😘', + '😚', '😋', '😏', '😫', '😩', '🥺', '🥵', '🥴', + '💖', '💗', '💕', '💞', '💓', '💗', '💖', '💘', '💝', + '💋', '💏', '💑' + ]; + const sparkle = document.createElement('div'); + sparkle.className = 'emoji-footprint'; + sparkle.textContent = extraEmojis[Math.floor(Math.random() * extraEmojis.length)]; + sparkle.style.left = Math.random() * window.innerWidth + 'px'; + sparkle.style.top = Math.random() * window.innerHeight + 'px'; + document.body.appendChild(sparkle); + + setTimeout(() => { + if (sparkle.parentNode) { + sparkle.remove(); + } + }, 3000); + + // Continue creating extra sparkles while in bonkers mode + const newMode = document.documentElement.getAttribute('data-website-mode'); + if (newMode === 'bonkers') { + setTimeout(() => createExtraSparkles(), 150); + } +} + +// Function to create slay effects +function createSlayEffects() { + const currentMode = document.documentElement.getAttribute('data-website-mode'); + if (currentMode !== 'bonkers') return; + + // Create floating "SLAY" text effects + const slayWords = [ + 'SLAY', 'QUEEN', 'FABULOUS', 'ICONIC', 'LEGENDARY', 'STUNNING', 'GORGEOUS', 'FLAWLESS', + 'DAZZLING', 'RADIANT', 'BREATHTAKING', 'EXQUISITE', 'DIVINE' + ]; + const slayElement = document.createElement('div'); + slayElement.className = 'slay-text'; + slayElement.textContent = slayWords[Math.floor(Math.random() * slayWords.length)]; + slayElement.style.left = Math.random() * window.innerWidth + 'px'; + slayElement.style.top = Math.random() * window.innerHeight + 'px'; + document.body.appendChild(slayElement); + + setTimeout(() => { + if (slayElement.parentNode) { + slayElement.remove(); + } + }, 3000); + + // Continue creating slay effects while in bonkers mode + const newMode = document.documentElement.getAttribute('data-website-mode'); + if (newMode === 'bonkers') { + setTimeout(() => createSlayEffects(), 800); + } +} + +// Watch for mode changes +function watchModeChanges() { + // Create a MutationObserver to watch for changes to the data-website-mode attribute + const observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === 'attributes' && mutation.attributeName === 'data-website-mode') { + const newMode = document.documentElement.getAttribute('data-website-mode'); + + if (newMode === 'bonkers') { + document.body.classList.add('bonkers-mode'); + setEmojiLevelClass(newMode); + + // Start the fabulous effects + createExtraSparkles(); + createSlayEffects(); + + console.log('🌈✨ Switched to bonkers mode! ✨🌈'); + } else { + document.body.classList.remove('bonkers-mode'); + setEmojiLevelClass(newMode); + console.log(`😴 Switched to ${newMode} mode`); + } + } + }); + }); + + // Start observing + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ['data-website-mode'] + }); +} + +// Initialize when DOM is loaded +document.addEventListener('DOMContentLoaded', function() { + initBonkersMode(); + watchModeChanges(); +}); + +export { initBonkersMode, watchModeChanges }; diff --git a/assets/javascript/numberInputs.js b/assets/javascript/numberInputs.js new file mode 100644 index 0000000..a4a8dc1 --- /dev/null +++ b/assets/javascript/numberInputs.js @@ -0,0 +1,55 @@ +// Function to initialize number input buttons +function initNumberInputs(container = document) { + container.querySelectorAll('.number-input-wrapper').forEach(function(wrapper) { + const input = wrapper.querySelector('input[type="number"]'); + const decreaseBtn = wrapper.querySelector('[data-action="decrease"]'); + const increaseBtn = wrapper.querySelector('[data-action="increase"]'); + + if (!input || !decreaseBtn || !increaseBtn) return; + + // Skip if already initialized + if (decreaseBtn.hasAttribute('data-initialized')) return; + + const step = parseFloat(input.getAttribute('step')) || 1; + const min = 0; + const max = input.getAttribute('max') ? parseFloat(input.getAttribute('max')) : null; + + decreaseBtn.addEventListener('click', function() { + const currentValue = parseFloat(input.value) || 0; + const newValue = currentValue - step; + + if (min === null || newValue >= min) { + input.value = newValue; + input.dispatchEvent(new Event('change', { bubbles: true })); + } + }); + + increaseBtn.addEventListener('click', function() { + const currentValue = parseFloat(input.value) || 0; + const newValue = currentValue + step; + + if (max === null || newValue <= max) { + input.value = newValue; + input.dispatchEvent(new Event('change', { bubbles: true })); + } + }); + + // Validate input on change + input.addEventListener('input', function() { + const value = parseFloat(this.value); + + if (min !== null && value < min) { + this.value = min; + } + if (max !== null && value > max) { + this.value = max; + } + }); + + // Mark as initialized + decreaseBtn.setAttribute('data-initialized', 'true'); + increaseBtn.setAttribute('data-initialized', 'true'); + }); +} + +export { initNumberInputs }; \ No newline at end of file diff --git a/assets/javascript/radioState.js b/assets/javascript/radioState.js new file mode 100644 index 0000000..a30d311 --- /dev/null +++ b/assets/javascript/radioState.js @@ -0,0 +1,35 @@ +// Radio button state management with localStorage +function initRadioState() { + // Store and retrieve radio button state + const radioButtons = document.querySelectorAll('input[name="mode"]'); + + // Load saved state on page load + const savedMode = localStorage.getItem('selectedMode'); + if (savedMode) { + const radioToCheck = document.getElementById(savedMode); + if (radioToCheck) { + radioToCheck.checked = true; + // Set the data attribute to match the saved mode + document.documentElement.setAttribute('data-website-mode', savedMode); + } + } else { + // If no saved state, set to the currently checked radio button + const checkedRadio = document.querySelector('input[name="mode"]:checked'); + if (checkedRadio) { + document.documentElement.setAttribute('data-website-mode', checkedRadio.id); + } + } + + // Save state when radio button changes + radioButtons.forEach(radio => { + radio.addEventListener('change', function() { + if (this.checked) { + localStorage.setItem('selectedMode', this.id); + // Update the data attribute when mode changes + document.documentElement.setAttribute('data-website-mode', this.id); + } + }); + }); +} + +export { initRadioState }; \ No newline at end of file diff --git a/assets/javascript/theme.js b/assets/javascript/theme.js new file mode 100644 index 0000000..8acf738 --- /dev/null +++ b/assets/javascript/theme.js @@ -0,0 +1,18 @@ +// Theme detection and switching +const getPreferredTheme = () => { + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' +} + +const setTheme = theme => { + document.documentElement.setAttribute('data-bs-theme', theme) +} + +// Set initial theme +setTheme(getPreferredTheme()) + +// Listen for changes in user's preferred color scheme +window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { + setTheme(getPreferredTheme()) +}) + +export { getPreferredTheme, setTheme }; \ No newline at end of file diff --git a/assets/styles/app.css b/assets/styles/app.css index dd6181a..7400735 100644 --- a/assets/styles/app.css +++ b/assets/styles/app.css @@ -1,3 +1,179 @@ -body { - background-color: skyblue; -} +/* + * ================================================================================================= + * 💖 BUBBLEGUM PUNK THEME (LIGHT) 💖 + * + * This isn't just a theme. It's a statement. + * Unapologetically loud, pink, and quirky. + * ================================================================================================= + */ + :root, + [data-bs-theme=light] { + /* --- CORE VIBE --- */ + --bs-pink: #FF007A; /* 💖 Hyper Pink (Our Queen) */ + --bs-green: #CFFF50; /* 🧪 Toxic Slime */ + --bs-purple: #A328D6; /* 👾 Graffiti Purple */ + --bs-yellow: #F9F871; /* ⚡ Neon Lemon */ + --bs-cyan: #00F5D4; /* 💎 Glitchy Teal */ + --bs-blue: #00A9E0; /* 💦 Splash Zone */ + + /* Let's redefine ALL the core colors to match the new energy */ + --bs-primary: var(--bs-pink); + --bs-secondary: var(--bs-green); + --bs-success: var(--bs-cyan); + --bs-info: var(--bs-blue); + --bs-warning: var(--bs-yellow); + --bs-danger: #FF3D3D; /* 🚨 Code Red Rave */ + + /* --- BACKGROUNDS & TEXT --- */ + /* No more boring white! */ + --bs-body-bg: #FFF5FD; /* A soft, dreamy pink canvas */ + --bs-body-color: #4A003D; /* Dark Plum (instead of black) for text */ + --bs-heading-color: var(--bs-purple); /* Make headings POP */ + --bs-secondary-color: rgba(74, 0, 61, 0.75); /* Plum, but softer */ + --bs-tertiary-color: rgba(74, 0, 61, 0.5); + + /* Make cards and containers pure white to contrast the pink background */ + --bs-tertiary-bg: #FFFFFF; + --bs-secondary-bg: #FEF9FE; + + /* --- LINKS & CODE --- */ + --bs-link-color: var(--bs-pink); + --bs-link-hover-color: var(--bs-purple); + --bs-code-color: var(--bs-purple); + + /* --- BORDERS & SHADOWS: LET'S GET QUIRKY --- */ + --bs-border-width: 2px; /* Chunky borders! */ + --bs-border-color: #FFD6F5; /* Pink-tinted border color */ + --bs-border-color-translucent: rgba(74, 0, 61, 0.2); + --bs-border-radius: 1rem; /* Super bubbly and round */ + --bs-border-radius-sm: 0.5rem; + --bs-border-radius-lg: 1.5rem; + --bs-border-radius-pill: 50rem; + + /* Say goodbye to black shadows, hello to colored glows! */ + --bs-box-shadow: 0 4px 12px rgba(255, 0, 122, 0.2); + --bs-box-shadow-sm: 0 2px 4px rgba(255, 0, 122, 0.15); + --bs-box-shadow-lg: 0 8px 30px rgba(255, 0, 122, 0.25); + --bs-box-shadow-inset: inset 0 1px 4px rgba(74, 0, 61, 0.2); + + /* --- THE GRADIENT: THE SOUL OF THE THEME --- */ + --bs-gradient: linear-gradient(75deg, var(--bs-primary), var(--bs-secondary)); + + /* --- Don't forget the RGB values for Bootstrap components! --- */ + --bs-primary-rgb: 255, 0, 122; + --bs-secondary-rgb: 207, 255, 80; + --bs-body-color-rgb: 74, 0, 61; + --bs-body-bg-rgb: 255, 245, 253; + } + + + /* + * ================================================================================================= + * 🌙🦇 CYBER GOTH THEME (DARK) 🦇🌙 + * + * The lights are out, the neon is ON. + * A dark, moody theme with vibrant, glowing accents. + * ================================================================================================= + */ + [data-bs-theme=dark] { + color-scheme: dark; + + /* --- BACKGROUNDS & TEXT --- */ + --bs-body-bg: #1D001A; /* Deep, dark space purple */ + --bs-body-color: #FFE9FA; /* Light pink text for high contrast */ + --bs-heading-color: var(--bs-cyan); /* Glowing cyan headings */ + + --bs-tertiary-bg: #2E0028; /* A slightly lighter container background */ + --bs-secondary-bg: #3A0033; + --bs-secondary-color: rgba(255, 233, 250, 0.75); + --bs-tertiary-color: rgba(255, 233, 250, 0.5); + + /* --- LINKS & CODE --- */ + /* Using the Toxic Slime for links gives it that cyber look */ + --bs-link-color: var(--bs-green); + --bs-link-hover-color: var(--bs-cyan); + --bs-code-color: var(--bs-pink); + + /* --- BORDERS & SHADOWS: NEON GLOWS --- */ + --bs-border-color: #5C004F; + --bs-border-color-translucent: rgba(255, 255, 255, 0.15); + + /* Redefine shadows to be neon glows */ + --bs-box-shadow: 0 0 15px rgba(var(--bs-primary-rgb), 0.4); + --bs-box-shadow-lg: 0 0 30px rgba(var(--bs-primary-rgb), 0.5); + + /* --- EMPHASIS & SUBTLE BACKGROUNDS --- */ + /* These are for alerts, badges, etc. They'll be dark with glowing text. */ + --bs-primary-text-emphasis: #FF8AD1; + --bs-secondary-text-emphasis: #E2FF8A; + --bs-success-text-emphasis: #8AFFEB; + --bs-info-text-emphasis: #7ADCF5; + --bs-warning-text-emphasis: #FAF8A8; + --bs-danger-text-emphasis: #FF8A8A; + + --bs-primary-bg-subtle: #3D002B; + --bs-secondary-bg-subtle: #415215; + --bs-success-bg-subtle: #00332B; + --bs-info-bg-subtle: #00313D; + --bs-warning-bg-subtle: #3E3D1C; + --bs-danger-bg-subtle: #520E0E; + } + +/* === EMOJI LEVELS === */ +.emoji-normal .emoji-normal { display: inline; } +.emoji-normal .emoji-enhanced, +.emoji-normal .emoji-bonkers { display: none; } + +.emoji-enhanced .emoji-enhanced { display: inline; } +.emoji-enhanced .emoji-normal, +.emoji-enhanced .emoji-bonkers { display: none; } + +.emoji-bonkers .emoji-bonkers { display: inline; } +.emoji-bonkers .emoji-normal, +.emoji-bonkers .emoji-enhanced { display: none; } + /* + * ================================================================================================= + * 🌈 RAINBOW PRIDE ELEMENTS 🌈 + * + * Fabulous rainbow-themed elements to celebrate diversity and pride! + * ================================================================================================= + */ + .bg-rainbow { + background: linear-gradient( + to right, + #FF5757, /* Red */ + #FFBD59, /* Orange */ + #F9F871, /* Yellow */ + #CFFF50, /* Green */ + #00F5D4, /* Teal */ + #00A9E0, /* Blue */ + #A328D6 /* Purple */ + ); + color: white; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); + font-weight: bold; + border: none; + } + + .fun-fact { + font-size: 1.1rem; + line-height: 1.6; + font-style: italic; + } + + /* Add a subtle rainbow border to the fun facts card */ + .card:has(.fun-fact) { + border-width: 2px; + border-style: solid; + border-image: linear-gradient( + to right, + #FF5757, /* Red */ + #FFBD59, /* Orange */ + #F9F871, /* Yellow */ + #CFFF50, /* Green */ + #00F5D4, /* Teal */ + #00A9E0, /* Blue */ + #A328D6 /* Purple */ + ) 1; + box-shadow: 0 4px 15px rgba(163, 40, 214, 0.2); + } diff --git a/assets/styles/emoji-footprint.css b/assets/styles/emoji-footprint.css new file mode 100644 index 0000000..b076361 --- /dev/null +++ b/assets/styles/emoji-footprint.css @@ -0,0 +1,30 @@ + +/* Emoji Footprint Animation */ +.emoji-footprint { + position: absolute; + font-size: 1.6rem; + pointer-events: none; + animation: emojiFade 1s ease-out forwards; + transform: translate(-50%, -50%) scale(1); + opacity: 1; + z-index: 9999; + text-shadow: + 0 0 4px #ff00bf, + 0 0 8px #ff80df, + 0 0 12px #ffccff; +} + +@keyframes emojiFade { + 0% { + transform: translate(-50%, -50%) scale(1); + opacity: 1; + } + 50% { + transform: translate(-50%, -50%) scale(1.5); + opacity: 0.7; + } + 100% { + transform: translate(-50%, -50%) scale(2); + opacity: 0; + } +} \ No newline at end of file diff --git a/assets/styles/modes.css b/assets/styles/modes.css new file mode 100644 index 0000000..383815b --- /dev/null +++ b/assets/styles/modes.css @@ -0,0 +1,565 @@ +/* 🌈✨ BONKERS MODE ANIMATIONS ✨🌈 */ +@keyframes rainbowGradient { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} + +@keyframes discoFlash { + 0%, 100% { + background-color: var(--bs-pink); + box-shadow: 0 0 20px var(--bs-pink), 0 0 40px var(--bs-pink); + } + 16.66% { + background-color: var(--bs-purple); + box-shadow: 0 0 20px var(--bs-purple), 0 0 40px var(--bs-purple); + } + 33.33% { + background-color: var(--bs-cyan); + box-shadow: 0 0 20px var(--bs-cyan), 0 0 40px var(--bs-cyan); + } + 50% { + background-color: var(--bs-yellow); + box-shadow: 0 0 20px var(--bs-yellow), 0 0 40px var(--bs-yellow); + } + 66.66% { + background-color: var(--bs-green); + box-shadow: 0 0 20px var(--bs-green), 0 0 40px var(--bs-green); + } + 83.33% { + background-color: var(--bs-orange); + box-shadow: 0 0 20px var(--bs-orange), 0 0 40px var(--bs-orange); + } +} + +@keyframes wiggle { + 0%, 100% { transform: rotate(0deg); } + 25% { transform: rotate(-2deg); } + 75% { transform: rotate(2deg); } +} + +@keyframes pulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.05); } +} + +@keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} + +@keyframes rainbowText { + 0% { color: var(--bs-red); } + 14.28% { color: var(--bs-orange); } + 28.57% { color: var(--bs-yellow); } + 42.85% { color: var(--bs-green); } + 57.14% { color: var(--bs-cyan); } + 71.42% { color: var(--bs-purple); } + 85.71% { color: var(--bs-pink); } + 100% { color: var(--bs-red); } +} + +@keyframes shine { + 0% { left: -100%; } + 50% { left: 100%; } + 100% { left: 100%; } +} + +@keyframes slayFloat { + 0% { + transform: translateY(0) scale(0.5); + opacity: 0; + } + 20% { + transform: translateY(-20px) scale(1); + opacity: 1; + } + 80% { + transform: translateY(-60px) scale(1.2); + opacity: 0.8; + } + 100% { + transform: translateY(-100px) scale(1.5); + opacity: 0; + } +} + +/* 🎭 BONKERS MODE CLASSES 🎭 */ +.bonkers-mode { + transition: all 0.3s ease-in-out; +} + +.bonkers-mode .btn { + animation: discoFlash 0.3s infinite, wiggle 0.2s infinite; + background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow), var(--bs-green), var(--bs-orange), var(--bs-red)); + background-size: 400% 400%; + animation: discoFlash 0.3s infinite, wiggle 0.2s infinite, rainbowGradient 1s ease infinite; + border: 4px solid var(--bs-white); + font-weight: bold; + text-shadow: 2px 2px 4px rgba(0,0,0,0.5); + position: relative; + overflow: hidden; + transition: all 0.2s ease; +} + +.bonkers-mode .btn:hover { + animation: discoFlash 0.2s infinite, wiggle 0.1s infinite, rainbowGradient 0.5s ease infinite; + box-shadow: 0 0 30px var(--bs-pink), 0 0 60px var(--bs-purple); +} + +.bonkers-mode .btn::before { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient(45deg, transparent, rgba(255,255,255,0.5), transparent); + transform: rotate(45deg); + animation: spin 0.5s linear infinite; +} + +.bonkers-mode .navbar { + background: linear-gradient(90deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow), var(--bs-green), var(--bs-orange), var(--bs-red)); + background-size: 200% 200%; + animation: rainbowGradient 2s ease infinite; + box-shadow: 0 0 50px rgba(255, 105, 180, 0.9); + height: auto !important; + min-height: 56px; +} + +.bonkers-mode .navbar-brand { + animation: rainbowText 0.8s infinite, wiggle 0.4s infinite; + font-size: 1.8em; + text-shadow: 3px 3px 6px rgba(0,0,0,0.5); + position: relative; + overflow: hidden; +} + +.bonkers-mode .navbar-brand::before { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient(45deg, transparent, rgba(255,255,255,0.3), transparent); + transform: rotate(45deg); + animation: spin 2s linear infinite; +} + +.bonkers-mode .navbar-nav .nav-link { + animation: rainbowText 1.2s infinite, wiggle 0.3s infinite; + font-weight: bold; + text-shadow: 2px 2px 4px rgba(0,0,0,0.5); + border: 2px solid transparent; + border-radius: 8px; + padding: 8px 16px; + margin: 0 4px; + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.bonkers-mode .navbar-nav .nav-link::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent); + animation: shine 1.5s ease-in-out infinite; +} + +.bonkers-mode .navbar-nav .nav-link:hover { + background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple)); + border-color: var(--bs-white); + box-shadow: 0 0 20px var(--bs-pink); + animation: discoFlash 0.5s infinite, wiggle 0.2s infinite; +} + +.bonkers-mode .navbar-nav .nav-link.active { + background: linear-gradient(45deg, var(--bs-yellow), var(--bs-orange)); + border-color: var(--bs-white); + box-shadow: 0 0 25px var(--bs-yellow); + animation: discoFlash 0.8s infinite, wiggle 0.3s infinite; +} + +.bonkers-mode .navbar-text { + animation: rainbowText 1.5s infinite, wiggle 0.5s infinite; + font-weight: bold; + text-shadow: 2px 2px 4px rgba(0,0,0,0.5); + border: 2px solid var(--bs-white); + border-radius: 8px; + padding: 6px 12px; + background: linear-gradient(45deg, var(--bs-cyan), var(--bs-blue)); + box-shadow: 0 0 15px var(--bs-cyan); +} + +.bonkers-mode .navbar-toggler { + border: 3px solid var(--bs-white); + background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple)); + animation: discoFlash 0.6s infinite, wiggle 0.4s infinite; + box-shadow: 0 0 20px var(--bs-pink); +} + +.bonkers-mode .navbar-toggler:focus { + box-shadow: 0 0 30px var(--bs-pink), 0 0 0 0.2rem rgba(255, 105, 180, 0.5); +} + +.bonkers-mode .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 1)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); + animation: spin 1s linear infinite; +} + +.bonkers-mode .dropdown-menu { + background: linear-gradient(135deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan)); + border: 3px solid var(--bs-white); + box-shadow: 0 0 30px rgba(255,105,180,0.8); + animation: rainbowGradient 2s ease infinite; +} + +.bonkers-mode .dropdown-item { + animation: rainbowText 1.8s infinite, wiggle 0.6s infinite; + font-weight: bold; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); + border-bottom: 1px solid rgba(255,255,255,0.3); + transition: all 0.3s ease; +} + +.bonkers-mode .dropdown-item:hover { + background: linear-gradient(45deg, var(--bs-yellow), var(--bs-orange)); + color: var(--bs-white); + box-shadow: 0 0 15px var(--bs-yellow); + animation: discoFlash 0.5s infinite, wiggle 0.3s infinite; +} + +.bonkers-mode .navbar-collapse { + background: linear-gradient(135deg, rgba(255,105,180,0.1), rgba(138,43,226,0.1)); + border-radius: 8px; + margin-top: 8px; + padding: 8px; + border: 2px solid var(--bs-pink); +} + +.bonkers-mode h1, .bonkers-mode h2, .bonkers-mode h3 { + animation: rainbowText 1.5s infinite; + text-shadow: 2px 2px 4px rgba(0,0,0,0.3); +} + +.bonkers-mode .table { + background: linear-gradient(135deg, rgba(255,105,180,0.2), rgba(138,43,226,0.2), rgba(0,255,255,0.2)); + animation: rainbowGradient 3s ease infinite; + border: 3px solid var(--bs-pink); + box-shadow: 0 0 30px rgba(255,105,180,0.5); +} + +.bonkers-mode .table th { + background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple)); + color: var(--bs-white); + animation: discoFlash 0.8s infinite; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); + font-size: 1.1em; +} + +.bonkers-mode .form-control { + border: 3px solid var(--bs-pink); + box-shadow: 0 0 15px var(--bs-pink); + animation: pulse 0.6s infinite; +} + +.bonkers-mode .alert { + animation: discoFlash 0.6s infinite, wiggle 0.3s infinite; + border: 4px solid var(--bs-white); + font-weight: bold; + font-size: 1.1em; +} + +.bonkers-mode .card { + background: linear-gradient(45deg, rgba(255,105,180,0.2), rgba(138,43,226,0.2)); + border: 3px solid var(--bs-purple); + box-shadow: 0 0 35px rgba(138,43,226,0.6); + animation: pulse 1s infinite; +} + +.bonkers-mode .modal-content { + background: linear-gradient(135deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan)); + border: 4px solid var(--bs-white); + box-shadow: 0 0 50px rgba(255,105,180,0.8); + animation: rainbowGradient 2s ease infinite; +} + +.bonkers-mode .modal-header { + background: linear-gradient(90deg, var(--bs-yellow), var(--bs-orange)); + animation: discoFlash 0.8s infinite; + font-size: 1.2em; +} + +.bonkers-mode .number-input-wrapper { + animation: wiggle 0.4s infinite; +} + +.bonkers-mode .number-input-wrapper .btn { + animation: discoFlash 0.3s infinite, wiggle 0.2s infinite; +} + +/* Enhanced mode styles (for future use) */ +[data-website-mode="enhanced"] .btn { + background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow), var(--bs-green), var(--bs-orange), var(--bs-red)); + background-size: 400% 400%; + animation: rainbowGradient 1s ease infinite; + border: 4px solid var(--bs-white); + font-weight: bold; + text-shadow: 2px 2px 4px rgba(0,0,0,0.5); + position: relative; + overflow: hidden; + transition: all 0.2s ease; +} + +[data-website-mode="enhanced"] .btn:hover { + animation: rainbowGradient 0.5s ease infinite; + box-shadow: 0 0 30px var(--bs-pink), 0 0 60px var(--bs-purple); +} + +[data-website-mode="enhanced"] .btn::before { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient(45deg, transparent, rgba(255,255,255,0.5), transparent); + transform: rotate(45deg); + animation: spin 0.5s linear infinite; +} + +[data-website-mode="enhanced"] .navbar { + background: linear-gradient(90deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow), var(--bs-green), var(--bs-orange), var(--bs-red)); + background-size: 200% 200%; + animation: rainbowGradient 2s ease infinite; + box-shadow: 0 0 50px rgba(255, 105, 180, 0.9); + height: auto !important; + min-height: 56px; +} + +[data-website-mode="enhanced"] .navbar-brand { + animation: rainbowText 0.8s infinite; + font-size: 1.8em; + text-shadow: 3px 3px 6px rgba(0,0,0,0.5); + position: relative; + overflow: hidden; +} + +[data-website-mode="enhanced"] .navbar-brand::before { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient(45deg, transparent, rgba(255,255,255,0.3), transparent); + transform: rotate(45deg); + animation: spin 2s linear infinite; +} + +[data-website-mode="enhanced"] .navbar-nav .nav-link { + animation: rainbowText 1.2s infinite; + font-weight: bold; + text-shadow: 2px 2px 4px rgba(0,0,0,0.5); + border: 2px solid transparent; + border-radius: 8px; + padding: 8px 16px; + margin: 0 4px; + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +[data-website-mode="enhanced"] .navbar-nav .nav-link::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent); + animation: shine 1.5s ease-in-out infinite; +} + +[data-website-mode="enhanced"] .navbar-nav .nav-link:hover { + background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple)); + border-color: var(--bs-white); + box-shadow: 0 0 20px var(--bs-pink); +} + +[data-website-mode="enhanced"] .navbar-nav .nav-link.active { + background: linear-gradient(45deg, var(--bs-yellow), var(--bs-orange)); + border-color: var(--bs-white); + box-shadow: 0 0 25px var(--bs-yellow); +} + +[data-website-mode="enhanced"] .navbar-text { + animation: rainbowText 1.5s infinite; + font-weight: bold; + text-shadow: 2px 2px 4px rgba(0,0,0,0.5); + border: 2px solid var(--bs-white); + border-radius: 8px; + padding: 6px 12px; + background: linear-gradient(45deg, var(--bs-cyan), var(--bs-blue)); + box-shadow: 0 0 15px var(--bs-cyan); +} + +[data-website-mode="enhanced"] .navbar-toggler { + border: 3px solid var(--bs-white); + background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple)); + animation: rainbowGradient 0.6s ease infinite; + box-shadow: 0 0 20px var(--bs-pink); +} + +[data-website-mode="enhanced"] .navbar-toggler:focus { + box-shadow: 0 0 30px var(--bs-pink), 0 0 0 0.2rem rgba(255, 105, 180, 0.5); +} + +[data-website-mode="enhanced"] .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 1)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); + animation: spin 1s linear infinite; +} + +[data-website-mode="enhanced"] .dropdown-menu { + background: linear-gradient(135deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan)); + border: 3px solid var(--bs-white); + box-shadow: 0 0 30px rgba(255,105,180,0.8); + animation: rainbowGradient 2s ease infinite; +} + +[data-website-mode="enhanced"] .dropdown-item { + animation: rainbowText 1.8s infinite; + font-weight: bold; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); + border-bottom: 1px solid rgba(255,255,255,0.3); + transition: all 0.3s ease; +} + +[data-website-mode="enhanced"] .dropdown-item:hover { + background: linear-gradient(45deg, var(--bs-yellow), var(--bs-orange)); + color: var(--bs-white); + box-shadow: 0 0 15px var(--bs-yellow); +} + +[data-website-mode="enhanced"] .navbar-collapse { + background: linear-gradient(135deg, rgba(255,105,180,0.1), rgba(138,43,226,0.1)); + border-radius: 8px; + margin-top: 8px; + padding: 8px; + border: 2px solid var(--bs-pink); +} + +[data-website-mode="enhanced"] h1, [data-website-mode="enhanced"] h2, [data-website-mode="enhanced"] h3 { + animation: rainbowText 1.5s infinite; + text-shadow: 2px 2px 4px rgba(0,0,0,0.3); +} + +[data-website-mode="enhanced"] .table { + background: linear-gradient(135deg, rgba(255,105,180,0.2), rgba(138,43,226,0.2), rgba(0,255,255,0.2)); + animation: rainbowGradient 3s ease infinite; + border: 3px solid var(--bs-pink); + box-shadow: 0 0 30px rgba(255,105,180,0.5); +} + +[data-website-mode="enhanced"] .table th { + background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple)); + color: var(--bs-white); + animation: rainbowGradient 0.8s ease infinite; + text-shadow: 1px 1px 2px rgba(0,0,0,0.5); + font-size: 1.1em; +} + +[data-website-mode="enhanced"] .form-control { + border: 3px solid var(--bs-pink); + box-shadow: 0 0 15px var(--bs-pink); +} + +[data-website-mode="enhanced"] .alert { + animation: rainbowGradient 0.6s ease infinite; + border: 4px solid var(--bs-white); + font-weight: bold; + font-size: 1.1em; +} + +[data-website-mode="enhanced"] .card { + background: linear-gradient(45deg, rgba(255,105,180,0.2), rgba(138,43,226,0.2)); + border: 3px solid var(--bs-purple); + box-shadow: 0 0 35px rgba(138,43,226,0.6); +} + +[data-website-mode="enhanced"] .modal-content { + background: linear-gradient(135deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan)); + border: 4px solid var(--bs-white); + box-shadow: 0 0 50px rgba(255,105,180,0.8); + animation: rainbowGradient 2s ease infinite; +} + +[data-website-mode="enhanced"] .modal-header { + background: linear-gradient(90deg, var(--bs-yellow), var(--bs-orange)); + animation: rainbowGradient 0.8s ease infinite; + font-size: 1.2em; +} + +[data-website-mode="enhanced"] .number-input-wrapper { +} + +[data-website-mode="enhanced"] .number-input-wrapper .btn { + animation: rainbowGradient 0.3s ease infinite; +} + +/* Emoji Footprint Animation */ +.emoji-footprint { + position: absolute; + font-size: 1.6rem; + pointer-events: none; + animation: emojiFade 1s ease-out forwards; + transform: translate(-50%, -50%) scale(1); + opacity: 1; + z-index: 9999; + text-shadow: + 0 0 4px #ff00bf, + 0 0 8px #ff80df, + 0 0 12px #ffccff; +} + +@keyframes emojiFade { + 0% { + transform: translate(-50%, -50%) scale(1); + opacity: 1; + } + 50% { + transform: translate(-50%, -50%) scale(1.5); + opacity: 0.7; + } + 100% { + transform: translate(-50%, -50%) scale(2); + opacity: 0; + } +} + +/* 💅 SLAY TEXT EFFECTS 💅 */ +.slay-text { + position: fixed; + font-size: 2rem; + font-weight: bold; + pointer-events: none; + z-index: 10000; + animation: slayFloat 3s ease-out forwards; + text-shadow: + 0 0 10px #ff00bf, + 0 0 20px #ff80df, + 0 0 30px #ffccff, + 2px 2px 4px rgba(0,0,0,0.5); + background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow)); + background-size: 400% 400%; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + animation: slayFloat 3s ease-out forwards, rainbowGradient 1s ease infinite; +} diff --git a/config/packages/twig.php b/config/packages/twig.php index d08fe3f..1c06a5b 100644 --- a/config/packages/twig.php +++ b/config/packages/twig.php @@ -1,17 +1,16 @@ extension('twig', [ - 'file_name_pattern' => '*.twig', - 'globals' => [ - 'favicon' => '@App\Service\Favicon', - ], - ]); +return static function ( + ContainerConfigurator $containerConfigurator, + TwigConfig $twig, + ): void { if ($containerConfigurator->env() === 'test') { - $containerConfigurator->extension('twig', [ - 'strict_variables' => true, - ]); + $twig->strictVariables(true); } + $twig->formThemes(['bootstrap_5_layout.html.twig']); + $twig->fileNamePattern('*.twig'); + $twig->global('favicon', '@App\Service\Favicon'); }; diff --git a/templates/_form.html.twig b/templates/_form.html.twig index bf20b98..e0ed7ee 100644 --- a/templates/_form.html.twig +++ b/templates/_form.html.twig @@ -1,4 +1,4 @@ -{{ form_start(form) }} - {{ form_widget(form) }} - +{{ form_start(form, {'attr': {'class': 'mb-3'}}) }} + {{ form_widget(form, {'attr': {'class': 'form-control'}}) }} + {{ form_end(form) }} diff --git a/templates/base.html.twig b/templates/base.html.twig index 942c876..6e78f0a 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -11,19 +11,53 @@ {% endblock %} -
-

Hello {{ app.request.cookies.get('username', 'nobody') }} - change name

-
username name extras actions
{{ item.createdBy }} {{ item.name }} {{ item.extras }} diff --git a/templates/food_order/table_row.html.twig b/templates/food_order/table_row.html.twig index e42bcb9..5f0bff9 100644 --- a/templates/food_order/table_row.html.twig +++ b/templates/food_order/table_row.html.twig @@ -1,4 +1,5 @@
{{ food_order.createdBy }} {{ food_order.foodVendor.name }} {{ food_order.createdAt ? food_order.createdAt|date('Y-m-d H:i:s') : '' }} {{ food_order.closedAt ? food_order.closedAt|date('Y-m-d H:i:s') : '' }}
- +
+ @@ -28,7 +29,7 @@ {% endfor %} {% if food_orders|length < 10 %} - @@ -36,10 +37,12 @@ {% endif %}
CreatedBy Vendor
+ check the archive for older orders
- {% if prev_page > 0 %} - previous page | - {% endif %} - {% if next_page > current_page %} - next page - {% endif %} +
+ {% if prev_page > 0 %} + previous page + {% endif %} + {% if next_page > current_page %} + next page + {% endif %} +
{% endblock %} diff --git a/templates/food_order/new.html.twig b/templates/food_order/new.html.twig index 72ed804..d309283 100644 --- a/templates/food_order/new.html.twig +++ b/templates/food_order/new.html.twig @@ -1,2 +1,4 @@ -{{ include('_form.html.twig') }} +
+ {{ include('_form.html.twig') }} +
diff --git a/templates/food_order/show.html.twig b/templates/food_order/show.html.twig index a7ace15..3114a60 100644 --- a/templates/food_order/show.html.twig +++ b/templates/food_order/show.html.twig @@ -3,9 +3,9 @@ {% block title %}FoodOrder{% endblock %} {% block body %} -

FoodOrder

+

FoodOrder

- +
@@ -29,16 +29,18 @@
Vendor
- back to list - {% if(food_order.isClosed) %} - reopen - {% else %} - close - {% endif %} +
+ back to list + {% if(food_order.isClosed) %} + reopen + {% else %} + close + {% endif %} +
-

Items

- - +

Items

+
+ @@ -57,15 +59,15 @@ {% endfor %}
Index username {% if(food_order.isClosed) %} {% else %} - edit - copy - remove + edit + copy + remove {% endif %}
- New Item + New Item {% endblock %} diff --git a/templates/food_order/table_row.html.twig b/templates/food_order/table_row.html.twig index 580d5fa..ebb01f8 100644 --- a/templates/food_order/table_row.html.twig +++ b/templates/food_order/table_row.html.twig @@ -4,6 +4,6 @@
{{ food_order.createdAt ? food_order.createdAt|date('Y-m-d H:i:s', 'Europe/Berlin') : '' }} {{ food_order.closedAt ? food_order.closedAt|date('Y-m-d H:i:s', 'Europe/Berlin') : '' }} - show + show
- +
+ @@ -17,17 +17,17 @@ {% else %} - + {% endfor %}
Name actions
{{ food_vendor.name }} - show - edit + show + edit
no records foundno records found
- Create new + Create new {% endblock %} diff --git a/templates/food_vendor/new.html.twig b/templates/food_vendor/new.html.twig index 44e3602..8f2d532 100644 --- a/templates/food_vendor/new.html.twig +++ b/templates/food_vendor/new.html.twig @@ -3,9 +3,11 @@ {% block title %}New FoodVendor{% endblock %} {% block body %} -

Create new FoodVendor

+

Create new FoodVendor

- {{ include('food_vendor/_form.html.twig') }} +
+ {{ include('food_vendor/_form.html.twig') }} +
- back to list + back to list {% endblock %} diff --git a/templates/food_vendor/show.html.twig b/templates/food_vendor/show.html.twig index cac8686..51c7e6d 100644 --- a/templates/food_vendor/show.html.twig +++ b/templates/food_vendor/show.html.twig @@ -3,9 +3,9 @@ {% block title %}FoodVendor{% endblock %} {% block body %} -

FoodVendor

+

FoodVendor

- +
@@ -18,23 +18,22 @@
Name
-
+

known menuitems

-
    +
      {% for item in food_vendor.menuItems %} -
    • +
    • {{ item.name }} {% if(item.aliasOf) %} - (alias of: {{ item.aliasOf.name }}) + (alias of: {{ item.aliasOf.name }}) {% endif %}
    • {% endfor %}
    -
- - back to list - - edit + {% endblock %} diff --git a/templates/menu_item/_delete_form.html.twig b/templates/menu_item/_delete_form.html.twig index bd63c7b..1a820c8 100644 --- a/templates/menu_item/_delete_form.html.twig +++ b/templates/menu_item/_delete_form.html.twig @@ -1,4 +1,4 @@
- +
diff --git a/templates/menu_item/_form.html.twig b/templates/menu_item/_form.html.twig index bf20b98..e0ed7ee 100644 --- a/templates/menu_item/_form.html.twig +++ b/templates/menu_item/_form.html.twig @@ -1,4 +1,4 @@ -{{ form_start(form) }} - {{ form_widget(form) }} - +{{ form_start(form, {'attr': {'class': 'mb-3'}}) }} + {{ form_widget(form, {'attr': {'class': 'form-control'}}) }} + {{ form_end(form) }} diff --git a/templates/menu_item/edit.html.twig b/templates/menu_item/edit.html.twig index 46aa766..c1c755e 100644 --- a/templates/menu_item/edit.html.twig +++ b/templates/menu_item/edit.html.twig @@ -3,9 +3,13 @@ {% block title %}Edit MenuItem{% endblock %} {% block body %} -

Edit MenuItem

+

Edit MenuItem

- {{ include('menu_item/_form.html.twig', {'button_label': 'Update'}) }} +
+ {{ include('menu_item/_form.html.twig', {'button_label': 'Update'}) }} +
- {{ include('menu_item/_delete_form.html.twig') }} +
+ {{ include('menu_item/_delete_form.html.twig') }} +
{% endblock %} diff --git a/templates/menu_item/index.html.twig b/templates/menu_item/index.html.twig index 1a895ac..26cb0a4 100644 --- a/templates/menu_item/index.html.twig +++ b/templates/menu_item/index.html.twig @@ -3,10 +3,10 @@ {% block title %}MenuItem index{% endblock %} {% block body %} -

MenuItem index

+

MenuItem index

- - +
+ @@ -19,17 +19,17 @@ {% else %} - + {% endfor %}
Id Name{{ menu_item.id }} {{ menu_item.name }} - show - edit + show + edit
no records foundno records found
- Create new + Create new {% endblock %} diff --git a/templates/menu_item/new.html.twig b/templates/menu_item/new.html.twig index 09eeaa9..0c42fd8 100644 --- a/templates/menu_item/new.html.twig +++ b/templates/menu_item/new.html.twig @@ -3,9 +3,11 @@ {% block title %}New MenuItem{% endblock %} {% block body %} -

Create new MenuItem

+

Create new MenuItem

- {{ include('menu_item/_form.html.twig') }} +
+ {{ include('menu_item/_form.html.twig') }} +
- back to list + back to list {% endblock %} diff --git a/templates/menu_item/show.html.twig b/templates/menu_item/show.html.twig index a07b969..631050f 100644 --- a/templates/menu_item/show.html.twig +++ b/templates/menu_item/show.html.twig @@ -3,9 +3,9 @@ {% block title %}MenuItem{% endblock %} {% block body %} -

MenuItem

+

MenuItem

- +
@@ -25,9 +25,9 @@ @@ -36,9 +36,9 @@
Id
Aliases -
    +
      {% for alias in menu_item.aliases %} -
    • {{ alias.name }}
    • +
    • {{ alias.name }}
    • {% endfor %}
- back to list - - edit - - {{ include('menu_item/_delete_form.html.twig') }} +
+ back to list + edit + {{ include('menu_item/_delete_form.html.twig') }} +
{% endblock %} diff --git a/templates/order_item/_form.html.twig b/templates/order_item/_form.html.twig index bf20b98..e0ed7ee 100644 --- a/templates/order_item/_form.html.twig +++ b/templates/order_item/_form.html.twig @@ -1,4 +1,4 @@ -{{ form_start(form) }} - {{ form_widget(form) }} - +{{ form_start(form, {'attr': {'class': 'mb-3'}}) }} + {{ form_widget(form, {'attr': {'class': 'form-control'}}) }} + {{ form_end(form) }} diff --git a/templates/order_item/edit.html.twig b/templates/order_item/edit.html.twig index 2f85f44..5eb4309 100644 --- a/templates/order_item/edit.html.twig +++ b/templates/order_item/edit.html.twig @@ -3,9 +3,11 @@ {% block title %}Edit OrderItem{% endblock %} {% block body %} -

Edit OrderItem

+

Edit OrderItem

- {{ include('order_item/_form.html.twig', {'button_label': 'Update'}) }} +
+ {{ include('order_item/_form.html.twig', {'button_label': 'Update'}) }} +
- back to list + back to list {% endblock %} diff --git a/templates/order_item/new.html.twig b/templates/order_item/new.html.twig index 0bcddd5..0418010 100644 --- a/templates/order_item/new.html.twig +++ b/templates/order_item/new.html.twig @@ -3,30 +3,32 @@ {% block title %}New OrderItem{% endblock %} {% block body %} -

Create new OrderItem

+

Create new OrderItem

- {{ include('order_item/_form.html.twig') }} +
+ {{ include('order_item/_form.html.twig') }} +

{% if food_order.foodVendor.menuLink != '' %} - + External link to Menu {% endif %} -
+
click a button to select a given menuitem
-
+
{% for menuItem in menuItems %} - {{ menuItem.name }} + {{ menuItem.name }} {% endfor %}

- back to list + back to list